Skip to content

feat(protocol): tolerate signed/unsigned int mismatch in data report decode#3998

Merged
Apollon77 merged 2 commits into
mainfrom
feat/relax-datareport-number-types
Jun 27, 2026
Merged

feat(protocol): tolerate signed/unsigned int mismatch in data report decode#3998
Apollon77 merged 2 commits into
mainfrom
feat/relax-datareport-number-types

Conversation

@Apollon77

Copy link
Copy Markdown
Collaborator

Problem

Some production devices encode an integer attribute/event value with the wrong TLV signedness — e.g. a uint8 value sent as a signed integer:

InputChunk Error decoding event 44/0x3b/0x1:
Unexpected type 0, was expecting 4.

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:

  • New internal TlvDecodingOptions.relaxNumberTypeChecks, threaded via the TlvReader, so no decode-method signature churn across schema subclasses.
  • Enabled only on the InputChunk data report path (DATA_REPORT_DECODE_OPTIONS) — not user-configurable, not applied to encode or any other decode.
  • Relax is limited to the integer family (Signed/Unsigned). Float stays strict.
  • The decoded value is still range-validated (validateBoundaries), so a negative value into a uint or an out-of-range value is still rejected.
  • Each tolerated mismatch is logged at 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-encoded uint attribute in a data report now decodes instead of being dropped.
  • Full gates green: types 360/360, protocol 1243/1243, clean build, format, lint.

…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>
Copilot AI review requested due to automatic review settings June 27, 2026 14:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.relaxNumberTypeChecks and thread it through TlvReader/decodeTlv so decode behavior can be adjusted without widespread signature churn.
  • Enable relaxed signed/unsigned integer decoding only for the InputChunk data report path, and log tolerated mismatches.
  • Add targeted tests covering relaxed integer decode, option threading through chunked arrays, and an end-to-end InputChunk decode 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.

Comment thread packages/protocol/src/action/client/InputChunk.ts
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@mergify

mergify Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@Apollon77 Apollon77 merged commit 67a669f into main Jun 27, 2026
37 checks passed
@Apollon77 Apollon77 deleted the feat/relax-datareport-number-types branch June 27, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants