Leave room for the answer: ALEX2ESP_MAX_MESSAGE defaults to ALEX2ESP_MAX_DIRECTIVE + 1024

Both limits were 2047 bytes. An answer repeats the correlationToken of its directive, which is most of a large directive, and adds 140 to 170 bytes for every property. So a directive between about 1,750 and 2,047 bytes was accepted, the sketch acted on it, and the answer was refused: the lamp switched and Alexa reported a device that does not respond.

The limit for messages now follows the limit for directives unless it is set: 2047 + 1024 = 3071 bytes, room for six properties on top of the largest directive. Both defines moved to src/AlexaLimits.h, next to each other, with the relation in the comment. The limit also applies to the discovery object of a device, which may now be 3071 bytes.

For a sketch: a report between 2,048 and 3,071 bytes is sent, where it was refused with an error. A project that sets ALEX2ESP_MAX_MESSAGE keeps its value.

Measured with the bridge built for the host against a fake MQTT client (not in the repository), a TurnOn of 2,047 bytes answered with two properties:
  8ea7778      handler ran, send() false, "2374 bytes not sent, the limit is 2047"
  this commit  handler ran, send() true, 2,374 bytes published

Tests: test_largest_directive_can_be_answered puts a directive of ALEX2ESP_MAX_DIRECTIVE bytes through the receive buffer, builds the Response of a lamp to it and checks it against ALEX2ESP_MAX_MESSAGE, also with six properties. 33 host tests pass.

examples/basicLight.cpp for d1_mini, static RAM / flash in bytes: 34,116 / 336,757 -> 34,116 / 336,757, no warnings.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
David 2026-09-28 15:38:46 +00:00
parent 46a27c26e9
commit e48f8580f9
5 changed files with 102 additions and 17 deletions

View file

@ -21,16 +21,12 @@
#include "AlexaBridgeLogic.h"
#include "AlexaDevice.h"
#include "AlexaInterface.h"
#include "AlexaLimits.h"
#include "AlexaLog.h"
#include "AlexaTransport.h"
#include "AlexaUtils.h"
#include <deque>
// Largest directive the bridge accepts, in bytes. Override with -DALEX2ESP_MAX_DIRECTIVE=<bytes> in build_flags.
#ifndef ALEX2ESP_MAX_DIRECTIVE
#define ALEX2ESP_MAX_DIRECTIVE 2047
#endif
enum class Alex2ESPState
{
UNINITIALIZED, // begin() has not been called

22
src/AlexaLimits.h Normal file
View file

@ -0,0 +1,22 @@
// The size limits of the bridge. Each is a default: -D<name>=<value> in build_flags overrides it for the whole
// project. The Arduino IDE has no per-sketch flags and builds with the defaults.
#ifndef ALEXA_LIMITS_H
#define ALEXA_LIMITS_H
// Largest directive the bridge accepts, in bytes. Alex2MQTT publishes directives of 600 to 900 bytes; most of
// that is the correlationToken.
#ifndef ALEX2ESP_MAX_DIRECTIVE
#define ALEX2ESP_MAX_DIRECTIVE 2047
#endif
// Largest message the bridge publishes, in bytes of JSON: a report, or the discovery object of one device.
//
// The answer to a directive repeats its correlationToken, so it is as large as the directive plus 140 to 170
// bytes for every property it reports. The default leaves 1024 bytes for the properties, six of them: a
// directive that was accepted can be answered. With a limit under ALEX2ESP_MAX_DIRECTIVE + 300 the answer of a
// lamp (two properties) to the largest directive is refused after the sketch has acted on the directive.
#ifndef ALEX2ESP_MAX_MESSAGE
#define ALEX2ESP_MAX_MESSAGE (ALEX2ESP_MAX_DIRECTIVE + 1024)
#endif
#endif // ALEXA_LIMITS_H

View file

@ -6,12 +6,7 @@
#include <stddef.h>
#include <stdint.h>
#include <ArduinoJson.h>
// Largest message the bridge publishes, in bytes of JSON: a report or the discovery object of one device.
// Override with -DALEX2ESP_MAX_MESSAGE=<bytes> in build_flags.
#ifndef ALEX2ESP_MAX_MESSAGE
#define ALEX2ESP_MAX_MESSAGE 2047
#endif
#include "AlexaLimits.h"
// "YYYY-MM-DDThh:mm:ssZ" and the terminating NUL
#define ALEXA_TIMESTAMP_SIZE 21