Send large BLE host frames across multiple notifies.

Prefer ATT MTU 517 and chunk oversized responses so CLIENT_INFO/BATTERY work with many pods; reset the goTool parser after timeouts so partial frames do not poison the next exchange.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-11-01 23:53:40 +01:00
co-authored by Cursor
parent 9046677460
commit 141176a824
7 changed files with 114 additions and 42 deletions
+12 -25
View File
@@ -7,10 +7,9 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "ota_session.h"
#include "pb_encode.h"
#include "uart.h"
#include "uart_cmd.h"
#include "uart_messages.pb.h"
#include "uart_proto.h"
#include <string.h>
static const char *TAG = "[BLE_STREAM]";
@@ -102,34 +101,22 @@ static bool any_accel_stream(void) {
}
static esp_err_t send_tick_truncated(alox_UartMessage *msg) {
uint8_t pb_buf[MAX_PAYLOAD_SIZE];
pb_ostream_t stream = pb_ostream_from_buffer(pb_buf, sizeof(pb_buf));
/*
* ble_host_tx splits frames larger than ATT MTU-3 across notifies. Only
* shrink the tick if it cannot encode into MAX_PAYLOAD_SIZE.
*/
while (true) {
stream = pb_ostream_from_buffer(pb_buf, sizeof(pb_buf));
if (!pb_encode(&stream, alox_UartMessage_fields, msg)) {
return ESP_FAIL;
esp_err_t err = uart_send_uart_message(msg);
if (err == ESP_OK) {
return ESP_OK;
}
size_t payload_len = stream.bytes_written + 1;
uint16_t max_pay = ble_host_max_payload();
/* Framed size = payload + UART_FRAME_OVERHEAD; notify must fit ATT MTU-3. */
size_t frame_len = payload_len + UART_FRAME_OVERHEAD;
if (payload_len <= MAX_PAYLOAD_SIZE && frame_len <= max_pay) {
uint8_t payload[MAX_PAYLOAD_SIZE];
payload[0] = (uint8_t)msg->type;
memcpy(&payload[1], pb_buf, stream.bytes_written);
return uart_send_framed(payload, payload_len);
}
if (msg->payload.ble_stream_tick.clients_count == 0) {
ESP_LOGW(TAG, "tick too large even with 0 clients (need %u max %u)",
(unsigned)frame_len, (unsigned)max_pay);
return ESP_ERR_NO_MEM;
ESP_LOGW(TAG, "tick too large even with 0 clients: %s",
esp_err_to_name(err));
return err;
}
msg->payload.ble_stream_tick.clients_count--;
ESP_LOGW(TAG, "truncating tick clients to %u for MTU",
ESP_LOGW(TAG, "truncating tick clients to %u for encode buffer",
(unsigned)msg->payload.ble_stream_tick.clients_count);
}
}