diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e289d9823ed0b5..02eba95d9188a9 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -110,6 +110,8 @@ jobs: src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml \ diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index 61b6ddea5b807d..f08ca5f227c422 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -53,6 +53,8 @@ jobs: DEBIAN_FRONTEND=noninteractive apt-get install -fy --fix-missing openjdk-17-jre - name: Generate all run: ./scripts/run_in_build_env.sh scripts/tools/zap_regen_all.py + - name: Generate script-maintained items (ERROR_CODES.md) + run: ./scripts/run_in_build_env.sh "scripts/error_table.py > docs/ERROR_CODES.md" - name: Ensure git works in current working directory run: git config --global --add safe.directory `pwd` - name: Check for uncommited changes diff --git a/.restyled.yaml b/.restyled.yaml index aeedbacd16240c..ddea89227f3727 100644 --- a/.restyled.yaml +++ b/.restyled.yaml @@ -84,6 +84,8 @@ exclude: - "scripts/setup/bootstrap.sh" # tries to quote loop variable - "integrations/docker/build-all.sh" # tries to quote loop variable - "scripts/setup/pigweed.json" # TODO(#29547). This file is temporary copy from pigweed repo that has minor edits. No restyle help in diff. + - "docs/ERROR_CODES.md" # generated by scripts, not easy to align tables + - "docs/clusters.md" # generated by scripts, not easy to align tables changed_paths: maximum: 100000 diff --git a/.spellcheck.yml b/.spellcheck.yml index 28915deea38167..e3e470a696bbeb 100644 --- a/.spellcheck.yml +++ b/.spellcheck.yml @@ -65,6 +65,6 @@ matrix: # converts markdown to HTML - pyspelling.filters.markdown: sources: - - '**/*.md|!third_party/**|!examples/common/**/repo/**|!docs/ERROR_CODES.md' + - '**/*.md|!third_party/**|!examples/common/**/repo/**|!docs/ERROR_CODES.md|!docs/clusters.md' aspell: ignore-case: true diff --git a/build/chip/java/kotlinc_runner.py b/build/chip/java/kotlinc_runner.py index 07d4aabe79a880..da8078127aeaae 100755 --- a/build/chip/java/kotlinc_runner.py +++ b/build/chip/java/kotlinc_runner.py @@ -127,6 +127,9 @@ def main(): if classpath: kotlin_args += ["-classpath", classpath] + kotlin_args += ["-J-Xms256m", "-J-Xmx4096m", "-J-XX:MaxPermSize=350m", + "-J-XX:ReservedCodeCacheSize=225m", "-J-XX:+UseCompressedOops"] + retcode = subprocess.check_call(kotlin_args + args.rest) if retcode != EXIT_SUCCESS: return retcode diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt index b2058fe75df41c..e32588db436e2c 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -38,12 +38,9 @@ if(NOT "${IDF_TARGET}" STREQUAL "esp32h2") endif() if (NOT CMAKE_BUILD_EARLY_EXPANSION) - if (CONFIG_COMPILER_OPTIMIZATION_DEFAULT OR CONFIG_COMPILER_OPTIMIZATION_NONE) + if (CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE) set(is_debug TRUE) else() - if (NOT CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE) - message(FATAL_ERROR "CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE shall be set") - endif() set(is_debug FALSE) endif() endif() diff --git a/data_model/clusters/AccountLogin.xml b/data_model/clusters/AccountLogin.xml index 3cd5c02590ea0a..cc7e74bf2256fd 100644 --- a/data_model/clusters/AccountLogin.xml +++ b/data_model/clusters/AccountLogin.xml @@ -1,4 +1,4 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +--> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/Channel.xml b/data_model/clusters/Channel.xml index b75540d94a6baf..0f9d546fef27fa 100644 --- a/data_model/clusters/Channel.xml +++ b/data_model/clusters/Channel.xml @@ -1,59 +1,59 @@ - @@ -67,6 +67,12 @@ Davis, CA 95616, USA + + + + + + @@ -85,6 +91,161 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -101,6 +262,12 @@ Davis, CA 95616, USA + + + + + + @@ -190,5 +357,94 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/ContentLauncher.xml b/data_model/clusters/ContentLauncher.xml index 32b47a77c233a3..114c2e4d6e10b7 100644 --- a/data_model/clusters/ContentLauncher.xml +++ b/data_model/clusters/ContentLauncher.xml @@ -1,59 +1,59 @@ - @@ -67,6 +67,15 @@ Davis, CA 95616, USA + + + + + + + + + @@ -125,6 +134,15 @@ Davis, CA 95616, USA + + + + + + + + + @@ -136,6 +154,16 @@ Davis, CA 95616, USA + + + + + + + + + + @@ -144,6 +172,9 @@ Davis, CA 95616, USA + + + @@ -182,6 +213,42 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -262,6 +329,12 @@ Davis, CA 95616, USA + + + + + + @@ -277,6 +350,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/MediaPlayback.xml b/data_model/clusters/MediaPlayback.xml index c53dc862808c12..94987fbcfdb449 100644 --- a/data_model/clusters/MediaPlayback.xml +++ b/data_model/clusters/MediaPlayback.xml @@ -1,59 +1,59 @@ - @@ -67,6 +67,12 @@ Davis, CA 95616, USA + + + + + + @@ -118,6 +124,86 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -172,6 +258,38 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -254,5 +372,88 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/TargetNavigator.xml b/data_model/clusters/TargetNavigator.xml index ffb6955d27bf3c..d93a7de1fc011c 100644 --- a/data_model/clusters/TargetNavigator.xml +++ b/data_model/clusters/TargetNavigator.xml @@ -1,59 +1,59 @@ - @@ -115,4 +115,21 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/ERROR_CODES.md b/docs/ERROR_CODES.md index 38aa66f59f34d0..d828eef779b69f 100644 --- a/docs/ERROR_CODES.md +++ b/docs/ERROR_CODES.md @@ -4,7 +4,6 @@ This file was **AUTOMATICALLY** generated by `python scripts/error_table.py > docs/ERROR_CODES.md`. DO NOT EDIT BY HAND! ## Table of contents - - [SDK Core errors: range `0x000..0x0FF`](#sdk-core-errors) - [SDK Inet Layer errors: range `0x100..0x1FF`](#sdk-inet-layer-errors) - [SDK Device Layer errors: range `0x200..0x2FF`](#sdk-device-layer-errors) @@ -14,242 +13,247 @@ This file was **AUTOMATICALLY** generated by ## SDK Core errors -| Decimal | Hex | Name | -| ------- | ---- | -------------------------------------------------- | -| 0 | 0x00 | `CHIP_NO_ERROR` | -| 1 | 0x01 | `CHIP_ERROR_SENDING_BLOCKED` | -| 2 | 0x02 | `CHIP_ERROR_CONNECTION_ABORTED` | -| 3 | 0x03 | `CHIP_ERROR_INCORRECT_STATE` | -| 4 | 0x04 | `CHIP_ERROR_MESSAGE_TOO_LONG` | -| 5 | 0x05 | `CHIP_ERROR_RECURSION_DEPTH_LIMIT` | -| 6 | 0x06 | `CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS` | -| 7 | 0x07 | `CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER` | -| 8 | 0x08 | `CHIP_ERROR_NO_CONNECTION_HANDLER` | -| 9 | 0x09 | `CHIP_ERROR_TOO_MANY_PEER_NODES` | -| 10 | 0x0A | `CHIP_ERROR_SENTINEL` | -| 11 | 0x0B | `CHIP_ERROR_NO_MEMORY` | -| 12 | 0x0C | `CHIP_ERROR_NO_MESSAGE_HANDLER` | -| 13 | 0x0D | `CHIP_ERROR_MESSAGE_INCOMPLETE` | -| 14 | 0x0E | `CHIP_ERROR_DATA_NOT_ALIGNED` | -| 15 | 0x0F | `CHIP_ERROR_UNKNOWN_KEY_TYPE` | -| 16 | 0x10 | `CHIP_ERROR_KEY_NOT_FOUND` | -| 17 | 0x11 | `CHIP_ERROR_WRONG_ENCRYPTION_TYPE` | -| 19 | 0x13 | `CHIP_ERROR_INTEGRITY_CHECK_FAILED` | -| 20 | 0x14 | `CHIP_ERROR_INVALID_SIGNATURE` | -| 23 | 0x17 | `CHIP_ERROR_UNSUPPORTED_SIGNATURE_TYPE` | -| 24 | 0x18 | `CHIP_ERROR_INVALID_MESSAGE_LENGTH` | -| 25 | 0x19 | `CHIP_ERROR_BUFFER_TOO_SMALL` | -| 26 | 0x1A | `CHIP_ERROR_DUPLICATE_KEY_ID` | -| 27 | 0x1B | `CHIP_ERROR_WRONG_KEY_TYPE` | -| 28 | 0x1C | `CHIP_ERROR_WELL_UNINITIALIZED` | -| 29 | 0x1D | `CHIP_ERROR_WELL_EMPTY` | -| 30 | 0x1E | `CHIP_ERROR_INVALID_STRING_LENGTH` | -| 31 | 0x1F | `CHIP_ERROR_INVALID_LIST_LENGTH` | -| 33 | 0x21 | `CHIP_ERROR_END_OF_TLV` | -| 34 | 0x22 | `CHIP_ERROR_TLV_UNDERRUN` | -| 35 | 0x23 | `CHIP_ERROR_INVALID_TLV_ELEMENT` | -| 36 | 0x24 | `CHIP_ERROR_INVALID_TLV_TAG` | -| 37 | 0x25 | `CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG` | -| 38 | 0x26 | `CHIP_ERROR_WRONG_TLV_TYPE` | -| 39 | 0x27 | `CHIP_ERROR_TLV_CONTAINER_OPEN` | -| 42 | 0x2A | `CHIP_ERROR_INVALID_MESSAGE_TYPE` | -| 43 | 0x2B | `CHIP_ERROR_UNEXPECTED_TLV_ELEMENT` | -| 45 | 0x2D | `CHIP_ERROR_NOT_IMPLEMENTED` | -| 46 | 0x2E | `CHIP_ERROR_INVALID_ADDRESS` | -| 47 | 0x2F | `CHIP_ERROR_INVALID_ARGUMENT` | -| 48 | 0x30 | `CHIP_ERROR_INVALID_PATH_LIST` | -| 49 | 0x31 | `CHIP_ERROR_INVALID_DATA_LIST` | -| 50 | 0x32 | `CHIP_ERROR_TIMEOUT` | -| 51 | 0x33 | `CHIP_ERROR_INVALID_DEVICE_DESCRIPTOR` | -| 56 | 0x38 | `CHIP_ERROR_INVALID_PASE_PARAMETER` | -| 59 | 0x3B | `CHIP_ERROR_INVALID_USE_OF_SESSION_KEY` | -| 60 | 0x3C | `CHIP_ERROR_CONNECTION_CLOSED_UNEXPECTEDLY` | -| 61 | 0x3D | `CHIP_ERROR_MISSING_TLV_ELEMENT` | -| 62 | 0x3E | `CHIP_ERROR_RANDOM_DATA_UNAVAILABLE` | -| 65 | 0x41 | `CHIP_ERROR_HOST_PORT_LIST_EMPTY` | -| 69 | 0x45 | `CHIP_ERROR_FORCED_RESET` | -| 70 | 0x46 | `CHIP_ERROR_NO_ENDPOINT` | -| 71 | 0x47 | `CHIP_ERROR_INVALID_DESTINATION_NODE_ID` | -| 72 | 0x48 | `CHIP_ERROR_NOT_CONNECTED` | -| 74 | 0x4A | `CHIP_ERROR_CA_CERT_NOT_FOUND` | -| 75 | 0x4B | `CHIP_ERROR_CERT_PATH_LEN_CONSTRAINT_EXCEEDED` | -| 76 | 0x4C | `CHIP_ERROR_CERT_PATH_TOO_LONG` | -| 77 | 0x4D | `CHIP_ERROR_CERT_USAGE_NOT_ALLOWED` | -| 78 | 0x4E | `CHIP_ERROR_CERT_EXPIRED` | -| 79 | 0x4F | `CHIP_ERROR_CERT_NOT_VALID_YET` | -| 80 | 0x50 | `CHIP_ERROR_UNSUPPORTED_CERT_FORMAT` | -| 81 | 0x51 | `CHIP_ERROR_UNSUPPORTED_ELLIPTIC_CURVE` | -| 83 | 0x53 | `CHIP_ERROR_CERT_NOT_FOUND` | -| 84 | 0x54 | `CHIP_ERROR_INVALID_CASE_PARAMETER` | -| 86 | 0x56 | `CHIP_ERROR_CERT_LOAD_FAILED` | -| 87 | 0x57 | `CHIP_ERROR_CERT_NOT_TRUSTED` | -| 89 | 0x59 | `CHIP_ERROR_WRONG_CERT_DN` | -| 92 | 0x5C | `CHIP_ERROR_WRONG_NODE_ID` | -| 100 | 0x64 | `CHIP_ERROR_RETRANS_TABLE_FULL` | -| 104 | 0x68 | `CHIP_ERROR_TRANSACTION_CANCELED` | -| 107 | 0x6B | `CHIP_ERROR_INVALID_SUBSCRIPTION` | -| 108 | 0x6C | `CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE` | -| 112 | 0x70 | `CHIP_ERROR_UNSOLICITED_MSG_NO_ORIGINATOR` | -| 113 | 0x71 | `CHIP_ERROR_INVALID_FABRIC_INDEX` | -| 114 | 0x72 | `CHIP_ERROR_TOO_MANY_CONNECTIONS` | -| 115 | 0x73 | `CHIP_ERROR_SHUT_DOWN` | -| 116 | 0x74 | `CHIP_ERROR_CANCELLED` | -| 118 | 0x76 | `CHIP_ERROR_TLV_TAG_NOT_FOUND` | -| 119 | 0x77 | `CHIP_ERROR_MISSING_SECURE_SESSION` | -| 120 | 0x78 | `CHIP_ERROR_INVALID_ADMIN_SUBJECT` | -| 121 | 0x79 | `CHIP_ERROR_INSUFFICIENT_PRIVILEGE` | -| 125 | 0x7D | `CHIP_ERROR_MESSAGE_COUNTER_EXHAUSTED` | -| 126 | 0x7E | `CHIP_ERROR_FABRIC_EXISTS` | -| 128 | 0x80 | `CHIP_ERROR_WRONG_ENCRYPTION_TYPE_FROM_PEER` | -| 133 | 0x85 | `CHIP_ERROR_INVALID_KEY_ID` | -| 134 | 0x86 | `CHIP_ERROR_INVALID_TIME` | -| 142 | 0x8E | `CHIP_ERROR_SCHEMA_MISMATCH` | -| 143 | 0x8F | `CHIP_ERROR_INVALID_INTEGER_VALUE` | -| 146 | 0x92 | `CHIP_ERROR_BAD_REQUEST` | -| 157 | 0x9D | `CHIP_ERROR_WRONG_CERT_TYPE` | -| 159 | 0x9F | `CHIP_ERROR_PERSISTED_STORAGE_FAILED` | -| 160 | 0xA0 | `CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND` | -| 161 | 0xA1 | `CHIP_ERROR_IM_FABRIC_DELETED` | -| 164 | 0xA4 | `CHIP_ERROR_IN_PROGRESS` | -| 165 | 0xA5 | `CHIP_ERROR_ACCESS_DENIED` | -| 166 | 0xA6 | `CHIP_ERROR_UNKNOWN_RESOURCE_ID` | -| 167 | 0xA7 | `CHIP_ERROR_VERSION_MISMATCH` | -| 171 | 0xAB | `CHIP_ERROR_EVENT_ID_FOUND` | -| 172 | 0xAC | `CHIP_ERROR_INTERNAL` | -| 173 | 0xAD | `CHIP_ERROR_OPEN_FAILED` | -| 174 | 0xAE | `CHIP_ERROR_READ_FAILED` | -| 175 | 0xAF | `CHIP_ERROR_WRITE_FAILED` | -| 176 | 0xB0 | `CHIP_ERROR_DECODE_FAILED` | -| 180 | 0xB4 | `CHIP_ERROR_MDNS_COLLISION` | -| 181 | 0xB5 | `CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB` | -| 182 | 0xB6 | `CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB` | -| 185 | 0xB9 | `CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_IB` | -| 186 | 0xBA | `CHIP_ERROR_IM_MALFORMED_EVENT_DATA_IB` | -| 188 | 0xBC | `CHIP_ERROR_PEER_NODE_NOT_FOUND` | -| 189 | 0xBD | `CHIP_ERROR_HSM` | -| 191 | 0xBF | `CHIP_ERROR_REAL_TIME_NOT_SYNCED` | -| 192 | 0xC0 | `CHIP_ERROR_UNEXPECTED_EVENT` | -| 193 | 0xC1 | `CHIP_ERROR_ENDPOINT_POOL_FULL` | -| 194 | 0xC2 | `CHIP_ERROR_INBOUND_MESSAGE_TOO_BIG` | -| 195 | 0xC3 | `CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG` | -| 196 | 0xC4 | `CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED` | -| 197 | 0xC5 | `CHIP_ERROR_INVALID_PUBLIC_KEY` | -| 198 | 0xC6 | `CHIP_ERROR_FABRIC_MISMATCH_ON_ICA` | -| 201 | 0xC9 | `CHIP_ERROR_NO_SHARED_TRUSTED_ROOT` | -| 202 | 0xCA | `CHIP_ERROR_IM_STATUS_CODE_RECEIVED` | -| 215 | 0xD7 | `CHIP_ERROR_IM_MALFORMED_DATA_VERSION_FILTER_IB` | -| 216 | 0xD8 | `CHIP_ERROR_NOT_FOUND` | -| 218 | 0xDA | `CHIP_ERROR_INVALID_FILE_IDENTIFIER` | -| 219 | 0xDB | `CHIP_ERROR_BUSY` | -| 220 | 0xDC | `CHIP_ERROR_MAX_RETRY_EXCEEDED` | -| 221 | 0xDD | `CHIP_ERROR_PROVIDER_LIST_EXHAUSTED` | -| 223 | 0xDF | `CHIP_ERROR_INVALID_SCHEME_PREFIX` | -| 224 | 0xE0 | `CHIP_ERROR_MISSING_URI_SEPARATOR` | -| 225 | 0xE1 | `CHIP_ERROR_HANDLER_NOT_SET` | +| Decimal | Hex | Name | +|-----------|-------|----------------------------------------------------| +| 0 | 0x00 | `CHIP_NO_ERROR` | +| 1 | 0x01 | `CHIP_ERROR_SENDING_BLOCKED` | +| 2 | 0x02 | `CHIP_ERROR_CONNECTION_ABORTED` | +| 3 | 0x03 | `CHIP_ERROR_INCORRECT_STATE` | +| 4 | 0x04 | `CHIP_ERROR_MESSAGE_TOO_LONG` | +| 5 | 0x05 | `CHIP_ERROR_RECURSION_DEPTH_LIMIT` | +| 6 | 0x06 | `CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS` | +| 7 | 0x07 | `CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER` | +| 8 | 0x08 | `CHIP_ERROR_NO_CONNECTION_HANDLER` | +| 9 | 0x09 | `CHIP_ERROR_TOO_MANY_PEER_NODES` | +| 10 | 0x0A | `CHIP_ERROR_SENTINEL` | +| 11 | 0x0B | `CHIP_ERROR_NO_MEMORY` | +| 12 | 0x0C | `CHIP_ERROR_NO_MESSAGE_HANDLER` | +| 13 | 0x0D | `CHIP_ERROR_MESSAGE_INCOMPLETE` | +| 14 | 0x0E | `CHIP_ERROR_DATA_NOT_ALIGNED` | +| 15 | 0x0F | `CHIP_ERROR_UNKNOWN_KEY_TYPE` | +| 16 | 0x10 | `CHIP_ERROR_KEY_NOT_FOUND` | +| 17 | 0x11 | `CHIP_ERROR_WRONG_ENCRYPTION_TYPE` | +| 18 | 0x12 | `CHIP_ERROR_INVALID_UTF8` | +| 19 | 0x13 | `CHIP_ERROR_INTEGRITY_CHECK_FAILED` | +| 20 | 0x14 | `CHIP_ERROR_INVALID_SIGNATURE` | +| 21 | 0x15 | `CHIP_ERROR_INVALID_TLV_CHAR_STRING` | +| 23 | 0x17 | `CHIP_ERROR_UNSUPPORTED_SIGNATURE_TYPE` | +| 24 | 0x18 | `CHIP_ERROR_INVALID_MESSAGE_LENGTH` | +| 25 | 0x19 | `CHIP_ERROR_BUFFER_TOO_SMALL` | +| 26 | 0x1A | `CHIP_ERROR_DUPLICATE_KEY_ID` | +| 27 | 0x1B | `CHIP_ERROR_WRONG_KEY_TYPE` | +| 28 | 0x1C | `CHIP_ERROR_UNINITIALIZED` | +| 29 | 0x1D | `CHIP_ERROR_EMPTY` | +| 30 | 0x1E | `CHIP_ERROR_INVALID_STRING_LENGTH` | +| 31 | 0x1F | `CHIP_ERROR_INVALID_LIST_LENGTH` | +| 33 | 0x21 | `CHIP_ERROR_END_OF_TLV` | +| 34 | 0x22 | `CHIP_ERROR_TLV_UNDERRUN` | +| 35 | 0x23 | `CHIP_ERROR_INVALID_TLV_ELEMENT` | +| 36 | 0x24 | `CHIP_ERROR_INVALID_TLV_TAG` | +| 37 | 0x25 | `CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG` | +| 38 | 0x26 | `CHIP_ERROR_WRONG_TLV_TYPE` | +| 39 | 0x27 | `CHIP_ERROR_TLV_CONTAINER_OPEN` | +| 42 | 0x2A | `CHIP_ERROR_INVALID_MESSAGE_TYPE` | +| 43 | 0x2B | `CHIP_ERROR_UNEXPECTED_TLV_ELEMENT` | +| 45 | 0x2D | `CHIP_ERROR_NOT_IMPLEMENTED` | +| 46 | 0x2E | `CHIP_ERROR_INVALID_ADDRESS` | +| 47 | 0x2F | `CHIP_ERROR_INVALID_ARGUMENT` | +| 48 | 0x30 | `CHIP_ERROR_INVALID_PATH_LIST` | +| 49 | 0x31 | `CHIP_ERROR_INVALID_DATA_LIST` | +| 50 | 0x32 | `CHIP_ERROR_TIMEOUT` | +| 51 | 0x33 | `CHIP_ERROR_INVALID_DEVICE_DESCRIPTOR` | +| 56 | 0x38 | `CHIP_ERROR_INVALID_PASE_PARAMETER` | +| 59 | 0x3B | `CHIP_ERROR_INVALID_USE_OF_SESSION_KEY` | +| 60 | 0x3C | `CHIP_ERROR_CONNECTION_CLOSED_UNEXPECTEDLY` | +| 61 | 0x3D | `CHIP_ERROR_MISSING_TLV_ELEMENT` | +| 62 | 0x3E | `CHIP_ERROR_RANDOM_DATA_UNAVAILABLE` | +| 65 | 0x41 | `CHIP_ERROR_HOST_PORT_LIST_EMPTY` | +| 69 | 0x45 | `CHIP_ERROR_FORCED_RESET` | +| 70 | 0x46 | `CHIP_ERROR_NO_ENDPOINT` | +| 71 | 0x47 | `CHIP_ERROR_INVALID_DESTINATION_NODE_ID` | +| 72 | 0x48 | `CHIP_ERROR_NOT_CONNECTED` | +| 74 | 0x4A | `CHIP_ERROR_CA_CERT_NOT_FOUND` | +| 75 | 0x4B | `CHIP_ERROR_CERT_PATH_LEN_CONSTRAINT_EXCEEDED` | +| 76 | 0x4C | `CHIP_ERROR_CERT_PATH_TOO_LONG` | +| 77 | 0x4D | `CHIP_ERROR_CERT_USAGE_NOT_ALLOWED` | +| 78 | 0x4E | `CHIP_ERROR_CERT_EXPIRED` | +| 79 | 0x4F | `CHIP_ERROR_CERT_NOT_VALID_YET` | +| 80 | 0x50 | `CHIP_ERROR_UNSUPPORTED_CERT_FORMAT` | +| 81 | 0x51 | `CHIP_ERROR_UNSUPPORTED_ELLIPTIC_CURVE` | +| 83 | 0x53 | `CHIP_ERROR_CERT_NOT_FOUND` | +| 84 | 0x54 | `CHIP_ERROR_INVALID_CASE_PARAMETER` | +| 86 | 0x56 | `CHIP_ERROR_CERT_LOAD_FAILED` | +| 87 | 0x57 | `CHIP_ERROR_CERT_NOT_TRUSTED` | +| 89 | 0x59 | `CHIP_ERROR_WRONG_CERT_DN` | +| 92 | 0x5C | `CHIP_ERROR_WRONG_NODE_ID` | +| 100 | 0x64 | `CHIP_ERROR_RETRANS_TABLE_FULL` | +| 104 | 0x68 | `CHIP_ERROR_TRANSACTION_CANCELED` | +| 107 | 0x6B | `CHIP_ERROR_INVALID_SUBSCRIPTION` | +| 108 | 0x6C | `CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE` | +| 112 | 0x70 | `CHIP_ERROR_UNSOLICITED_MSG_NO_ORIGINATOR` | +| 113 | 0x71 | `CHIP_ERROR_INVALID_FABRIC_INDEX` | +| 114 | 0x72 | `CHIP_ERROR_TOO_MANY_CONNECTIONS` | +| 115 | 0x73 | `CHIP_ERROR_SHUT_DOWN` | +| 116 | 0x74 | `CHIP_ERROR_CANCELLED` | +| 118 | 0x76 | `CHIP_ERROR_TLV_TAG_NOT_FOUND` | +| 119 | 0x77 | `CHIP_ERROR_MISSING_SECURE_SESSION` | +| 120 | 0x78 | `CHIP_ERROR_INVALID_ADMIN_SUBJECT` | +| 121 | 0x79 | `CHIP_ERROR_INSUFFICIENT_PRIVILEGE` | +| 125 | 0x7D | `CHIP_ERROR_MESSAGE_COUNTER_EXHAUSTED` | +| 126 | 0x7E | `CHIP_ERROR_FABRIC_EXISTS` | +| 128 | 0x80 | `CHIP_ERROR_WRONG_ENCRYPTION_TYPE_FROM_PEER` | +| 133 | 0x85 | `CHIP_ERROR_INVALID_KEY_ID` | +| 134 | 0x86 | `CHIP_ERROR_INVALID_TIME` | +| 142 | 0x8E | `CHIP_ERROR_SCHEMA_MISMATCH` | +| 143 | 0x8F | `CHIP_ERROR_INVALID_INTEGER_VALUE` | +| 146 | 0x92 | `CHIP_ERROR_BAD_REQUEST` | +| 157 | 0x9D | `CHIP_ERROR_WRONG_CERT_TYPE` | +| 159 | 0x9F | `CHIP_ERROR_PERSISTED_STORAGE_FAILED` | +| 160 | 0xA0 | `CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND` | +| 161 | 0xA1 | `CHIP_ERROR_IM_FABRIC_DELETED` | +| 164 | 0xA4 | `CHIP_ERROR_IN_PROGRESS` | +| 165 | 0xA5 | `CHIP_ERROR_ACCESS_DENIED` | +| 166 | 0xA6 | `CHIP_ERROR_UNKNOWN_RESOURCE_ID` | +| 167 | 0xA7 | `CHIP_ERROR_VERSION_MISMATCH` | +| 171 | 0xAB | `CHIP_ERROR_EVENT_ID_FOUND` | +| 172 | 0xAC | `CHIP_ERROR_INTERNAL` | +| 173 | 0xAD | `CHIP_ERROR_OPEN_FAILED` | +| 174 | 0xAE | `CHIP_ERROR_READ_FAILED` | +| 175 | 0xAF | `CHIP_ERROR_WRITE_FAILED` | +| 176 | 0xB0 | `CHIP_ERROR_DECODE_FAILED` | +| 179 | 0xB3 | `CHIP_ERROR_DNS_SD_UNAUTHORIZED` | +| 180 | 0xB4 | `CHIP_ERROR_MDNS_COLLISION` | +| 181 | 0xB5 | `CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB` | +| 182 | 0xB6 | `CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB` | +| 185 | 0xB9 | `CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_IB` | +| 186 | 0xBA | `CHIP_ERROR_IM_MALFORMED_EVENT_DATA_IB` | +| 188 | 0xBC | `CHIP_ERROR_PEER_NODE_NOT_FOUND` | +| 189 | 0xBD | `CHIP_ERROR_HSM` | +| 191 | 0xBF | `CHIP_ERROR_REAL_TIME_NOT_SYNCED` | +| 192 | 0xC0 | `CHIP_ERROR_UNEXPECTED_EVENT` | +| 193 | 0xC1 | `CHIP_ERROR_ENDPOINT_POOL_FULL` | +| 194 | 0xC2 | `CHIP_ERROR_INBOUND_MESSAGE_TOO_BIG` | +| 195 | 0xC3 | `CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG` | +| 196 | 0xC4 | `CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED` | +| 197 | 0xC5 | `CHIP_ERROR_INVALID_PUBLIC_KEY` | +| 198 | 0xC6 | `CHIP_ERROR_FABRIC_MISMATCH_ON_ICA` | +| 201 | 0xC9 | `CHIP_ERROR_NO_SHARED_TRUSTED_ROOT` | +| 202 | 0xCA | `CHIP_ERROR_IM_STATUS_CODE_RECEIVED` | +| 215 | 0xD7 | `CHIP_ERROR_IM_MALFORMED_DATA_VERSION_FILTER_IB` | +| 216 | 0xD8 | `CHIP_ERROR_NOT_FOUND` | +| 218 | 0xDA | `CHIP_ERROR_INVALID_FILE_IDENTIFIER` | +| 219 | 0xDB | `CHIP_ERROR_BUSY` | +| 220 | 0xDC | `CHIP_ERROR_MAX_RETRY_EXCEEDED` | +| 221 | 0xDD | `CHIP_ERROR_PROVIDER_LIST_EXHAUSTED` | +| 223 | 0xDF | `CHIP_ERROR_INVALID_SCHEME_PREFIX` | +| 224 | 0xE0 | `CHIP_ERROR_MISSING_URI_SEPARATOR` | +| 225 | 0xE1 | `CHIP_ERROR_HANDLER_NOT_SET` | ## SDK Inet Layer errors -| Decimal | Hex | Name | -| ------- | ----- | ----------------------------------------- | -| 257 | 0x101 | `INET_ERROR_WRONG_ADDRESS_TYPE` | -| 258 | 0x102 | `INET_ERROR_PEER_DISCONNECTED` | -| 265 | 0x109 | `INET_ERROR_HOST_NOT_FOUND` | -| 266 | 0x10A | `INET_ERROR_DNS_TRY_AGAIN` | -| 267 | 0x10B | `INET_ERROR_DNS_NO_RECOVERY` | -| 269 | 0x10D | `INET_ERROR_WRONG_PROTOCOL_TYPE` | -| 270 | 0x10E | `INET_ERROR_UNKNOWN_INTERFACE` | -| 272 | 0x110 | `INET_ERROR_ADDRESS_NOT_FOUND` | -| 273 | 0x111 | `INET_ERROR_HOST_NAME_TOO_LONG` | -| 274 | 0x112 | `INET_ERROR_INVALID_HOST_NAME` | -| 277 | 0x115 | `INET_ERROR_IDLE_TIMEOUT` | -| 279 | 0x117 | `INET_ERROR_INVALID_IPV6_PKT` | -| 280 | 0x118 | `INET_ERROR_INTERFACE_INIT_FAILURE` | -| 281 | 0x119 | `INET_ERROR_TCP_USER_TIMEOUT` | -| 282 | 0x11A | `INET_ERROR_TCP_CONNECT_TIMEOUT` | -| 283 | 0x11B | `INET_ERROR_INCOMPATIBLE_IP_ADDRESS_TYPE` | +| Decimal | Hex | Name | +|-----------|-------|-------------------------------------------| +| 257 | 0x101 | `INET_ERROR_WRONG_ADDRESS_TYPE` | +| 258 | 0x102 | `INET_ERROR_PEER_DISCONNECTED` | +| 265 | 0x109 | `INET_ERROR_HOST_NOT_FOUND` | +| 266 | 0x10A | `INET_ERROR_DNS_TRY_AGAIN` | +| 267 | 0x10B | `INET_ERROR_DNS_NO_RECOVERY` | +| 269 | 0x10D | `INET_ERROR_WRONG_PROTOCOL_TYPE` | +| 270 | 0x10E | `INET_ERROR_UNKNOWN_INTERFACE` | +| 272 | 0x110 | `INET_ERROR_ADDRESS_NOT_FOUND` | +| 273 | 0x111 | `INET_ERROR_HOST_NAME_TOO_LONG` | +| 274 | 0x112 | `INET_ERROR_INVALID_HOST_NAME` | +| 277 | 0x115 | `INET_ERROR_IDLE_TIMEOUT` | +| 279 | 0x117 | `INET_ERROR_INVALID_IPV6_PKT` | +| 280 | 0x118 | `INET_ERROR_INTERFACE_INIT_FAILURE` | +| 281 | 0x119 | `INET_ERROR_TCP_USER_TIMEOUT` | +| 282 | 0x11A | `INET_ERROR_TCP_CONNECT_TIMEOUT` | +| 283 | 0x11B | `INET_ERROR_INCOMPATIBLE_IP_ADDRESS_TYPE` | ## SDK Device Layer errors -| Decimal | Hex | Name | -| ------- | ----- | ------------------------------------------- | -| 513 | 0x201 | `CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND` | -| 514 | 0x202 | `CHIP_DEVICE_ERROR_NOT_SERVICE_PROVISIONED` | -| 515 | 0x203 | `CHIP_DEVICE_ERROR_SOFTWARE_UPDATE_ABORTED` | -| 516 | 0x204 | `CHIP_DEVICE_ERROR_SOFTWARE_UPDATE_IGNORED` | +| Decimal | Hex | Name | +|-----------|-------|---------------------------------------------| +| 513 | 0x201 | `CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND` | +| 514 | 0x202 | `CHIP_DEVICE_ERROR_NOT_SERVICE_PROVISIONED` | +| 515 | 0x203 | `CHIP_DEVICE_ERROR_SOFTWARE_UPDATE_ABORTED` | +| 516 | 0x204 | `CHIP_DEVICE_ERROR_SOFTWARE_UPDATE_IGNORED` | ## ASN1 Layer errors -| Decimal | Hex | Name | -| ------- | ----- | --------------------------------- | -| 768 | 0x300 | `ASN1_END` | -| 769 | 0x301 | `ASN1_ERROR_UNDERRUN` | -| 770 | 0x302 | `ASN1_ERROR_OVERFLOW` | -| 771 | 0x303 | `ASN1_ERROR_INVALID_STATE` | -| 772 | 0x304 | `ASN1_ERROR_MAX_DEPTH_EXCEEDED` | -| 773 | 0x305 | `ASN1_ERROR_INVALID_ENCODING` | -| 774 | 0x306 | `ASN1_ERROR_UNSUPPORTED_ENCODING` | -| 775 | 0x307 | `ASN1_ERROR_TAG_OVERFLOW` | -| 776 | 0x308 | `ASN1_ERROR_LENGTH_OVERFLOW` | -| 777 | 0x309 | `ASN1_ERROR_VALUE_OVERFLOW` | -| 778 | 0x30A | `ASN1_ERROR_UNKNOWN_OBJECT_ID` | +| Decimal | Hex | Name | +|-----------|-------|-----------------------------------| +| 768 | 0x300 | `ASN1_END` | +| 769 | 0x301 | `ASN1_ERROR_UNDERRUN` | +| 770 | 0x302 | `ASN1_ERROR_OVERFLOW` | +| 771 | 0x303 | `ASN1_ERROR_INVALID_STATE` | +| 772 | 0x304 | `ASN1_ERROR_MAX_DEPTH_EXCEEDED` | +| 773 | 0x305 | `ASN1_ERROR_INVALID_ENCODING` | +| 774 | 0x306 | `ASN1_ERROR_UNSUPPORTED_ENCODING` | +| 775 | 0x307 | `ASN1_ERROR_TAG_OVERFLOW` | +| 776 | 0x308 | `ASN1_ERROR_LENGTH_OVERFLOW` | +| 777 | 0x309 | `ASN1_ERROR_VALUE_OVERFLOW` | +| 778 | 0x30A | `ASN1_ERROR_UNKNOWN_OBJECT_ID` | ## BLE Layer errors -| Decimal | Hex | Name | -| ------- | ----- | ------------------------------------------- | -| 1027 | 0x403 | `BLE_ERROR_NO_CONNECTION_RECEIVED_CALLBACK` | -| 1028 | 0x404 | `BLE_ERROR_CENTRAL_UNSUBSCRIBED` | -| 1029 | 0x405 | `BLE_ERROR_GATT_SUBSCRIBE_FAILED` | -| 1030 | 0x406 | `BLE_ERROR_GATT_UNSUBSCRIBE_FAILED` | -| 1031 | 0x407 | `BLE_ERROR_GATT_WRITE_FAILED` | -| 1032 | 0x408 | `BLE_ERROR_GATT_INDICATE_FAILED` | -| 1035 | 0x40B | `BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT` | -| 1036 | 0x40C | `BLE_ERROR_REMOTE_DEVICE_DISCONNECTED` | -| 1037 | 0x40D | `BLE_ERROR_APP_CLOSED_CONNECTION` | -| 1039 | 0x40F | `BLE_ERROR_NOT_CHIP_DEVICE` | -| 1040 | 0x410 | `BLE_ERROR_INCOMPATIBLE_PROTOCOL_VERSIONS` | -| 1043 | 0x413 | `BLE_ERROR_INVALID_FRAGMENT_SIZE` | -| 1044 | 0x414 | `BLE_ERROR_START_TIMER_FAILED` | -| 1045 | 0x415 | `BLE_ERROR_CONNECT_TIMED_OUT` | -| 1046 | 0x416 | `BLE_ERROR_RECEIVE_TIMED_OUT` | -| 1047 | 0x417 | `BLE_ERROR_INVALID_MESSAGE` | -| 1048 | 0x418 | `BLE_ERROR_FRAGMENT_ACK_TIMED_OUT` | -| 1049 | 0x419 | `BLE_ERROR_KEEP_ALIVE_TIMED_OUT` | -| 1050 | 0x41A | `BLE_ERROR_NO_CONNECT_COMPLETE_CALLBACK` | -| 1051 | 0x41B | `BLE_ERROR_INVALID_ACK` | -| 1052 | 0x41C | `BLE_ERROR_REASSEMBLER_MISSING_DATA` | -| 1053 | 0x41D | `BLE_ERROR_INVALID_BTP_HEADER_FLAGS` | -| 1054 | 0x41E | `BLE_ERROR_INVALID_BTP_SEQUENCE_NUMBER` | -| 1055 | 0x41F | `BLE_ERROR_REASSEMBLER_INCORRECT_STATE` | +| Decimal | Hex | Name | +|-----------|-------|---------------------------------------------| +| 1027 | 0x403 | `BLE_ERROR_NO_CONNECTION_RECEIVED_CALLBACK` | +| 1028 | 0x404 | `BLE_ERROR_CENTRAL_UNSUBSCRIBED` | +| 1029 | 0x405 | `BLE_ERROR_GATT_SUBSCRIBE_FAILED` | +| 1030 | 0x406 | `BLE_ERROR_GATT_UNSUBSCRIBE_FAILED` | +| 1031 | 0x407 | `BLE_ERROR_GATT_WRITE_FAILED` | +| 1032 | 0x408 | `BLE_ERROR_GATT_INDICATE_FAILED` | +| 1035 | 0x40B | `BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT` | +| 1036 | 0x40C | `BLE_ERROR_REMOTE_DEVICE_DISCONNECTED` | +| 1037 | 0x40D | `BLE_ERROR_APP_CLOSED_CONNECTION` | +| 1039 | 0x40F | `BLE_ERROR_NOT_CHIP_DEVICE` | +| 1040 | 0x410 | `BLE_ERROR_INCOMPATIBLE_PROTOCOL_VERSIONS` | +| 1043 | 0x413 | `BLE_ERROR_INVALID_FRAGMENT_SIZE` | +| 1044 | 0x414 | `BLE_ERROR_START_TIMER_FAILED` | +| 1045 | 0x415 | `BLE_ERROR_CONNECT_TIMED_OUT` | +| 1046 | 0x416 | `BLE_ERROR_RECEIVE_TIMED_OUT` | +| 1047 | 0x417 | `BLE_ERROR_INVALID_MESSAGE` | +| 1048 | 0x418 | `BLE_ERROR_FRAGMENT_ACK_TIMED_OUT` | +| 1049 | 0x419 | `BLE_ERROR_KEEP_ALIVE_TIMED_OUT` | +| 1050 | 0x41A | `BLE_ERROR_NO_CONNECT_COMPLETE_CALLBACK` | +| 1051 | 0x41B | `BLE_ERROR_INVALID_ACK` | +| 1052 | 0x41C | `BLE_ERROR_REASSEMBLER_MISSING_DATA` | +| 1053 | 0x41D | `BLE_ERROR_INVALID_BTP_HEADER_FLAGS` | +| 1054 | 0x41E | `BLE_ERROR_INVALID_BTP_SEQUENCE_NUMBER` | +| 1055 | 0x41F | `BLE_ERROR_REASSEMBLER_INCORRECT_STATE` | ## IM Global errors errors -| Decimal | Hex | Name | -| ------- | ----- | -------------------------- | -| 1280 | 0x500 | `SUCCESS` | -| 1281 | 0x501 | `FAILURE` | -| 1405 | 0x57D | `INVALID_SUBSCRIPTION` | -| 1406 | 0x57E | `UNSUPPORTED_ACCESS` | -| 1407 | 0x57F | `UNSUPPORTED_ENDPOINT` | -| 1408 | 0x580 | `INVALID_ACTION` | -| 1409 | 0x581 | `UNSUPPORTED_COMMAND` | -| 1413 | 0x585 | `INVALID_COMMAND` | -| 1414 | 0x586 | `UNSUPPORTED_ATTRIBUTE` | -| 1415 | 0x587 | `CONSTRAINT_ERROR` | -| 1416 | 0x588 | `UNSUPPORTED_WRITE` | -| 1417 | 0x589 | `RESOURCE_EXHAUSTED` | -| 1419 | 0x58B | `NOT_FOUND` | -| 1420 | 0x58C | `UNREPORTABLE_ATTRIBUTE` | -| 1421 | 0x58D | `INVALID_DATA_TYPE` | -| 1423 | 0x58F | `UNSUPPORTED_READ` | -| 1426 | 0x592 | `DATA_VERSION_MISMATCH` | -| 1428 | 0x594 | `TIMEOUT` | -| 1436 | 0x59C | `BUSY` | -| 1475 | 0x5C3 | `UNSUPPORTED_CLUSTER` | -| 1477 | 0x5C5 | `NO_UPSTREAM_SUBSCRIPTION` | -| 1478 | 0x5C6 | `NEEDS_TIMED_INTERACTION` | -| 1479 | 0x5C7 | `UNSUPPORTED_EVENT` | -| 1480 | 0x5C8 | `PATHS_EXHAUSTED` | -| 1481 | 0x5C9 | `TIMED_REQUEST_MISMATCH` | -| 1482 | 0x5CA | `FAILSAFE_REQUIRED` | -| 1520 | 0x5F0 | `WRITE_IGNORED` | +| Decimal | Hex | Name | +|-----------|-------|----------------------------| +| 1280 | 0x500 | `SUCCESS` | +| 1281 | 0x501 | `FAILURE` | +| 1405 | 0x57D | `INVALID_SUBSCRIPTION` | +| 1406 | 0x57E | `UNSUPPORTED_ACCESS` | +| 1407 | 0x57F | `UNSUPPORTED_ENDPOINT` | +| 1408 | 0x580 | `INVALID_ACTION` | +| 1409 | 0x581 | `UNSUPPORTED_COMMAND` | +| 1413 | 0x585 | `INVALID_COMMAND` | +| 1414 | 0x586 | `UNSUPPORTED_ATTRIBUTE` | +| 1415 | 0x587 | `CONSTRAINT_ERROR` | +| 1416 | 0x588 | `UNSUPPORTED_WRITE` | +| 1417 | 0x589 | `RESOURCE_EXHAUSTED` | +| 1419 | 0x58B | `NOT_FOUND` | +| 1420 | 0x58C | `UNREPORTABLE_ATTRIBUTE` | +| 1421 | 0x58D | `INVALID_DATA_TYPE` | +| 1423 | 0x58F | `UNSUPPORTED_READ` | +| 1426 | 0x592 | `DATA_VERSION_MISMATCH` | +| 1428 | 0x594 | `TIMEOUT` | +| 1436 | 0x59C | `BUSY` | +| 1475 | 0x5C3 | `UNSUPPORTED_CLUSTER` | +| 1477 | 0x5C5 | `NO_UPSTREAM_SUBSCRIPTION` | +| 1478 | 0x5C6 | `NEEDS_TIMED_INTERACTION` | +| 1479 | 0x5C7 | `UNSUPPORTED_EVENT` | +| 1480 | 0x5C8 | `PATHS_EXHAUSTED` | +| 1481 | 0x5C9 | `TIMED_REQUEST_MISMATCH` | +| 1482 | 0x5CA | `FAILSAFE_REQUIRED` | +| 1483 | 0x5CB | `INVALID_IN_STATE` | +| 1520 | 0x5F0 | `WRITE_IGNORED` | + diff --git a/docs/clusters.md b/docs/clusters.md new file mode 100644 index 00000000000000..f7354001a9b069 --- /dev/null +++ b/docs/clusters.md @@ -0,0 +1,124 @@ + + +## List of currently defined clusters + +| Code (dec) | Code (hex) | Name | +| ---------- | ---------- | ------------------------------------------------------- | +| 3 | 0x03 | Identify | +| 4 | 0x04 | Groups | +| 5 | 0x05 | Scenes | +| 6 | 0x06 | OnOff | +| 7 | 0x07 | OnOffSwitchConfiguration | +| 8 | 0x08 | LevelControl | +| 15 | 0x0F | BinaryInputBasic | +| 28 | 0x1C | PulseWidthModulation | +| 29 | 0x1D | Descriptor | +| 30 | 0x1E | Binding | +| 31 | 0x1F | AccessControl | +| 37 | 0x25 | Actions | +| 40 | 0x28 | BasicInformation | +| 41 | 0x29 | OtaSoftwareUpdateProvider | +| 42 | 0x2A | OtaSoftwareUpdateRequestor | +| 43 | 0x2B | LocalizationConfiguration | +| 44 | 0x2C | TimeFormatLocalization | +| 45 | 0x2D | UnitLocalization | +| 46 | 0x2E | PowerSourceConfiguration | +| 47 | 0x2F | PowerSource | +| 48 | 0x30 | GeneralCommissioning | +| 49 | 0x31 | NetworkCommissioning | +| 50 | 0x32 | DiagnosticLogs | +| 51 | 0x33 | GeneralDiagnostics | +| 52 | 0x34 | SoftwareDiagnostics | +| 53 | 0x35 | ThreadNetworkDiagnostics | +| 54 | 0x36 | WiFiNetworkDiagnostics | +| 55 | 0x37 | EthernetNetworkDiagnostics | +| 56 | 0x38 | TimeSynchronization | +| 57 | 0x39 | BridgedDeviceBasicInformation | +| 59 | 0x3B | Switch | +| 60 | 0x3C | AdministratorCommissioning | +| 62 | 0x3E | OperationalCredentials | +| 63 | 0x3F | GroupKeyManagement | +| 64 | 0x40 | FixedLabel | +| 65 | 0x41 | UserLabel | +| 66 | 0x42 | ProxyConfiguration | +| 67 | 0x43 | ProxyDiscovery | +| 68 | 0x44 | ProxyValid | +| 69 | 0x45 | BooleanState | +| 70 | 0x46 | IcdManagement | +| 71 | 0x47 | Timer | +| 72 | 0x48 | OvenCavityOperationalState | +| 73 | 0x49 | OvenMode | +| 74 | 0x4A | LaundryDryerControls | +| 80 | 0x50 | ModeSelect | +| 81 | 0x51 | LaundryWasherMode | +| 82 | 0x52 | RefrigeratorAndTemperatureControlledCabinetMode | +| 83 | 0x53 | LaundryWasherControls | +| 84 | 0x54 | RvcRunMode | +| 85 | 0x55 | RvcCleanMode | +| 86 | 0x56 | TemperatureControl | +| 87 | 0x57 | RefrigeratorAlarm | +| 89 | 0x59 | DishwasherMode | +| 91 | 0x5B | AirQuality | +| 92 | 0x5C | SmokeCoAlarm | +| 93 | 0x5D | DishwasherAlarm | +| 94 | 0x5E | MicrowaveOvenMode | +| 95 | 0x5F | MicrowaveOvenControl | +| 96 | 0x60 | OperationalState | +| 97 | 0x61 | RvcOperationalState | +| 113 | 0x71 | HepaFilterMonitoring | +| 114 | 0x72 | ActivatedCarbonFilterMonitoring | +| 128 | 0x80 | BooleanSensorConfiguration | +| 129 | 0x81 | ValveConfigurationAndControl | +| 150 | 0x96 | DemandResponseLoadControl | +| 153 | 0x99 | EnergyEvse | +| 257 | 0x101 | DoorLock | +| 258 | 0x102 | WindowCovering | +| 259 | 0x103 | BarrierControl | +| 512 | 0x200 | PumpConfigurationAndControl | +| 513 | 0x201 | Thermostat | +| 514 | 0x202 | FanControl | +| 516 | 0x204 | ThermostatUserInterfaceConfiguration | +| 768 | 0x300 | ColorControl | +| 769 | 0x301 | BallastConfiguration | +| 1024 | 0x400 | IlluminanceMeasurement | +| 1026 | 0x402 | TemperatureMeasurement | +| 1027 | 0x403 | PressureMeasurement | +| 1028 | 0x404 | FlowMeasurement | +| 1029 | 0x405 | RelativeHumidityMeasurement | +| 1030 | 0x406 | OccupancySensing | +| 1036 | 0x40C | CarbonMonoxideConcentrationMeasurement | +| 1037 | 0x40D | CarbonDioxideConcentrationMeasurement | +| 1043 | 0x413 | NitrogenDioxideConcentrationMeasurement | +| 1045 | 0x415 | OzoneConcentrationMeasurement | +| 1066 | 0x42A | Pm25ConcentrationMeasurement | +| 1067 | 0x42B | FormaldehydeConcentrationMeasurement | +| 1068 | 0x42C | Pm1ConcentrationMeasurement | +| 1069 | 0x42D | Pm10ConcentrationMeasurement | +| 1070 | 0x42E | TotalVolatileOrganicCompoundsConcentrationMeasurement | +| 1071 | 0x42F | RadonConcentrationMeasurement | +| 1283 | 0x503 | WakeOnLan | +| 1284 | 0x504 | Channel | +| 1285 | 0x505 | TargetNavigator | +| 1286 | 0x506 | MediaPlayback | +| 1287 | 0x507 | MediaInput | +| 1288 | 0x508 | LowPower | +| 1289 | 0x509 | KeypadInput | +| 1290 | 0x50A | ContentLauncher | +| 1291 | 0x50B | AudioOutput | +| 1292 | 0x50C | ApplicationLauncher | +| 1293 | 0x50D | ApplicationBasic | +| 1294 | 0x50E | AccountLogin | +| 1295 | 0x50F | ContentControl | +| 1296 | 0x510 | ContentAppObserver | +| 2820 | 0xB04 | ElectricalMeasurement | +| 4294048773 | 0xFFF1FC05 | UnitTesting | +| 4294048774 | 0xFFF1FC06 | FaultInjection | +| 4294048800 | 0xFFF1FC20 | SampleMei | diff --git a/docs/index.md b/docs/index.md index c3200d13835fd4..f6575ed88a5d7c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,6 +17,7 @@ examples/index tools/index BUG_REPORT code_generation +clusters ERROR_CODES ``` diff --git a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter index 305e12ce3f335e..d73ebdd8a9dc66 100644 --- a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter +++ b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter @@ -634,13 +634,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -697,7 +697,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter index 5b6e3e88f39aca..c7e916af31e41c 100644 --- a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter +++ b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter @@ -634,13 +634,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/air-quality-sensor-app/telink/include/AppConfig.h b/examples/air-quality-sensor-app/telink/include/AppConfig.h index ec5c54343cf852..7513ed3771b961 100644 --- a/examples/air-quality-sensor-app/telink/include/AppConfig.h +++ b/examples/air-quality-sensor-app/telink/include/AppConfig.h @@ -25,4 +25,6 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif 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 945c9e89be638d..15cef48f6500c6 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 @@ -1763,13 +1763,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1826,7 +1826,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } @@ -5649,7 +5649,7 @@ internal cluster UnitTesting = 4294048773 { attribute int8s rangeRestrictedInt8s = 39; attribute int16u rangeRestrictedInt16u = 40; attribute int16s rangeRestrictedInt16s = 41; - attribute LONG_OCTET_STRING listLongOctetString[] = 42; + attribute long_octet_string listLongOctetString[] = 42; attribute TestFabricScoped listFabricScoped[] = 43; timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; diff --git a/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp b/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp index 3fde24f3817d04..e9f9dc1a171484 100644 --- a/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp +++ b/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp @@ -163,7 +163,7 @@ CHIP_ERROR AppTask::Init() if (rc != 0) { P6_LOG("boot_set_confirmed failed"); - appError(CHIP_ERROR_WELL_UNINITIALIZED); + appError(CHIP_ERROR_UNINITIALIZED); } #endif // Register the callback to init the MDNS server when connectivity is available diff --git a/examples/all-clusters-app/telink/include/AppConfig.h b/examples/all-clusters-app/telink/include/AppConfig.h index 0329fd5f8a4392..68263bbda460db 100644 --- a/examples/all-clusters-app/telink/include/AppConfig.h +++ b/examples/all-clusters-app/telink/include/AppConfig.h @@ -24,4 +24,6 @@ #define APP_USE_THREAD_START_BUTTON 1 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 1 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index 0cd9cbfdb5ad68..f9a695d21e6d8d 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -1643,13 +1643,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1706,7 +1706,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } @@ -3137,7 +3137,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; @@ -4270,6 +4270,12 @@ cluster WakeOnLan = 1283 { cluster Channel = 1284 { revision 1; // NOTE: Default/not specifically set + enum ChannelTypeEnum : enum8 { + kSatellite = 0; + kCable = 1; + kTerrestrial = 2; + } + enum LineupInfoTypeEnum : enum8 { kMSO = 0; } @@ -4283,6 +4289,29 @@ cluster Channel = 1284 { bitmap Feature : bitmap32 { kChannelList = 0x1; kLineupInfo = 0x2; + kElectronicGuide = 0x3; + kRecordProgram = 0x4; + } + + bitmap RecordingFlagBitmap : bitmap32 { + kScheduled = 0x1; + kRecordSeries = 0x2; + kRecorded = 0x3; + } + + struct ProgramCastStruct { + char_string name = 0; + char_string role = 1; + } + + struct ProgramCategoryStruct { + char_string category = 0; + optional char_string subCategory = 1; + } + + struct SeriesInfoStruct { + char_string season = 0; + char_string episode = 1; } struct ChannelInfoStruct { @@ -4291,6 +4320,46 @@ cluster Channel = 1284 { optional char_string name = 2; optional char_string callSign = 3; optional char_string affiliateCallSign = 4; + optional char_string identifier = 5; + optional ChannelTypeEnum type = 6; + } + + struct ProgramStruct { + char_string identifier = 0; + ChannelInfoStruct channel = 1; + epoch_s startTime = 2; + epoch_s endTime = 3; + char_string title = 4; + optional char_string subtitle = 5; + optional char_string description = 6; + optional char_string audioLanguages[] = 7; + optional char_string ratings[] = 8; + optional char_string thumbnailUrl = 9; + optional char_string posterArtUrl = 10; + optional char_string dvbiUrl = 11; + optional char_string releaseDate = 12; + optional char_string parentalGuidanceText = 13; + optional RecordingFlagBitmap recordingFlag = 14; + optional nullable SeriesInfoStruct seriesInfo = 15; + optional ProgramCategoryStruct categoryList[] = 16; + optional ProgramCastStruct castList[] = 17; + optional ProgramCastStruct externalIDList[] = 18; + } + + struct PageTokenStruct { + optional int16u limit = 0; + optional char_string after = 1; + optional char_string before = 2; + } + + struct ChannelPagingStruct { + optional nullable PageTokenStruct previousToken = 0; + optional nullable PageTokenStruct nextToken = 1; + } + + struct AdditionalInfoStruct { + char_string name = 0; + char_string value = 1; } struct LineupInfoStruct { @@ -4328,12 +4397,47 @@ cluster Channel = 1284 { int16s count = 0; } + request struct GetProgramGuideRequest { + optional epoch_s startTime = 0; + optional epoch_s endTime = 1; + optional ChannelInfoStruct channelList[] = 2; + optional PageTokenStruct pageToken = 3; + optional RecordingFlagBitmap recordingFlag = 4; + optional AdditionalInfoStruct externalIDList[] = 5; + optional octet_string data = 6; + } + + response struct ProgramGuideResponse = 5 { + int16s channelPagingStruct = 0; + ProgramStruct programList[] = 1; + } + + request struct RecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + + request struct CancelRecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + /** Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. */ command ChangeChannel(ChangeChannelRequest): ChangeChannelResponse = 0; /** Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. */ command ChangeChannelByNumber(ChangeChannelByNumberRequest): DefaultSuccess = 2; /** This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. */ command SkipChannel(SkipChannelRequest): DefaultSuccess = 3; + /** This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ + command GetProgramGuide(GetProgramGuideRequest): ProgramGuideResponse = 4; + /** Record a specific program or series when it goes live. This functionality enables DVR recording features. */ + command RecordProgram(RecordProgramRequest): DefaultSuccess = 6; + /** Cancel recording for a specific program or series. */ + command CancelRecordProgram(CancelRecordProgramRequest): DefaultSuccess = 7; } /** This cluster provides an interface for UX navigation within a set of targets on a device or endpoint. */ @@ -4351,6 +4455,12 @@ cluster TargetNavigator = 1285 { char_string name = 1; } + info event TargetUpdated = 0 { + TargetInfoStruct targetList[] = 0; + int8u currentTarget = 1; + octet_string data = 2; + } + readonly attribute TargetInfoStruct targetList[] = 0; readonly attribute optional int8u currentTarget = 1; readonly attribute command_id generatedCommandList[] = 65528; @@ -4378,6 +4488,27 @@ cluster TargetNavigator = 1285 { cluster MediaPlayback = 1286 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum PlaybackStateEnum : enum8 { kPlaying = 0; kPaused = 1; @@ -4397,6 +4528,19 @@ cluster MediaPlayback = 1286 { bitmap Feature : bitmap32 { kAdvancedSeek = 0x1; kVariableSpeed = 0x2; + kTextTracks = 0x3; + kAudioTracks = 0x4; + kAudioAdvance = 0x5; + } + + struct TrackAttributesStruct { + char_string<32> languageCode = 0; + optional nullable char_string displayName = 1; + } + + struct TrackStruct { + char_string<32> id = 0; + nullable TrackAttributesStruct trackAttributes = 1; } struct PlaybackPositionStruct { @@ -4404,6 +4548,18 @@ cluster MediaPlayback = 1286 { nullable int64u position = 1; } + info event StateChanged = 0 { + PlaybackStateEnum currentState = 0; + EPOCH_US startTime = 1; + INT64U duration = 2; + PlaybackPositionStruct sampledPosition = 3; + single playbackSpeed = 4; + INT64U seekRangeEnd = 5; + INT64U seekRangeStart = 6; + optional OCTET_STRING data = 7; + boolean audioAdvanceUnmuted = 8; + } + readonly attribute PlaybackStateEnum currentState = 0; readonly attribute optional nullable epoch_us startTime = 1; readonly attribute optional nullable int64u duration = 2; @@ -4411,6 +4567,10 @@ cluster MediaPlayback = 1286 { readonly attribute optional single playbackSpeed = 4; readonly attribute optional nullable int64u seekRangeEnd = 5; readonly attribute optional nullable int64u seekRangeStart = 6; + readonly attribute optional nullable TrackStruct activeAudioTrack = 7; + readonly attribute optional nullable TrackStruct availableAudioTracks[] = 8; + readonly attribute optional nullable TrackStruct activeTextTrack = 9; + readonly attribute optional nullable TrackStruct availableTextTracks[] = 10; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -4418,6 +4578,14 @@ cluster MediaPlayback = 1286 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct RewindRequest { + optional boolean audioAdvanceUnmuted = 0; + } + + request struct FastForwardRequest { + optional boolean audioAdvanceUnmuted = 0; + } + request struct SkipForwardRequest { int64u deltaPositionMilliseconds = 0; } @@ -4435,6 +4603,15 @@ cluster MediaPlayback = 1286 { int64u position = 0; } + request struct ActivateAudioTrackRequest { + CHAR_STRING trackID = 0; + INT8U audioOutputIndex = 1; + } + + request struct ActivateTextTrackRequest { + CHAR_STRING trackID = 0; + } + /** Upon receipt, this SHALL play media. */ command Play(): PlaybackResponse = 0; /** Upon receipt, this SHALL pause media. */ @@ -4448,15 +4625,21 @@ cluster MediaPlayback = 1286 { /** Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. */ command Next(): PlaybackResponse = 5; /** Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command Rewind(): PlaybackResponse = 6; + command Rewind(RewindRequest): PlaybackResponse = 6; /** Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command FastForward(): PlaybackResponse = 7; + command FastForward(FastForwardRequest): PlaybackResponse = 7; /** Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: */ command SkipForward(SkipForwardRequest): PlaybackResponse = 8; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command SkipBackward(SkipBackwardRequest): PlaybackResponse = 9; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command Seek(SeekRequest): PlaybackResponse = 11; + /** Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. */ + command ActivateAudioTrack(ActivateAudioTrackRequest): DefaultSuccess = 12; + /** Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. */ + command ActivateTextTrack(ActivateTextTrackRequest): DefaultSuccess = 13; + /** If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. */ + command DeactivateTextTrack(): DefaultSuccess = 14; } /** This cluster provides an interface for controlling the Input Selector on a media device such as a TV. */ @@ -4660,6 +4843,27 @@ cluster KeypadInput = 1289 { cluster ContentLauncher = 1290 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum MetricTypeEnum : enum8 { kPixels = 0; kPercentage = 1; @@ -4680,22 +4884,31 @@ cluster ContentLauncher = 1290 { kSportsTeam = 11; kType = 12; kVideo = 13; + kSeason = 14; + kEpisode = 15; + kAny = 16; } enum StatusEnum : enum8 { kSuccess = 0; kURLNotAvailable = 1; kAuthFailed = 2; + kTextTrackNotAvailable = 3; + kAudioTrackNotAvailable = 4; } bitmap Feature : bitmap32 { kContentSearch = 0x1; kURLPlayback = 0x2; + kAdvancedSeek = 0x3; + kTextTracks = 0x4; + kAudioTracks = 0x5; } bitmap SupportedProtocolsBitmap : bitmap32 { kDASH = 0x1; kHLS = 0x2; + kWebRTC = 0x2; } struct DimensionStruct { @@ -4704,6 +4917,18 @@ cluster ContentLauncher = 1290 { MetricTypeEnum metric = 2; } + struct TrackPreferenceStruct { + char_string<32> languageCode = 0; + optional CharacteristicEnum characteristics[] = 1; + int8u audioOutputIndex = 2; + } + + struct PlaybackPreferencesStruct { + int64u playbackPosition = 0; + TrackPreferenceStruct textTrack = 1; + optional TrackPreferenceStruct audioTracks[] = 2; + } + struct AdditionalInfoStruct { char_string<256> name = 0; char_string<8192> value = 1; @@ -4747,6 +4972,8 @@ cluster ContentLauncher = 1290 { ContentSearchStruct search = 0; boolean autoPlay = 1; optional char_string data = 2; + optional PlaybackPreferencesStruct playbackPreferences = 3; + optional boolean useCurrentContext = 4; } request struct LaunchURLRequest { @@ -4908,6 +5135,10 @@ cluster ApplicationBasic = 1293 { cluster AccountLogin = 1294 { revision 1; // NOTE: Default/not specifically set + critical event LoggedOut = 0 { + optional node_id node = 0; + } + readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -4926,6 +5157,11 @@ cluster AccountLogin = 1294 { request struct LoginRequest { char_string<100> tempAccountIdentifier = 0; char_string setupPIN = 1; + optional node_id node = 2; + } + + request struct LogoutRequest { + optional node_id node = 0; } /** Upon receipt, the Content App checks if the account associated with the client Temp Account Identifier Rotating ID is the same acount that is active on the given Content App. If the accounts are the same, then the Content App includes the Setup PIN in the GetSetupPIN Response. */ @@ -4933,7 +5169,7 @@ cluster AccountLogin = 1294 { /** Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. */ fabric timed command access(invoke: administer) Login(LoginRequest): DefaultSuccess = 2; /** The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. */ - fabric timed command Logout(): DefaultSuccess = 3; + fabric timed command Logout(LogoutRequest): DefaultSuccess = 3; } /** The Test Cluster is meant to validate the generated code */ @@ -5098,7 +5334,7 @@ internal cluster UnitTesting = 4294048773 { attribute int8s rangeRestrictedInt8s = 39; attribute int16u rangeRestrictedInt16u = 40; attribute int16s rangeRestrictedInt16s = 41; - attribute LONG_OCTET_STRING listLongOctetString[] = 42; + attribute long_octet_string listLongOctetString[] = 42; attribute TestFabricScoped listFabricScoped[] = 43; timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; diff --git a/examples/all-clusters-minimal-app/infineon/psoc6/src/AppTask.cpp b/examples/all-clusters-minimal-app/infineon/psoc6/src/AppTask.cpp index efbbb4af9ec705..3fcbc365fbc426 100644 --- a/examples/all-clusters-minimal-app/infineon/psoc6/src/AppTask.cpp +++ b/examples/all-clusters-minimal-app/infineon/psoc6/src/AppTask.cpp @@ -160,7 +160,7 @@ CHIP_ERROR AppTask::Init() if (rc != 0) { P6_LOG("boot_set_confirmed failed"); - appError(CHIP_ERROR_WELL_UNINITIALIZED); + appError(CHIP_ERROR_UNINITIALIZED); } #endif // Register the callback to init the MDNS server when connectivity is available diff --git a/examples/all-clusters-minimal-app/telink/include/AppConfig.h b/examples/all-clusters-minimal-app/telink/include/AppConfig.h index 7cd1d6e62a3fc7..5ef62e04203e1b 100644 --- a/examples/all-clusters-minimal-app/telink/include/AppConfig.h +++ b/examples/all-clusters-minimal-app/telink/include/AppConfig.h @@ -25,4 +25,3 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 0 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 1 -#define APP_USE_IDENTIFY_PWM 0 diff --git a/examples/bridge-app/bridge-common/bridge-app.matter b/examples/bridge-app/bridge-common/bridge-app.matter index 6d2ec93be95ad0..3c836ed07ffb37 100644 --- a/examples/bridge-app/bridge-common/bridge-app.matter +++ b/examples/bridge-app/bridge-common/bridge-app.matter @@ -1035,13 +1035,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1098,7 +1098,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/bridge-app/telink/include/AppConfig.h b/examples/bridge-app/telink/include/AppConfig.h index 15a358a2920abe..e5e26efb2871d1 100644 --- a/examples/bridge-app/telink/include/AppConfig.h +++ b/examples/bridge-app/telink/include/AppConfig.h @@ -25,4 +25,6 @@ #define APP_USE_THREAD_START_BUTTON 1 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif diff --git a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter index 2d78ad3dccd074..88ec64bfb0b86d 100644 --- a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter @@ -871,7 +871,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter index 4480831edafc1c..8a22d48b7236db 100644 --- a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter +++ b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter @@ -557,13 +557,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -620,7 +620,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter index 89d807ddc3cd55..2aa12d5374c50e 100644 --- a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter +++ b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter @@ -693,13 +693,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -756,7 +756,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter index 133f2c707b5889..e3da1bf7d4c4ef 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter @@ -715,13 +715,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -778,7 +778,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } @@ -1230,6 +1230,12 @@ cluster WakeOnLan = 1283 { cluster Channel = 1284 { revision 1; // NOTE: Default/not specifically set + enum ChannelTypeEnum : enum8 { + kSatellite = 0; + kCable = 1; + kTerrestrial = 2; + } + enum LineupInfoTypeEnum : enum8 { kMSO = 0; } @@ -1243,6 +1249,29 @@ cluster Channel = 1284 { bitmap Feature : bitmap32 { kChannelList = 0x1; kLineupInfo = 0x2; + kElectronicGuide = 0x3; + kRecordProgram = 0x4; + } + + bitmap RecordingFlagBitmap : bitmap32 { + kScheduled = 0x1; + kRecordSeries = 0x2; + kRecorded = 0x3; + } + + struct ProgramCastStruct { + char_string name = 0; + char_string role = 1; + } + + struct ProgramCategoryStruct { + char_string category = 0; + optional char_string subCategory = 1; + } + + struct SeriesInfoStruct { + char_string season = 0; + char_string episode = 1; } struct ChannelInfoStruct { @@ -1251,6 +1280,46 @@ cluster Channel = 1284 { optional char_string name = 2; optional char_string callSign = 3; optional char_string affiliateCallSign = 4; + optional char_string identifier = 5; + optional ChannelTypeEnum type = 6; + } + + struct ProgramStruct { + char_string identifier = 0; + ChannelInfoStruct channel = 1; + epoch_s startTime = 2; + epoch_s endTime = 3; + char_string title = 4; + optional char_string subtitle = 5; + optional char_string description = 6; + optional char_string audioLanguages[] = 7; + optional char_string ratings[] = 8; + optional char_string thumbnailUrl = 9; + optional char_string posterArtUrl = 10; + optional char_string dvbiUrl = 11; + optional char_string releaseDate = 12; + optional char_string parentalGuidanceText = 13; + optional RecordingFlagBitmap recordingFlag = 14; + optional nullable SeriesInfoStruct seriesInfo = 15; + optional ProgramCategoryStruct categoryList[] = 16; + optional ProgramCastStruct castList[] = 17; + optional ProgramCastStruct externalIDList[] = 18; + } + + struct PageTokenStruct { + optional int16u limit = 0; + optional char_string after = 1; + optional char_string before = 2; + } + + struct ChannelPagingStruct { + optional nullable PageTokenStruct previousToken = 0; + optional nullable PageTokenStruct nextToken = 1; + } + + struct AdditionalInfoStruct { + char_string name = 0; + char_string value = 1; } struct LineupInfoStruct { @@ -1288,12 +1357,47 @@ cluster Channel = 1284 { int16s count = 0; } + request struct GetProgramGuideRequest { + optional epoch_s startTime = 0; + optional epoch_s endTime = 1; + optional ChannelInfoStruct channelList[] = 2; + optional PageTokenStruct pageToken = 3; + optional RecordingFlagBitmap recordingFlag = 4; + optional AdditionalInfoStruct externalIDList[] = 5; + optional octet_string data = 6; + } + + response struct ProgramGuideResponse = 5 { + int16s channelPagingStruct = 0; + ProgramStruct programList[] = 1; + } + + request struct RecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + + request struct CancelRecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + /** Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. */ command ChangeChannel(ChangeChannelRequest): ChangeChannelResponse = 0; /** Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. */ command ChangeChannelByNumber(ChangeChannelByNumberRequest): DefaultSuccess = 2; /** This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. */ command SkipChannel(SkipChannelRequest): DefaultSuccess = 3; + /** This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ + command GetProgramGuide(GetProgramGuideRequest): ProgramGuideResponse = 4; + /** Record a specific program or series when it goes live. This functionality enables DVR recording features. */ + command RecordProgram(RecordProgramRequest): DefaultSuccess = 6; + /** Cancel recording for a specific program or series. */ + command CancelRecordProgram(CancelRecordProgramRequest): DefaultSuccess = 7; } /** This cluster provides an interface for UX navigation within a set of targets on a device or endpoint. */ @@ -1311,6 +1415,12 @@ cluster TargetNavigator = 1285 { char_string name = 1; } + info event TargetUpdated = 0 { + TargetInfoStruct targetList[] = 0; + int8u currentTarget = 1; + octet_string data = 2; + } + readonly attribute TargetInfoStruct targetList[] = 0; readonly attribute optional int8u currentTarget = 1; readonly attribute command_id generatedCommandList[] = 65528; @@ -1338,6 +1448,27 @@ cluster TargetNavigator = 1285 { cluster MediaPlayback = 1286 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum PlaybackStateEnum : enum8 { kPlaying = 0; kPaused = 1; @@ -1357,6 +1488,19 @@ cluster MediaPlayback = 1286 { bitmap Feature : bitmap32 { kAdvancedSeek = 0x1; kVariableSpeed = 0x2; + kTextTracks = 0x3; + kAudioTracks = 0x4; + kAudioAdvance = 0x5; + } + + struct TrackAttributesStruct { + char_string<32> languageCode = 0; + optional nullable char_string displayName = 1; + } + + struct TrackStruct { + char_string<32> id = 0; + nullable TrackAttributesStruct trackAttributes = 1; } struct PlaybackPositionStruct { @@ -1364,6 +1508,18 @@ cluster MediaPlayback = 1286 { nullable int64u position = 1; } + info event StateChanged = 0 { + PlaybackStateEnum currentState = 0; + EPOCH_US startTime = 1; + INT64U duration = 2; + PlaybackPositionStruct sampledPosition = 3; + single playbackSpeed = 4; + INT64U seekRangeEnd = 5; + INT64U seekRangeStart = 6; + optional OCTET_STRING data = 7; + boolean audioAdvanceUnmuted = 8; + } + readonly attribute PlaybackStateEnum currentState = 0; readonly attribute optional nullable epoch_us startTime = 1; readonly attribute optional nullable int64u duration = 2; @@ -1371,6 +1527,10 @@ cluster MediaPlayback = 1286 { readonly attribute optional single playbackSpeed = 4; readonly attribute optional nullable int64u seekRangeEnd = 5; readonly attribute optional nullable int64u seekRangeStart = 6; + readonly attribute optional nullable TrackStruct activeAudioTrack = 7; + readonly attribute optional nullable TrackStruct availableAudioTracks[] = 8; + readonly attribute optional nullable TrackStruct activeTextTrack = 9; + readonly attribute optional nullable TrackStruct availableTextTracks[] = 10; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1378,6 +1538,14 @@ cluster MediaPlayback = 1286 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct RewindRequest { + optional boolean audioAdvanceUnmuted = 0; + } + + request struct FastForwardRequest { + optional boolean audioAdvanceUnmuted = 0; + } + request struct SkipForwardRequest { int64u deltaPositionMilliseconds = 0; } @@ -1395,6 +1563,15 @@ cluster MediaPlayback = 1286 { int64u position = 0; } + request struct ActivateAudioTrackRequest { + CHAR_STRING trackID = 0; + INT8U audioOutputIndex = 1; + } + + request struct ActivateTextTrackRequest { + CHAR_STRING trackID = 0; + } + /** Upon receipt, this SHALL play media. */ command Play(): PlaybackResponse = 0; /** Upon receipt, this SHALL pause media. */ @@ -1408,15 +1585,21 @@ cluster MediaPlayback = 1286 { /** Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. */ command Next(): PlaybackResponse = 5; /** Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command Rewind(): PlaybackResponse = 6; + command Rewind(RewindRequest): PlaybackResponse = 6; /** Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command FastForward(): PlaybackResponse = 7; + command FastForward(FastForwardRequest): PlaybackResponse = 7; /** Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: */ command SkipForward(SkipForwardRequest): PlaybackResponse = 8; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command SkipBackward(SkipBackwardRequest): PlaybackResponse = 9; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command Seek(SeekRequest): PlaybackResponse = 11; + /** Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. */ + command ActivateAudioTrack(ActivateAudioTrackRequest): DefaultSuccess = 12; + /** Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. */ + command ActivateTextTrack(ActivateTextTrackRequest): DefaultSuccess = 13; + /** If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. */ + command DeactivateTextTrack(): DefaultSuccess = 14; } /** This cluster provides an interface for controlling the Input Selector on a media device such as a TV. */ diff --git a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter index 04e8702dcc7970..d2dc6330fc8cab 100644 --- a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter +++ b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter @@ -908,13 +908,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -971,7 +971,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter index ea7762a72d9078..cab46f88570baa 100644 --- a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter +++ b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter index 7729d21e1835f2..e9e2c6c7592cb0 100644 --- a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter @@ -988,13 +988,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1051,7 +1051,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter index de4f3ae4511c28..f2d76d87a642cd 100644 --- a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter +++ b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter @@ -565,13 +565,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter index 3ee6c4e2252611..4c9c2220548a96 100644 --- a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter +++ b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } @@ -1838,7 +1838,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; diff --git a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter index 363b3c281c41b1..b153dab715acd1 100644 --- a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter +++ b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter @@ -988,13 +988,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1051,7 +1051,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter index 53f08939f0884d..7dc61754445396 100644 --- a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter +++ b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter @@ -770,13 +770,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -833,7 +833,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter index 88ec2c996d8c05..ce3c0238cfd6e2 100644 --- a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter +++ b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter index df0ca20bc46c18..38b82e1514b9b4 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter @@ -480,13 +480,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -543,7 +543,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter index 3854901bf6842b..573c76f03d23c5 100644 --- a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter +++ b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter @@ -988,13 +988,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1051,7 +1051,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter index 957c82ce56998c..bc782020810768 100644 --- a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter +++ b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter index 284bd571b7ee81..52ac204c0638e0 100644 --- a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter +++ b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter @@ -565,13 +565,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter index 597d57f8fe40cb..f67589562ab69e 100644 --- a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter +++ b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter index 6886beaf5c2689..e732bdcdb61128 100644 --- a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter +++ b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter index f2b2146970c0ec..e4765c2c421817 100644 --- a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter +++ b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter @@ -988,13 +988,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1051,7 +1051,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_onofflight_samplemei.matter b/examples/chef/devices/rootnode_onofflight_samplemei.matter index edcb450041aa11..8ba32e0a35e1cc 100644 --- a/examples/chef/devices/rootnode_onofflight_samplemei.matter +++ b/examples/chef/devices/rootnode_onofflight_samplemei.matter @@ -988,13 +988,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1051,7 +1051,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter index d83eda8632d485..dbece9b40c3e10 100644 --- a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter +++ b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter @@ -935,13 +935,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -998,7 +998,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter index 9e8a02aa2028a0..42cb4ab553d92d 100644 --- a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter +++ b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter @@ -863,13 +863,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -926,7 +926,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter index 01c9744ac3fd3c..fd9316e307662b 100644 --- a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter +++ b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_pump_5f904818cc.matter b/examples/chef/devices/rootnode_pump_5f904818cc.matter index 210a87ccb22298..665ee013541b77 100644 --- a/examples/chef/devices/rootnode_pump_5f904818cc.matter +++ b/examples/chef/devices/rootnode_pump_5f904818cc.matter @@ -637,13 +637,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/chef/devices/rootnode_pump_a811bb33a0.matter b/examples/chef/devices/rootnode_pump_a811bb33a0.matter index 319f858806555b..0800e7f48d9e37 100644 --- a/examples/chef/devices/rootnode_pump_a811bb33a0.matter +++ b/examples/chef/devices/rootnode_pump_a811bb33a0.matter @@ -637,13 +637,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter index beefeb5829ddf4..bd1afd187a18a0 100644 --- a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter +++ b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter @@ -565,13 +565,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter index ea81b8089e311b..761967b72943c8 100644 --- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter +++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter @@ -557,13 +557,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -620,7 +620,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter index 0984abb57bd51b..96d1c16d25be15 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter @@ -629,13 +629,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -692,7 +692,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter index 612735364136de..71bcbbca8aabea 100644 --- a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter +++ b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter @@ -816,13 +816,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -879,7 +879,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter index 0f5ee3ec4ff373..87b796ebcd61b4 100644 --- a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter +++ b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter @@ -911,13 +911,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -974,7 +974,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter index 8644cd6e2aa03c..60b66ad5041e6d 100644 --- a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter +++ b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter index 385d293467e24b..cce209d5335ea8 100644 --- a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter +++ b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter index 64f392d852f6de..dc780e8a0f143c 100644 --- a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter +++ b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter @@ -791,13 +791,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -854,7 +854,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/chef/telink/include/AppConfig.h b/examples/chef/telink/include/AppConfig.h index e5c7b0417ef160..b3092856c49902 100644 --- a/examples/chef/telink/include/AppConfig.h +++ b/examples/chef/telink/include/AppConfig.h @@ -25,4 +25,3 @@ #define APP_USE_THREAD_START_BUTTON 1 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 -#define APP_USE_IDENTIFY_PWM 0 diff --git a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter index 88f2e69451d66e..9a2dfc6cc1fb2a 100644 --- a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter +++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter @@ -770,13 +770,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -833,7 +833,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/contact-sensor-app/telink/include/AppConfig.h b/examples/contact-sensor-app/telink/include/AppConfig.h index bd38d80b41282d..feb2b82d7417fc 100644 --- a/examples/contact-sensor-app/telink/include/AppConfig.h +++ b/examples/contact-sensor-app/telink/include/AppConfig.h @@ -24,4 +24,6 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif diff --git a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter index b38dd1bfe0aafc..64c2805b091c4f 100644 --- a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter +++ b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter @@ -663,13 +663,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter index 6c204fd29a4db8..f77f86517cc047 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter @@ -1106,13 +1106,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1169,7 +1169,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/light-switch-app/telink/include/AppConfig.h b/examples/light-switch-app/telink/include/AppConfig.h index 3ee892f2494bad..8258f39573039c 100644 --- a/examples/light-switch-app/telink/include/AppConfig.h +++ b/examples/light-switch-app/telink/include/AppConfig.h @@ -25,4 +25,6 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter index b0926fb67024af..4e46da63b54a5d 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter @@ -967,13 +967,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1030,7 +1030,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter index a57bd7306e4663..9709aeb9f2cd02 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter @@ -967,13 +967,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1030,7 +1030,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter index d40a42e99b8752..4ac2b49a0dbce1 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter @@ -967,13 +967,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1030,7 +1030,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/lighting-app/infineon/psoc6/src/AppTask.cpp b/examples/lighting-app/infineon/psoc6/src/AppTask.cpp index 987213e84073e1..2315086b246594 100644 --- a/examples/lighting-app/infineon/psoc6/src/AppTask.cpp +++ b/examples/lighting-app/infineon/psoc6/src/AppTask.cpp @@ -177,7 +177,7 @@ CHIP_ERROR AppTask::Init() if (rc != 0) { P6_LOG("boot_set_confirmed failed"); - appError(CHIP_ERROR_WELL_UNINITIALIZED); + appError(CHIP_ERROR_UNINITIALIZED); } #endif // Register the callback to init the MDNS server when connectivity is available diff --git a/examples/lighting-app/lighting-common/lighting-app.matter b/examples/lighting-app/lighting-common/lighting-app.matter index b60127c5728b4e..cf916ead11f73e 100644 --- a/examples/lighting-app/lighting-common/lighting-app.matter +++ b/examples/lighting-app/lighting-common/lighting-app.matter @@ -1160,13 +1160,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1223,7 +1223,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.matter b/examples/lighting-app/nxp/zap/lighting-on-off.matter index 0003dd40b4fa46..67684e8049af17 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.matter +++ b/examples/lighting-app/nxp/zap/lighting-on-off.matter @@ -908,13 +908,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/lighting-app/qpg/zap/light.matter b/examples/lighting-app/qpg/zap/light.matter index b1b05de8c97f12..a3739105d0654d 100644 --- a/examples/lighting-app/qpg/zap/light.matter +++ b/examples/lighting-app/qpg/zap/light.matter @@ -908,13 +908,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -971,7 +971,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter index 1dba6f81f7ad56..89a6868e1f7b95 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter @@ -1419,13 +1419,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1482,7 +1482,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter index f2dfca3f1353b1..ba983a58a34e57 100644 --- a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter @@ -1419,13 +1419,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1482,7 +1482,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/lighting-app/telink/include/AppConfig.h b/examples/lighting-app/telink/include/AppConfig.h index e677ba3a2ef7db..b616746393ff03 100644 --- a/examples/lighting-app/telink/include/AppConfig.h +++ b/examples/lighting-app/telink/include/AppConfig.h @@ -25,7 +25,9 @@ #define APP_USE_THREAD_START_BUTTON 1 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif // Lighting LED config #define USE_RGB_PWM 0 diff --git a/examples/lighting-app/telink/include/AppTask.h b/examples/lighting-app/telink/include/AppTask.h index 764cb209505a82..67b69ef84e2e45 100644 --- a/examples/lighting-app/telink/include/AppTask.h +++ b/examples/lighting-app/telink/include/AppTask.h @@ -19,6 +19,7 @@ #pragma once #include "AppTaskCommon.h" +#include "PWMDevice.h" class AppTask : public AppTaskCommon { diff --git a/examples/lighting-app/telink/src/AppTask.cpp b/examples/lighting-app/telink/src/AppTask.cpp index 7dbb9e1aac2102..fde4a836c90886 100644 --- a/examples/lighting-app/telink/src/AppTask.cpp +++ b/examples/lighting-app/telink/src/AppTask.cpp @@ -30,10 +30,10 @@ namespace { #ifdef CONFIG_WS2812_STRIP const struct device * const ws2812_dev = DEVICE_DT_GET(DT_ALIAS(led_strip)); #else -const struct pwm_dt_spec sPwmRgbSpecBlueLed = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0)); +const struct pwm_dt_spec sPwmRgbSpecBlueLed = PWM_DT_SPEC_GET_OR(DT_ALIAS(pwm_led0), {}); #if USE_RGB_PWM -const struct pwm_dt_spec sPwmRgbSpecGreenLed = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led1)); -const struct pwm_dt_spec sPwmRgbSpecRedLed = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led2)); +const struct pwm_dt_spec sPwmRgbSpecGreenLed = PWM_DT_SPEC_GET_OR(DT_ALIAS(pwm_led1), {}); +const struct pwm_dt_spec sPwmRgbSpecRedLed = PWM_DT_SPEC_GET_OR(DT_ALIAS(pwm_led2), {}); #endif #endif // CONFIG_WS2812_STRIP diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter index 60b6d81a531006..a11ae73b013a70 100644 --- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter +++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter @@ -660,13 +660,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/lock-app/infineon/psoc6/src/AppTask.cpp b/examples/lock-app/infineon/psoc6/src/AppTask.cpp index ea8ae2417e55b7..e3be287e024442 100644 --- a/examples/lock-app/infineon/psoc6/src/AppTask.cpp +++ b/examples/lock-app/infineon/psoc6/src/AppTask.cpp @@ -282,7 +282,7 @@ void AppTask::Init() if (rc != 0) { P6_LOG("boot_set_confirmed failed"); - appError(CHIP_ERROR_WELL_UNINITIALIZED); + appError(CHIP_ERROR_UNINITIALIZED); } #endif // Initialise WSTK buttons PB0 and PB1 (including debounce). diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index ec76655cded197..5eaa5c3eaeb6a6 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -936,13 +936,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -999,7 +999,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } @@ -2365,7 +2365,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; diff --git a/examples/lock-app/nxp/zap/lock-app.matter b/examples/lock-app/nxp/zap/lock-app.matter index 4caa02dcc3183e..7fdfe292c4b946 100644 --- a/examples/lock-app/nxp/zap/lock-app.matter +++ b/examples/lock-app/nxp/zap/lock-app.matter @@ -480,13 +480,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1627,7 +1627,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter index 79b2c29cbc1259..b8cae3d18b0a79 100644 --- a/examples/lock-app/qpg/zap/lock.matter +++ b/examples/lock-app/qpg/zap/lock.matter @@ -711,13 +711,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -774,7 +774,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } @@ -2021,7 +2021,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; diff --git a/examples/lock-app/telink/include/AppConfig.h b/examples/lock-app/telink/include/AppConfig.h index f4b55ec79564af..05bbd6afa79d46 100644 --- a/examples/lock-app/telink/include/AppConfig.h +++ b/examples/lock-app/telink/include/AppConfig.h @@ -34,4 +34,6 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif diff --git a/examples/log-source-app/log-source-common/log-source-app.matter b/examples/log-source-app/log-source-common/log-source-app.matter index cefb45b48434d3..c73d26c06662dd 100644 --- a/examples/log-source-app/log-source-common/log-source-app.matter +++ b/examples/log-source-app/log-source-common/log-source-app.matter @@ -300,13 +300,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -363,7 +363,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/network-manager-app/network-manager-common/network-manager-app.matter b/examples/network-manager-app/network-manager-common/network-manager-app.matter index a91e5664fcf32e..39ff5ab68cc720 100644 --- a/examples/network-manager-app/network-manager-common/network-manager-app.matter +++ b/examples/network-manager-app/network-manager-common/network-manager-app.matter @@ -480,13 +480,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter b/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter index ce2ebcf6c7cbcc..d67ea9cbd61669 100644 --- a/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter +++ b/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter @@ -640,13 +640,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter index fa9e65e16d2ad9..7325efd9f6400a 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter @@ -842,13 +842,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/ota-requestor-app/telink/include/AppConfig.h b/examples/ota-requestor-app/telink/include/AppConfig.h index 9cda66df104ff7..05e62e8b612725 100644 --- a/examples/ota-requestor-app/telink/include/AppConfig.h +++ b/examples/ota-requestor-app/telink/include/AppConfig.h @@ -25,4 +25,6 @@ #define APP_USE_THREAD_START_BUTTON 1 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 1 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 7a7065331795e0..839a1e0e525597 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -1827,13 +1827,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -3731,7 +3731,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; @@ -4353,7 +4353,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; @@ -5900,6 +5900,12 @@ cluster OccupancySensing = 1030 { cluster Channel = 1284 { revision 1; // NOTE: Default/not specifically set + enum ChannelTypeEnum : enum8 { + kSatellite = 0; + kCable = 1; + kTerrestrial = 2; + } + enum LineupInfoTypeEnum : enum8 { kMSO = 0; } @@ -5913,6 +5919,29 @@ cluster Channel = 1284 { bitmap Feature : bitmap32 { kChannelList = 0x1; kLineupInfo = 0x2; + kElectronicGuide = 0x3; + kRecordProgram = 0x4; + } + + bitmap RecordingFlagBitmap : bitmap32 { + kScheduled = 0x1; + kRecordSeries = 0x2; + kRecorded = 0x3; + } + + struct ProgramCastStruct { + char_string name = 0; + char_string role = 1; + } + + struct ProgramCategoryStruct { + char_string category = 0; + optional char_string subCategory = 1; + } + + struct SeriesInfoStruct { + char_string season = 0; + char_string episode = 1; } struct ChannelInfoStruct { @@ -5921,6 +5950,46 @@ cluster Channel = 1284 { optional char_string name = 2; optional char_string callSign = 3; optional char_string affiliateCallSign = 4; + optional char_string identifier = 5; + optional ChannelTypeEnum type = 6; + } + + struct ProgramStruct { + char_string identifier = 0; + ChannelInfoStruct channel = 1; + epoch_s startTime = 2; + epoch_s endTime = 3; + char_string title = 4; + optional char_string subtitle = 5; + optional char_string description = 6; + optional char_string audioLanguages[] = 7; + optional char_string ratings[] = 8; + optional char_string thumbnailUrl = 9; + optional char_string posterArtUrl = 10; + optional char_string dvbiUrl = 11; + optional char_string releaseDate = 12; + optional char_string parentalGuidanceText = 13; + optional RecordingFlagBitmap recordingFlag = 14; + optional nullable SeriesInfoStruct seriesInfo = 15; + optional ProgramCategoryStruct categoryList[] = 16; + optional ProgramCastStruct castList[] = 17; + optional ProgramCastStruct externalIDList[] = 18; + } + + struct PageTokenStruct { + optional int16u limit = 0; + optional char_string after = 1; + optional char_string before = 2; + } + + struct ChannelPagingStruct { + optional nullable PageTokenStruct previousToken = 0; + optional nullable PageTokenStruct nextToken = 1; + } + + struct AdditionalInfoStruct { + char_string name = 0; + char_string value = 1; } struct LineupInfoStruct { @@ -5958,18 +6027,59 @@ cluster Channel = 1284 { int16s count = 0; } + request struct GetProgramGuideRequest { + optional epoch_s startTime = 0; + optional epoch_s endTime = 1; + optional ChannelInfoStruct channelList[] = 2; + optional PageTokenStruct pageToken = 3; + optional RecordingFlagBitmap recordingFlag = 4; + optional AdditionalInfoStruct externalIDList[] = 5; + optional octet_string data = 6; + } + + response struct ProgramGuideResponse = 5 { + int16s channelPagingStruct = 0; + ProgramStruct programList[] = 1; + } + + request struct RecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + + request struct CancelRecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + /** Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. */ command ChangeChannel(ChangeChannelRequest): ChangeChannelResponse = 0; /** Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. */ command ChangeChannelByNumber(ChangeChannelByNumberRequest): DefaultSuccess = 2; /** This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. */ command SkipChannel(SkipChannelRequest): DefaultSuccess = 3; + /** This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ + command GetProgramGuide(GetProgramGuideRequest): ProgramGuideResponse = 4; + /** Record a specific program or series when it goes live. This functionality enables DVR recording features. */ + command RecordProgram(RecordProgramRequest): DefaultSuccess = 6; + /** Cancel recording for a specific program or series. */ + command CancelRecordProgram(CancelRecordProgramRequest): DefaultSuccess = 7; } /** This cluster provides an interface for controlling the current Channel on a device. */ cluster Channel = 1284 { revision 1; // NOTE: Default/not specifically set + enum ChannelTypeEnum : enum8 { + kSatellite = 0; + kCable = 1; + kTerrestrial = 2; + } + enum LineupInfoTypeEnum : enum8 { kMSO = 0; } @@ -5983,6 +6093,29 @@ cluster Channel = 1284 { bitmap Feature : bitmap32 { kChannelList = 0x1; kLineupInfo = 0x2; + kElectronicGuide = 0x3; + kRecordProgram = 0x4; + } + + bitmap RecordingFlagBitmap : bitmap32 { + kScheduled = 0x1; + kRecordSeries = 0x2; + kRecorded = 0x3; + } + + struct ProgramCastStruct { + char_string name = 0; + char_string role = 1; + } + + struct ProgramCategoryStruct { + char_string category = 0; + optional char_string subCategory = 1; + } + + struct SeriesInfoStruct { + char_string season = 0; + char_string episode = 1; } struct ChannelInfoStruct { @@ -5991,6 +6124,46 @@ cluster Channel = 1284 { optional char_string name = 2; optional char_string callSign = 3; optional char_string affiliateCallSign = 4; + optional char_string identifier = 5; + optional ChannelTypeEnum type = 6; + } + + struct ProgramStruct { + char_string identifier = 0; + ChannelInfoStruct channel = 1; + epoch_s startTime = 2; + epoch_s endTime = 3; + char_string title = 4; + optional char_string subtitle = 5; + optional char_string description = 6; + optional char_string audioLanguages[] = 7; + optional char_string ratings[] = 8; + optional char_string thumbnailUrl = 9; + optional char_string posterArtUrl = 10; + optional char_string dvbiUrl = 11; + optional char_string releaseDate = 12; + optional char_string parentalGuidanceText = 13; + optional RecordingFlagBitmap recordingFlag = 14; + optional nullable SeriesInfoStruct seriesInfo = 15; + optional ProgramCategoryStruct categoryList[] = 16; + optional ProgramCastStruct castList[] = 17; + optional ProgramCastStruct externalIDList[] = 18; + } + + struct PageTokenStruct { + optional int16u limit = 0; + optional char_string after = 1; + optional char_string before = 2; + } + + struct ChannelPagingStruct { + optional nullable PageTokenStruct previousToken = 0; + optional nullable PageTokenStruct nextToken = 1; + } + + struct AdditionalInfoStruct { + char_string name = 0; + char_string value = 1; } struct LineupInfoStruct { @@ -6028,12 +6201,47 @@ cluster Channel = 1284 { int16s count = 0; } + request struct GetProgramGuideRequest { + optional epoch_s startTime = 0; + optional epoch_s endTime = 1; + optional ChannelInfoStruct channelList[] = 2; + optional PageTokenStruct pageToken = 3; + optional RecordingFlagBitmap recordingFlag = 4; + optional AdditionalInfoStruct externalIDList[] = 5; + optional octet_string data = 6; + } + + response struct ProgramGuideResponse = 5 { + int16s channelPagingStruct = 0; + ProgramStruct programList[] = 1; + } + + request struct RecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + + request struct CancelRecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + /** Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. */ command ChangeChannel(ChangeChannelRequest): ChangeChannelResponse = 0; /** Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. */ command ChangeChannelByNumber(ChangeChannelByNumberRequest): DefaultSuccess = 2; /** This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. */ command SkipChannel(SkipChannelRequest): DefaultSuccess = 3; + /** This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ + command GetProgramGuide(GetProgramGuideRequest): ProgramGuideResponse = 4; + /** Record a specific program or series when it goes live. This functionality enables DVR recording features. */ + command RecordProgram(RecordProgramRequest): DefaultSuccess = 6; + /** Cancel recording for a specific program or series. */ + command CancelRecordProgram(CancelRecordProgramRequest): DefaultSuccess = 7; } /** This cluster provides an interface for UX navigation within a set of targets on a device or endpoint. */ @@ -6051,6 +6259,12 @@ cluster TargetNavigator = 1285 { char_string name = 1; } + info event TargetUpdated = 0 { + TargetInfoStruct targetList[] = 0; + int8u currentTarget = 1; + octet_string data = 2; + } + readonly attribute TargetInfoStruct targetList[] = 0; readonly attribute optional int8u currentTarget = 1; readonly attribute command_id generatedCommandList[] = 65528; @@ -6089,6 +6303,12 @@ cluster TargetNavigator = 1285 { char_string name = 1; } + info event TargetUpdated = 0 { + TargetInfoStruct targetList[] = 0; + int8u currentTarget = 1; + octet_string data = 2; + } + readonly attribute TargetInfoStruct targetList[] = 0; readonly attribute optional int8u currentTarget = 1; readonly attribute command_id generatedCommandList[] = 65528; @@ -6116,6 +6336,27 @@ cluster TargetNavigator = 1285 { cluster MediaPlayback = 1286 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum PlaybackStateEnum : enum8 { kPlaying = 0; kPaused = 1; @@ -6135,6 +6376,19 @@ cluster MediaPlayback = 1286 { bitmap Feature : bitmap32 { kAdvancedSeek = 0x1; kVariableSpeed = 0x2; + kTextTracks = 0x3; + kAudioTracks = 0x4; + kAudioAdvance = 0x5; + } + + struct TrackAttributesStruct { + char_string<32> languageCode = 0; + optional nullable char_string displayName = 1; + } + + struct TrackStruct { + char_string<32> id = 0; + nullable TrackAttributesStruct trackAttributes = 1; } struct PlaybackPositionStruct { @@ -6142,6 +6396,18 @@ cluster MediaPlayback = 1286 { nullable int64u position = 1; } + info event StateChanged = 0 { + PlaybackStateEnum currentState = 0; + EPOCH_US startTime = 1; + INT64U duration = 2; + PlaybackPositionStruct sampledPosition = 3; + single playbackSpeed = 4; + INT64U seekRangeEnd = 5; + INT64U seekRangeStart = 6; + optional OCTET_STRING data = 7; + boolean audioAdvanceUnmuted = 8; + } + readonly attribute PlaybackStateEnum currentState = 0; readonly attribute optional nullable epoch_us startTime = 1; readonly attribute optional nullable int64u duration = 2; @@ -6149,6 +6415,10 @@ cluster MediaPlayback = 1286 { readonly attribute optional single playbackSpeed = 4; readonly attribute optional nullable int64u seekRangeEnd = 5; readonly attribute optional nullable int64u seekRangeStart = 6; + readonly attribute optional nullable TrackStruct activeAudioTrack = 7; + readonly attribute optional nullable TrackStruct availableAudioTracks[] = 8; + readonly attribute optional nullable TrackStruct activeTextTrack = 9; + readonly attribute optional nullable TrackStruct availableTextTracks[] = 10; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -6156,6 +6426,14 @@ cluster MediaPlayback = 1286 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct RewindRequest { + optional boolean audioAdvanceUnmuted = 0; + } + + request struct FastForwardRequest { + optional boolean audioAdvanceUnmuted = 0; + } + request struct SkipForwardRequest { int64u deltaPositionMilliseconds = 0; } @@ -6173,6 +6451,15 @@ cluster MediaPlayback = 1286 { int64u position = 0; } + request struct ActivateAudioTrackRequest { + CHAR_STRING trackID = 0; + INT8U audioOutputIndex = 1; + } + + request struct ActivateTextTrackRequest { + CHAR_STRING trackID = 0; + } + /** Upon receipt, this SHALL play media. */ command Play(): PlaybackResponse = 0; /** Upon receipt, this SHALL pause media. */ @@ -6186,21 +6473,48 @@ cluster MediaPlayback = 1286 { /** Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. */ command Next(): PlaybackResponse = 5; /** Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command Rewind(): PlaybackResponse = 6; + command Rewind(RewindRequest): PlaybackResponse = 6; /** Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command FastForward(): PlaybackResponse = 7; + command FastForward(FastForwardRequest): PlaybackResponse = 7; /** Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: */ command SkipForward(SkipForwardRequest): PlaybackResponse = 8; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command SkipBackward(SkipBackwardRequest): PlaybackResponse = 9; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command Seek(SeekRequest): PlaybackResponse = 11; + /** Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. */ + command ActivateAudioTrack(ActivateAudioTrackRequest): DefaultSuccess = 12; + /** Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. */ + command ActivateTextTrack(ActivateTextTrackRequest): DefaultSuccess = 13; + /** If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. */ + command DeactivateTextTrack(): DefaultSuccess = 14; } /** This cluster provides an interface for controlling Media Playback (PLAY, PAUSE, etc) on a media device such as a TV or Speaker. */ cluster MediaPlayback = 1286 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum PlaybackStateEnum : enum8 { kPlaying = 0; kPaused = 1; @@ -6220,6 +6534,19 @@ cluster MediaPlayback = 1286 { bitmap Feature : bitmap32 { kAdvancedSeek = 0x1; kVariableSpeed = 0x2; + kTextTracks = 0x3; + kAudioTracks = 0x4; + kAudioAdvance = 0x5; + } + + struct TrackAttributesStruct { + char_string<32> languageCode = 0; + optional nullable char_string displayName = 1; + } + + struct TrackStruct { + char_string<32> id = 0; + nullable TrackAttributesStruct trackAttributes = 1; } struct PlaybackPositionStruct { @@ -6227,6 +6554,18 @@ cluster MediaPlayback = 1286 { nullable int64u position = 1; } + info event StateChanged = 0 { + PlaybackStateEnum currentState = 0; + EPOCH_US startTime = 1; + INT64U duration = 2; + PlaybackPositionStruct sampledPosition = 3; + single playbackSpeed = 4; + INT64U seekRangeEnd = 5; + INT64U seekRangeStart = 6; + optional OCTET_STRING data = 7; + boolean audioAdvanceUnmuted = 8; + } + readonly attribute PlaybackStateEnum currentState = 0; readonly attribute optional nullable epoch_us startTime = 1; readonly attribute optional nullable int64u duration = 2; @@ -6234,6 +6573,10 @@ cluster MediaPlayback = 1286 { readonly attribute optional single playbackSpeed = 4; readonly attribute optional nullable int64u seekRangeEnd = 5; readonly attribute optional nullable int64u seekRangeStart = 6; + readonly attribute optional nullable TrackStruct activeAudioTrack = 7; + readonly attribute optional nullable TrackStruct availableAudioTracks[] = 8; + readonly attribute optional nullable TrackStruct activeTextTrack = 9; + readonly attribute optional nullable TrackStruct availableTextTracks[] = 10; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -6241,6 +6584,14 @@ cluster MediaPlayback = 1286 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct RewindRequest { + optional boolean audioAdvanceUnmuted = 0; + } + + request struct FastForwardRequest { + optional boolean audioAdvanceUnmuted = 0; + } + request struct SkipForwardRequest { int64u deltaPositionMilliseconds = 0; } @@ -6258,6 +6609,15 @@ cluster MediaPlayback = 1286 { int64u position = 0; } + request struct ActivateAudioTrackRequest { + CHAR_STRING trackID = 0; + INT8U audioOutputIndex = 1; + } + + request struct ActivateTextTrackRequest { + CHAR_STRING trackID = 0; + } + /** Upon receipt, this SHALL play media. */ command Play(): PlaybackResponse = 0; /** Upon receipt, this SHALL pause media. */ @@ -6271,15 +6631,21 @@ cluster MediaPlayback = 1286 { /** Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. */ command Next(): PlaybackResponse = 5; /** Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command Rewind(): PlaybackResponse = 6; + command Rewind(RewindRequest): PlaybackResponse = 6; /** Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command FastForward(): PlaybackResponse = 7; + command FastForward(FastForwardRequest): PlaybackResponse = 7; /** Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: */ command SkipForward(SkipForwardRequest): PlaybackResponse = 8; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command SkipBackward(SkipBackwardRequest): PlaybackResponse = 9; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command Seek(SeekRequest): PlaybackResponse = 11; + /** Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. */ + command ActivateAudioTrack(ActivateAudioTrackRequest): DefaultSuccess = 12; + /** Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. */ + command ActivateTextTrack(ActivateTextTrackRequest): DefaultSuccess = 13; + /** If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. */ + command DeactivateTextTrack(): DefaultSuccess = 14; } /** This cluster provides an interface for controlling the Input Selector on a media device such as a TV. */ @@ -6665,6 +7031,27 @@ cluster KeypadInput = 1289 { cluster ContentLauncher = 1290 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum MetricTypeEnum : enum8 { kPixels = 0; kPercentage = 1; @@ -6685,22 +7072,31 @@ cluster ContentLauncher = 1290 { kSportsTeam = 11; kType = 12; kVideo = 13; + kSeason = 14; + kEpisode = 15; + kAny = 16; } enum StatusEnum : enum8 { kSuccess = 0; kURLNotAvailable = 1; kAuthFailed = 2; + kTextTrackNotAvailable = 3; + kAudioTrackNotAvailable = 4; } bitmap Feature : bitmap32 { kContentSearch = 0x1; kURLPlayback = 0x2; + kAdvancedSeek = 0x3; + kTextTracks = 0x4; + kAudioTracks = 0x5; } bitmap SupportedProtocolsBitmap : bitmap32 { kDASH = 0x1; kHLS = 0x2; + kWebRTC = 0x2; } struct DimensionStruct { @@ -6709,6 +7105,18 @@ cluster ContentLauncher = 1290 { MetricTypeEnum metric = 2; } + struct TrackPreferenceStruct { + char_string<32> languageCode = 0; + optional CharacteristicEnum characteristics[] = 1; + int8u audioOutputIndex = 2; + } + + struct PlaybackPreferencesStruct { + int64u playbackPosition = 0; + TrackPreferenceStruct textTrack = 1; + optional TrackPreferenceStruct audioTracks[] = 2; + } + struct AdditionalInfoStruct { char_string<256> name = 0; char_string<8192> value = 1; @@ -6752,6 +7160,8 @@ cluster ContentLauncher = 1290 { ContentSearchStruct search = 0; boolean autoPlay = 1; optional char_string data = 2; + optional PlaybackPreferencesStruct playbackPreferences = 3; + optional boolean useCurrentContext = 4; } request struct LaunchURLRequest { @@ -6775,6 +7185,27 @@ cluster ContentLauncher = 1290 { cluster ContentLauncher = 1290 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum MetricTypeEnum : enum8 { kPixels = 0; kPercentage = 1; @@ -6795,22 +7226,31 @@ cluster ContentLauncher = 1290 { kSportsTeam = 11; kType = 12; kVideo = 13; + kSeason = 14; + kEpisode = 15; + kAny = 16; } enum StatusEnum : enum8 { kSuccess = 0; kURLNotAvailable = 1; kAuthFailed = 2; + kTextTrackNotAvailable = 3; + kAudioTrackNotAvailable = 4; } bitmap Feature : bitmap32 { kContentSearch = 0x1; kURLPlayback = 0x2; + kAdvancedSeek = 0x3; + kTextTracks = 0x4; + kAudioTracks = 0x5; } bitmap SupportedProtocolsBitmap : bitmap32 { kDASH = 0x1; kHLS = 0x2; + kWebRTC = 0x2; } struct DimensionStruct { @@ -6819,6 +7259,18 @@ cluster ContentLauncher = 1290 { MetricTypeEnum metric = 2; } + struct TrackPreferenceStruct { + char_string<32> languageCode = 0; + optional CharacteristicEnum characteristics[] = 1; + int8u audioOutputIndex = 2; + } + + struct PlaybackPreferencesStruct { + int64u playbackPosition = 0; + TrackPreferenceStruct textTrack = 1; + optional TrackPreferenceStruct audioTracks[] = 2; + } + struct AdditionalInfoStruct { char_string<256> name = 0; char_string<8192> value = 1; @@ -6862,6 +7314,8 @@ cluster ContentLauncher = 1290 { ContentSearchStruct search = 0; boolean autoPlay = 1; optional char_string data = 2; + optional PlaybackPreferencesStruct playbackPreferences = 3; + optional boolean useCurrentContext = 4; } request struct LaunchURLRequest { @@ -7161,6 +7615,10 @@ cluster ApplicationBasic = 1293 { cluster AccountLogin = 1294 { revision 1; // NOTE: Default/not specifically set + critical event LoggedOut = 0 { + optional node_id node = 0; + } + readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -7179,6 +7637,11 @@ cluster AccountLogin = 1294 { request struct LoginRequest { char_string<100> tempAccountIdentifier = 0; char_string setupPIN = 1; + optional node_id node = 2; + } + + request struct LogoutRequest { + optional node_id node = 0; } /** Upon receipt, the Content App checks if the account associated with the client Temp Account Identifier Rotating ID is the same acount that is active on the given Content App. If the accounts are the same, then the Content App includes the Setup PIN in the GetSetupPIN Response. */ @@ -7186,13 +7649,17 @@ cluster AccountLogin = 1294 { /** Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. */ fabric timed command access(invoke: administer) Login(LoginRequest): DefaultSuccess = 2; /** The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. */ - fabric timed command Logout(): DefaultSuccess = 3; + fabric timed command Logout(LogoutRequest): DefaultSuccess = 3; } /** This cluster provides commands that facilitate user account login on a Content App or a node. For example, a Content App running on a Video Player device, which is represented as an endpoint (see [TV Architecture]), can use this cluster to help make the user account on the Content App match the user account on the Client. */ cluster AccountLogin = 1294 { revision 1; // NOTE: Default/not specifically set + critical event LoggedOut = 0 { + optional node_id node = 0; + } + readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -7211,6 +7678,11 @@ cluster AccountLogin = 1294 { request struct LoginRequest { char_string<100> tempAccountIdentifier = 0; char_string setupPIN = 1; + optional node_id node = 2; + } + + request struct LogoutRequest { + optional node_id node = 0; } /** Upon receipt, the Content App checks if the account associated with the client Temp Account Identifier Rotating ID is the same acount that is active on the given Content App. If the accounts are the same, then the Content App includes the Setup PIN in the GetSetupPIN Response. */ @@ -7218,7 +7690,7 @@ cluster AccountLogin = 1294 { /** Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. */ fabric timed command access(invoke: administer) Login(LoginRequest): DefaultSuccess = 2; /** The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. */ - fabric timed command Logout(): DefaultSuccess = 3; + fabric timed command Logout(LogoutRequest): DefaultSuccess = 3; } endpoint 0 { diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index 626c5e064c3fe6..f01e0b2838b48e 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -1784,13 +1784,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -3688,7 +3688,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; @@ -4310,7 +4310,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; @@ -5857,6 +5857,12 @@ cluster OccupancySensing = 1030 { cluster Channel = 1284 { revision 1; // NOTE: Default/not specifically set + enum ChannelTypeEnum : enum8 { + kSatellite = 0; + kCable = 1; + kTerrestrial = 2; + } + enum LineupInfoTypeEnum : enum8 { kMSO = 0; } @@ -5870,6 +5876,29 @@ cluster Channel = 1284 { bitmap Feature : bitmap32 { kChannelList = 0x1; kLineupInfo = 0x2; + kElectronicGuide = 0x3; + kRecordProgram = 0x4; + } + + bitmap RecordingFlagBitmap : bitmap32 { + kScheduled = 0x1; + kRecordSeries = 0x2; + kRecorded = 0x3; + } + + struct ProgramCastStruct { + char_string name = 0; + char_string role = 1; + } + + struct ProgramCategoryStruct { + char_string category = 0; + optional char_string subCategory = 1; + } + + struct SeriesInfoStruct { + char_string season = 0; + char_string episode = 1; } struct ChannelInfoStruct { @@ -5878,6 +5907,46 @@ cluster Channel = 1284 { optional char_string name = 2; optional char_string callSign = 3; optional char_string affiliateCallSign = 4; + optional char_string identifier = 5; + optional ChannelTypeEnum type = 6; + } + + struct ProgramStruct { + char_string identifier = 0; + ChannelInfoStruct channel = 1; + epoch_s startTime = 2; + epoch_s endTime = 3; + char_string title = 4; + optional char_string subtitle = 5; + optional char_string description = 6; + optional char_string audioLanguages[] = 7; + optional char_string ratings[] = 8; + optional char_string thumbnailUrl = 9; + optional char_string posterArtUrl = 10; + optional char_string dvbiUrl = 11; + optional char_string releaseDate = 12; + optional char_string parentalGuidanceText = 13; + optional RecordingFlagBitmap recordingFlag = 14; + optional nullable SeriesInfoStruct seriesInfo = 15; + optional ProgramCategoryStruct categoryList[] = 16; + optional ProgramCastStruct castList[] = 17; + optional ProgramCastStruct externalIDList[] = 18; + } + + struct PageTokenStruct { + optional int16u limit = 0; + optional char_string after = 1; + optional char_string before = 2; + } + + struct ChannelPagingStruct { + optional nullable PageTokenStruct previousToken = 0; + optional nullable PageTokenStruct nextToken = 1; + } + + struct AdditionalInfoStruct { + char_string name = 0; + char_string value = 1; } struct LineupInfoStruct { @@ -5915,18 +5984,59 @@ cluster Channel = 1284 { int16s count = 0; } + request struct GetProgramGuideRequest { + optional epoch_s startTime = 0; + optional epoch_s endTime = 1; + optional ChannelInfoStruct channelList[] = 2; + optional PageTokenStruct pageToken = 3; + optional RecordingFlagBitmap recordingFlag = 4; + optional AdditionalInfoStruct externalIDList[] = 5; + optional octet_string data = 6; + } + + response struct ProgramGuideResponse = 5 { + int16s channelPagingStruct = 0; + ProgramStruct programList[] = 1; + } + + request struct RecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + + request struct CancelRecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + /** Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. */ command ChangeChannel(ChangeChannelRequest): ChangeChannelResponse = 0; /** Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. */ command ChangeChannelByNumber(ChangeChannelByNumberRequest): DefaultSuccess = 2; /** This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. */ command SkipChannel(SkipChannelRequest): DefaultSuccess = 3; + /** This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ + command GetProgramGuide(GetProgramGuideRequest): ProgramGuideResponse = 4; + /** Record a specific program or series when it goes live. This functionality enables DVR recording features. */ + command RecordProgram(RecordProgramRequest): DefaultSuccess = 6; + /** Cancel recording for a specific program or series. */ + command CancelRecordProgram(CancelRecordProgramRequest): DefaultSuccess = 7; } /** This cluster provides an interface for controlling the current Channel on a device. */ cluster Channel = 1284 { revision 1; // NOTE: Default/not specifically set + enum ChannelTypeEnum : enum8 { + kSatellite = 0; + kCable = 1; + kTerrestrial = 2; + } + enum LineupInfoTypeEnum : enum8 { kMSO = 0; } @@ -5940,6 +6050,29 @@ cluster Channel = 1284 { bitmap Feature : bitmap32 { kChannelList = 0x1; kLineupInfo = 0x2; + kElectronicGuide = 0x3; + kRecordProgram = 0x4; + } + + bitmap RecordingFlagBitmap : bitmap32 { + kScheduled = 0x1; + kRecordSeries = 0x2; + kRecorded = 0x3; + } + + struct ProgramCastStruct { + char_string name = 0; + char_string role = 1; + } + + struct ProgramCategoryStruct { + char_string category = 0; + optional char_string subCategory = 1; + } + + struct SeriesInfoStruct { + char_string season = 0; + char_string episode = 1; } struct ChannelInfoStruct { @@ -5948,6 +6081,46 @@ cluster Channel = 1284 { optional char_string name = 2; optional char_string callSign = 3; optional char_string affiliateCallSign = 4; + optional char_string identifier = 5; + optional ChannelTypeEnum type = 6; + } + + struct ProgramStruct { + char_string identifier = 0; + ChannelInfoStruct channel = 1; + epoch_s startTime = 2; + epoch_s endTime = 3; + char_string title = 4; + optional char_string subtitle = 5; + optional char_string description = 6; + optional char_string audioLanguages[] = 7; + optional char_string ratings[] = 8; + optional char_string thumbnailUrl = 9; + optional char_string posterArtUrl = 10; + optional char_string dvbiUrl = 11; + optional char_string releaseDate = 12; + optional char_string parentalGuidanceText = 13; + optional RecordingFlagBitmap recordingFlag = 14; + optional nullable SeriesInfoStruct seriesInfo = 15; + optional ProgramCategoryStruct categoryList[] = 16; + optional ProgramCastStruct castList[] = 17; + optional ProgramCastStruct externalIDList[] = 18; + } + + struct PageTokenStruct { + optional int16u limit = 0; + optional char_string after = 1; + optional char_string before = 2; + } + + struct ChannelPagingStruct { + optional nullable PageTokenStruct previousToken = 0; + optional nullable PageTokenStruct nextToken = 1; + } + + struct AdditionalInfoStruct { + char_string name = 0; + char_string value = 1; } struct LineupInfoStruct { @@ -5985,12 +6158,47 @@ cluster Channel = 1284 { int16s count = 0; } + request struct GetProgramGuideRequest { + optional epoch_s startTime = 0; + optional epoch_s endTime = 1; + optional ChannelInfoStruct channelList[] = 2; + optional PageTokenStruct pageToken = 3; + optional RecordingFlagBitmap recordingFlag = 4; + optional AdditionalInfoStruct externalIDList[] = 5; + optional octet_string data = 6; + } + + response struct ProgramGuideResponse = 5 { + int16s channelPagingStruct = 0; + ProgramStruct programList[] = 1; + } + + request struct RecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + + request struct CancelRecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + /** Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. */ command ChangeChannel(ChangeChannelRequest): ChangeChannelResponse = 0; /** Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. */ command ChangeChannelByNumber(ChangeChannelByNumberRequest): DefaultSuccess = 2; /** This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. */ command SkipChannel(SkipChannelRequest): DefaultSuccess = 3; + /** This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ + command GetProgramGuide(GetProgramGuideRequest): ProgramGuideResponse = 4; + /** Record a specific program or series when it goes live. This functionality enables DVR recording features. */ + command RecordProgram(RecordProgramRequest): DefaultSuccess = 6; + /** Cancel recording for a specific program or series. */ + command CancelRecordProgram(CancelRecordProgramRequest): DefaultSuccess = 7; } /** This cluster provides an interface for UX navigation within a set of targets on a device or endpoint. */ @@ -6008,6 +6216,12 @@ cluster TargetNavigator = 1285 { char_string name = 1; } + info event TargetUpdated = 0 { + TargetInfoStruct targetList[] = 0; + int8u currentTarget = 1; + octet_string data = 2; + } + readonly attribute TargetInfoStruct targetList[] = 0; readonly attribute optional int8u currentTarget = 1; readonly attribute command_id generatedCommandList[] = 65528; @@ -6046,6 +6260,12 @@ cluster TargetNavigator = 1285 { char_string name = 1; } + info event TargetUpdated = 0 { + TargetInfoStruct targetList[] = 0; + int8u currentTarget = 1; + octet_string data = 2; + } + readonly attribute TargetInfoStruct targetList[] = 0; readonly attribute optional int8u currentTarget = 1; readonly attribute command_id generatedCommandList[] = 65528; @@ -6073,6 +6293,27 @@ cluster TargetNavigator = 1285 { cluster MediaPlayback = 1286 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum PlaybackStateEnum : enum8 { kPlaying = 0; kPaused = 1; @@ -6092,6 +6333,19 @@ cluster MediaPlayback = 1286 { bitmap Feature : bitmap32 { kAdvancedSeek = 0x1; kVariableSpeed = 0x2; + kTextTracks = 0x3; + kAudioTracks = 0x4; + kAudioAdvance = 0x5; + } + + struct TrackAttributesStruct { + char_string<32> languageCode = 0; + optional nullable char_string displayName = 1; + } + + struct TrackStruct { + char_string<32> id = 0; + nullable TrackAttributesStruct trackAttributes = 1; } struct PlaybackPositionStruct { @@ -6099,6 +6353,18 @@ cluster MediaPlayback = 1286 { nullable int64u position = 1; } + info event StateChanged = 0 { + PlaybackStateEnum currentState = 0; + EPOCH_US startTime = 1; + INT64U duration = 2; + PlaybackPositionStruct sampledPosition = 3; + single playbackSpeed = 4; + INT64U seekRangeEnd = 5; + INT64U seekRangeStart = 6; + optional OCTET_STRING data = 7; + boolean audioAdvanceUnmuted = 8; + } + readonly attribute PlaybackStateEnum currentState = 0; readonly attribute optional nullable epoch_us startTime = 1; readonly attribute optional nullable int64u duration = 2; @@ -6106,6 +6372,10 @@ cluster MediaPlayback = 1286 { readonly attribute optional single playbackSpeed = 4; readonly attribute optional nullable int64u seekRangeEnd = 5; readonly attribute optional nullable int64u seekRangeStart = 6; + readonly attribute optional nullable TrackStruct activeAudioTrack = 7; + readonly attribute optional nullable TrackStruct availableAudioTracks[] = 8; + readonly attribute optional nullable TrackStruct activeTextTrack = 9; + readonly attribute optional nullable TrackStruct availableTextTracks[] = 10; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -6113,6 +6383,14 @@ cluster MediaPlayback = 1286 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct RewindRequest { + optional boolean audioAdvanceUnmuted = 0; + } + + request struct FastForwardRequest { + optional boolean audioAdvanceUnmuted = 0; + } + request struct SkipForwardRequest { int64u deltaPositionMilliseconds = 0; } @@ -6130,6 +6408,15 @@ cluster MediaPlayback = 1286 { int64u position = 0; } + request struct ActivateAudioTrackRequest { + CHAR_STRING trackID = 0; + INT8U audioOutputIndex = 1; + } + + request struct ActivateTextTrackRequest { + CHAR_STRING trackID = 0; + } + /** Upon receipt, this SHALL play media. */ command Play(): PlaybackResponse = 0; /** Upon receipt, this SHALL pause media. */ @@ -6143,21 +6430,48 @@ cluster MediaPlayback = 1286 { /** Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. */ command Next(): PlaybackResponse = 5; /** Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command Rewind(): PlaybackResponse = 6; + command Rewind(RewindRequest): PlaybackResponse = 6; /** Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command FastForward(): PlaybackResponse = 7; + command FastForward(FastForwardRequest): PlaybackResponse = 7; /** Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: */ command SkipForward(SkipForwardRequest): PlaybackResponse = 8; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command SkipBackward(SkipBackwardRequest): PlaybackResponse = 9; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command Seek(SeekRequest): PlaybackResponse = 11; + /** Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. */ + command ActivateAudioTrack(ActivateAudioTrackRequest): DefaultSuccess = 12; + /** Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. */ + command ActivateTextTrack(ActivateTextTrackRequest): DefaultSuccess = 13; + /** If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. */ + command DeactivateTextTrack(): DefaultSuccess = 14; } /** This cluster provides an interface for controlling Media Playback (PLAY, PAUSE, etc) on a media device such as a TV or Speaker. */ cluster MediaPlayback = 1286 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum PlaybackStateEnum : enum8 { kPlaying = 0; kPaused = 1; @@ -6177,6 +6491,19 @@ cluster MediaPlayback = 1286 { bitmap Feature : bitmap32 { kAdvancedSeek = 0x1; kVariableSpeed = 0x2; + kTextTracks = 0x3; + kAudioTracks = 0x4; + kAudioAdvance = 0x5; + } + + struct TrackAttributesStruct { + char_string<32> languageCode = 0; + optional nullable char_string displayName = 1; + } + + struct TrackStruct { + char_string<32> id = 0; + nullable TrackAttributesStruct trackAttributes = 1; } struct PlaybackPositionStruct { @@ -6184,6 +6511,18 @@ cluster MediaPlayback = 1286 { nullable int64u position = 1; } + info event StateChanged = 0 { + PlaybackStateEnum currentState = 0; + EPOCH_US startTime = 1; + INT64U duration = 2; + PlaybackPositionStruct sampledPosition = 3; + single playbackSpeed = 4; + INT64U seekRangeEnd = 5; + INT64U seekRangeStart = 6; + optional OCTET_STRING data = 7; + boolean audioAdvanceUnmuted = 8; + } + readonly attribute PlaybackStateEnum currentState = 0; readonly attribute optional nullable epoch_us startTime = 1; readonly attribute optional nullable int64u duration = 2; @@ -6191,6 +6530,10 @@ cluster MediaPlayback = 1286 { readonly attribute optional single playbackSpeed = 4; readonly attribute optional nullable int64u seekRangeEnd = 5; readonly attribute optional nullable int64u seekRangeStart = 6; + readonly attribute optional nullable TrackStruct activeAudioTrack = 7; + readonly attribute optional nullable TrackStruct availableAudioTracks[] = 8; + readonly attribute optional nullable TrackStruct activeTextTrack = 9; + readonly attribute optional nullable TrackStruct availableTextTracks[] = 10; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -6198,6 +6541,14 @@ cluster MediaPlayback = 1286 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct RewindRequest { + optional boolean audioAdvanceUnmuted = 0; + } + + request struct FastForwardRequest { + optional boolean audioAdvanceUnmuted = 0; + } + request struct SkipForwardRequest { int64u deltaPositionMilliseconds = 0; } @@ -6215,6 +6566,15 @@ cluster MediaPlayback = 1286 { int64u position = 0; } + request struct ActivateAudioTrackRequest { + CHAR_STRING trackID = 0; + INT8U audioOutputIndex = 1; + } + + request struct ActivateTextTrackRequest { + CHAR_STRING trackID = 0; + } + /** Upon receipt, this SHALL play media. */ command Play(): PlaybackResponse = 0; /** Upon receipt, this SHALL pause media. */ @@ -6228,15 +6588,21 @@ cluster MediaPlayback = 1286 { /** Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. */ command Next(): PlaybackResponse = 5; /** Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command Rewind(): PlaybackResponse = 6; + command Rewind(RewindRequest): PlaybackResponse = 6; /** Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command FastForward(): PlaybackResponse = 7; + command FastForward(FastForwardRequest): PlaybackResponse = 7; /** Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: */ command SkipForward(SkipForwardRequest): PlaybackResponse = 8; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command SkipBackward(SkipBackwardRequest): PlaybackResponse = 9; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command Seek(SeekRequest): PlaybackResponse = 11; + /** Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. */ + command ActivateAudioTrack(ActivateAudioTrackRequest): DefaultSuccess = 12; + /** Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. */ + command ActivateTextTrack(ActivateTextTrackRequest): DefaultSuccess = 13; + /** If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. */ + command DeactivateTextTrack(): DefaultSuccess = 14; } /** This cluster provides an interface for controlling the Input Selector on a media device such as a TV. */ @@ -6622,6 +6988,27 @@ cluster KeypadInput = 1289 { cluster ContentLauncher = 1290 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum MetricTypeEnum : enum8 { kPixels = 0; kPercentage = 1; @@ -6642,22 +7029,31 @@ cluster ContentLauncher = 1290 { kSportsTeam = 11; kType = 12; kVideo = 13; + kSeason = 14; + kEpisode = 15; + kAny = 16; } enum StatusEnum : enum8 { kSuccess = 0; kURLNotAvailable = 1; kAuthFailed = 2; + kTextTrackNotAvailable = 3; + kAudioTrackNotAvailable = 4; } bitmap Feature : bitmap32 { kContentSearch = 0x1; kURLPlayback = 0x2; + kAdvancedSeek = 0x3; + kTextTracks = 0x4; + kAudioTracks = 0x5; } bitmap SupportedProtocolsBitmap : bitmap32 { kDASH = 0x1; kHLS = 0x2; + kWebRTC = 0x2; } struct DimensionStruct { @@ -6666,6 +7062,18 @@ cluster ContentLauncher = 1290 { MetricTypeEnum metric = 2; } + struct TrackPreferenceStruct { + char_string<32> languageCode = 0; + optional CharacteristicEnum characteristics[] = 1; + int8u audioOutputIndex = 2; + } + + struct PlaybackPreferencesStruct { + int64u playbackPosition = 0; + TrackPreferenceStruct textTrack = 1; + optional TrackPreferenceStruct audioTracks[] = 2; + } + struct AdditionalInfoStruct { char_string<256> name = 0; char_string<8192> value = 1; @@ -6709,6 +7117,8 @@ cluster ContentLauncher = 1290 { ContentSearchStruct search = 0; boolean autoPlay = 1; optional char_string data = 2; + optional PlaybackPreferencesStruct playbackPreferences = 3; + optional boolean useCurrentContext = 4; } request struct LaunchURLRequest { @@ -6732,6 +7142,27 @@ cluster ContentLauncher = 1290 { cluster ContentLauncher = 1290 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum MetricTypeEnum : enum8 { kPixels = 0; kPercentage = 1; @@ -6752,22 +7183,31 @@ cluster ContentLauncher = 1290 { kSportsTeam = 11; kType = 12; kVideo = 13; + kSeason = 14; + kEpisode = 15; + kAny = 16; } enum StatusEnum : enum8 { kSuccess = 0; kURLNotAvailable = 1; kAuthFailed = 2; + kTextTrackNotAvailable = 3; + kAudioTrackNotAvailable = 4; } bitmap Feature : bitmap32 { kContentSearch = 0x1; kURLPlayback = 0x2; + kAdvancedSeek = 0x3; + kTextTracks = 0x4; + kAudioTracks = 0x5; } bitmap SupportedProtocolsBitmap : bitmap32 { kDASH = 0x1; kHLS = 0x2; + kWebRTC = 0x2; } struct DimensionStruct { @@ -6776,6 +7216,18 @@ cluster ContentLauncher = 1290 { MetricTypeEnum metric = 2; } + struct TrackPreferenceStruct { + char_string<32> languageCode = 0; + optional CharacteristicEnum characteristics[] = 1; + int8u audioOutputIndex = 2; + } + + struct PlaybackPreferencesStruct { + int64u playbackPosition = 0; + TrackPreferenceStruct textTrack = 1; + optional TrackPreferenceStruct audioTracks[] = 2; + } + struct AdditionalInfoStruct { char_string<256> name = 0; char_string<8192> value = 1; @@ -6819,6 +7271,8 @@ cluster ContentLauncher = 1290 { ContentSearchStruct search = 0; boolean autoPlay = 1; optional char_string data = 2; + optional PlaybackPreferencesStruct playbackPreferences = 3; + optional boolean useCurrentContext = 4; } request struct LaunchURLRequest { @@ -7118,6 +7572,10 @@ cluster ApplicationBasic = 1293 { cluster AccountLogin = 1294 { revision 1; // NOTE: Default/not specifically set + critical event LoggedOut = 0 { + optional node_id node = 0; + } + readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -7136,6 +7594,11 @@ cluster AccountLogin = 1294 { request struct LoginRequest { char_string<100> tempAccountIdentifier = 0; char_string setupPIN = 1; + optional node_id node = 2; + } + + request struct LogoutRequest { + optional node_id node = 0; } /** Upon receipt, the Content App checks if the account associated with the client Temp Account Identifier Rotating ID is the same acount that is active on the given Content App. If the accounts are the same, then the Content App includes the Setup PIN in the GetSetupPIN Response. */ @@ -7143,13 +7606,17 @@ cluster AccountLogin = 1294 { /** Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. */ fabric timed command access(invoke: administer) Login(LoginRequest): DefaultSuccess = 2; /** The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. */ - fabric timed command Logout(): DefaultSuccess = 3; + fabric timed command Logout(LogoutRequest): DefaultSuccess = 3; } /** This cluster provides commands that facilitate user account login on a Content App or a node. For example, a Content App running on a Video Player device, which is represented as an endpoint (see [TV Architecture]), can use this cluster to help make the user account on the Content App match the user account on the Client. */ cluster AccountLogin = 1294 { revision 1; // NOTE: Default/not specifically set + critical event LoggedOut = 0 { + optional node_id node = 0; + } + readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -7168,6 +7635,11 @@ cluster AccountLogin = 1294 { request struct LoginRequest { char_string<100> tempAccountIdentifier = 0; char_string setupPIN = 1; + optional node_id node = 2; + } + + request struct LogoutRequest { + optional node_id node = 0; } /** Upon receipt, the Content App checks if the account associated with the client Temp Account Identifier Rotating ID is the same acount that is active on the given Content App. If the accounts are the same, then the Content App includes the Setup PIN in the GetSetupPIN Response. */ @@ -7175,7 +7647,7 @@ cluster AccountLogin = 1294 { /** Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. */ fabric timed command access(invoke: administer) Login(LoginRequest): DefaultSuccess = 2; /** The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. */ - fabric timed command Logout(): DefaultSuccess = 3; + fabric timed command Logout(LogoutRequest): DefaultSuccess = 3; } endpoint 0 { diff --git a/examples/platform/linux/LinuxCommissionableDataProvider.cpp b/examples/platform/linux/LinuxCommissionableDataProvider.cpp index a4d1d8ca3db52e..dac5adb4a0bbbb 100644 --- a/examples/platform/linux/LinuxCommissionableDataProvider.cpp +++ b/examples/platform/linux/LinuxCommissionableDataProvider.cpp @@ -42,7 +42,7 @@ CHIP_ERROR LinuxCommissionableDataProvider::Init(chip::Optional> spake2pSalt, uint32_t spake2pIterationCount, chip::Optional setupPasscode, uint16_t discriminator) { - VerifyOrReturnError(mIsInitialized == false, CHIP_ERROR_WELL_UNINITIALIZED); + VerifyOrReturnError(mIsInitialized == false, CHIP_ERROR_UNINITIALIZED); if (discriminator > chip::kMaxDiscriminatorValue) { @@ -174,21 +174,21 @@ CHIP_ERROR LinuxCommissionableDataProvider::Init(chip::Optional= kSpake2p_Max_PBKDF_Salt_Length, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltBuf.data(), mPaseSalt.data(), mPaseSalt.size()); @@ -199,7 +199,7 @@ CHIP_ERROR LinuxCommissionableDataProvider::GetSpake2pSalt(chip::MutableByteSpan CHIP_ERROR LinuxCommissionableDataProvider::GetSpake2pVerifier(chip::MutableByteSpan & verifierBuf, size_t & outVerifierLen) { - VerifyOrReturnError(mIsInitialized == true, CHIP_ERROR_WELL_UNINITIALIZED); + VerifyOrReturnError(mIsInitialized == true, CHIP_ERROR_UNINITIALIZED); // By now, serialized verifier from Init should be correct size VerifyOrReturnError(mSerializedPaseVerifier.size() == kSpake2p_VerifierSerialized_Length, CHIP_ERROR_INTERNAL); @@ -214,7 +214,7 @@ CHIP_ERROR LinuxCommissionableDataProvider::GetSpake2pVerifier(chip::MutableByte CHIP_ERROR LinuxCommissionableDataProvider::GetSetupPasscode(uint32_t & setupPasscode) { - VerifyOrReturnError(mIsInitialized == true, CHIP_ERROR_WELL_UNINITIALIZED); + VerifyOrReturnError(mIsInitialized == true, CHIP_ERROR_UNINITIALIZED); // Pretend not implemented if we don't have a passcode value externally set if (!mSetupPasscode.HasValue()) diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index c8a99b45ac1a5d..9cf51e8917315a 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -397,13 +397,6 @@ void BaseApplication::LightEventHandler() #endif /* CHIP_ENABLE_OPENTHREAD */ sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); -#ifdef DISPLAY_ENABLED - SilabsLCD::DisplayStatus_t status; - status.connected = sIsEnabled && sIsAttached; - status.advertising = chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen(); - status.nbFabric = chip::Server::GetInstance().GetFabricTable().FabricCount(); - slLCD.SetStatus(status); -#endif PlatformMgr().UnlockChipStack(); } @@ -467,6 +460,7 @@ void BaseApplication::ButtonHandler(AppEvent * aEvent) OutputQrCode(false); #ifdef DISPLAY_ENABLED + UpdateLCDStatusScreen(); slLCD.CycleScreens(); #endif @@ -663,6 +657,31 @@ SilabsLCD & BaseApplication::GetLCD(void) { return slLCD; } + +void BaseApplication::UpdateLCDStatusScreen(void) +{ + SilabsLCD::DisplayStatus_t status; + bool enabled, attached; + chip::DeviceLayer::PlatformMgr().LockChipStack(); +#ifdef SL_WIFI + enabled = ConnectivityMgr().IsWiFiStationEnabled(); + attached = ConnectivityMgr().IsWiFiStationConnected(); +#endif /* SL_WIFI */ +#if CHIP_ENABLE_OPENTHREAD + enabled = ConnectivityMgr().IsThreadEnabled(); + attached = ConnectivityMgr().IsThreadAttached(); +#endif /* CHIP_ENABLE_OPENTHREAD */ + status.connected = enabled && attached; + status.advertising = chip::Server::GetInstance().GetCommissioningWindowManager().IsCommissioningWindowOpen(); + status.nbFabric = chip::Server::GetInstance().GetFabricTable().FabricCount(); +#if CHIP_CONFIG_ENABLE_ICD_SERVER + status.icdMode = (ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::SIT) + ? SilabsLCD::ICDMode_e::SIT + : SilabsLCD::ICDMode_e::LIT; +#endif + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + slLCD.SetStatus(status); +} #endif void BaseApplication::PostEvent(const AppEvent * aEvent) @@ -725,6 +744,10 @@ void BaseApplication::OnPlatformEvent(const ChipDeviceEvent * event, intptr_t) { BaseApplication::sIsProvisioned = event->ServiceProvisioningChange.IsServiceProvisioned; } + +#ifdef DISPLAY_ENABLED + UpdateLCDStatusScreen(); +#endif } void BaseApplication::OutputQrCode(bool refreshLCD) diff --git a/examples/platform/silabs/BaseApplication.h b/examples/platform/silabs/BaseApplication.h index 7b31f233d920a4..0bde0e76f227a2 100644 --- a/examples/platform/silabs/BaseApplication.h +++ b/examples/platform/silabs/BaseApplication.h @@ -36,9 +36,7 @@ #include #include -#if defined(ENABLE_WSTK_LEDS) #include "LEDWidget.h" -#endif // ENABLE_WSTK_LEDS #ifdef EMBER_AF_PLUGIN_IDENTIFY_SERVER #include @@ -112,6 +110,8 @@ class BaseApplication * @brief Return LCD object */ static SilabsLCD & GetLCD(void); + + static void UpdateLCDStatusScreen(void); #endif /** diff --git a/examples/platform/silabs/display/lcd.cpp b/examples/platform/silabs/display/lcd.cpp index adcb4aea019e40..43a134f923e24c 100644 --- a/examples/platform/silabs/display/lcd.cpp +++ b/examples/platform/silabs/display/lcd.cpp @@ -192,11 +192,11 @@ void SilabsLCD::WriteStatus() GLIB_drawStringOnLine(&glibContext, str, lineNb++, GLIB_ALIGN_LEFT, 0, 0, true); sprintf(str, "Advertising : %c", mStatus.advertising ? 'Y' : 'N'); GLIB_drawStringOnLine(&glibContext, str, lineNb++, GLIB_ALIGN_LEFT, 0, 0, true); -#if CHIP_CONFIG_ENABLE_ICD_SERVER - GLIB_drawStringOnLine(&glibContext, "Is ICD : Y", lineNb++, GLIB_ALIGN_LEFT, 0, 0, true); -#else - GLIB_drawStringOnLine(&glibContext, "Is ICD : N", lineNb++, GLIB_ALIGN_LEFT, 0, 0, true); -#endif + if (mStatus.icdMode != NotICD) + { + sprintf(str, "ICD : %s", mStatus.icdMode == SIT ? "SIT" : "LIT"); + GLIB_drawStringOnLine(&glibContext, str, lineNb++, GLIB_ALIGN_LEFT, 0, 0, true); + } updateDisplay(); } diff --git a/examples/platform/silabs/display/lcd.h b/examples/platform/silabs/display/lcd.h index 9324f068b15742..b6f3fc9a0669fc 100644 --- a/examples/platform/silabs/display/lcd.h +++ b/examples/platform/silabs/display/lcd.h @@ -43,12 +43,20 @@ class SilabsLCD InvalidScreen, } Screen_e; + typedef enum icdMode + { + NotICD = 0, + SIT, + LIT, + } ICDMode_e; + typedef struct dStatus { uint8_t nbFabric = 0; bool connected = false; char networkName[50] = { "TODO" }; bool advertising = false; + ICDMode_e icdMode = NotICD; } DisplayStatus_t; typedef void (*customUICB)(GLIB_Context_t * context); diff --git a/examples/platform/telink/common/include/AppTaskCommon.h b/examples/platform/telink/common/include/AppTaskCommon.h index 8cb25d4e8cbede..7bacaeb4377ee4 100644 --- a/examples/platform/telink/common/include/AppTaskCommon.h +++ b/examples/platform/telink/common/include/AppTaskCommon.h @@ -25,7 +25,7 @@ #include "LEDWidget.h" #endif -#if APP_USE_IDENTIFY_PWM +#ifdef APP_USE_IDENTIFY_PWM #include "PWMDevice.h" #endif @@ -121,7 +121,7 @@ class AppTaskCommon static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); -#if APP_USE_IDENTIFY_PWM +#ifdef APP_USE_IDENTIFY_PWM PWMDevice mPwmIdentifyLed; static void ActionIdentifyStateUpdateHandler(k_timer * timer); diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index d2aa42bfdeb258..cd3831caa40c1c 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -64,7 +64,7 @@ const struct gpio_dt_spec sButtonRow1Dt = GPIO_DT_SPEC_GET(DT_NODELABEL(key_matr const struct gpio_dt_spec sButtonRow2Dt = GPIO_DT_SPEC_GET(DT_NODELABEL(key_matrix_row2), gpios); #endif -#if APP_USE_IDENTIFY_PWM +#ifdef APP_USE_IDENTIFY_PWM constexpr uint32_t kIdentifyBlinkRateMs = 200; constexpr uint32_t kIdentifyOkayOnRateMs = 50; constexpr uint32_t kIdentifyOkayOffRateMs = 950; @@ -73,7 +73,7 @@ constexpr uint32_t kIdentifyFinishOffRateMs = 50; constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; constexpr uint32_t kIdentifyBreatheRateMs = 1000; -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = PWM_DT_SPEC_GET_OR(DT_ALIAS(pwm_led3), {}); +const struct pwm_dt_spec sPwmIdentifySpecGreenLed = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)); #endif #if APP_SET_NETWORK_COMM_ENDPOINT_SEC @@ -110,7 +110,7 @@ bool sHaveBLEConnections = false; chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; #endif -#if APP_USE_IDENTIFY_PWM +#ifdef APP_USE_IDENTIFY_PWM void OnIdentifyTriggerEffect(Identify * identify) { AppTaskCommon::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); @@ -272,7 +272,7 @@ CHIP_ERROR AppTaskCommon::InitCommonParts(void) k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); k_timer_user_data_set(&sFactoryResetTimer, this); -#if APP_USE_IDENTIFY_PWM +#ifdef APP_USE_IDENTIFY_PWM // Initialize PWM Identify led err = GetAppTask().mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); if (err != CHIP_NO_ERROR) @@ -464,7 +464,7 @@ void AppTaskCommon::UpdateStatusLED() } #endif -#if APP_USE_IDENTIFY_PWM +#ifdef APP_USE_IDENTIFY_PWM void AppTaskCommon::ActionIdentifyStateUpdateHandler(k_timer * timer) { AppEvent event; diff --git a/examples/pump-app/pump-common/pump-app.matter b/examples/pump-app/pump-common/pump-app.matter index d65bfcd7e1a00d..e382204137356b 100644 --- a/examples/pump-app/pump-common/pump-app.matter +++ b/examples/pump-app/pump-common/pump-app.matter @@ -852,13 +852,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/pump-app/silabs/data_model/pump-thread-app.matter b/examples/pump-app/silabs/data_model/pump-thread-app.matter index fd28d5c1f1f9d0..3e3ccdeb64cb0e 100644 --- a/examples/pump-app/silabs/data_model/pump-thread-app.matter +++ b/examples/pump-app/silabs/data_model/pump-thread-app.matter @@ -852,13 +852,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/pump-app/silabs/data_model/pump-wifi-app.matter b/examples/pump-app/silabs/data_model/pump-wifi-app.matter index fd28d5c1f1f9d0..3e3ccdeb64cb0e 100644 --- a/examples/pump-app/silabs/data_model/pump-wifi-app.matter +++ b/examples/pump-app/silabs/data_model/pump-wifi-app.matter @@ -852,13 +852,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/pump-app/telink/include/AppConfig.h b/examples/pump-app/telink/include/AppConfig.h index 03aee4e8063bf8..85792a55a3d316 100644 --- a/examples/pump-app/telink/include/AppConfig.h +++ b/examples/pump-app/telink/include/AppConfig.h @@ -25,7 +25,9 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif // Time it takes in ms for the simulated pump to move from one state to another. #define PUMP_START_PERIOS_MS 2000 diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter index 779d472458cefd..e07a0b73a10f9b 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter @@ -727,13 +727,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/pump-controller-app/telink/include/AppConfig.h b/examples/pump-controller-app/telink/include/AppConfig.h index c843625ced4207..1650e13ca88d8c 100644 --- a/examples/pump-controller-app/telink/include/AppConfig.h +++ b/examples/pump-controller-app/telink/include/AppConfig.h @@ -25,7 +25,9 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif // Time it takes in ms for the simulated pump to move from one state to another. #define PUMP_START_PERIOS_MS 2000 diff --git a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter index 9f983ac99a1d8c..82d729aa5d2bbc 100644 --- a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter +++ b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter @@ -515,13 +515,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/rvc-app/rvc-common/rvc-app.matter b/examples/rvc-app/rvc-common/rvc-app.matter index 9e4c390c035120..120945d791429d 100644 --- a/examples/rvc-app/rvc-common/rvc-app.matter +++ b/examples/rvc-app/rvc-common/rvc-app.matter @@ -480,13 +480,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -543,7 +543,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/smoke-co-alarm-app/silabs/include/AppConfig.h b/examples/smoke-co-alarm-app/silabs/include/AppConfig.h index c14a373e223c0d..3158c6c34a09aa 100644 --- a/examples/smoke-co-alarm-app/silabs/include/AppConfig.h +++ b/examples/smoke-co-alarm-app/silabs/include/AppConfig.h @@ -30,57 +30,57 @@ #define ACTUATOR_MOVEMENT_PERIOS_MS 10 #define ON_DEMO_BITMAP \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, \ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0x1f, 0xfe, 0x07, 0xe0, \ - 0x7f, 0xf8, 0xff, 0xff, 0x3f, 0xfc, 0x00, 0x00, 0x3f, 0xfc, 0xff, 0xff, 0x7f, 0x3c, 0xe0, 0x07, 0x3c, 0xfe, 0xff, 0xff, \ - 0xff, 0x1f, 0xfe, 0x7f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, \ - 0xe3, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, \ - 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, \ - 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, \ - 0x7f, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, \ - 0x7f, 0xfc, 0xff, 0x0f, 0x38, 0xfe, 0xff, 0xff, 0x7f, 0x1c, 0xf0, 0x0f, 0x38, 0xfe, 0x03, 0xc0, 0x7f, 0x1c, 0xf0, 0x0f, \ - 0x38, 0xfe, 0x27, 0xe9, 0x7f, 0x1c, 0xf0, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, \ - 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xe7, 0xe7, 0x7f, 0xfc, 0xff, 0xff, 0x7f, 0xfe, 0xef, 0xf7, 0x7f, 0xfe, 0xff, 0xff, \ - 0x7f, 0xfc, 0xef, 0xf7, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xfc, 0xef, 0xf3, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xcf, 0xf3, \ - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xdf, 0xfb, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xdf, 0xfb, 0x8f, 0xff, 0xff, 0xff, \ - 0xff, 0xe3, 0x9f, 0xf9, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x9f, 0xf9, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xc7, 0x9f, 0xfd, \ - 0xe3, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xbf, 0xfd, 0xf1, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x3f, 0xfc, 0xf8, 0xff, 0xff, 0xff, \ - 0xff, 0x3f, 0x3e, 0x7c, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0x3f, \ - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xE0, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, \ + 0x07, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x01, 0xE0, 0xFF, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0xFC, 0xFF, 0x07, \ + 0xE0, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x1F, 0xC0, 0xFF, 0xFF, 0x7F, 0x80, 0xFF, 0xFF, 0x7F, 0x80, 0xFF, 0xFF, 0x3F, \ + 0xE0, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x1F, 0xF0, 0x7F, 0xC0, 0xFF, 0x01, 0xFF, 0xFF, 0x0F, 0xF8, 0x0F, 0x00, 0xFE, \ + 0x03, 0xFE, 0xFF, 0x0F, 0xFC, 0x03, 0x00, 0xF8, 0x07, 0xFC, 0xFF, 0x07, 0xFE, 0xC3, 0x7F, 0xF8, 0x0F, 0xFC, 0x07, 0x07, \ + 0xFE, 0xF7, 0xFF, 0xFF, 0x0F, 0xF8, 0x07, 0x03, 0xFF, 0xFF, 0xE1, 0xFF, 0x1F, 0xF8, 0x07, 0x03, 0xFF, 0x3F, 0x80, 0xFF, \ + 0x3F, 0xF8, 0x07, 0x81, 0xDF, 0x3F, 0x80, 0x7F, 0x3F, 0xF0, 0x07, 0x81, 0x9F, 0x7F, 0xDF, 0x3F, 0x7E, 0xF0, 0x07, 0xC1, \ + 0x8F, 0xFF, 0xFF, 0x3F, 0x7E, 0xF0, 0x07, 0xC0, 0xCF, 0xFF, 0xFF, 0x7F, 0x7C, 0xE0, 0x07, 0xC0, 0xC7, 0xFD, 0xFF, 0x77, \ + 0x7C, 0xE0, 0x07, 0xC0, 0xC7, 0xF9, 0xFF, 0xE3, 0xFC, 0xE0, 0x07, 0xE0, 0xC7, 0xF8, 0xF3, 0xE3, 0xFC, 0xE0, 0x07, 0xE0, \ + 0xE7, 0xF8, 0xE0, 0xE7, 0xFC, 0xE0, 0x07, 0xE0, 0xE7, 0xF8, 0xE0, 0xE7, 0xF8, 0xE0, 0x07, 0xE0, 0xE7, 0xF8, 0xE0, 0xE7, \ + 0xF8, 0xE0, 0x07, 0xE0, 0xE7, 0xF8, 0xE0, 0xE7, 0xF8, 0xE0, 0x07, 0xE0, 0xC7, 0xF8, 0xF3, 0xE3, 0xFC, 0xE0, 0x07, 0xC0, \ + 0xC7, 0xF9, 0xFF, 0xE3, 0xFC, 0xE0, 0xFF, 0xC0, 0xC7, 0xFD, 0xFF, 0x77, 0xFC, 0xE0, 0xFF, 0xC1, 0xCF, 0xFF, 0xFF, 0x7F, \ + 0x7C, 0xE0, 0xFF, 0xC1, 0x8F, 0xFF, 0xFF, 0x3F, 0x7E, 0xF0, 0xFF, 0x81, 0x9F, 0x7F, 0xDF, 0x3F, 0x7E, 0xF0, 0xFF, 0x81, \ + 0xDF, 0x3F, 0x80, 0x7F, 0x3F, 0xF0, 0x07, 0x03, 0xFF, 0x3F, 0x80, 0xFF, 0x3F, 0xF8, 0x07, 0x03, 0xFF, 0xFF, 0xF1, 0xFF, \ + 0x1F, 0xF8, 0x07, 0x07, 0xFE, 0xF7, 0xFF, 0xFF, 0x1F, 0xF8, 0x07, 0x07, 0xFE, 0xC3, 0xFF, 0xF8, 0x0F, 0xFC, 0x07, 0x0F, \ + 0xFC, 0x03, 0x00, 0xF8, 0x07, 0xFC, 0xFF, 0x0F, 0xF8, 0x0F, 0x00, 0xFE, 0x03, 0xFE, 0xFF, 0x1F, 0xF0, 0x7F, 0xC0, 0xFF, \ + 0x01, 0xFF, 0xFF, 0x3F, 0xE0, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x7F, 0xC0, 0xFF, 0xFF, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, \ + 0x00, 0xFF, 0xFF, 0x1F, 0xC0, 0xFF, 0xFF, 0xFF, 0x01, 0xFC, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0xFF, 0x03, 0xE0, 0xFF, 0x00, \ + 0xF8, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, \ + 0x3F, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFC, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF #define OFF_DEMO_BITMAP \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xe0, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xe0, 0x07, 0xfc, 0xff, 0xff, 0xff, \ - 0xff, 0x1f, 0xfe, 0x7f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, \ - 0xe3, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, \ - 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, \ - 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, \ - 0x7f, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, \ - 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, \ - 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, \ - 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, \ - 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, \ - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, \ - 0xff, 0xe3, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, \ - 0xe3, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, \ - 0xff, 0x3f, 0xfe, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0x3f, \ - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, \ + 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xF8, 0x1F, 0x00, 0xFE, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, \ + 0x00, 0xFC, 0xFF, 0xFF, 0x1F, 0xE0, 0xFF, 0xFF, 0x07, 0xF8, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, \ + 0x07, 0xF8, 0xFF, 0xFF, 0x1F, 0xE0, 0xFF, 0xFF, 0x03, 0xFE, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0xFF, 0x03, 0xFF, 0x01, 0x80, \ + 0xFF, 0xC0, 0xFF, 0xFF, 0x81, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x80, 0x7F, 0xF8, 0x1F, 0xFE, 0x81, 0xFF, 0xFF, \ + 0xC0, 0xFF, 0xFE, 0x7F, 0xFF, 0x03, 0xFF, 0x7F, 0xE0, 0xFF, 0x3F, 0xFC, 0xFF, 0x03, 0xFF, 0x7F, 0xE0, 0xFF, 0x07, 0xE0, \ + 0xFF, 0x07, 0xFE, 0x7F, 0xF0, 0xF7, 0x07, 0xE0, 0xEF, 0x07, 0xFE, 0x3F, 0xF0, 0xE3, 0xEF, 0xF7, 0xC7, 0x0F, 0xFE, 0x3F, \ + 0xF0, 0xF1, 0xFF, 0xFF, 0x8F, 0x0F, 0xFC, 0x3F, 0xF8, 0xF1, 0xFF, 0xFF, 0x8F, 0x1F, 0xFC, 0x3F, 0xF8, 0x71, 0xFF, 0xFF, \ + 0x8E, 0x1F, 0xFC, 0x3F, 0xF8, 0x38, 0xFE, 0x7F, 0x1C, 0x1F, 0xFC, 0x1F, 0xF8, 0x38, 0x7F, 0xFE, 0x1C, 0x1F, 0xFC, 0x1F, \ + 0xF8, 0x38, 0x3F, 0xFC, 0x1C, 0x1F, 0xFC, 0x1F, 0xF8, 0x18, 0x1F, 0xF8, 0x18, 0x1F, 0xF8, 0x1F, 0xF8, 0x18, 0x1F, 0xF8, \ + 0x18, 0x1F, 0xF8, 0x1F, 0xF8, 0x18, 0x3F, 0xFC, 0x1C, 0x1F, 0xF8, 0x1F, 0xF8, 0x38, 0x7F, 0xFE, 0x1C, 0x1F, 0xFC, 0x3F, \ + 0xF8, 0x38, 0xFE, 0x7F, 0x1C, 0x1F, 0xFC, 0x3F, 0xF8, 0x39, 0xFF, 0xFF, 0x9C, 0x1F, 0xFC, 0x3F, 0xF8, 0xF1, 0xFF, 0xFF, \ + 0x8F, 0x1F, 0xFC, 0x3F, 0xF0, 0xF1, 0xFF, 0xFF, 0x8F, 0x0F, 0xFC, 0x3F, 0xF0, 0xE3, 0xEF, 0xF7, 0xC7, 0x0F, 0xFC, 0x7F, \ + 0xF0, 0xF7, 0x07, 0xE0, 0xEF, 0x0F, 0xFE, 0x7F, 0xE0, 0xFF, 0x07, 0xE0, 0xFF, 0x07, 0xFE, 0xFF, 0xE0, 0xFF, 0x3F, 0xFC, \ + 0xFF, 0x07, 0xFF, 0xFF, 0xC0, 0xFF, 0xFE, 0x7F, 0xFF, 0x03, 0xFF, 0xFF, 0x80, 0x7F, 0xF8, 0x1F, 0xFE, 0x81, 0xFF, 0xFF, \ + 0x81, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x03, 0xFF, 0x01, 0x80, 0xFF, 0xC0, 0xFF, 0xFF, 0x03, 0xFE, 0x0F, 0xF0, \ + 0x7F, 0xC0, 0xFF, 0xFF, 0x07, 0xFC, 0xFF, 0xFF, 0x1F, 0xE0, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, \ + 0x1F, 0xE0, 0xFF, 0xFF, 0x07, 0xF8, 0xFF, 0xFF, 0x3F, 0x80, 0xFF, 0xFF, 0x01, 0xFC, 0xFF, 0xFF, 0x7F, 0x00, 0xFC, 0x3F, \ + 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0x07, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF diff --git a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter index 47a3f7f98b2a6f..8df2eb9c7f2aee 100644 --- a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter +++ b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter @@ -1029,13 +1029,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1092,7 +1092,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/smoke-co-alarm-app/telink/include/AppConfig.h b/examples/smoke-co-alarm-app/telink/include/AppConfig.h index bfaeb98eb8ac15..f002310df57420 100644 --- a/examples/smoke-co-alarm-app/telink/include/AppConfig.h +++ b/examples/smoke-co-alarm-app/telink/include/AppConfig.h @@ -25,4 +25,6 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif diff --git a/examples/temperature-measurement-app/telink/include/AppConfig.h b/examples/temperature-measurement-app/telink/include/AppConfig.h index 76e68ac1b1349c..b0e7847e16fdcb 100644 --- a/examples/temperature-measurement-app/telink/include/AppConfig.h +++ b/examples/temperature-measurement-app/telink/include/AppConfig.h @@ -25,4 +25,3 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 -#define APP_USE_IDENTIFY_PWM 0 diff --git a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter index 0a70fa23aa53a5..dc6239ff7d8caf 100644 --- a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter +++ b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter @@ -669,13 +669,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -732,7 +732,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter index c50eb6145009eb..3312d9b5d2e0de 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter @@ -1319,13 +1319,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter index 49646a363f683f..251a64e1e42669 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter @@ -1319,13 +1319,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/thermostat/telink/include/AppConfig.h b/examples/thermostat/telink/include/AppConfig.h index 8fc6ceac48ad19..9b427c5644145f 100644 --- a/examples/thermostat/telink/include/AppConfig.h +++ b/examples/thermostat/telink/include/AppConfig.h @@ -25,4 +25,6 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif diff --git a/examples/thermostat/thermostat-common/thermostat.matter b/examples/thermostat/thermostat-common/thermostat.matter index 7192fd47b956fa..9818995f052e4c 100644 --- a/examples/thermostat/thermostat-common/thermostat.matter +++ b/examples/thermostat/thermostat-common/thermostat.matter @@ -867,13 +867,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -930,7 +930,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } diff --git a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java index 1ff92853ec8648..6a4eb77cb4be3b 100644 --- a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java +++ b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java @@ -28,8 +28,8 @@ public void onReceive(Context context, Intent intent) { switch (intentAction) { case MatterIntentConstants.ACTION_MATTER_COMMAND: - int commandId = intent.getIntExtra(MatterIntentConstants.EXTRA_COMMAND_ID, -1); - int clusterId = intent.getIntExtra(MatterIntentConstants.EXTRA_CLUSTER_ID, -1); + long commandId = intent.getLongExtra(MatterIntentConstants.EXTRA_COMMAND_ID, -1); + long clusterId = intent.getLongExtra(MatterIntentConstants.EXTRA_CLUSTER_ID, -1); if (commandId != -1) { byte[] commandPayload = intent.getByteArrayExtra(MatterIntentConstants.EXTRA_COMMAND_PAYLOAD); @@ -56,7 +56,7 @@ public void onReceive(Context context, Intent intent) { sendResponseViaPendingIntent(context, intent, response); } else { - int attributeId = intent.getIntExtra(MatterIntentConstants.EXTRA_ATTRIBUTE_ID, -1); + long attributeId = intent.getLongExtra(MatterIntentConstants.EXTRA_ATTRIBUTE_ID, -1); String attributeAction = intent.getStringExtra(MatterIntentConstants.EXTRA_ATTRIBUTE_ACTION); if (attributeAction.equals(MatterIntentConstants.ATTRIBUTE_ACTION_READ)) { diff --git a/examples/tv-app/android/BUILD.gn b/examples/tv-app/android/BUILD.gn index 115d5dfb2a4cf0..0793b7d2993ef8 100644 --- a/examples/tv-app/android/BUILD.gn +++ b/examples/tv-app/android/BUILD.gn @@ -33,6 +33,10 @@ shared_library("jni") { "include/audio-output/AudioOutputManager.cpp", "include/audio-output/AudioOutputManager.h", "include/cluster-init.cpp", + "include/content-app-observer/ContentAppObserver.cpp", + "include/content-app-observer/ContentAppObserver.h", + "include/content-control/ContentController.cpp", + "include/content-control/ContentController.h", "include/content-launcher/AppContentLauncherManager.cpp", "include/content-launcher/AppContentLauncherManager.h", "include/media-playback/AppMediaPlaybackManager.cpp", diff --git a/examples/tv-app/android/include/account-login/AccountLoginManager.cpp b/examples/tv-app/android/include/account-login/AccountLoginManager.cpp index 0f2e77e06be53f..2fbc0aa5899004 100644 --- a/examples/tv-app/android/include/account-login/AccountLoginManager.cpp +++ b/examples/tv-app/android/include/account-login/AccountLoginManager.cpp @@ -32,7 +32,8 @@ AccountLoginManager::AccountLoginManager(ContentAppCommandDelegate * commandDele CopyString(mSetupPin, sizeof(mSetupPin), setupPin); } -bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountIdentifier, const CharSpan & setupPin) +bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountIdentifier, const CharSpan & setupPin, + const chip::Optional & nodeId) { ChipLogProgress(DeviceLayer, "AccountLoginManager::HandleLogin called for endpoint %d", mEndpointId); string tempAccountIdentifierString(tempAccountIdentifier.data(), tempAccountIdentifier.size()); @@ -50,7 +51,7 @@ bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountIdentifier, co } } -bool AccountLoginManager::HandleLogout() +bool AccountLoginManager::HandleLogout(const chip::Optional & nodeId) { // TODO: Insert your code here to send logout request return true; diff --git a/examples/tv-app/android/include/account-login/AccountLoginManager.h b/examples/tv-app/android/include/account-login/AccountLoginManager.h index aa229d8bb9d88b..a02a029f307eee 100644 --- a/examples/tv-app/android/include/account-login/AccountLoginManager.h +++ b/examples/tv-app/android/include/account-login/AccountLoginManager.h @@ -39,8 +39,9 @@ class AccountLoginManager : public AccountLoginDelegate inline void SetSetupPin(char * setupPin) override { CopyString(mSetupPin, sizeof(mSetupPin), setupPin); }; - bool HandleLogin(const CharSpan & tempAccountIdentifierString, const CharSpan & setupPinString) override; - bool HandleLogout() override; + bool HandleLogin(const CharSpan & tempAccountIdentifierString, const CharSpan & setupPinString, + const chip::Optional & nodeId) override; + bool HandleLogout(const chip::Optional & nodeId) override; void HandleGetSetupPin(CommandResponseHelper & helper, const CharSpan & tempAccountIdentifierString) override; void GetSetupPin(char * setupPin, size_t setupPinSize, const CharSpan & tempAccountIdentifierString) override; diff --git a/examples/tv-app/android/include/content-app-observer/ContentAppObserver.cpp b/examples/tv-app/android/include/content-app-observer/ContentAppObserver.cpp new file mode 100644 index 00000000000000..7145ba24305f21 --- /dev/null +++ b/examples/tv-app/android/include/content-app-observer/ContentAppObserver.cpp @@ -0,0 +1,36 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ContentAppObserver.h" + +#include +#include + +using namespace std; +using namespace chip; +using namespace chip::app::Clusters::ContentAppObserver; + +ContentAppObserver::ContentAppObserver() +{ + // Create Test Data +} + +void ContentAppObserver::HandleContentAppMessage(chip::app::CommandResponseHelper & helper, + const chip::Optional & data, const chip::CharSpan & encodingHint) +{ + ChipLogProgress(Zcl, "ContentAppObserver::HandleContentAppMessage"); +} diff --git a/examples/tv-app/android/include/content-app-observer/ContentAppObserver.h b/examples/tv-app/android/include/content-app-observer/ContentAppObserver.h new file mode 100644 index 00000000000000..d866362191b880 --- /dev/null +++ b/examples/tv-app/android/include/content-app-observer/ContentAppObserver.h @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +using ContentAppObserverDelegate = chip::app::Clusters::ContentAppObserver::Delegate; +using ContentAppMessageResponse = chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessageResponse::Type; + +class ContentAppObserver : public ContentAppObserverDelegate +{ +public: + ContentAppObserver(); + + void HandleContentAppMessage(chip::app::CommandResponseHelper & helper, + const chip::Optional & data, const chip::CharSpan & encodingHint) override; + void SetEndpointId(chip::EndpointId epId) { mEndpointId = epId; }; + +protected: +private: + chip::EndpointId mEndpointId; +}; diff --git a/examples/tv-app/android/include/content-control/ContentController.cpp b/examples/tv-app/android/include/content-control/ContentController.cpp new file mode 100644 index 00000000000000..c4eee0355f4552 --- /dev/null +++ b/examples/tv-app/android/include/content-control/ContentController.cpp @@ -0,0 +1,106 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ContentController.h" +#include +#include + +using namespace std; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters::ContentControl; + +ContentController::ContentController() +{ + // Create Test Data +} + +// Attribute Delegates +bool ContentController::HandleGetEnabled() +{ + return false; +} + +CHIP_ERROR ContentController::HandleGetOnDemandRatings(chip::app::AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(chip::CharSpan()); +} + +chip::CharSpan ContentController::HandleGetOnDemandRatingThreshold() +{ + return chip::CharSpan(); +} + +CHIP_ERROR ContentController::HandleGetScheduledContentRatings(chip::app::AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(chip::CharSpan()); +} + +chip::CharSpan ContentController::HandleGetScheduledContentRatingThreshold() +{ + return chip::CharSpan(); +} + +uint32_t ContentController::HandleGetScreenDailyTime() +{ + return (uint32_t) 0xFFFFFFFF; +} + +uint32_t ContentController::HandleGetRemainingScreenTime() +{ + return (uint32_t) 0xFFFFFFFF; +} + +bool ContentController::HandleGetBlockUnrated() +{ + return false; +} + +// Command Delegates +void ContentController::HandleUpdatePIN(chip::Optional oldPIN, chip::CharSpan newPIN) {} + +void ContentController::HandleResetPIN(chip::app::CommandResponseHelper & helper) {} + +void ContentController::HandleEnable() {} + +void ContentController::HandleDisable() {} + +void ContentController::HandleAddBonusTime(chip::Optional PINCode, chip::Optional bonusTime) {} + +void ContentController::HandleSetScreenDailyTime(uint32_t screenDailyTime) {} + +void ContentController::HandleBlockUnratedContent() {} + +void ContentController::HandleUnblockUnratedContent() {} + +void ContentController::HandleSetOnDemandRatingThreshold(chip::CharSpan rating) {} + +void ContentController::HandleSetScheduledContentRatingThreshold(chip::CharSpan rating) {} + +uint32_t ContentController::GetFeatureMap(chip::EndpointId endpoint) +{ + if (endpoint >= EMBER_AF_CONTENT_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT) + { + return mDynamicEndpointFeatureMap; + } + + uint32_t featureMap = 0; + // TODO: ReEnable the code bellow + // Attributes::FeatureMap::Get(endpoint, &featureMap); + return featureMap; +} diff --git a/examples/tv-app/android/include/content-control/ContentController.h b/examples/tv-app/android/include/content-control/ContentController.h new file mode 100644 index 00000000000000..eaafef098f65c0 --- /dev/null +++ b/examples/tv-app/android/include/content-control/ContentController.h @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +using ContentControlDelegate = chip::app::Clusters::ContentControl::Delegate; +using ResetPINResponseType = chip::app::Clusters::ContentControl::Commands::ResetPINResponse::Type; + +class ContentController : public ContentControlDelegate +{ +public: + ContentController(); + + // Attribute Delegates + bool HandleGetEnabled() override; + CHIP_ERROR HandleGetOnDemandRatings(chip::app::AttributeValueEncoder & aEncoder) override; + chip::CharSpan HandleGetOnDemandRatingThreshold() override; + CHIP_ERROR HandleGetScheduledContentRatings(chip::app::AttributeValueEncoder & aEncoder) override; + chip::CharSpan HandleGetScheduledContentRatingThreshold() override; + uint32_t HandleGetScreenDailyTime() override; + uint32_t HandleGetRemainingScreenTime() override; + bool HandleGetBlockUnrated() override; + + // Command Delegates + void HandleUpdatePIN(chip::Optional oldPIN, chip::CharSpan newPIN) override; + void HandleResetPIN(chip::app::CommandResponseHelper & helper) override; + void HandleEnable() override; + void HandleDisable() override; + void HandleAddBonusTime(chip::Optional PINCode, chip::Optional bonusTime) override; + void HandleSetScreenDailyTime(uint32_t screenDailyTime) override; + void HandleBlockUnratedContent() override; + void HandleUnblockUnratedContent() override; + void HandleSetOnDemandRatingThreshold(chip::CharSpan rating) override; + void HandleSetScheduledContentRatingThreshold(chip::CharSpan rating) override; + + uint32_t GetFeatureMap(chip::EndpointId endpoint) override; + void SetEndpointId(chip::EndpointId epId) { mEndpointId = epId; }; + +protected: +private: + // TODO: set this based upon meta data from app + uint32_t mDynamicEndpointFeatureMap = 3; + chip::EndpointId mEndpointId; +}; diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp index 61e8af0193fa9e..329df8cd802299 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp @@ -38,7 +38,9 @@ AppContentLauncherManager::AppContentLauncherManager(ContentAppAttributeDelegate void AppContentLauncherManager::HandleLaunchContent(CommandResponseHelper & helper, const DecodableList & parameterList, bool autoplay, - const CharSpan & data) + const CharSpan & data, + const chip::Optional playbackPreferences, + bool useCurrentContext) { ChipLogProgress(Zcl, "AppContentLauncherManager::HandleLaunchContent for endpoint %d", mEndpointId); string dataString(data.data(), data.size()); diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h index 2843486a037363..67812744ce0d36 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h @@ -29,6 +29,7 @@ using chip::app::CommandResponseHelper; using ContentLauncherDelegate = chip::app::Clusters::ContentLauncher::Delegate; using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LauncherResponse::Type; using ParameterType = chip::app::Clusters::ContentLauncher::Structs::ParameterStruct::DecodableType; +using PlaybackPreferencesType = chip::app::Clusters::ContentLauncher::Structs::PlaybackPreferencesStruct::DecodableType; using BrandingInformationType = chip::app::Clusters::ContentLauncher::Structs::BrandingInformationStruct::Type; using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate; @@ -40,7 +41,9 @@ class AppContentLauncherManager : public ContentLauncherDelegate void HandleLaunchContent(CommandResponseHelper & helper, const chip::app::DataModel::DecodableList & parameterList, bool autoplay, - const CharSpan & data) override; + const CharSpan & data, const chip::Optional playbackPreferences, + bool useCurrentContext) override; + void HandleLaunchUrl(CommandResponseHelper & helper, const CharSpan & contentUrl, const CharSpan & displayString, const BrandingInformationType & brandingInformation) override; CHIP_ERROR HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder) override; diff --git a/examples/tv-app/android/include/media-playback/AppMediaPlaybackManager.cpp b/examples/tv-app/android/include/media-playback/AppMediaPlaybackManager.cpp index 0fe5e9d63d4f6f..e7d8100e9e5ce0 100644 --- a/examples/tv-app/android/include/media-playback/AppMediaPlaybackManager.cpp +++ b/examples/tv-app/android/include/media-playback/AppMediaPlaybackManager.cpp @@ -69,6 +69,44 @@ uint64_t AppMediaPlaybackManager::HandleGetSeekRangeEnd() return HandleMediaRequestGetAttribute(MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_END); } +CHIP_ERROR AppMediaPlaybackManager::HandleGetActiveAudioTrack(AttributeValueEncoder & aEncoder) +{ + TrackType mActiveAudioTrack; + return aEncoder.Encode(mActiveAudioTrack); +} + +CHIP_ERROR AppMediaPlaybackManager::HandleGetAvailableAudioTracks(AttributeValueEncoder & aEncoder) +{ + std::vector mAvailableAudioTracks; + // TODO: Insert code here + return aEncoder.EncodeList([mAvailableAudioTracks](const auto & encoder) -> CHIP_ERROR { + for (auto const & audioTrack : mAvailableAudioTracks) + { + ReturnErrorOnFailure(encoder.Encode(audioTrack)); + } + return CHIP_NO_ERROR; + }); +} + +CHIP_ERROR AppMediaPlaybackManager::HandleGetActiveTextTrack(AttributeValueEncoder & aEncoder) +{ + TrackType mActiveTextTrack; + return aEncoder.Encode(mActiveTextTrack); +} + +CHIP_ERROR AppMediaPlaybackManager::HandleGetAvailableTextTracks(AttributeValueEncoder & aEncoder) +{ + std::vector mAvailableTextTracks; + // TODO: Insert code here + return aEncoder.EncodeList([mAvailableTextTracks](const auto & encoder) -> CHIP_ERROR { + for (auto const & textTrack : mAvailableTextTracks) + { + ReturnErrorOnFailure(encoder.Encode(textTrack)); + } + return CHIP_NO_ERROR; + }); +} + void AppMediaPlaybackManager::HandlePlay(CommandResponseHelper & helper) { helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_PLAY, 0)); @@ -84,7 +122,8 @@ void AppMediaPlaybackManager::HandleStop(CommandResponseHelper & helper) +void AppMediaPlaybackManager::HandleFastForward(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) { helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_FAST_FORWARD, 0)); } @@ -94,7 +133,8 @@ void AppMediaPlaybackManager::HandlePrevious(CommandResponseHelper & helper) +void AppMediaPlaybackManager::HandleRewind(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) { helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_REWIND, 0)); } @@ -127,6 +167,27 @@ void AppMediaPlaybackManager::HandleStartOver(CommandResponseHelper #include #include +#include enum MediaPlaybackRequestAttribute : chip::AttributeId { - MEDIA_PLAYBACK_ATTRIBUTE_PLAYBACK_STATE = chip::app::Clusters::MediaPlayback::Attributes::CurrentState::Id, - MEDIA_PLAYBACK_ATTRIBUTE_START_TIME = chip::app::Clusters::MediaPlayback::Attributes::StartTime::Id, - MEDIA_PLAYBACK_ATTRIBUTE_DURATION = chip::app::Clusters::MediaPlayback::Attributes::Duration::Id, - MEDIA_PLAYBACK_ATTRIBUTE_SPEED = chip::app::Clusters::MediaPlayback::Attributes::PlaybackSpeed::Id, - MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_END = chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::Id, - MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_START = chip::app::Clusters::MediaPlayback::Attributes::SeekRangeStart::Id, + MEDIA_PLAYBACK_ATTRIBUTE_PLAYBACK_STATE = chip::app::Clusters::MediaPlayback::Attributes::CurrentState::Id, + MEDIA_PLAYBACK_ATTRIBUTE_START_TIME = chip::app::Clusters::MediaPlayback::Attributes::StartTime::Id, + MEDIA_PLAYBACK_ATTRIBUTE_DURATION = chip::app::Clusters::MediaPlayback::Attributes::Duration::Id, + MEDIA_PLAYBACK_ATTRIBUTE_SPEED = chip::app::Clusters::MediaPlayback::Attributes::PlaybackSpeed::Id, + MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_END = chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::Id, + MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_START = chip::app::Clusters::MediaPlayback::Attributes::SeekRangeStart::Id, + MEDIA_PLAYBACK_ATTRIBUTE_ACTIVE_AUDIO_TRACK = chip::app::Clusters::MediaPlayback::Attributes::ActiveAudioTrack::Id, + MEDIA_PLAYBACK_ATTRIBUTE_AVAILABLE_AUDIO_TRACKS = chip::app::Clusters::MediaPlayback::Attributes::AvailableAudioTracks::Id, + MEDIA_PLAYBACK_ATTRIBUTE_ACTIVE_TEXT_TRACK = chip::app::Clusters::MediaPlayback::Attributes::ActiveTextTrack::Id, + MEDIA_PLAYBACK_ATTRIBUTE_AVAILABLE_TEXT_TRACKS = chip::app::Clusters::MediaPlayback::Attributes::AvailableTextTracks::Id, }; enum MediaPlaybackRequest : uint8_t { - MEDIA_PLAYBACK_REQUEST_PLAY = 0, - MEDIA_PLAYBACK_REQUEST_PAUSE = 1, - MEDIA_PLAYBACK_REQUEST_STOP = 2, - MEDIA_PLAYBACK_REQUEST_START_OVER = 3, - MEDIA_PLAYBACK_REQUEST_PREVIOUS = 4, - MEDIA_PLAYBACK_REQUEST_NEXT = 5, - MEDIA_PLAYBACK_REQUEST_REWIND = 6, - MEDIA_PLAYBACK_REQUEST_FAST_FORWARD = 7, - MEDIA_PLAYBACK_REQUEST_SKIP_FORWARD = 8, - MEDIA_PLAYBACK_REQUEST_SKIP_BACKWARD = 9, - MEDIA_PLAYBACK_REQUEST_SEEK = 10, + MEDIA_PLAYBACK_REQUEST_PLAY = 0, + MEDIA_PLAYBACK_REQUEST_PAUSE = 1, + MEDIA_PLAYBACK_REQUEST_STOP = 2, + MEDIA_PLAYBACK_REQUEST_START_OVER = 3, + MEDIA_PLAYBACK_REQUEST_PREVIOUS = 4, + MEDIA_PLAYBACK_REQUEST_NEXT = 5, + MEDIA_PLAYBACK_REQUEST_REWIND = 6, + MEDIA_PLAYBACK_REQUEST_FAST_FORWARD = 7, + MEDIA_PLAYBACK_REQUEST_SKIP_FORWARD = 8, + MEDIA_PLAYBACK_REQUEST_SKIP_BACKWARD = 9, + MEDIA_PLAYBACK_REQUEST_SEEK = 10, + MEDIA_PLAYBACK_REQUEST_ACTIVATE_AUDIO_TRACK = 11, + MEDIA_PLAYBACK_REQUEST_ACTIVATE_TEXT_TRACK = 12, + MEDIA_PLAYBACK_REQUEST_DEACTIVATE_TEXT_TRACK = 13, }; using chip::EndpointId; @@ -55,6 +63,7 @@ using chip::app::CommandResponseHelper; using MediaPlaybackDelegate = chip::app::Clusters::MediaPlayback::Delegate; using PlaybackResponseType = chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type; using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate; +using TrackType = chip::app::Clusters::MediaPlayback::Structs::TrackStruct::Type; class AppMediaPlaybackManager : public MediaPlaybackDelegate { @@ -68,13 +77,19 @@ class AppMediaPlaybackManager : public MediaPlaybackDelegate float HandleGetPlaybackSpeed() override; uint64_t HandleGetSeekRangeStart() override; uint64_t HandleGetSeekRangeEnd() override; + CHIP_ERROR HandleGetActiveAudioTrack(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAvailableAudioTracks(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetActiveTextTrack(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAvailableTextTracks(AttributeValueEncoder & aEncoder) override; void HandlePlay(CommandResponseHelper & helper) override; void HandlePause(CommandResponseHelper & helper) override; void HandleStop(CommandResponseHelper & helper) override; - void HandleFastForward(CommandResponseHelper & helper) override; + void HandleFastForward(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) override; void HandlePrevious(CommandResponseHelper & helper) override; - void HandleRewind(CommandResponseHelper & helper) override; + void HandleRewind(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) override; void HandleSkipBackward(CommandResponseHelper & helper, const uint64_t & deltaPositionMilliseconds) override; void HandleSkipForward(CommandResponseHelper & helper, @@ -82,6 +97,9 @@ class AppMediaPlaybackManager : public MediaPlaybackDelegate void HandleSeek(CommandResponseHelper & helper, const uint64_t & positionMilliseconds) override; void HandleNext(CommandResponseHelper & helper) override; void HandleStartOver(CommandResponseHelper & helper) override; + bool HandleActivateAudioTrack(const chip::CharSpan & trackId, const uint8_t & audioOutputIndex) override; + bool HandleActivateTextTrack(const chip::CharSpan & trackId) override; + bool HandleDeactivateTextTrack() override; uint32_t GetFeatureMap(chip::EndpointId endpoint) override; diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h index 657d7e92c0299a..7d6bf20c7bb37c 100644 --- a/examples/tv-app/android/java/AppImpl.h +++ b/examples/tv-app/android/java/AppImpl.h @@ -35,6 +35,8 @@ #include "../include/account-login/AccountLoginManager.h" #include "../include/application-basic/ApplicationBasicManager.h" #include "../include/application-launcher/ApplicationLauncherManager.h" +#include "../include/content-app-observer/ContentAppObserver.h" +#include "../include/content-control/ContentController.h" #include "../include/content-launcher/AppContentLauncherManager.h" #include "../include/media-playback/AppMediaPlaybackManager.h" #include "../include/target-navigator/TargetNavigatorManager.h" @@ -47,6 +49,8 @@ #include #include #include +#include +#include #include #include #include @@ -72,6 +76,8 @@ using ApplicationBasicDelegate = app::Clusters::ApplicationBasic::Delegate; using ApplicationLauncherDelegate = app::Clusters::ApplicationLauncher::Delegate; using ChannelDelegate = app::Clusters::Channel::Delegate; using ContentLauncherDelegate = app::Clusters::ContentLauncher::Delegate; +using ContentAppObserverDelegate = app::Clusters::ContentAppObserver::Delegate; +using ContentControlDelegate = app::Clusters::ContentControl::Delegate; using KeypadInputDelegate = app::Clusters::KeypadInput::Delegate; using MediaPlaybackDelegate = app::Clusters::MediaPlayback::Delegate; using TargetNavigatorDelegate = app::Clusters::TargetNavigator::Delegate; @@ -112,6 +118,16 @@ class DLL_EXPORT ContentAppImpl : public ContentApp mContentLauncherDelegate.SetEndpointId(GetEndpointId()); return &mContentLauncherDelegate; }; + ContentAppObserverDelegate * GetContentAppObserverDelegate() override + { + mContentAppObserverDelegate.SetEndpointId(GetEndpointId()); + return &mContentAppObserverDelegate; + }; + ContentControlDelegate * GetContentControlDelegate() override + { + mContentControlDelegate.SetEndpointId(GetEndpointId()); + return &mContentControlDelegate; + }; KeypadInputDelegate * GetKeypadInputDelegate() override { return &mKeypadInputDelegate; }; MediaPlaybackDelegate * GetMediaPlaybackDelegate() override { @@ -129,6 +145,8 @@ class DLL_EXPORT ContentAppImpl : public ContentApp AccountLoginManager mAccountLoginDelegate; ApplicationLauncherManager mApplicationLauncherDelegate; ChannelManager mChannelDelegate; + ContentController mContentControlDelegate; + ContentAppObserver mContentAppObserverDelegate; AppContentLauncherManager mContentLauncherDelegate; KeypadInputManager mKeypadInputDelegate; AppMediaPlaybackManager mMediaPlaybackDelegate; diff --git a/examples/tv-app/android/java/ChannelManager.cpp b/examples/tv-app/android/java/ChannelManager.cpp index 098b9af180c7a7..586e56bf99b27f 100644 --- a/examples/tv-app/android/java/ChannelManager.cpp +++ b/examples/tv-app/android/java/ChannelManager.cpp @@ -355,6 +355,40 @@ bool ChannelManager::HandleSkipChannel(const int16_t & count) return static_cast(ret); } +void ChannelManager::HandleGetProgramGuide( + CommandResponseHelper & helper, const chip::Optional & startTime, + const chip::Optional & endTime, + const chip::Optional> & channelList, + const chip::Optional & pageToken, const chip::Optional> & recordingFlag, + const chip::Optional> & externalIdList, + const chip::Optional & data) +{ + + // 1. Decode received parameters + // 2. Perform search + // 3. Return results + ProgramGuideResponseType response; + // response.channelPagingStruct; + // response.programList; + helper.Success(response); +} + +bool ChannelManager::HandleRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) +{ + // Start recording + return true; +} + +bool ChannelManager::HandleCancelRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) +{ + // Cancel recording + return true; +} + void ChannelManager::InitializeWithObjects(jobject managerObject) { JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); diff --git a/examples/tv-app/android/java/ChannelManager.h b/examples/tv-app/android/java/ChannelManager.h index 77221069c30fc1..fca3d03056f0fe 100644 --- a/examples/tv-app/android/java/ChannelManager.h +++ b/examples/tv-app/android/java/ChannelManager.h @@ -25,6 +25,12 @@ using chip::app::AttributeValueEncoder; using chip::app::CommandResponseHelper; using ChannelDelegate = chip::app::Clusters::Channel::Delegate; using ChangeChannelResponseType = chip::app::Clusters::Channel::Commands::ChangeChannelResponse::Type; +using RecordingFlagBitmap = chip::app::Clusters::Channel::RecordingFlagBitmap; +using ProgramGuideResponseType = chip::app::Clusters::Channel::Commands::ProgramGuideResponse::Type; +using ChannelInfoType = chip::app::Clusters::Channel::Structs::ChannelInfoStruct::Type; +using AdditionalInfoType = chip::app::Clusters::Channel::Structs::AdditionalInfoStruct::Type; +using LineupInfoType = chip::app::Clusters::Channel::Structs::LineupInfoStruct::Type; +using PageTokenType = chip::app::Clusters::Channel::Structs::PageTokenStruct::Type; class ChannelManager : public ChannelDelegate { @@ -39,6 +45,21 @@ class ChannelManager : public ChannelDelegate void HandleChangeChannel(CommandResponseHelper & helper, const CharSpan & match) override; bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) override; bool HandleSkipChannel(const int16_t & count) override; + void HandleGetProgramGuide(CommandResponseHelper & helper, const chip::Optional & startTime, + const chip::Optional & endTime, + const chip::Optional> & channelList, + const chip::Optional & pageToken, + const chip::Optional> & recordingFlag, + const chip::Optional> & externalIdList, + const chip::Optional & data) override; + + bool HandleRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const chip::app::DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) override; + + bool HandleCancelRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const chip::app::DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) override; uint32_t GetFeatureMap(chip::EndpointId endpoint) override; diff --git a/examples/tv-app/android/java/ContentLauncherManager.cpp b/examples/tv-app/android/java/ContentLauncherManager.cpp index e57ad4c3a76270..ee2f36c1667666 100644 --- a/examples/tv-app/android/java/ContentLauncherManager.cpp +++ b/examples/tv-app/android/java/ContentLauncherManager.cpp @@ -47,7 +47,9 @@ void ContentLauncherManager::NewManager(jint endpoint, jobject manager) void ContentLauncherManager::HandleLaunchContent(CommandResponseHelper & helper, const DecodableList & parameterList, bool autoplay, - const chip::CharSpan & data) + const chip::CharSpan & data, + const chip::Optional playbackPreferences, + bool useCurrentContext) { Commands::LauncherResponse::Type response; CHIP_ERROR err = CHIP_NO_ERROR; diff --git a/examples/tv-app/android/java/ContentLauncherManager.h b/examples/tv-app/android/java/ContentLauncherManager.h index ba978500c2e3e5..ac65dcaac0dc71 100644 --- a/examples/tv-app/android/java/ContentLauncherManager.h +++ b/examples/tv-app/android/java/ContentLauncherManager.h @@ -30,6 +30,7 @@ using ContentLauncherDelegate = chip::app::Clusters::ContentLauncher::Delegate; using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LauncherResponse::Type; using ParameterType = chip::app::Clusters::ContentLauncher::Structs::ParameterStruct::DecodableType; using BrandingInformationType = chip::app::Clusters::ContentLauncher::Structs::BrandingInformationStruct::Type; +using PlaybackPreferencesType = chip::app::Clusters::ContentLauncher::Structs::PlaybackPreferencesStruct::DecodableType; class ContentLauncherManager : public ContentLauncherDelegate { @@ -39,7 +40,8 @@ class ContentLauncherManager : public ContentLauncherDelegate void HandleLaunchContent(CommandResponseHelper & helper, const chip::app::DataModel::DecodableList & parameterList, bool autoplay, - const CharSpan & data) override; + const CharSpan & data, const chip::Optional playbackPreferences, + bool useCurrentContext) override; void HandleLaunchUrl(CommandResponseHelper & helper, const CharSpan & contentUrl, const CharSpan & displayString, const BrandingInformationType & brandingInformation) override; CHIP_ERROR HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder) override; diff --git a/examples/tv-app/android/java/MediaPlaybackManager.cpp b/examples/tv-app/android/java/MediaPlaybackManager.cpp index 53a7066551cd22..30931a48709a0f 100644 --- a/examples/tv-app/android/java/MediaPlaybackManager.cpp +++ b/examples/tv-app/android/java/MediaPlaybackManager.cpp @@ -90,6 +90,44 @@ uint64_t MediaPlaybackManager::HandleGetSeekRangeEnd() return HandleMediaRequestGetAttribute(MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_END); } +CHIP_ERROR MediaPlaybackManager::HandleGetActiveAudioTrack(AttributeValueEncoder & aEncoder) +{ + TrackType mActiveAudioTrack; + return aEncoder.Encode(mActiveAudioTrack); +} + +CHIP_ERROR MediaPlaybackManager::HandleGetAvailableAudioTracks(AttributeValueEncoder & aEncoder) +{ + std::vector mAvailableAudioTracks; + // TODO: Insert code here + return aEncoder.EncodeList([mAvailableAudioTracks](const auto & encoder) -> CHIP_ERROR { + for (auto const & audioTrack : mAvailableAudioTracks) + { + ReturnErrorOnFailure(encoder.Encode(audioTrack)); + } + return CHIP_NO_ERROR; + }); +} + +CHIP_ERROR MediaPlaybackManager::HandleGetActiveTextTrack(AttributeValueEncoder & aEncoder) +{ + TrackType mActiveTextTrack; + return aEncoder.Encode(mActiveTextTrack); +} + +CHIP_ERROR MediaPlaybackManager::HandleGetAvailableTextTracks(AttributeValueEncoder & aEncoder) +{ + std::vector mAvailableTextTracks; + // TODO: Insert code here + return aEncoder.EncodeList([mAvailableTextTracks](const auto & encoder) -> CHIP_ERROR { + for (auto const & textTrack : mAvailableTextTracks) + { + ReturnErrorOnFailure(encoder.Encode(textTrack)); + } + return CHIP_NO_ERROR; + }); +} + void MediaPlaybackManager::HandlePlay(CommandResponseHelper & helper) { helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_PLAY, 0)); @@ -105,7 +143,8 @@ void MediaPlaybackManager::HandleStop(CommandResponseHelper & helper) +void MediaPlaybackManager::HandleFastForward(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) { helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_FAST_FORWARD, 0)); } @@ -115,7 +154,8 @@ void MediaPlaybackManager::HandlePrevious(CommandResponseHelper & helper) +void MediaPlaybackManager::HandleRewind(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) { helper.Success(HandleMediaRequest(MEDIA_PLAYBACK_REQUEST_REWIND, 0)); } @@ -148,6 +188,27 @@ void MediaPlaybackManager::HandleStartOver(CommandResponseHelper #include #include +#include enum MediaPlaybackRequestAttribute : uint8_t { - MEDIA_PLAYBACK_ATTRIBUTE_PLAYBACK_STATE = 0, - MEDIA_PLAYBACK_ATTRIBUTE_START_TIME = 1, - MEDIA_PLAYBACK_ATTRIBUTE_DURATION = 2, - MEDIA_PLAYBACK_ATTRIBUTE_SPEED = 3, - MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_END = 4, - MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_START = 5, + MEDIA_PLAYBACK_ATTRIBUTE_PLAYBACK_STATE = 0, + MEDIA_PLAYBACK_ATTRIBUTE_START_TIME = 1, + MEDIA_PLAYBACK_ATTRIBUTE_DURATION = 2, + MEDIA_PLAYBACK_ATTRIBUTE_SPEED = 3, + MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_END = 4, + MEDIA_PLAYBACK_ATTRIBUTE_SEEK_RANGE_START = 5, + MEDIA_PLAYBACK_ATTRIBUTE_ACTIVE_AUDIO_TRACK = 6, + MEDIA_PLAYBACK_ATTRIBUTE_AVAILABLE_AUDIO_TRACKS = 7, + MEDIA_PLAYBACK_ATTRIBUTE_ACTIVE_TEXT_TRACK = 8, + MEDIA_PLAYBACK_ATTRIBUTE_AVAILABLE_TEXT_TRACKS = 9, MEDIA_PLAYBACK_ATTRIBUTE_COUNT, }; enum MediaPlaybackRequest : uint8_t { - MEDIA_PLAYBACK_REQUEST_PLAY = 0, - MEDIA_PLAYBACK_REQUEST_PAUSE = 1, - MEDIA_PLAYBACK_REQUEST_STOP = 2, - MEDIA_PLAYBACK_REQUEST_START_OVER = 3, - MEDIA_PLAYBACK_REQUEST_PREVIOUS = 4, - MEDIA_PLAYBACK_REQUEST_NEXT = 5, - MEDIA_PLAYBACK_REQUEST_REWIND = 6, - MEDIA_PLAYBACK_REQUEST_FAST_FORWARD = 7, - MEDIA_PLAYBACK_REQUEST_SKIP_FORWARD = 8, - MEDIA_PLAYBACK_REQUEST_SKIP_BACKWARD = 9, - MEDIA_PLAYBACK_REQUEST_SEEK = 10, + MEDIA_PLAYBACK_REQUEST_PLAY = 0, + MEDIA_PLAYBACK_REQUEST_PAUSE = 1, + MEDIA_PLAYBACK_REQUEST_STOP = 2, + MEDIA_PLAYBACK_REQUEST_START_OVER = 3, + MEDIA_PLAYBACK_REQUEST_PREVIOUS = 4, + MEDIA_PLAYBACK_REQUEST_NEXT = 5, + MEDIA_PLAYBACK_REQUEST_REWIND = 6, + MEDIA_PLAYBACK_REQUEST_FAST_FORWARD = 7, + MEDIA_PLAYBACK_REQUEST_SKIP_FORWARD = 8, + MEDIA_PLAYBACK_REQUEST_SKIP_BACKWARD = 9, + MEDIA_PLAYBACK_REQUEST_SEEK = 10, + MEDIA_PLAYBACK_REQUEST_ACTIVATE_AUDIO_TRACK = 11, + MEDIA_PLAYBACK_REQUEST_ACTIVATE_TEXT_TRACK = 12, + MEDIA_PLAYBACK_REQUEST_DEACTIVATE_TEXT_TRACK = 13, }; using chip::app::AttributeValueEncoder; using chip::app::CommandResponseHelper; using MediaPlaybackDelegate = chip::app::Clusters::MediaPlayback::Delegate; using PlaybackResponseType = chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type; +using TrackType = chip::app::Clusters::MediaPlayback::Structs::TrackStruct::Type; class MediaPlaybackManager : public MediaPlaybackDelegate { @@ -66,13 +75,19 @@ class MediaPlaybackManager : public MediaPlaybackDelegate float HandleGetPlaybackSpeed() override; uint64_t HandleGetSeekRangeStart() override; uint64_t HandleGetSeekRangeEnd() override; + CHIP_ERROR HandleGetActiveAudioTrack(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAvailableAudioTracks(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetActiveTextTrack(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAvailableTextTracks(AttributeValueEncoder & aEncoder) override; void HandlePlay(CommandResponseHelper & helper) override; void HandlePause(CommandResponseHelper & helper) override; void HandleStop(CommandResponseHelper & helper) override; - void HandleFastForward(CommandResponseHelper & helper) override; + void HandleFastForward(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) override; void HandlePrevious(CommandResponseHelper & helper) override; - void HandleRewind(CommandResponseHelper & helper) override; + void HandleRewind(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) override; void HandleSkipBackward(CommandResponseHelper & helper, const uint64_t & deltaPositionMilliseconds) override; void HandleSkipForward(CommandResponseHelper & helper, @@ -80,6 +95,9 @@ class MediaPlaybackManager : public MediaPlaybackDelegate void HandleSeek(CommandResponseHelper & helper, const uint64_t & positionMilliseconds) override; void HandleNext(CommandResponseHelper & helper) override; void HandleStartOver(CommandResponseHelper & helper) override; + bool HandleActivateAudioTrack(const chip::CharSpan & trackId, const uint8_t & audioOutputIndex) override; + bool HandleActivateTextTrack(const chip::CharSpan & trackId) override; + bool HandleDeactivateTextTrack() override; uint32_t GetFeatureMap(chip::EndpointId endpoint) override; diff --git a/examples/tv-app/tv-common/BUILD.gn b/examples/tv-app/tv-common/BUILD.gn index 03d98b3227c82d..b24fd24839bdb3 100644 --- a/examples/tv-app/tv-common/BUILD.gn +++ b/examples/tv-app/tv-common/BUILD.gn @@ -52,6 +52,10 @@ source_set("tv-common-sources") { "clusters/audio-output/AudioOutputManager.h", "clusters/channel/ChannelManager.cpp", "clusters/channel/ChannelManager.h", + "clusters/content-app-observer/ContentAppObserver.cpp", + "clusters/content-app-observer/ContentAppObserver.h", + "clusters/content-control/ContentController.cpp", + "clusters/content-control/ContentController.h", "clusters/content-launcher/ContentLauncherManager.cpp", "clusters/content-launcher/ContentLauncherManager.h", "clusters/keypad-input/KeypadInputManager.cpp", diff --git a/examples/tv-app/tv-common/clusters/account-login/AccountLoginManager.cpp b/examples/tv-app/tv-common/clusters/account-login/AccountLoginManager.cpp index d5f70305716d29..1127d3a8aea35c 100644 --- a/examples/tv-app/tv-common/clusters/account-login/AccountLoginManager.cpp +++ b/examples/tv-app/tv-common/clusters/account-login/AccountLoginManager.cpp @@ -28,7 +28,8 @@ AccountLoginManager::AccountLoginManager(const char * setupPin) CopyString(mSetupPin, sizeof(mSetupPin), setupPin); } -bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountIdentifier, const CharSpan & setupPin) +bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountIdentifier, const CharSpan & setupPin, + const chip::Optional & nodeId) { string tempAccountIdentifierString(tempAccountIdentifier.data(), tempAccountIdentifier.size()); string setupPinString(setupPin.data(), setupPin.size()); @@ -45,7 +46,7 @@ bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountIdentifier, co return false; } -bool AccountLoginManager::HandleLogout() +bool AccountLoginManager::HandleLogout(const chip::Optional & nodeId) { // TODO: Insert your code here to send logout request ChipLogProgress(Zcl, "AccountLoginManager::HandleLogout success"); diff --git a/examples/tv-app/tv-common/clusters/account-login/AccountLoginManager.h b/examples/tv-app/tv-common/clusters/account-login/AccountLoginManager.h index 86326f9440a610..4d6f53759b56d3 100644 --- a/examples/tv-app/tv-common/clusters/account-login/AccountLoginManager.h +++ b/examples/tv-app/tv-common/clusters/account-login/AccountLoginManager.h @@ -36,8 +36,9 @@ class AccountLoginManager : public AccountLoginDelegate inline void SetSetupPin(char * setupPin) override { CopyString(mSetupPin, sizeof(mSetupPin), setupPin); }; - bool HandleLogin(const CharSpan & tempAccountIdentifierString, const CharSpan & setupPinString) override; - bool HandleLogout() override; + bool HandleLogin(const CharSpan & tempAccountIdentifierString, const CharSpan & setupPinString, + const chip::Optional & nodeId) override; + bool HandleLogout(const chip::Optional & nodeId) override; void HandleGetSetupPin(CommandResponseHelper & helper, const CharSpan & tempAccountIdentifierString) override; inline void GetSetupPin(char * setupPin, size_t setupPinSize, const CharSpan & tempAccountIdentifierString) override diff --git a/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp b/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp index d057a631ea372d..59b00e828aff26 100644 --- a/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp +++ b/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp @@ -191,6 +191,40 @@ bool ChannelManager::HandleSkipChannel(const int16_t & count) return true; } +void ChannelManager::HandleGetProgramGuide( + CommandResponseHelper & helper, const chip::Optional & startTime, + const chip::Optional & endTime, + const chip::Optional> & channelList, + const chip::Optional & pageToken, const chip::Optional> & recordingFlag, + const chip::Optional> & externalIdList, + const chip::Optional & data) +{ + + // 1. Decode received parameters + // 2. Perform search + // 3. Return results + ProgramGuideResponseType response; + // response.channelPagingStruct; + // response.programList; + helper.Success(response); +} + +bool ChannelManager::HandleRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) +{ + // Start recording + return true; +} + +bool ChannelManager::HandleCancelRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) +{ + // Cancel recording + return true; +} + uint32_t ChannelManager::GetFeatureMap(chip::EndpointId endpoint) { if (endpoint >= EMBER_AF_CONTENT_LAUNCHER_CLUSTER_SERVER_ENDPOINT_COUNT) diff --git a/examples/tv-app/tv-common/clusters/channel/ChannelManager.h b/examples/tv-app/tv-common/clusters/channel/ChannelManager.h index 326edddc53cc77..68c473e74dc70d 100644 --- a/examples/tv-app/tv-common/clusters/channel/ChannelManager.h +++ b/examples/tv-app/tv-common/clusters/channel/ChannelManager.h @@ -23,10 +23,14 @@ using chip::CharSpan; using chip::app::AttributeValueEncoder; using chip::app::CommandResponseHelper; +using RecordingFlagBitmap = chip::app::Clusters::Channel::RecordingFlagBitmap; using ChannelDelegate = chip::app::Clusters::Channel::Delegate; using ChangeChannelResponseType = chip::app::Clusters::Channel::Commands::ChangeChannelResponse::Type; +using ProgramGuideResponseType = chip::app::Clusters::Channel::Commands::ProgramGuideResponse::Type; using ChannelInfoType = chip::app::Clusters::Channel::Structs::ChannelInfoStruct::Type; +using AdditionalInfoType = chip::app::Clusters::Channel::Structs::AdditionalInfoStruct::Type; using LineupInfoType = chip::app::Clusters::Channel::Structs::LineupInfoStruct::Type; +using PageTokenType = chip::app::Clusters::Channel::Structs::PageTokenStruct::Type; class ChannelManager : public ChannelDelegate { @@ -40,6 +44,21 @@ class ChannelManager : public ChannelDelegate void HandleChangeChannel(CommandResponseHelper & helper, const CharSpan & match) override; bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) override; bool HandleSkipChannel(const int16_t & count) override; + void HandleGetProgramGuide(CommandResponseHelper & helper, const chip::Optional & startTime, + const chip::Optional & endTime, + const chip::Optional> & channelList, + const chip::Optional & pageToken, + const chip::Optional> & recordingFlag, + const chip::Optional> & externalIdList, + const chip::Optional & data) override; + + bool HandleRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const chip::app::DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) override; + + bool HandleCancelRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const chip::app::DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) override; uint32_t GetFeatureMap(chip::EndpointId endpoint) override; diff --git a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp new file mode 100644 index 00000000000000..7145ba24305f21 --- /dev/null +++ b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp @@ -0,0 +1,36 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ContentAppObserver.h" + +#include +#include + +using namespace std; +using namespace chip; +using namespace chip::app::Clusters::ContentAppObserver; + +ContentAppObserver::ContentAppObserver() +{ + // Create Test Data +} + +void ContentAppObserver::HandleContentAppMessage(chip::app::CommandResponseHelper & helper, + const chip::Optional & data, const chip::CharSpan & encodingHint) +{ + ChipLogProgress(Zcl, "ContentAppObserver::HandleContentAppMessage"); +} diff --git a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h new file mode 100644 index 00000000000000..07ba89b2de3a1a --- /dev/null +++ b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h @@ -0,0 +1,37 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +using ContentAppObserverDelegate = chip::app::Clusters::ContentAppObserver::Delegate; +using ContentAppMessageResponse = chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessageResponse::Type; + +class ContentAppObserver : public ContentAppObserverDelegate +{ +public: + ContentAppObserver(); + + void HandleContentAppMessage(chip::app::CommandResponseHelper & helper, + const chip::Optional & data, const chip::CharSpan & encodingHint) override; + +protected: +}; diff --git a/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp b/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp new file mode 100644 index 00000000000000..c4eee0355f4552 --- /dev/null +++ b/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp @@ -0,0 +1,106 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ContentController.h" +#include +#include + +using namespace std; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters::ContentControl; + +ContentController::ContentController() +{ + // Create Test Data +} + +// Attribute Delegates +bool ContentController::HandleGetEnabled() +{ + return false; +} + +CHIP_ERROR ContentController::HandleGetOnDemandRatings(chip::app::AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(chip::CharSpan()); +} + +chip::CharSpan ContentController::HandleGetOnDemandRatingThreshold() +{ + return chip::CharSpan(); +} + +CHIP_ERROR ContentController::HandleGetScheduledContentRatings(chip::app::AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(chip::CharSpan()); +} + +chip::CharSpan ContentController::HandleGetScheduledContentRatingThreshold() +{ + return chip::CharSpan(); +} + +uint32_t ContentController::HandleGetScreenDailyTime() +{ + return (uint32_t) 0xFFFFFFFF; +} + +uint32_t ContentController::HandleGetRemainingScreenTime() +{ + return (uint32_t) 0xFFFFFFFF; +} + +bool ContentController::HandleGetBlockUnrated() +{ + return false; +} + +// Command Delegates +void ContentController::HandleUpdatePIN(chip::Optional oldPIN, chip::CharSpan newPIN) {} + +void ContentController::HandleResetPIN(chip::app::CommandResponseHelper & helper) {} + +void ContentController::HandleEnable() {} + +void ContentController::HandleDisable() {} + +void ContentController::HandleAddBonusTime(chip::Optional PINCode, chip::Optional bonusTime) {} + +void ContentController::HandleSetScreenDailyTime(uint32_t screenDailyTime) {} + +void ContentController::HandleBlockUnratedContent() {} + +void ContentController::HandleUnblockUnratedContent() {} + +void ContentController::HandleSetOnDemandRatingThreshold(chip::CharSpan rating) {} + +void ContentController::HandleSetScheduledContentRatingThreshold(chip::CharSpan rating) {} + +uint32_t ContentController::GetFeatureMap(chip::EndpointId endpoint) +{ + if (endpoint >= EMBER_AF_CONTENT_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT) + { + return mDynamicEndpointFeatureMap; + } + + uint32_t featureMap = 0; + // TODO: ReEnable the code bellow + // Attributes::FeatureMap::Get(endpoint, &featureMap); + return featureMap; +} diff --git a/examples/tv-app/tv-common/clusters/content-control/ContentController.h b/examples/tv-app/tv-common/clusters/content-control/ContentController.h new file mode 100644 index 00000000000000..01636f37fcb772 --- /dev/null +++ b/examples/tv-app/tv-common/clusters/content-control/ContentController.h @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +using ContentControlDelegate = chip::app::Clusters::ContentControl::Delegate; +using ResetPINResponseType = chip::app::Clusters::ContentControl::Commands::ResetPINResponse::Type; + +class ContentController : public ContentControlDelegate +{ +public: + ContentController(); + + // Attribute Delegates + bool HandleGetEnabled() override; + CHIP_ERROR HandleGetOnDemandRatings(chip::app::AttributeValueEncoder & aEncoder) override; + chip::CharSpan HandleGetOnDemandRatingThreshold() override; + CHIP_ERROR HandleGetScheduledContentRatings(chip::app::AttributeValueEncoder & aEncoder) override; + chip::CharSpan HandleGetScheduledContentRatingThreshold() override; + uint32_t HandleGetScreenDailyTime() override; + uint32_t HandleGetRemainingScreenTime() override; + bool HandleGetBlockUnrated() override; + + // Command Delegates + void HandleUpdatePIN(chip::Optional oldPIN, chip::CharSpan newPIN) override; + void HandleResetPIN(chip::app::CommandResponseHelper & helper) override; + void HandleEnable() override; + void HandleDisable() override; + void HandleAddBonusTime(chip::Optional PINCode, chip::Optional bonusTime) override; + void HandleSetScreenDailyTime(uint32_t screenDailyTime) override; + void HandleBlockUnratedContent() override; + void HandleUnblockUnratedContent() override; + void HandleSetOnDemandRatingThreshold(chip::CharSpan rating) override; + void HandleSetScheduledContentRatingThreshold(chip::CharSpan rating) override; + + uint32_t GetFeatureMap(chip::EndpointId endpoint) override; + +protected: +private: + // TODO: set this based upon meta data from app + uint32_t mDynamicEndpointFeatureMap = 3; +}; diff --git a/examples/tv-app/tv-common/clusters/content-launcher/ContentLauncherManager.cpp b/examples/tv-app/tv-common/clusters/content-launcher/ContentLauncherManager.cpp index 5ad2dfa0c11f2b..ff2da45d7db461 100644 --- a/examples/tv-app/tv-common/clusters/content-launcher/ContentLauncherManager.cpp +++ b/examples/tv-app/tv-common/clusters/content-launcher/ContentLauncherManager.cpp @@ -95,7 +95,9 @@ ContentLauncherManager::ContentLauncherManager(list acceptHeaderLis void ContentLauncherManager::HandleLaunchContent(CommandResponseHelper & helper, const DecodableList & parameterList, bool autoplay, - const CharSpan & data) + const CharSpan & data, + const chip::Optional playbackPreferences, + bool useCurrentContext) { ChipLogProgress(Zcl, "ContentLauncherManager::HandleLaunchContent"); string dataString(data.data(), data.size()); @@ -103,6 +105,9 @@ void ContentLauncherManager::HandleLaunchContent(CommandResponseHelpermContentList) { diff --git a/examples/tv-app/tv-common/clusters/content-launcher/ContentLauncherManager.h b/examples/tv-app/tv-common/clusters/content-launcher/ContentLauncherManager.h index d08e708a4158da..51c5b1ab4b765e 100644 --- a/examples/tv-app/tv-common/clusters/content-launcher/ContentLauncherManager.h +++ b/examples/tv-app/tv-common/clusters/content-launcher/ContentLauncherManager.h @@ -29,6 +29,7 @@ using ContentLauncherDelegate = chip::app::Clusters::ContentLauncher::Delegate; using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LauncherResponse::Type; using ParameterType = chip::app::Clusters::ContentLauncher::Structs::ParameterStruct::DecodableType; using BrandingInformationType = chip::app::Clusters::ContentLauncher::Structs::BrandingInformationStruct::Type; +using PlaybackPreferencesType = chip::app::Clusters::ContentLauncher::Structs::PlaybackPreferencesStruct::DecodableType; class ContentEntry { @@ -45,7 +46,8 @@ class ContentLauncherManager : public ContentLauncherDelegate void HandleLaunchContent(CommandResponseHelper & helper, const chip::app::DataModel::DecodableList & parameterList, bool autoplay, - const CharSpan & data) override; + const CharSpan & data, const chip::Optional playbackPreferences, + bool useCurrentContext) override; void HandleLaunchUrl(CommandResponseHelper & helper, const CharSpan & contentUrl, const CharSpan & displayString, const BrandingInformationType & brandingInformation) override; CHIP_ERROR HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder) override; diff --git a/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.cpp b/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.cpp index 6d018d6522ede8..6eb71bd53a96bd 100644 --- a/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.cpp +++ b/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.cpp @@ -60,6 +60,40 @@ uint64_t MediaPlaybackManager::HandleGetSeekRangeEnd() return mDuration; } +CHIP_ERROR MediaPlaybackManager::HandleGetActiveAudioTrack(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(mActiveAudioTrack); +} + +CHIP_ERROR MediaPlaybackManager::HandleGetAvailableAudioTracks(AttributeValueEncoder & aEncoder) +{ + // TODO: Insert code here + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + for (auto const & audioTrack : mAvailableAudioTracks) + { + ReturnErrorOnFailure(encoder.Encode(audioTrack)); + } + return CHIP_NO_ERROR; + }); +} + +CHIP_ERROR MediaPlaybackManager::HandleGetActiveTextTrack(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(mActiveTextTrack); +} + +CHIP_ERROR MediaPlaybackManager::HandleGetAvailableTextTracks(AttributeValueEncoder & aEncoder) +{ + // TODO: Insert code here + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + for (auto const & textTrack : mAvailableTextTracks) + { + ReturnErrorOnFailure(encoder.Encode(textTrack)); + } + return CHIP_NO_ERROR; + }); +} + void MediaPlaybackManager::HandlePlay(CommandResponseHelper & helper) { // TODO: Insert code here @@ -97,7 +131,8 @@ void MediaPlaybackManager::HandleStop(CommandResponseHelper & helper) +void MediaPlaybackManager::HandleFastForward(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) { // TODO: Insert code here if (mPlaybackSpeed == kPlaybackMaxForwardSpeed) @@ -137,7 +172,8 @@ void MediaPlaybackManager::HandlePrevious(CommandResponseHelper & helper) +void MediaPlaybackManager::HandleRewind(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) { // TODO: Insert code here if (mPlaybackSpeed == kPlaybackMaxRewindSpeed) @@ -239,6 +275,56 @@ void MediaPlaybackManager::HandleStartOver(CommandResponseHelper= EMBER_AF_CONTENT_LAUNCHER_CLUSTER_SERVER_ENDPOINT_COUNT) diff --git a/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h b/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h index 9c0f8ce52f80e7..54fc9de5b67e87 100644 --- a/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h +++ b/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h @@ -19,12 +19,15 @@ #pragma once #include +#include using chip::app::AttributeValueEncoder; using chip::app::CommandResponseHelper; using MediaPlaybackDelegate = chip::app::Clusters::MediaPlayback::Delegate; using PlaybackResponseType = chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type; using PlaybackPositionType = chip::app::Clusters::MediaPlayback::Structs::PlaybackPositionStruct::Type; +using TrackType = chip::app::Clusters::MediaPlayback::Structs::TrackStruct::Type; +using TrackAttributesType = chip::app::Clusters::MediaPlayback::Structs::TrackAttributesStruct::Type; class MediaPlaybackManager : public MediaPlaybackDelegate { @@ -36,13 +39,19 @@ class MediaPlaybackManager : public MediaPlaybackDelegate float HandleGetPlaybackSpeed() override; uint64_t HandleGetSeekRangeStart() override; uint64_t HandleGetSeekRangeEnd() override; + CHIP_ERROR HandleGetActiveAudioTrack(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAvailableAudioTracks(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetActiveTextTrack(AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAvailableTextTracks(AttributeValueEncoder & aEncoder) override; void HandlePlay(CommandResponseHelper & helper) override; void HandlePause(CommandResponseHelper & helper) override; void HandleStop(CommandResponseHelper & helper) override; - void HandleFastForward(CommandResponseHelper & helper) override; + void HandleFastForward(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) override; void HandlePrevious(CommandResponseHelper & helper) override; - void HandleRewind(CommandResponseHelper & helper) override; + void HandleRewind(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) override; void HandleSkipBackward(CommandResponseHelper & helper, const uint64_t & deltaPositionMilliseconds) override; void HandleSkipForward(CommandResponseHelper & helper, @@ -50,6 +59,9 @@ class MediaPlaybackManager : public MediaPlaybackDelegate void HandleSeek(CommandResponseHelper & helper, const uint64_t & positionMilliseconds) override; void HandleNext(CommandResponseHelper & helper) override; void HandleStartOver(CommandResponseHelper & helper) override; + bool HandleActivateAudioTrack(const chip::CharSpan & trackId, const uint8_t & audioOutputIndex) override; + bool HandleActivateTextTrack(const chip::CharSpan & trackId) override; + bool HandleDeactivateTextTrack() override; uint32_t GetFeatureMap(chip::EndpointId endpoint) override; @@ -58,11 +70,46 @@ class MediaPlaybackManager : public MediaPlaybackDelegate // the CI test cases expect these values, and need to be fixed. chip::app::Clusters::MediaPlayback::PlaybackStateEnum mCurrentState = chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kPlaying; - PlaybackPositionType mPlaybackPosition = { 0, chip::app::DataModel::Nullable(0) }; - float mPlaybackSpeed = 0; - uint64_t mStartTime = 0; + PlaybackPositionType mPlaybackPosition = { 0, chip::app::DataModel::Nullable(0) }; + TrackType mActiveAudioTrack = { chip::CharSpan("activeAudioTrackId_0", 20), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode", 12), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }; + std::vector mAvailableAudioTracks = { + { chip::CharSpan("activeAudioTrackId_0", 20), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode", 12), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }, + { chip::CharSpan("activeAudioTrackId_1", 20), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode", 12), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) } + }; + TrackType mActiveTextTrack = { chip::CharSpan("activeTextTrackId_0", 20), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode", 12), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }; + std::vector mAvailableTextTracks = { + { chip::CharSpan("activeTextTrackId_0", 20), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode", 12), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }, + { chip::CharSpan("activeTextTrackId_1", 20), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode", 12), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) } + }; + float mPlaybackSpeed = 0; + uint64_t mStartTime = 0; // Magic number for testing. - uint64_t mDuration = 80000; + uint64_t mDuration = 80000; + bool mAudioAdvanceMuted = false; static const int kPlaybackMaxForwardSpeed = 10; static const int kPlaybackMaxRewindSpeed = -10; diff --git a/examples/tv-app/tv-common/include/AppTv.h b/examples/tv-app/tv-common/include/AppTv.h index 5f02536b3b86d0..8bfdf558dd1465 100644 --- a/examples/tv-app/tv-common/include/AppTv.h +++ b/examples/tv-app/tv-common/include/AppTv.h @@ -33,6 +33,8 @@ #include "application-basic/ApplicationBasicManager.h" #include "application-launcher/ApplicationLauncherManager.h" #include "channel/ChannelManager.h" +#include "content-app-observer/ContentAppObserver.h" +#include "content-control/ContentController.h" #include "content-launcher/ContentLauncherManager.h" #include "keypad-input/KeypadInputManager.h" #include "media-playback/MediaPlaybackManager.h" @@ -57,6 +59,8 @@ using ApplicationBasicDelegate = app::Clusters::ApplicationBasic::Delegate; using ApplicationLauncherDelegate = app::Clusters::ApplicationLauncher::Delegate; using ChannelDelegate = app::Clusters::Channel::Delegate; using ContentLauncherDelegate = app::Clusters::ContentLauncher::Delegate; +using ContentControllerDelegate = app::Clusters::ContentControl::Delegate; +using ContentAppObserverDelegate = app::Clusters::ContentAppObserver::Delegate; using KeypadInputDelegate = app::Clusters::KeypadInput::Delegate; using MediaPlaybackDelegate = app::Clusters::MediaPlayback::Delegate; using TargetNavigatorDelegate = app::Clusters::TargetNavigator::Delegate; @@ -85,6 +89,8 @@ class DLL_EXPORT ContentAppImpl : public ContentApp ApplicationLauncherDelegate * GetApplicationLauncherDelegate() override { return &mApplicationLauncherDelegate; }; ChannelDelegate * GetChannelDelegate() override { return &mChannelDelegate; }; ContentLauncherDelegate * GetContentLauncherDelegate() override { return &mContentLauncherDelegate; }; + ContentControllerDelegate * GetContentControlDelegate() override { return &mContentControlDelegate; }; + ContentAppObserverDelegate * GetContentAppObserverDelegate() override { return &mContentAppObserverDelegate; }; KeypadInputDelegate * GetKeypadInputDelegate() override { return &mKeypadInputDelegate; }; MediaPlaybackDelegate * GetMediaPlaybackDelegate() override { return &mMediaPlaybackDelegate; }; TargetNavigatorDelegate * GetTargetNavigatorDelegate() override { return &mTargetNavigatorDelegate; }; @@ -95,6 +101,8 @@ class DLL_EXPORT ContentAppImpl : public ContentApp ApplicationLauncherManager mApplicationLauncherDelegate; ChannelManager mChannelDelegate; ContentLauncherManager mContentLauncherDelegate; + ContentAppObserver mContentAppObserverDelegate; + ContentController mContentControlDelegate; KeypadInputManager mKeypadInputDelegate; MediaPlaybackManager mMediaPlaybackDelegate; TargetNavigatorManager mTargetNavigatorDelegate; diff --git a/examples/tv-app/tv-common/src/ZCLCallbacks.cpp b/examples/tv-app/tv-common/src/ZCLCallbacks.cpp index 8522f1f3d71f5a..8a5416ff3569b4 100644 --- a/examples/tv-app/tv-common/src/ZCLCallbacks.cpp +++ b/examples/tv-app/tv-common/src/ZCLCallbacks.cpp @@ -31,6 +31,8 @@ #include "application-launcher/ApplicationLauncherManager.h" #include "audio-output/AudioOutputManager.h" #include "channel/ChannelManager.h" +#include "content-app-observer/ContentAppObserver.h" +#include "content-control/ContentController.h" #include "content-launcher/ContentLauncherManager.h" #include "keypad-input/KeypadInputManager.h" #include "low-power/LowPowerManager.h" diff --git a/examples/tv-app/tv-common/tv-app.cmake b/examples/tv-app/tv-common/tv-app.cmake index cf257b8073fd1b..bfa554d0e77ec5 100644 --- a/examples/tv-app/tv-common/tv-app.cmake +++ b/examples/tv-app/tv-common/tv-app.cmake @@ -56,6 +56,8 @@ macro(chip_add_tv_app_common target) ${CHIP_TV_COMMON_BASE_DIR}/clusters/audio-output/AudioOutputManager.cpp ${CHIP_TV_COMMON_BASE_DIR}/clusters/channel/ChannelManager.cpp ${CHIP_TV_COMMON_BASE_DIR}/clusters/content-launcher/ContentLauncherManager.cpp + ${CHIP_TV_COMMON_BASE_DIR}/clusters/content-control/ContentController.cpp + ${CHIP_TV_COMMON_BASE_DIR}/clusters/content-app-observer/ContentAppObserver.cpp ${CHIP_TV_COMMON_BASE_DIR}/clusters/keypad-input/KeypadInputManager.cpp ${CHIP_TV_COMMON_BASE_DIR}/clusters/low-power/LowPowerManager.cpp ${CHIP_TV_COMMON_BASE_DIR}/clusters/media-input/MediaInputManager.cpp diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index c86cf83826d4c0..36a1cb63d8f41c 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -899,13 +899,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1079,13 +1079,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1142,7 +1142,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } @@ -2039,6 +2039,12 @@ cluster WakeOnLan = 1283 { cluster Channel = 1284 { revision 1; // NOTE: Default/not specifically set + enum ChannelTypeEnum : enum8 { + kSatellite = 0; + kCable = 1; + kTerrestrial = 2; + } + enum LineupInfoTypeEnum : enum8 { kMSO = 0; } @@ -2052,6 +2058,29 @@ cluster Channel = 1284 { bitmap Feature : bitmap32 { kChannelList = 0x1; kLineupInfo = 0x2; + kElectronicGuide = 0x3; + kRecordProgram = 0x4; + } + + bitmap RecordingFlagBitmap : bitmap32 { + kScheduled = 0x1; + kRecordSeries = 0x2; + kRecorded = 0x3; + } + + struct ProgramCastStruct { + char_string name = 0; + char_string role = 1; + } + + struct ProgramCategoryStruct { + char_string category = 0; + optional char_string subCategory = 1; + } + + struct SeriesInfoStruct { + char_string season = 0; + char_string episode = 1; } struct ChannelInfoStruct { @@ -2060,6 +2089,46 @@ cluster Channel = 1284 { optional char_string name = 2; optional char_string callSign = 3; optional char_string affiliateCallSign = 4; + optional char_string identifier = 5; + optional ChannelTypeEnum type = 6; + } + + struct ProgramStruct { + char_string identifier = 0; + ChannelInfoStruct channel = 1; + epoch_s startTime = 2; + epoch_s endTime = 3; + char_string title = 4; + optional char_string subtitle = 5; + optional char_string description = 6; + optional char_string audioLanguages[] = 7; + optional char_string ratings[] = 8; + optional char_string thumbnailUrl = 9; + optional char_string posterArtUrl = 10; + optional char_string dvbiUrl = 11; + optional char_string releaseDate = 12; + optional char_string parentalGuidanceText = 13; + optional RecordingFlagBitmap recordingFlag = 14; + optional nullable SeriesInfoStruct seriesInfo = 15; + optional ProgramCategoryStruct categoryList[] = 16; + optional ProgramCastStruct castList[] = 17; + optional ProgramCastStruct externalIDList[] = 18; + } + + struct PageTokenStruct { + optional int16u limit = 0; + optional char_string after = 1; + optional char_string before = 2; + } + + struct ChannelPagingStruct { + optional nullable PageTokenStruct previousToken = 0; + optional nullable PageTokenStruct nextToken = 1; + } + + struct AdditionalInfoStruct { + char_string name = 0; + char_string value = 1; } struct LineupInfoStruct { @@ -2097,12 +2166,47 @@ cluster Channel = 1284 { int16s count = 0; } + request struct GetProgramGuideRequest { + optional epoch_s startTime = 0; + optional epoch_s endTime = 1; + optional ChannelInfoStruct channelList[] = 2; + optional PageTokenStruct pageToken = 3; + optional RecordingFlagBitmap recordingFlag = 4; + optional AdditionalInfoStruct externalIDList[] = 5; + optional octet_string data = 6; + } + + response struct ProgramGuideResponse = 5 { + int16s channelPagingStruct = 0; + ProgramStruct programList[] = 1; + } + + request struct RecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + + request struct CancelRecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + /** Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. */ command ChangeChannel(ChangeChannelRequest): ChangeChannelResponse = 0; /** Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. */ command ChangeChannelByNumber(ChangeChannelByNumberRequest): DefaultSuccess = 2; /** This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. */ command SkipChannel(SkipChannelRequest): DefaultSuccess = 3; + /** This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ + command GetProgramGuide(GetProgramGuideRequest): ProgramGuideResponse = 4; + /** Record a specific program or series when it goes live. This functionality enables DVR recording features. */ + command RecordProgram(RecordProgramRequest): DefaultSuccess = 6; + /** Cancel recording for a specific program or series. */ + command CancelRecordProgram(CancelRecordProgramRequest): DefaultSuccess = 7; } /** This cluster provides an interface for UX navigation within a set of targets on a device or endpoint. */ @@ -2120,6 +2224,12 @@ cluster TargetNavigator = 1285 { char_string name = 1; } + info event TargetUpdated = 0 { + TargetInfoStruct targetList[] = 0; + int8u currentTarget = 1; + octet_string data = 2; + } + readonly attribute TargetInfoStruct targetList[] = 0; readonly attribute optional int8u currentTarget = 1; readonly attribute command_id generatedCommandList[] = 65528; @@ -2147,6 +2257,27 @@ cluster TargetNavigator = 1285 { cluster MediaPlayback = 1286 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum PlaybackStateEnum : enum8 { kPlaying = 0; kPaused = 1; @@ -2166,6 +2297,19 @@ cluster MediaPlayback = 1286 { bitmap Feature : bitmap32 { kAdvancedSeek = 0x1; kVariableSpeed = 0x2; + kTextTracks = 0x3; + kAudioTracks = 0x4; + kAudioAdvance = 0x5; + } + + struct TrackAttributesStruct { + char_string<32> languageCode = 0; + optional nullable char_string displayName = 1; + } + + struct TrackStruct { + char_string<32> id = 0; + nullable TrackAttributesStruct trackAttributes = 1; } struct PlaybackPositionStruct { @@ -2173,6 +2317,18 @@ cluster MediaPlayback = 1286 { nullable int64u position = 1; } + info event StateChanged = 0 { + PlaybackStateEnum currentState = 0; + EPOCH_US startTime = 1; + INT64U duration = 2; + PlaybackPositionStruct sampledPosition = 3; + single playbackSpeed = 4; + INT64U seekRangeEnd = 5; + INT64U seekRangeStart = 6; + optional OCTET_STRING data = 7; + boolean audioAdvanceUnmuted = 8; + } + readonly attribute PlaybackStateEnum currentState = 0; readonly attribute optional nullable epoch_us startTime = 1; readonly attribute optional nullable int64u duration = 2; @@ -2180,6 +2336,10 @@ cluster MediaPlayback = 1286 { readonly attribute optional single playbackSpeed = 4; readonly attribute optional nullable int64u seekRangeEnd = 5; readonly attribute optional nullable int64u seekRangeStart = 6; + readonly attribute optional nullable TrackStruct activeAudioTrack = 7; + readonly attribute optional nullable TrackStruct availableAudioTracks[] = 8; + readonly attribute optional nullable TrackStruct activeTextTrack = 9; + readonly attribute optional nullable TrackStruct availableTextTracks[] = 10; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2187,6 +2347,14 @@ cluster MediaPlayback = 1286 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct RewindRequest { + optional boolean audioAdvanceUnmuted = 0; + } + + request struct FastForwardRequest { + optional boolean audioAdvanceUnmuted = 0; + } + request struct SkipForwardRequest { int64u deltaPositionMilliseconds = 0; } @@ -2204,6 +2372,15 @@ cluster MediaPlayback = 1286 { int64u position = 0; } + request struct ActivateAudioTrackRequest { + CHAR_STRING trackID = 0; + INT8U audioOutputIndex = 1; + } + + request struct ActivateTextTrackRequest { + CHAR_STRING trackID = 0; + } + /** Upon receipt, this SHALL play media. */ command Play(): PlaybackResponse = 0; /** Upon receipt, this SHALL pause media. */ @@ -2217,15 +2394,21 @@ cluster MediaPlayback = 1286 { /** Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. */ command Next(): PlaybackResponse = 5; /** Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command Rewind(): PlaybackResponse = 6; + command Rewind(RewindRequest): PlaybackResponse = 6; /** Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command FastForward(): PlaybackResponse = 7; + command FastForward(FastForwardRequest): PlaybackResponse = 7; /** Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: */ command SkipForward(SkipForwardRequest): PlaybackResponse = 8; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command SkipBackward(SkipBackwardRequest): PlaybackResponse = 9; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command Seek(SeekRequest): PlaybackResponse = 11; + /** Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. */ + command ActivateAudioTrack(ActivateAudioTrackRequest): DefaultSuccess = 12; + /** Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. */ + command ActivateTextTrack(ActivateTextTrackRequest): DefaultSuccess = 13; + /** If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. */ + command DeactivateTextTrack(): DefaultSuccess = 14; } /** This cluster provides an interface for controlling the Input Selector on a media device such as a TV. */ @@ -2429,6 +2612,27 @@ cluster KeypadInput = 1289 { cluster ContentLauncher = 1290 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum MetricTypeEnum : enum8 { kPixels = 0; kPercentage = 1; @@ -2449,22 +2653,31 @@ cluster ContentLauncher = 1290 { kSportsTeam = 11; kType = 12; kVideo = 13; + kSeason = 14; + kEpisode = 15; + kAny = 16; } enum StatusEnum : enum8 { kSuccess = 0; kURLNotAvailable = 1; kAuthFailed = 2; + kTextTrackNotAvailable = 3; + kAudioTrackNotAvailable = 4; } bitmap Feature : bitmap32 { kContentSearch = 0x1; kURLPlayback = 0x2; + kAdvancedSeek = 0x3; + kTextTracks = 0x4; + kAudioTracks = 0x5; } bitmap SupportedProtocolsBitmap : bitmap32 { kDASH = 0x1; kHLS = 0x2; + kWebRTC = 0x2; } struct DimensionStruct { @@ -2473,6 +2686,18 @@ cluster ContentLauncher = 1290 { MetricTypeEnum metric = 2; } + struct TrackPreferenceStruct { + char_string<32> languageCode = 0; + optional CharacteristicEnum characteristics[] = 1; + int8u audioOutputIndex = 2; + } + + struct PlaybackPreferencesStruct { + int64u playbackPosition = 0; + TrackPreferenceStruct textTrack = 1; + optional TrackPreferenceStruct audioTracks[] = 2; + } + struct AdditionalInfoStruct { char_string<256> name = 0; char_string<8192> value = 1; @@ -2516,6 +2741,8 @@ cluster ContentLauncher = 1290 { ContentSearchStruct search = 0; boolean autoPlay = 1; optional char_string data = 2; + optional PlaybackPreferencesStruct playbackPreferences = 3; + optional boolean useCurrentContext = 4; } request struct LaunchURLRequest { @@ -2677,6 +2904,10 @@ cluster ApplicationBasic = 1293 { cluster AccountLogin = 1294 { revision 1; // NOTE: Default/not specifically set + critical event LoggedOut = 0 { + optional node_id node = 0; + } + readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2695,6 +2926,11 @@ cluster AccountLogin = 1294 { request struct LoginRequest { char_string<100> tempAccountIdentifier = 0; char_string setupPIN = 1; + optional node_id node = 2; + } + + request struct LogoutRequest { + optional node_id node = 0; } /** Upon receipt, the Content App checks if the account associated with the client Temp Account Identifier Rotating ID is the same acount that is active on the given Content App. If the accounts are the same, then the Content App includes the Setup PIN in the GetSetupPIN Response. */ @@ -2702,7 +2938,121 @@ cluster AccountLogin = 1294 { /** Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. */ fabric timed command access(invoke: administer) Login(LoginRequest): DefaultSuccess = 2; /** The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. */ - fabric timed command Logout(): DefaultSuccess = 3; + fabric timed command Logout(LogoutRequest): DefaultSuccess = 3; +} + +/** This cluster is used for managing the content control (including "parental control") settings on a media device such as a TV, or Set-top Box. */ +cluster ContentControl = 1295 { + revision 1; // NOTE: Default/not specifically set + + bitmap Feature : bitmap32 { + kScreenTime = 0x1; + kPINManagement = 0x2; + kBlockUnrated = 0x3; + kOnDemandContentRating = 0x4; + kScheduledContentRating = 0x5; + } + + struct RatingNameStruct { + char_string ratingName = 0; + optional char_string ratingNameDesc = 1; + } + + info event RemainingScreenTimeExpired = 0 { + } + + readonly attribute boolean enabled = 0; + readonly attribute optional RatingNameStruct onDemandRatings[] = 1; + readonly attribute optional char_string<8> onDemandRatingThreshold = 2; + readonly attribute optional RatingNameStruct scheduledContentRatings[] = 3; + readonly attribute optional char_string<8> scheduledContentRatingThreshold = 4; + readonly attribute optional elapsed_s screenDailyTime = 5; + readonly attribute optional elapsed_s remainingScreenTime = 6; + readonly attribute boolean blockUnrated = 7; + 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 UpdatePINRequest { + optional char_string oldPIN = 0; + char_string newPIN = 1; + } + + response struct ResetPINResponse = 2 { + char_string PINCode = 0; + } + + request struct AddBonusTimeRequest { + optional char_string PINCode = 0; + optional elapsed_s bonusTime = 1; + } + + request struct SetScreenDailyTimeRequest { + elapsed_s screenTime = 0; + } + + request struct SetOnDemandRatingThresholdRequest { + char_string rating = 0; + } + + request struct SetScheduledContentRatingThresholdRequest { + char_string rating = 0; + } + + /** The purpose of this command is to update the PIN used for protecting configuration of the content control settings. Upon success, the old PIN SHALL no longer work. The PIN is used to ensure that only the Node (or User) with the PIN code can make changes to the Content Control settings, for example, turn off Content Controls or modify the ScreenDailyTime. The PIN is composed of a numeric string of up to 6 human readable characters (displayable) . Upon receipt of this command, the media device SHALL check if the OldPIN field of this command is the same as the current PIN. If the PINs are the same, then the PIN code SHALL be set to NewPIN. Otherwise a response with InvalidPINCode error status SHALL be returned. The media device MAY provide a default PIN to the User via an out of band mechanism. For security reasons, it is recommended that a client encourage the user to update the PIN from its default value when performing configuration of the Content Control settings exposed by this cluster. The ResetPIN command can also be used to obtain the default PIN. */ + command UpdatePIN(UpdatePINRequest): DefaultSuccess = 0; + /** The purpose of this command is to reset the PIN. If this command is executed successfully, a ResetPINResponse command with a new PIN SHALL be returned. */ + command ResetPIN(): ResetPINResponse = 1; + /** The purpose of this command is to turn on the Content Control feature on a media device. On receipt of the Enable command, the media device SHALL set the Enabled attribute to TRUE. */ + command Enable(): DefaultSuccess = 3; + /** The purpose of this command is to turn off the Content Control feature on a media device. On receipt of the Disable command, the media device SHALL set the Enabled attribute to FALSE. */ + command Disable(): DefaultSuccess = 4; + /** The purpose of this command is to add the extra screen time for the user. If a client with Operate privilege invokes this command, the media device SHALL check whether the PINCode passed in the command matches the current PINCode value. If these match, then the RemainingScreenTime attribute SHALL be increased by the specified BonusTime value. If the PINs do not match, then a response with InvalidPINCode error status SHALL be returned, and no changes SHALL be made to RemainingScreenTime. If a client with Manage privilege or greater invokes this command, the media device SHALL ignore the PINCode field and directly increase the RemainingScreenTime attribute by the specified BonusTime value. A server that does not support the PM feature SHALL respond with InvalidPINCode to clients that only have Operate privilege unless: It has been provided with the PIN value to expect via an out of band mechanism, and The client has provided a PINCode that matches the expected PIN value. */ + command AddBonusTime(AddBonusTimeRequest): DefaultSuccess = 5; + /** The purpose of this command is to set the ScreenDailyTime attribute. On receipt of the SetScreenDailyTime command, the media device SHALL set the ScreenDailyTime attribute to the ScreenTime value. */ + command SetScreenDailyTime(SetScreenDailyTimeRequest): DefaultSuccess = 6; + /** The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the BlockUnratedContent command, the media device SHALL set the BlockUnrated attribute to TRUE. */ + command BlockUnratedContent(): DefaultSuccess = 7; + /** The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the UnblockUnratedContent command, the media device SHALL set the BlockUnrated attribute to FALSE. */ + command UnblockUnratedContent(): DefaultSuccess = 8; + /** The purpose of this command is to set the OnDemandRatingThreshold attribute. On receipt of the SetOnDemandRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the OnDemandRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. */ + command SetOnDemandRatingThreshold(SetOnDemandRatingThresholdRequest): DefaultSuccess = 9; + /** The purpose of this command is to set ScheduledContentRatingThreshold attribute. On receipt of the SetScheduledContentRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the ScheduledContentRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. */ + command SetScheduledContentRatingThreshold(SetScheduledContentRatingThresholdRequest): DefaultSuccess = 10; +} + +/** This cluster provides an interface for sending targeted commands to an Observer of a Content App on a Video Player device such as a Streaming Media Player, Smart TV or Smart Screen. The cluster server for Content App Observer is implemented by an endpoint that communicates with a Content App, such as a Casting Video Client. The cluster client for Content App Observer is implemented by a Content App endpoint. A Content App is informed of the NodeId of an Observer when a binding is set on the Content App. The Content App can then send the ContentAppMessage to the Observer (server cluster), and the Observer responds with a ContentAppMessageResponse. */ +cluster ContentAppObserver = 1296 { + revision 1; // NOTE: Default/not specifically set + + enum StatusEnum : enum8 { + kSuccess = 0; + kUnexpectedData = 1; + } + + 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 ContentAppMessageRequest { + optional char_string data = 0; + char_string encodingHint = 1; + } + + response struct ContentAppMessageResponse = 1 { + optional StatusEnum status = 0; + char_string data = 1; + char_string encodingHint = 2; + } + + /** Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. */ + command ContentAppMessage(ContentAppMessageRequest): ContentAppMessageResponse = 0; } endpoint 0 { @@ -3097,9 +3447,14 @@ endpoint 1 { handle command ChangeChannelResponse; handle command ChangeChannelByNumber; handle command SkipChannel; + handle command GetProgramGuide; + handle command ProgramGuideResponse; + handle command RecordProgram; + handle command CancelRecordProgram; } server cluster TargetNavigator { + emits event TargetUpdated; callback attribute targetList; ram attribute currentTarget default = 0; ram attribute featureMap default = 0; @@ -3110,6 +3465,7 @@ endpoint 1 { } server cluster MediaPlayback { + emits event StateChanged; ram attribute currentState default = 0x00; ram attribute startTime default = 0x00; ram attribute duration default = 0; @@ -3117,6 +3473,10 @@ endpoint 1 { ram attribute playbackSpeed default = 0; ram attribute seekRangeEnd; ram attribute seekRangeStart; + callback attribute activeAudioTrack; + callback attribute availableAudioTracks; + callback attribute activeTextTrack; + callback attribute availableTextTracks; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; @@ -3135,6 +3495,9 @@ endpoint 1 { handle command SkipBackward; handle command PlaybackResponse; handle command Seek; + handle command ActivateAudioTrack; + handle command ActivateTextTrack; + handle command DeactivateTextTrack; } server cluster MediaInput { @@ -3198,6 +3561,48 @@ endpoint 1 { handle command HideApp; handle command LauncherResponse; } + + server cluster ContentControl { + emits event RemainingScreenTimeExpired; + ram attribute enabled; + callback attribute onDemandRatings; + ram attribute onDemandRatingThreshold; + callback attribute scheduledContentRatings; + ram attribute scheduledContentRatingThreshold; + ram attribute screenDailyTime; + ram attribute remainingScreenTime; + ram attribute blockUnrated; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command UpdatePIN; + handle command ResetPIN; + handle command ResetPINResponse; + handle command Enable; + handle command Disable; + handle command AddBonusTime; + handle command SetScreenDailyTime; + handle command BlockUnratedContent; + handle command UnblockUnratedContent; + handle command SetOnDemandRatingThreshold; + handle command SetScheduledContentRatingThreshold; + } + + server cluster ContentAppObserver { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ContentAppMessage; + handle command ContentAppMessageResponse; + } } endpoint 2 { device type ma_speaker = 34, version 1; @@ -3264,6 +3669,9 @@ endpoint 3 { } server cluster Channel { + callback attribute channelList; + callback attribute lineup; + callback attribute currentChannel; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; @@ -3274,6 +3682,10 @@ endpoint 3 { handle command ChangeChannelResponse; handle command ChangeChannelByNumber; handle command SkipChannel; + handle command GetProgramGuide; + handle command ProgramGuideResponse; + handle command RecordProgram; + handle command CancelRecordProgram; } server cluster TargetNavigator { @@ -3289,6 +3701,7 @@ endpoint 3 { } server cluster MediaPlayback { + emits event StateChanged; ram attribute currentState default = 0x00; ram attribute startTime default = 0xFF; ram attribute duration; @@ -3296,6 +3709,10 @@ endpoint 3 { ram attribute playbackSpeed; ram attribute seekRangeEnd; ram attribute seekRangeStart; + callback attribute activeAudioTrack; + callback attribute availableAudioTracks; + callback attribute activeTextTrack; + callback attribute availableTextTracks; ram attribute featureMap default = 0x0003; ram attribute clusterRevision default = 1; @@ -3311,6 +3728,9 @@ endpoint 3 { handle command SkipBackward; handle command PlaybackResponse; handle command Seek; + handle command ActivateAudioTrack; + handle command ActivateTextTrack; + handle command DeactivateTextTrack; } server cluster KeypadInput { @@ -3373,6 +3793,48 @@ endpoint 3 { handle command Login; handle command Logout; } + + server cluster ContentControl { + emits event RemainingScreenTimeExpired; + ram attribute enabled; + callback attribute onDemandRatings; + ram attribute onDemandRatingThreshold; + callback attribute scheduledContentRatings; + ram attribute scheduledContentRatingThreshold; + ram attribute screenDailyTime; + ram attribute remainingScreenTime; + ram attribute blockUnrated; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command UpdatePIN; + handle command ResetPIN; + handle command ResetPINResponse; + handle command Enable; + handle command Disable; + handle command AddBonusTime; + handle command SetScreenDailyTime; + handle command BlockUnratedContent; + handle command UnblockUnratedContent; + handle command SetOnDemandRatingThreshold; + handle command SetScheduledContentRatingThreshold; + } + + server cluster ContentAppObserver { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ContentAppMessage; + handle command ContentAppMessageResponse; + } } diff --git a/examples/tv-app/tv-common/tv-app.zap b/examples/tv-app/tv-common/tv-app.zap index e8f086310fd08c..ee3c171287a754 100644 --- a/examples/tv-app/tv-common/tv-app.zap +++ b/examples/tv-app/tv-common/tv-app.zap @@ -4788,6 +4788,38 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "GetProgramGuide", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ProgramGuideResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RecordProgram", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CancelRecordProgram", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -4963,6 +4995,15 @@ "maxInterval": 65344, "reportableChange": 0 } + ], + "events": [ + { + "name": "TargetUpdated", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } ] }, { @@ -5068,6 +5109,30 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "ActivateAudioTrack", + "code": 12, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ActivateTextTrack", + "code": 13, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "DeactivateTextTrack", + "code": 14, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -5183,6 +5248,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "ActiveAudioTrack", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "TrackStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AvailableAudioTracks", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveTextTrack", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "TrackStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AvailableTextTracks", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -5263,6 +5392,15 @@ "maxInterval": 65534, "reportableChange": 0 } + ], + "events": [ + { + "name": "StateChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } ] }, { @@ -5824,46 +5962,17 @@ "reportableChange": 0 } ] - } - ] - }, - { - "id": 3, - "name": "MA-speaker", - "deviceTypeRef": { - "code": 34, - "profileId": 259, - "label": "MA-speaker", - "name": "MA-speaker" - }, - "deviceTypes": [ - { - "code": 34, - "profileId": 259, - "label": "MA-speaker", - "name": "MA-speaker" - } - ], - "deviceVersions": [ - 1 - ], - "deviceIdentifiers": [ - 34 - ], - "deviceTypeName": "MA-speaker", - "deviceTypeCode": 34, - "deviceTypeProfileId": 259, - "clusters": [ + }, { - "name": "On/Off", - "code": 6, + "name": "Content Control", + "code": 1295, "mfgCode": null, - "define": "ON_OFF_CLUSTER", + "define": "CONTENT_CONTROL_CLUSTER", "side": "server", "enabled": 1, "commands": [ { - "name": "Off", + "name": "UpdatePIN", "code": 0, "mfgCode": null, "source": "client", @@ -5871,7 +5980,7 @@ "isEnabled": 1 }, { - "name": "On", + "name": "ResetPIN", "code": 1, "mfgCode": null, "source": "client", @@ -5879,132 +5988,72 @@ "isEnabled": 1 }, { - "name": "Toggle", + "name": "ResetPINResponse", "code": 2, "mfgCode": null, - "source": "client", - "isIncoming": 1, + "source": "server", + "isIncoming": 0, "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "OnOff", - "code": 0, - "mfgCode": null, - "side": "server", - "type": "boolean", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0x00", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "server", - "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": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "5", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - } - ] - }, - { - "name": "Level Control", - "code": 8, - "mfgCode": null, - "define": "LEVEL_CONTROL_CLUSTER", - "side": "server", - "enabled": 1, - "commands": [ - { - "name": "MoveToLevel", - "code": 0, + "name": "Enable", + "code": 3, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "Move", - "code": 1, + "name": "Disable", + "code": 4, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "Step", - "code": 2, + "name": "AddBonusTime", + "code": 5, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "Stop", - "code": 3, + "name": "SetScreenDailyTime", + "code": 6, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "MoveToLevelWithOnOff", - "code": 4, + "name": "BlockUnratedContent", + "code": 7, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "MoveWithOnOff", - "code": 5, + "name": "UnblockUnratedContent", + "code": 8, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "StepWithOnOff", - "code": 6, + "name": "SetOnDemandRatingThreshold", + "code": 9, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "StopWithOnOff", - "code": 7, + "name": "SetScheduledContentRatingThreshold", + "code": 10, "mfgCode": null, "source": "client", "isIncoming": 1, @@ -6013,224 +6062,192 @@ ], "attributes": [ { - "name": "CurrentLevel", + "name": "Enabled", "code": 0, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "boolean", "included": 1, - "storageOption": "NVM", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x00", + "defaultValue": "", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "RemainingTime", + "name": "OnDemandRatings", "code": 1, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0x0000", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "MinLevel", + "name": "OnDemandRatingThreshold", "code": 2, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "char_string", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x00", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "MaxLevel", + "name": "ScheduledContentRatings", "code": 3, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0xFF", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "CurrentFrequency", + "name": "ScheduledContentRatingThreshold", "code": 4, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "char_string", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x0000", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "MinFrequency", + "name": "ScreenDailyTime", "code": 5, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "elapsed_s", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x0000", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "MaxFrequency", + "name": "RemainingScreenTime", "code": 6, "mfgCode": null, "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0x0000", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "Options", - "code": 15, - "mfgCode": null, - "side": "server", - "type": "OptionsBitmap", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0x00", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "OnOffTransitionTime", - "code": 16, - "mfgCode": null, - "side": "server", - "type": "int16u", + "type": "elapsed_s", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x0000", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "OnLevel", - "code": 17, + "name": "BlockUnrated", + "code": 7, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "boolean", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0xFE", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "OnTransitionTime", - "code": 18, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "OffTransitionTime", - "code": 19, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "DefaultMoveRate", - "code": 20, + "name": "EventList", + "code": 65530, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "StartUpCurrentLevel", - "code": 16384, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "array", "included": 1, - "storageOption": "NVM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "255", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6246,7 +6263,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "0", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6262,26 +6279,53 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "5", + "defaultValue": "1", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 } + ], + "events": [ + { + "name": "RemainingScreenTimeExpired", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } ] }, { - "name": "Descriptor", - "code": 29, + "name": "Content App Observer", + "code": 1296, "mfgCode": null, - "define": "DESCRIPTOR_CLUSTER", + "define": "CONTENT_APP_OBSERVER_CLUSTER", "side": "server", "enabled": 1, - "attributes": [ + "commands": [ { - "name": "DeviceTypeList", + "name": "ContentAppMessage", "code": 0, "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ContentAppMessageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, "side": "server", "type": "array", "included": 1, @@ -6295,8 +6339,8 @@ "reportableChange": 0 }, { - "name": "ServerList", - "code": 1, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", "type": "array", @@ -6311,8 +6355,8 @@ "reportableChange": 0 }, { - "name": "ClientList", - "code": 2, + "name": "EventList", + "code": 65530, "mfgCode": null, "side": "server", "type": "array", @@ -6327,8 +6371,8 @@ "reportableChange": 0 }, { - "name": "PartsList", - "code": 3, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", "type": "array", @@ -6365,10 +6409,10 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6379,91 +6423,970 @@ ] }, { - "id": 4, - "name": "MA-contentapplication", + "id": 3, + "name": "MA-speaker", "deviceTypeRef": { - "code": 36, + "code": 34, "profileId": 259, - "label": "MA-contentapp", - "name": "MA-contentapp" + "label": "MA-speaker", + "name": "MA-speaker" }, "deviceTypes": [ { - "code": 36, + "code": 34, "profileId": 259, - "label": "MA-contentapp", - "name": "MA-contentapp" + "label": "MA-speaker", + "name": "MA-speaker" } ], "deviceVersions": [ 1 ], "deviceIdentifiers": [ - 36 + 34 ], - "deviceTypeName": "MA-contentapp", - "deviceTypeCode": 36, + "deviceTypeName": "MA-speaker", + "deviceTypeCode": 34, "deviceTypeProfileId": 259, "clusters": [ { - "name": "Descriptor", - "code": 29, + "name": "On/Off", + "code": 6, "mfgCode": null, - "define": "DESCRIPTOR_CLUSTER", + "define": "ON_OFF_CLUSTER", "side": "server", "enabled": 1, + "commands": [ + { + "name": "Off", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "On", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Toggle", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], "attributes": [ { - "name": "DeviceTypeList", + "name": "OnOff", "code": 0, "mfgCode": null, "side": "server", - "type": "array", + "type": "boolean", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "0x00", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 }, { - "name": "ServerList", - "code": 1, + "name": "FeatureMap", + "code": 65532, "mfgCode": null, "side": "server", - "type": "array", + "type": "bitmap32", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "0", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ClientList", - "code": 2, + "name": "ClusterRevision", + "code": 65533, "mfgCode": null, "side": "server", - "type": "array", + "type": "int16u", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "5", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 - }, + } + ] + }, + { + "name": "Level Control", + "code": 8, + "mfgCode": null, + "define": "LEVEL_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "MoveToLevel", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Move", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Step", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Stop", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "MoveToLevelWithOnOff", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "MoveWithOnOff", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StepWithOnOff", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StopWithOnOff", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "CurrentLevel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RemainingTime", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MinLevel", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxLevel", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFF", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentFrequency", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MinFrequency", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxFrequency", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Options", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "OptionsBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnOffTransitionTime", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnLevel", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFE", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnTransitionTime", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OffTransitionTime", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DefaultMoveRate", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StartUpCurrentLevel", + "code": 16384, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "255", + "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": "1", + "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": "5", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "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": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 4, + "name": "MA-contentapplication", + "deviceTypeRef": { + "code": 36, + "profileId": 259, + "label": "MA-contentapp", + "name": "MA-contentapp" + }, + "deviceTypes": [ + { + "code": 36, + "profileId": 259, + "label": "MA-contentapp", + "name": "MA-contentapp" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 36 + ], + "deviceTypeName": "MA-contentapp", + "deviceTypeCode": 36, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "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": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Channel", + "code": 1284, + "mfgCode": null, + "define": "CHANNEL_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ChangeChannel", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ChangeChannelResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ChangeChannelByNumber", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SkipChannel", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetProgramGuide", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ProgramGuideResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RecordProgram", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CancelRecordProgram", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "ChannelList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Lineup", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "LineupInfoStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentChannel", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "ChannelInfoStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "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": null, + "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": null, + "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": null, + "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": "0", + "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": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Target Navigator", + "code": 1285, + "mfgCode": null, + "define": "TARGET_NAVIGATOR_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "NavigateTarget", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NavigateTargetResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "TargetList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { - "name": "PartsList", - "code": 3, + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "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": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", "type": "array", @@ -6500,10 +7423,10 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6512,15 +7435,15 @@ ] }, { - "name": "Channel", - "code": 1284, + "name": "Media Playback", + "code": 1286, "mfgCode": null, - "define": "CHANNEL_CLUSTER", + "define": "MEDIA_PLAYBACK_CLUSTER", "side": "server", "enabled": 1, "commands": [ { - "name": "ChangeChannel", + "name": "Play", "code": 0, "mfgCode": null, "source": "client", @@ -6528,34 +7451,250 @@ "isEnabled": 1 }, { - "name": "ChangeChannelResponse", + "name": "Pause", "code": 1, "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Stop", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StartOver", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Previous", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Next", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Rewind", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "FastForward", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SkipForward", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SkipBackward", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "PlaybackResponse", + "code": 10, + "mfgCode": null, "source": "server", "isIncoming": 0, "isEnabled": 1 }, { - "name": "ChangeChannelByNumber", - "code": 2, + "name": "Seek", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ActivateAudioTrack", + "code": 12, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ActivateTextTrack", + "code": 13, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "DeactivateTextTrack", + "code": 14, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "CurrentState", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PlaybackStateEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "StartTime", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "epoch_us", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFF", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Duration", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SampledPosition", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "PlaybackPositionStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PlaybackSpeed", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "single", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SeekRangeEnd", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SeekRangeStart", + "code": 6, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 }, { - "name": "SkipChannel", - "code": 3, + "name": "ActiveAudioTrack", + "code": 7, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - } - ], - "attributes": [ + "side": "server", + "type": "TrackStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { - "name": "GeneratedCommandList", - "code": 65528, + "name": "AvailableAudioTracks", + "code": 8, "mfgCode": null, "side": "server", "type": "array", @@ -6570,11 +7709,11 @@ "reportableChange": 0 }, { - "name": "AcceptedCommandList", - "code": 65529, + "name": "ActiveTextTrack", + "code": 9, "mfgCode": null, "side": "server", - "type": "array", + "type": "TrackStruct", "included": 1, "storageOption": "External", "singleton": 0, @@ -6586,8 +7725,8 @@ "reportableChange": 0 }, { - "name": "AttributeList", - "code": 65531, + "name": "AvailableTextTracks", + "code": 10, "mfgCode": null, "side": "server", "type": "array", @@ -6611,7 +7750,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "0x0003", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6629,22 +7768,31 @@ "bounded": 0, "defaultValue": "1", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 } + ], + "events": [ + { + "name": "StateChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } ] }, { - "name": "Target Navigator", - "code": 1285, + "name": "Keypad Input", + "code": 1289, "mfgCode": null, - "define": "TARGET_NAVIGATOR_CLUSTER", + "define": "KEYPAD_INPUT_CLUSTER", "side": "server", "enabled": 1, "commands": [ { - "name": "NavigateTarget", + "name": "SendKey", "code": 0, "mfgCode": null, "source": "client", @@ -6652,7 +7800,7 @@ "isEnabled": 1 }, { - "name": "NavigateTargetResponse", + "name": "SendKeyResponse", "code": 1, "mfgCode": null, "source": "server", @@ -6661,22 +7809,6 @@ } ], "attributes": [ - { - "name": "TargetList", - "code": 0, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "GeneratedCommandList", "code": 65528, @@ -6760,15 +7892,15 @@ ] }, { - "name": "Media Playback", - "code": 1286, + "name": "Content Launcher", + "code": 1290, "mfgCode": null, - "define": "MEDIA_PLAYBACK_CLUSTER", + "define": "CONTENT_LAUNCHER_CLUSTER", "side": "server", "enabled": 1, "commands": [ { - "name": "Play", + "name": "LaunchContent", "code": 0, "mfgCode": null, "source": "client", @@ -6776,7 +7908,7 @@ "isEnabled": 1 }, { - "name": "Pause", + "name": "LaunchURL", "code": 1, "mfgCode": null, "source": "client", @@ -6784,141 +7916,21 @@ "isEnabled": 1 }, { - "name": "Stop", + "name": "LauncherResponse", "code": 2, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "StartOver", - "code": 3, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "Previous", - "code": 4, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "Next", - "code": 5, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "Rewind", - "code": 6, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "FastForward", - "code": 7, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "SkipForward", - "code": 8, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "SkipBackward", - "code": 9, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "PlaybackResponse", - "code": 10, - "mfgCode": null, "source": "server", "isIncoming": 0, "isEnabled": 1 - }, - { - "name": "Seek", - "code": 11, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 } ], "attributes": [ { - "name": "CurrentState", + "name": "AcceptHeader", "code": 0, "mfgCode": null, "side": "server", - "type": "PlaybackStateEnum", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0x00", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "StartTime", - "code": 1, - "mfgCode": null, - "side": "server", - "type": "epoch_us", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0xFF", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "Duration", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "int64u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "SampledPosition", - "code": 3, - "mfgCode": null, - "side": "server", - "type": "PlaybackPositionStruct", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -6930,43 +7942,11 @@ "reportableChange": 0 }, { - "name": "PlaybackSpeed", - "code": 4, - "mfgCode": null, - "side": "server", - "type": "single", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "SeekRangeEnd", - "code": 5, - "mfgCode": null, - "side": "server", - "type": "int64u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "SeekRangeStart", - "code": 6, + "name": "SupportedStreamingProtocols", + "code": 1, "mfgCode": null, "side": "server", - "type": "int64u", + "type": "SupportedProtocolsBitmap", "included": 1, "storageOption": "RAM", "singleton": 0, @@ -7012,15 +7992,15 @@ ] }, { - "name": "Keypad Input", - "code": 1289, + "name": "Application Launcher", + "code": 1292, "mfgCode": null, - "define": "KEYPAD_INPUT_CLUSTER", + "define": "APPLICATION_LAUNCHER_CLUSTER", "side": "server", "enabled": 1, "commands": [ { - "name": "SendKey", + "name": "LaunchApp", "code": 0, "mfgCode": null, "source": "client", @@ -7028,9 +8008,25 @@ "isEnabled": 1 }, { - "name": "SendKeyResponse", + "name": "StopApp", "code": 1, "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "HideApp", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "LauncherResponse", + "code": 3, + "mfgCode": null, "source": "server", "isIncoming": 0, "isEnabled": 1 @@ -7120,147 +8116,141 @@ ] }, { - "name": "Content Launcher", - "code": 1290, + "name": "Application Basic", + "code": 1293, "mfgCode": null, - "define": "CONTENT_LAUNCHER_CLUSTER", + "define": "APPLICATION_BASIC_CLUSTER", "side": "server", "enabled": 1, - "commands": [ + "attributes": [ { - "name": "LaunchContent", + "name": "VendorName", "code": 0, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 }, { - "name": "LaunchURL", + "name": "VendorID", "code": 1, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 }, { - "name": "LauncherResponse", + "name": "ApplicationName", "code": 2, "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "AcceptHeader", - "code": 0, - "mfgCode": null, "side": "server", - "type": "array", + "type": "long_char_string", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 }, { - "name": "SupportedStreamingProtocols", - "code": 1, + "name": "ProductID", + "code": 3, "mfgCode": null, "side": "server", - "type": "SupportedProtocolsBitmap", + "type": "int16u", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": "0x00", "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 }, { - "name": "FeatureMap", - "code": 65532, + "name": "Application", + "code": 4, "mfgCode": null, "side": "server", - "type": "bitmap32", + "type": "ApplicationStruct", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0x0003", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ClusterRevision", - "code": 65533, + "name": "Status", + "code": 5, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "ApplicationStatusEnum", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "", "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 - } - ] - }, - { - "name": "Application Launcher", - "code": 1292, - "mfgCode": null, - "define": "APPLICATION_LAUNCHER_CLUSTER", - "side": "server", - "enabled": 1, - "commands": [ - { - "name": "LaunchApp", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 }, { - "name": "StopApp", - "code": 1, + "name": "ApplicationVersion", + "code": 6, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 }, { - "name": "HideApp", - "code": 2, + "name": "AllowedVendorList", + "code": 7, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 }, - { - "name": "LauncherResponse", - "code": 3, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - } - ], - "attributes": [ { "name": "GeneratedCommandList", "code": 65528, @@ -7337,143 +8327,309 @@ "bounded": 0, "defaultValue": "1", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Account Login", + "code": 1294, + "mfgCode": null, + "define": "ACCOUNT_LOGIN_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "GetSetupPIN", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetSetupPINResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "Login", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Logout", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "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": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 } ] }, { - "name": "Application Basic", - "code": 1293, + "name": "Content Control", + "code": 1295, "mfgCode": null, - "define": "APPLICATION_BASIC_CLUSTER", + "define": "CONTENT_CONTROL_CLUSTER", "side": "server", "enabled": 1, + "commands": [ + { + "name": "UpdatePIN", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ResetPIN", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ResetPINResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "Enable", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Disable", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddBonusTime", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetScreenDailyTime", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "BlockUnratedContent", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UnblockUnratedContent", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetOnDemandRatingThreshold", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetScheduledContentRatingThreshold", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], "attributes": [ { - "name": "VendorName", + "name": "Enabled", "code": 0, "mfgCode": null, "side": "server", - "type": "char_string", + "type": "boolean", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, "defaultValue": "", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "VendorID", + "name": "OnDemandRatings", "code": 1, "mfgCode": null, "side": "server", - "type": "vendor_id", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ApplicationName", + "name": "OnDemandRatingThreshold", "code": 2, "mfgCode": null, "side": "server", - "type": "long_char_string", + "type": "char_string", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, "defaultValue": "", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ProductID", + "name": "ScheduledContentRatings", "code": 3, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0x00", + "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "Application", + "name": "ScheduledContentRatingThreshold", "code": 4, "mfgCode": null, "side": "server", - "type": "ApplicationStruct", + "type": "char_string", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "Status", + "name": "ScreenDailyTime", "code": 5, "mfgCode": null, "side": "server", - "type": "ApplicationStatusEnum", + "type": "elapsed_s", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, "defaultValue": "", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ApplicationVersion", + "name": "RemainingScreenTime", "code": 6, "mfgCode": null, "side": "server", - "type": "char_string", + "type": "elapsed_s", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, "defaultValue": "", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "AllowedVendorList", + "name": "BlockUnrated", "code": 7, "mfgCode": null, "side": "server", - "type": "array", + "type": "boolean", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -7511,6 +8667,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "AttributeList", "code": 65531, @@ -7555,22 +8727,31 @@ "bounded": 0, "defaultValue": "1", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 } + ], + "events": [ + { + "name": "RemainingScreenTimeExpired", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } ] }, { - "name": "Account Login", - "code": 1294, + "name": "Content App Observer", + "code": 1296, "mfgCode": null, - "define": "ACCOUNT_LOGIN_CLUSTER", + "define": "CONTENT_APP_OBSERVER_CLUSTER", "side": "server", "enabled": 1, "commands": [ { - "name": "GetSetupPIN", + "name": "ContentAppMessage", "code": 0, "mfgCode": null, "source": "client", @@ -7578,31 +8759,79 @@ "isEnabled": 1 }, { - "name": "GetSetupPINResponse", + "name": "ContentAppMessageResponse", "code": 1, "mfgCode": null, "source": "server", "isIncoming": 0, "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 }, { - "name": "Login", - "code": 2, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 }, { - "name": "Logout", - "code": 3, + "name": "EventList", + "code": 65530, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - } - ], - "attributes": [ + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "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": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -7631,8 +8860,8 @@ "bounded": 0, "defaultValue": "1", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 } ] @@ -7669,5 +8898,6 @@ "endpointId": 3, "networkId": 0 } - ] + ], + "log": [] } \ No newline at end of file diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter index e892d579cac82e..810f249772319e 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter @@ -914,13 +914,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1501,6 +1501,12 @@ cluster WakeOnLan = 1283 { cluster Channel = 1284 { revision 1; // NOTE: Default/not specifically set + enum ChannelTypeEnum : enum8 { + kSatellite = 0; + kCable = 1; + kTerrestrial = 2; + } + enum LineupInfoTypeEnum : enum8 { kMSO = 0; } @@ -1514,6 +1520,29 @@ cluster Channel = 1284 { bitmap Feature : bitmap32 { kChannelList = 0x1; kLineupInfo = 0x2; + kElectronicGuide = 0x3; + kRecordProgram = 0x4; + } + + bitmap RecordingFlagBitmap : bitmap32 { + kScheduled = 0x1; + kRecordSeries = 0x2; + kRecorded = 0x3; + } + + struct ProgramCastStruct { + char_string name = 0; + char_string role = 1; + } + + struct ProgramCategoryStruct { + char_string category = 0; + optional char_string subCategory = 1; + } + + struct SeriesInfoStruct { + char_string season = 0; + char_string episode = 1; } struct ChannelInfoStruct { @@ -1522,6 +1551,46 @@ cluster Channel = 1284 { optional char_string name = 2; optional char_string callSign = 3; optional char_string affiliateCallSign = 4; + optional char_string identifier = 5; + optional ChannelTypeEnum type = 6; + } + + struct ProgramStruct { + char_string identifier = 0; + ChannelInfoStruct channel = 1; + epoch_s startTime = 2; + epoch_s endTime = 3; + char_string title = 4; + optional char_string subtitle = 5; + optional char_string description = 6; + optional char_string audioLanguages[] = 7; + optional char_string ratings[] = 8; + optional char_string thumbnailUrl = 9; + optional char_string posterArtUrl = 10; + optional char_string dvbiUrl = 11; + optional char_string releaseDate = 12; + optional char_string parentalGuidanceText = 13; + optional RecordingFlagBitmap recordingFlag = 14; + optional nullable SeriesInfoStruct seriesInfo = 15; + optional ProgramCategoryStruct categoryList[] = 16; + optional ProgramCastStruct castList[] = 17; + optional ProgramCastStruct externalIDList[] = 18; + } + + struct PageTokenStruct { + optional int16u limit = 0; + optional char_string after = 1; + optional char_string before = 2; + } + + struct ChannelPagingStruct { + optional nullable PageTokenStruct previousToken = 0; + optional nullable PageTokenStruct nextToken = 1; + } + + struct AdditionalInfoStruct { + char_string name = 0; + char_string value = 1; } struct LineupInfoStruct { @@ -1559,12 +1628,47 @@ cluster Channel = 1284 { int16s count = 0; } + request struct GetProgramGuideRequest { + optional epoch_s startTime = 0; + optional epoch_s endTime = 1; + optional ChannelInfoStruct channelList[] = 2; + optional PageTokenStruct pageToken = 3; + optional RecordingFlagBitmap recordingFlag = 4; + optional AdditionalInfoStruct externalIDList[] = 5; + optional octet_string data = 6; + } + + response struct ProgramGuideResponse = 5 { + int16s channelPagingStruct = 0; + ProgramStruct programList[] = 1; + } + + request struct RecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + + request struct CancelRecordProgramRequest { + char_string programIdentifier = 0; + boolean shouldRecordSeries = 1; + AdditionalInfoStruct externalIDList[] = 2; + octet_string data = 3; + } + /** Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. */ command ChangeChannel(ChangeChannelRequest): ChangeChannelResponse = 0; /** Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. */ command ChangeChannelByNumber(ChangeChannelByNumberRequest): DefaultSuccess = 2; /** This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. */ command SkipChannel(SkipChannelRequest): DefaultSuccess = 3; + /** This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ + command GetProgramGuide(GetProgramGuideRequest): ProgramGuideResponse = 4; + /** Record a specific program or series when it goes live. This functionality enables DVR recording features. */ + command RecordProgram(RecordProgramRequest): DefaultSuccess = 6; + /** Cancel recording for a specific program or series. */ + command CancelRecordProgram(CancelRecordProgramRequest): DefaultSuccess = 7; } /** This cluster provides an interface for UX navigation within a set of targets on a device or endpoint. */ @@ -1582,6 +1686,12 @@ cluster TargetNavigator = 1285 { char_string name = 1; } + info event TargetUpdated = 0 { + TargetInfoStruct targetList[] = 0; + int8u currentTarget = 1; + octet_string data = 2; + } + readonly attribute TargetInfoStruct targetList[] = 0; readonly attribute optional int8u currentTarget = 1; readonly attribute command_id generatedCommandList[] = 65528; @@ -1609,6 +1719,27 @@ cluster TargetNavigator = 1285 { cluster MediaPlayback = 1286 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum PlaybackStateEnum : enum8 { kPlaying = 0; kPaused = 1; @@ -1628,6 +1759,19 @@ cluster MediaPlayback = 1286 { bitmap Feature : bitmap32 { kAdvancedSeek = 0x1; kVariableSpeed = 0x2; + kTextTracks = 0x3; + kAudioTracks = 0x4; + kAudioAdvance = 0x5; + } + + struct TrackAttributesStruct { + char_string<32> languageCode = 0; + optional nullable char_string displayName = 1; + } + + struct TrackStruct { + char_string<32> id = 0; + nullable TrackAttributesStruct trackAttributes = 1; } struct PlaybackPositionStruct { @@ -1635,6 +1779,18 @@ cluster MediaPlayback = 1286 { nullable int64u position = 1; } + info event StateChanged = 0 { + PlaybackStateEnum currentState = 0; + EPOCH_US startTime = 1; + INT64U duration = 2; + PlaybackPositionStruct sampledPosition = 3; + single playbackSpeed = 4; + INT64U seekRangeEnd = 5; + INT64U seekRangeStart = 6; + optional OCTET_STRING data = 7; + boolean audioAdvanceUnmuted = 8; + } + readonly attribute PlaybackStateEnum currentState = 0; readonly attribute optional nullable epoch_us startTime = 1; readonly attribute optional nullable int64u duration = 2; @@ -1642,6 +1798,10 @@ cluster MediaPlayback = 1286 { readonly attribute optional single playbackSpeed = 4; readonly attribute optional nullable int64u seekRangeEnd = 5; readonly attribute optional nullable int64u seekRangeStart = 6; + readonly attribute optional nullable TrackStruct activeAudioTrack = 7; + readonly attribute optional nullable TrackStruct availableAudioTracks[] = 8; + readonly attribute optional nullable TrackStruct activeTextTrack = 9; + readonly attribute optional nullable TrackStruct availableTextTracks[] = 10; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1649,6 +1809,14 @@ cluster MediaPlayback = 1286 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct RewindRequest { + optional boolean audioAdvanceUnmuted = 0; + } + + request struct FastForwardRequest { + optional boolean audioAdvanceUnmuted = 0; + } + request struct SkipForwardRequest { int64u deltaPositionMilliseconds = 0; } @@ -1666,6 +1834,15 @@ cluster MediaPlayback = 1286 { int64u position = 0; } + request struct ActivateAudioTrackRequest { + CHAR_STRING trackID = 0; + INT8U audioOutputIndex = 1; + } + + request struct ActivateTextTrackRequest { + CHAR_STRING trackID = 0; + } + /** Upon receipt, this SHALL play media. */ command Play(): PlaybackResponse = 0; /** Upon receipt, this SHALL pause media. */ @@ -1679,15 +1856,21 @@ cluster MediaPlayback = 1286 { /** Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. */ command Next(): PlaybackResponse = 5; /** Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command Rewind(): PlaybackResponse = 6; + command Rewind(RewindRequest): PlaybackResponse = 6; /** Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - command FastForward(): PlaybackResponse = 7; + command FastForward(FastForwardRequest): PlaybackResponse = 7; /** Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: */ command SkipForward(SkipForwardRequest): PlaybackResponse = 8; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command SkipBackward(SkipBackwardRequest): PlaybackResponse = 9; /** Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: */ command Seek(SeekRequest): PlaybackResponse = 11; + /** Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. */ + command ActivateAudioTrack(ActivateAudioTrackRequest): DefaultSuccess = 12; + /** Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. */ + command ActivateTextTrack(ActivateTextTrackRequest): DefaultSuccess = 13; + /** If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. */ + command DeactivateTextTrack(): DefaultSuccess = 14; } /** This cluster provides an interface for controlling the Input Selector on a media device such as a TV. */ @@ -1891,6 +2074,27 @@ cluster KeypadInput = 1289 { cluster ContentLauncher = 1290 { revision 1; // NOTE: Default/not specifically set + enum CharacteristicEnum : enum8 { + kForcedSubtitles = 0; + kDescribesVideo = 1; + kEasyToRead = 2; + kFrameBased = 3; + kMainProgram = 4; + kOriginalContent = 5; + kVoiceOverTranslation = 6; + kCaption = 7; + kSubtitle = 8; + kAlternate = 9; + kSupplementary = 10; + kCommentary = 11; + kDubbedTranslation = 12; + kDescription = 13; + kMetadata = 14; + kEnhancedAudioIntelligibility = 15; + kEmergency = 16; + kKaraoke = 17; + } + enum MetricTypeEnum : enum8 { kPixels = 0; kPercentage = 1; @@ -1911,22 +2115,31 @@ cluster ContentLauncher = 1290 { kSportsTeam = 11; kType = 12; kVideo = 13; + kSeason = 14; + kEpisode = 15; + kAny = 16; } enum StatusEnum : enum8 { kSuccess = 0; kURLNotAvailable = 1; kAuthFailed = 2; + kTextTrackNotAvailable = 3; + kAudioTrackNotAvailable = 4; } bitmap Feature : bitmap32 { kContentSearch = 0x1; kURLPlayback = 0x2; + kAdvancedSeek = 0x3; + kTextTracks = 0x4; + kAudioTracks = 0x5; } bitmap SupportedProtocolsBitmap : bitmap32 { kDASH = 0x1; kHLS = 0x2; + kWebRTC = 0x2; } struct DimensionStruct { @@ -1935,6 +2148,18 @@ cluster ContentLauncher = 1290 { MetricTypeEnum metric = 2; } + struct TrackPreferenceStruct { + char_string<32> languageCode = 0; + optional CharacteristicEnum characteristics[] = 1; + int8u audioOutputIndex = 2; + } + + struct PlaybackPreferencesStruct { + int64u playbackPosition = 0; + TrackPreferenceStruct textTrack = 1; + optional TrackPreferenceStruct audioTracks[] = 2; + } + struct AdditionalInfoStruct { char_string<256> name = 0; char_string<8192> value = 1; @@ -1978,6 +2203,8 @@ cluster ContentLauncher = 1290 { ContentSearchStruct search = 0; boolean autoPlay = 1; optional char_string data = 2; + optional PlaybackPreferencesStruct playbackPreferences = 3; + optional boolean useCurrentContext = 4; } request struct LaunchURLRequest { @@ -2139,6 +2366,10 @@ cluster ApplicationBasic = 1293 { cluster AccountLogin = 1294 { revision 1; // NOTE: Default/not specifically set + critical event LoggedOut = 0 { + optional node_id node = 0; + } + readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2157,6 +2388,11 @@ cluster AccountLogin = 1294 { request struct LoginRequest { char_string<100> tempAccountIdentifier = 0; char_string setupPIN = 1; + optional node_id node = 2; + } + + request struct LogoutRequest { + optional node_id node = 0; } /** Upon receipt, the Content App checks if the account associated with the client Temp Account Identifier Rotating ID is the same acount that is active on the given Content App. If the accounts are the same, then the Content App includes the Setup PIN in the GetSetupPIN Response. */ @@ -2164,7 +2400,7 @@ cluster AccountLogin = 1294 { /** Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. */ fabric timed command access(invoke: administer) Login(LoginRequest): DefaultSuccess = 2; /** The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. */ - fabric timed command Logout(): DefaultSuccess = 3; + fabric timed command Logout(LogoutRequest): DefaultSuccess = 3; } endpoint 0 { diff --git a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter index d2ef47811bfbf7..af3eff24fa99c9 100644 --- a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter +++ b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter @@ -1263,13 +1263,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ @@ -1326,7 +1326,7 @@ cluster DiagnosticLogs = 50 { response struct RetrieveLogsResponse = 1 { StatusEnum status = 0; - LONG_OCTET_STRING logContent = 1; + long_octet_string logContent = 1; optional epoch_us UTCTimeStamp = 2; optional systime_us timeSinceBoot = 3; } @@ -2613,7 +2613,7 @@ cluster DoorLock = 257 { request struct SetCredentialRequest { DataOperationTypeEnum operationType = 0; CredentialStruct credential = 1; - LONG_OCTET_STRING credentialData = 2; + long_octet_string credentialData = 2; nullable int16u userIndex = 3; nullable UserStatusEnum userStatus = 4; nullable UserTypeEnum userType = 5; diff --git a/examples/window-app/common/window-app.matter b/examples/window-app/common/window-app.matter index ef9fd7e18ef574..8dad58acb1116d 100644 --- a/examples/window-app/common/window-app.matter +++ b/examples/window-app/common/window-app.matter @@ -1055,13 +1055,13 @@ cluster NetworkCommissioning = 49 { } request struct QueryIdentityRequest { - OCTET_STRING<20> keyIdentifier = 0; - optional OCTET_STRING<32> possessionNonce = 1; + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; } response struct QueryIdentityResponse = 10 { - OCTET_STRING<140> identity = 0; - optional OCTET_STRING<64> possessionSignature = 1; + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; } /** Detemine the set of networks the device sees as available. */ diff --git a/examples/window-app/telink/include/AppConfig.h b/examples/window-app/telink/include/AppConfig.h index f729f0a018d8d9..f0ace63aecd608 100644 --- a/examples/window-app/telink/include/AppConfig.h +++ b/examples/window-app/telink/include/AppConfig.h @@ -24,4 +24,6 @@ #define APP_USE_THREAD_START_BUTTON 0 #define APP_SET_DEVICE_INFO_PROVIDER 1 #define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#if defined(CONFIG_BOARD_TLSR9518ADK80D) || defined(CONFIG_BOARD_TLSR9528A) #define APP_USE_IDENTIFY_PWM 1 +#endif diff --git a/scripts/error_table.py b/scripts/error_table.py old mode 100644 new mode 100755 index 54e9474fa8f338..634d31f00a27ac --- a/scripts/error_table.py +++ b/scripts/error_table.py @@ -29,6 +29,8 @@ from operator import attrgetter from pathlib import Path +from tabulate import tabulate + @dataclass class ErrorCode: @@ -112,19 +114,21 @@ def dump_table(header_path: Path, descriptor: ErrorDescriptor): markdown_title, _ = get_section_title(descriptor.section) print(f"## {markdown_title}") print() + + headers = ["Decimal", "Hex", "Name"] + if descriptor.include_description: - print("| Decimal | Hex | Name | Description |") - print("| --- | --- | --- | --- |") - else: - print("| Decimal | Hex | Name |") - print("| --- | --- | --- |") + headers.append("Description") + + data = [] for code in sorted(codes_for_section, key=attrgetter("code")): + line = [code.code, "0x%02X" % code.code, f"`{code.name}`"] if descriptor.include_description: - print(f"| {code.code} | 0x{code.code:02X} | `{code.name}` | {code.description} |") - else: - print(f"| {code.code} | 0x{code.code:02X} | `{code.name}` |") + line.append(code.description) + data.append(line) + print(tabulate(data, headers, tablefmt="github", numalign="left")) print() @@ -140,14 +144,14 @@ def main(): print("# Matter SDK `CHIP_ERROR` enums values") print() - print("This file was **AUTOMATICALLY** generated by `python scripts/error_table.py > docs/ERROR_CODES.md`.") - print("DO NOT EDIT BY HAND!") + print("This file was **AUTOMATICALLY** generated by") + print("`python scripts/error_table.py > docs/ERROR_CODES.md`. DO NOT EDIT BY HAND!") print() print("## Table of contents") for descriptor in descriptors.values(): markdown_title, anchor_name = get_section_title(descriptor.section) - print(f"- [{markdown_title}: range `0x{descriptor.code_range:03X}..0x{descriptor.code_range | 0xFF:03X}`]({anchor_name})") + print(f"- [{markdown_title}: range `0x{descriptor.code_range:03X}..0x{descriptor.code_range | 0xFF:03X}`]({anchor_name})") print() for filename, descriptor in descriptors.items(): diff --git a/scripts/py_matter_idl/BUILD.gn b/scripts/py_matter_idl/BUILD.gn index 01983d0a890724..9fef16e43e24ad 100644 --- a/scripts/py_matter_idl/BUILD.gn +++ b/scripts/py_matter_idl/BUILD.gn @@ -68,6 +68,7 @@ pw_python_package("matter_idl") { "matter_idl/test_matter_idl_parser.py", "matter_idl/test_generators.py", "matter_idl/test_idl_generator.py", + "matter_idl/test_supported_types.py", "matter_idl/test_zapxml.py", ] diff --git a/scripts/py_matter_idl/matter_idl/generators/markdown/__init__.py b/scripts/py_matter_idl/matter_idl/generators/markdown/__init__.py new file mode 100644 index 00000000000000..fc49931ff60f21 --- /dev/null +++ b/scripts/py_matter_idl/matter_idl/generators/markdown/__init__.py @@ -0,0 +1,35 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os + +from matter_idl.generators import CodeGenerator, GeneratorStorage +from matter_idl.matter_idl_types import Idl + + +class SummaryMarkdownGenerator(CodeGenerator): + """ + Code generation for markdown files + """ + + def __init__(self, storage: GeneratorStorage, idl: Idl, **kargs): + super().__init__(storage, idl, fs_loader_searchpath=os.path.dirname(__file__)) + + def internal_render_all(self): + self.internal_render_one_output( + template_path="clusters_markdown.jinja", + output_file_name="clusters.md", + vars={ + 'idl': self.idl, + } + ) diff --git a/scripts/py_matter_idl/matter_idl/generators/markdown/clusters_markdown.jinja b/scripts/py_matter_idl/matter_idl/generators/markdown/clusters_markdown.jinja new file mode 100644 index 00000000000000..bc9f7c8ad36a85 --- /dev/null +++ b/scripts/py_matter_idl/matter_idl/generators/markdown/clusters_markdown.jinja @@ -0,0 +1,17 @@ + + +## List of currently defined clusters + +| Code (dec) | Code (hex) | Name | +| ---------- | ---------- | ------------------------------------------------------- | +{%- for cluster in idl.clusters | sort(attribute="code") %} +| {{ "%10d" | format(cluster.code) }} | {{ ("0x%02X" | format(cluster.code)).rjust(10) }} | {{cluster.name.ljust(55)}} | +{%- endfor %} diff --git a/scripts/py_matter_idl/matter_idl/generators/registry.py b/scripts/py_matter_idl/matter_idl/generators/registry.py index c91981e8ad7391..e1851964d33d05 100644 --- a/scripts/py_matter_idl/matter_idl/generators/registry.py +++ b/scripts/py_matter_idl/matter_idl/generators/registry.py @@ -20,6 +20,7 @@ from matter_idl.generators.idl import IdlGenerator from matter_idl.generators.java import JavaClassGenerator, JavaJNIGenerator from matter_idl.generators.kotlin import KotlinClassGenerator +from matter_idl.generators.markdown import SummaryMarkdownGenerator class CodeGenerator(enum.Enum): @@ -34,6 +35,7 @@ class CodeGenerator(enum.Enum): CPP_APPLICATION = enum.auto() CPP_TLVMETA = enum.auto() IDL = enum.auto() + SUMMARY_MARKDOWN = enum.auto() CUSTOM = enum.auto() def Create(self, *args, **kargs): @@ -49,6 +51,8 @@ def Create(self, *args, **kargs): return TLVMetaDataGenerator(*args, **kargs) elif self == CodeGenerator.IDL: return IdlGenerator(*args, **kargs) + elif self == CodeGenerator.SUMMARY_MARKDOWN: + return SummaryMarkdownGenerator(*args, **kargs) elif self == CodeGenerator.CUSTOM: # Use a package naming convention to find the custom generator: # ./matter_idl_plugin/__init__.py defines a subclass of CodeGenerator named CustomGenerator. @@ -80,5 +84,6 @@ def FromString(name): 'cpp-app': CodeGenerator.CPP_APPLICATION, 'cpp-tlvmeta': CodeGenerator.CPP_TLVMETA, 'idl': CodeGenerator.IDL, + 'summary-markdown': CodeGenerator.SUMMARY_MARKDOWN, 'custom': CodeGenerator.CUSTOM, } diff --git a/scripts/py_matter_idl/matter_idl/generators/type_definitions.py b/scripts/py_matter_idl/matter_idl/generators/type_definitions.py index 29d496b48315bb..b5243e4f9c7162 100644 --- a/scripts/py_matter_idl/matter_idl/generators/type_definitions.py +++ b/scripts/py_matter_idl/matter_idl/generators/type_definitions.py @@ -169,6 +169,7 @@ def is_struct(self) -> bool: "bitmap64": BasicInteger(idl_name="bitmap64", byte_count=8, is_signed=False), "bitmap8": BasicInteger(idl_name="bitmap8", byte_count=1, is_signed=False), "enum16": BasicInteger(idl_name="enum16", byte_count=2, is_signed=False), + "enum24": BasicInteger(idl_name="enum24", byte_count=3, is_signed=False), "enum32": BasicInteger(idl_name="enum32", byte_count=4, is_signed=False), "enum8": BasicInteger(idl_name="enum8", byte_count=1, is_signed=False), "int16s": BasicInteger(idl_name="int16s", byte_count=2, is_signed=True), @@ -188,7 +189,7 @@ def is_struct(self) -> bool: "int8s": BasicInteger(idl_name="int8s", byte_count=1, is_signed=True), "int8u": BasicInteger(idl_name="int8u", byte_count=1, is_signed=False), # Derived types - # Specification describes them in section '7.18.2. Derived Data Types' + # Specification describes them in section '7.19.2. Derived Data Types' "action_id": BasicInteger(idl_name="action_id", byte_count=1, is_signed=False), "attrib_id": BasicInteger(idl_name="attrib_id", byte_count=4, is_signed=False), "cluster_id": BasicInteger(idl_name="cluster_id", byte_count=4, is_signed=False), @@ -213,7 +214,8 @@ def is_struct(self) -> bool: "percent100ths": BasicInteger(idl_name="percent100ths", byte_count=2, is_signed=False), "posix_ms": BasicInteger(idl_name="posix_ms", byte_count=8, is_signed=False), "priority": BasicInteger(idl_name="priority", byte_count=1, is_signed=False), - "status": BasicInteger(idl_name="status", byte_count=2, is_signed=False), + "semtag": BasicInteger(idl_name="semtag", byte_count=4, is_signed=False), + "status": BasicInteger(idl_name="status", byte_count=1, is_signed=False), "systime_ms": BasicInteger(idl_name="systime_ms", byte_count=8, is_signed=False), "systime_us": BasicInteger(idl_name="systime_us", byte_count=8, is_signed=False), "tag": BasicInteger(idl_name="tag", byte_count=1, is_signed=False), @@ -334,7 +336,7 @@ def is_enum_type(self, name: str): Handles both standard names (like enum8) as well as enumerations defined within the current lookup context. """ - if name.lower() in ["enum8", "enum16", "enum32"]: + if name.lower() in ["enum8", "enum16", "enum24", "enum32"]: return True return any(map(lambda e: e.name == name, self.all_enums)) @@ -384,9 +386,9 @@ def ParseDataType(data_type: DataType, lookup: TypeLookupContext) -> Union[Basic return BasicString(idl_name=lowercase_name, is_binary=False, max_length=data_type.max_length) elif lowercase_name in ['octet_string', 'long_octet_string']: return BasicString(idl_name=lowercase_name, is_binary=True, max_length=data_type.max_length) - elif lowercase_name in ['enum8', 'enum16', 'enum32']: + elif lowercase_name in ['enum8', 'enum16', 'enum24', 'enum32']: return IdlEnumType(idl_name=lowercase_name, base_type=__CHIP_SIZED_TYPES__[lowercase_name]) - elif lowercase_name in ['bitmap8', 'bitmap16', 'bitmap24', 'bitmap32']: + elif lowercase_name in ['bitmap8', 'bitmap16', 'bitmap24', 'bitmap32', 'bitmap64']: return IdlBitmapType(idl_name=lowercase_name, base_type=__CHIP_SIZED_TYPES__[lowercase_name]) int_type = __CHIP_SIZED_TYPES__.get(lowercase_name, None) diff --git a/scripts/py_matter_idl/matter_idl/test_supported_types.py b/scripts/py_matter_idl/matter_idl/test_supported_types.py new file mode 100755 index 00000000000000..62f7d4c59956c5 --- /dev/null +++ b/scripts/py_matter_idl/matter_idl/test_supported_types.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import unittest +import xml.etree.ElementTree as ET + +try: + from matter_idl.generators.type_definitions import ParseDataType +except ImportError: + import sys + + sys.path.append(os.path.abspath( + os.path.join(os.path.dirname(__file__), '..'))) + from matter_idl.generators.type_definitions import ParseDataType + +from matter_idl.generators.type_definitions import BasicInteger, TypeLookupContext +from matter_idl.matter_idl_types import DataType, Idl + + +class TestSupportedTypes(unittest.TestCase): + + def __init__(self, *args, **kargs): + super().__init__(*args, **kargs) + self.maxDiff = None + + def testAllTypesSupported(self): + # ALL types defined in chip-types.xml should be understandable + # by the generator type parsing + path = "src/app/zap-templates/zcl/data-model/chip/chip-types.xml" + path = os.path.join(os.path.dirname(__file__), "../../..", path) + dom = ET.parse(path).getroot() + + # Format we expect: + # - configurator/atomic/type + self.assertEqual(dom.tag, "configurator") + types = dom.findall("./atomic/type") + + # Arbitrary non-empty assumption to make sure we + # test something and did not mess up our XPath query + self.assertTrue(len(types) > 10) + + empty_lookup = TypeLookupContext(idl=Idl(), cluster=None) + + for t in types: + # every type has the following intersting attributes: + # - name (to be validated) + # - size (in bytes, but may not be power of two) + # - one of discrete/analog/composite + + if "composite" in t.attrib and t.attrib["composite"] == "true": + # struct, array, octet_string and such + continue + + data_type = DataType(name=t.attrib["name"]) + + # filter some know things + if data_type.name in { + "no_data", # intentionally skipped + # handled as a non-integer type + "boolean", "single", "double", + # handled as specific bitmaps + "bitmap8", "bitmap16", "bitmap24", "bitmap32", "bitmap64", + # handled as specific enums + "enum8", "enum16", "enum24", "enum32", + + # TODO: these may be bugs to fix + "unknown" + }: + continue + + parsed = ParseDataType(data_type, empty_lookup) + + self.assertTrue(parsed is not None) # this should always pass. + fail_message = f"{data_type.name} was parsed as {parsed}" + + self.assertIs(type(parsed), BasicInteger, fail_message) + + # check that types match + if "signed" in t.attrib and t.attrib["signed"] == "true": + # Oddly enough, we have no sign info for int8s and int8u + # Only temperature really has a signed component + self.assertTrue(parsed.is_signed, fail_message) + + if "size" in t.attrib: + self.assertEqual(parsed.byte_count, int( + t.attrib["size"]), fail_message) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint index 55885086b0fa45..9f87179489e41f 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -21,6 +21,8 @@ load "../src/app/zap-templates/zcl/data-model/chip/clusters-extensions.xml"; load "../src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml"; diff --git a/scripts/tools/check_includes_config.py b/scripts/tools/check_includes_config.py index 1e06f933dfb63c..abe2c0ed42f5af 100644 --- a/scripts/tools/check_includes_config.py +++ b/scripts/tools/check_includes_config.py @@ -164,5 +164,8 @@ 'src/lib/support/jsontlv/JsonToTlv.cpp': {'sstream'}, 'src/lib/support/jsontlv/JsonToTlv.h': {'string'}, 'src/lib/support/jsontlv/TlvToJson.h': {'string'}, - 'src/lib/support/jsontlv/TextFormat.h': {'string'} + 'src/lib/support/jsontlv/TextFormat.h': {'string'}, + 'src/app/icd/client/DefaultICDClientStorage.cpp': {'vector'}, + 'src/app/icd/client/DefaultICDClientStorage.h': {'vector'}, + 'src/app/icd/client/DefaultICDStorageKey.h': {'vector'} } diff --git a/scripts/tools/sdk.json b/scripts/tools/sdk.json deleted file mode 100644 index dfc680589e80b1..00000000000000 --- a/scripts/tools/sdk.json +++ /dev/null @@ -1,290 +0,0 @@ -{ - "meta": { - "sdkRoot": "../..", - "description": "Matter SDK", - "requiredFeatureLevel": 95 - }, - "zcl": { - "main": "src/app/zap-templates/zcl/zcl.json", - "main_ext": "src/app/zap-templates/zcl/zcl-with-test-extensions.json" - }, - "templates": { - "app-zap": "src/app/zap-templates/app-templates.json", - "placeholder": "examples/placeholder/templates/templates.json", - "chip-tool-test": "examples/chip-tool/templates/tests/templates.json", - "darwin-test": "examples/darwin-framework-tool/templates/tests/templates.json", - "app-common": "src/app/common/templates/templates.json", - "app-test": "src/app/tests/suites/templates/templates.json", - "chip-tool": "examples/chip-tool/templates/templates.json", - "darwin": "examples/darwin-framework-tool/templates/templates.json", - "python": "src/controller/python/templates/templates.json", - "darwin-chip": "src/darwin/Framework/CHIP/templates/templates.json", - "java": "src/controller/java/templates/templates.json" - }, - "zapFiles": { - "thermostat": "examples/thermostat/thermostat-common/thermostat.zap", - "bridge-app": "examples/bridge-app/bridge-common/bridge-app.zap", - "log-source-app": "examples/log-source-app/log-source-common/log-source-app.zap", - "lock-app": "examples/lock-app/lock-common/lock-app.zap", - "lighting-app": "examples/lighting-app/lighting-common/lighting-app.zap", - "all-clusters-minimal-app": "examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap", - "temperature-measurement": "examples/temperature-measurement-app/esp32/main/temperature-measurement.zap", - "all-clusters-app": "examples/all-clusters-app/all-clusters-common/all-clusters-app.zap", - "pump-controller-app": "examples/pump-controller-app/pump-controller-common/pump-controller-app.zap", - "tv-app": "examples/tv-app/tv-common/tv-app.zap", - "light-switch-app": "examples/light-switch-app/light-switch-common/light-switch-app.zap", - "ota-provider-app": "examples/ota-provider-app/ota-provider-common/ota-provider-app.zap", - "pump-app": "examples/pump-app/pump-common/pump-app.zap", - "ota-requestor-app": "examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap", - "tv-casting-app": "examples/tv-casting-app/tv-casting-common/tv-casting-app.zap", - "window-app": "examples/window-app/common/window-app.zap", - "app2": "examples/placeholder/linux/apps/app2/config.zap", - "app1": "examples/placeholder/linux/apps/app1/config.zap", - "chef_dimmablelight": "examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.zap", - "chef_contactsensor": "examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.zap", - "chef_humiditysensor": "examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.zap", - "chef_speaker": "examples/chef/devices/rootnode_speaker_RpzeXdimqA.zap", - "chef_temperaturesensor": "examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.zap", - "chef_flowsensor": "examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.zap", - "chef_thermostat": "examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.zap", - "chef_onofflightswitch": "examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.zap", - "chef_heatingcoolingunit": "examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.zap", - "chef_occupancysensor": "examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap", - "chef_onofflight": "examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap", - "chef_pressuresensor": "examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.zap", - "chef_windowcovering": "examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.zap", - "chef_onoffpluginunit": "examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.zap", - "chef_lightsensor": "examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.zap", - "controller": "src/controller/data_model/controller-clusters.zap" - }, - "generation": [ - { - "zapFile": "all-clusters-app", - "output": "zzz_generated/all-clusters-app/zap-generated", - "zcl": "main_ext", - "template": "app-zap" - }, - { - "zapFile": "all-clusters-minimal-app", - "output": "zzz_generated/all-clusters-minimal-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "app1", - "output": "zzz_generated/placeholder/app1/zap-generated", - "zcl": "main", - "template": ["app-zap", "placeholder"] - }, - { - "zapFile": "app2", - "output": "zzz_generated/placeholder/app2/zap-generated", - "zcl": "main", - "template": ["app-zap", "placeholder"] - }, - { - "zapFile": "bridge-app", - "output": "zzz_generated/bridge-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_contactsensor", - "output": "zzz_generated/chef-rootnode_contactsensor_lFAGG1bfRO/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_dimmablelight", - "output": "zzz_generated/chef-rootnode_dimmablelight_bCwGYSDpoe/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_flowsensor", - "output": "zzz_generated/chef-rootnode_flowsensor_1zVxHedlaV/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_heatingcoolingunit", - "output": "zzz_generated/chef-rootnode_heatingcoolingunit_ncdGai1E5a/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_humiditysensor", - "output": "zzz_generated/chef-rootnode_humiditysensor_Xyj4gda6Hb/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_lightsensor", - "output": "zzz_generated/chef-rootnode_lightsensor_lZQycTFcJK/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_occupancysensor", - "output": "zzz_generated/chef-rootnode_occupancysensor_iHyVgifZuo/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_onofflight", - "output": "zzz_generated/chef-rootnode_onofflight_bbs1b7IaOV/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_onofflightswitch", - "output": "zzz_generated/chef-rootnode_onofflightswitch_FsPlMr090Q/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_onoffpluginunit", - "output": "zzz_generated/chef-rootnode_onoffpluginunit_Wtf8ss5EBY/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_pressuresensor", - "output": "zzz_generated/chef-rootnode_pressuresensor_s0qC9wLH4k/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_speaker", - "output": "zzz_generated/chef-rootnode_speaker_RpzeXdimqA/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_temperaturesensor", - "output": "zzz_generated/chef-rootnode_temperaturesensor_Qy1zkNW7c3/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_thermostat", - "output": "zzz_generated/chef-rootnode_thermostat_bm3fb8dhYi/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "chef_windowcovering", - "output": "zzz_generated/chef-rootnode_windowcovering_RLCxaGi9Yx/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "controller", - "output": "", - "zcl": "main", - "template": ["python", "darwin-chip", "java"] - }, - { - "zapFile": "controller", - "output": "zzz_generated/app-common/app-common/zap-generated", - "zcl": "main", - "template": ["app-common", "app-test"] - }, - { - "zapFile": "controller", - "output": "zzz_generated/chip-tool/zap-generated", - "zcl": "main", - "template": ["chip-tool-test", "chip-tool"] - }, - { - "zapFile": "controller", - "output": "zzz_generated/controller-clusters/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "controller", - "output": "zzz_generated/darwin-framework-tool/zap-generated", - "zcl": "main", - "template": ["darwin-test", "darwin"] - }, - { - "zapFile": "light-switch-app", - "output": "zzz_generated/light-switch-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "lighting-app", - "output": "zzz_generated/lighting-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "lock-app", - "output": "zzz_generated/lock-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "log-source-app", - "output": "zzz_generated/log-source-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "ota-provider-app", - "output": "zzz_generated/ota-provider-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "ota-requestor-app", - "output": "zzz_generated/ota-requestor-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "pump-app", - "output": "zzz_generated/pump-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "pump-controller-app", - "output": "zzz_generated/pump-controller-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "temperature-measurement", - "output": "zzz_generated/temperature-measurement-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "thermostat", - "output": "zzz_generated/thermostat/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "tv-app", - "output": "zzz_generated/tv-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "tv-casting-app", - "output": "zzz_generated/tv-casting-app/zap-generated", - "zcl": "main", - "template": "app-zap" - }, - { - "zapFile": "window-app", - "output": "zzz_generated/window-app/zap-generated", - "zcl": "main", - "template": "app-zap" - } - ] -} diff --git a/scripts/tools/zap_regen_all.py b/scripts/tools/zap_regen_all.py index 6650740c4b734a..0b89b661ee31c5 100755 --- a/scripts/tools/zap_regen_all.py +++ b/scripts/tools/zap_regen_all.py @@ -438,6 +438,11 @@ def getCodegenTemplates(): idl_path="src/controller/data_model/controller-clusters.matter", output_directory="src/controller/java/generated")) + targets.append(JinjaCodegenTarget( + generator="summary-markdown", + idl_path="src/controller/data_model/controller-clusters.matter", + output_directory="docs")) + return targets diff --git a/src/app/BufferedReadCallback.cpp b/src/app/BufferedReadCallback.cpp index 0279eff5eeab73..da38d0b38418bb 100644 --- a/src/app/BufferedReadCallback.cpp +++ b/src/app/BufferedReadCallback.cpp @@ -40,6 +40,7 @@ void BufferedReadCallback::OnReportEnd() if (err != CHIP_NO_ERROR) { mCallback.OnError(err); + return; } mCallback.OnReportEnd(); diff --git a/src/app/CommandHandler.cpp b/src/app/CommandHandler.cpp index 8fd13bab7247f0..1b4f8ea92998ba 100644 --- a/src/app/CommandHandler.cpp +++ b/src/app/CommandHandler.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,13 @@ using Status = Protocols::InteractionModel::Status; CommandHandler::CommandHandler(Callback * apCallback) : mExchangeCtx(*this), mpCallback(apCallback), mSuppressResponse(false) {} +CommandHandler::CommandHandler(TestOnlyMarker aTestMarker, Callback * apCallback, CommandPathRegistry * apCommandPathRegistry) : + CommandHandler(apCallback) +{ + mMaxPathsPerInvoke = apCommandPathRegistry->MaxSize(); + mCommandPathRegistry = apCommandPathRegistry; +} + CHIP_ERROR CommandHandler::AllocateBuffer() { if (!mBufferAllocated) @@ -97,11 +105,74 @@ void CommandHandler::OnInvokeCommandRequest(Messaging::ExchangeContext * ec, con mGoneAsync = true; } +CHIP_ERROR CommandHandler::ValidateInvokeRequestsAndBuildRegistry(TLV::TLVReader & invokeRequestsReader) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + size_t commandCount = 0; + bool commandRefExpected = false; + + ReturnErrorOnFailure(TLV::Utilities::Count(invokeRequestsReader, commandCount, false /* recurse */)); + + // If this is a GroupRequest the only thing to check is that there is only one + // CommandDataIB. + if (IsGroupRequest()) + { + VerifyOrReturnError(commandCount == 1, CHIP_ERROR_INVALID_ARGUMENT); + return CHIP_NO_ERROR; + } + // While technically any commandCount == 1 should already be unique and does not need + // any further validation, we do need to read and populate the registry to help + // in building the InvokeResponse. + + VerifyOrReturnError(commandCount <= MaxPathsPerInvoke(), CHIP_ERROR_INVALID_ARGUMENT); + + // If there is more than one CommandDataIB, spec states that CommandRef must be provided. + commandRefExpected = commandCount > 1; + + while (CHIP_NO_ERROR == (err = invokeRequestsReader.Next())) + { + VerifyOrReturnError(TLV::AnonymousTag() == invokeRequestsReader.GetTag(), CHIP_ERROR_INVALID_ARGUMENT); + CommandDataIB::Parser commandData; + ReturnErrorOnFailure(commandData.Init(invokeRequestsReader)); + + // First validate that we can get a ConcreteCommandPath. + CommandPathIB::Parser commandPath; + ConcreteCommandPath concretePath(0, 0, 0); + ReturnErrorOnFailure(commandData.GetPath(&commandPath)); + ReturnErrorOnFailure(commandPath.GetConcreteCommandPath(concretePath)); + + // Grab the CommandRef if there is one, and validate that it's there when it + // has to be. + Optional commandRef; + uint16_t ref; + err = commandData.GetRef(&ref); + VerifyOrReturnError(err == CHIP_NO_ERROR || err == CHIP_END_OF_TLV, err); + if (err == CHIP_END_OF_TLV && commandRefExpected) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + if (err == CHIP_NO_ERROR) + { + commandRef.SetValue(ref); + } + + // Adding can fail if concretePath is not unique, or if commandRef is a value + // and is not unique, or if we have already added more paths than we support. + ReturnErrorOnFailure(GetCommandPathRegistry().Add(concretePath, commandRef)); + } + + // It's OK/expected to have reached the end of the container without failure. + if (CHIP_END_OF_TLV == err) + { + err = CHIP_NO_ERROR; + } + return err; +} + Status CommandHandler::ProcessInvokeRequest(System::PacketBufferHandle && payload, bool isTimedInvoke) { CHIP_ERROR err = CHIP_NO_ERROR; System::PacketBufferTLVReader reader; - TLV::TLVReader invokeRequestsReader; InvokeRequestMessage::Parser invokeRequestMessage; InvokeRequests::Parser invokeRequests; reader.Init(std::move(payload)); @@ -109,28 +180,33 @@ Status CommandHandler::ProcessInvokeRequest(System::PacketBufferHandle && payloa #if CHIP_CONFIG_IM_PRETTY_PRINT invokeRequestMessage.PrettyPrint(); #endif + if (mExchangeCtx->IsGroupExchangeContext()) + { + SetGroupRequest(true); + } VerifyOrReturnError(invokeRequestMessage.GetSuppressResponse(&mSuppressResponse) == CHIP_NO_ERROR, Status::InvalidAction); VerifyOrReturnError(invokeRequestMessage.GetTimedRequest(&mTimedRequest) == CHIP_NO_ERROR, Status::InvalidAction); VerifyOrReturnError(invokeRequestMessage.GetInvokeRequests(&invokeRequests) == CHIP_NO_ERROR, Status::InvalidAction); VerifyOrReturnError(mTimedRequest == isTimedInvoke, Status::UnsupportedAccess); - invokeRequests.GetReader(&invokeRequestsReader); { - // We don't support handling multiple commands but the protocol is ready to support it in the future, reject all of them and - // IM Engine will send a status response. - size_t commandCount = 0; - TLV::Utilities::Count(invokeRequestsReader, commandCount, false /* recurse */); - VerifyOrReturnError(commandCount == 1, Status::InvalidAction); + TLV::TLVReader validationInvokeRequestsReader; + invokeRequests.GetReader(&validationInvokeRequestsReader); + VerifyOrReturnError(ValidateInvokeRequestsAndBuildRegistry(validationInvokeRequestsReader) == CHIP_NO_ERROR, + Status::InvalidAction); } + TLV::TLVReader invokeRequestsReader; + invokeRequests.GetReader(&invokeRequestsReader); + while (CHIP_NO_ERROR == (err = invokeRequestsReader.Next())) { VerifyOrReturnError(TLV::AnonymousTag() == invokeRequestsReader.GetTag(), Status::InvalidAction); CommandDataIB::Parser commandData; VerifyOrReturnError(commandData.Init(invokeRequestsReader) == CHIP_NO_ERROR, Status::InvalidAction); Status status = Status::Success; - if (mExchangeCtx->IsGroupExchangeContext()) + if (IsGroupRequest()) { status = ProcessGroupCommandDataIB(commandData); } @@ -200,7 +276,7 @@ void CommandHandler::DecrementHoldOff() { ChipLogProgress(DataManagement, "Skipping command response: exchange context is null"); } - else if (!mExchangeCtx->IsGroupExchangeContext()) + else if (!IsGroupRequest()) { CHIP_ERROR err = SendCommandResponse(); if (err != CHIP_NO_ERROR) @@ -251,8 +327,6 @@ Status CommandHandler::ProcessCommandDataIB(CommandDataIB::Parser & aCommandElem ConcreteCommandPath concretePath(0, 0, 0); TLV::TLVReader commandDataReader; - SetGroupRequest(false); - // NOTE: errors may occur before the concrete command path is even fully decoded. err = aCommandElement.GetPath(&commandPath); @@ -354,7 +428,6 @@ Status CommandHandler::ProcessGroupCommandDataIB(CommandDataIB::Parser & aComman Credentials::GroupDataProvider::GroupEndpoint mapping; Credentials::GroupDataProvider * groupDataProvider = Credentials::GetGroupDataProvider(); Credentials::GroupDataProvider::EndpointIterator * iterator; - SetGroupRequest(true); err = aCommandElement.GetPath(&commandPath); VerifyOrReturnError(err == CHIP_NO_ERROR, Status::InvalidAction); @@ -465,7 +538,7 @@ CHIP_ERROR CommandHandler::AddStatusInternal(const ConcreteCommandPath & aComman void CommandHandler::AddStatus(const ConcreteCommandPath & aCommandPath, const Protocols::InteractionModel::Status aStatus, const char * context) { - // Return prematurely in case of requests targeted to a group that should not add the status for response purposes. + // Return early in case of requests targeted to a group, since they should not add a response. VerifyOrReturn(!IsGroupRequest()); VerifyOrDie(FallibleAddStatus(aCommandPath, aStatus, context) == CHIP_NO_ERROR); } @@ -500,15 +573,51 @@ CHIP_ERROR CommandHandler::AddClusterSpecificFailure(const ConcreteCommandPath & return AddStatusInternal(aCommandPath, StatusIB(Status::Failure, aClusterStatus)); } -CHIP_ERROR CommandHandler::PrepareCommand(const ConcreteCommandPath & aCommandPath, bool aStartDataStruct) +CHIP_ERROR CommandHandler::PrepareInvokeResponseCommand(const ConcreteCommandPath & aResponseCommandPath, + const CommandHandler::InvokeResponseParameters & aPrepareParameters) +{ + auto commandPathRegistryEntry = GetCommandPathRegistry().Find(aPrepareParameters.mRequestCommandPath); + VerifyOrReturnValue(commandPathRegistryEntry.HasValue(), CHIP_ERROR_INCORRECT_STATE); + + return PrepareInvokeResponseCommand(commandPathRegistryEntry.Value(), aResponseCommandPath, + aPrepareParameters.mStartOrEndDataStruct); +} + +CHIP_ERROR CommandHandler::PrepareCommand(const ConcreteCommandPath & aResponseCommandPath, bool aStartDataStruct) +{ + // Legacy code is calling the deprecated version of PrepareCommand. If we are in a case where + // there was a single command in the request, we can just assume this response is triggered by + // the single command. + size_t countOfPathRegistryEntries = GetCommandPathRegistry().Count(); + + // At this point application supports Batch Invoke Commands since CommandPathRegistry has more than 1 entry, + // but application is calling the deprecated PrepareCommand. We have no way to determine the associated CommandRef + // to put into the InvokeResponse. + VerifyOrDieWithMsg(countOfPathRegistryEntries == 1, DataManagement, + "Seemingly device supports batch commands, but is calling the deprecated PrepareCommand API"); + + auto commandPathRegistryEntry = GetCommandPathRegistry().GetFirstEntry(); + VerifyOrReturnValue(commandPathRegistryEntry.HasValue(), CHIP_ERROR_INCORRECT_STATE); + + return PrepareInvokeResponseCommand(commandPathRegistryEntry.Value(), aResponseCommandPath, aStartDataStruct); +} + +CHIP_ERROR CommandHandler::PrepareInvokeResponseCommand(const CommandPathRegistryEntry & apCommandPathRegistryEntry, + const ConcreteCommandPath & aCommandPath, bool aStartDataStruct) { ReturnErrorOnFailure(AllocateBuffer()); mInvokeResponseBuilder.Checkpoint(mBackupWriter); + mBackupState = mState; // // We must not be in the middle of preparing a command, or having prepared or sent one. // - VerifyOrReturnError(mState == State::Idle, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mState == State::Idle || mState == State::AddedCommand, CHIP_ERROR_INCORRECT_STATE); + + // TODO(#30453): See if we can pass this back up the stack so caller can provide this instead of taking up + // space in CommandHanlder. + mRefForResponse = apCommandPathRegistryEntry.ref; + MoveToState(State::Preparing); InvokeResponseIBs::Builder & invokeResponses = mInvokeResponseBuilder.GetInvokeResponses(); InvokeResponseIB::Builder & invokeResponse = invokeResponses.CreateInvokeResponse(); @@ -536,10 +645,14 @@ CHIP_ERROR CommandHandler::FinishCommand(bool aStartDataStruct) { ReturnErrorOnFailure(commandData.GetWriter()->EndContainer(mDataElementContainerType)); } + + if (mRefForResponse.HasValue()) + { + ReturnErrorOnFailure(commandData.Ref(mRefForResponse.Value())); + } + ReturnErrorOnFailure(commandData.EndOfCommandDataIB()); ReturnErrorOnFailure(mInvokeResponseBuilder.GetInvokeResponses().GetInvokeResponse().EndOfInvokeResponseIB()); - ReturnErrorOnFailure(mInvokeResponseBuilder.GetInvokeResponses().EndOfInvokeResponses()); - ReturnErrorOnFailure(mInvokeResponseBuilder.EndOfInvokeResponseMessage()); MoveToState(State::AddedCommand); return CHIP_NO_ERROR; } @@ -550,7 +663,12 @@ CHIP_ERROR CommandHandler::PrepareStatus(const ConcreteCommandPath & aCommandPat // // We must not be in the middle of preparing a command, or having prepared or sent one. // - VerifyOrReturnError(mState == State::Idle, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mState == State::Idle || mState == State::AddedCommand, CHIP_ERROR_INCORRECT_STATE); + + auto commandPathRegistryEntry = GetCommandPathRegistry().Find(aCommandPath); + VerifyOrReturnError(commandPathRegistryEntry.HasValue(), CHIP_ERROR_INCORRECT_STATE); + mRefForResponse = commandPathRegistryEntry.Value().ref; + MoveToState(State::Preparing); InvokeResponseIBs::Builder & invokeResponses = mInvokeResponseBuilder.GetInvokeResponses(); InvokeResponseIB::Builder & invokeResponse = invokeResponses.CreateInvokeResponse(); @@ -567,10 +685,15 @@ CHIP_ERROR CommandHandler::PrepareStatus(const ConcreteCommandPath & aCommandPat CHIP_ERROR CommandHandler::FinishStatus() { VerifyOrReturnError(mState == State::AddingCommand, CHIP_ERROR_INCORRECT_STATE); + + CommandStatusIB::Builder & commandStatus = mInvokeResponseBuilder.GetInvokeResponses().GetInvokeResponse().GetStatus(); + if (mRefForResponse.HasValue()) + { + ReturnErrorOnFailure(commandStatus.Ref(mRefForResponse.Value())); + } + ReturnErrorOnFailure(mInvokeResponseBuilder.GetInvokeResponses().GetInvokeResponse().GetStatus().EndOfCommandStatusIB()); ReturnErrorOnFailure(mInvokeResponseBuilder.GetInvokeResponses().GetInvokeResponse().EndOfInvokeResponseIB()); - ReturnErrorOnFailure(mInvokeResponseBuilder.GetInvokeResponses().EndOfInvokeResponses()); - ReturnErrorOnFailure(mInvokeResponseBuilder.EndOfInvokeResponseMessage()); MoveToState(State::AddedCommand); return CHIP_NO_ERROR; } @@ -579,9 +702,7 @@ CHIP_ERROR CommandHandler::RollbackResponse() { VerifyOrReturnError(mState == State::Preparing || mState == State::AddingCommand, CHIP_ERROR_INCORRECT_STATE); mInvokeResponseBuilder.Rollback(mBackupWriter); - // Note: We only support one command per request, so we reset the state to Idle here, need to review the states when adding - // supports of having multiple requests in the same transaction. - MoveToState(State::Idle); + MoveToState(mBackupState); return CHIP_NO_ERROR; } @@ -635,6 +756,8 @@ CommandHandler::Handle::Handle(CommandHandler * handle) CHIP_ERROR CommandHandler::Finalize(System::PacketBufferHandle & commandPacket) { VerifyOrReturnError(mState == State::AddedCommand, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure(mInvokeResponseBuilder.GetInvokeResponses().EndOfInvokeResponses()); + ReturnErrorOnFailure(mInvokeResponseBuilder.EndOfInvokeResponseMessage()); return mCommandMessageWriter.Finalize(&commandPacket); } diff --git a/src/app/CommandHandler.h b/src/app/CommandHandler.h index 65542ef0587f55..037e2c5619f50e 100644 --- a/src/app/CommandHandler.h +++ b/src/app/CommandHandler.h @@ -30,6 +30,8 @@ #pragma once +#include "CommandPathRegistry.h" + #include #include #include @@ -151,6 +153,32 @@ class CommandHandler : public Messaging::ExchangeDelegate uint32_t mMagic = 0; }; + // Previously we kept adding arguments with default values individually as parameters. This is because there + // is legacy code outside of the SDK that would call PrepareCommand. With the new PrepareInvokeResponseCommand + // replacing PrepareCommand, we took this opportunity to create a new parameter structure to make it easier to + // add new parameters without there needing to be an ever increasing parameter list with defaults. + struct InvokeResponseParameters + { + InvokeResponseParameters(ConcreteCommandPath aRequestCommandPath) : mRequestCommandPath(aRequestCommandPath) {} + + InvokeResponseParameters & SetStartOrEndDataStruct(bool aStartOrEndDataStruct) + { + mStartOrEndDataStruct = aStartOrEndDataStruct; + return *this; + } + + ConcreteCommandPath mRequestCommandPath; + /** + * Whether the method this is being provided to should start/end the TLV container for the CommandFields element + * within CommandDataIB. + */ + bool mStartOrEndDataStruct = true; + }; + + class TestOnlyMarker + { + }; + /* * Constructor. * @@ -158,6 +186,14 @@ class CommandHandler : public Messaging::ExchangeDelegate */ CommandHandler(Callback * apCallback); + /* + * Constructor to override number of supported paths per invoke. + * + * The callback and command path registry passed in has to outlive this CommandHandler object. + * For testing purposes. + */ + CommandHandler(TestOnlyMarker aTestMarker, Callback * apCallback, CommandPathRegistry * apCommandPathRegistry); + /* * Main entrypoint for this class to handle an invoke request. * @@ -171,6 +207,15 @@ class CommandHandler : public Messaging::ExchangeDelegate void OnInvokeCommandRequest(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader, System::PacketBufferHandle && payload, bool isTimedInvoke); + /** + * Checks that all CommandDataIB within InvokeRequests satisfy the spec's general + * constraints for CommandDataIB. + * + * This also builds a registry that to ensure that all commands can be responded + * to with the data required as per spec. + */ + CHIP_ERROR ValidateInvokeRequestsAndBuildRegistry(TLV::TLVReader & invokeRequestsReader); + /** * Adds the given command status and returns any failures in adding statuses (e.g. out * of buffer space) to the caller @@ -190,9 +235,77 @@ class CommandHandler : public Messaging::ExchangeDelegate CHIP_ERROR AddClusterSpecificFailure(const ConcreteCommandPath & aCommandPath, ClusterStatus aClusterStatus); Protocols::InteractionModel::Status ProcessInvokeRequest(System::PacketBufferHandle && payload, bool isTimedInvoke); - CHIP_ERROR PrepareCommand(const ConcreteCommandPath & aCommandPath, bool aStartDataStruct = true); + + /** + * This adds a new CommandDataIB element into InvokeResponses for the associated + * aRequestCommandPath. This adds up until the `CommandFields` element within + * `CommandDataIB`. + * + * This call will fail if CommandHandler is already in the middle of building a + * CommandStatusIB or CommandDataIB (i.e. something has called Prepare*, without + * calling Finish*), or is already sending InvokeResponseMessage. + * + * Upon success, the caller is expected to call `FinishCommand` once they have added + * all the fields into the CommandFields element of CommandDataIB. + * + * @param [in] aResponseCommandPath the concrete response path that we are sending to Requester. + * @param [in] aPrepareParameters struct containing paramters needs for preparing a command. Data + * such as request path, and whether this method should start the CommandFields element within + * CommandDataIB. + */ + CHIP_ERROR PrepareInvokeResponseCommand(const ConcreteCommandPath & aResponseCommandPath, + const InvokeResponseParameters & aPrepareParameters); + + [[deprecated("PrepareCommand now needs the requested command path. Please use PrepareInvokeResponseCommand")]] CHIP_ERROR + PrepareCommand(const ConcreteCommandPath & aCommandPath, bool aStartDataStruct = true); + + /** + * Finishes the CommandDataIB element within the InvokeResponses. + * + * Caller must have first successfully called `PrepareInvokeResponseCommand`. + * + * @param [in] aEndDataStruct end the TLV container for the CommandFields element within + * CommandDataIB. This should match the boolean passed into Prepare*. + * + * @return CHIP_ERROR_INCORRECT_STATE + * If device has not previously successfully called + * `PrepareInvokeResponseCommand`. + * @return CHIP_ERROR_BUFFER_TOO_SMALL + * If writing the values needed to finish the InvokeReponseIB + * with the current contents of the InvokeResponseMessage + * would exceed the limit. When this error occurs, it is possible + * we have already closed some of the IB Builders that were + * previously started in `PrepareInvokeResponseCommand`. + * @return CHIP_ERROR_NO_MEMORY + * If TLVWriter attempted to allocate an output buffer failed due to + * lack of memory. + * @return other Other TLVWriter related errors. Typically occurs if + * `GetCommandDataIBTLVWriter()` was called and used incorrectly. + */ + // TODO(#30453): We should be able to eliminate the chances of OOM issues with reserve. + // This will be completed in a follow up PR. CHIP_ERROR FinishCommand(bool aEndDataStruct = true); + + /** + * This will add a new CommandStatusIB element into InvokeResponses. It will put the + * aCommandPath into the CommandPath element within CommandStatusIB. + * + * This call will fail if CommandHandler is already in the middle of building a + * CommandStatusIB or CommandDataIB (i.e. something has called Prepare*, without + * calling Finish*), or is already sending InvokeResponseMessage. + * + * Upon success, the caller is expected to call `FinishStatus` once they have encoded + * StatusIB. + * + * @param [in] aCommandPath the concrete path of the command we are responding to. + */ CHIP_ERROR PrepareStatus(const ConcreteCommandPath & aCommandPath); + + /** + * Finishes the CommandStatusIB element within the InvokeResponses. + * + * Caller must have first successfully called `PrepareStatus`. + */ CHIP_ERROR FinishStatus(); TLV::TLVWriter * GetCommandDataIBTLVWriter(); @@ -315,7 +428,7 @@ class CommandHandler : public Messaging::ExchangeDelegate VerifyOrDie(false); } - enum class State + enum class State : uint8_t { Idle, ///< Default state that the object starts out in, where no work has commenced Preparing, ///< We are prepaing the command or status header. @@ -363,6 +476,9 @@ class CommandHandler : public Messaging::ExchangeDelegate */ CHIP_ERROR AllocateBuffer(); + CHIP_ERROR PrepareInvokeResponseCommand(const CommandPathRegistryEntry & apCommandPathRegistryEntry, + const ConcreteCommandPath & aCommandPath, bool aStartDataStruct); + CHIP_ERROR Finalize(System::PacketBufferHandle & commandPacket); /** @@ -397,8 +513,15 @@ class CommandHandler : public Messaging::ExchangeDelegate template CHIP_ERROR TryAddResponseData(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) { - ConcreteCommandPath path = { aRequestCommandPath.mEndpointId, aRequestCommandPath.mClusterId, CommandData::GetCommandId() }; - ReturnErrorOnFailure(PrepareCommand(path, false)); + // Return early in case of requests targeted to a group, since they should not add a response. + VerifyOrReturnValue(!IsGroupRequest(), CHIP_NO_ERROR); + + InvokeResponseParameters prepareParams(aRequestCommandPath); + prepareParams.SetStartOrEndDataStruct(false); + + ConcreteCommandPath responsePath = { aRequestCommandPath.mEndpointId, aRequestCommandPath.mClusterId, + CommandData::GetCommandId() }; + ReturnErrorOnFailure(PrepareInvokeResponseCommand(responsePath, prepareParams)); TLV::TLVWriter * writer = GetCommandDataIBTLVWriter(); VerifyOrReturnError(writer != nullptr, CHIP_ERROR_INCORRECT_STATE); ReturnErrorOnFailure(DataModel::Encode(*writer, TLV::ContextTag(CommandDataIB::Tag::kFields), aData)); @@ -416,21 +539,32 @@ class CommandHandler : public Messaging::ExchangeDelegate */ void SetGroupRequest(bool isGroupRequest) { mGroupRequest = isGroupRequest; } + CommandPathRegistry & GetCommandPathRegistry() const { return *mCommandPathRegistry; } + + size_t MaxPathsPerInvoke() const { return mMaxPathsPerInvoke; } + Messaging::ExchangeHolder mExchangeCtx; Callback * mpCallback = nullptr; InvokeResponseMessage::Builder mInvokeResponseBuilder; TLV::TLVType mDataElementContainerType = TLV::kTLVType_NotSpecified; size_t mPendingWork = 0; - bool mSuppressResponse = false; - bool mTimedRequest = false; - bool mSentStatusResponse = false; - - State mState = State::Idle; - bool mGroupRequest = false; chip::System::PacketBufferTLVWriter mCommandMessageWriter; TLV::TLVWriter mBackupWriter; - bool mBufferAllocated = false; + size_t mMaxPathsPerInvoke = CHIP_CONFIG_MAX_PATHS_PER_INVOKE; + // TODO(#30453): See if we can reduce this size for the default cases + // TODO Allow flexibility in registration. + BasicCommandPathRegistry mBasicCommandPathRegistry; + CommandPathRegistry * mCommandPathRegistry = &mBasicCommandPathRegistry; + Optional mRefForResponse; + + State mState = State::Idle; + State mBackupState; + bool mSuppressResponse = false; + bool mTimedRequest = false; + bool mSentStatusResponse = false; + bool mGroupRequest = false; + bool mBufferAllocated = false; // If mGoneAsync is true, we have finished out initial processing of the // incoming invoke. After this point, our session could go away at any // time. diff --git a/src/app/CommandPathRegistry.h b/src/app/CommandPathRegistry.h new file mode 100644 index 00000000000000..0d914ef1de3348 --- /dev/null +++ b/src/app/CommandPathRegistry.h @@ -0,0 +1,118 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include +#include + +namespace chip { +namespace app { + +struct CommandPathRegistryEntry +{ + ConcreteCommandPath requestPath = ConcreteCommandPath(0, 0, 0); + Optional ref; +}; + +class CommandPathRegistry +{ +public: + virtual ~CommandPathRegistry() = default; + + virtual Optional Find(const ConcreteCommandPath & requestPath) const = 0; + virtual Optional GetFirstEntry() const = 0; + virtual CHIP_ERROR Add(const ConcreteCommandPath & requestPath, const Optional & ref) = 0; + virtual size_t Count() const = 0; + virtual size_t MaxSize() const = 0; +}; + +/** + * @class BasicCommandPathRegistry + * + * @brief Allows looking up CommandRef using the requested ConcreteCommandPath. + * + * While there are faster implementations, right now batch commands are capped at a low number due to + * message size constraints. All commands need to be contained within a single InvokeRequest. In + * practice this is usually less than 60 commands (but could be much more with TCP transports or + * newer transports). + */ +template +class BasicCommandPathRegistry : public CommandPathRegistry +{ +public: + Optional Find(const ConcreteCommandPath & requestPath) const override + { + for (size_t i = 0; i < mCount; i++) + { + if (mTable[i].requestPath == requestPath) + { + return MakeOptional(mTable[i]); + } + } + return NullOptional; + } + + Optional GetFirstEntry() const override + { + if (mCount > 0) + { + return MakeOptional(mTable[0]); + } + return NullOptional; + } + + CHIP_ERROR Add(const ConcreteCommandPath & requestPath, const Optional & ref) override + { + if (mCount >= N) + { + return CHIP_ERROR_NO_MEMORY; + } + for (size_t i = 0; i < mCount; i++) + { + if (mTable[i].requestPath == requestPath) + { + return CHIP_ERROR_DUPLICATE_KEY_ID; + } + // No need to check if either has value. This is because if there is more than + // 1 entry in the table expectation is to have all entirely unique ref values + // so duplicate optional would mean we would want to error out. + if (mTable[i].ref == ref) + { + return CHIP_ERROR_DUPLICATE_KEY_ID; + } + } + + mTable[mCount] = CommandPathRegistryEntry{ requestPath, ref }; + mCount++; + return CHIP_NO_ERROR; + } + + virtual size_t Count() const override { return mCount; } + virtual size_t MaxSize() const override { return N; } + +private: + size_t mCount = 0; + CommandPathRegistryEntry mTable[N]; +}; + +} // namespace app +} // namespace chip diff --git a/src/app/ConcreteAttributePath.h b/src/app/ConcreteAttributePath.h index b06a4b8a3b3acf..076575dcafa2a1 100644 --- a/src/app/ConcreteAttributePath.h +++ b/src/app/ConcreteAttributePath.h @@ -132,6 +132,12 @@ struct ConcreteDataAttributePath : public ConcreteAttributePath bool IsListOperation() const { return mListOp != ListOperation::NotList; } bool IsListItemOperation() const { return ((mListOp != ListOperation::NotList) && (mListOp != ListOperation::ReplaceAll)); } + void LogPath() const + { + ChipLogProgress(DataManagement, "Concrete Attribute Path: (%d, " ChipLogFormatMEI ", " ChipLogFormatMEI ") ", mEndpointId, + ChipLogValueMEI(mClusterId), ChipLogValueMEI(mAttributeId)); + } + // // This index is only valid if `mListOp` is set to a list item operation, i.e // ReplaceItem, DeleteItem or AppendItem. Otherwise, it is to be ignored. diff --git a/src/app/EventHeader.h b/src/app/EventHeader.h index c3ba210bfbfa5d..72887962a9348e 100644 --- a/src/app/EventHeader.h +++ b/src/app/EventHeader.h @@ -30,6 +30,12 @@ struct EventHeader EventNumber mEventNumber = 0; PriorityLevel mPriorityLevel = PriorityLevel::Invalid; Timestamp mTimestamp; + + void LogPath() const + { + ChipLogProgress(DataManagement, "Concrete Event Path: (%d, " ChipLogFormatMEI ", " ChipLogFormatMEI ") ", mPath.mEndpointId, + ChipLogValueMEI(mPath.mClusterId), ChipLogValueMEI(mPath.mEventId)); + } }; } // namespace app } // namespace chip diff --git a/src/app/MessageDef/InvokeResponseMessage.cpp b/src/app/MessageDef/InvokeResponseMessage.cpp index 225f2c3dc4acac..cb36aa15160633 100644 --- a/src/app/MessageDef/InvokeResponseMessage.cpp +++ b/src/app/MessageDef/InvokeResponseMessage.cpp @@ -63,6 +63,15 @@ CHIP_ERROR InvokeResponseMessage::Parser::PrettyPrint() const ReturnErrorOnFailure(invokeResponses.PrettyPrint()); PRETTY_PRINT_DECDEPTH(); } + break; + case to_underlying(Tag::kMoreChunkedMessages): +#if CHIP_DETAIL_LOGGING + { + bool moreChunkedMessages; + ReturnErrorOnFailure(reader.Get(moreChunkedMessages)); + PRETTY_PRINT("\tmoreChunkedMessages = %s, ", moreChunkedMessages ? "true" : "false"); + } +#endif // CHIP_DETAIL_LOGGING break; case kInteractionModelRevisionTag: ReturnErrorOnFailure(MessageParser::CheckInteractionModelRevision(reader)); @@ -98,6 +107,11 @@ CHIP_ERROR InvokeResponseMessage::Parser::GetInvokeResponses(InvokeResponseIBs:: return apStatus->Init(reader); } +CHIP_ERROR InvokeResponseMessage::Parser::GetMoreChunkedMessages(bool * const apMoreChunkedMessages) const +{ + return GetSimpleValue(to_underlying(Tag::kMoreChunkedMessages), TLV::kTLVType_Boolean, apMoreChunkedMessages); +} + InvokeResponseMessage::Builder & InvokeResponseMessage::Builder::SuppressResponse(const bool aSuppressResponse) { if (mError == CHIP_NO_ERROR) @@ -116,6 +130,16 @@ InvokeResponseIBs::Builder & InvokeResponseMessage::Builder::CreateInvokeRespons return mInvokeResponses; } +InvokeResponseMessage::Builder & InvokeResponseMessage::Builder::MoreChunkedMessages(const bool aMoreChunkedMessages) +{ + // skip if error has already been set + if (mError == CHIP_NO_ERROR) + { + mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kMoreChunkedMessages), aMoreChunkedMessages); + } + return *this; +} + CHIP_ERROR InvokeResponseMessage::Builder::EndOfInvokeResponseMessage() { if (mError == CHIP_NO_ERROR) diff --git a/src/app/MessageDef/InvokeResponseMessage.h b/src/app/MessageDef/InvokeResponseMessage.h index 87cb7c14746646..34cc69aecfe976 100644 --- a/src/app/MessageDef/InvokeResponseMessage.h +++ b/src/app/MessageDef/InvokeResponseMessage.h @@ -33,8 +33,9 @@ namespace app { namespace InvokeResponseMessage { enum class Tag : uint8_t { - kSuppressResponse = 0, - kInvokeResponses = 1, + kSuppressResponse = 0, + kInvokeResponses = 1, + kMoreChunkedMessages = 2, }; class Parser : public MessageParser @@ -61,6 +62,16 @@ class Parser : public MessageParser * #CHIP_END_OF_TLV if there is no such element */ CHIP_ERROR GetInvokeResponses(InvokeResponseIBs::Parser * const apInvokeResponses) const; + + /** + * @brief Get MoreChunkedMessages boolean + * + * @param [out] apMoreChunkedMessages A pointer to bool for storing more chunked messages value. + * + * @return #CHIP_NO_ERROR on success + * #CHIP_END_OF_TLV if there is no such element + */ + CHIP_ERROR GetMoreChunkedMessages(bool * const apMoreChunkedMessages) const; }; class Builder : public MessageBuilder @@ -86,6 +97,13 @@ class Builder : public MessageBuilder */ InvokeResponseIBs::Builder & GetInvokeResponses() { return mInvokeResponses; } + /** + * @brief Set True if the set of InvokeResponseIB have to be sent across multiple packets in a single transaction + * @param [in] aMoreChunkedMessages true if more chunked messages are needed + * @return A reference to *this + */ + InvokeResponseMessage::Builder & MoreChunkedMessages(const bool aMoreChunkedMessages); + /** * @brief Mark the end of this InvokeResponseMessage * diff --git a/src/app/app-platform/ContentApp.h b/src/app/app-platform/ContentApp.h index e5eb99a5a701bd..915e47d8672e37 100644 --- a/src/app/app-platform/ContentApp.h +++ b/src/app/app-platform/ContentApp.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -41,6 +43,8 @@ using ApplicationBasicDelegate = app::Clusters::ApplicationBasic::Delegate; using ApplicationLauncherDelegate = app::Clusters::ApplicationLauncher::Delegate; using ChannelDelegate = app::Clusters::Channel::Delegate; using ContentLauncherDelegate = app::Clusters::ContentLauncher::Delegate; +using ContentAppObserverDelegate = app::Clusters::ContentAppObserver::Delegate; +using ContentControlDelegate = app::Clusters::ContentControl::Delegate; using KeypadInputDelegate = app::Clusters::KeypadInput::Delegate; using MediaPlaybackDelegate = app::Clusters::MediaPlayback::Delegate; using TargetNavigatorDelegate = app::Clusters::TargetNavigator::Delegate; @@ -58,6 +62,8 @@ class DLL_EXPORT ContentApp virtual ApplicationLauncherDelegate * GetApplicationLauncherDelegate() = 0; virtual ChannelDelegate * GetChannelDelegate() = 0; virtual ContentLauncherDelegate * GetContentLauncherDelegate() = 0; + virtual ContentControlDelegate * GetContentControlDelegate() = 0; + virtual ContentAppObserverDelegate * GetContentAppObserverDelegate() = 0; virtual KeypadInputDelegate * GetKeypadInputDelegate() = 0; virtual MediaPlaybackDelegate * GetMediaPlaybackDelegate() = 0; virtual TargetNavigatorDelegate * GetTargetNavigatorDelegate() = 0; diff --git a/src/app/clusters/account-login-server/account-login-delegate.h b/src/app/clusters/account-login-server/account-login-delegate.h index 3842412f40d7a2..0abf1de306d933 100644 --- a/src/app/clusters/account-login-server/account-login-delegate.h +++ b/src/app/clusters/account-login-server/account-login-delegate.h @@ -37,11 +37,12 @@ class Delegate // helper method to allow the platform to facilitate providing the pin virtual void SetSetupPin(char * setupPin) = 0; - virtual bool HandleLogin(const chip::CharSpan & tempAccountIdentifierString, const chip::CharSpan & setupPinString) = 0; - virtual bool HandleLogout() = 0; + virtual bool HandleLogin(const chip::CharSpan & tempAccountIdentifierString, const chip::CharSpan & setupPinString, + const chip::Optional & nodeId) = 0; + virtual bool HandleLogout(const chip::Optional & nodeId) = 0; virtual void HandleGetSetupPin(CommandResponseHelper & helper, - const chip::CharSpan & tempAccountIdentifierString) = 0; - virtual void GetSetupPin(char * setupPin, size_t setupPinSize, const chip::CharSpan & tempAccountIdentifierString) = 0; + const chip::CharSpan & tempAccountIdentifierString) = 0; + virtual void GetSetupPin(char * setupPin, size_t setupPinSize, const chip::CharSpan & tempAccountIdentifierString) = 0; virtual ~Delegate() = default; }; diff --git a/src/app/clusters/account-login-server/account-login-server.cpp b/src/app/clusters/account-login-server/account-login-server.cpp index b9a05b8bc65cc8..b9727a9ad9561f 100644 --- a/src/app/clusters/account-login-server/account-login-server.cpp +++ b/src/app/clusters/account-login-server/account-login-server.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -41,12 +42,43 @@ using namespace chip::app::Clusters::AccountLogin; #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED using namespace chip::AppPlatform; #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using chip::NodeId; +using chip::app::LogEvent; using chip::app::Clusters::AccountLogin::Delegate; using chip::Protocols::InteractionModel::Status; +using LoggedOutEvent = chip::app::Clusters::AccountLogin::Events::LoggedOut::Type; static constexpr size_t kAccountLoginDeletageTableSize = EMBER_AF_ACCOUNT_LOGIN_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; static_assert(kAccountLoginDeletageTableSize <= kEmberInvalidEndpointIndex, "AccountLogin Delegate table size error"); + +NodeId getNodeId(const chip::app::CommandHandler * commandObj) +{ + // TODO: Why are we doing all these checks? At all the callsites we have + // just received a command, so we better have a handler, exchange, session, + // etc. The only thing we should be checking is that it's a CASE session. + if (nullptr == commandObj || nullptr == commandObj->GetExchangeContext()) + { + ChipLogError(Zcl, "Cannot access ExchangeContext of Command Object for Node ID"); + return kUndefinedNodeId; + } + + if (!commandObj->GetExchangeContext()->HasSessionHandle()) + { + ChipLogError(Zcl, "Cannot access session of Command Object for Node ID"); + return kUndefinedNodeId; + } + + auto descriptor = commandObj->GetExchangeContext()->GetSessionHandle()->GetSubjectDescriptor(); + if (descriptor.authMode != Access::AuthMode::kCase) + { + ChipLogError(Zcl, "Cannot get Node ID from non-CASE session of Command Object"); + return kUndefinedNodeId; + } + + return descriptor.subject; +} + // ----------------------------------------------------------------------------- // Delegate Implementation @@ -143,11 +175,12 @@ bool emberAfAccountLoginClusterLoginCallback(app::CommandHandler * command, cons Status status = Status::Success; auto & tempAccountIdentifier = commandData.tempAccountIdentifier; auto & setupPin = commandData.setupPIN; + auto & nodeId = commandData.node; Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); - if (!delegate->HandleLogin(tempAccountIdentifier, setupPin)) + if (!delegate->HandleLogin(tempAccountIdentifier, setupPin, nodeId)) { status = Status::UnsupportedAccess; } @@ -169,10 +202,12 @@ bool emberAfAccountLoginClusterLogoutCallback(app::CommandHandler * commandObj, EndpointId endpoint = commandPath.mEndpointId; Status status = Status::Success; + auto & nodeId = commandData.node; + Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); - if (!delegate->HandleLogout()) + if (!delegate->HandleLogout(nodeId)) { status = Status::Failure; } @@ -184,6 +219,19 @@ bool emberAfAccountLoginClusterLogoutCallback(app::CommandHandler * commandObj, status = Status::Failure; } + if (nodeId.HasValue()) + { + // NodeId nodeId = getNodeId(commandObj); + EventNumber eventNumber; + LoggedOutEvent event{ .node = nodeId }; + CHIP_ERROR logEventError = LogEvent(event, endpoint, eventNumber); + + if (CHIP_NO_ERROR != logEventError) + { + ChipLogError(Zcl, "[Notify] Unable to send notify event: %s [endpointId=%d]", logEventError.AsString(), endpoint); + } + } + commandObj->AddStatus(commandPath, status); return true; } diff --git a/src/app/clusters/channel-server/channel-delegate.h b/src/app/clusters/channel-server/channel-delegate.h index f5fbbadda7ae16..6007bf06f8867f 100644 --- a/src/app/clusters/channel-server/channel-delegate.h +++ b/src/app/clusters/channel-server/channel-delegate.h @@ -29,6 +29,10 @@ namespace app { namespace Clusters { namespace Channel { +using ChannelInfo = chip::app::Clusters::Channel::Structs::ChannelInfoStruct::DecodableType; +using AdditionalInfo = chip::app::Clusters::Channel::Structs::AdditionalInfoStruct::DecodableType; +using PageToken = chip::app::Clusters::Channel::Structs::PageTokenStruct::Type; + /** @brief * Defines methods for implementing application-specific logic for the Channel Cluster. */ @@ -43,6 +47,21 @@ class Delegate const chip::CharSpan & match) = 0; virtual bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) = 0; virtual bool HandleSkipChannel(const int16_t & count) = 0; + virtual void HandleGetProgramGuide(CommandResponseHelper & helper, + const chip::Optional & startTime, const chip::Optional & endTime, + const chip::Optional> & channelList, + const chip::Optional & pageToken, + const chip::Optional> & recordingFlag, + const chip::Optional> & externalIdList, + const chip::Optional & data) = 0; + + virtual bool HandleRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) = 0; + + virtual bool HandleCancelRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) = 0; bool HasFeature(chip::EndpointId endpoint, Feature feature); virtual uint32_t GetFeatureMap(chip::EndpointId endpoint) = 0; diff --git a/src/app/clusters/channel-server/channel-server.cpp b/src/app/clusters/channel-server/channel-server.cpp index 91e9fc613dadf5..52d30083075d66 100644 --- a/src/app/clusters/channel-server/channel-server.cpp +++ b/src/app/clusters/channel-server/channel-server.cpp @@ -288,6 +288,115 @@ bool emberAfChannelClusterSkipChannelCallback(app::CommandHandler * command, con return true; } +/** + * @brief Channel Cluster GetProgramGuide Command callback (from client) + */ +bool emberAfChannelClusterGetProgramGuideCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::Channel::Commands::GetProgramGuide::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + + auto & startTime = commandData.startTime; + auto & endTime = commandData.endTime; + auto & channelList = commandData.channelList; + auto & pageToken = commandData.pageToken; + auto & recordingFlag = commandData.recordingFlag; + auto & externalIDList = commandData.externalIDList; + auto & data = commandData.data; + + app::CommandResponseHelper responder(command, commandPath); + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleGetProgramGuide(responder, startTime, endTime, channelList, pageToken, recordingFlag, externalIDList, data); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfChannelClusterGetProgramGuideCallback error: %s", err.AsString()); + } + + // If isDelegateNull, no one will call responder, so HasSentResponse will be false + if (!responder.HasSentResponse()) + { + command->AddStatus(commandPath, Status::Failure); + } + + return true; +} + +/** + * @brief Channel Cluster RecordProgram Command callback (from client) + */ +bool emberAfChannelClusterRecordProgramCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::Channel::Commands::RecordProgram::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + auto & programIdentifier = commandData.programIdentifier; + auto & shouldRecordSeries = commandData.shouldRecordSeries; + auto & externalIDList = commandData.externalIDList; + auto & data = commandData.data; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + + if (!delegate->HandleRecordProgram(programIdentifier, shouldRecordSeries, externalIDList, data)) + { + status = Status::Failure; + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfChannelClusterRecordProgramCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Channel Cluster CancelRecordProgram Command callback (from client) + */ +bool emberAfChannelClusterCancelRecordProgramCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::Channel::Commands::CancelRecordProgram::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + auto & programIdentifier = commandData.programIdentifier; + auto & shouldRecordSeries = commandData.shouldRecordSeries; + auto & externalIDList = commandData.externalIDList; + auto & data = commandData.data; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + + if (!delegate->HandleCancelRecordProgram(programIdentifier, shouldRecordSeries, externalIDList, data)) + { + status = Status::Failure; + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfChannelClusterCancelRecordProgramCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + void MatterChannelPluginServerInitCallback() { registerAttributeAccessOverride(&gChannelAttrAccess); diff --git a/src/app/clusters/content-app-observer/content-app-observer-delegate.h b/src/app/clusters/content-app-observer/content-app-observer-delegate.h new file mode 100644 index 00000000000000..d206f19ff1c174 --- /dev/null +++ b/src/app/clusters/content-app-observer/content-app-observer-delegate.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ContentAppObserver { + +/** @brief + * Defines methods for implementing application-specific logic for the Content App Observer Cluster. + */ +class Delegate +{ +public: + virtual void HandleContentAppMessage(CommandResponseHelper & helper, + const chip::Optional & data, const chip::CharSpan & encodingHint) = 0; + + virtual ~Delegate() = default; +}; + +} // namespace ContentAppObserver +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/content-app-observer/content-app-observer.cpp b/src/app/clusters/content-app-observer/content-app-observer.cpp new file mode 100644 index 00000000000000..26739027b494af --- /dev/null +++ b/src/app/clusters/content-app-observer/content-app-observer.cpp @@ -0,0 +1,153 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/**************************************************************************** + * @file + * @brief Routines for the Application Launcher plugin, the + *server implementation of the Application Launcher cluster. + ******************************************************************************* + ******************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ContentAppObserver; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using chip::app::Clusters::ContentAppObserver::Delegate; +using chip::Protocols::InteractionModel::Status; + +static constexpr size_t kContentAppObserverDeletageTableSize = + EMBER_AF_CONTENT_APP_OBSERVER_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; +static_assert(kContentAppObserverDeletageTableSize <= kEmberInvalidEndpointIndex, "ContentAppObserver Delegate table size error"); + +// ----------------------------------------------------------------------------- +// Delegate Implementation + +namespace { + +Delegate * gDelegateTable[kContentAppObserverDeletageTableSize] = { nullptr }; + +Delegate * GetDelegate(EndpointId endpoint) +{ +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogProgress(Zcl, "ContentAppObserver returning ContentApp delegate for endpoint:%u", endpoint); + return app->GetContentAppObserverDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogProgress(Zcl, "ContentAppObserver NOT returning ContentApp delegate for endpoint:%u", endpoint); + + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, ContentAppObserver::Id, + EMBER_AF_CONTENT_APP_OBSERVER_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= kContentAppObserverDeletageTableSize ? nullptr : gDelegateTable[ep]); +} + +bool isDelegateNull(Delegate * delegate, EndpointId endpoint) +{ + if (delegate == nullptr) + { + ChipLogProgress(Zcl, "Content App Observer has no delegate set for endpoint:%u", endpoint); + return true; + } + return false; +} +} // namespace + +namespace chip { +namespace app { +namespace Clusters { +namespace ContentAppObserver { + +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, ContentAppObserver::Id, + EMBER_AF_CONTENT_APP_OBSERVER_CLUSTER_SERVER_ENDPOINT_COUNT); + // if endpoint is found + if (ep < kContentAppObserverDeletageTableSize) + { + gDelegateTable[ep] = delegate; + } + else + { + } +} + +} // namespace ContentAppObserver +} // namespace Clusters +} // namespace app +} // namespace chip + +// ----------------------------------------------------------------------------- +// Matter Framework Callbacks Implementation + +/** + * @brief Content App Observer Cluster ContentAppMessage Command callback (from client) + */ +bool emberAfContentAppObserverClusterContentAppMessageCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessage::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + + auto & data = commandData.data; + auto & encodingHint = commandData.encodingHint; + + app::CommandResponseHelper responder(command, commandPath); + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleContentAppMessage(responder, data, encodingHint); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentAppObserverClusterContentAppMessageCallback error: %s", err.AsString()); + } + + // If isDelegateNull, no one will call responder, so HasSentResponse will be false + if (!responder.HasSentResponse()) + { + command->AddStatus(commandPath, Status::Failure); + } + + return true; +} + +// ----------------------------------------------------------------------------- +// Plugin initialization + +void MatterContentAppObserverPluginServerInitCallback() {} diff --git a/src/app/clusters/content-app-observer/content-app-observer.h b/src/app/clusters/content-app-observer/content-app-observer.h new file mode 100644 index 00000000000000..3d16ba2a99b866 --- /dev/null +++ b/src/app/clusters/content-app-observer/content-app-observer.h @@ -0,0 +1,39 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/**************************************************************************** + * @file + * @brief Routines for the Content App Observer plugin, the + *server implementation of the Content App Observer cluster. + ******************************************************************************* + ******************************************************************************/ + +#pragma once + +#include "content-app-observer-delegate.h" +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ContentAppObserver { + +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); + +} // namespace ContentAppObserver +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/content-control-server/content-control-delegate.h b/src/app/clusters/content-control-server/content-control-delegate.h new file mode 100644 index 00000000000000..b587c3a7610a3c --- /dev/null +++ b/src/app/clusters/content-control-server/content-control-delegate.h @@ -0,0 +1,69 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ContentControl { + +/** @brief + * Defines methods for implementing application-specific logic for the Content Control Cluster. + */ +class Delegate +{ +public: + // Attribute Delegates + virtual bool HandleGetEnabled() = 0; + virtual CHIP_ERROR HandleGetOnDemandRatings(app::AttributeValueEncoder & aEncoder) = 0; + virtual chip::CharSpan HandleGetOnDemandRatingThreshold() = 0; + virtual CHIP_ERROR HandleGetScheduledContentRatings(app::AttributeValueEncoder & aEncoder) = 0; + virtual chip::CharSpan HandleGetScheduledContentRatingThreshold() = 0; + virtual uint32_t HandleGetScreenDailyTime() = 0; + virtual uint32_t HandleGetRemainingScreenTime() = 0; + virtual bool HandleGetBlockUnrated() = 0; + + // Command Delegates + virtual void HandleUpdatePIN(Optional oldPIN, chip::CharSpan newPIN) = 0; + virtual void HandleResetPIN(CommandResponseHelper & helper) = 0; + virtual void HandleEnable() = 0; + virtual void HandleDisable() = 0; + virtual void HandleAddBonusTime(Optional PINCode, Optional bonusTime) = 0; + virtual void HandleSetScreenDailyTime(uint32_t screenDailyTime) = 0; + virtual void HandleBlockUnratedContent() = 0; + virtual void HandleUnblockUnratedContent() = 0; + virtual void HandleSetOnDemandRatingThreshold(chip::CharSpan rating) = 0; + virtual void HandleSetScheduledContentRatingThreshold(chip::CharSpan rating) = 0; + + bool HasFeature(chip::EndpointId endpoint, Feature feature); + + virtual uint32_t GetFeatureMap(chip::EndpointId endpoint) = 0; + + virtual ~Delegate() = default; +}; + +} // namespace ContentControl +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/content-control-server/content-control-server.cpp b/src/app/clusters/content-control-server/content-control-server.cpp new file mode 100644 index 00000000000000..1434e25000f389 --- /dev/null +++ b/src/app/clusters/content-control-server/content-control-server.cpp @@ -0,0 +1,417 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/**************************************************************************** + * @file + * @brief Routines for the Application Launcher plugin, the + *server implementation of the Application Launcher cluster. + ******************************************************************************* + ******************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +#include +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ContentControl; +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using namespace chip::AppPlatform; +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using chip::NodeId; +using chip::app::LogEvent; +using chip::app::Clusters::ContentControl::Delegate; +using chip::Protocols::InteractionModel::Status; +using RemainingScreenTimeExpiredEvent = chip::app::Clusters::ContentControl::Events::RemainingScreenTimeExpired::Type; + +static constexpr size_t kContentControlDeletageTableSize = + EMBER_AF_CONTENT_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; +static_assert(kContentControlDeletageTableSize <= kEmberInvalidEndpointIndex, "ContentControl Delegate table size error"); + +// ----------------------------------------------------------------------------- +// Delegate Implementation + +namespace { + +Delegate * gDelegateTable[kContentControlDeletageTableSize] = { nullptr }; + +Delegate * GetDelegate(EndpointId endpoint) +{ +#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(endpoint); + if (app != nullptr) + { + ChipLogProgress(Zcl, "ContentControl returning ContentApp delegate for endpoint:%u", endpoint); + return app->GetContentControlDelegate(); + } +#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + ChipLogProgress(Zcl, "ContentControl NOT returning ContentApp delegate for endpoint:%u", endpoint); + + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, ContentControl::Id, EMBER_AF_CONTENT_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= kContentControlDeletageTableSize ? nullptr : gDelegateTable[ep]); +} + +bool isDelegateNull(Delegate * delegate, EndpointId endpoint) +{ + if (delegate == nullptr) + { + ChipLogProgress(Zcl, "Content App Observer has no delegate set for endpoint:%u", endpoint); + return true; + } + return false; +} +} // namespace + +namespace chip { +namespace app { +namespace Clusters { +namespace ContentControl { + +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) +{ + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, ContentControl::Id, EMBER_AF_CONTENT_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); + // if endpoint is found + if (ep < kContentControlDeletageTableSize) + { + gDelegateTable[ep] = delegate; + } + else + { + } +} + +} // namespace ContentControl +} // namespace Clusters +} // namespace app +} // namespace chip + +// ----------------------------------------------------------------------------- +// Matter Framework Callbacks Implementation + +/** + * @brief Content Control Cluster UpdatePIN Command callback (from client) + */ +bool emberAfContentControlClusterUpdatePINCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::UpdatePIN::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + auto & oldPin = commandData.oldPIN; + auto & newPin = commandData.newPIN; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleUpdatePIN(oldPin, newPin); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterUpdatePINCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Content Control Cluster ResetPIN Command callback (from client) + */ +bool emberAfContentControlClusterResetPINCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::ResetPIN::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + + app::CommandResponseHelper responder(command, commandPath); + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleResetPIN(responder); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterResetPINCallback error: %s", err.AsString()); + } + + // If isDelegateNull, no one will call responder, so HasSentResponse will be false + if (!responder.HasSentResponse()) + { + command->AddStatus(commandPath, Status::Failure); + } + + return true; +} + +/** + * @brief Content Control Cluster Enable Command callback (from client) + */ +bool emberAfContentControlClusterEnableCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::Enable::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleEnable(); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterEnableCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Content Control Cluster Disable Command callback (from client) + */ +bool emberAfContentControlClusterDisableCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::Disable::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleDisable(); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterDisableCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Content Control Cluster AddBonusTime Command callback (from client) + */ +bool emberAfContentControlClusterAddBonusTimeCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::AddBonusTime::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + auto & pinCode = commandData.PINCode; + auto & bonusTime = commandData.bonusTime; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleAddBonusTime(pinCode, bonusTime); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterAddBonusTimeCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Content Control Cluster SetScreenDailyTime Command callback (from client) + */ +bool emberAfContentControlClusterSetScreenDailyTimeCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::SetScreenDailyTime::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + auto & screenTime = commandData.screenTime; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleSetScreenDailyTime(screenTime); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterSetScreenDailyTimeCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Content Control Cluster BlockUnratedContent Command callback (from client) + */ +bool emberAfContentControlClusterBlockUnratedContentCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::BlockUnratedContent::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleBlockUnratedContent(); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterBlockUnratedContentCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Content Control Cluster UnblockUnratedContent Command callback (from client) + */ +bool emberAfContentControlClusterUnblockUnratedContentCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::UnblockUnratedContent::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleUnblockUnratedContent(); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterUnblockUnratedContentCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Content Control Cluster SetOnDemandRatingThreshold Command callback (from client) + */ +bool emberAfContentControlClusterSetOnDemandRatingThresholdCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::SetOnDemandRatingThreshold::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + auto & rating = commandData.rating; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleSetOnDemandRatingThreshold(rating); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterSetOnDemandRatingThresholdCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Content Control Cluster SetScheduledContentRatingThreshold Command callback (from client) + */ +bool emberAfContentControlClusterSetScheduledContentRatingThresholdCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ContentControl::Commands::SetScheduledContentRatingThreshold::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + auto & rating = commandData.rating; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleSetScheduledContentRatingThreshold(rating); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfContentControlClusterSetScheduledContentRatingThresholdCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +// ----------------------------------------------------------------------------- +// Plugin initialization + +void MatterContentControlPluginServerInitCallback() {} diff --git a/src/app/clusters/content-control-server/content-control-server.h b/src/app/clusters/content-control-server/content-control-server.h new file mode 100644 index 00000000000000..4ae61a6dc484c9 --- /dev/null +++ b/src/app/clusters/content-control-server/content-control-server.h @@ -0,0 +1,39 @@ +/** + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/**************************************************************************** + * @file + * @brief Routines for the Content App Observer plugin, the + *server implementation of the Content App Observer cluster. + ******************************************************************************* + ******************************************************************************/ + +#pragma once + +#include "content-control-delegate.h" +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ContentControl { + +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); + +} // namespace ContentControl +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/content-launch-server/content-launch-delegate.h b/src/app/clusters/content-launch-server/content-launch-delegate.h index 5f189861164088..0f84887c881788 100644 --- a/src/app/clusters/content-launch-server/content-launch-delegate.h +++ b/src/app/clusters/content-launch-server/content-launch-delegate.h @@ -31,6 +31,7 @@ namespace Clusters { namespace ContentLauncher { using BrandingInformation = chip::app::Clusters::ContentLauncher::Structs::BrandingInformationStruct::Type; +using PlaybackPreferences = chip::app::Clusters::ContentLauncher::Structs::PlaybackPreferencesStruct::DecodableType; using Parameter = chip::app::Clusters::ContentLauncher::Structs::ParameterStruct::DecodableType; /** @brief @@ -41,7 +42,8 @@ class Delegate public: virtual void HandleLaunchContent(CommandResponseHelper & helper, const DataModel::DecodableList & parameterList, bool autoplay, - const CharSpan & data) = 0; + const CharSpan & data, const Optional playbackPreferences, + bool useCurrentContext) = 0; virtual void HandleLaunchUrl(CommandResponseHelper & helper, const CharSpan & contentUrl, const CharSpan & displayString, const BrandingInformation & brandingInformation) = 0; diff --git a/src/app/clusters/content-launch-server/content-launch-server.cpp b/src/app/clusters/content-launch-server/content-launch-server.cpp index 70144aaec1b06d..405ec7b427f373 100644 --- a/src/app/clusters/content-launch-server/content-launch-server.cpp +++ b/src/app/clusters/content-launch-server/content-launch-server.cpp @@ -206,6 +206,8 @@ bool emberAfContentLauncherClusterLaunchContentCallback(CommandHandler * command auto & autoplay = commandData.autoPlay; auto & data = commandData.data; auto & decodableParameterList = commandData.search.parameterList; + auto & playbackPreferences = commandData.playbackPreferences; + auto & useCurrentContext = commandData.useCurrentContext; app::CommandResponseHelper responder(commandObj, commandPath); @@ -214,7 +216,9 @@ bool emberAfContentLauncherClusterLaunchContentCallback(CommandHandler * command VerifyOrExit(isDelegateNull(delegate, endpoint) != true && delegate->HasFeature(endpoint, Feature::kContentSearch), err = CHIP_ERROR_INCORRECT_STATE); - delegate->HandleLaunchContent(responder, decodableParameterList, autoplay, data.HasValue() ? data.Value() : CharSpan()); + // note assume if client does not send useCurrentContext then it's set to false + delegate->HandleLaunchContent(responder, decodableParameterList, autoplay, data.HasValue() ? data.Value() : CharSpan(), + playbackPreferences, useCurrentContext.HasValue() ? useCurrentContext.Value() : false); exit: if (err != CHIP_NO_ERROR) diff --git a/src/app/clusters/icd-management-server/icd-management-server.cpp b/src/app/clusters/icd-management-server/icd-management-server.cpp index 941789d28144cc..73f278794b0243 100644 --- a/src/app/clusters/icd-management-server/icd-management-server.cpp +++ b/src/app/clusters/icd-management-server/icd-management-server.cpp @@ -188,6 +188,30 @@ class IcdManagementFabricDelegate : public FabricTable::Delegate IcdManagementFabricDelegate gFabricDelegate; IcdManagementAttributeAccess gAttribute; +/** + * @brief Function checks if the client as admin permissions to the cluster in the commandPath + * + * @param[out] isClientAdmin True : Client has admin permissions + * False : Client does not have admin permissions + * If an error ocurs, isClientAdmin is not changed + * @return CHIP_ERROR + */ +CHIP_ERROR CheckAdmin(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, bool & isClientAdmin) +{ + RequestPath requestPath{ .cluster = commandPath.mClusterId, .endpoint = commandPath.mEndpointId }; + CHIP_ERROR err = GetAccessControl().Check(commandObj->GetSubjectDescriptor(), requestPath, Privilege::kAdminister); + if (CHIP_NO_ERROR == err) + { + isClientAdmin = true; + } + else if (CHIP_ERROR_ACCESS_DENIED == err) + { + isClientAdmin = false; + err = CHIP_NO_ERROR; + } + return err; +} + } // namespace /* @@ -198,22 +222,32 @@ PersistentStorageDelegate * ICDManagementServer::mStorage = nullptr; Crypto::SymmetricKeystore * ICDManagementServer::mSymmetricKeystore = nullptr; ICDConfigurationData * ICDManagementServer::mICDConfigurationData = nullptr; -Status ICDManagementServer::RegisterClient(FabricIndex fabric_index, NodeId node_id, uint64_t monitored_subject, ByteSpan key, - Optional verification_key, bool isAdmin, uint32_t & icdCounter) +Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, + const Commands::RegisterClient::DecodableType & commandData, uint32_t & icdCounter) { + FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex(); + NodeId nodeId = commandData.checkInNodeID; + uint64_t monitoredSubject = commandData.monitoredSubject; + ByteSpan key = commandData.key; + Optional verificationKey = commandData.verificationKey; + bool isClientAdmin = false; + + // Check if client is admin + VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure); + bool isFirstEntryForFabric = false; - ICDMonitoringTable table(*mStorage, fabric_index, mICDConfigurationData->GetClientsSupportedPerFabric(), mSymmetricKeystore); + ICDMonitoringTable table(*mStorage, fabricIndex, mICDConfigurationData->GetClientsSupportedPerFabric(), mSymmetricKeystore); // Get current entry, if exists ICDMonitoringEntry entry(mSymmetricKeystore); - CHIP_ERROR err = table.Find(node_id, entry); + CHIP_ERROR err = table.Find(nodeId, entry); if (CHIP_NO_ERROR == err) { // Existing entry: Validate Key if, and only if, the ISD does NOT have administrator permissions - if (!isAdmin) + if (!isClientAdmin) { - VerifyOrReturnError(verification_key.HasValue(), InteractionModel::Status::Failure); - VerifyOrReturnError(entry.IsKeyEquivalent(verification_key.Value()), InteractionModel::Status::Failure); + VerifyOrReturnError(verificationKey.HasValue(), InteractionModel::Status::Failure); + VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), InteractionModel::Status::Failure); } } else if (CHIP_ERROR_NOT_FOUND == err) @@ -231,8 +265,8 @@ Status ICDManagementServer::RegisterClient(FabricIndex fabric_index, NodeId node } // Save - entry.checkInNodeID = node_id; - entry.monitoredSubject = monitored_subject; + entry.checkInNodeID = nodeId; + entry.monitoredSubject = monitoredSubject; if (entry.keyHandleValid) { entry.DeleteKey(); @@ -262,19 +296,27 @@ Status ICDManagementServer::RegisterClient(FabricIndex fabric_index, NodeId node return InteractionModel::Status::Success; } -Status ICDManagementServer::UnregisterClient(FabricIndex fabric_index, NodeId node_id, Optional verificationKey, - bool isAdmin) +Status ICDManagementServer::UnregisterClient(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, + const Commands::UnregisterClient::DecodableType & commandData) { - ICDMonitoringTable table(*mStorage, fabric_index, mICDConfigurationData->GetClientsSupportedPerFabric(), mSymmetricKeystore); + FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex(); + NodeId nodeId = commandData.checkInNodeID; + Optional verificationKey = commandData.verificationKey; + bool isClientAdmin = false; + + // Check if client is admin + VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure); + + ICDMonitoringTable table(*mStorage, fabricIndex, mICDConfigurationData->GetClientsSupportedPerFabric(), mSymmetricKeystore); // Get current entry, if exists ICDMonitoringEntry entry(mSymmetricKeystore); - CHIP_ERROR err = table.Find(node_id, entry); + CHIP_ERROR err = table.Find(nodeId, entry); VerifyOrReturnError(CHIP_ERROR_NOT_FOUND != err, InteractionModel::Status::NotFound); VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); // Existing entry: Validate Key if, and only if, the ISD has NOT administrator permissions - if (!isAdmin) + if (!isClientAdmin) { VerifyOrReturnError(verificationKey.HasValue(), InteractionModel::Status::Failure); VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), InteractionModel::Status::Failure); @@ -291,7 +333,7 @@ Status ICDManagementServer::UnregisterClient(FabricIndex fabric_index, NodeId no return InteractionModel::Status::Success; } -Status ICDManagementServer::StayActiveRequest(FabricIndex fabric_index) +Status ICDManagementServer::StayActiveRequest(FabricIndex fabricIndex) { // TODO: Implementent stay awake logic for end device // https://github.com/project-chip/connectedhomeip/issues/24259 @@ -304,22 +346,6 @@ void ICDManagementServer::TriggerICDMTableUpdatedEvent() ICDNotifier::GetInstance().BroadcastICDManagementEvent(ICDListener::ICDManagementEvents::kTableUpdated); } -CHIP_ERROR ICDManagementServer::CheckAdmin(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, bool & isAdmin) -{ - RequestPath requestPath{ .cluster = commandPath.mClusterId, .endpoint = commandPath.mEndpointId }; - CHIP_ERROR err = GetAccessControl().Check(commandObj->GetSubjectDescriptor(), requestPath, Privilege::kAdminister); - if (CHIP_NO_ERROR == err) - { - isAdmin = true; - } - else if (CHIP_ERROR_ACCESS_DENIED == err) - { - isAdmin = false; - err = CHIP_NO_ERROR; - } - return err; -} - void ICDManagementServer::Init(PersistentStorageDelegate & storage, Crypto::SymmetricKeystore * symmetricKeystore, ICDConfigurationData & icdConfigurationData) { @@ -339,17 +365,10 @@ void ICDManagementServer::Init(PersistentStorageDelegate & storage, Crypto::Symm bool emberAfIcdManagementClusterRegisterClientCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::RegisterClient::DecodableType & commandData) { - InteractionModel::Status status = InteractionModel::Status::Failure; - bool isAdmin = false; - uint32_t icdCounter = 0; - ICDManagementServer server; + uint32_t icdCounter = 0; - if (CHIP_NO_ERROR == server.CheckAdmin(commandObj, commandPath, isAdmin)) - { - status = - server.RegisterClient(commandObj->GetAccessingFabricIndex(), commandData.checkInNodeID, commandData.monitoredSubject, - commandData.key, commandData.verificationKey, isAdmin, icdCounter); - } + ICDManagementServer server; + InteractionModel::Status status = server.RegisterClient(commandObj, commandPath, commandData, icdCounter); if (InteractionModel::Status::Success == status) { @@ -371,15 +390,8 @@ bool emberAfIcdManagementClusterRegisterClientCallback(CommandHandler * commandO bool emberAfIcdManagementClusterUnregisterClientCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::UnregisterClient::DecodableType & commandData) { - InteractionModel::Status status = InteractionModel::Status::Failure; - bool isAdmin = false; ICDManagementServer server; - - if (CHIP_NO_ERROR == server.CheckAdmin(commandObj, commandPath, isAdmin)) - { - status = server.UnregisterClient(commandObj->GetAccessingFabricIndex(), commandData.checkInNodeID, - commandData.verificationKey, isAdmin); - } + InteractionModel::Status status = server.UnregisterClient(commandObj, commandPath, commandData); commandObj->AddStatus(commandPath, status); return true; diff --git a/src/app/clusters/icd-management-server/icd-management-server.h b/src/app/clusters/icd-management-server/icd-management-server.h index 76fad5ca941475..0255112d801388 100644 --- a/src/app/clusters/icd-management-server/icd-management-server.h +++ b/src/app/clusters/icd-management-server/icd-management-server.h @@ -17,6 +17,7 @@ #pragma once +#include #include #include #include @@ -37,16 +38,22 @@ class ICDManagementServer static void Init(chip::PersistentStorageDelegate & storage, chip::Crypto::SymmetricKeystore * symmetricKeystore, chip::ICDConfigurationData & ICDConfigurationData); - Status RegisterClient(chip::FabricIndex fabric_index, chip::NodeId node_id, uint64_t monitored_subject, chip::ByteSpan key, - chip::Optional verification_key, bool is_admin, uint32_t & icdCounter); - Status UnregisterClient(chip::FabricIndex fabric_index, chip::NodeId node_id, chip::Optional verificationKey, - bool is_admin); + /** + * @brief Function that executes the business logic of the RegisterClient Command + * + * @param[out] icdCounter If function succeeds, icdCounter will have the current value of the ICDCounter stored in the + * ICDConfigurationData If function fails, icdCounter will be unchanged + * @return Status + */ + Status RegisterClient(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::IcdManagement::Commands::RegisterClient::DecodableType & commandData, + uint32_t & icdCounter); - Status StayActiveRequest(chip::FabricIndex fabric_index); + Status UnregisterClient(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::IcdManagement::Commands::UnregisterClient::DecodableType & commandData); - CHIP_ERROR CheckAdmin(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - bool & is_admin); + Status StayActiveRequest(chip::FabricIndex fabricIndex); private: /** diff --git a/src/app/clusters/media-playback-server/media-playback-delegate.h b/src/app/clusters/media-playback-server/media-playback-delegate.h index 64b85b85480318..db60f897b8b623 100644 --- a/src/app/clusters/media-playback-server/media-playback-delegate.h +++ b/src/app/clusters/media-playback-server/media-playback-delegate.h @@ -30,34 +30,45 @@ namespace app { namespace Clusters { namespace MediaPlayback { +using TrackStruct = chip::app::Clusters::MediaPlayback::Structs::TrackStruct::Type; + /** @brief * Defines methods for implementing application-specific logic for the Media Playback Cluster. */ class Delegate { public: - virtual PlaybackStateEnum HandleGetCurrentState() = 0; - virtual uint64_t HandleGetStartTime() = 0; - virtual uint64_t HandleGetDuration() = 0; - virtual CHIP_ERROR HandleGetSampledPosition(app::AttributeValueEncoder & aEncoder) = 0; - virtual float HandleGetPlaybackSpeed() = 0; - virtual uint64_t HandleGetSeekRangeStart() = 0; - virtual uint64_t HandleGetSeekRangeEnd() = 0; + virtual PlaybackStateEnum HandleGetCurrentState() = 0; + virtual uint64_t HandleGetStartTime() = 0; + virtual uint64_t HandleGetDuration() = 0; + virtual CHIP_ERROR HandleGetSampledPosition(app::AttributeValueEncoder & aEncoder) = 0; + virtual float HandleGetPlaybackSpeed() = 0; + virtual uint64_t HandleGetSeekRangeStart() = 0; + virtual uint64_t HandleGetSeekRangeEnd() = 0; + virtual CHIP_ERROR HandleGetActiveAudioTrack(app::AttributeValueEncoder & aEncoder) = 0; + virtual CHIP_ERROR HandleGetAvailableAudioTracks(app::AttributeValueEncoder & aEncoder) = 0; + virtual CHIP_ERROR HandleGetActiveTextTrack(app::AttributeValueEncoder & aEncoder) = 0; + virtual CHIP_ERROR HandleGetAvailableTextTracks(app::AttributeValueEncoder & aEncoder) = 0; - virtual void HandlePlay(CommandResponseHelper & helper) = 0; - virtual void HandlePause(CommandResponseHelper & helper) = 0; - virtual void HandleStop(CommandResponseHelper & helper) = 0; - virtual void HandleFastForward(CommandResponseHelper & helper) = 0; - virtual void HandlePrevious(CommandResponseHelper & helper) = 0; - virtual void HandleRewind(CommandResponseHelper & helper) = 0; + virtual void HandlePlay(CommandResponseHelper & helper) = 0; + virtual void HandlePause(CommandResponseHelper & helper) = 0; + virtual void HandleStop(CommandResponseHelper & helper) = 0; + virtual void HandleFastForward(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) = 0; + virtual void HandlePrevious(CommandResponseHelper & helper) = 0; + virtual void HandleRewind(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) = 0; virtual void HandleSkipBackward(CommandResponseHelper & helper, - const uint64_t & deltaPositionMilliseconds) = 0; + const uint64_t & deltaPositionMilliseconds) = 0; virtual void HandleSkipForward(CommandResponseHelper & helper, - const uint64_t & deltaPositionMilliseconds) = 0; + const uint64_t & deltaPositionMilliseconds) = 0; virtual void HandleSeek(CommandResponseHelper & helper, - const uint64_t & positionMilliseconds) = 0; - virtual void HandleNext(CommandResponseHelper & helper) = 0; - virtual void HandleStartOver(CommandResponseHelper & helper) = 0; + const uint64_t & positionMilliseconds) = 0; + virtual void HandleNext(CommandResponseHelper & helper) = 0; + virtual void HandleStartOver(CommandResponseHelper & helper) = 0; + virtual bool HandleActivateAudioTrack(const chip::CharSpan & trackId, const uint8_t & audioOutputIndex) = 0; + virtual bool HandleActivateTextTrack(const chip::CharSpan & trackId) = 0; + virtual bool HandleDeactivateTextTrack() = 0; virtual uint32_t GetFeatureMap(chip::EndpointId endpoint) = 0; diff --git a/src/app/clusters/media-playback-server/media-playback-server.cpp b/src/app/clusters/media-playback-server/media-playback-server.cpp index 028fa8fcc2ec6e..a23a2d9e2a5c77 100644 --- a/src/app/clusters/media-playback-server/media-playback-server.cpp +++ b/src/app/clusters/media-playback-server/media-playback-server.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,8 @@ using namespace chip::app::Clusters::MediaPlayback; using namespace chip::AppPlatform; #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED using chip::Protocols::InteractionModel::Status; +using StateChangedEvent = chip::app::Clusters::MediaPlayback::Events::StateChanged::Type; +using chip::app::LogEvent; static constexpr size_t kMediaPlaybackDelegateTableSize = EMBER_AF_MEDIA_PLAYBACK_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; @@ -131,6 +134,10 @@ class MediaPlaybackAttrAccess : public app::AttributeAccessInterface CHIP_ERROR ReadPlaybackSpeedAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate); CHIP_ERROR ReadSeekRangeStartAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate); CHIP_ERROR ReadSeekRangeEndAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate); + CHIP_ERROR ReadActiveAudioTrackAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate); + CHIP_ERROR ReadAvailableAudioTracksAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate); + CHIP_ERROR ReadActiveTextTrackAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate); + CHIP_ERROR ReadAvailableTextTracksAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate); CHIP_ERROR ReadFeatureFlagAttribute(EndpointId endpoint, app::AttributeValueEncoder & aEncoder, Delegate * delegate); }; @@ -141,9 +148,23 @@ CHIP_ERROR MediaPlaybackAttrAccess::Read(const app::ConcreteReadAttributePath & EndpointId endpoint = aPath.mEndpointId; Delegate * delegate = GetDelegate(endpoint); + // TODO: Add hasFeature condition + if (isDelegateNull(delegate, endpoint)) { - return CHIP_NO_ERROR; + switch (aPath.mAttributeId) + { + case app::Clusters::MediaPlayback::Attributes::AvailableAudioTracks::Id: { + return aEncoder.EncodeEmptyList(); + } + case app::Clusters::MediaPlayback::Attributes::AvailableTextTracks::Id: { + return aEncoder.EncodeEmptyList(); + } + default: { + return CHIP_NO_ERROR; + break; + } + } } switch (aPath.mAttributeId) @@ -169,6 +190,18 @@ CHIP_ERROR MediaPlaybackAttrAccess::Read(const app::ConcreteReadAttributePath & case app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::Id: { return ReadSeekRangeEndAttribute(aEncoder, delegate); } + case app::Clusters::MediaPlayback::Attributes::ActiveAudioTrack::Id: { + return ReadActiveAudioTrackAttribute(aEncoder, delegate); + } + case app::Clusters::MediaPlayback::Attributes::AvailableAudioTracks::Id: { + return ReadAvailableAudioTracksAttribute(aEncoder, delegate); + } + case app::Clusters::MediaPlayback::Attributes::ActiveTextTrack::Id: { + return ReadActiveTextTrackAttribute(aEncoder, delegate); + } + case app::Clusters::MediaPlayback::Attributes::AvailableTextTracks::Id: { + return ReadAvailableTextTracksAttribute(aEncoder, delegate); + } case app::Clusters::ContentLauncher::Attributes::FeatureMap::Id: { return ReadFeatureFlagAttribute(endpoint, aEncoder, delegate); } @@ -228,6 +261,26 @@ CHIP_ERROR MediaPlaybackAttrAccess::ReadSeekRangeEndAttribute(app::AttributeValu return aEncoder.Encode(seekRangeEnd); } +CHIP_ERROR MediaPlaybackAttrAccess::ReadActiveAudioTrackAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) +{ + return delegate->HandleGetActiveAudioTrack(aEncoder); +} + +CHIP_ERROR MediaPlaybackAttrAccess::ReadAvailableAudioTracksAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) +{ + return delegate->HandleGetAvailableAudioTracks(aEncoder); +} + +CHIP_ERROR MediaPlaybackAttrAccess::ReadActiveTextTrackAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) +{ + return delegate->HandleGetActiveTextTrack(aEncoder); +} + +CHIP_ERROR MediaPlaybackAttrAccess::ReadAvailableTextTracksAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate) +{ + return delegate->HandleGetAvailableTextTracks(aEncoder); +} + } // anonymous namespace // ----------------------------------------------------------------------------- @@ -312,11 +365,13 @@ bool emberAfMediaPlaybackClusterFastForwardCallback(app::CommandHandler * comman EndpointId endpoint = commandPath.mEndpointId; app::CommandResponseHelper responder(command, commandPath); + auto & audioAdvanceUnmuted = commandData.audioAdvanceUnmuted; + Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - delegate->HandleFastForward(responder); + delegate->HandleFastForward(responder, audioAdvanceUnmuted); } exit: @@ -360,11 +415,13 @@ bool emberAfMediaPlaybackClusterRewindCallback(app::CommandHandler * command, co EndpointId endpoint = commandPath.mEndpointId; app::CommandResponseHelper responder(command, commandPath); + auto & audioAdvanceUnmuted = commandData.audioAdvanceUnmuted; + Delegate * delegate = GetDelegate(endpoint); VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); { - delegate->HandleRewind(responder); + delegate->HandleRewind(responder, audioAdvanceUnmuted); } exit: @@ -501,6 +558,150 @@ bool emberAfMediaPlaybackClusterStartOverCallback(app::CommandHandler * command, return true; } +/** + * @brief Media Playback Cluster ActivateAudioTrack Command callback (from client) + */ +bool emberAfMediaPlaybackClusterActivateAudioTrackCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::MediaPlayback::Commands::ActivateAudioTrack::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + auto & trackId = commandData.trackID; + auto & audioOutputIndex = commandData.audioOutputIndex; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleActivateAudioTrack(trackId, audioOutputIndex); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfMediaPlaybackClusterActivateAudioTrackCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Media Playback Cluster ActivateTextTrack Command callback (from client) + */ +bool emberAfMediaPlaybackClusterActivateTextTrackCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::MediaPlayback::Commands::ActivateTextTrack::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + auto & trackId = commandData.trackID; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleActivateTextTrack(trackId); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfMediaPlaybackClusterActivateTextTrackCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** + * @brief Media Playback Cluster DeactivateTextTrack Command callback (from client) + */ +bool emberAfMediaPlaybackClusterDeactivateTextTrackCallback( + chip::app::CommandHandler * command, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::MediaPlayback::Commands::DeactivateTextTrack::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE); + { + delegate->HandleDeactivateTextTrack(); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfMediaPlaybackClusterDeactivateTextTrackCallback error: %s", err.AsString()); + status = Status::Failure; + } + + command->AddStatus(commandPath, status); + return true; +} + +/** @brief Media Playback Cluster Server Attribute Changed + * + * Server Attribute Changed + * + * @param attributePath Concrete attribute path that changed + */ +void MatterMediaPlaybackClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath) +{ + ChipLogProgress(Zcl, "Media Playback Server Cluster Attribute changed [EP:%d, ID:0x%x]", attributePath.mEndpointId, + (unsigned int) attributePath.mAttributeId); + + // TODO: Check if event feature is supported and only then continue + switch (attributePath.mAttributeId) + { + case app::Clusters::MediaPlayback::Attributes::CurrentState::Id: + case app::Clusters::MediaPlayback::Attributes::StartTime::Id: + case app::Clusters::MediaPlayback::Attributes::Duration::Id: + case app::Clusters::MediaPlayback::Attributes::SampledPosition::Id: + case app::Clusters::MediaPlayback::Attributes::PlaybackSpeed::Id: + case app::Clusters::MediaPlayback::Attributes::SeekRangeStart::Id: + case app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::Id: { + EventNumber eventNumber; + + // TODO: Update values + PlaybackStateEnum currentState = static_cast(0); + uint64_t startTime = static_cast(0); + uint64_t duration = static_cast(0); + Structs::PlaybackPositionStruct::Type sampledPosition; + float playbackSpeed = static_cast(0); + uint64_t seekRangeEnd = static_cast(0); + uint64_t seekRangeStart = static_cast(0); + chip::ByteSpan data = ByteSpan(); + bool audioAdvanceUnmuted = false; + + StateChangedEvent event{ currentState, startTime, duration, sampledPosition, playbackSpeed, + seekRangeEnd, seekRangeStart, MakeOptional(data), audioAdvanceUnmuted }; + + // TODO: Add endpoint variable instead of 0 + CHIP_ERROR logEventError = LogEvent(event, 0, eventNumber); + + if (CHIP_NO_ERROR != logEventError) + { + // TODO: Add endpoint variable instead of 0 + ChipLogError(Zcl, "[Notify] Unable to send notify event: %s [endpointId=%d]", logEventError.AsString(), 0); + } + break; + } + + default: { + ChipLogProgress(Zcl, "Media Playback Server: unhandled attribute ID"); + break; + } + } +} + void MatterMediaPlaybackPluginServerInitCallback() { registerAttributeAccessOverride(&gMediaPlaybackAttrAccess); diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp index 19ddd5025a7346..1c5a8641a59aa2 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.cpp +++ b/src/app/clusters/network-commissioning/network-commissioning.cpp @@ -830,8 +830,10 @@ void Instance::OnFinished(Status status, CharSpan debugText, ThreadScanResponseI size_t scanResponseArrayLength = 0; uint8_t extendedAddressBuffer[Thread::kSizeExtendedPanId]; - SuccessOrExit(err = commandHandle->PrepareCommand( - ConcreteCommandPath(mPath.mEndpointId, NetworkCommissioning::Id, Commands::ScanNetworksResponse::Id))); + const CommandHandler::InvokeResponseParameters prepareParams(mPath); + SuccessOrExit( + err = commandHandle->PrepareInvokeResponseCommand( + ConcreteCommandPath(mPath.mEndpointId, NetworkCommissioning::Id, Commands::ScanNetworksResponse::Id), prepareParams)); VerifyOrExit((writer = commandHandle->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); SuccessOrExit(err = writer->Put(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kNetworkingStatus), status)); @@ -942,8 +944,10 @@ void Instance::OnFinished(Status status, CharSpan debugText, WiFiScanResponseIte WiFiScanResponse scanResponse; size_t networksEncoded = 0; - SuccessOrExit(err = commandHandle->PrepareCommand( - ConcreteCommandPath(mPath.mEndpointId, NetworkCommissioning::Id, Commands::ScanNetworksResponse::Id))); + const CommandHandler::InvokeResponseParameters prepareParams(mPath); + SuccessOrExit( + err = commandHandle->PrepareInvokeResponseCommand( + ConcreteCommandPath(mPath.mEndpointId, NetworkCommissioning::Id, Commands::ScanNetworksResponse::Id), prepareParams)); VerifyOrExit((writer = commandHandle->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); SuccessOrExit(err = writer->Put(TLV::ContextTag(Commands::ScanNetworksResponse::Fields::kNetworkingStatus), status)); diff --git a/src/app/clusters/target-navigator-server/target-navigator-server.cpp b/src/app/clusters/target-navigator-server/target-navigator-server.cpp index 1718b2b9cc459c..e52ef407003eb1 100644 --- a/src/app/clusters/target-navigator-server/target-navigator-server.cpp +++ b/src/app/clusters/target-navigator-server/target-navigator-server.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -43,7 +44,9 @@ using namespace chip::app::Clusters::TargetNavigator; #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED using namespace chip::AppPlatform; #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED +using chip::app::LogEvent; using chip::Protocols::InteractionModel::Status; +using TargetUpdatedEvent = chip::app::Clusters::TargetNavigator::Events::TargetUpdated::Type; static constexpr size_t kTargetNavigatorDelegateTableSize = EMBER_AF_TARGET_NAVIGATOR_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; @@ -203,6 +206,49 @@ bool emberAfTargetNavigatorClusterNavigateTargetCallback(app::CommandHandler * c return true; } +/** @brief Target Navigator Cluster Server Attribute Changed + * + * Server Attribute Changed + * + * @param attributePath Concrete attribute path that changed + */ +void MatterTargetNavigatorClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath) +{ + ChipLogProgress(Zcl, "Target Navigator Server Cluster Attribute changed [EP:%d, ID:0x%x]", attributePath.mEndpointId, + (unsigned int) attributePath.mAttributeId); + + // TODO: Check if event feature is supported and only then continue + switch (attributePath.mAttributeId) + { + case app::Clusters::TargetNavigator::Attributes::TargetList::Id: + case app::Clusters::TargetNavigator::Attributes::CurrentTarget::Id: { + EventNumber eventNumber; + + // TODO: Update values + chip::app::DataModel::List targetList; + uint8_t currentTarget = static_cast(0); + chip::ByteSpan data = ByteSpan(); + + TargetUpdatedEvent event{ targetList, currentTarget, data }; + + // TODO: Add endpoint variable instead of 0 + CHIP_ERROR logEventError = LogEvent(event, 0, eventNumber); + + if (CHIP_NO_ERROR != logEventError) + { + // TODO: Add endpoint variable instead of 0 + ChipLogError(Zcl, "[Notify] Unable to send notify event: %s [endpointId=%d]", logEventError.AsString(), 0); + } + break; + } + + default: { + ChipLogProgress(Zcl, "Media Playback Server: unhandled attribute ID"); + break; + } + } +} + void MatterTargetNavigatorPluginServerInitCallback() { registerAttributeAccessOverride(&gTargetNavigatorAttrAccess); diff --git a/src/app/icd/ICDCheckInSender.cpp b/src/app/icd/ICDCheckInSender.cpp index 8557967eceba1a..9781069b2c743d 100644 --- a/src/app/icd/ICDCheckInSender.cpp +++ b/src/app/icd/ICDCheckInSender.cpp @@ -61,10 +61,7 @@ CHIP_ERROR ICDCheckInSender::SendCheckInMsg(const Transport::PeerAddress & addr) VerifyOrReturnError(!buffer.IsNull(), CHIP_ERROR_NO_MEMORY); MutableByteSpan output{ buffer->Start(), buffer->MaxDataLength() }; - // TODO retrieve Check-in counter - CounterType counter = 0; - - ReturnErrorOnFailure(CheckinMessage::GenerateCheckinMessagePayload(mKey, counter, ByteSpan(), output)); + ReturnErrorOnFailure(CheckinMessage::GenerateCheckinMessagePayload(mKey, mICDCounter, ByteSpan(), output)); buffer->SetDataLength(static_cast(output.size())); VerifyOrReturnError(mExchangeManager->GetSessionManager() != nullptr, CHIP_ERROR_INTERNAL); @@ -81,13 +78,15 @@ CHIP_ERROR ICDCheckInSender::SendCheckInMsg(const Transport::PeerAddress & addr) return exchangeContext->SendMessage(MsgType::ICD_CheckIn, std::move(buffer), Messaging::SendMessageFlags::kNoAutoRequestAck); } -CHIP_ERROR ICDCheckInSender::RequestResolve(ICDMonitoringEntry & entry, FabricTable * fabricTable) +CHIP_ERROR ICDCheckInSender::RequestResolve(ICDMonitoringEntry & entry, FabricTable * fabricTable, uint32_t counter) { VerifyOrReturnError(entry.IsValid(), CHIP_ERROR_INTERNAL); VerifyOrReturnError(fabricTable != nullptr, CHIP_ERROR_INTERNAL); const FabricInfo * fabricInfo = fabricTable->FindFabricWithIndex(entry.fabricIndex); PeerId peerId(fabricInfo->GetCompressedFabricId(), entry.checkInNodeID); + mICDCounter = counter; + AddressResolve::NodeLookupRequest request(peerId); memcpy(mKey.AsMutable(), entry.key.As(), diff --git a/src/app/icd/ICDCheckInSender.h b/src/app/icd/ICDCheckInSender.h index a06efeee419287..0055d66804d0fb 100644 --- a/src/app/icd/ICDCheckInSender.h +++ b/src/app/icd/ICDCheckInSender.h @@ -34,7 +34,7 @@ class ICDCheckInSender : public AddressResolve::NodeListener ICDCheckInSender(Messaging::ExchangeManager * exchangeManager); ~ICDCheckInSender(){}; - CHIP_ERROR RequestResolve(ICDMonitoringEntry & entry, FabricTable * fabricTable); + CHIP_ERROR RequestResolve(ICDMonitoringEntry & entry, FabricTable * fabricTable, uint32_t counter); // AddressResolve::NodeListener - notifications when dnssd finds a node IP address void OnNodeAddressResolved(const PeerId & peerId, const AddressResolve::ResolveResult & result) override; @@ -51,6 +51,8 @@ class ICDCheckInSender : public AddressResolve::NodeListener Messaging::ExchangeManager * mExchangeManager = nullptr; Crypto::Aes128KeyHandle mKey = Crypto::Aes128KeyHandle(); + + uint32_t mICDCounter = 0; }; } // namespace app diff --git a/src/app/icd/ICDConfigurationData.h b/src/app/icd/ICDConfigurationData.h index efb4e7e73867ca..4fd16c92c1a7b1 100644 --- a/src/app/icd/ICDConfigurationData.h +++ b/src/app/icd/ICDConfigurationData.h @@ -42,6 +42,8 @@ class ICDManager; class ICDConfigurationData { public: + static constexpr uint32_t ICD_CHECK_IN_COUNTER_MIN_INCREMENT = 100; + enum class ICDMode : uint8_t { SIT, // Short Interval Time ICD @@ -108,8 +110,6 @@ class ICDConfigurationData uint16_t mActiveThreshold_ms = CHIP_CONFIG_ICD_ACTIVE_MODE_THRESHOLD_MS; - // TODO : Implement ICD counter - // https://github.com/project-chip/connectedhomeip/issues/29184 uint32_t mICDCounter = 0; static_assert((CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC) >= 1, diff --git a/src/app/icd/ICDManager.cpp b/src/app/icd/ICDManager.cpp index eac574ca20ab2d..daf312058ee693 100644 --- a/src/app/icd/ICDManager.cpp +++ b/src/app/icd/ICDManager.cpp @@ -64,6 +64,8 @@ void ICDManager::Init(PersistentStorageDelegate * storage, FabricTable * fabricT mSymmetricKeystore = symmetricKeystore; mExchangeManager = exchangeManager; + VerifyOrDie(InitCounter() == CHIP_NO_ERROR); + // Removing the check for now since it is possible for the Fast polling // to be larger than the ActiveModeDuration for now // uint32_t activeModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDurationMs(); @@ -105,6 +107,9 @@ void ICDManager::SendCheckInMsgs() #if !CONFIG_BUILD_FOR_HOST_UNIT_TEST VerifyOrDie(mStorage != nullptr); VerifyOrDie(mFabricTable != nullptr); + uint32_t counter = ICDConfigurationData::GetInstance().GetICDCounter(); + bool counterIncremented = false; + for (const auto & fabricInfo : *mFabricTable) { uint16_t supported_clients = ICDConfigurationData::GetInstance().GetClientsSupportedPerFabric(); @@ -139,12 +144,23 @@ void ICDManager::SendCheckInMsgs() continue; } + // Increment counter only once to prevent depletion of the available range. + if (!counterIncremented) + { + counterIncremented = true; + + if (CHIP_NO_ERROR != IncrementCounter()) + { + ChipLogError(AppServer, "Incremented ICDCounter but failed to access/save to Persistent storage"); + } + } + // SenderPool will be released upon transition from active to idle state // This will happen when all ICD Check-In messages are sent on the network ICDCheckInSender * sender = mICDSenderPool.CreateObject(mExchangeManager); VerifyOrReturn(sender != nullptr, ChipLogError(AppServer, "Failed to allocate ICDCheckinSender")); - if (CHIP_NO_ERROR != sender->RequestResolve(entry, mFabricTable)) + if (CHIP_NO_ERROR != sender->RequestResolve(entry, mFabricTable, counter)) { ChipLogError(AppServer, "Failed to send ICD Check-In"); } @@ -153,6 +169,54 @@ void ICDManager::SendCheckInMsgs() #endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST } +CHIP_ERROR ICDManager::InitCounter() +{ + CHIP_ERROR err; + uint32_t temp; + uint16_t size = static_cast(sizeof(uint32_t)); + + err = mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::ICDCheckInCounter().KeyName(), &temp, size); + if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) + { + // First time retrieving the counter + temp = chip::Crypto::GetRandU32(); + } + else if (err != CHIP_NO_ERROR) + { + return err; + } + + ICDConfigurationData::GetInstance().SetICDCounter(temp); + temp += ICDConfigurationData::ICD_CHECK_IN_COUNTER_MIN_INCREMENT; + + // Increment the count directly to minimize flash write. + return mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDCheckInCounter().KeyName(), &temp, size); +} + +CHIP_ERROR ICDManager::IncrementCounter() +{ + uint32_t temp = 0; + StorageKeyName key = DefaultStorageKeyAllocator::ICDCheckInCounter(); + uint16_t size = static_cast(sizeof(uint32_t)); + + ICDConfigurationData::GetInstance().mICDCounter++; + + if (mStorage == nullptr) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + ReturnErrorOnFailure(mStorage->SyncGetKeyValue(key.KeyName(), &temp, size)); + + if (temp == ICDConfigurationData::GetInstance().mICDCounter) + { + temp = ICDConfigurationData::GetInstance().mICDCounter + ICDConfigurationData::ICD_CHECK_IN_COUNTER_MIN_INCREMENT; + return mStorage->SyncSetKeyValue(key.KeyName(), &temp, size); + } + + return CHIP_NO_ERROR; +} + void ICDManager::UpdateICDMode() { assertChipStackLockedByCurrentThread(); diff --git a/src/app/icd/ICDManager.h b/src/app/icd/ICDManager.h index 7958adada0de63..4034f1520b34df 100644 --- a/src/app/icd/ICDManager.h +++ b/src/app/icd/ICDManager.h @@ -120,6 +120,10 @@ class ICDManager : public ICDListener */ static void OnTransitionToIdle(System::Layer * aLayer, void * appState); + // ICD Counter + CHIP_ERROR IncrementCounter(); + CHIP_ERROR InitCounter(); + uint8_t mOpenExchangeContextCount = 0; uint8_t mCheckInRequestCount = 0; diff --git a/src/app/icd/client/BUILD.gn b/src/app/icd/client/BUILD.gn new file mode 100644 index 00000000000000..8e04d3b586140f --- /dev/null +++ b/src/app/icd/client/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +# ICD sources and configurations +source_set("manager") { + sources = [ + "DefaultICDClientStorage.cpp", + "DefaultICDClientStorage.h", + "ICDClientInfo.h", + "ICDClientStorage.h", + ] + + deps = [ "${chip_root}/src/lib/core" ] + public_deps = [ + "${chip_root}/src/app:app_config", + "${chip_root}/src/crypto", + "${chip_root}/src/lib/support", + ] +} diff --git a/src/app/icd/client/DefaultICDClientStorage.cpp b/src/app/icd/client/DefaultICDClientStorage.cpp new file mode 100644 index 00000000000000..b7fa634064826f --- /dev/null +++ b/src/app/icd/client/DefaultICDClientStorage.cpp @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DefaultICDClientStorage.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +// FabricIndex is uint8_t, the tlv size with anonymous tag is 1(control bytes) + 1(value) = 2 +constexpr size_t kFabricIndexTlvSize = 2; + +// The array itself has a control byte and an end-of-array marker. +constexpr size_t kArrayOverHead = 2; +constexpr size_t kFabricIndexMax = 255; + +constexpr size_t kMaxFabricListTlvLength = kFabricIndexTlvSize * kFabricIndexMax + kArrayOverHead; +static_assert(kMaxFabricListTlvLength <= std::numeric_limits::max(), "Expected size for fabric list TLV is too large!"); +} // namespace + +namespace chip { +namespace app { +CHIP_ERROR DefaultICDClientStorage::UpdateFabricList(FabricIndex fabricIndex) +{ + for (auto & fabric_idx : mFabricList) + { + if (fabric_idx == fabricIndex) + { + return CHIP_NO_ERROR; + } + } + + mFabricList.push_back(fabricIndex); + + Platform::ScopedMemoryBuffer backingBuffer; + size_t counter = mFabricList.size(); + size_t total = kFabricIndexTlvSize * counter + kArrayOverHead; + ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); + + TLV::TLVType arrayType; + ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Array, arrayType)); + for (auto & fabric_idx : mFabricList) + { + ReturnErrorOnFailure(writer.Put(TLV::AnonymousTag(), fabric_idx)); + } + ReturnErrorOnFailure(writer.EndContainer(arrayType)); + + const auto len = writer.GetLengthWritten(); + VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); + + writer.Finalize(backingBuffer); + return mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName(), backingBuffer.Get(), + static_cast(len)); +} + +CHIP_ERROR DefaultICDClientStorage::LoadFabricList() +{ + Platform::ScopedMemoryBuffer backingBuffer; + ReturnErrorCodeIf(!backingBuffer.Calloc(kMaxFabricListTlvLength), CHIP_ERROR_NO_MEMORY); + uint16_t length = kMaxFabricListTlvLength; + ReturnErrorOnFailure( + mpClientInfoStore->SyncGetKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName(), backingBuffer.Get(), length)); + + TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), length); + ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Array, TLV::AnonymousTag())); + TLV::TLVType arrayType; + ReturnErrorOnFailure(reader.EnterContainer(arrayType)); + + while ((reader.Next(TLV::kTLVType_UnsignedInteger, TLV::AnonymousTag())) == CHIP_NO_ERROR) + { + FabricIndex fabricIndex; + ReturnErrorOnFailure(reader.Get(fabricIndex)); + mFabricList.push_back(fabricIndex); + } + + ReturnErrorOnFailure(reader.ExitContainer(arrayType)); + return reader.VerifyEndOfContainer(); +} + +DefaultICDClientStorage::ICDClientInfoIteratorImpl::ICDClientInfoIteratorImpl(DefaultICDClientStorage & manager) : mManager(manager) +{ + mFabricListIndex = 0; + mClientInfoIndex = 0; + mClientInfoVector.clear(); +} + +size_t DefaultICDClientStorage::ICDClientInfoIteratorImpl::Count() +{ + size_t total = 0; + for (auto & fabric_idx : mManager.mFabricList) + { + size_t count = 0; + size_t clientInfoSize = 0; + if (mManager.LoadCounter(fabric_idx, count, clientInfoSize) != CHIP_NO_ERROR) + { + return 0; + }; + IgnoreUnusedVariable(clientInfoSize); + total += count; + } + + return total; +} + +bool DefaultICDClientStorage::ICDClientInfoIteratorImpl::Next(ICDClientInfo & item) +{ + for (; mFabricListIndex < mManager.mFabricList.size(); mFabricListIndex++) + { + if (mClientInfoVector.size() == 0) + { + size_t clientInfoSize = 0; + if (mManager.Load(mManager.mFabricList[mFabricListIndex], mClientInfoVector, clientInfoSize) != CHIP_NO_ERROR) + { + continue; + } + IgnoreUnusedVariable(clientInfoSize); + } + if (mClientInfoIndex < mClientInfoVector.size()) + { + item = mClientInfoVector[mClientInfoIndex]; + mClientInfoIndex++; + return true; + } + mClientInfoIndex = 0; + mClientInfoVector.clear(); + } + + return false; +} + +void DefaultICDClientStorage::ICDClientInfoIteratorImpl::Release() +{ + mManager.mICDClientInfoIterators.ReleaseObject(this); +} + +CHIP_ERROR DefaultICDClientStorage::Init(PersistentStorageDelegate * clientInfoStore, Crypto::SymmetricKeystore * keyStore) +{ + VerifyOrReturnError(clientInfoStore != nullptr && keyStore != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mpClientInfoStore == nullptr && mpKeyStore == nullptr, CHIP_ERROR_INCORRECT_STATE); + mpClientInfoStore = clientInfoStore; + mpKeyStore = keyStore; + CHIP_ERROR err = LoadFabricList(); + if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) + { + err = CHIP_NO_ERROR; + } + return err; +} + +DefaultICDClientStorage::ICDClientInfoIterator * DefaultICDClientStorage::IterateICDClientInfo() +{ + return mICDClientInfoIterators.CreateObject(*this); +} + +CHIP_ERROR DefaultICDClientStorage::LoadCounter(FabricIndex fabricIndex, size_t & count, size_t & clientInfoSize) +{ + Platform::ScopedMemoryBuffer backingBuffer; + size_t len = MaxICDCounterSize(); + VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY); + uint16_t length = static_cast(len); + + CHIP_ERROR err = mpClientInfoStore->SyncGetKeyValue( + DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName(), backingBuffer.Get(), length); + if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + + TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), len); + ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())); + TLV::TLVType structType; + ReturnErrorOnFailure(reader.EnterContainer(structType)); + uint32_t tempCount = 0; + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(CounterTag::kCount))); + ReturnErrorOnFailure(reader.Get(tempCount)); + count = static_cast(tempCount); + + uint32_t tempClientInfoSize = 0; + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(CounterTag::kSize))); + ReturnErrorOnFailure(reader.Get(tempClientInfoSize)); + clientInfoSize = static_cast(tempClientInfoSize); + + ReturnErrorOnFailure(reader.ExitContainer(structType)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DefaultICDClientStorage::Load(FabricIndex fabricIndex, std::vector & clientInfoVector, + size_t & clientInfoSize) +{ + size_t count = 0; + ReturnErrorOnFailure(LoadCounter(fabricIndex, count, clientInfoSize)); + size_t len = clientInfoSize * count + kArrayOverHead; + Platform::ScopedMemoryBuffer backingBuffer; + VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY); + uint16_t length = static_cast(len); + CHIP_ERROR err = mpClientInfoStore->SyncGetKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricIndex).KeyName(), + backingBuffer.Get(), length); + if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + + TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), len); + + ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Array, TLV::AnonymousTag())); + TLV::TLVType arrayType; + ReturnErrorOnFailure(reader.EnterContainer(arrayType)); + + while ((err = reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())) == CHIP_NO_ERROR) + { + ICDClientInfo clientInfo; + TLV::TLVType ICDClientInfoType; + NodeId nodeId; + FabricIndex fabric; + ReturnErrorOnFailure(reader.EnterContainer(ICDClientInfoType)); + // Peer Node ID + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kPeerNodeId))); + ReturnErrorOnFailure(reader.Get(nodeId)); + + // Fabric Index + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kFabricIndex))); + ReturnErrorOnFailure(reader.Get(fabric)); + clientInfo.peer_node = ScopedNodeId(nodeId, fabric); + + // Start ICD Counter + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kStartICDCounter))); + ReturnErrorOnFailure(reader.Get(clientInfo.start_icd_counter)); + + // Offset + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kOffset))); + ReturnErrorOnFailure(reader.Get(clientInfo.offset)); + + // MonitoredSubject + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kMonitoredSubject))); + ReturnErrorOnFailure(reader.Get(clientInfo.monitored_subject)); + + // Shared key + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kSharedKey))); + ByteSpan buf; + ReturnErrorOnFailure(reader.Get(buf)); + VerifyOrReturnError(buf.size() == sizeof(Crypto::Aes128KeyByteArray), CHIP_ERROR_INTERNAL); + memcpy(clientInfo.shared_key.AsMutable(), buf.data(), sizeof(Crypto::Aes128KeyByteArray)); + ReturnErrorOnFailure(reader.ExitContainer(ICDClientInfoType)); + clientInfoVector.push_back(clientInfo); + } + + if (err != CHIP_END_OF_TLV) + { + return err; + } + + return reader.ExitContainer(arrayType); +} + +CHIP_ERROR DefaultICDClientStorage::SetKey(ICDClientInfo & clientInfo, const ByteSpan keyData) +{ + VerifyOrReturnError(keyData.size() == sizeof(Crypto::Aes128KeyByteArray), CHIP_ERROR_INVALID_ARGUMENT); + + Crypto::Aes128KeyByteArray keyMaterial; + memcpy(keyMaterial, keyData.data(), sizeof(Crypto::Aes128KeyByteArray)); + + return mpKeyStore->CreateKey(keyMaterial, clientInfo.shared_key); +} + +CHIP_ERROR DefaultICDClientStorage::SerializeToTlv(TLV::TLVWriter & writer, const std::vector & clientInfoVector) +{ + TLV::TLVType arrayType; + ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Array, arrayType)); + for (auto & clientInfo : clientInfoVector) + { + TLV::TLVType ICDClientInfoContainerType; + ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, ICDClientInfoContainerType)); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kPeerNodeId), clientInfo.peer_node.GetNodeId())); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kFabricIndex), clientInfo.peer_node.GetFabricIndex())); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kStartICDCounter), clientInfo.start_icd_counter)); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kOffset), clientInfo.offset)); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kMonitoredSubject), clientInfo.monitored_subject)); + ByteSpan buf(clientInfo.shared_key.As()); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kSharedKey), buf)); + ReturnErrorOnFailure(writer.EndContainer(ICDClientInfoContainerType)); + } + return writer.EndContainer(arrayType); +} + +CHIP_ERROR DefaultICDClientStorage::StoreEntry(const ICDClientInfo & clientInfo) +{ + std::vector clientInfoVector; + size_t clientInfoSize = MaxICDClientInfoSize(); + ReturnErrorOnFailure(Load(clientInfo.peer_node.GetFabricIndex(), clientInfoVector, clientInfoSize)); + + for (auto it = clientInfoVector.begin(); it != clientInfoVector.end(); it++) + { + if (clientInfo.peer_node.GetNodeId() == it->peer_node.GetNodeId()) + { + ReturnErrorOnFailure(DecreaseEntryCountForFabric(clientInfo.peer_node.GetFabricIndex())); + clientInfoVector.erase(it); + break; + } + } + + clientInfoVector.push_back(clientInfo); + size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead; + Platform::ScopedMemoryBuffer backingBuffer; + ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); + + ReturnErrorOnFailure(SerializeToTlv(writer, clientInfoVector)); + + const auto len = writer.GetLengthWritten(); + VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); + + writer.Finalize(backingBuffer); + ReturnErrorOnFailure(mpClientInfoStore->SyncSetKeyValue( + DefaultStorageKeyAllocator::ICDClientInfoKey(clientInfo.peer_node.GetFabricIndex()).KeyName(), backingBuffer.Get(), + static_cast(len))); + + return IncreaseEntryCountForFabric(clientInfo.peer_node.GetFabricIndex()); +} + +CHIP_ERROR DefaultICDClientStorage::IncreaseEntryCountForFabric(FabricIndex fabricIndex) +{ + return UpdateEntryCountForFabric(fabricIndex, /*increase*/ true); +} + +CHIP_ERROR DefaultICDClientStorage::DecreaseEntryCountForFabric(FabricIndex fabricIndex) +{ + return UpdateEntryCountForFabric(fabricIndex, /*increase*/ false); +} + +CHIP_ERROR DefaultICDClientStorage::UpdateEntryCountForFabric(FabricIndex fabricIndex, bool increase) +{ + size_t count = 0; + size_t clientInfoSize = MaxICDClientInfoSize(); + ReturnErrorOnFailure(LoadCounter(fabricIndex, count, clientInfoSize)); + if (increase) + { + count++; + } + else + { + count--; + } + + size_t total = MaxICDCounterSize(); + Platform::ScopedMemoryBuffer backingBuffer; + ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); + + TLV::TLVType structType; + ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, structType)); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(CounterTag::kCount), static_cast(count))); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(CounterTag::kSize), static_cast(clientInfoSize))); + ReturnErrorOnFailure(writer.EndContainer(structType)); + + const auto len = writer.GetLengthWritten(); + VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); + writer.Finalize(backingBuffer); + + return mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName(), + backingBuffer.Get(), static_cast(len)); +} + +CHIP_ERROR DefaultICDClientStorage::DeleteEntry(const ScopedNodeId & peerNode) +{ + size_t clientInfoSize = 0; + std::vector clientInfoVector; + ReturnErrorOnFailure(Load(peerNode.GetFabricIndex(), clientInfoVector, clientInfoSize)); + + for (auto it = clientInfoVector.begin(); it != clientInfoVector.end(); it++) + { + if (peerNode.GetNodeId() == it->peer_node.GetNodeId()) + { + mpKeyStore->DestroyKey(it->shared_key); + it = clientInfoVector.erase(it); + break; + } + } + + ReturnErrorOnFailure( + mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName())); + + size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead; + Platform::ScopedMemoryBuffer backingBuffer; + ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); + + ReturnErrorOnFailure(SerializeToTlv(writer, clientInfoVector)); + + const auto len = writer.GetLengthWritten(); + VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); + + writer.Finalize(backingBuffer); + ReturnErrorOnFailure( + mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName(), + backingBuffer.Get(), static_cast(len))); + + return DecreaseEntryCountForFabric(peerNode.GetFabricIndex()); +} + +CHIP_ERROR DefaultICDClientStorage::DeleteAllEntries(FabricIndex fabricIndex) +{ + size_t clientInfoSize = 0; + std::vector clientInfoVector; + ReturnErrorOnFailure(Load(fabricIndex, clientInfoVector, clientInfoSize)); + IgnoreUnusedVariable(clientInfoSize); + for (auto & clientInfo : clientInfoVector) + { + mpKeyStore->DestroyKey(clientInfo.shared_key); + } + ReturnErrorOnFailure( + mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricIndex).KeyName())); + return mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::FabricICDClientInfoCounter(fabricIndex).KeyName()); +} + +CHIP_ERROR DefaultICDClientStorage::ProcessCheckInPayload(const ByteSpan & payload, ICDClientInfo & clientInfo) +{ + // TODO: Need to implement default decription code using CheckinMessage::ParseCheckinMessagePayload + return CHIP_NO_ERROR; +} +} // namespace app +} // namespace chip diff --git a/src/app/icd/client/DefaultICDClientStorage.h b/src/app/icd/client/DefaultICDClientStorage.h new file mode 100644 index 00000000000000..adc8c69113a700 --- /dev/null +++ b/src/app/icd/client/DefaultICDClientStorage.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "ICDClientStorage.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO: SymmetricKeystore is an alias for SessionKeystore, replace the below when sdk supports SymmetricKeystore +namespace chip { +namespace Crypto { +using SymmetricKeystore = SessionKeystore; +} // namespace Crypto +} // namespace chip + +namespace chip { +namespace app { + +/** + * A DefaultICDClientStorage implementation of ICDClientStorage. + */ +class DefaultICDClientStorage : public ICDClientStorage +{ +public: + static constexpr size_t kIteratorsMax = CHIP_CONFIG_MAX_ICD_CLIENTS_INFO_STORAGE_CONCURRENT_ITERATORS; + + CHIP_ERROR Init(PersistentStorageDelegate * clientInfoStore, Crypto::SymmetricKeystore * keyStore); + + ICDClientInfoIterator * IterateICDClientInfo() override; + + CHIP_ERROR UpdateFabricList(FabricIndex fabricIndex); + + CHIP_ERROR SetKey(ICDClientInfo & clientInfo, const ByteSpan keyData) override; + + CHIP_ERROR StoreEntry(const ICDClientInfo & clientInfo) override; + + CHIP_ERROR DeleteEntry(const ScopedNodeId & peerNodeId) override; + + CHIP_ERROR DeleteAllEntries(FabricIndex fabricIndex) override; + + CHIP_ERROR ProcessCheckInPayload(const ByteSpan & payload, ICDClientInfo & clientInfo) override; + +protected: + enum class ClientInfoTag : uint8_t + { + kPeerNodeId = 1, + kFabricIndex = 2, + kStartICDCounter = 3, + kOffset = 4, + kMonitoredSubject = 5, + kSharedKey = 6 + }; + + enum class CounterTag : uint8_t + { + kCount = 1, + kSize = 2, + }; + + class ICDClientInfoIteratorImpl : public ICDClientInfoIterator + { + public: + ICDClientInfoIteratorImpl(DefaultICDClientStorage & manager); + size_t Count() override; + bool Next(ICDClientInfo & info) override; + void Release() override; + + private: + DefaultICDClientStorage & mManager; + size_t mFabricListIndex = 0; + size_t mClientInfoIndex = 0; + std::vector mClientInfoVector; + }; + + static constexpr size_t MaxICDClientInfoSize() + { + // All the fields added together + return TLV::EstimateStructOverhead(sizeof(NodeId), sizeof(FabricIndex), sizeof(uint32_t), sizeof(uint32_t), + sizeof(uint64_t), sizeof(Crypto::Aes128KeyByteArray)); + } + + static constexpr size_t MaxICDCounterSize() + { + // All the fields added together + return TLV::EstimateStructOverhead(sizeof(size_t), sizeof(size_t)); + } + +private: + friend class ICDClientInfoIteratorImpl; + CHIP_ERROR LoadFabricList(); + CHIP_ERROR LoadCounter(FabricIndex fabricIndex, size_t & count, size_t & clientInfoSize); + + CHIP_ERROR IncreaseEntryCountForFabric(FabricIndex fabricIndex); + CHIP_ERROR DecreaseEntryCountForFabric(FabricIndex fabricIndex); + CHIP_ERROR UpdateEntryCountForFabric(FabricIndex fabricIndex, bool increase); + + CHIP_ERROR SerializeToTlv(TLV::TLVWriter & writer, const std::vector & clientInfoVector); + CHIP_ERROR Load(FabricIndex fabricIndex, std::vector & clientInfoVector, size_t & clientInfoSize); + + ObjectPool mICDClientInfoIterators; + + PersistentStorageDelegate * mpClientInfoStore = nullptr; + Crypto::SymmetricKeystore * mpKeyStore = nullptr; + std::vector mFabricList; +}; +} // namespace app +} // namespace chip diff --git a/src/app/icd/client/ICDClientInfo.h b/src/app/icd/client/ICDClientInfo.h new file mode 100644 index 00000000000000..4ab2aeec6dc8e5 --- /dev/null +++ b/src/app/icd/client/ICDClientInfo.h @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { + +struct ICDClientInfo +{ + ScopedNodeId peer_node; + uint32_t start_icd_counter = 0; + uint32_t offset = 0; + uint64_t monitored_subject = static_cast(0); + Crypto::Aes128KeyHandle shared_key = Crypto::Aes128KeyHandle(); + + ICDClientInfo() {} + ICDClientInfo(const ICDClientInfo & other) { *this = other; } + + ICDClientInfo & operator=(const ICDClientInfo & other) + { + peer_node = other.peer_node; + start_icd_counter = other.start_icd_counter; + offset = other.offset; + monitored_subject = other.monitored_subject; + ByteSpan buf(other.shared_key.As()); + memcpy(shared_key.AsMutable(), buf.data(), sizeof(Crypto::Aes128KeyByteArray)); + return *this; + } +}; + +} // namespace app +} // namespace chip diff --git a/src/app/icd/client/ICDClientStorage.h b/src/app/icd/client/ICDClientStorage.h new file mode 100644 index 00000000000000..4df2c961260104 --- /dev/null +++ b/src/app/icd/client/ICDClientStorage.h @@ -0,0 +1,95 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "ICDClientInfo.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { + +/** + * The ICDClientStorage class is an abstract interface that defines the operations + * for storing, retrieving and deleting ICD client information in persistent storage. + */ +class ICDClientStorage +{ +public: + using ICDClientInfoIterator = CommonIterator; + + virtual ~ICDClientStorage() = default; + + /** + * Iterate through persisted ICD Client Info + * + * @return A valid iterator on success. Use CommonIterator accessor to retrieve ICDClientInfo + */ + virtual ICDClientInfoIterator * IterateICDClientInfo() = 0; + + /** + * Called during ICD device registration in commissioning, commissioner/controller + * provides raw key data, the shared key handle in clientInfo is updated based upon raw key data + * + * @param[inout] aICDClientInfo the ICD Client information to be updated with keyData and be saved + * @param[in] aKeyData raw key data provided by application + */ + virtual CHIP_ERROR SetKey(ICDClientInfo & clientInfo, const ByteSpan keyData) = 0; + + /** + * Store updated ICD ClientInfo to storage when ICD registration completes or check-in message + * comes. + * + * @param[in] aICDClientInfo the updated ICD Client Info. + */ + virtual CHIP_ERROR StoreEntry(const ICDClientInfo & clientInfo) = 0; + + /** + * Delete ICD Client persistent information associated with the specified scoped node Id. + * when ICD device is unpaired/removed, the corresponding entry in ICD storage is removed. + * @param aPeerNodeId scoped node with peer node id and fabric index + */ + virtual CHIP_ERROR DeleteEntry(const ScopedNodeId & peerNodeId) = 0; + + /** + * Remove all ICDClient persistent information associated with the specified + * fabric index. If no entries for the fabric index exist, this is a no-op + * and is considered successful. + * When the whole fabric is removed, all entries from persistent storage in current fabric index are removed. + * + * @param[in] fabricIndex the index of the fabric for which to remove ICDClient persistent information + */ + virtual CHIP_ERROR DeleteAllEntries(FabricIndex fabricIndex) = 0; + + /** + * Process received ICD Check-in message payload. The implementation needs to parse the payload, + * look for a key that allows successfully decrypting the payload, verify that the counter in the payload is valid, + * and populate the clientInfo with the stored information corresponding to the key. + * @param[in] payload received checkIn Message payload + * @param[out] clientInfo retrieved matched clientInfo from storage + */ + virtual CHIP_ERROR ProcessCheckInPayload(const ByteSpan & payload, ICDClientInfo & clientInfo) = 0; +}; +} // namespace app +} // namespace chip diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 78e3bdb229e49c..8bfb3fb6df816b 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -128,6 +128,7 @@ chip_test_suite_using_nltest("tests") { "TestAttributePersistenceProvider.cpp", "TestAttributeValueDecoder.cpp", "TestAttributeValueEncoder.cpp", + "TestBasicCommandPathRegistry.cpp", "TestBindingTable.cpp", "TestBuilderParser.cpp", "TestClusterInfo.cpp", @@ -161,6 +162,7 @@ chip_test_suite_using_nltest("tests") { } test_sources += [ "TestAclAttribute.cpp" ] + test_sources += [ "TestDefaultICDClientStorage.cpp" ] # # On NRF platforms, the allocation of a large number of pbufs in this test @@ -200,6 +202,7 @@ chip_test_suite_using_nltest("tests") { "${chip_root}/src/app", "${chip_root}/src/app/common:cluster-objects", "${chip_root}/src/app/icd:manager", + "${chip_root}/src/app/icd/client:manager", "${chip_root}/src/app/tests:helpers", "${chip_root}/src/app/util/mock:mock_ember", "${chip_root}/src/lib/core", diff --git a/src/app/tests/TestBasicCommandPathRegistry.cpp b/src/app/tests/TestBasicCommandPathRegistry.cpp new file mode 100644 index 00000000000000..61e859b95498f0 --- /dev/null +++ b/src/app/tests/TestBasicCommandPathRegistry.cpp @@ -0,0 +1,147 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +namespace chip { +namespace app { +namespace TestBasicCommandPathRegistry { +namespace { + +size_t constexpr kQuickTestSize = 10; + +} // namespace + +void TestAddingSameConcretePath(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BasicCommandPathRegistry basicCommandPathRegistry; + + ConcreteCommandPath concretePath(0, 0, 0); + Optional commandRef; + uint16_t commandRefValue = 0; + + size_t idx = 0; + for (idx = 0; idx < kQuickTestSize && err == CHIP_NO_ERROR; idx++) + { + commandRef.SetValue(commandRefValue); + commandRefValue++; + err = basicCommandPathRegistry.Add(concretePath, commandRef); + } + + NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_DUPLICATE_KEY_ID); + NL_TEST_ASSERT(apSuite, basicCommandPathRegistry.Count() == 1); +} + +void TestAddingSameCommandRef(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BasicCommandPathRegistry basicCommandPathRegistry; + + Optional commandRef; + commandRef.SetValue(0); + + uint16_t endpointValue = 0; + + size_t idx = 0; + for (idx = 0; idx < kQuickTestSize && err == CHIP_NO_ERROR; idx++) + { + ConcreteCommandPath concretePath(endpointValue, 0, 0); + endpointValue++; + err = basicCommandPathRegistry.Add(concretePath, commandRef); + } + + NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_DUPLICATE_KEY_ID); + NL_TEST_ASSERT(apSuite, basicCommandPathRegistry.Count() == 1); +} + +void TestAddingMaxNumberOfEntries(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BasicCommandPathRegistry basicCommandPathRegistry; + + Optional commandRef; + uint16_t commandRefAndEndpointValue = 0; + + size_t idx = 0; + for (idx = 0; idx < kQuickTestSize && err == CHIP_NO_ERROR; idx++) + { + ConcreteCommandPath concretePath(commandRefAndEndpointValue, 0, 0); + commandRef.SetValue(commandRefAndEndpointValue); + commandRefAndEndpointValue++; + err = basicCommandPathRegistry.Add(concretePath, commandRef); + } + + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(apSuite, basicCommandPathRegistry.Count() == kQuickTestSize); +} + +void TestAddingTooManyEntries(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BasicCommandPathRegistry basicCommandPathRegistry; + size_t maxPlusOne = kQuickTestSize + 1; + + Optional commandRef; + uint16_t commandRefAndEndpointValue = 0; + + size_t idx = 0; + for (idx = 0; idx < maxPlusOne && err == CHIP_NO_ERROR; idx++) + { + ConcreteCommandPath concretePath(commandRefAndEndpointValue, 0, 0); + commandRef.SetValue(commandRefAndEndpointValue); + commandRefAndEndpointValue++; + err = basicCommandPathRegistry.Add(concretePath, commandRef); + } + + NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_NO_MEMORY); + NL_TEST_ASSERT(apSuite, basicCommandPathRegistry.Count() == kQuickTestSize); +} + +} // namespace TestBasicCommandPathRegistry +} // namespace app +} // namespace chip + +namespace { +// clang-format off +const nlTest sTests[] = +{ + NL_TEST_DEF("TestAddingSameConcretePath", chip::app::TestBasicCommandPathRegistry::TestAddingSameConcretePath), + NL_TEST_DEF("TestAddingSameCommandRef", chip::app::TestBasicCommandPathRegistry::TestAddingSameCommandRef), + NL_TEST_DEF("TestAddingMaxNumberOfEntries", chip::app::TestBasicCommandPathRegistry::TestAddingMaxNumberOfEntries), + NL_TEST_DEF("TestAddingTooManyEntries", chip::app::TestBasicCommandPathRegistry::TestAddingTooManyEntries), + + NL_TEST_SENTINEL() +}; +// clang-format on + +} // namespace + +int TestBasicCommandPathRegistry() +{ + nlTestSuite theSuite = { "CommandPathRegistry", &sTests[0], nullptr, nullptr }; + + nlTestRunner(&theSuite, nullptr); + + return (nlTestRunnerStats(&theSuite)); +} + +CHIP_REGISTER_TEST_SUITE(TestBasicCommandPathRegistry) diff --git a/src/app/tests/TestCommandInteraction.cpp b/src/app/tests/TestCommandInteraction.cpp index 718f7d38e567c2..0e589243026a7a 100644 --- a/src/app/tests/TestCommandInteraction.cpp +++ b/src/app/tests/TestCommandInteraction.cpp @@ -68,7 +68,8 @@ void CheckForInvalidAction(nlTestSuite * apSuite, chip::Test::MessageCapturer & namespace chip { namespace { -bool isCommandDispatched = false; +bool isCommandDispatched = false; +size_t commandDispatchedCount = 0; bool sendResponse = true; bool asyncCommand = false; @@ -82,28 +83,30 @@ constexpr CommandId kTestCommandIdWithData = 4; constexpr CommandId kTestCommandIdNoData = 5; constexpr CommandId kTestCommandIdCommandSpecificResponse = 6; constexpr CommandId kTestNonExistCommandId = 0; + +const app::CommandHandler::TestOnlyMarker kThisIsForTestOnly; } // namespace namespace app { CommandHandler::Handle asyncCommandHandle; -InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aRequestCommandPath) { // Mock cluster catalog, only support commands on one cluster on one endpoint. using InteractionModel::Status; - if (aCommandPath.mEndpointId != kTestEndpointId) + if (aRequestCommandPath.mEndpointId != kTestEndpointId) { return Status::UnsupportedEndpoint; } - if (aCommandPath.mClusterId != kTestClusterId) + if (aRequestCommandPath.mClusterId != kTestClusterId) { return Status::UnsupportedCluster; } - if (aCommandPath.mCommandId == kTestNonExistCommandId) + if (aRequestCommandPath.mCommandId == kTestNonExistCommandId) { return Status::UnsupportedCommand; } @@ -111,17 +114,18 @@ InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & return Status::Success; } -void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader, +void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader, CommandHandler * apCommandObj) { ChipLogDetail(Controller, "Received Cluster Command: Endpoint=%x Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI, - aCommandPath.mEndpointId, ChipLogValueMEI(aCommandPath.mClusterId), ChipLogValueMEI(aCommandPath.mCommandId)); + aRequestCommandPath.mEndpointId, ChipLogValueMEI(aRequestCommandPath.mClusterId), + ChipLogValueMEI(aRequestCommandPath.mCommandId)); // Duplicate what our normal command-field-decode code does, in terms of // checking for a struct and then entering it before getting the fields. if (aReader.GetType() != TLV::kTLVType_Structure) { - apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidAction); + apCommandObj->AddStatus(aRequestCommandPath, Protocols::InteractionModel::Status::InvalidAction); return; } @@ -130,7 +134,7 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip NL_TEST_ASSERT(gSuite, err == CHIP_NO_ERROR); err = aReader.Next(); - if (aCommandPath.mCommandId == kTestCommandIdNoData) + if (aRequestCommandPath.mCommandId == kTestCommandIdNoData) { NL_TEST_ASSERT(gSuite, err == CHIP_ERROR_END_OF_TLV); } @@ -155,13 +159,15 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip if (sendResponse) { - if (aCommandPath.mCommandId == kTestCommandIdNoData || aCommandPath.mCommandId == kTestCommandIdWithData) + if (aRequestCommandPath.mCommandId == kTestCommandIdNoData || aRequestCommandPath.mCommandId == kTestCommandIdWithData) { - apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::Success); + apCommandObj->AddStatus(aRequestCommandPath, Protocols::InteractionModel::Status::Success); } else { - apCommandObj->PrepareCommand(aCommandPath); + const CommandHandler::InvokeResponseParameters prepareParams(aRequestCommandPath); + const ConcreteCommandPath responseCommandPath = aRequestCommandPath; + apCommandObj->PrepareInvokeResponseCommand(responseCommandPath, prepareParams); chip::TLV::TLVWriter * writer = apCommandObj->GetCommandDataIBTLVWriter(); writer->PutBoolean(chip::TLV::ContextTag(1), true); apCommandObj->FinishCommand(); @@ -169,6 +175,7 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip } chip::isCommandDispatched = true; + commandDispatchedCount++; } class MockCommandSenderCallback : public CommandSender::Callback @@ -218,6 +225,8 @@ class MockCommandHandlerCallback : public CommandHandler::Callback return ServerClusterCommandExists(aCommandPath); } + void ResetCounter() { onFinalCalledTimes = 0; } + int onFinalCalledTimes = 0; } mockCommandHandlerDelegate; @@ -244,7 +253,10 @@ class TestCommandInteraction static void TestCommandHandlerWithSendEmptyResponse(nlTestSuite * apSuite, void * apContext); static void TestCommandHandlerWithProcessReceivedEmptyDataMsg(nlTestSuite * apSuite, void * apContext); - static void TestCommandHandlerRejectMultipleCommands(nlTestSuite * apSuite, void * apContext); + static void TestCommandHandlerRejectMultipleIdenticalCommands(nlTestSuite * apSuite, void * apContext); + static void TestCommandHandlerRejectsMultipleCommandsWithIdenticalCommandRef(nlTestSuite * apSuite, void * apContext); + static void TestCommandHandlerRejectMultipleCommandsWhenHandlerOnlySupportsOne(nlTestSuite * apSuite, void * apContext); + static void TestCommandHandlerAcceptMultipleCommands(nlTestSuite * apSuite, void * apContext); #if CONFIG_BUILD_FOR_HOST_UNIT_TEST static void TestCommandHandlerReleaseWithExchangeClosed(nlTestSuite * apSuite, void * apContext); @@ -263,6 +275,24 @@ class TestCommandInteraction } private: + /** + * With the introduction of batch invoke commands, CommandHandler keeps track of incoming + * ConcreteCommandPath and the associated CommandRef. Normally this is populated as a part + * of OnMessageReceived from the incoming request. For some unit tests were we want to just + * test some of the processing messages we need to inject commands into the table of + * ConcreteCommandPath/CommandRef pairs. + */ + class CommandHandlerWithOutstandingCommand : public app::CommandHandler + { + public: + CommandHandlerWithOutstandingCommand(CommandHandler::Callback * apCallback, const ConcreteCommandPath & aRequestCommandPath, + const Optional & aRef) : + CommandHandler(apCallback) + { + GetCommandPathRegistry().Add(aRequestCommandPath, aRef); + } + }; + // Generate an invoke request. If aCommandId is kTestCommandIdWithData, a // payload will be included. Otherwise no payload will be included. static void GenerateInvokeRequest(nlTestSuite * apSuite, void * apContext, System::PacketBufferHandle & aPayload, @@ -451,18 +481,19 @@ void TestCommandInteraction::AddInvokeResponseData(nlTestSuite * apSuite, void * { CHIP_ERROR err = CHIP_NO_ERROR; + constexpr EndpointId kTestEndpointId = 1; + constexpr ClusterId kTestClusterId = 3; + constexpr CommandId kTestCommandIdWithData = 4; + ConcreteCommandPath requestCommandPath = { kTestEndpointId, kTestClusterId, kTestCommandIdWithData }; if (aNeedStatusCode) { - chip::app::ConcreteCommandPath commandPath(1, // Endpoint - 3, // ClusterId - 4 // CommandId - ); - apCommandHandler->AddStatus(commandPath, Protocols::InteractionModel::Status::Success); + apCommandHandler->AddStatus(requestCommandPath, Protocols::InteractionModel::Status::Success); } else { - ConcreteCommandPath path = { kTestEndpointId, kTestClusterId, aCommandId }; - err = apCommandHandler->PrepareCommand(path); + const CommandHandler::InvokeResponseParameters prepareParams(requestCommandPath); + ConcreteCommandPath responseCommandPath = { kTestEndpointId, kTestClusterId, aCommandId }; + err = apCommandHandler->PrepareInvokeResponseCommand(responseCommandPath, prepareParams); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); chip::TLV::TLVWriter * writer = apCommandHandler->GetCommandDataIBTLVWriter(); @@ -489,13 +520,16 @@ void TestCommandInteraction::TestCommandSenderWithWrongState(nlTestSuite * apSui void TestCommandInteraction::TestCommandHandlerWithWrongState(nlTestSuite * apSuite, void * apContext) { - TestContext & ctx = *static_cast(apContext); - CHIP_ERROR err = CHIP_NO_ERROR; - ConcreteCommandPath path = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData }; + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + ConcreteCommandPath requestCommandPath = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData }; + ConcreteCommandPath responseCommandPath = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData }; - app::CommandHandler commandHandler(&mockCommandHandlerDelegate); + CommandHandlerWithOutstandingCommand commandHandler(&mockCommandHandlerDelegate, requestCommandPath, + /* aRef = */ NullOptional); - err = commandHandler.PrepareCommand(path); + const CommandHandler::InvokeResponseParameters prepareParams(requestCommandPath); + err = commandHandler.PrepareInvokeResponseCommand(responseCommandPath, prepareParams); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); TestExchangeDelegate delegate; @@ -538,18 +572,21 @@ void TestCommandInteraction::TestCommandSenderWithSendCommand(nlTestSuite * apSu void TestCommandInteraction::TestCommandHandlerWithSendEmptyCommand(nlTestSuite * apSuite, void * apContext) { - TestContext & ctx = *static_cast(apContext); - CHIP_ERROR err = CHIP_NO_ERROR; - ConcreteCommandPath path = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData }; + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + ConcreteCommandPath requestCommandPath = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData }; + ConcreteCommandPath responseCommandPath = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData }; - app::CommandHandler commandHandler(&mockCommandHandlerDelegate); + CommandHandlerWithOutstandingCommand commandHandler(&mockCommandHandlerDelegate, requestCommandPath, + /* aRef = */ NullOptional); System::PacketBufferHandle commandDatabuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); TestExchangeDelegate delegate; auto exchange = ctx.NewExchangeToAlice(&delegate, false); commandHandler.mExchangeCtx.Grab(exchange); - err = commandHandler.PrepareCommand(path); + const CommandHandler::InvokeResponseParameters prepareParams(requestCommandPath); + err = commandHandler.PrepareInvokeResponseCommand(responseCommandPath, prepareParams); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); err = commandHandler.FinishCommand(); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); @@ -577,8 +614,10 @@ void TestCommandInteraction::ValidateCommandHandlerWithSendCommand(nlTestSuite * { TestContext & ctx = *static_cast(apContext); CHIP_ERROR err = CHIP_NO_ERROR; - app::CommandHandler commandHandler(&mockCommandHandlerDelegate); System::PacketBufferHandle commandPacket; + chip::app::ConcreteCommandPath requestCommandPath(kTestEndpointId, kTestClusterId, kTestCommandIdWithData); + CommandHandlerWithOutstandingCommand commandHandler(&mockCommandHandlerDelegate, requestCommandPath, + /* aRef = */ NullOptional); TestExchangeDelegate delegate; auto exchange = ctx.NewExchangeToAlice(&delegate, false); @@ -643,18 +682,18 @@ struct BadFields void TestCommandInteraction::TestCommandHandlerCommandDataEncoding(nlTestSuite * apSuite, void * apContext) { - TestContext & ctx = *static_cast(apContext); - CHIP_ERROR err = CHIP_NO_ERROR; - app::CommandHandler commandHandler(nullptr); + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + auto path = MakeTestCommandPath(); + auto requestCommandPath = ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId); + CommandHandlerWithOutstandingCommand commandHandler(nullptr, requestCommandPath, /* aRef = */ NullOptional); System::PacketBufferHandle commandPacket; TestExchangeDelegate delegate; auto exchange = ctx.NewExchangeToAlice(&delegate, false); commandHandler.mExchangeCtx.Grab(exchange); - auto path = MakeTestCommandPath(); - - commandHandler.AddResponse(ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId), Fields()); + commandHandler.AddResponse(requestCommandPath, Fields()); err = commandHandler.Finalize(commandPacket); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); @@ -678,18 +717,18 @@ void TestCommandInteraction::TestCommandHandlerCommandDataEncoding(nlTestSuite * void TestCommandInteraction::TestCommandHandlerCommandEncodeFailure(nlTestSuite * apSuite, void * apContext) { - TestContext & ctx = *static_cast(apContext); - CHIP_ERROR err = CHIP_NO_ERROR; - app::CommandHandler commandHandler(nullptr); + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + auto path = MakeTestCommandPath(); + auto requestCommandPath = ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId); + CommandHandlerWithOutstandingCommand commandHandler(nullptr, requestCommandPath, NullOptional); System::PacketBufferHandle commandPacket; TestExchangeDelegate delegate; auto exchange = ctx.NewExchangeToAlice(&delegate, false); commandHandler.mExchangeCtx.Grab(exchange); - auto path = MakeTestCommandPath(); - - commandHandler.AddResponse(ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId), BadFields()); + commandHandler.AddResponse(requestCommandPath, BadFields()); err = commandHandler.Finalize(commandPacket); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); @@ -1067,9 +1106,15 @@ void TestCommandInteraction::TestCommandHandlerInvalidMessageAsync(nlTestSuite * err = commandSender.SendCommandRequest(ctx.GetSessionBobToAlice()); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + // Warning! This test is not testing what the testname is suggesting. Because the invoke request is malformed, + // DispatchSingleClusterCommand is never called and asyncCommandHandle is never set. Possible fix to this test + // might be incoming when CommandSender is capable of sending multiple invoke command requests. + // Decrease CommandHandler refcount and send response asyncCommandHandle = nullptr; + // Prevent breaking other tests. + asyncCommand = false; ctx.DrainAndServiceIO(); NL_TEST_ASSERT(apSuite, @@ -1082,21 +1127,20 @@ void TestCommandInteraction::TestCommandHandlerInvalidMessageAsync(nlTestSuite * void TestCommandInteraction::TestCommandHandlerCommandEncodeExternalFailure(nlTestSuite * apSuite, void * apContext) { - TestContext & ctx = *static_cast(apContext); - CHIP_ERROR err = CHIP_NO_ERROR; - app::CommandHandler commandHandler(nullptr); + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + auto path = MakeTestCommandPath(); + auto requestCommandPath = ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId); + CommandHandlerWithOutstandingCommand commandHandler(nullptr, requestCommandPath, NullOptional); System::PacketBufferHandle commandPacket; TestExchangeDelegate delegate; auto exchange = ctx.NewExchangeToAlice(&delegate, false); commandHandler.mExchangeCtx.Grab(exchange); - auto path = MakeTestCommandPath(); - - err = commandHandler.AddResponseData(ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId), BadFields()); + err = commandHandler.AddResponseData(requestCommandPath, BadFields()); NL_TEST_ASSERT(apSuite, err != CHIP_NO_ERROR); - commandHandler.AddStatus(ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId), - Protocols::InteractionModel::Status::Failure); + commandHandler.AddStatus(requestCommandPath, Protocols::InteractionModel::Status::Failure); err = commandHandler.Finalize(commandPacket); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); @@ -1331,7 +1375,7 @@ void TestCommandInteraction::TestCommandSenderAbruptDestruction(nlTestSuite * ap NL_TEST_ASSERT(apSuite, GetNumActiveHandlerObjects() == 0); } -void TestCommandInteraction::TestCommandHandlerRejectMultipleCommands(nlTestSuite * apSuite, void * apContext) +void TestCommandInteraction::TestCommandHandlerRejectMultipleIdenticalCommands(nlTestSuite * apSuite, void * apContext) { TestContext & ctx = *static_cast(apContext); CHIP_ERROR err = CHIP_NO_ERROR; @@ -1387,6 +1431,236 @@ void TestCommandInteraction::TestCommandHandlerRejectMultipleCommands(nlTestSuit NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); } +void TestCommandInteraction::TestCommandHandlerRejectsMultipleCommandsWithIdenticalCommandRef(nlTestSuite * apSuite, + void * apContext) +{ + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + + isCommandDispatched = false; + mockCommandSenderDelegate.ResetCounter(); + + // Using commandSender to help build afterward we take the buffer to feed into standalone CommandHandler + app::CommandSender commandSender(&mockCommandSenderDelegate, &ctx.GetExchangeManager()); + + size_t numberOfCommandsToSend = 2; + { + CommandPathParams requestCommandPaths[] = { + MakeTestCommandPath(kTestCommandIdWithData), + MakeTestCommandPath(kTestCommandIdCommandSpecificResponse), + }; + + commandSender.AllocateBuffer(); + + // CommandSender does not support sending multiple commands with public API, so we craft a message manaully. + for (size_t i = 0; i < numberOfCommandsToSend; i++) + { + InvokeRequests::Builder & invokeRequests = commandSender.mInvokeRequestBuilder.GetInvokeRequests(); + CommandDataIB::Builder & invokeRequest = invokeRequests.CreateCommandData(); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequests.GetError()); + CommandPathIB::Builder & path = invokeRequest.CreatePath(); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.GetError()); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == path.Encode(requestCommandPaths[i])); + NL_TEST_ASSERT(apSuite, + CHIP_NO_ERROR == + invokeRequest.GetWriter()->StartContainer(TLV::ContextTag(CommandDataIB::Tag::kFields), + TLV::kTLVType_Structure, + commandSender.mDataElementContainerType)); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.GetWriter()->PutBoolean(chip::TLV::ContextTag(1), true)); + NL_TEST_ASSERT(apSuite, + CHIP_NO_ERROR == invokeRequest.GetWriter()->EndContainer(commandSender.mDataElementContainerType)); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.Ref(1)); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.EndOfCommandDataIB()); + } + + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == commandSender.mInvokeRequestBuilder.GetInvokeRequests().EndOfInvokeRequests()); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == commandSender.mInvokeRequestBuilder.EndOfInvokeRequestMessage()); + + commandSender.MoveToState(app::CommandSender::State::AddedCommand); + } + + CommandHandler commandHandler(&mockCommandHandlerDelegate); + TestExchangeDelegate delegate; + auto exchange = ctx.NewExchangeToAlice(&delegate, false); + commandHandler.mExchangeCtx.Grab(exchange); + + // Hackery to steal the InvokeRequest buffer from commandSender. + System::PacketBufferHandle commandDatabuf; + err = commandSender.Finalize(commandDatabuf); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + mockCommandHandlerDelegate.ResetCounter(); + commandDispatchedCount = 0; + + InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); + NL_TEST_ASSERT(apSuite, status == InteractionModel::Status::InvalidAction); + + NL_TEST_ASSERT(apSuite, commandDispatchedCount == 0); + + // + // Ordinarily, the ExchangeContext will close itself on a responder exchange when unwinding back from an + // OnMessageReceived callback and not having sent a subsequent message (as is the case when calling ProcessInvokeRequest + // above, which doesn't actually send back a response in these cases). Since that isn't the case in this artificial + // setup here (where we created a responder exchange that's not responding to anything), we need to explicitly close it + // out. This is not expected in normal application logic. + // + exchange->Close(); +} + +void TestCommandInteraction::TestCommandHandlerRejectMultipleCommandsWhenHandlerOnlySupportsOne(nlTestSuite * apSuite, + void * apContext) +{ + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + + isCommandDispatched = false; + mockCommandSenderDelegate.ResetCounter(); + + // Using commandSender to help build afterward we take the buffer to feed into standalone CommandHandler + app::CommandSender commandSender(&mockCommandSenderDelegate, &ctx.GetExchangeManager()); + + size_t numberOfCommandsToSend = 2; + { + CommandPathParams requestCommandPaths[] = { + MakeTestCommandPath(kTestCommandIdWithData), + MakeTestCommandPath(kTestCommandIdCommandSpecificResponse), + }; + + commandSender.AllocateBuffer(); + + // CommandSender does not support sending multiple commands with public API, so we craft a message manaully. + for (size_t i = 0; i < numberOfCommandsToSend; i++) + { + InvokeRequests::Builder & invokeRequests = commandSender.mInvokeRequestBuilder.GetInvokeRequests(); + CommandDataIB::Builder & invokeRequest = invokeRequests.CreateCommandData(); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequests.GetError()); + CommandPathIB::Builder & path = invokeRequest.CreatePath(); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.GetError()); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == path.Encode(requestCommandPaths[i])); + NL_TEST_ASSERT(apSuite, + CHIP_NO_ERROR == + invokeRequest.GetWriter()->StartContainer(TLV::ContextTag(CommandDataIB::Tag::kFields), + TLV::kTLVType_Structure, + commandSender.mDataElementContainerType)); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.GetWriter()->PutBoolean(chip::TLV::ContextTag(1), true)); + NL_TEST_ASSERT(apSuite, + CHIP_NO_ERROR == invokeRequest.GetWriter()->EndContainer(commandSender.mDataElementContainerType)); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.Ref(static_cast(i))); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.EndOfCommandDataIB()); + } + + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == commandSender.mInvokeRequestBuilder.GetInvokeRequests().EndOfInvokeRequests()); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == commandSender.mInvokeRequestBuilder.EndOfInvokeRequestMessage()); + + commandSender.MoveToState(app::CommandSender::State::AddedCommand); + } + + BasicCommandPathRegistry<4> mBasicCommandPathRegistry; + CommandHandler commandHandler(kThisIsForTestOnly, &mockCommandHandlerDelegate, &mBasicCommandPathRegistry); + TestExchangeDelegate delegate; + auto exchange = ctx.NewExchangeToAlice(&delegate, false); + commandHandler.mExchangeCtx.Grab(exchange); + + // Hackery to steal the InvokeRequest buffer from commandSender. + System::PacketBufferHandle commandDatabuf; + err = commandSender.Finalize(commandDatabuf); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + mockCommandHandlerDelegate.ResetCounter(); + sendResponse = true; + commandDispatchedCount = 0; + + InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); + NL_TEST_ASSERT(apSuite, status == InteractionModel::Status::Success); + + NL_TEST_ASSERT(apSuite, commandDispatchedCount == 2); + + // + // Ordinarily, the ExchangeContext will close itself on a responder exchange when unwinding back from an + // OnMessageReceived callback and not having sent a subsequent message (as is the case when calling ProcessInvokeRequest + // above, which doesn't actually send back a response in these cases). Since that isn't the case in this artificial + // setup here (where we created a responder exchange that's not responding to anything), we need to explicitly close it + // out. This is not expected in normal application logic. + // + exchange->Close(); +} + +void TestCommandInteraction::TestCommandHandlerAcceptMultipleCommands(nlTestSuite * apSuite, void * apContext) +{ + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + + isCommandDispatched = false; + mockCommandSenderDelegate.ResetCounter(); + + // Using commandSender to help build afterward we take the buffer to feed into standalone CommandHandler + app::CommandSender commandSender(&mockCommandSenderDelegate, &ctx.GetExchangeManager()); + + size_t numberOfCommandsToSend = 2; + { + CommandPathParams requestCommandPaths[] = { + MakeTestCommandPath(kTestCommandIdWithData), + MakeTestCommandPath(kTestCommandIdCommandSpecificResponse), + }; + + commandSender.AllocateBuffer(); + + // CommandSender does not support sending multiple commands with public API, so we craft a message manaully. + for (size_t i = 0; i < numberOfCommandsToSend; i++) + { + InvokeRequests::Builder & invokeRequests = commandSender.mInvokeRequestBuilder.GetInvokeRequests(); + CommandDataIB::Builder & invokeRequest = invokeRequests.CreateCommandData(); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequests.GetError()); + CommandPathIB::Builder & path = invokeRequest.CreatePath(); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.GetError()); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == path.Encode(requestCommandPaths[i])); + NL_TEST_ASSERT(apSuite, + CHIP_NO_ERROR == + invokeRequest.GetWriter()->StartContainer(TLV::ContextTag(CommandDataIB::Tag::kFields), + TLV::kTLVType_Structure, + commandSender.mDataElementContainerType)); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.GetWriter()->PutBoolean(chip::TLV::ContextTag(1), true)); + NL_TEST_ASSERT(apSuite, + CHIP_NO_ERROR == invokeRequest.GetWriter()->EndContainer(commandSender.mDataElementContainerType)); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.Ref(static_cast(i))); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == invokeRequest.EndOfCommandDataIB()); + } + + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == commandSender.mInvokeRequestBuilder.GetInvokeRequests().EndOfInvokeRequests()); + NL_TEST_ASSERT(apSuite, CHIP_NO_ERROR == commandSender.mInvokeRequestBuilder.EndOfInvokeRequestMessage()); + + commandSender.MoveToState(app::CommandSender::State::AddedCommand); + } + + BasicCommandPathRegistry<4> mBasicCommandPathRegistry; + CommandHandler commandHandler(kThisIsForTestOnly, &mockCommandHandlerDelegate, &mBasicCommandPathRegistry); + TestExchangeDelegate delegate; + auto exchange = ctx.NewExchangeToAlice(&delegate, false); + commandHandler.mExchangeCtx.Grab(exchange); + + // Hackery to steal the InvokeRequest buffer from commandSender. + System::PacketBufferHandle commandDatabuf; + err = commandSender.Finalize(commandDatabuf); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + mockCommandHandlerDelegate.ResetCounter(); + commandDispatchedCount = 0; + + InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); + NL_TEST_ASSERT(apSuite, status == InteractionModel::Status::Success); + + NL_TEST_ASSERT(apSuite, commandDispatchedCount == 2); + + // + // Ordinarily, the ExchangeContext will close itself on a responder exchange when unwinding back from an + // OnMessageReceived callback and not having sent a subsequent message (as is the case when calling ProcessInvokeRequest + // above, which doesn't actually send back a response in these cases). Since that isn't the case in this artificial + // setup here (where we created a responder exchange that's not responding to anything), we need to explicitly close it + // out. This is not expected in normal application logic. + // + exchange->Close(); +} + #if CONFIG_BUILD_FOR_HOST_UNIT_TEST // // This test needs a special unit-test only API being exposed in ExchangeContext to be able to correctly simulate @@ -1443,7 +1717,11 @@ const nlTest sTests[] = NL_TEST_DEF("TestCommandHandlerWithSendSimpleStatusCode", chip::app::TestCommandInteraction::TestCommandHandlerWithSendSimpleStatusCode), NL_TEST_DEF("TestCommandHandlerWithProcessReceivedNotExistCommand", chip::app::TestCommandInteraction::TestCommandHandlerWithProcessReceivedNotExistCommand), NL_TEST_DEF("TestCommandHandlerWithProcessReceivedEmptyDataMsg", chip::app::TestCommandInteraction::TestCommandHandlerWithProcessReceivedEmptyDataMsg), - NL_TEST_DEF("TestCommandHandlerRejectMultipleCommands", chip::app::TestCommandInteraction::TestCommandHandlerRejectMultipleCommands), + NL_TEST_DEF("TestCommandHandlerRejectMultipleIdenticalCommands", chip::app::TestCommandInteraction::TestCommandHandlerRejectMultipleIdenticalCommands), + NL_TEST_DEF("TestCommandHandlerRejectsMultipleCommandsWithIdenticalCommandRef", chip::app::TestCommandInteraction::TestCommandHandlerRejectsMultipleCommandsWithIdenticalCommandRef), + NL_TEST_DEF("TestCommandHandlerRejectMultipleCommandsWhenHandlerOnlySupportsOne", chip::app::TestCommandInteraction::TestCommandHandlerRejectMultipleCommandsWhenHandlerOnlySupportsOne), + NL_TEST_DEF("TestCommandHandlerAcceptMultipleCommands", chip::app::TestCommandInteraction::TestCommandHandlerAcceptMultipleCommands), + #if CONFIG_BUILD_FOR_HOST_UNIT_TEST NL_TEST_DEF("TestCommandHandlerReleaseWithExchangeClosed", chip::app::TestCommandInteraction::TestCommandHandlerReleaseWithExchangeClosed), diff --git a/src/app/tests/TestDefaultICDClientStorage.cpp b/src/app/tests/TestDefaultICDClientStorage.cpp new file mode 100644 index 00000000000000..399f7689aee2ef --- /dev/null +++ b/src/app/tests/TestDefaultICDClientStorage.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include + +using namespace chip; +using namespace app; +using namespace System; +using TestSessionKeystoreImpl = Crypto::DefaultSessionKeystore; + +constexpr uint8_t kKeyBuffer1[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f +}; + +constexpr uint8_t kKeyBuffer2[] = { + 0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x14, 0x31, 0x21, 0x11, 0x01 +}; +constexpr uint8_t kKeyBuffer3[] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f +}; + +struct TestClientInfo : public ICDClientInfo +{ + bool operator==(const ICDClientInfo & that) const + { + if ((peer_node != that.peer_node)) + { + return false; + } + return true; + } +}; + +void TestClientInfoCount(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + FabricIndex fabricId = 1; + NodeId nodeId1 = 6666; + NodeId nodeId2 = 6667; + + TestPersistentStorageDelegate clientInfoStorage; + TestSessionKeystoreImpl keystore; + + { + DefaultICDClientStorage manager; + err = manager.Init(&clientInfoStorage, &keystore); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.UpdateFabricList(fabricId); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + // Write some ClientInfos and see the counts are correct + ICDClientInfo clientInfo1; + clientInfo1.peer_node = ScopedNodeId(nodeId1, fabricId); + ICDClientInfo clientInfo2; + clientInfo2.peer_node = ScopedNodeId(nodeId2, fabricId); + ICDClientInfo clientInfo3; + clientInfo3.peer_node = ScopedNodeId(nodeId1, fabricId); + err = manager.SetKey(clientInfo1, ByteSpan(kKeyBuffer1)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.StoreEntry(clientInfo1); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + err = manager.SetKey(clientInfo2, ByteSpan(kKeyBuffer2)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.StoreEntry(clientInfo2); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + err = manager.SetKey(clientInfo3, ByteSpan(kKeyBuffer3)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.StoreEntry(clientInfo3); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + // Make sure iterator counts correctly + auto * iterator = manager.IterateICDClientInfo(); + // same nodeId for clientInfo2 and clientInfo3, so the new one replace old one + NL_TEST_ASSERT(apSuite, iterator->Count() == 2); + + ICDClientInfo clientInfo; + NL_TEST_ASSERT(apSuite, iterator->Next(clientInfo)); + NL_TEST_ASSERT(apSuite, clientInfo.peer_node.GetNodeId() == nodeId2); + NL_TEST_ASSERT(apSuite, iterator->Next(clientInfo)); + NL_TEST_ASSERT(apSuite, clientInfo.peer_node.GetNodeId() == nodeId1); + + iterator->Release(); + + // Delete all and verify iterator counts 0 + err = manager.DeleteAllEntries(fabricId); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + iterator = manager.IterateICDClientInfo(); + NL_TEST_ASSERT(apSuite, iterator->Count() == 0); + + // Verify ClientInfos manually count correctly + size_t count = 0; + while (iterator->Next(clientInfo)) + { + count++; + } + iterator->Release(); + NL_TEST_ASSERT(apSuite, count == 0); + } + + { + DefaultICDClientStorage manager; + err = manager.Init(&clientInfoStorage, &keystore); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.UpdateFabricList(fabricId); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + } +} + +void TestClientInfoCountMultipleFabric(nlTestSuite * apSuite, void * apContext) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + FabricIndex fabricId1 = 1; + FabricIndex fabricId2 = 2; + NodeId nodeId1 = 6666; + NodeId nodeId2 = 6667; + NodeId nodeId3 = 6668; + DefaultICDClientStorage manager; + TestPersistentStorageDelegate clientInfoStorage; + TestSessionKeystoreImpl keystore; + err = manager.Init(&clientInfoStorage, &keystore); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.UpdateFabricList(fabricId1); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.UpdateFabricList(fabricId2); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + // Write some ClientInfos and see the counts are correct + ICDClientInfo clientInfo1; + clientInfo1.peer_node = ScopedNodeId(nodeId1, fabricId1); + ICDClientInfo clientInfo2; + clientInfo2.peer_node = ScopedNodeId(nodeId2, fabricId1); + ICDClientInfo clientInfo3; + clientInfo3.peer_node = ScopedNodeId(nodeId3, fabricId2); + + err = manager.SetKey(clientInfo1, ByteSpan(kKeyBuffer1)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.StoreEntry(clientInfo1); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + err = manager.SetKey(clientInfo2, ByteSpan(kKeyBuffer2)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.StoreEntry(clientInfo2); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + + err = manager.SetKey(clientInfo3, ByteSpan(kKeyBuffer3)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = manager.StoreEntry(clientInfo3); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + // Make sure iterator counts correctly + auto * iterator = manager.IterateICDClientInfo(); + NL_TEST_ASSERT(apSuite, iterator->Count() == 3); + iterator->Release(); + + // Delete all and verify iterator counts 0 + err = manager.DeleteEntry(ScopedNodeId(nodeId1, fabricId1)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + iterator = manager.IterateICDClientInfo(); + NL_TEST_ASSERT(apSuite, iterator->Count() == 2); + + err = manager.DeleteEntry(ScopedNodeId(nodeId2, fabricId1)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(apSuite, iterator->Count() == 1); + + err = manager.DeleteEntry(ScopedNodeId(nodeId3, fabricId2)); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(apSuite, iterator->Count() == 0); + + // Verify ClientInfos manually count correctly + size_t count = 0; + ICDClientInfo clientInfo; + while (iterator->Next(clientInfo)) + { + count++; + } + iterator->Release(); + NL_TEST_ASSERT(apSuite, count == 0); +} + +/** + * Set up the test suite. + */ +int TestClientInfo_Setup(void * apContext) +{ + VerifyOrReturnError(CHIP_NO_ERROR == Platform::MemoryInit(), FAILURE); + + return SUCCESS; +} + +/** + * Tear down the test suite. + */ +int TestClientInfo_Teardown(void * apContext) +{ + Platform::MemoryShutdown(); + return SUCCESS; +} + +// Test Suite + +/** + * Test Suite that lists all the test functions. + */ +// clang-format off +static const nlTest sTests[] = +{ + NL_TEST_DEF("TestClientInfoCount", TestClientInfoCount), + NL_TEST_DEF("TestClientInfoCountMultipleFabric", TestClientInfoCountMultipleFabric), + NL_TEST_SENTINEL() +}; +// clang-format on + +// clang-format off +static nlTestSuite sSuite = +{ + "TestDefaultICDClientStorage", + &sTests[0], + &TestClientInfo_Setup, &TestClientInfo_Teardown +}; +// clang-format on + +/** + * Main + */ +int TestDefaultICDClientStorage() +{ + // Run test suit against one context + nlTestRunner(&sSuite, nullptr); + + return (nlTestRunnerStats(&sSuite)); +} + +CHIP_REGISTER_TEST_SUITE(TestDefaultICDClientStorage) diff --git a/src/app/tests/TestICDManager.cpp b/src/app/tests/TestICDManager.cpp index e3ca6eccbea768..03f3b7c2a76901 100644 --- a/src/app/tests/TestICDManager.cpp +++ b/src/app/tests/TestICDManager.cpp @@ -314,6 +314,15 @@ class TestICDManager // Check ICDManager is still in the LIT operating mode NL_TEST_ASSERT(aSuite, ICDConfigurationData::GetInstance().GetICDMode() == ICDConfigurationData::ICDMode::SIT); } + + static void TestICDCounter(nlTestSuite * aSuite, void * aContext) + { + TestContext * ctx = static_cast(aContext); + uint32_t counter = ICDConfigurationData::GetInstance().GetICDCounter(); + ctx->mICDManager.IncrementCounter(); + uint32_t counter2 = ICDConfigurationData::GetInstance().GetICDCounter(); + NL_TEST_ASSERT(aSuite, (counter + 1) == counter2); + } }; } // namespace app @@ -329,6 +338,7 @@ static const nlTest sTests[] = NL_TEST_DEF("TestICDModeDurations", TestICDManager::TestICDModeDurations), NL_TEST_DEF("TestKeepActivemodeRequests", TestICDManager::TestKeepActivemodeRequests), NL_TEST_DEF("TestICDMRegisterUnregisterEvents", TestICDManager::TestICDMRegisterUnregisterEvents), + NL_TEST_DEF("TestICDCounter", TestICDManager::TestICDCounter), NL_TEST_SENTINEL() }; // clang-format on diff --git a/src/app/tests/TestMessageDef.cpp b/src/app/tests/TestMessageDef.cpp index 16f7db862ff692..c78545926f59b2 100644 --- a/src/app/tests/TestMessageDef.cpp +++ b/src/app/tests/TestMessageDef.cpp @@ -954,6 +954,9 @@ void BuildInvokeResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVWriter & aW BuildInvokeResponses(apSuite, invokeResponsesBuilder); + invokeResponseMessageBuilder.MoreChunkedMessages(true); + NL_TEST_ASSERT(apSuite, invokeResponseMessageBuilder.GetError() == CHIP_NO_ERROR); + invokeResponseMessageBuilder.EndOfInvokeResponseMessage(); NL_TEST_ASSERT(apSuite, invokeResponseMessageBuilder.GetError() == CHIP_NO_ERROR); } @@ -966,8 +969,15 @@ void ParseInvokeResponseMessage(nlTestSuite * apSuite, chip::TLV::TLVReader & aR NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); bool suppressResponse = false; - invokeResponseMessageParser.GetSuppressResponse(&suppressResponse); + err = invokeResponseMessageParser.GetSuppressResponse(&suppressResponse); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); NL_TEST_ASSERT(apSuite, suppressResponse == true); + + bool moreChunkedMessages = true; + err = invokeResponseMessageParser.GetMoreChunkedMessages(&suppressResponse); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + NL_TEST_ASSERT(apSuite, moreChunkedMessages == true); + #if CHIP_CONFIG_IM_PRETTY_PRINT invokeResponseMessageParser.PrettyPrint(); #endif diff --git a/src/app/tests/integration/chip_im_responder.cpp b/src/app/tests/integration/chip_im_responder.cpp index e8fa74d9baa26c..17d47a06ea803d 100644 --- a/src/app/tests/integration/chip_im_responder.cpp +++ b/src/app/tests/integration/chip_im_responder.cpp @@ -73,12 +73,12 @@ Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCom return Status::Success; } -void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader, +void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader, CommandHandler * apCommandObj) { static bool statusCodeFlipper = false; - if (ServerClusterCommandExists(aCommandPath) != Protocols::InteractionModel::Status::Success) + if (ServerClusterCommandExists(aRequestCommandPath) != Protocols::InteractionModel::Status::Success) { return; } @@ -106,7 +106,8 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip chip::TLV::TLVWriter * writer; - ReturnOnFailure(apCommandObj->PrepareCommand(path)); + const CommandHandler::InvokeResponseParameters prepareParams(aRequestCommandPath); + ReturnOnFailure(apCommandObj->PrepareInvokeResponseCommand(path, prepareParams)); writer = apCommandObj->GetCommandDataIBTLVWriter(); ReturnOnFailure(writer->Put(chip::TLV::ContextTag(kTestFieldId1), kTestFieldValue1)); diff --git a/src/app/tests/suites/TV_AccountLoginCluster.yaml b/src/app/tests/suites/TV_AccountLoginCluster.yaml index cc80a57f18636d..8f92502da47218 100644 --- a/src/app/tests/suites/TV_AccountLoginCluster.yaml +++ b/src/app/tests/suites/TV_AccountLoginCluster.yaml @@ -48,7 +48,13 @@ tests: value: "asdf" - name: "SetupPIN" value: "tempPin123" + - name: "Node" + value: nodeId - label: "Logout Command" command: "Logout" timedInteractionTimeoutMs: 10000 + arguments: + values: + - name: "Node" + value: nodeId diff --git a/src/app/tests/suites/TV_ContentLauncherCluster.yaml b/src/app/tests/suites/TV_ContentLauncherCluster.yaml index 3ec333c6f2e61f..33634a1b540c82 100644 --- a/src/app/tests/suites/TV_ContentLauncherCluster.yaml +++ b/src/app/tests/suites/TV_ContentLauncherCluster.yaml @@ -61,6 +61,27 @@ tests: }, ], } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } + - name: "UseCurrentContext" + value: true response: values: - name: "Data" diff --git a/src/app/tests/suites/TestIcdManagementCluster.yaml b/src/app/tests/suites/TestIcdManagementCluster.yaml index e07b707e190858..d23c06e96ed208 100644 --- a/src/app/tests/suites/TestIcdManagementCluster.yaml +++ b/src/app/tests/suites/TestIcdManagementCluster.yaml @@ -56,7 +56,10 @@ tests: command: "readAttribute" attribute: "ICDCounter" response: - value: 0 + constraints: + type: int32u + minValue: 0x0 + maxValue: 0xFFFFFFFF - label: "Read ClientsSupportedPerFabric" command: "readAttribute" @@ -136,7 +139,10 @@ tests: response: values: - name: "ICDCounter" - value: 0 + constraints: + type: int32u + minValue: 0x0 + maxValue: 0xFFFFFFFF - label: "Register 2.1" command: "RegisterClient" @@ -152,7 +158,10 @@ tests: response: values: - name: "ICDCounter" - value: 0 + constraints: + type: int32u + minValue: 0x0 + maxValue: 0xFFFFFFFF - label: "Register 3.1" command: "RegisterClient" @@ -190,7 +199,10 @@ tests: response: values: - name: "ICDCounter" - value: 0 + constraints: + type: int32u + minValue: 0x0 + maxValue: 0xFFFFFFFF - label: "Read RegisteredClients" command: "readAttribute" @@ -218,7 +230,10 @@ tests: response: values: - name: "ICDCounter" - value: 0 + constraints: + type: int32u + minValue: 0x0 + maxValue: 0xFFFFFFFF - label: "Read RegisteredClients" command: "readAttribute" diff --git a/src/app/tests/suites/certification/Test_TC_ALOGIN_12_1.yaml b/src/app/tests/suites/certification/Test_TC_ALOGIN_12_1.yaml index db1826a4949557..2c7be1eebcf05e 100644 --- a/src/app/tests/suites/certification/Test_TC_ALOGIN_12_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_ALOGIN_12_1.yaml @@ -75,7 +75,7 @@ tests: - name: "SetupPIN" saveAs: setupPIN constraints: - minLength: 11 + minLength: 8 - label: "Step 2: TH sends a Login command to the DUT with test values provided @@ -89,6 +89,8 @@ tests: value: TempAccountIdentifier - name: "SetupPIN" value: setupPIN + - name: "Node" + value: nodeId - label: "Step 3: TH sends a Logout command to the DUT with test values @@ -96,3 +98,7 @@ tests: PICS: ALOGIN.S.C03.Rsp && PICS_SKIP_SAMPLE_APP command: "Logout" timedInteractionTimeoutMs: 10000 + arguments: + values: + - name: "Node" + value: nodeId diff --git a/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_10_3.yaml b/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_10_3.yaml index 85336aefe3b4a0..06eccef6b6363e 100644 --- a/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_10_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_10_3.yaml @@ -72,6 +72,27 @@ tests: }, ], } + - name: "UseCurrentContext" + value: false + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Data" @@ -123,6 +144,27 @@ tests: }, ], } + - name: "UseCurrentContext" + value: false + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Data" diff --git a/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_10_7.yaml b/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_10_7.yaml index 4c1515efe4a296..299d812dd94e44 100644 --- a/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_10_7.yaml +++ b/src/app/tests/suites/certification/Test_TC_CONTENTLAUNCHER_10_7.yaml @@ -46,6 +46,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 0, Value: "Gaby sHoffman" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -75,6 +94,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 1, Value: "PBS" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -104,6 +142,25 @@ tests: value: false - name: "Search" value: { ParameterList: [{ Type: 2, Value: "Snow White" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -133,6 +190,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 3, Value: "Spike Lee" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -162,6 +238,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 4, Value: "Football games" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -191,6 +286,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 5, Value: "Star Wars" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -220,6 +334,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 6, Value: "Horror" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -249,6 +382,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 7, Value: "NCAA" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -278,6 +430,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 8, Value: PopularityName }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -307,6 +478,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 9, Value: "Netflix" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -336,6 +526,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 10, Value: "football" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -365,6 +574,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 11, Value: "Arsenel" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" @@ -394,6 +622,25 @@ tests: value: true - name: "Search" value: { ParameterList: [{ Type: 12, Value: "TVSeries" }] } + - name: "PlaybackPreferences" + value: + { + PlaybackPosition: 0, + TextTrack: + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + AudioTracks: + [ + { + LanguageCode: "exampleLanguageCode", + Characteristics: [0], + AudioOutputIndex: 0, + }, + ], + } response: values: - name: "Status" diff --git a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml index 070a1b17aa65df..17cef9f767ee54 100644 --- a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml @@ -72,13 +72,13 @@ limitations under the License. and enforce Access Control for the Node's endpoints and their associated cluster instances. - + ACL - + Extension diff --git a/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml index 992b07897336c9..273533c5fa82a1 100644 --- a/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml @@ -35,11 +35,13 @@ limitations under the License. Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. - + + The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. + @@ -47,5 +49,10 @@ limitations under the License. + + This event can be used by the Content App to indicate that the current user has logged out. In response to this event, the Fabric Admin SHALL remove access to this Content App by the specified Node. If no Node is provided, then the Fabric Admin SHALL remove access to all non-Admin Nodes. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml index c19bca0017a675..acf28b88e46414 100644 --- a/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml @@ -90,8 +90,8 @@ limitations under the License. ACTIONS_CLUSTER This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. - ActionList - EndpointLists + ActionList + EndpointLists SetupURL diff --git a/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml index a3c54b8c1d8c53..e6331f698fd423 100644 --- a/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml @@ -31,7 +31,7 @@ limitations under the License. Application Status ApplicationVersion - + AllowedVendorList diff --git a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml index d68b3d3851ae22..7a50d97d666b5f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml @@ -25,7 +25,7 @@ limitations under the License. true This cluster provides an interface for launching content on a media player device such as a TV or Speaker. - CatalogList + CatalogList CurrentApp diff --git a/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml index 7cca1ca7f19c28..2067d048d4e569 100644 --- a/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml @@ -24,7 +24,7 @@ limitations under the License. true true This cluster provides an interface for controlling the Output on a media device such as a TV. - OutputList + OutputList CurrentOutput diff --git a/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml index 96b3be1377de41..741a5a9372edc0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml @@ -31,7 +31,7 @@ limitations under the License. 0x001e BINDING_CLUSTER The Binding Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for supporting the binding table. - + Binding diff --git a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml index ec8a2e2cc5d068..5dc01df19f65f5 100644 --- a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml @@ -24,7 +24,7 @@ limitations under the License. true true This cluster provides an interface for controlling the current Channel on a device. - ChannelList + ChannelList Lineup CurrentChannel @@ -50,6 +50,39 @@ limitations under the License. + + This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. + + + + + + + + + + + This command is a response to the GetProgramGuide command. + + + + + + Record a specific program or series when it goes live. This functionality enables DVR recording features. + + + + + + + + Cancel recording for a specific program or series. + + + + + + @@ -59,6 +92,8 @@ limitations under the License. + + @@ -69,6 +104,66 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -81,10 +176,26 @@ limitations under the License. + + + + + + + + + + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/chip-ota.xml b/src/app/zap-templates/zcl/data-model/chip/chip-ota.xml index 8ea8bc06d52aad..28cf9f2f728360 100644 --- a/src/app/zap-templates/zcl/data-model/chip/chip-ota.xml +++ b/src/app/zap-templates/zcl/data-model/chip/chip-ota.xml @@ -121,7 +121,7 @@ limitations under the License. OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER true true - DefaultOTAProviders + DefaultOTAProviders UpdatePossible UpdateState UpdateStateProgress diff --git a/src/app/zap-templates/zcl/data-model/chip/chip-types.xml b/src/app/zap-templates/zcl/data-model/chip/chip-types.xml index 0756fd85569f6c..a9466ff6d79ffc 100644 --- a/src/app/zap-templates/zcl/data-model/chip/chip-types.xml +++ b/src/app/zap-templates/zcl/data-model/chip/chip-types.xml @@ -102,6 +102,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml new file mode 100644 index 00000000000000..89d72eb768e519 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml @@ -0,0 +1,49 @@ + + + + + + Media + Content App Observer + 0x0510 + CONTENT_APP_OBSERVER_CLUSTER + true + true + This cluster provides an interface for sending targeted commands to an Observer of a Content App on a Video Player device such as a Streaming Media Player, Smart TV or Smart Screen. The cluster server for Content App Observer is implemented by an endpoint that communicates with a Content App, such as a Casting Video Client. The cluster client for Content App Observer is implemented by a Content App endpoint. A Content App is informed of the NodeId of an Observer when a binding is set on the Content App. The Content App can then send the ContentAppMessage to the Observer (server cluster), and the Observer responds with a ContentAppMessageResponse. + + + Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. + + + + + + This command SHALL be generated in response to ContentAppMessage command. + + + + + + + + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml new file mode 100644 index 00000000000000..6dcf825c364c03 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml @@ -0,0 +1,108 @@ + + + + + + Media + Content Control + 0x050F + CONTENT_CONTROL_CLUSTER + true + true + This cluster is used for managing the content control (including "parental control") settings on a media device such as a TV, or Set-top Box. + Enabled + OnDemandRatings + OnDemandRatingThreshold + ScheduledContentRatings + ScheduledContentRatingThreshold + ScreenDailyTime + RemainingScreenTime + BlockUnrated + + + The purpose of this command is to update the PIN used for protecting configuration of the content control settings. Upon success, the old PIN SHALL no longer work. The PIN is used to ensure that only the Node (or User) with the PIN code can make changes to the Content Control settings, for example, turn off Content Controls or modify the ScreenDailyTime. The PIN is composed of a numeric string of up to 6 human readable characters (displayable) . Upon receipt of this command, the media device SHALL check if the OldPIN field of this command is the same as the current PIN. If the PINs are the same, then the PIN code SHALL be set to NewPIN. Otherwise a response with InvalidPINCode error status SHALL be returned. The media device MAY provide a default PIN to the User via an out of band mechanism. For security reasons, it is recommended that a client encourage the user to update the PIN from its default value when performing configuration of the Content Control settings exposed by this cluster. The ResetPIN command can also be used to obtain the default PIN. + + + + + + The purpose of this command is to reset the PIN. If this command is executed successfully, a ResetPINResponse command with a new PIN SHALL be returned. + + + + This command SHALL be generated in response to a ResetPIN command. The data for this command SHALL be as follows: + + + + + The purpose of this command is to turn on the Content Control feature on a media device. On receipt of the Enable command, the media device SHALL set the Enabled attribute to TRUE. + + + + The purpose of this command is to turn off the Content Control feature on a media device. On receipt of the Disable command, the media device SHALL set the Enabled attribute to FALSE. + + + + The purpose of this command is to add the extra screen time for the user. If a client with Operate privilege invokes this command, the media device SHALL check whether the PINCode passed in the command matches the current PINCode value. If these match, then the RemainingScreenTime attribute SHALL be increased by the specified BonusTime value. If the PINs do not match, then a response with InvalidPINCode error status SHALL be returned, and no changes SHALL be made to RemainingScreenTime. If a client with Manage privilege or greater invokes this command, the media device SHALL ignore the PINCode field and directly increase the RemainingScreenTime attribute by the specified BonusTime value. A server that does not support the PM feature SHALL respond with InvalidPINCode to clients that only have Operate privilege unless: It has been provided with the PIN value to expect via an out of band mechanism, and The client has provided a PINCode that matches the expected PIN value. + + + + + + The purpose of this command is to set the ScreenDailyTime attribute. On receipt of the SetScreenDailyTime command, the media device SHALL set the ScreenDailyTime attribute to the ScreenTime value. + + + + + The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the BlockUnratedContent command, the media device SHALL set the BlockUnrated attribute to TRUE. + + + + The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the UnblockUnratedContent command, the media device SHALL set the BlockUnrated attribute to FALSE. + + + + The purpose of this command is to set the OnDemandRatingThreshold attribute. On receipt of the SetOnDemandRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the OnDemandRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. + + + + + The purpose of this command is to set ScheduledContentRatingThreshold attribute. On receipt of the SetScheduledContentRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the ScheduledContentRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. + + + + + This event SHALL be generated when the RemainingScreenTime equals 0. + + + + + + + + + + + + + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml index 949a5d89924f8d..f74b61a29f4784 100644 --- a/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml @@ -26,7 +26,7 @@ limitations under the License. This cluster provides an interface for launching content on a media player device such as a TV or Speaker. - AcceptHeader + AcceptHeader SupportedStreamingProtocols @@ -34,6 +34,8 @@ limitations under the License. + + @@ -111,6 +113,9 @@ limitations under the License. + + + @@ -118,6 +123,8 @@ limitations under the License. + + @@ -127,15 +134,55 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml index f0670e25b0aab4..f95d2acb1b2f40 100644 --- a/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml @@ -45,10 +45,10 @@ limitations under the License. - DeviceTypeList - ServerList - ClientList - PartsList - TagList + DeviceTypeList + ServerList + ClientList + PartsList + TagList diff --git a/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml index c55edf507f51be..27162f66e5e6db 100644 --- a/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml @@ -52,7 +52,7 @@ limitations under the License. Response to the RetrieveLogsRequest - + diff --git a/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml index 686deb61a4fc8c..c578c164c0ca0f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml @@ -34,7 +34,7 @@ limitations under the License. Attributes and commands for selecting a mode from a list of supported options. - SupportedModes + SupportedModes CurrentMode StartUpMode OnMode diff --git a/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml index b7c7782b221030..6673d4644e3105 100644 --- a/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml @@ -362,7 +362,7 @@ limitations under the License. - + diff --git a/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml index c5e4b98ae6d333..fdffc7d58d051c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml @@ -185,10 +185,10 @@ limitations under the License. true - LoadControlPrograms + LoadControlPrograms NumberOfLoadControlPrograms - Events - ActiveEvents + Events + ActiveEvents NumberOfEventsPerProgram NumberOfTransitions diff --git a/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml index a0280a3a3ab2eb..96e420f01902de 100644 --- a/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml @@ -31,6 +31,6 @@ limitations under the License. FIXED_LABEL_CLUSTER The Fixed Label Cluster provides a feature for the device to tag an endpoint with zero or more read only labels. - LabelList + LabelList diff --git a/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml index 7bc52936563263..7fb2ebc4387dad 100644 --- a/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml @@ -83,15 +83,15 @@ limitations under the License. 0x0033 GENERAL_DIAGNOSTICS_CLUSTER The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. - NetworkInterfaces + NetworkInterfaces RebootCount UpTime TotalOperationalHours BootReason - ActiveHardwareFaults - ActiveRadioFaults - ActiveNetworkFaults + ActiveHardwareFaults + ActiveRadioFaults + ActiveNetworkFaults TestEventTriggersEnabled - SupportedModes + SupportedModes CurrentMode StartUpMode OnMode diff --git a/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml index aa8a5083a29903..9bdededd0fcd6e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml @@ -32,6 +32,6 @@ limitations under the License. ActiveLocale - SupportedLocales + SupportedLocales diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index b73bea88aab9af..e9717e9c740987 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -1966,6 +1966,18 @@ limitations under the License. + + + MA-oven + CHIP + Matter Oven + 0x0103 + 0x007B + Simple + Endpoint + + + MA-refrigerator @@ -2018,6 +2030,22 @@ limitations under the License. + + MA-extractor-hood + CHIP + Matter Extractor Hood + 0x0103 + 0x007A + Simple + Endpoint + + + + + + + + MA-robotic-vacuum-cleaner CHIP diff --git a/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml index d6b6b1782769fd..028ab467af7c0c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml @@ -26,7 +26,7 @@ limitations under the License. This cluster provides an interface for controlling the Input Selector on a media device such as a TV. - InputList + InputList CurrentInput diff --git a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml index 23ab5f6fd7b3e5..1d9b56dc9a1385 100644 --- a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml @@ -33,6 +33,10 @@ limitations under the License. PlaybackSpeed SeekRangeEnd SeekRangeStart + ActiveAudioTrack + AvailableAudioTracks + ActiveTextTrack + AvailableTextTracks @@ -61,10 +65,12 @@ limitations under the License. Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). + Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). + @@ -88,8 +94,48 @@ limitations under the License. + + Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. + + + + + + Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. + + + + + If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. + + + + If supported, this event SHALL be generated when there is a change in any of the supported attributes of the Media Playback cluster. + + + + + + + + + + + + + + + + + + + + + + + @@ -118,5 +164,31 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml index 2d5f09201f4218..826d77ecd9f42a 100644 --- a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml @@ -33,7 +33,7 @@ limitations under the License. Attributes and commands for selecting a mode from a list of supported options. - SupportedModes + SupportedModes CurrentMode diff --git a/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml index 9d31baf004f7e5..2bf3905b7f34c5 100644 --- a/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml @@ -59,7 +59,7 @@ This is because zap does not currently support generating code for clusters that - + diff --git a/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml index 323f12e551eaf3..0462a48e8bc513 100644 --- a/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml @@ -44,7 +44,7 @@ limitations under the License. Description StandardNamespace - SupportedModes + SupportedModes CurrentMode StartUpMode OnMode diff --git a/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml index 56e98e16d27a6a..340effa347298d 100644 --- a/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml @@ -109,7 +109,7 @@ limitations under the License. MaxNetworks - + Networks @@ -132,7 +132,7 @@ limitations under the License. LastConnectErrorValue - + SupportedWiFiBands @@ -206,14 +206,14 @@ limitations under the License. Retrieve details about and optionally proof of possession of a network client identity. - - + + Command that contains details about a network client identity and optionally a proof of possession. - - + + diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml index d79cbb845c7827..5b06c93e0ab7fd 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml @@ -59,14 +59,14 @@ limitations under the License. OPERATIONAL_CREDENTIALS_CLUSTER This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. - + NOCs - Fabrics + Fabrics SupportedFabrics CommissionedFabrics - TrustedRootCertificates + TrustedRootCertificates CurrentFabricIndex diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml index e3f7581b52f829..a93e27fe130333 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml @@ -63,10 +63,10 @@ limitations under the License. - PhaseList + PhaseList CurrentPhase CountdownTime - OperationalStateList + OperationalStateList OperationalState OperationalError diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml index 2305667a44f8a0..f121b6357d605b 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml @@ -27,10 +27,10 @@ limitations under the License. - PhaseList + PhaseList CurrentPhase CountdownTime - OperationalStateList + OperationalStateList OperationalState OperationalError diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml index 44982132bce51d..b34995597bd6f7 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml @@ -47,10 +47,10 @@ limitations under the License. - PhaseList + PhaseList CurrentPhase CountdownTime - OperationalStateList + OperationalStateList - SupportedModes + SupportedModes CurrentMode StartUpMode OnMode diff --git a/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml index d795b8758f107b..913df128cc758e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml @@ -36,7 +36,7 @@ limitations under the License. WiredNominalVoltage WiredMaximumCurrent WiredPresent - ActiveWiredFaults + ActiveWiredFaults BatVoltage BatPercentRemaining @@ -45,7 +45,7 @@ limitations under the License. BatReplacementNeeded BatReplaceability BatPresent - ActiveBatFaults + ActiveBatFaults BatReplacementDescription BatCommonDesignation BatANSIDesignation @@ -57,8 +57,8 @@ limitations under the License. BatTimeToFullCharge BatFunctionalWhileCharging BatChargingCurrent - ActiveBatChargeFaults - EndpointList + ActiveBatChargeFaults + EndpointList The WiredFaultChange Event SHALL indicate a change in the set of wired faults currently detected by the Node on this wired power source. diff --git a/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml index 994cdb78969a88..04a7cdb121c775 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml @@ -26,6 +26,6 @@ limitations under the License. true true - Sources + Sources diff --git a/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml index bbd0e229338883..a8f9605b81a1bc 100644 --- a/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml @@ -33,7 +33,7 @@ limitations under the License. Attributes and commands for selecting a mode from a list of supported options. - SupportedModes + SupportedModes CurrentMode StartUpMode OnMode diff --git a/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml index 11643c6b836624..4be5dbddc12478 100644 --- a/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml @@ -31,7 +31,7 @@ limitations under the License. ChangeIndication InPlaceIndicator LastChangedTime - ReplacementProductList + ReplacementProductList @@ -54,7 +54,7 @@ limitations under the License. ChangeIndication InPlaceIndicator LastChangedTime - ReplacementProductList + ReplacementProductList diff --git a/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml index 44a2669c8d018e..03725f92756c56 100644 --- a/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml @@ -39,7 +39,7 @@ limitations under the License. Attributes and commands for selecting a mode from a list of supported options. - SupportedModes + SupportedModes CurrentMode OnMode diff --git a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml index 2175e26ed9f257..1a866b5f5868da 100644 --- a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml @@ -45,7 +45,7 @@ limitations under the License. Attributes and commands for selecting a mode from a list of supported options. - SupportedModes + SupportedModes CurrentMode OnMode diff --git a/src/app/zap-templates/zcl/data-model/chip/scene.xml b/src/app/zap-templates/zcl/data-model/chip/scene.xml index b8bcbc1243a1dd..b1273514dd9f04 100644 --- a/src/app/zap-templates/zcl/data-model/chip/scene.xml +++ b/src/app/zap-templates/zcl/data-model/chip/scene.xml @@ -15,12 +15,12 @@ See the License for the specific language governing permissions and limitations under the License. --> - + - + @@ -64,7 +64,7 @@ limitations under the License. NameSupport LastConfiguredBy SceneTableSize - FabricSceneInfo + FabricSceneInfo Add a scene to the scene table. Extension field sets are supported, and are inputed as '{"ClusterID": VALUE, "AttributeValueList":[{"AttributeId": VALUE, "AttributeValue": VALUE}]}' diff --git a/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml index 2745b367d24f58..41dfb3a156693b 100644 --- a/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml @@ -30,7 +30,7 @@ limitations under the License. 0x0034 SOFTWARE_DIAGNOSTICS_CLUSTER The Software Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. - ThreadMetrics + ThreadMetrics CurrentHeapFree CurrentHeapUsed CurrentHeapHighWatermark diff --git a/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml index 0daa3817da96a4..388770512ee27c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml @@ -24,7 +24,7 @@ limitations under the License. true true This cluster provides an interface for UX navigation within a set of targets on a device or endpoint. - TargetList + TargetList CurrentTarget @@ -38,6 +38,13 @@ limitations under the License. + + + This field SHALL indicate the updated target list as defined by the TargetList attribute if there is a change in the list of targets. Otherwise this field can be omitted from the event. + + + + @@ -49,7 +56,7 @@ limitations under the License. - + diff --git a/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml index e9960e93981097..7509e9b44579cb 100644 --- a/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml @@ -30,7 +30,7 @@ limitations under the License. MaxTemperature Step SelectedTemperatureLevel - SupportedTemperatureLevels + SupportedTemperatureLevels Set Temperature diff --git a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml index 9117389fa3f9c6..6e81b67b5c46e9 100644 --- a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml @@ -166,20 +166,20 @@ limitations under the License. int64s enum8 enum16 - float_single - float_double + float_single + float_double octet_string - list_int8u - list_octet_string - list_struct_octet_string - long_octet_string + list_int8u + list_octet_string + list_struct_octet_string + long_octet_string char_string long_char_string epoch_us epoch_s vendor_id - list_nullables_and_optionals_struct enum_attr struct_attr @@ -187,8 +187,8 @@ limitations under the License. range_restricted_int8s range_restricted_int16u range_restricted_int16s - list_long_octet_string - list_fabric_scoped + list_long_octet_string + list_fabric_scoped timed_write_boolean