updated tdd for http client

This commit is contained in:
2026-03-28 15:38:38 -04:00
parent 2ced2f0b0a
commit e5b72bbb20
+52 -8
View File
@@ -168,16 +168,34 @@ menu "Calendink Client"
endmenu
```
#### main.cpp Test Flow
#### Client File Structure
After WiFi connects successfully:
Provider communication logic is in its own file, not in `main.cpp`:
```
1. Resolve Provider IP via mdns_query_host("calendink", timeout)
- On success: use resolved IP
- On failure: fall back to CONFIG_CALENDINK_PROVIDER_FALLBACK_IP if set, else abort
Client/main/
├── CMakeLists.txt # SRCS: main.cpp, provider.cpp
├── Kconfig.projbuild # Provider connection settings
├── idf_component.yml # Dependencies: network, led, http_client, espressif/mdns
├── main.cpp # Boot, NVS, WiFi connect → calls test_provider_communication()
├── provider.hpp # Header for provider communication
└── provider.cpp # mDNS resolution, device registration, screen fetch
```
2. Get own MAC: esp_wifi_get_mac(WIFI_IF_STA, mac_bytes) → format "XX:XX:XX:XX:XX:XX"
#### provider.cpp Test Flow
After network connects (WiFi or Ethernet):
```
1. Resolve Provider IP via mdns_query_a("calendink", 5000, &addr)
- On success: use resolved IP
- On failure: runtime check strlen(CONFIG_CALENDINK_PROVIDER_FALLBACK_IP) > 0
- If set: use fallback IP
- If empty: abort with error log
2. Get own MAC via get_mac_address(mac_bytes) from the network component
- Returns Ethernet MAC if connected via Ethernet, WiFi MAC if via WiFi
- Format as "XX:XX:XX:XX:XX:XX"
3. POST /api/devices/register
- Body: {"mac": "XX:XX:XX:XX:XX:XX"}
@@ -185,17 +203,22 @@ After WiFi connects successfully:
- Free response
4. GET /api/devices/screen.png?mac=XX:XX:XX:XX:XX:XX
- Download full PNG into memory
- Log: status code + received byte count
- Free response (we don't use the image data yet)
- Free response
```
#### Dependencies Added to Client
| File | Change |
|---|---|
| `Client/main/idf_component.yml` | Add `http_client: path: "../../components/http_client"` |
| `Client/main/idf_component.yml` | Add `http_client` (local path) + `espressif/mdns: ^1.4.1` (managed) |
| `Client/main/CMakeLists.txt` | Add `http_client` and `mdns` to `PRIV_REQUIRES` |
#### Network Component Changes
`get_mac_address(uint8_t *mac_out)` was added to `network.hpp` / `network.cpp`. It uses `esp_netif_get_mac()` on whichever interface is active — Ethernet preferred, WiFi fallback. This keeps all `esp_wifi` usage inside the network component.
### 3.5. Component Build Configuration
```cmake
@@ -232,5 +255,26 @@ Error: 400 if missing mac param, 404 if device not registered, 500 on render
We add a new shared component `http_client` that wraps `esp_http_client` in a simple synchronous API with `http_get_text()`, `http_get_binary()`, and `http_post_json()`. The component is generic — it takes host/port/path and knows nothing about mDNS or Kconfig. The Client firmware integrates it by resolving the Provider via mDNS (`calendink.local`), registering itself, and fetching its screen image as a connectivity test. No Provider-side changes are needed.
## 5. Implementation Notes (Post-Development)
### Decisions Made During Implementation
1. **File separation** — Provider communication logic was extracted from `main.cpp` into `provider.cpp`/`provider.hpp` to keep `main.cpp` focused on boot/init (~78 lines). This follows the pattern of keeping `main` lean.
2. **Fallback IP check** — The original plan used a `#if` preprocessor check to test if the fallback IP string was non-empty. This doesn't work because Kconfig string values can't be indexed in preprocessor expressions. Changed to a runtime `strlen()` check, which the compiler optimizes away when the string is a compile-time constant.
3. **Interface-agnostic MAC**`get_mac_address()` was added to the `network` component using `esp_netif_get_mac()` (instead of `esp_wifi_get_mac()`). It checks `s_eth_netif` first, then `s_wifi_netif`, making it work for both Ethernet and WiFi connections without the caller needing to know which is active.
4. **mDNS as managed component** — The Client uses `espressif/mdns: ^1.4.1` from the ESP-IDF component registry (specified in `idf_component.yml`) rather than a local path, since it's an official Espressif component.
5. **No `esp_wifi` in Client** — The Client project has no direct dependency on `esp_wifi`. All WiFi/Ethernet access goes through the `network` component. This was a deliberate architectural decision to keep the Client decoupled from transport details.
### Verified On-Device
- mDNS resolution of `calendink.local` → Provider IP ✅
- `POST /api/devices/register` → 200 with device MAC ✅
- `GET /api/devices/screen.png?mac=XX` → 200 with PNG binary data ✅
---
*Created by Antigravity (Claude Opus 4.6) - 2026-03-28*
*Updated: 2026-03-28 — Post-implementation notes added*