Skip to content

Wait for data when parsing JSON from a TLS stream - #85

Merged
elliotmatson merged 1 commit into
mainfrom
fix-release-list-stream
Oct 4, 2026
Merged

elliotmatson merged 1 commit into
mainfrom
fix-release-list-stream

Conversation

@elliotmatson

Copy link
Copy Markdown
Owner

Problem

On v0.6.0-b2, every development-channel update check fails:

E findFirmwareRelease: Could not parse release list: IncompleteInput

NetworkClientSecure::read(buf, n) returns -1 whenever no decrypted data is ready yet, and NetworkClient::readBytes() takes -1 as an error and stops. ArduinoJson reads through readBytes(), so the 52 KB release list ends at the first pause. At boot the check runs while telemetry's TLS connection is opening, so it failed on every boot (3 of 3 here). The same JSON parses fine on the host.

Fix

lib/cube_utils/waiting_stream.h: a Stream wrapper that overrides only the single-byte read(), so Stream::readBytes() (which retries until the client's timeout) is used. Applied to the release-list parse and to the Weather pattern, which parsed the same way. The firmware download loop already waits on available() and is unchanged.

Tested on the cube

  • Wiped, flashed v0.4.11: its updater picked up v0.6.0-b2 (esp32s3.bin), installed and confirmed it; settings imported; telemetry connected.
  • v0.6.0-b2 then failed the release check on 3 of 3 boots.
  • This branch, built as v0.6.0-b1 and flashed over USB twice: both boots found v0.6.0-b2 and installed it, with telemetry connecting at the same moment.

Cubes already on v0.6.0-b2 need a manual update (upload card or ArduinoOTA) to get past this, since their own check can't see newer releases.

🤖 Generated with Claude Code

NetworkClientSecure::read(buf, n) returns -1 whenever no decrypted data
is ready yet, and NetworkClient::readBytes() treats that as an error and
stops. ArduinoJson reads through readBytes(), so the GitHub release list
(52 KB on the development channel) ended at the first pause and every
check failed with IncompleteInput -- at boot, with telemetry's TLS
connection opening alongside, on every boot. A cube on v0.6.0-b2's
development channel could never see a newer release.

WaitingStream exposes only the single-byte read(), so Stream's own
readBytes(), which retries until the timeout, is used. The Weather
pattern parsed the same way and gets the same wrapper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

Tests

124/124 passed.

Suite Tests Passed Failed Time
native:test_firmware_image 14 14 0 10.54s
native:test_pong 6 6 0 0.76s
native:test_remote 7 7 0 0.99s
native:test_rubiks 7 7 0 0.59s
native:test_timezones 5 5 0 0.59s
native:test_sand 6 6 0 0.58s
native:test_bounce 6 6 0 0.58s
native:test_maze 4 4 0 0.59s
native:test_cube_geometry 22 22 0 0.72s
native:test_life 7 7 0 0.59s
native:test_noise 5 5 0 0.71s
native:test_breakout 6 6 0 0.58s
native:test_wordclock 5 5 0 0.57s
native:test_color 6 6 0 0.60s
native:test_langton 5 5 0 0.58s
native:test_particles 7 7 0 0.60s
native:test_weather 6 6 0 0.66s

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

Static analysis

No defects found.

pio check, failing on high and above. 1 defect in downloaded dependencies withheld; pass include-dependencies to see them.

@elliotmatson
elliotmatson merged commit ec0c25b into main Oct 4, 2026
6 checks passed
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

Firmware size

+93.9 KB across 1 environment.

Env Image Δ App partition Flash Δ RAM Δ
esp32-s3-devkitc-1 ⚠️ 1.89 MB +93.9 KB 23.6% → 24.81% +93.8 KB +145.4 KB
esp32-s3-devkitc-1 — 9 section(s) changed
Section Base Head Δ
.flash.text 1.17 MB 1.24 MB +76.6 KB
.ext_ram.dummy 1.75 MB 1.81 MB +64.0 KB
.flash_rodata_dummy 1.19 MB 1.25 MB +64.0 KB
.flash.rodata 517.6 KB 534.3 KB +16.7 KB
.dram0.dummy 87.5 KB 88.0 KB +512 B
.iram0.text 102.4 KB 102.9 KB +488 B
.dram0.bss 37.8 KB 37.9 KB +184 B
.iram0.text_end 61 B 85 B +24 B
.dram0.data 23.8 KB 23.8 KB +16 B
esp32-s3-devkitc-1 — 560 symbol(s) changed
Symbol Base Head Δ
esp_mqtt_task 0 B 4.5 KB +4.5 KB
Telemetry::publishBoot() 0 B 2.8 KB +2.8 KB
Telemetry::publishCrash(bool) 0 B 2.8 KB +2.8 KB
Telemetry::scanInto(ArduinoJson::V743PB22::JsonArray, int) 0 B 2.1 KB +2.1 KB
esp_mqtt_set_config 0 B 2.0 KB +2.0 KB
_ZNK11ArduinoJson8V743PB226detail11VariantData6acceptINS1_14JsonSerializerINS1_6WriterI6StringvEEEEEENT_11result_typeERS9_PKNS1_15ResourceManagerE$isra$0 1.5 KB 3.4 KB +2.0 KB
Telemetry::publishSettings() 0 B 1.9 KB +1.9 KB
ArduinoJson::V743PB22::DeserializationError::Code ArduinoJson::V743PB22::detail::JsonDeserializer<ArduinoJson::V743PB22::detail::Reader<WaitingStream, void> >::parseObject<ArduinoJson::V743PB22::DeserializationOption::Filter>(ArduinoJson::V743PB22::detail::ObjectData&, ArduinoJson::V743PB22::DeserializationOption::Filter, ArduinoJson::V743PB22::DeserializationOption::NestingLimit) 0 B 1.6 KB +1.6 KB
ws_read 0 B 1.5 KB +1.5 KB
Telemetry::publishLocation() 0 B 1.5 KB +1.5 KB
tcp_connect 638 B 2.0 KB +1.4 KB
Telemetry::publishHealth() 0 B 1.4 KB +1.4 KB
Telemetry::publishNetwork() 0 B 1.3 KB +1.3 KB
Telemetry::publishUsage() 0 B 1.3 KB +1.3 KB
ws_connect 0 B 1.2 KB +1.2 KB
+545 more

Baseline: 79ea3f8. Image size is firmware.bin against the smaller app partition slot. RAM is static allocation only — the linker cannot see heap or stack.

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