updated tdd for http client
This commit is contained in:
@@ -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*
|
||||
|
||||
Reference in New Issue
Block a user