diff options
| author | Your Name <you@example.com> | 2026-05-16 11:56:43 +0530 |
|---|---|---|
| committer | Your Name <you@example.com> | 2026-05-16 11:56:43 +0530 |
| commit | 38aa9ec3801f5895e09866fe92cb8e44fb987cee (patch) | |
| tree | c702c27cd59fa0e73bc3e8665e1582e6b9509cf6 /main | |
| parent | ee4e13680f522253f94e8ebdea5df80332afc495 (diff) | |
Unique SSID/IP per board + captive detection fix + mint list in portal
- Derive unique SSID (TollGate-{MAC4}{MAC5}) and AP IP (10.{b5}.{subnet}.1)
from factory MAC — boards no longer conflict
- Board A: TollGate-377C @ 10.55.85.1, Board B: TollGate-5050 @ 10.80.10.1
- Captive portal detection URIs return 200 with portal HTML (matching
esp32-mesh working approach) instead of 302 redirect
- Dynamic AP IP in portal HTML via __AP_IP__ template substitution
- Supported mints section in portal page (shows mint URL, tap to copy)
- Fixed mint URL to testnut.cashu.space (was stale in SPIFFS)
- DoT reject server on port 853 for DNS-over-TLS fallback
- DNS hijack: NXDOMAIN for all non-A queries, no forwarding for unauthed
- Playwright tests updated for 200 response on detection URIs
- Phase 2 test suite: 20/21 pass (test 22 expiry ping route issue)
- Tests 25-27 deferred to Phase 3 (Board B as second client)
Diffstat (limited to 'main')
| -rw-r--r-- | main/captive_portal.c | 104 | ||||
| -rw-r--r-- | main/captive_portal.h | 2 | ||||
| -rw-r--r-- | main/config.c | 26 | ||||
| -rw-r--r-- | main/config.h | 9 | ||||
| -rw-r--r-- | main/tollgate_main.c | 22 |
5 files changed, 123 insertions, 40 deletions
diff --git a/main/captive_portal.c b/main/captive_portal.c index 0ae46ab..1f7340e 100644 --- a/main/captive_portal.c +++ b/main/captive_portal.c | |||
| @@ -11,8 +11,9 @@ | |||
| 11 | 11 | ||
| 12 | static const char *TAG = "captive_portal"; | 12 | static const char *TAG = "captive_portal"; |
| 13 | static httpd_handle_t s_server = NULL; | 13 | static httpd_handle_t s_server = NULL; |
| 14 | static char s_ap_ip_str[16] = "10.0.0.1"; | ||
| 14 | 15 | ||
| 15 | static const char PORTAL_HTML[] = \ | 16 | static const char PORTAL_HTML_TEMPLATE[] = \ |
| 16 | "<!DOCTYPE html>" | 17 | "<!DOCTYPE html>" |
| 17 | "<html><head>" | 18 | "<html><head>" |
| 18 | "<meta charset='utf-8'>" | 19 | "<meta charset='utf-8'>" |
| @@ -27,9 +28,15 @@ static const char PORTAL_HTML[] = \ | |||
| 27 | "max-width:400px;width:100%;text-align:center}" | 28 | "max-width:400px;width:100%;text-align:center}" |
| 28 | "h1{font-size:28px;margin-bottom:8px;color:#f7931a}" | 29 | "h1{font-size:28px;margin-bottom:8px;color:#f7931a}" |
| 29 | ".subtitle{color:#888;margin-bottom:24px;font-size:14px}" | 30 | ".subtitle{color:#888;margin-bottom:24px;font-size:14px}" |
| 30 | ".price{background:#252525;border-radius:12px;padding:16px;margin-bottom:24px}" | 31 | ".price{background:#252525;border-radius:12px;padding:16px;margin-bottom:16px}" |
| 31 | ".price-amount{font-size:36px;font-weight:bold;color:#f7931a}" | 32 | ".price-amount{font-size:36px;font-weight:bold;color:#f7931a}" |
| 32 | ".price-unit{color:#888;font-size:14px}" | 33 | ".price-unit{color:#888;font-size:14px}" |
| 34 | ".mints{background:#252525;border-radius:12px;padding:12px;margin-bottom:16px;text-align:left}" | ||
| 35 | ".mints-title{color:#888;font-size:12px;margin-bottom:8px}" | ||
| 36 | ".mint-url{font-family:monospace;font-size:11px;color:#f7931a;word-break:break-all;" | ||
| 37 | "background:#1a1a1a;padding:8px;border-radius:6px;position:relative;cursor:pointer}" | ||
| 38 | ".mint-url:active{opacity:0.7}" | ||
| 39 | ".mint-hint{color:#666;font-size:10px;margin-top:4px}" | ||
| 33 | "#status{margin-top:16px;padding:12px;border-radius:8px;display:none;font-size:14px}" | 40 | "#status{margin-top:16px;padding:12px;border-radius:8px;display:none;font-size:14px}" |
| 34 | "#status.success{display:block;background:#1a472a;color:#4caf50}" | 41 | "#status.success{display:block;background:#1a472a;color:#4caf50}" |
| 35 | "#status.error{display:block;background:#471a1a;color:#f44336}" | 42 | "#status.error{display:block;background:#471a1a;color:#f44336}" |
| @@ -49,6 +56,11 @@ static const char PORTAL_HTML[] = \ | |||
| 49 | "<div class='price-amount' id='price'>Loading...</div>" | 56 | "<div class='price-amount' id='price'>Loading...</div>" |
| 50 | "<div class='price-unit'>sats per minute</div>" | 57 | "<div class='price-unit'>sats per minute</div>" |
| 51 | "</div>" | 58 | "</div>" |
| 59 | "<div class='mints'>" | ||
| 60 | "<div class='mints-title'>SUPPORTED MINTS</div>" | ||
| 61 | "<div class='mint-url' id='mintUrl' onclick='copyMint()'>Loading...</div>" | ||
| 62 | "<div class='mint-hint'>Tap to copy • Mint tokens at this URL before paying</div>" | ||
| 63 | "</div>" | ||
| 52 | "<textarea id='tokenInput' placeholder='Paste your Cashu token here (cashuA...)'></textarea>" | 64 | "<textarea id='tokenInput' placeholder='Paste your Cashu token here (cashuA...)'></textarea>" |
| 53 | "<button class='btn' id='payBtn' onclick='payToken()'>Pay & Connect</button>" | 65 | "<button class='btn' id='payBtn' onclick='payToken()'>Pay & Connect</button>" |
| 54 | "<div id='status'></div>" | 66 | "<div id='status'></div>" |
| @@ -58,16 +70,25 @@ static const char PORTAL_HTML[] = \ | |||
| 58 | "const statusEl=document.getElementById('status');" | 70 | "const statusEl=document.getElementById('status');" |
| 59 | "const payBtn=document.getElementById('payBtn');" | 71 | "const payBtn=document.getElementById('payBtn');" |
| 60 | "const tokenInput=document.getElementById('tokenInput');" | 72 | "const tokenInput=document.getElementById('tokenInput');" |
| 61 | "fetch('http://192.168.4.1:2121/').then(r=>r.json()).then(d=>{" | 73 | "const mintUrlEl=document.getElementById('mintUrl');" |
| 62 | "if(d.tags){const p=d.tags.find(t=>t[0]==='price_per_step');if(p)priceEl.textContent=p[2]||'21';}" | 74 | "fetch('http://__AP_IP__:2121/').then(r=>r.json()).then(d=>{" |
| 63 | "}).catch(()=>{priceEl.textContent='21';});" | 75 | "if(d.tags){" |
| 76 | "const p=d.tags.find(t=>t[0]==='price_per_step');if(p){priceEl.textContent=p[2]||'21';" | ||
| 77 | "if(p[4]){mintUrlEl.textContent=p[4];}}" | ||
| 78 | "}" | ||
| 79 | "}).catch(()=>{priceEl.textContent='21';mintUrlEl.textContent='Error loading mint URL';});" | ||
| 80 | "function copyMint(){" | ||
| 81 | "const url=mintUrlEl.textContent;" | ||
| 82 | "if(navigator.clipboard){navigator.clipboard.writeText(url);" | ||
| 83 | "mintUrlEl.textContent='Copied!';setTimeout(()=>{mintUrlEl.textContent=url;},1000);}" | ||
| 84 | "}" | ||
| 64 | "function showStatus(msg,type){statusEl.textContent=msg;statusEl.className=type;}" | 85 | "function showStatus(msg,type){statusEl.textContent=msg;statusEl.className=type;}" |
| 65 | "function payToken(){" | 86 | "function payToken(){" |
| 66 | "const token=tokenInput.value.trim();" | 87 | "const token=tokenInput.value.trim();" |
| 67 | "if(!token||!token.startsWith('cashuA')){showStatus('Please paste a valid Cashu token','error');return;}" | 88 | "if(!token||!token.startsWith('cashuA')){showStatus('Please paste a valid Cashu token','error');return;}" |
| 68 | "payBtn.disabled=true;" | 89 | "payBtn.disabled=true;" |
| 69 | "showStatus('Processing payment...','processing');" | 90 | "showStatus('Processing payment...','processing');" |
| 70 | "fetch('http://192.168.4.1:2121/',{method:'POST',body:token}).then(r=>{" | 91 | "fetch('http://__AP_IP__:2121/',{method:'POST',body:token}).then(r=>{" |
| 71 | "if(r.ok)return r.json();" | 92 | "if(r.ok)return r.json();" |
| 72 | "return r.json().then(d=>{throw new Error(d.content||'Payment failed');});" | 93 | "return r.json().then(d=>{throw new Error(d.content||'Payment failed');});" |
| 73 | "}).then(d=>{" | 94 | "}).then(d=>{" |
| @@ -91,28 +112,47 @@ static esp_err_t get_client_ip(httpd_req_t *req, uint32_t *ip_out) | |||
| 91 | return ESP_FAIL; | 112 | return ESP_FAIL; |
| 92 | } | 113 | } |
| 93 | 114 | ||
| 94 | static bool is_captive_detection_uri(const char *uri) | 115 | static esp_err_t portal_handler(httpd_req_t *req); |
| 95 | { | ||
| 96 | return strcmp(uri, "/generate_204") == 0 || | ||
| 97 | strcmp(uri, "/hotspot-detect.html") == 0 || | ||
| 98 | strcmp(uri, "/canonical.html") == 0 || | ||
| 99 | strcmp(uri, "/success.txt") == 0 || | ||
| 100 | strcmp(uri, "/ncsi.txt") == 0 || | ||
| 101 | strcmp(uri, "/connecttest.txt") == 0 || | ||
| 102 | strcmp(uri, "/wpad.dat") == 0 || | ||
| 103 | strcmp(uri, "/redirect") == 0 || | ||
| 104 | strcmp(uri, "/kindle-wifi/wifistub.html") == 0 || | ||
| 105 | strcmp(uri, "/fwlink") == 0 || | ||
| 106 | strcmp(uri, "/connectivity-check.html") == 0 || | ||
| 107 | strcmp(uri, "/generate_204/") == 0 || | ||
| 108 | strcmp(uri, "/hotspot-detect.html/") == 0; | ||
| 109 | } | ||
| 110 | 116 | ||
| 111 | static esp_err_t portal_handler(httpd_req_t *req) | 117 | static esp_err_t portal_handler(httpd_req_t *req) |
| 112 | { | 118 | { |
| 113 | ESP_LOGI(TAG, "GET %s from client", req->uri); | 119 | ESP_LOGI(TAG, "GET %s from client", req->uri); |
| 114 | httpd_resp_set_type(req, "text/html"); | 120 | httpd_resp_set_type(req, "text/html"); |
| 115 | httpd_resp_send(req, PORTAL_HTML, strlen(PORTAL_HTML)); | 121 | |
| 122 | char *html = NULL; | ||
| 123 | const char *tpl = PORTAL_HTML_TEMPLATE; | ||
| 124 | size_t tpl_len = strlen(tpl); | ||
| 125 | int count = 0; | ||
| 126 | const char *p = tpl; | ||
| 127 | while ((p = strstr(p, "__AP_IP__")) != NULL) { count++; p += 9; } | ||
| 128 | |||
| 129 | size_t ip_len = strlen(s_ap_ip_str); | ||
| 130 | html = malloc(tpl_len + count * (ip_len > 9 ? ip_len - 9 : 0) + 1); | ||
| 131 | if (!html) { | ||
| 132 | httpd_resp_send_500(req); | ||
| 133 | return ESP_OK; | ||
| 134 | } | ||
| 135 | |||
| 136 | char *out = html; | ||
| 137 | const char *src = tpl; | ||
| 138 | while (*src) { | ||
| 139 | const char *found = strstr(src, "__AP_IP__"); | ||
| 140 | if (found) { | ||
| 141 | memcpy(out, src, found - src); | ||
| 142 | out += found - src; | ||
| 143 | memcpy(out, s_ap_ip_str, ip_len); | ||
| 144 | out += ip_len; | ||
| 145 | src = found + 9; | ||
| 146 | } else { | ||
| 147 | strcpy(out, src); | ||
| 148 | out += strlen(src); | ||
| 149 | break; | ||
| 150 | } | ||
| 151 | } | ||
| 152 | *out = '\0'; | ||
| 153 | |||
| 154 | httpd_resp_send(req, html, out - html); | ||
| 155 | free(html); | ||
| 116 | return ESP_OK; | 156 | return ESP_OK; |
| 117 | } | 157 | } |
| 118 | 158 | ||
| @@ -187,19 +227,18 @@ static esp_err_t reset_auth_handler(httpd_req_t *req) | |||
| 187 | 227 | ||
| 188 | static esp_err_t redirect_to_portal_handler(httpd_req_t *req) | 228 | static esp_err_t redirect_to_portal_handler(httpd_req_t *req) |
| 189 | { | 229 | { |
| 190 | ESP_LOGI(TAG, "Captive detect: GET %s → 302 → http://192.168.4.1/", req->uri); | 230 | ESP_LOGI(TAG, "Captive detect: GET %s → 200 portal HTML", req->uri); |
| 191 | httpd_resp_set_status(req, "302 Found"); | 231 | return portal_handler(req); |
| 192 | httpd_resp_set_hdr(req, "Location", "http://192.168.4.1/"); | ||
| 193 | httpd_resp_set_hdr(req, "Connection", "close"); | ||
| 194 | httpd_resp_send(req, NULL, 0); | ||
| 195 | return ESP_OK; | ||
| 196 | } | 232 | } |
| 197 | 233 | ||
| 198 | static esp_err_t catchall_handler(httpd_req_t *req) | 234 | static esp_err_t catchall_handler(httpd_req_t *req) |
| 199 | { | 235 | { |
| 200 | ESP_LOGI(TAG, "Catchall: GET %s → 302 → http://192.168.4.1/", req->uri); | 236 | ESP_LOGI(TAG, "Catchall: GET %s → 302 → http://%s/", req->uri, s_ap_ip_str); |
| 201 | httpd_resp_set_status(req, "302 Found"); | 237 | httpd_resp_set_status(req, "302 Found"); |
| 202 | httpd_resp_set_hdr(req, "Location", "http://192.168.4.1/"); | 238 | |
| 239 | char location[64]; | ||
| 240 | snprintf(location, sizeof(location), "http://%s/", s_ap_ip_str); | ||
| 241 | httpd_resp_set_hdr(req, "Location", location); | ||
| 203 | httpd_resp_set_hdr(req, "Connection", "close"); | 242 | httpd_resp_set_hdr(req, "Connection", "close"); |
| 204 | httpd_resp_send(req, NULL, 0); | 243 | httpd_resp_send(req, NULL, 0); |
| 205 | return ESP_OK; | 244 | return ESP_OK; |
| @@ -220,9 +259,10 @@ static const httpd_uri_t uri_connecttest = { .uri = "/connecttest.txt", .method | |||
| 220 | static const httpd_uri_t uri_wpad = { .uri = "/wpad.dat", .method = HTTP_GET, .handler = redirect_to_portal_handler }; | 259 | static const httpd_uri_t uri_wpad = { .uri = "/wpad.dat", .method = HTTP_GET, .handler = redirect_to_portal_handler }; |
| 221 | static const httpd_uri_t uri_catchall = { .uri = "/*", .method = HTTP_GET, .handler = catchall_handler }; | 260 | static const httpd_uri_t uri_catchall = { .uri = "/*", .method = HTTP_GET, .handler = catchall_handler }; |
| 222 | 261 | ||
| 223 | esp_err_t captive_portal_start(void) | 262 | esp_err_t captive_portal_start(const char *ap_ip_str) |
| 224 | { | 263 | { |
| 225 | if (s_server) return ESP_OK; | 264 | if (s_server) return ESP_OK; |
| 265 | strncpy(s_ap_ip_str, ap_ip_str, sizeof(s_ap_ip_str) - 1); | ||
| 226 | 266 | ||
| 227 | httpd_config_t config = HTTPD_DEFAULT_CONFIG(); | 267 | httpd_config_t config = HTTPD_DEFAULT_CONFIG(); |
| 228 | config.max_uri_handlers = 20; | 268 | config.max_uri_handlers = 20; |
diff --git a/main/captive_portal.h b/main/captive_portal.h index 30d8c3e..06eb860 100644 --- a/main/captive_portal.h +++ b/main/captive_portal.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | #include "esp_http_server.h" | 4 | #include "esp_http_server.h" |
| 5 | #include "esp_err.h" | 5 | #include "esp_err.h" |
| 6 | 6 | ||
| 7 | esp_err_t captive_portal_start(void); | 7 | esp_err_t captive_portal_start(const char *ap_ip_str); |
| 8 | void captive_portal_stop(void); | 8 | void captive_portal_stop(void); |
| 9 | httpd_handle_t captive_portal_get_server(void); | 9 | httpd_handle_t captive_portal_get_server(void); |
| 10 | 10 | ||
diff --git a/main/config.c b/main/config.c index b44c3c5..d7837bc 100644 --- a/main/config.c +++ b/main/config.c | |||
| @@ -1,8 +1,12 @@ | |||
| 1 | #include "config.h" | 1 | #include "config.h" |
| 2 | #include "esp_log.h" | 2 | #include "esp_log.h" |
| 3 | #include "esp_spiffs.h" | 3 | #include "esp_spiffs.h" |
| 4 | #include "esp_system.h" | ||
| 5 | #include "esp_mac.h" | ||
| 6 | #include "lwip/ip4_addr.h" | ||
| 4 | #include "cJSON.h" | 7 | #include "cJSON.h" |
| 5 | #include <string.h> | 8 | #include <string.h> |
| 9 | #include <stdio.h> | ||
| 6 | 10 | ||
| 7 | static const char *TAG = "tollgate_config"; | 11 | static const char *TAG = "tollgate_config"; |
| 8 | static tollgate_config_t g_config; | 12 | static tollgate_config_t g_config; |
| @@ -140,3 +144,25 @@ esp_err_t tollgate_config_get_next_wifi(wifi_config_t *wifi_config) | |||
| 140 | g_config.current_network = (g_config.current_network + 1) % g_config.network_count; | 144 | g_config.current_network = (g_config.current_network + 1) % g_config.network_count; |
| 141 | return tollgate_config_get_wifi(wifi_config); | 145 | return tollgate_config_get_wifi(wifi_config); |
| 142 | } | 146 | } |
| 147 | |||
| 148 | void tollgate_config_derive_unique(tollgate_config_t *cfg) | ||
| 149 | { | ||
| 150 | if (cfg->unique_derived) return; | ||
| 151 | |||
| 152 | uint8_t mac[6]; | ||
| 153 | esp_read_mac(mac, ESP_MAC_WIFI_STA); | ||
| 154 | |||
| 155 | snprintf(cfg->ap_ssid + strlen(cfg->ap_ssid), | ||
| 156 | TOLLGATE_MAX_AP_SSID_LEN - strlen(cfg->ap_ssid), | ||
| 157 | "-%02X%02X", mac[4], mac[5]); | ||
| 158 | |||
| 159 | uint8_t b5 = mac[4]; | ||
| 160 | uint8_t b6 = mac[5]; | ||
| 161 | uint8_t subnet = (b5 ^ b6) % 200 + 10; | ||
| 162 | IP4_ADDR(&cfg->ap_ip, 10, b5, subnet, 1); | ||
| 163 | snprintf(cfg->ap_ip_str, sizeof(cfg->ap_ip_str), IPSTR, IP2STR(&cfg->ap_ip)); | ||
| 164 | |||
| 165 | cfg->unique_derived = true; | ||
| 166 | |||
| 167 | ESP_LOGI(TAG, "Unique config: SSID='%s', AP_IP=%s", cfg->ap_ssid, cfg->ap_ip_str); | ||
| 168 | } | ||
diff --git a/main/config.h b/main/config.h index d26b7ae..dd3fe05 100644 --- a/main/config.h +++ b/main/config.h | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | #include "esp_err.h" | 4 | #include "esp_err.h" |
| 5 | #include "esp_wifi.h" | 5 | #include "esp_wifi.h" |
| 6 | #include "esp_netif.h" | ||
| 7 | #include <stdbool.h> | ||
| 6 | 8 | ||
| 7 | #define TOLLGATE_MAX_WIFI_NETWORKS 5 | 9 | #define TOLLGATE_MAX_WIFI_NETWORKS 5 |
| 8 | #define TOLLGATE_MAX_MINT_URLS 3 | 10 | #define TOLLGATE_MAX_MINT_URLS 3 |
| @@ -25,12 +27,19 @@ typedef struct { | |||
| 25 | uint8_t ap_channel; | 27 | uint8_t ap_channel; |
| 26 | uint8_t ap_max_conn; | 28 | uint8_t ap_max_conn; |
| 27 | 29 | ||
| 30 | esp_ip4_addr_t ap_ip; | ||
| 31 | char ap_ip_str[16]; | ||
| 32 | |||
| 28 | char mint_url[256]; | 33 | char mint_url[256]; |
| 29 | char lnurl_url[256]; | 34 | char lnurl_url[256]; |
| 30 | int price_per_step; | 35 | int price_per_step; |
| 31 | int step_size_ms; | 36 | int step_size_ms; |
| 37 | |||
| 38 | bool unique_derived; | ||
| 32 | } tollgate_config_t; | 39 | } tollgate_config_t; |
| 33 | 40 | ||
| 41 | void tollgate_config_derive_unique(tollgate_config_t *cfg); | ||
| 42 | |||
| 34 | esp_err_t tollgate_config_init(void); | 43 | esp_err_t tollgate_config_init(void); |
| 35 | const tollgate_config_t *tollgate_config_get(void); | 44 | const tollgate_config_t *tollgate_config_get(void); |
| 36 | esp_err_t tollgate_config_get_wifi(wifi_config_t *wifi_config); | 45 | esp_err_t tollgate_config_get_wifi(wifi_config_t *wifi_config); |
diff --git a/main/tollgate_main.c b/main/tollgate_main.c index 04f64b9..30fad8d 100644 --- a/main/tollgate_main.c +++ b/main/tollgate_main.c | |||
| @@ -18,9 +18,6 @@ | |||
| 18 | #include "tollgate_api.h" | 18 | #include "tollgate_api.h" |
| 19 | 19 | ||
| 20 | #define MAX_STA_RETRY 5 | 20 | #define MAX_STA_RETRY 5 |
| 21 | #define AP_IP_ADDR "192.168.4.1" | ||
| 22 | #define AP_SUBNET "255.255.255.0" | ||
| 23 | |||
| 24 | static const char *TAG = "tollgate_main"; | 21 | static const char *TAG = "tollgate_main"; |
| 25 | 22 | ||
| 26 | static EventGroupHandle_t s_wifi_event_group; | 23 | static EventGroupHandle_t s_wifi_event_group; |
| @@ -31,6 +28,7 @@ static esp_netif_t *s_ap_netif = NULL; | |||
| 31 | static int s_retry_count = 0; | 28 | static int s_retry_count = 0; |
| 32 | static bool s_services_running = false; | 29 | static bool s_services_running = false; |
| 33 | static SemaphoreHandle_t s_services_mutex = NULL; | 30 | static SemaphoreHandle_t s_services_mutex = NULL; |
| 31 | static char s_ap_ip_str[16] = "10.0.0.1"; | ||
| 34 | 32 | ||
| 35 | static void start_services(void); | 33 | static void start_services(void); |
| 36 | static void stop_services(void); | 34 | static void stop_services(void); |
| @@ -109,8 +107,9 @@ static void start_services(void) | |||
| 109 | firewall_init(ap_ip_info.ip); | 107 | firewall_init(ap_ip_info.ip); |
| 110 | session_manager_init(); | 108 | session_manager_init(); |
| 111 | 109 | ||
| 110 | const tollgate_config_t *cfg = tollgate_config_get(); | ||
| 112 | dns_server_start(ap_ip_info.ip, upstream_dns); | 111 | dns_server_start(ap_ip_info.ip, upstream_dns); |
| 113 | captive_portal_start(); | 112 | captive_portal_start(cfg->ap_ip_str); |
| 114 | tollgate_api_start(); | 113 | tollgate_api_start(); |
| 115 | 114 | ||
| 116 | s_services_running = true; | 115 | s_services_running = true; |
| @@ -140,10 +139,18 @@ static void wifi_create_ap_netif(void) | |||
| 140 | { | 139 | { |
| 141 | s_ap_netif = esp_netif_create_default_wifi_ap(); | 140 | s_ap_netif = esp_netif_create_default_wifi_ap(); |
| 142 | 141 | ||
| 142 | const tollgate_config_t *cfg = tollgate_config_get(); | ||
| 143 | esp_ip4_addr_t ap_ip = cfg->ap_ip; | ||
| 144 | esp_ip4_addr_t ap_gw = cfg->ap_ip; | ||
| 145 | esp_ip4_addr_t ap_mask; | ||
| 146 | IP4_ADDR(&ap_mask, 255, 255, 255, 0); | ||
| 147 | |||
| 148 | strncpy(s_ap_ip_str, cfg->ap_ip_str, sizeof(s_ap_ip_str) - 1); | ||
| 149 | |||
| 143 | esp_netif_ip_info_t ip_info = { | 150 | esp_netif_ip_info_t ip_info = { |
| 144 | .ip.addr = esp_ip4addr_aton(AP_IP_ADDR), | 151 | .ip.addr = ap_ip.addr, |
| 145 | .gw.addr = esp_ip4addr_aton(AP_IP_ADDR), | 152 | .gw.addr = ap_gw.addr, |
| 146 | .netmask.addr = esp_ip4addr_aton(AP_SUBNET), | 153 | .netmask.addr = ap_mask.addr, |
| 147 | }; | 154 | }; |
| 148 | ESP_ERROR_CHECK(esp_netif_dhcps_stop(s_ap_netif)); | 155 | ESP_ERROR_CHECK(esp_netif_dhcps_stop(s_ap_netif)); |
| 149 | ESP_ERROR_CHECK(esp_netif_set_ip_info(s_ap_netif, &ip_info)); | 156 | ESP_ERROR_CHECK(esp_netif_set_ip_info(s_ap_netif, &ip_info)); |
| @@ -190,6 +197,7 @@ void app_main(void) | |||
| 190 | ESP_ERROR_CHECK(ret); | 197 | ESP_ERROR_CHECK(ret); |
| 191 | 198 | ||
| 192 | ESP_ERROR_CHECK(tollgate_config_init()); | 199 | ESP_ERROR_CHECK(tollgate_config_init()); |
| 200 | tollgate_config_derive_unique((tollgate_config_t *)tollgate_config_get()); | ||
| 193 | ESP_ERROR_CHECK(esp_netif_init()); | 201 | ESP_ERROR_CHECK(esp_netif_init()); |
| 194 | ESP_ERROR_CHECK(esp_event_loop_create_default()); | 202 | ESP_ERROR_CHECK(esp_event_loop_create_default()); |
| 195 | 203 | ||