8ea7778kept one directive for loop() and recognised the repeat that the broker mirror delivers in two ways: bytes compared with the directive that still waited, and the messageId once loop() had parsed it. A repeat that arrived after its directive had been read therefore took the one place until the next loop(), and a different directive behind it was dropped. Alexa sends a group command as one directive per endpoint, so a board with several endpoints lost directives whenever they arrived faster than loop() ran; 1.1.0 queued five tokens. AlexaDirectiveBuffer is now a queue. The arriving message is collected in a heap block of its own and hashed (FNV-1a, 64 bit) as its fragments come in. At the last fragment it is one of three things: a repeat, when the hash is among the last 16 that were queued, and then it is freed and never takes a place; a directive, which is queued; or lost, when eight directives (ALEX2ESP_MAX_QUEUED_DIRECTIVES) or 8188 bytes (ALEX2ESP_MAX_QUEUED_BYTES, four times the largest directive) already wait. Whether there is a place is decided at the last fragment, because loop() may have read a directive by then. A message for which there is no memory is still hashed, so its loss is reported only when it is not a repeat. loop() parses one directive per call, in the order of arrival, and frees its block before the handler runs. The messageId check stays for a directive that comes again with other bytes; it remembers 16 ids instead of 4 and shares the ring with the buffer (AlexaRecentHashes). The two limits are in src/AlexaLimits.h, with #error for values that cannot work. The constructor of the buffer takes the allocator, malloc by default, so the tests can let it fail. For a sketch: nothing to change. The error line of a directive that finds no place reads "directive of N bytes on <topic> dropped: 8 directives, M bytes, already wait for loop()". The heap holds up to 8188 bytes of waiting directives and one arriving directive of up to 2048, where it held one directive. Measured with the bridge built for the host against a fake MQTT client (not in the repository), directives of 793 bytes, every message delivered twice,8ea7778-> this commit: repeat of D1 and a new D2 after D1 was handled D2 dropped -> D2 handled group of 5 in one burst 1 of 5 handled, 8 error lines -> 5 of 5, none group of 8 in one burst 8 of 8 handled, no error line group of 10 in one burst, not mirrored 8 of 10 handled, 2 error lines group of 10, a loop() after every fourth message 10 of 10 handled, no error line Tests: 41 host tests (33 before). New: the order of the queue and the reuse of its places, the ninth directive, a place that becomes free while a directive arrives, the limit in bytes, the largest directive in an empty queue, the repeat of a waiting directive and of one that was read, a group of five with repeats, a repeat when no place is free, a directive that differs in one byte, how long a repeat is remembered, a directive and a repeat without memory, the FNV-1a test vectors. They also pass under -fsanitize=address,undefined. Seven faults planted in a copy of AlexaBridgeLogic.cpp (no repeat check, no limit in bytes, no limit in places, no bounds check, a lost directive remembered, release() that keeps the bytes, last in first out) were each noticed: six by failing tests, the missing bounds check by AddressSanitizer as a heap-buffer-overflow. Built for d1_mini with empty credentials (PlatformIO 6.2.0, espressif8266 4.2.1), static RAM / flash in bytes,e48f858-> this commit, no warnings: basicLight 34,116 / 336,757 -> 34,444 / 337,145 lightWithBrightness 34,232 / 340,517 -> 34,560 / 340,921 lightWithColorTemp 34,380 / 341,177 -> 34,708 / 341,581 tempSensor 34,024 / 335,457 -> 34,352 / 335,845 blindControl 34,256 / 338,925 -> 34,584 / 339,313 The 328 bytes of RAM are the two rings of 16 hashes (256) and the eight places of the queue. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
96 lines
2.3 KiB
Text
96 lines
2.3 KiB
Text
#######################################
|
|
# Syntax Coloring Map For Alex2ESP
|
|
#######################################
|
|
|
|
#######################################
|
|
# Datatypes (KEYWORD1)
|
|
#######################################
|
|
|
|
Alex2ESP KEYWORD1
|
|
Alex2ESPState KEYWORD1
|
|
AlexaDevice KEYWORD1
|
|
AlexaInterface KEYWORD1
|
|
AlexaInterfaceType KEYWORD1
|
|
AlexaInterfaceUtils KEYWORD1
|
|
AlexaStatusMessage KEYWORD1
|
|
ActionMapping KEYWORD1
|
|
AlexaActions KEYWORD1
|
|
AlexaActionsUtils KEYWORD1
|
|
FriendlyName KEYWORD1
|
|
DisplayCategory KEYWORD1
|
|
DisplayCategoryUtils KEYWORD1
|
|
EndpointHealth KEYWORD1
|
|
PowerController KEYWORD1
|
|
TemperatureSensorScale KEYWORD1
|
|
AlexaUtils KEYWORD1
|
|
AlexaLog KEYWORD1
|
|
AlexaLogLevel KEYWORD1
|
|
AlexaSendResult KEYWORD1
|
|
AlexaTransport KEYWORD1
|
|
|
|
#######################################
|
|
# Methods and Functions (KEYWORD2)
|
|
#######################################
|
|
|
|
begin KEYWORD2
|
|
loop KEYWORD2
|
|
getState KEYWORD2
|
|
getDisconnectReason KEYWORD2
|
|
getDevice KEYWORD2
|
|
setLogLevel KEYWORD2
|
|
setTimeSource KEYWORD2
|
|
publish KEYWORD2
|
|
timestamp KEYWORD2
|
|
setName KEYWORD2
|
|
getName KEYWORD2
|
|
getEndpointId KEYWORD2
|
|
hasEndpointId KEYWORD2
|
|
setDisplayCategory KEYWORD2
|
|
getDisplayCategory KEYWORD2
|
|
setDescription KEYWORD2
|
|
getDescription KEYWORD2
|
|
setManufacturerName KEYWORD2
|
|
getManufacturerName KEYWORD2
|
|
setManufacturer KEYWORD2
|
|
getManufacturer KEYWORD2
|
|
setModel KEYWORD2
|
|
getModel KEYWORD2
|
|
getSoftwareVersion KEYWORD2
|
|
getDeviceJSON KEYWORD2
|
|
addCapability KEYWORD2
|
|
registerEvent KEYWORD2
|
|
triggerEvent KEYWORD2
|
|
buildStatusMessage KEYWORD2
|
|
getType KEYWORD2
|
|
getTypeString KEYWORD2
|
|
getVersion KEYWORD2
|
|
getProps KEYWORD2
|
|
setInstance KEYWORD2
|
|
addFriendlyName KEYWORD2
|
|
isRetrievable KEYWORD2
|
|
isProactivelyReported KEYWORD2
|
|
setRetrievable KEYWORD2
|
|
setProactivelyReported KEYWORD2
|
|
addActionMapping KEYWORD2
|
|
getJSON KEYWORD2
|
|
AddHealthProp KEYWORD2
|
|
AddPowerControllerProp KEYWORD2
|
|
AddTemperatureSensorProp KEYWORD2
|
|
AddBrightnessControllerProp KEYWORD2
|
|
AddColorTemperatureControllerProp KEYWORD2
|
|
AddToggleControllerProp KEYWORD2
|
|
AddContextProp KEYWORD2
|
|
send KEYWORD2
|
|
printMemoryInfo KEYWORD2
|
|
|
|
#######################################
|
|
# Constants (LITERAL1)
|
|
#######################################
|
|
|
|
ALEX2ESP_MAX_DIRECTIVE LITERAL1
|
|
ALEX2ESP_MAX_MESSAGE LITERAL1
|
|
ALEX2ESP_MAX_QUEUED_DIRECTIVES LITERAL1
|
|
ALEX2ESP_MAX_QUEUED_BYTES LITERAL1
|
|
ALEX2ESP_LOG_MAX LITERAL1
|
|
ALEXA_TIMESTAMP_SIZE LITERAL1
|
|
MAX_EVENTS LITERAL1
|