upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/PRICING_DISCOVERY_PLAN.md
diff options
context:
space:
mode:
Diffstat (limited to 'PRICING_DISCOVERY_PLAN.md')
-rw-r--r--PRICING_DISCOVERY_PLAN.md79
1 files changed, 79 insertions, 0 deletions
diff --git a/PRICING_DISCOVERY_PLAN.md b/PRICING_DISCOVERY_PLAN.md
new file mode 100644
index 0000000..3cf7742
--- /dev/null
+++ b/PRICING_DISCOVERY_PLAN.md
@@ -0,0 +1,79 @@
1# Price Discovery — Two-Board Cross-Discovery Plan
2
3## Goal
4
5Get `test-price-discovery.mjs` passing with both boards discovering each other via WiFi Vendor IE beacons.
6
7## Root Cause
8
9Cross-discovery never worked because of two compounding issues:
10
111. **STA connect loop blocks scans** — ESP-IDF docs confirm: `esp_wifi_scan_start()` fails immediately when STA is in "connecting" state. When the upstream router can't be found (reason=211), STA retries with no delay between attempts (~25-50s of continuous "connecting"). Market scanner can never start a scan during this window.
12
132. **Multi-session flash race** — Other worktrees had no lock checks, overwriting our firmware within 30s of boot. Now fixed.
14
15## Phases
16
17### Phase 1: Firmware fixes (no hardware needed)
18
19- [x] 1a. Add 2s delay before `esp_wifi_connect()` in disconnect handler (creates scan window)
20- [x] 1b. Guard `WIFI_EVENT_STA_START` against double-connect during retry loop
21- [x] 1c. Add `write-config-ap-only-a/b` Makefile targets (no `wifi_networks` in config)
22- [x] 1d. Update `test-price-discovery.mjs` with correct Board B IP
23- [x] 1e. Run `make test-unit` — must pass
24
25### Phase 2: Flash and verify both boards (hardware needed)
26
27- [x] 2a. Acquire locks on both boards (`make lock-a`, `make lock-b`)
28- [x] 2b. Build firmware (`make build`)
29- [x] 2c. Flash Board A with AP-only config (`make write-config-ap-only-a && make flash-a`)
30- [x] 2d. Flash Board B with AP-only config (`make write-config-ap-only-b && make flash-b`)
31- [x] 2e. Verify serial: both boards show AP services started, beacon IE injected, market initialized
32- [x] 2f. Wait 60s for scan cycle, verify `GET /market` returns valid JSON on both boards
33
34### Phase 3: Cross-discovery test (hardware needed)
35
36- [x] 3a. Verify Board A `/market` shows Board B entry (BSSID `3A:2A:EB:C0:E9:CA`, SSID TollGate-C0E9CA)
37- [x] 3b. Verify Board B `/market` shows Board A entry (BSSID `FE:08:F7:B9:6D:80`, SSID TollGate-B96D80)
38- [x] 3c. Run `test-price-discovery.mjs` — 7/7 passed (per board, sequential due to single WiFi adapter)
39- [x] 3d. Run `test-market.mjs` on both boards — 9/9 passed on both
40
41### Phase 4: STA-connected test (stretch, hardware + upstream router needed)
42
43- [ ] 4a. Flash with STA config (`write-config-a/b`)
44- [ ] 4b. Verify STA connects to upstream router
45- [ ] 4c. Verify cross-discovery still works with STA connected (background scan)
46- [ ] 4d. Run full test suite
47
48## Risk: vendor_ie_cb may not fire during scan
49
50**CONFIRMED: vendor_ie_cb fires during passive scan.** No fallback needed.
51
52Both boards successfully receive Vendor IEs from the other board's beacon frames during passive WiFi scan. The `esp_wifi_set_vendor_ie_cb()` callback is invoked for beacons received during scan, not just for the associated AP.
53
54## Results
55
56| Test | Result |
57|------|--------|
58| `make test-unit` | 17/17 passed |
59| `idf.py build` | Pass |
60| `test-market.mjs` Board A | 9/9 passed |
61| `test-market.mjs` Board B | 9/9 passed |
62| `test-price-discovery.mjs` Board A | 7/7 passed |
63| `test-price-discovery.mjs` Board B | 7/7 passed |
64
65### Cross-Discovery Data
66
67| Board | Sees | BSSID | SSID | RSSI | Price |
68|-------|------|-------|------|------|-------|
69| A (10.185.47.1) | Board B | `3A:2A:EB:C0:E9:CA` | TollGate-C0E9CA | -30 | 21 sats/step |
70| B (10.192.45.1) | Board A | `FE:08:F7:B9:6D:80` | TollGate-B96D80 | -25 | 21 sats/step |
71
72## Key Technical Details
73
74- **Vendor IE OUI:** `0xC0, 0xFF, 0xEE`
75- **IE type:** `0x01`
76- **Payload:** 26-byte packed struct (version, metric, price, step, mint_hash, geohash, npub_hash)
77- **Scan config:** passive, 120ms/channel, all channels
78- **Self-filter:** `npub_hash` comparison avoids processing own beacons
79- **AP-only mode:** No `wifi_networks` in config → STA never connects → scans always work