feat(protocol): tolerate signed/unsigned int mismatch in data report decode#3998
Merged
Conversation
…decode Non-compliant devices that encode a uint value as a signed integer (or vice-versa) no longer have the affected attribute/event dropped on read and subscription decode. Adds an internal TlvDecodingOptions.relaxNumberTypeChecks flag, enabled only on the InputChunk data report path. The decoded value is still range-validated and the mismatch is logged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates Matter.js’s schema-driven TLV decoding for incoming read/subscription data reports to tolerate non-compliant devices that encode integer values with the wrong TLV signedness (signed ↔ unsigned), while still enforcing numeric bounds.
Changes:
- Add
TlvDecodingOptions.relaxNumberTypeChecksand thread it throughTlvReader/decodeTlvso decode behavior can be adjusted without widespread signature churn. - Enable relaxed signed/unsigned integer decoding only for the
InputChunkdata report path, and log tolerated mismatches. - Add targeted tests covering relaxed integer decode, option threading through chunked arrays, and an end-to-end
InputChunkdecode case.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/types/test/tlv/TlvNumberTest.ts | Adds unit tests for relaxed signed/unsigned integer decoding and option propagation through chunked arrays. |
| packages/types/src/tlv/TlvSchema.ts | Introduces TlvDecodingOptions, adds options to TlvReader, and threads options into decodeTlv readers. |
| packages/types/src/tlv/TlvNumber.ts | Implements the relaxed integer-type mismatch handling (signed/unsigned only) with bounds validation and info logging. |
| packages/types/src/tlv/TlvArray.ts | Threads decoding options through chunked-array decoding so element decode respects the relaxed mode when enabled. |
| packages/protocol/test/action/client/InputChunkTest.ts | Adds an integration-style test ensuring a signed-encoded unsigned attribute value decodes in data reports. |
| packages/protocol/src/interaction/AttributeDataDecoder.ts | Allows passing decode options down into schema decoding and chunked-array reassembly. |
| packages/protocol/src/action/client/InputChunk.ts | Enables relaxed integer checks specifically for data report decoding via DATA_REPORT_DECODE_OPTIONS. |
| CHANGELOG.md | Documents the protocol enhancement for tolerating signed/unsigned integer mismatches in incoming reports. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Contributor
|
Tick the box to add this pull request to the merge queue (same as
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Some production devices encode an integer attribute/event value with the wrong TLV signedness — e.g. a
uint8value sent as a signed integer:matter.js decode is schema-driven and strictly required the on-wire type to match the schema type, so the whole attribute/event entry was dropped. The wider ecosystem ingests these reports via wire-driven generic decode (chip-tool JSON, Apple data-value dictionaries) and keeps the value, so matter.js was the outlier dropping data.
Change
Incoming read/subscription data reports now tolerate signed↔unsigned integer encoding mismatches:
TlvDecodingOptions.relaxNumberTypeChecks, threaded via theTlvReader, so no decode-method signature churn across schema subclasses.InputChunkdata report path (DATA_REPORT_DECODE_OPTIONS) — not user-configurable, not applied to encode or any other decode.validateBoundaries), so a negative value into auintor an out-of-range value is still rejected.info(still non-compliant — report to vendor).This covers the reported case (signed→uint, positive) plus the reverse (uint→signed, in-range) and enums (
TlvEnum=TlvUInt32).Why this matches the ecosystem, not just leniency
CHIP's typed decoders (C++
Get, python controller) are strict on signed→uint, but the generic wire-driven path every hub actually uses to ingest device reports is type-agnostic. This change mirrors that wire-driven behavior for the data report path while keeping range safety.Tests
TlvNumber: signed→uint (accept positive / reject negative), uint→signed (accept in-range / reject out-of-range), float stays strict, enum, chunked-array element threading.InputChunk: a signed-encodeduintattribute in a data report now decodes instead of being dropped.