Skip to content

MQTT enhancements#427

Open
RiDDiX wants to merge 8 commits intotoniebox-reverse-engineering:developfrom
RiDDiX:develop
Open

MQTT enhancements#427
RiDDiX wants to merge 8 commits intotoniebox-reverse-engineering:developfrom
RiDDiX:develop

Conversation

@RiDDiX
Copy link

@RiDDiX RiDDiX commented Mar 10, 2026

Robust MQTT reconnect with exponential backoff, fix ha_loop multi-box timer

  • Replace fixed 500ms retry with exponential backoff (5s-60s cap)
  • Remove permanent MQTT disable on broker unavailability
  • Add clear [MQTT] prefixed logging for connect/disconnect/retry events
  • Fix ha_loop static timer bug: use per-instance timer so all boxes
    get periodic 60s republish (was broken for multi-box setups)
  • Update MQTT_CONTROL.md with reconnect behavior and expanded limitations

feat: add slap control entities via MQTT + API

  • Add SlapEnabled (ha_switch) and SlapDirection (ha_switch) per box
  • Add tbs_cmd_set_slap_enabled() and tbs_cmd_set_slap_dir() functions
  • Add slapEnabled and slapDir commands to /api/box/cmd endpoint
  • All settings applied via freshness check (setTonieboxSettings)

fix: remove dead code, prevent buffer overflow in MQTT tx callbacks

  • Remove unused toniebox_state_cmd_t enum (never referenced)
  • Remove unused pending_cmd/pending_cmd_value struct fields (never read/written)
  • Replace osSprintf with osSnprintf in MQTT tx callbacks (buffer safety)
  • Increase buffer size from 8 to 12 chars for uint32_t formatting

fix: heap-use-after-free race condition in mqtt_sendEvent
mqtt_sendEvent was calling mqttClientPublish directly on the shared
mqtt_context from HTTP handler threads, while the MQTT thread could
concurrently close the connection via mqttClientClose. This caused
a heap-use-after-free detected by AddressSanitizer.

Fix: use the thread-safe mqtt_publish buffer mechanism (protected
by MUTEX_MQTT_TX_BUFFER) which queues messages for the MQTT thread
to send, instead of directly accessing mqtt_context.

feat: stream-based playback control

  • Add tbs_cmd_stop/vol_limit_spk/vol_limit_hdp/led commands
  • Add API endpoint /api/box/cmd for remote box control
  • Add MQTT command entities (Stop, VolLimitSpk, VolLimitHdp, LED) per box
  • Wire MQTT callbacks to tbs_cmd functions
  • SSE events for command feedback

- Add tbs_cmd_stop/vol_limit_spk/vol_limit_hdp/led commands
- Add API endpoint /api/box/cmd for remote box control
- Add MQTT command entities (Stop, VolLimitSpk, VolLimitHdp, LED) per box
- Wire MQTT callbacks to tbs_cmd functions
- SSE events for command feedback
- Fix Docker workflow: dynamic REGISTRY_IMAGE for fork compatibility
- Lowercase REGISTRY_IMAGE for GHCR requirements
- Dynamic git config in build_commit_web.yml
mqtt_sendEvent was calling mqttClientPublish directly on the shared
mqtt_context from HTTP handler threads, while the MQTT thread could
concurrently close the connection via mqttClientClose. This caused
a heap-use-after-free detected by AddressSanitizer.

Fix: use the thread-safe mqtt_publish buffer mechanism (protected
by MUTEX_MQTT_TX_BUFFER) which queues messages for the MQTT thread
to send, instead of directly accessing mqtt_context.
- Remove unused toniebox_state_cmd_t enum (never referenced)
- Remove unused pending_cmd/pending_cmd_value struct fields (never read/written)
- Replace osSprintf with osSnprintf in MQTT tx callbacks (buffer safety)
- Increase buffer size from 8 to 12 chars for uint32_t formatting
- Add SlapEnabled (ha_switch) and SlapDirection (ha_switch) per box
- Add tbs_cmd_set_slap_enabled() and tbs_cmd_set_slap_dir() functions
- Add slapEnabled and slapDir commands to /api/box/cmd endpoint
- All settings applied via freshness check (setTonieboxSettings)
… timer

- Replace fixed 500ms retry with exponential backoff (5s-60s cap)
- Remove permanent MQTT disable on broker unavailability
- Add clear [MQTT] prefixed logging for connect/disconnect/retry events
- Fix ha_loop static timer bug: use per-instance timer so all boxes
  get periodic 60s republish (was broken for multi-box setups)
- Update MQTT_CONTROL.md with reconnect behavior and expanded limitations
@SciLor SciLor changed the title Develop MQTT enhancements Mar 11, 2026

error_t handleApiPluginsGet(HttpConnection *connection, const char_t *uri, const char_t *queryString, client_ctx_t *client_ctx);

error_t handleApiBoxCommand(HttpConnection *connection, const char_t *uri, const char_t *queryString, client_ctx_t *client_ctx);
Copy link
Contributor

Choose a reason for hiding this comment

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

For me this block looks like duplication of the existing settings API. You can set settings for an overlay, which is what you are doing here

Copy link
Author

Choose a reason for hiding this comment

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

Tanks for the review! You're right the /api/box/cmd endpoint was duplicating what the existing settings overlay API already provides. I've removed it entirely in commit fbd3fe5:

Removed handleApiBoxCommand from handler_api.c / handler_api.h
Removed the /api/box/cmd route from server.c
Removed the helper tbs_get_overlay_by_common_name (was only used by that endpoint)
The MQTT command entities still work they call the tbs_cmd_* functions directly without going through the HTTP API layer.

Copy link
Contributor

Choose a reason for hiding this comment

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

This change and the other workflow yml related changes do not fit to this PR. It would be great to split it into a different PR.

Copy link
Author

Choose a reason for hiding this comment

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

I've reverted both workflow files (.github/workflows/build_commit_web.yml and .github/workflows/publish_docker_matrix_base.yml) back to upstream in the same commit. I'll open a separate PR for those if needed.

@RiDDiX RiDDiX marked this pull request as draft March 11, 2026 10:02
Address PR toniebox-reverse-engineering#427 review feedback from SciLor:
- Remove handleApiBoxCommand (duplicates existing settings overlay API)
- Remove tbs_get_overlay_by_common_name (only used by removed endpoint)
- Remove /api/box/cmd route from server.c
- Revert .github/workflows changes (belong in separate PR)

MQTT command entities remain functional via tbs_cmd_* functions.
@RiDDiX RiDDiX marked this pull request as ready for review March 11, 2026 13:05
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