upleb.uk

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

summaryrefslogtreecommitdiff
path: root/main/tollgate_api.c
diff options
context:
space:
mode:
authorYour Name <you@example.com>2026-05-19 13:14:48 +0530
committerYour Name <you@example.com>2026-05-19 13:14:48 +0530
commitfe6aa9663d4cdabdc6e71db6068f8cd9e3739ffe (patch)
tree8cadb07243c07a6b3fa9453b239c9ac5cb02b454 /main/tollgate_api.c
parent77031f06a9a87320d011f501590985161d1eb305 (diff)
feat: WiFi beacon price discovery via Vendor IE (two-board verified)
Price discovery allows TollGate ESP32 boards to advertise their per-step price via WiFi Vendor-Specific Information Elements (OUI 0xC0FFEE) in beacon and probe response frames. Nearby boards passively scan and build a market view of competing TollGates without requiring internet access. Features: - beacon_price.c/h: 26-byte packed Vendor IE payload (price, step, metric, mint_hash, geohash, npub_hash), injected via esp_wifi_set_vendor_ie() - market.c/h: Passive WiFi scan receiver, vendor IE callback parsing, BSSID-correlated market entries, effective price ranking - GET /market API endpoint: JSON market snapshot with discovered entries - AP-only services: beacon + market + API start on WIFI_EVENT_AP_START, independent of STA connectivity - STA reconnect fix: 2s delay between retries creates scan windows; s_sta_connecting guard prevents double-connect - write-config-ap-only-a/b Makefile targets for STA-less testing - market_tick() in main loop, client price comparison logging Hardware verified: both boards discover each other via Vendor IE beacons. Board A sees TollGate-C0E9CA (RSSI=-30), Board B sees TollGate-B96D80 (RSSI=-25). test-market.mjs: 9/9, test-price-discovery.mjs: 7/7 per board. Unit tests: 45 new assertions across test_beacon_price (28) and test_market (17). All 15 test suites pass. ESP-IDF build clean for ESP32-S3.
Diffstat (limited to 'main/tollgate_api.c')
-rw-r--r--main/tollgate_api.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/main/tollgate_api.c b/main/tollgate_api.c
index 650b0f3..15640c7 100644
--- a/main/tollgate_api.c
+++ b/main/tollgate_api.c
@@ -4,7 +4,10 @@
4#include "session.h" 4#include "session.h"
5#include "firewall.h" 5#include "firewall.h"
6#include "nucula_wallet.h" 6#include "nucula_wallet.h"
7#include "mint_health.h"
8#include "market.h"
7#include "esp_log.h" 9#include "esp_log.h"
10#include "esp_system.h"
8#include "cJSON.h" 11#include "cJSON.h"
9#include "lwip/sockets.h" 12#include "lwip/sockets.h"
10#include "lwip/netdb.h" 13#include "lwip/netdb.h"
@@ -471,6 +474,45 @@ static const httpd_uri_t uri_wallet = { .uri = "/wallet", .method = HTTP_GET, .h
471static const httpd_uri_t uri_wallet_swap = { .uri = "/wallet/swap", .method = HTTP_POST, .handler = api_post_wallet_swap }; 474static const httpd_uri_t uri_wallet_swap = { .uri = "/wallet/swap", .method = HTTP_POST, .handler = api_post_wallet_swap };
472static const httpd_uri_t uri_wallet_send = { .uri = "/wallet/send", .method = HTTP_POST, .handler = api_post_wallet_send }; 475static const httpd_uri_t uri_wallet_send = { .uri = "/wallet/send", .method = HTTP_POST, .handler = api_post_wallet_send };
473 476
477static esp_err_t api_get_market(httpd_req_t *req)
478{
479 const market_t *mkt = market_get();
480
481 cJSON *root = cJSON_CreateObject();
482 cJSON_AddNumberToObject(root, "count", mkt->count);
483 cJSON_AddNumberToObject(root, "last_scan_s", (double)(mkt->last_scan_ms / 1000));
484
485 cJSON *entries = cJSON_CreateArray();
486 for (int i = 0; i < MARKET_MAX_ENTRIES; i++) {
487 if (!mkt->entries[i].valid) continue;
488 const market_entry_t *e = &mkt->entries[i];
489
490 cJSON *entry = cJSON_CreateObject();
491 char bssid_str[18];
492 snprintf(bssid_str, sizeof(bssid_str), "%02X:%02X:%02X:%02X:%02X:%02X",
493 e->bssid[0], e->bssid[1], e->bssid[2],
494 e->bssid[3], e->bssid[4], e->bssid[5]);
495 cJSON_AddStringToObject(entry, "bssid", bssid_str);
496 cJSON_AddStringToObject(entry, "ssid", e->ssid[0] ? e->ssid : "unknown");
497 cJSON_AddNumberToObject(entry, "rssi", e->rssi);
498 cJSON_AddNumberToObject(entry, "price_per_step", e->price_per_step);
499 cJSON_AddNumberToObject(entry, "step_size", (double)e->step_size);
500 cJSON_AddStringToObject(entry, "metric", e->metric ? "bytes" : "milliseconds");
501 if (e->geohash[0]) cJSON_AddStringToObject(entry, "geohash", e->geohash);
502 cJSON_AddItemToArray(entries, entry);
503 }
504 cJSON_AddItemToObject(root, "entries", entries);
505
506 char *json = cJSON_PrintUnformatted(root);
507 httpd_resp_set_type(req, "application/json");
508 httpd_resp_send(req, json, strlen(json));
509 cJSON_free(json);
510 cJSON_Delete(root);
511 return ESP_OK;
512}
513
514static const httpd_uri_t uri_market = { .uri = "/market", .method = HTTP_GET, .handler = api_get_market };
515
474esp_err_t tollgate_api_start(void) 516esp_err_t tollgate_api_start(void)
475{ 517{
476 if (s_api_server) return ESP_OK; 518 if (s_api_server) return ESP_OK;
@@ -494,6 +536,7 @@ esp_err_t tollgate_api_start(void)
494 httpd_register_uri_handler(s_api_server, &uri_wallet); 536 httpd_register_uri_handler(s_api_server, &uri_wallet);
495 httpd_register_uri_handler(s_api_server, &uri_wallet_swap); 537 httpd_register_uri_handler(s_api_server, &uri_wallet_swap);
496 httpd_register_uri_handler(s_api_server, &uri_wallet_send); 538 httpd_register_uri_handler(s_api_server, &uri_wallet_send);
539 httpd_register_uri_handler(s_api_server, &uri_market);
497 540
498 ESP_LOGI(TAG, "TollGate API started on port 2121"); 541 ESP_LOGI(TAG, "TollGate API started on port 2121");
499 return ESP_OK; 542 return ESP_OK;