- Fix Bytes({key_int}) bug in LXMessage::unpack_from_bytes() that caused
incoming field keys to be empty, making fields_get() always miss
- Telemetry-only messages (fields present, no body) now skip chat bubble,
notification sound, and message store entirely
- Implement position_peer_markers() with proper lat/lon to screen coords
- Add display name resolution for map markers via recall_app_data()
- Store peer locations for repositioning on pan/zoom
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three bugs prevented Pyxis telemetry from appearing on Columba's map:
1. Bytes({0x02}) called Bytes(size_t capacity=2) instead of creating a
1-byte buffer containing 0x02. Both field keys were empty, so the
second fields_set() overwrote the first — FIELD_TELEMETRY was missing
from the wire payload. Fixed with Bytes(&key, 1).
2. FIELD_COLUMBA_META was encoded as msgpack but Columba expects JSON
(json.loads after .decode('utf-8')). Changed to manual JSON string.
3. expires was sent as Unix seconds but Columba compares against
System.currentTimeMillis() (milliseconds). Locations were immediately
deleted as expired. Now sends expires_ms = end_time * 1000.
Also: set OPPORTUNISTIC delivery method on telemetry/cease messages,
add pyxis_log() diagnostics for telemetry pipeline, and manage tile
download task lifecycle (start on show, stop on hide).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Route mbedtls allocations to PSRAM via mbedtls_platform_set_calloc_free()
to fix TLS handshake failure (-32512 SSL alloc) with only ~36KB internal heap
- Use WiFiClientSecure with setInsecure() for HTTPS tile downloads from OSM
- Move tile downloads to background FreeRTOS task to avoid blocking UI thread
- Add incremental tile loading (one PNG decode per update cycle) to prevent
LVGL mutex timeout from decoding 4 tiles synchronously
- Enable LVGL image cache (LV_IMG_CACHE_DEF_SIZE=8) so decoded PNGs stay
in PSRAM and don't re-decode on every redraw
- Add touch drag panning for map navigation via LV_EVENT_PRESSING
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TileDownloader fetches OSM raster tiles over HTTPS when not found
on SD card, saves them for permanent offline cache. MapScreen calls
ensure_tile() before each LVGL load — tiles download once, then
load from SD on subsequent views.
Default tile server: tile.openstreetmap.org (configurable via
set_tile_url). Proper User-Agent set per OSM usage policy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>