<feed xmlns='http://www.w3.org/2005/Atom'>
<title>luke/esp32-poe-scrypted-viewport/main/ota.c, branch v1.4.0</title>
<subtitle>ESP32-POE Scrypted viewport (private)
</subtitle>
<id>https://src.nth.io/luke/esp32-poe-scrypted-viewport/atom?h=v1.4.0</id>
<link rel='self' href='https://src.nth.io/luke/esp32-poe-scrypted-viewport/atom?h=v1.4.0'/>
<link rel='alternate' type='text/html' href='https://src.nth.io/luke/esp32-poe-scrypted-viewport/'/>
<updated>2026-07-17T23:56:03+00:00</updated>
<entry>
<title>main: code-review fixes — brightness units, OTA stall cap, stats + locking</title>
<updated>2026-07-17T23:56:03+00:00</updated>
<author>
<name>Luke Hoersten</name>
<email>luke@hoersten.org</email>
</author>
<published>2026-07-17T23:56:03+00:00</published>
<link rel='alternate' type='text/html' href='https://src.nth.io/luke/esp32-poe-scrypted-viewport/commit/?id=9d94f710f7b00d109bf6f6ee57996f43bce5c67f'/>
<id>urn:sha1:9d94f710f7b00d109bf6f6ee57996f43bce5c67f</id>
<content type='text'>
- display: s_last_pwm cached the raw 0-100 percentage at init but
  display_wake writes it straight to REG_PWM (0-255 duty) — first wake
  ran visibly dim until a /config brightness change. Shared pct_to_duty
  helper now converts in both paths.
- http_api: cap consecutive OTA recv timeouts (a stalled client spun
  forever holding s_ota_in_progress, wedging OTA until reboot); cap
  viewport name at 54 chars so viewport-&lt;name&gt; fits the 63-byte mDNS
  label; log mdns_service_refresh failures; /state builds JSON from a
  snapshot instead of holding the state lock across ~25 cJSON allocs;
  respond_400 delegates to respond_status.
- stream_server: bytes_in_window now counts painted frames only (frames
  discarded while asleep inflated the first post-wake window's MB/s,
  avg-jpeg and chunk/wire averages; recv_bytes folded in); so_rcvbuf
  carried into the stats snapshot under the mux; drop dead HEADER_BYTES;
  merge read_body_instrumented into read_n.
- state_machine: transition mutex serializes concurrent wake/sleep
  (display side-effects ran after the state lock dropped, so racing
  callers could leave the backlight contradicting st-&gt;state); wake-path
  placeholder paint now takes the decoder lock like the stream path
  (concurrent esp_lcd_panel_draw_bitmap from two tasks isn't safe).
- local_screens: overlay paint takes the decoder lock too; check the
  overlay timer create; panel dims from viewport_state.h.
- jpeg_decoder: try_lock before init returns busy instead of passing a
  NULL semaphore to xSemaphoreTake.
- net_eth: clear cached IP string on link down (stale /state + info).
- dead code: display_present_bgr888, TOUCH_FT5426_ADDR, touch s_task,
  JPEG_DECODER_MAX_OUTPUT_BYTES; doc drift in nvs_config.h /
  jpeg_decoder.h / app_main flag legend.
</content>
</entry>
<entry>
<title>firmware: OTA firmware updates via POST /firmware + rollback</title>
<updated>2026-06-20T18:03:23+00:00</updated>
<author>
<name>Luke Hoersten</name>
<email>luke@hoersten.org</email>
</author>
<published>2026-06-20T18:03:23+00:00</published>
<link rel='alternate' type='text/html' href='https://src.nth.io/luke/esp32-poe-scrypted-viewport/commit/?id=175dd50ba2a2a6c8d033a9fd4e91f4823f9e210a'/>
<id>urn:sha1:175dd50ba2a2a6c8d033a9fd4e91f4823f9e210a</id>
<content type='text'>
Streams the raw .bin to the inactive ota_0/ota_1 slot via esp_ota_*, flips otadata, replies 200, reboots after 500 ms. Single-shot guarded by atomic_flag (409 on concurrent). CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE armed: new images boot pending-verify and ota_arm_healthy_timer marks them valid after 30 s of healthy uptime; otherwise the bootloader reverts on next reset. /state gains ota_state.
</content>
</entry>
</feed>
