Commit Graph

3 Commits

Author SHA1 Message Date
David Montero bb4d06cc7a fix(picow): make the IoT gateway robust to real browsers
Two real-world failures hit the Pico W gateway that the headless e2e
(node fetch, tiny request, fast timing) didn't surface:

- A browser sends KILOBYTES of headers (cookies, User-Agent, sec-*).
  Forwarded verbatim, the request overran the chip's small recv()
  (e.g. recv(1024)); lwIP then RST the connection on close-with-unread-
  data, crashing blocking-socket sketches with ECONNRESET. Now we forward
  a MINIMAL request (method, path, Host, Connection: close, and
  Content-Type/Length for bodies) — nothing a tiny server can choke on.

- After a gateway request completed we dropped the connection immediately,
  so a late chip segment (retransmitted FIN / trailing ACK) no longer
  matched and fell through to the chip-initiated NAT, which RST it. Add a
  short TIME_WAIT: keep the connection briefly and re-ACK late segments so
  the chip closes cleanly, never RSTing it.
2026-06-14 03:11:54 +02:00
David Montero 173cc3ea36 feat(picow): IoT gateway — proxy browser HTTP into the chip's server
ESP32 web-server examples are reachable from the browser via
/api/gateway/<client_id>/ (QEMU slirp hostfwd). The Pico W server lives
in the browser-side lwIP, so there was no inbound path: visiting the
chip's IP did nothing.

Add the mirror of tcp_nat.py: tcp_inbound.TcpInbound originates a TCP
connection INTO the chip over the WebSocket bridge (SYN -> SYN+ACK ->
ACK -> request -> response -> FIN), so the backend can fetch a page the
sketch serves on 10.13.37.42:80 and hand it back to the browser.

- bridge.py routes chip TCP segments addressed to a gateway-opened
  connection to TcpInbound (before the chip-initiated NAT, which would
  RST them); exposes http_into_chip() + ensure_chip_mac() (primes the
  chip's gateway ARP).
- iot_gateway.py: same /api/gateway/<client_id>/ route now falls through
  to the Pico W bridge when there's no ESP32 instance, builds a raw
  HTTP/1.1 request, and parses the chip's response. Same plan gate, same
  URL shape — the browser sees no difference between ESP32 and Pico W.

Validated end to end (real RP2040 emulator serving an HTTP page ->
gateway returns it) plus 6 unit tests for the TCP state machine,
response parsing and ARP priming.
2026-06-14 02:15:53 +02:00
David Montero Crespo 89c9d7c6c6 Implement TCP and UDP NAT services for chip-initiated connections
- Added tcp_nat.py to handle TCP NAT, implementing the three-way handshake, data flow, and connection state management.
- Introduced udp_nat.py for UDP NAT, managing chip-initiated datagrams and maintaining flow state.
- Created integration tests in test_picow_net_bridge.py to validate the functionality of the TCP and UDP NAT implementations, including ARP, DHCP, ICMP, and DNS interactions.
2026-04-29 08:43:41 -03:00