<feed xmlns='http://www.w3.org/2005/Atom'>
<title>npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/tests, branch feature/display-fix</title>
<subtitle>[no description]</subtitle>
<id>https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/atom?h=feature%2Fdisplay-fix</id>
<link rel='self' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/atom?h=feature%2Fdisplay-fix'/>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/'/>
<updated>2026-05-19T19:32:20+00:00</updated>
<entry>
<title>test: fix Playwright Layer 2 tests - all 13 passing</title>
<updated>2026-05-19T19:32:20+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-19T19:32:20+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=59ea2f02c49a3c678ecae19f55d542b7442d6f7e'/>
<id>urn:sha1:59ea2f02c49a3c678ecae19f55d542b7442d6f7e</id>
<content type='text'>
- Fix SETUP_HTML innerHTML newline syntax error (single-quoted string can't span lines)
- Fix route interception: use page.goto with http://tollgate.test/setup instead of page.setContent
- Add **/setup route for serving mock HTML
- Fix Layer 1 POST tests: handle ECONNRESET gracefully, accept any error message
- Add Layer 1.5 redirect test (needs live board)
- Add **/setup route to rescan test
- Load page with waitUntil: networkidle
</content>
</entry>
<entry>
<title>feat: web-based WiFi setup via captive portal, portrait-only display</title>
<updated>2026-05-18T22:51:14+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-18T22:51:14+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=aa58b47996083f36e3587b8e10f9bbb681610491'/>
<id>urn:sha1:aa58b47996083f36e3587b8e10f9bbb681610491</id>
<content type='text'>
- Remove touchscreen WiFi setup (touch.c, keyboard.c, wifi_setup.c from build)
- Remove offscreen buffer and landscape rotation from axs15231b driver
- Add /setup HTML page with WiFi scan/connect via captive portal
- Add /wifi/scan, /wifi/connect, /wifi/status HTTP endpoints
- Display shows SETUP_PENDING (QR + SSID + setup URL) when unconfigured
- Display shows ERROR with setup URL when upstream is down
- All 101 unit tests pass, builds and flashes to Board C
</content>
</entry>
<entry>
<title>Dynamic layout for WiFi setup: landscape rotation, responsive render, highlight feedback</title>
<updated>2026-05-18T20:14:11+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-18T20:14:11+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=58a0b5fd115d9687a1292e5e82e6b9fa8454b930'/>
<id>urn:sha1:58a0b5fd115d9687a1292e5e82e6b9fa8454b930</id>
<content type='text'>
- Render functions use axs15231b_get_width/height() instead of hardcoded coords
- render_wifi_setup_list: dynamic item widths, screen-relative cancel button
- render_wifi_setup_password: dynamic field/eye/keyboard from kb_get_layout()
- render_wifi_setup_result: centered on screen, dynamic button placement
- handle_wifi_setup_touch: matching dynamic hit areas, highlight_rect() feedback
- Rotation lifecycle: enter_wifi_setup_rotation/exit wired into all entry/exit paths
- display_enter_wifi_setup + READY/ERROR touch + SUCCESS auto-return + LIST cancel
- Added kb_result_t typedef to keyboard.h (was only in .c)
- Fixed test_keyboard.c: use computed offsets from kb_layout_t defaults
- All 101 unit tests pass (touch:19, keyboard:46, wifi_setup:36)
</content>
</entry>
<entry>
<title>fix: keyboard KB_START_Y must match render position (70), simplify row 3 layout</title>
<updated>2026-05-18T18:11:19+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-18T18:11:19+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=699fc6c03899c3b1ff853d8c7c6cf32173436354'/>
<id>urn:sha1:699fc6c03899c3b1ff853d8c7c6cf32173436354</id>
<content type='text'>
- KB_START_Y was 310 but keyboard rendered at y=70 — touch hits never matched
- Row 3 simplified to 3 keys: [layer/shift, space, done]
- All 362 unit tests pass
</content>
</entry>
<entry>
<title>feat: add WiFi setup state machine + config_add_wifi with unit tests</title>
<updated>2026-05-18T17:19:34+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-18T17:19:34+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=eb2ae72d91a4b2ec0333a2e6d18eeeeee6b60464'/>
<id>urn:sha1:eb2ae72d91a4b2ec0333a2e6d18eeeeee6b60464</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat: add on-screen keyboard with layout/hit detection tests</title>
<updated>2026-05-18T17:16:53+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-18T17:16:53+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=910fe47b2ed1284d93ff4d274f5c2341cb0d2d0b'/>
<id>urn:sha1:910fe47b2ed1284d93ff4d274f5c2341cb0d2d0b</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat: add AXS15231B touch driver with coordinate parsing tests</title>
<updated>2026-05-18T17:14:37+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-18T17:14:37+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=f2c4b15c72a2fa89caed5d8a11a4ea9832c48be6'/>
<id>urn:sha1:f2c4b15c72a2fa89caed5d8a11a4ea9832c48be6</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat: ContextVM (MCP over Nostr) server with WS masking fix</title>
<updated>2026-05-17T22:07:27+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-17T22:07:27+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=8a2f7a6c9423e0c00fae3c1233bee9e0bb3ae239'/>
<id>urn:sha1:8a2f7a6c9423e0c00fae3c1233bee9e0bb3ae239</id>
<content type='text'>
- Full CVM server: persistent WS relay listener, kind 25910 subscription
- MCP protocol handlers: initialize, tools/list, tools/call, ping
- 10 MCP tools: get_config, set_config, get_balance, wallet_send,
  get_sessions, get_usage, set_payout, set_metric, set_price, wallet_melt
- CEP-6 announcements via WS (kinds 11316, 11317, 10002)
- Auth check: owner npub only
- Fix: WebSocket client-to-server frame masking (RFC 6455 requirement)
- Fix: Raw event JSON in EVENT wrapper (no re-parsing that breaks sig)
- SNTP init after STA gets IP
- 282 unit tests passing (61 CVM + 60 MCP handler + 161 existing)
- Integration test scaffold: tests/integration/test-cvm.mjs
</content>
</entry>
<entry>
<title>refactor: reorganize test suite, add integration tests for NAT filter</title>
<updated>2026-05-17T11:48:43+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-17T11:48:43+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=8071741815f0b0938701e80a63e80b0ec94b2778'/>
<id>urn:sha1:8071741815f0b0938701e80a63e80b0ec94b2778</id>
<content type='text'>
- Move integration tests (api, network, phase2, smoke) to tests/integration/
- Move Playwright specs (captive-portal, interop-happy-path) to tests/e2e/
- Move playwright.config.mjs to tests/e2e/
- Fix hardcoded IP fallbacks: 192.168.4.1 → 10.192.45.1
- Add test-reset-auth.mjs: reset→pay→allow→revoke→block cycle
- Add test-session-expiry.mjs: pay→wait 65s→verify blocked (slow test)
- Add test-dns-firewall.mjs: DNS hijack/forward + per-client NAT filter
- Update Makefile with test-unit, test-integration, test-e2e, test-all targets
- Update package.json scripts for new paths
- Fix Playwright video: retain-on-failure instead of always-on
- Update AGENTS.md: per-client NAT filter description
- Update CHECKLIST.md: mark completed items, add Board B identity
- Board B nsec: 9af47906... → SSID TollGate-b96d80, AP IP 10.185.47.1
- 186 unit tests passing
</content>
</entry>
<entry>
<title>feat: per-client NAT filtering via LWIP_HOOK_IP4_CANFORWARD</title>
<updated>2026-05-17T11:09:31+00:00</updated>
<author>
<name>Your Name</name>
<email>you@example.com</email>
</author>
<published>2026-05-17T11:09:31+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub12m5exm2uk3xa674cc5r0hlyvccs5xxn7qv83ezuteefv5972nquq4j4szl/esp32-tollgate/commit/?id=0c2c67b463d6a90aaa0bb69bf3c91dba1d9ec3ec'/>
<id>urn:sha1:0c2c67b463d6a90aaa0bb69bf3c91dba1d9ec3ec</id>
<content type='text'>
- Add lwip_tollgate_hooks.h defining LWIP_HOOK_IP4_CANFORWARD macro
- Inject hook into lwIP build via CMakeLists.txt ESP_IDF_LWIP_HOOK_FILENAME
- Filter forwarded packets by source IP against firewall allowed list
- Only filter packets from AP subnet (10.192.45.0/24), allow all others
- Fix byte order bug: use network byte order for firewall_is_client_allowed
- NAT always enabled, removed global NAT toggle functions
- Remove spent-secret tracking from session.c (mint is authority)
- Remove unused get_ap_netif() function
- Reduce API server stack from 32KB to 16KB (fixes ESP_ERR_HTTPD_TASK)
- Add esp_random.h stub for unit tests
- All 186 unit tests passing
- Verified on hardware: block-&gt;pay-&gt;allow-&gt;revoke-&gt;block E2E works
</content>
</entry>
</feed>
