Skip to content

Fix MQTT 5 SUBACK reason codes passed to completion callbacks - #141

Open
ZoneMR wants to merge 1 commit into
FreeRTOS:mainfrom
ZoneMR:codex/fix-mqtt5-suback-reason-codes
Open

ZoneMR wants to merge 1 commit into
FreeRTOS:mainfrom
ZoneMR:codex/fix-mqtt5-suback-reason-codes

Conversation

@ZoneMR

@ZoneMR ZoneMR commented Sep 23, 2026

Copy link
Copy Markdown

Description

MQTT 5 SUBACK packets include a variable-length properties section between the packet identifier and the per-filter reason codes. handleAcks() still uses the MQTT 3 offset (pRemainingData[2]), so callbacks receive the property-length byte as the first result and miss the last filter's actual reason code.

For example, 90 04 00 01 00 87 is a valid single-filter SUBACK reporting Not authorized. The completion callback currently sees 0x00 (granted QoS 0) instead of 0x87. Replies containing properties can expose property bytes as grant codes instead.

Use the parser's reason-code view, preserving the existing callback pointer type. Verify that the acknowledged command is a SUBSCRIBE and that the number of reason codes matches the requested filters before exposing the array. Invalid metadata completes the command with MQTTBadResponse and no reason-code pointer.

Eight unit tests cover single and batched refusals, a Reason String property, short/long reason arrays, missing metadata/storage, and a mismatched command type. No public API changes.

Test Steps

  • Both upstream unit-test suites pass: 52 agent tests and 16 command-function tests.
  • A separate integration harness using the actual MQTT parser and agent passes, including multi-byte property lengths; its single-filter refusal case fails against the original implementation.
  • The integration tests also pass with AddressSanitizer and UndefinedBehaviorSanitizer.
  • Formatted with uncrustify 0.69.0 and the upstream configuration.

Upstream tests were built on macOS with C99, Ruby 2.6, and explicit Clang coverage-runtime linker flags:

cmake -S test -B build-tests -DUNITTEST=ON -DCOV_ANALYSIS=ON \
  -DCMAKE_C_STANDARD=99 \
  -DCMAKE_EXE_LINKER_FLAGS='-fprofile-arcs -ftest-coverage -fprofile-generate' \
  -DCMAKE_SHARED_LINKER_FLAGS='-fprofile-arcs -ftest-coverage -fprofile-generate'
cmake --build build-tests -j1
ctest --test-dir build-tests --output-on-failure

Checklist:

  • I have tested my changes. No regression in existing tests.
  • I have modified and/or added unit-tests to cover the code changes in this Pull Request.

Related Issue

None.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Use the deserialized reason-code view instead of the MQTT 3 fixed offset, which exposes the property length as the first grant and omits the final filter's result. Validate the command type and reason-code count before invoking callbacks. Add eight unit tests for refusals, properties, malformed reason arrays and mismatched commands.

This branch has not been deployed

No deployments
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.

1 participant