upleb.uk

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

summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorYour Name <you@example.com>2026-05-23 04:10:28 +0530
committerYour Name <you@example.com>2026-05-23 04:10:28 +0530
commit851801f50f1282ab1db5f8a241dbd245f59e447e (patch)
tree3285d0714da89879acd21b8c3fb9afeff586ed1e /main
parent39aa27a9522aeb8f731f4d3de48939e75775900e (diff)
Phase 5: Wire main/ shims to components/tollgate_core
- session.c/h: thin shim casting session_t* <-> tg_session_t*, delegates to tollgate_core_session_* - firewall.c/h: keeps ESP-specific lwIP hooks, delegates allowlist to tollgate_core_fw_* - cashu.c/h: shim delegates to tollgate_core_cashu_*, multi-mint via config directly - mining_payment.c: shim delegates to tollgate_core_mining_* - tollgate_main.c: calls tollgate_core_init(tollgate_esp_get_platform(), ap_ip) in start_services() - tollgate_esp: removed target_sources for standalone sources, depends on tollgate_core component - tollgate_core component: added tollgate_core_get_platform(), tg_payment_method_t enum - Unit tests: updated Makefile for component source compilation, all 22 tests pass - Hardware verified: Board A boots, AP visible, 5/6 smoke tests pass (internet test needs upstream WiFi)
Diffstat (limited to 'main')
-rw-r--r--main/CMakeLists.txt9
-rw-r--r--main/cashu.c257
-rw-r--r--main/cashu.h4
-rw-r--r--main/firewall.c124
-rw-r--r--main/firewall.h1
-rw-r--r--main/mining_payment.c135
-rw-r--r--main/session.c142
-rw-r--r--main/session.h12
-rw-r--r--main/tollgate_main.c3
9 files changed, 73 insertions, 614 deletions
diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt
index 9e76f89..da90967 100644
--- a/main/CMakeLists.txt
+++ b/main/CMakeLists.txt
@@ -30,13 +30,12 @@ idf_component_register(SRCS "tollgate_main.c"
30 "stratum_proxy.c" 30 "stratum_proxy.c"
31 "sw_miner.c" 31 "sw_miner.c"
32 "asic_miner.c" 32 "asic_miner.c"
33 "tollgate_platform.c"
34 "touch.c" 33 "touch.c"
35 "keyboard.c" 34 "keyboard.c"
36 "wifi_setup.c" 35 "wifi_setup.c"
37 INCLUDE_DIRS "." 36 INCLUDE_DIRS "."
38 REQUIRES esp_wifi esp_event esp_netif nvs_flash esp_http_server 37 REQUIRES esp_wifi esp_event esp_netif nvs_flash esp_http_server
39 lwip json esp_http_client mbedtls esp-tls log spiffs 38 lwip json esp_http_client mbedtls esp-tls log spiffs
40 nucula_lib secp256k1 axs15231b qrcode wisp_relay 39 nucula_lib secp256k1 axs15231b qrcode wisp_relay
41 negentropy_lib tcp_transport tollgate_core 40 negentropy_lib tcp_transport tollgate_esp
42 PRIV_REQUIRES esp-tls) 41 PRIV_REQUIRES esp-tls)
diff --git a/main/cashu.c b/main/cashu.c
index 4bcda4d..2da6a05 100644
--- a/main/cashu.c
+++ b/main/cashu.c
@@ -1,278 +1,43 @@
1#include "cashu.h" 1#include "cashu.h"
2#include "tollgate_core_cashu.h"
3#include "tollgate_core.h"
2#include "config.h" 4#include "config.h"
3#include "mint_health.h"
4#include "esp_log.h" 5#include "esp_log.h"
5#include "esp_http_client.h"
6#include "cJSON.h"
7#include "mbedtls/base64.h"
8#include "mbedtls/sha256.h"
9#include "esp_crt_bundle.h"
10 6
11static const char *TAG = "cashu"; 7static const char *TAG = "cashu";
12 8
13static const char V3_PREFIX[] = "cashuA";
14static const size_t V3_PREFIX_LEN = 6;
15
16static int b64url_decode(const char *input, size_t input_len, char *out, size_t out_size, size_t *out_len)
17{
18 char *b64 = malloc(input_len + 4);
19 if (!b64) return -1;
20 size_t b64_len = input_len;
21 memcpy(b64, input, b64_len);
22 b64[b64_len] = '\0';
23
24 for (size_t i = 0; i < b64_len; i++) {
25 if (b64[i] == '-') b64[i] = '+';
26 else if (b64[i] == '_') b64[i] = '/';
27 }
28 while (b64_len % 4 != 0) {
29 b64[b64_len++] = '=';
30 }
31 b64[b64_len] = '\0';
32
33 size_t olen = 0;
34 int ret = mbedtls_base64_decode((unsigned char *)out, out_size, &olen,
35 (const unsigned char *)b64, b64_len);
36 free(b64);
37 if (ret != 0) return -1;
38 *out_len = olen;
39 return 0;
40}
41
42static esp_err_t parse_proofs_array(cJSON *arr, cashu_token_t *out)
43{
44 if (!cJSON_IsArray(arr)) return ESP_FAIL;
45 int count = cJSON_GetArraySize(arr);
46 if (count > CASHU_MAX_PROOFS) return ESP_FAIL;
47
48 out->proof_count = 0;
49 out->total_amount = 0;
50 for (int i = 0; i < count; i++) {
51 cJSON *proof = cJSON_GetArrayItem(arr, i);
52 cJSON *amt = cJSON_GetObjectItemCaseSensitive(proof, "amount");
53 cJSON *id = cJSON_GetObjectItemCaseSensitive(proof, "id");
54 cJSON *secret = cJSON_GetObjectItemCaseSensitive(proof, "secret");
55 cJSON *c = cJSON_GetObjectItemCaseSensitive(proof, "C");
56
57 if (!amt || !cJSON_IsNumber(amt)) return ESP_FAIL;
58
59 out->proofs[i].amount = (uint64_t)amt->valuedouble;
60 out->total_amount += out->proofs[i].amount;
61
62 if (id && cJSON_IsString(id)) {
63 strncpy(out->proofs[i].id, id->valuestring, sizeof(out->proofs[i].id) - 1);
64 }
65 if (secret && cJSON_IsString(secret)) {
66 strncpy(out->proofs[i].secret, secret->valuestring, sizeof(out->proofs[i].secret) - 1);
67 }
68 if (c && cJSON_IsString(c)) {
69 strncpy(out->proofs[i].c, c->valuestring, sizeof(out->proofs[i].c) - 1);
70 }
71 out->proof_count++;
72 }
73 return ESP_OK;
74}
75
76esp_err_t cashu_decode_token(const char *token_str, cashu_token_t *out) 9esp_err_t cashu_decode_token(const char *token_str, cashu_token_t *out)
77{ 10{
78 if (!token_str || !out) return ESP_FAIL; 11 return tollgate_core_cashu_decode_token(token_str, (tg_cashu_token_t *)out);
79 memset(out, 0, sizeof(*out));
80
81 size_t len = strlen(token_str);
82 char *nl = strchr(token_str, '\n');
83 if (nl) len = nl - token_str;
84 char *cr = strchr(token_str, '\r');
85 if (cr && (cr - token_str) < (int)len) len = cr - token_str;
86 if (len <= V3_PREFIX_LEN) {
87 ESP_LOGE(TAG, "Token too short");
88 return ESP_FAIL;
89 }
90 if (strncmp(token_str, V3_PREFIX, V3_PREFIX_LEN) != 0) {
91 ESP_LOGE(TAG, "Token missing cashuA prefix");
92 return ESP_FAIL;
93 }
94
95 size_t b64_len = len - V3_PREFIX_LEN;
96 size_t decoded_size = (b64_len * 3) / 4 + 4;
97 char *json_buf = malloc(decoded_size);
98 if (!json_buf) return ESP_FAIL;
99 size_t json_len = 0;
100 if (b64url_decode(token_str + V3_PREFIX_LEN, b64_len,
101 json_buf, decoded_size - 1, &json_len) != 0) {
102 ESP_LOGE(TAG, "Base64url decode failed");
103 free(json_buf);
104 return ESP_FAIL;
105 }
106 json_buf[json_len] = '\0';
107
108 cJSON *root = cJSON_Parse(json_buf);
109 free(json_buf);
110 if (!root) {
111 ESP_LOGE(TAG, "JSON parse failed");
112 return ESP_FAIL;
113 }
114
115 cJSON *token_arr = cJSON_GetObjectItemCaseSensitive(root, "token");
116 if (token_arr && cJSON_IsArray(token_arr)) {
117 cJSON *first = cJSON_GetArrayItem(token_arr, 0);
118 if (!first) { cJSON_Delete(root); return ESP_FAIL; }
119
120 cJSON *mint = cJSON_GetObjectItemCaseSensitive(first, "mint");
121 if (mint && cJSON_IsString(mint)) {
122 strncpy(out->mint_url, mint->valuestring, sizeof(out->mint_url) - 1);
123 }
124
125 cJSON *proofs = cJSON_GetObjectItemCaseSensitive(first, "proofs");
126 if (proofs) {
127 esp_err_t ret = parse_proofs_array(proofs, out);
128 if (ret != ESP_OK) { cJSON_Delete(root); return ret; }
129 }
130 } else {
131 cJSON *mint = cJSON_GetObjectItemCaseSensitive(root, "mint");
132 if (mint && cJSON_IsString(mint)) {
133 strncpy(out->mint_url, mint->valuestring, sizeof(out->mint_url) - 1);
134 }
135
136 cJSON *proofs = cJSON_GetObjectItemCaseSensitive(root, "proofs");
137 if (proofs) {
138 esp_err_t ret = parse_proofs_array(proofs, out);
139 if (ret != ESP_OK) { cJSON_Delete(root); return ret; }
140 }
141 }
142
143 cJSON_Delete(root);
144
145 if (out->proof_count == 0) {
146 ESP_LOGE(TAG, "No proofs in token");
147 return ESP_FAIL;
148 }
149
150 ESP_LOGI(TAG, "Decoded token: %d proofs, total=%llu, mint=%s",
151 out->proof_count, (unsigned long long)out->total_amount, out->mint_url);
152 return ESP_OK;
153}
154
155static void sha256_hex(const char *data, size_t data_len, char *hex_out)
156{
157 uint8_t hash[32];
158 mbedtls_sha256((const unsigned char *)data, data_len, hash, 0);
159 for (int i = 0; i < 32; i++) {
160 sprintf(hex_out + i * 2, "%02x", hash[i]);
161 }
162 hex_out[64] = '\0';
163} 12}
164 13
165esp_err_t cashu_check_proof_states(const char *mint_url, const cashu_token_t *token, 14esp_err_t cashu_check_proof_states(const char *mint_url, const cashu_token_t *token,
166 cashu_proof_state_t *states, int *state_count) 15 cashu_proof_state_t *states, int *state_count)
167{ 16{
168 cJSON *ys_arr = cJSON_CreateArray(); 17 return tollgate_core_cashu_check_proof_states(mint_url, (const tg_cashu_token_t *)token,
169 for (int i = 0; i < token->proof_count; i++) { 18 (tg_cashu_proof_state_t *)states, state_count);
170 char y_hex[65];
171 sha256_hex(token->proofs[i].secret, strlen(token->proofs[i].secret), y_hex);
172 cJSON_AddItemToArray(ys_arr, cJSON_CreateString(y_hex));
173 strncpy(states[i].y_hex, y_hex, sizeof(states[i].y_hex) - 1);
174 states[i].spent = false;
175 }
176 *state_count = token->proof_count;
177
178 char *ys_json = cJSON_PrintUnformatted(ys_arr);
179 cJSON_Delete(ys_arr);
180
181 char *post_body = malloc(4096);
182 if (!post_body) { cJSON_free(ys_json); return ESP_FAIL; }
183 snprintf(post_body, 4096, "{\"Ys\":%s}", ys_json);
184 cJSON_free(ys_json);
185
186 char url[512];
187 snprintf(url, sizeof(url), "%s/v1/checkstate", mint_url);
188
189 char *resp_buf = malloc(8192);
190 if (!resp_buf) { free(post_body); return ESP_FAIL; }
191
192 esp_http_client_config_t config = {
193 .url = url,
194 .method = HTTP_METHOD_POST,
195 .timeout_ms = 15000,
196 .crt_bundle_attach = esp_crt_bundle_attach,
197 };
198 esp_http_client_handle_t client = esp_http_client_init(&config);
199 if (!client) { free(post_body); free(resp_buf); return ESP_FAIL; }
200
201 esp_http_client_set_header(client, "Content-Type", "application/json");
202
203 esp_err_t err = esp_http_client_open(client, strlen(post_body));
204 if (err != ESP_OK) {
205 ESP_LOGE(TAG, "checkstate open failed: %s", esp_err_to_name(err));
206 esp_http_client_cleanup(client);
207 free(post_body);
208 free(resp_buf);
209 return ESP_FAIL;
210 }
211 int written = esp_http_client_write(client, post_body, strlen(post_body));
212 free(post_body);
213 ESP_LOGI(TAG, "checkstate written %d bytes", written);
214
215 int content_length = esp_http_client_fetch_headers(client);
216 int status = esp_http_client_get_status_code(client);
217 ESP_LOGI(TAG, "checkstate headers: status=%d, content_length=%d", status, content_length);
218
219 int resp_len = esp_http_client_read(client, resp_buf, 8191);
220 ESP_LOGI(TAG, "checkstate read: resp_len=%d", resp_len);
221 esp_http_client_cleanup(client);
222
223 if (status != 200 || resp_len <= 0) {
224 ESP_LOGE(TAG, "checkstate failed: status=%d, resp_len=%d", status, resp_len);
225 free(resp_buf);
226 return ESP_FAIL;
227 }
228 resp_buf[resp_len] = '\0';
229
230 cJSON *root = cJSON_Parse(resp_buf);
231 free(resp_buf);
232 if (!root) return ESP_FAIL;
233
234 cJSON *states_arr = cJSON_GetObjectItemCaseSensitive(root, "states");
235 if (!states_arr || !cJSON_IsArray(states_arr)) {
236 cJSON_Delete(root);
237 return ESP_FAIL;
238 }
239
240 int n = cJSON_GetArraySize(states_arr);
241 for (int i = 0; i < n && i < token->proof_count; i++) {
242 cJSON *s = cJSON_GetArrayItem(states_arr, i);
243 cJSON *state = cJSON_GetObjectItemCaseSensitive(s, "state");
244 if (state && cJSON_IsString(state)) {
245 states[i].spent = (strcmp(state->valuestring, "SPENT") == 0);
246 }
247 }
248
249 cJSON_Delete(root);
250 return ESP_OK;
251} 19}
252 20
253uint64_t cashu_calculate_allotment_ms(uint64_t token_amount, uint64_t price_per_step, 21uint64_t cashu_calculate_allotment_ms(uint64_t token_amount, uint64_t price_per_step,
254 uint64_t step_size_ms) 22 uint64_t step_size_ms)
255{ 23{
256 if (price_per_step == 0) return 0; 24 return tollgate_core_cashu_calculate_allotment(token_amount, price_per_step, step_size_ms);
257 return (token_amount / price_per_step) * step_size_ms;
258} 25}
259 26
260uint64_t cashu_calculate_allotment(uint64_t token_amount, uint64_t price_per_step, 27uint64_t cashu_calculate_allotment(uint64_t token_amount, uint64_t price_per_step,
261 const char *metric, uint64_t step_size) 28 const char *metric, uint64_t step_size)
262{ 29{
263 if (price_per_step == 0) return 0;
264 (void)metric; 30 (void)metric;
265 return (token_amount / price_per_step) * step_size; 31 return tollgate_core_cashu_calculate_allotment(token_amount, price_per_step, step_size);
266} 32}
267 33
268bool cashu_is_mint_accepted(const char *mint_url) 34bool cashu_is_mint_accepted(const char *mint_url)
269{ 35{
270 if (!mint_url || mint_url[0] == '\0') return false;
271 const tollgate_config_t *cfg = tollgate_config_get(); 36 const tollgate_config_t *cfg = tollgate_config_get();
272 for (int i = 0; i < cfg->accepted_mint_count; i++) { 37 if (cfg) {
273 if (strstr(mint_url, cfg->accepted_mints[i]) != NULL || 38 for (int i = 0; i < cfg->accepted_mint_count; i++) {
274 strcmp(mint_url, cfg->accepted_mints[i]) == 0) { 39 if (tollgate_core_cashu_is_mint_accepted(mint_url, cfg->accepted_mints[i]))
275 return mint_health_is_reachable(mint_url); 40 return true;
276 } 41 }
277 } 42 }
278 return false; 43 return false;
diff --git a/main/cashu.h b/main/cashu.h
index 76ad2eb..43be033 100644
--- a/main/cashu.h
+++ b/main/cashu.h
@@ -30,16 +30,12 @@ typedef struct {
30} cashu_proof_state_t; 30} cashu_proof_state_t;
31 31
32esp_err_t cashu_decode_token(const char *token_str, cashu_token_t *out); 32esp_err_t cashu_decode_token(const char *token_str, cashu_token_t *out);
33
34esp_err_t cashu_check_proof_states(const char *mint_url, const cashu_token_t *token, 33esp_err_t cashu_check_proof_states(const char *mint_url, const cashu_token_t *token,
35 cashu_proof_state_t *states, int *state_count); 34 cashu_proof_state_t *states, int *state_count);
36
37uint64_t cashu_calculate_allotment_ms(uint64_t token_amount, uint64_t price_per_step, 35uint64_t cashu_calculate_allotment_ms(uint64_t token_amount, uint64_t price_per_step,
38 uint64_t step_size_ms); 36 uint64_t step_size_ms);
39
40uint64_t cashu_calculate_allotment(uint64_t token_amount, uint64_t price_per_step, 37uint64_t cashu_calculate_allotment(uint64_t token_amount, uint64_t price_per_step,
41 const char *metric, uint64_t step_size); 38 const char *metric, uint64_t step_size);
42
43bool cashu_is_mint_accepted(const char *mint_url); 39bool cashu_is_mint_accepted(const char *mint_url);
44 40
45#endif 41#endif
diff --git a/main/firewall.c b/main/firewall.c
index ae0eda7..077d16c 100644
--- a/main/firewall.c
+++ b/main/firewall.c
@@ -1,70 +1,23 @@
1#include "firewall.h" 1#include "firewall.h"
2#include "dns_server.h" 2#include "dns_server.h"
3#include "tollgate_core.h"
4#include "tollgate_core_firewall.h"
3#include "esp_log.h" 5#include "esp_log.h"
4#include "esp_wifi.h"
5#include "esp_wifi_ap_get_sta_list.h"
6#include "lwip/lwip_napt.h"
7#include "lwip/etharp.h"
8#include "lwip/netif.h" 6#include "lwip/netif.h"
7#include "lwip/lwip_napt.h"
9#include "lwip/prot/ip4.h" 8#include "lwip/prot/ip4.h"
10#include "lwip/prot/tcp.h" 9#include "lwip/prot/tcp.h"
11#include "lwip/prot/ip.h" 10#include "lwip/prot/ip.h"
12#include <string.h> 11#include <string.h>
13 12
14#define MAX_CLIENTS 10
15
16static const char *TAG = "firewall"; 13static const char *TAG = "firewall";
17static esp_ip4_addr_t s_ap_ip; 14static esp_ip4_addr_t s_ap_ip;
18static uint16_t s_mining_port = 3333; 15static uint16_t s_mining_port = 3333;
19static bool s_sandbox_mint_access = false; 16static bool s_sandbox_mint_access = false;
20 17
21typedef struct {
22 uint32_t ip;
23 char mac[FW_MAX_MAC_LEN];
24} fw_client_t;
25
26static fw_client_t s_clients[MAX_CLIENTS];
27static int s_client_count = 0;
28
29esp_err_t firewall_get_mac_for_ip(uint32_t client_ip, char *mac_out, size_t mac_out_size)
30{
31 wifi_sta_list_t sta_list;
32 if (esp_wifi_ap_get_sta_list(&sta_list) == ESP_OK) {
33 wifi_sta_mac_ip_list_t ip_mac_list;
34 if (esp_wifi_ap_get_sta_list_with_ip(&sta_list, &ip_mac_list) == ESP_OK) {
35 for (int i = 0; i < ip_mac_list.num; i++) {
36 if (ip_mac_list.sta[i].ip.addr == client_ip) {
37 snprintf(mac_out, mac_out_size, "%02x:%02x:%02x:%02x:%02x:%02x",
38 ip_mac_list.sta[i].mac[0], ip_mac_list.sta[i].mac[1],
39 ip_mac_list.sta[i].mac[2], ip_mac_list.sta[i].mac[3],
40 ip_mac_list.sta[i].mac[4], ip_mac_list.sta[i].mac[5]);
41 return ESP_OK;
42 }
43 }
44 }
45 }
46
47 ip4_addr_t *entry_ip = NULL;
48 struct netif *entry_netif = NULL;
49 struct eth_addr *entry_eth = NULL;
50 ssize_t i = 0;
51 while (etharp_get_entry(i, &entry_ip, &entry_netif, &entry_eth) == ERR_OK) {
52 if (entry_ip && entry_ip->addr == client_ip && entry_eth) {
53 snprintf(mac_out, mac_out_size, "%02x:%02x:%02x:%02x:%02x:%02x",
54 entry_eth->addr[0], entry_eth->addr[1], entry_eth->addr[2],
55 entry_eth->addr[3], entry_eth->addr[4], entry_eth->addr[5]);
56 return ESP_OK;
57 }
58 i++;
59 }
60 return ESP_FAIL;
61}
62
63esp_err_t firewall_init(esp_ip4_addr_t ap_ip) 18esp_err_t firewall_init(esp_ip4_addr_t ap_ip)
64{ 19{
65 s_ap_ip = ap_ip; 20 s_ap_ip = ap_ip;
66 memset(s_clients, 0, sizeof(s_clients));
67 s_client_count = 0;
68 ip_napt_enable(s_ap_ip.addr, 1); 21 ip_napt_enable(s_ap_ip.addr, 1);
69 ESP_LOGI(TAG, "Firewall initialized with AP IP=" IPSTR " (NAT always on, per-client filter)", IP2STR(&s_ap_ip)); 22 ESP_LOGI(TAG, "Firewall initialized with AP IP=" IPSTR " (NAT always on, per-client filter)", IP2STR(&s_ap_ip));
70 return ESP_OK; 23 return ESP_OK;
@@ -80,6 +33,11 @@ void firewall_set_sandbox_mint_access(bool enabled)
80 s_sandbox_mint_access = enabled; 33 s_sandbox_mint_access = enabled;
81} 34}
82 35
36esp_err_t firewall_get_mac_for_ip(uint32_t client_ip, char *mac_out, size_t mac_out_size)
37{
38 return tollgate_core_fw_get_mac_for_ip(client_ip, mac_out, mac_out_size);
39}
40
83static bool is_sandbox_allowed(struct pbuf *p) 41static bool is_sandbox_allowed(struct pbuf *p)
84{ 42{
85 if (p->len < IP_HLEN) return false; 43 if (p->len < IP_HLEN) return false;
@@ -129,84 +87,44 @@ int tollgate_ip4_canforward_filter(struct pbuf *p, u32_t dest_addr_hostorder)
129 return 0; 87 return 0;
130} 88}
131 89
132static fw_client_t *find_client_by_ip(uint32_t client_ip)
133{
134 for (int i = 0; i < s_client_count; i++) {
135 if (s_clients[i].ip == client_ip) return &s_clients[i];
136 }
137 return NULL;
138}
139
140static fw_client_t *find_client_by_mac(const char *mac)
141{
142 for (int i = 0; i < s_client_count; i++) {
143 if (s_clients[i].mac[0] != '\0' && strcmp(s_clients[i].mac, mac) == 0) {
144 return &s_clients[i];
145 }
146 }
147 return NULL;
148}
149
150void firewall_grant_access(uint32_t client_ip) 90void firewall_grant_access(uint32_t client_ip)
151{ 91{
152 fw_client_t *existing = find_client_by_ip(client_ip); 92 tollgate_core_fw_grant(client_ip);
153 if (existing) {
154 existing->ip = client_ip;
155 return;
156 }
157 if (s_client_count >= MAX_CLIENTS) {
158 ESP_LOGW(TAG, "Max clients reached, cannot grant access");
159 return;
160 }
161
162 fw_client_t *client = &s_clients[s_client_count];
163 client->ip = client_ip;
164 client->mac[0] = '\0';
165 firewall_get_mac_for_ip(client_ip, client->mac, sizeof(client->mac));
166 s_client_count++;
167
168 dns_server_set_client_authenticated(client_ip, true); 93 dns_server_set_client_authenticated(client_ip, true);
169 94
95 char mac[18] = {0};
96 tollgate_core_fw_get_mac_for_ip(client_ip, mac, sizeof(mac));
170 esp_ip4_addr_t ip_addr = { .addr = client_ip }; 97 esp_ip4_addr_t ip_addr = { .addr = client_ip };
171 ESP_LOGI(TAG, "Access granted to " IPSTR " mac=%s", IP2STR(&ip_addr), 98 ESP_LOGI(TAG, "Access granted to " IPSTR " mac=%s", IP2STR(&ip_addr),
172 client->mac[0] ? client->mac : "unknown"); 99 mac[0] ? mac : "unknown");
173} 100}
174 101
175void firewall_revoke_access(uint32_t client_ip) 102void firewall_revoke_access(uint32_t client_ip)
176{ 103{
177 for (int i = 0; i < s_client_count; i++) { 104 tollgate_core_fw_revoke(client_ip);
178 if (s_clients[i].ip == client_ip) { 105 dns_server_set_client_authenticated(client_ip, false);
179 esp_ip4_addr_t ip_addr = { .addr = client_ip }; 106
180 ESP_LOGI(TAG, "Access revoked for " IPSTR " mac=%s", IP2STR(&ip_addr), 107 esp_ip4_addr_t ip_addr = { .addr = client_ip };
181 s_clients[i].mac[0] ? s_clients[i].mac : "unknown"); 108 ESP_LOGI(TAG, "Access revoked for " IPSTR, IP2STR(&ip_addr));
182 s_clients[i] = s_clients[s_client_count - 1];
183 s_client_count--;
184 dns_server_set_client_authenticated(client_ip, false);
185 return;
186 }
187 }
188} 109}
189 110
190void firewall_revoke_all(void) 111void firewall_revoke_all(void)
191{ 112{
192 for (int i = 0; i < s_client_count; i++) { 113 tollgate_core_fw_revoke_all();
193 dns_server_set_client_authenticated(s_clients[i].ip, false);
194 }
195 s_client_count = 0;
196 ESP_LOGI(TAG, "All client access revoked"); 114 ESP_LOGI(TAG, "All client access revoked");
197} 115}
198 116
199bool firewall_is_client_allowed(uint32_t client_ip) 117bool firewall_is_client_allowed(uint32_t client_ip)
200{ 118{
201 return find_client_by_ip(client_ip) != NULL; 119 return tollgate_core_is_client_allowed(client_ip);
202} 120}
203 121
204bool firewall_is_mac_allowed(const char *mac) 122bool firewall_is_mac_allowed(const char *mac)
205{ 123{
206 return find_client_by_mac(mac) != NULL; 124 return tollgate_core_fw_is_mac_allowed(mac);
207} 125}
208 126
209int firewall_client_count(void) 127int firewall_client_count(void)
210{ 128{
211 return s_client_count; 129 return tollgate_core_allowed_client_count();
212} 130}
diff --git a/main/firewall.h b/main/firewall.h
index 77300e2..8d6e1c1 100644
--- a/main/firewall.h
+++ b/main/firewall.h
@@ -19,7 +19,6 @@ void firewall_revoke_all(void);
19bool firewall_is_client_allowed(uint32_t client_ip); 19bool firewall_is_client_allowed(uint32_t client_ip);
20bool firewall_is_mac_allowed(const char *mac); 20bool firewall_is_mac_allowed(const char *mac);
21int firewall_client_count(void); 21int firewall_client_count(void);
22
23esp_err_t firewall_get_mac_for_ip(uint32_t client_ip, char *mac_out, size_t mac_out_size); 22esp_err_t firewall_get_mac_for_ip(uint32_t client_ip, char *mac_out, size_t mac_out_size);
24 23
25int tollgate_ip4_canforward_filter(struct pbuf *p, uint32_t dest_addr_hostorder); 24int tollgate_ip4_canforward_filter(struct pbuf *p, uint32_t dest_addr_hostorder);
diff --git a/main/mining_payment.c b/main/mining_payment.c
index 8c5e4d5..f9d01b6 100644
--- a/main/mining_payment.c
+++ b/main/mining_payment.c
@@ -1,169 +1,66 @@
1#include "mining_payment.h" 1#include "mining_payment.h"
2#include "config.h" 2#include "tollgate_core_mining.h"
3#include "tollgate_core.h"
3#include "esp_log.h" 4#include "esp_log.h"
4#include "freertos/FreeRTOS.h"
5#include "freertos/task.h"
6#include <string.h>
7#include <math.h>
8 5
9static const char *TAG = "mining_payment"; 6static const char *TAG = "mining_payment";
10 7
11static mining_client_stats_t s_clients[MINING_MAX_CLIENTS];
12static int s_client_count = 0;
13static double s_current_hashprice = 0.0;
14static uint32_t s_current_nbits = 0;
15static uint64_t s_current_difficulty = 1;
16
17static int64_t get_time_ms(void)
18{
19 return (int64_t)xTaskGetTickCount() * portTICK_PERIOD_MS;
20}
21
22uint64_t mining_nbits_to_difficulty(uint32_t nbits) 8uint64_t mining_nbits_to_difficulty(uint32_t nbits)
23{ 9{
24 if (nbits == 0) return UINT64_MAX; 10 return tollgate_core_mining_nbits_to_difficulty(nbits);
25
26 uint32_t exponent = (nbits >> 24) & 0xFF;
27 uint32_t mantissa = nbits & 0x007FFFFF;
28
29 if (exponent <= 3) {
30 mantissa >>= (8 * (3 - exponent));
31 if (mantissa == 0) return UINT64_MAX;
32 return 0x00000000FFFF0000ULL / mantissa;
33 }
34
35 uint64_t target = (uint64_t)mantissa << (8 * (exponent - 3));
36 if (target == 0) return UINT64_MAX;
37
38 uint64_t pdiff = 0x00000000FFFF0000ULL;
39 uint64_t diff = pdiff / (target >> (exponent > 7 ? 0 : 0));
40 if (diff == 0) diff = 1;
41 return diff;
42} 11}
43 12
44double mining_calculate_hashprice(uint32_t nbits) 13double mining_calculate_hashprice(uint32_t nbits)
45{ 14{
46 uint64_t diff = mining_nbits_to_difficulty(nbits); 15 return tollgate_core_mining_calc_hashprice(nbits);
47 if (diff == 0 || diff == UINT64_MAX) return 0.0;
48
49 double network_hashrate_th = (double)diff * 4294967296.0 / 1e12;
50 double daily_sats = (double)MINING_BLOCK_SUBSIDY_SATS * (double)MINING_BLOCKS_PER_DAY;
51 double sats_per_th_day = daily_sats / network_hashrate_th;
52 return sats_per_th_day / 1000.0;
53} 16}
54 17
55double mining_calculate_hashprice_override(uint64_t sats_per_ghs_day) 18double mining_calculate_hashprice_override(uint64_t sats_per_ghs_day)
56{ 19{
57 return (double)sats_per_ghs_day; 20 return tollgate_core_mining_calc_hashprice_override(sats_per_ghs_day);
58} 21}
59 22
60esp_err_t mining_validate_share(const uint8_t *header80, uint32_t nonce, const uint8_t *target, int target_len) 23esp_err_t mining_validate_share(const uint8_t *header80, uint32_t nonce, const uint8_t *target, int target_len)
61{ 24{
62 (void)header80; 25 return tollgate_core_mining_validate_share(header80, nonce, target, target_len);
63 (void)nonce;
64 (void)target;
65 (void)target_len;
66 return ESP_OK;
67} 26}
68 27
69uint64_t mining_shares_to_allotment_ms(double hashrate_ghs, double hashprice_sats_per_ghs_s, 28uint64_t mining_shares_to_allotment_ms(double hashrate_ghs, double hashprice_sats_per_ghs_s, int price_per_step, int step_size_ms)
70 int price_per_step, int step_size_ms)
71{ 29{
72 if (hashrate_ghs <= 0.0 || hashprice_sats_per_ghs_s <= 0.0 || price_per_step <= 0) return 0; 30 return tollgate_core_mining_shares_to_allotment_ms(hashrate_ghs, hashprice_sats_per_ghs_s, price_per_step, step_size_ms);
73
74 double sats_per_ms = hashrate_ghs * hashprice_sats_per_ghs_s / 86400000.0;
75 double steps_earned = sats_per_ms * (double)step_size_ms / (double)price_per_step;
76 uint64_t allotment = (uint64_t)(steps_earned * (double)step_size_ms);
77 return allotment > 0 ? allotment : 1;
78} 31}
79 32
80uint64_t mining_shares_to_allotment_bytes(double hashrate_ghs, double hashprice_sats_per_ghs_s, 33uint64_t mining_shares_to_allotment_bytes(double hashrate_ghs, double hashprice_sats_per_ghs_s, int price_per_step, int step_size_bytes)
81 int price_per_step, int step_size_bytes)
82{ 34{
83 if (hashrate_ghs <= 0.0 || hashprice_sats_per_ghs_s <= 0.0 || price_per_step <= 0) return 0; 35 return tollgate_core_mining_shares_to_allotment_bytes(hashrate_ghs, hashprice_sats_per_ghs_s, price_per_step, step_size_bytes);
84
85 double sats_per_ms = hashrate_ghs * hashprice_sats_per_ghs_s / 86400000.0;
86 double steps_earned = sats_per_ms * 1000.0 / (double)price_per_step;
87 uint64_t allotment = (uint64_t)(steps_earned * (double)step_size_bytes);
88 return allotment > 0 ? allotment : 1;
89} 36}
90 37
91mining_client_stats_t *mining_get_or_create_client(uint32_t client_ip) 38mining_client_stats_t *mining_get_or_create_client(uint32_t client_ip)
92{ 39{
93 for (int i = 0; i < s_client_count; i++) { 40 return (mining_client_stats_t *)tollgate_core_mining_get_or_create_client(client_ip);
94 if (s_clients[i].ip == client_ip) return &s_clients[i];
95 }
96
97 if (s_client_count >= MINING_MAX_CLIENTS) {
98 for (int i = 0; i < MINING_MAX_CLIENTS; i++) {
99 int64_t age = get_time_ms() - s_clients[i].last_share_time_ms;
100 if (age > MINING_SHARE_WINDOW_S * 2000) {
101 memset(&s_clients[i], 0, sizeof(mining_client_stats_t));
102 s_clients[i].ip = client_ip;
103 s_clients[i].first_share_time_ms = get_time_ms();
104 return &s_clients[i];
105 }
106 }
107 return NULL;
108 }
109
110 mining_client_stats_t *c = &s_clients[s_client_count];
111 memset(c, 0, sizeof(mining_client_stats_t));
112 c->ip = client_ip;
113 c->first_share_time_ms = get_time_ms();
114 s_client_count++;
115 return c;
116} 41}
117 42
118void mining_update_hashrate(uint32_t client_ip, bool accepted) 43void mining_update_hashrate(uint32_t client_ip, bool accepted)
119{ 44{
120 mining_client_stats_t *stats = mining_get_or_create_client(client_ip); 45 tollgate_core_mining_update_hashrate(client_ip, accepted);
121 if (!stats) return;
122
123 if (accepted) {
124 stats->shares_accepted++;
125 } else {
126 stats->shares_rejected++;
127 }
128 stats->last_share_time_ms = get_time_ms();
129
130 int64_t window_ms = stats->last_share_time_ms - stats->first_share_time_ms;
131 if (window_ms < 1000) window_ms = 1000;
132
133 double window_s = (double)window_ms / 1000.0;
134 double shares_per_s = (double)stats->shares_accepted / window_s;
135 double diff = (s_current_difficulty > 0) ? (double)s_current_difficulty : 1.0;
136 stats->hashrate_ghs = shares_per_s * diff * 4294967296.0 / 1e9;
137} 46}
138 47
139const mining_client_stats_t *mining_get_client_stats(uint32_t client_ip) 48const mining_client_stats_t *mining_get_client_stats(uint32_t client_ip)
140{ 49{
141 for (int i = 0; i < s_client_count; i++) { 50 return (const mining_client_stats_t *)tollgate_core_mining_get_client_stats(client_ip);
142 if (s_clients[i].ip == client_ip) return &s_clients[i];
143 }
144 return NULL;
145} 51}
146 52
147double mining_get_current_hashprice(void) 53double mining_get_current_hashprice(void)
148{ 54{
149 return s_current_hashprice; 55 return tollgate_core_mining_get_current_hashprice();
150} 56}
151 57
152void mining_set_current_nbits(uint32_t nbits) 58void mining_set_current_nbits(uint32_t nbits)
153{ 59{
154 s_current_nbits = nbits; 60 tollgate_core_mining_set_current_nbits(nbits);
155 s_current_difficulty = mining_nbits_to_difficulty(nbits);
156 s_current_hashprice = mining_calculate_hashprice(nbits);
157 ESP_LOGI(TAG, "nbits updated: 0x%08lx, diff=%llu, hashprice=%.6f sat/GH/s/day",
158 (unsigned long)nbits, (unsigned long long)s_current_difficulty, s_current_hashprice);
159} 61}
160 62
161void mining_payment_init(void) 63void mining_payment_init(void)
162{ 64{
163 memset(s_clients, 0, sizeof(s_clients)); 65 ESP_LOGI(TAG, "Mining payment initialized (via tollgate_core)");
164 s_client_count = 0;
165 s_current_hashprice = 0.0;
166 s_current_nbits = 0;
167 s_current_difficulty = 1;
168 ESP_LOGI(TAG, "Mining payment module initialized");
169} 66}
diff --git a/main/session.c b/main/session.c
index feea272..3e3813a 100644
--- a/main/session.c
+++ b/main/session.c
@@ -1,192 +1,86 @@
1#include "session.h" 1#include "session.h"
2#include "firewall.h" 2#include "tollgate_core_session.h"
3#include "dns_server.h" 3#include "tollgate_core_firewall.h"
4#include "config.h" 4#include "tollgate_core.h"
5#include "esp_log.h" 5#include "esp_log.h"
6#include "freertos/FreeRTOS.h" 6#include "freertos/FreeRTOS.h"
7#include "freertos/task.h" 7#include "freertos/task.h"
8#include <string.h> 8#include <string.h>
9 9
10static const char *TAG = "session"; 10static const char *TAG = "session";
11static session_t s_sessions[SESSION_MAX_CLIENTS];
12static int s_session_count = 0;
13
14static int64_t get_time_ms(void)
15{
16 return (int64_t)xTaskGetTickCount() * portTICK_PERIOD_MS;
17}
18 11
19esp_err_t session_manager_init(void) 12esp_err_t session_manager_init(void)
20{ 13{
21 memset(s_sessions, 0, sizeof(s_sessions)); 14 tollgate_core_session_init();
22 s_session_count = 0; 15 ESP_LOGI(TAG, "Session manager initialized (via tollgate_core)");
23 ESP_LOGI(TAG, "Session manager initialized");
24 return ESP_OK; 16 return ESP_OK;
25} 17}
26 18
27static void populate_mac(session_t *session, uint32_t client_ip)
28{
29 if (firewall_get_mac_for_ip(client_ip, session->mac, sizeof(session->mac)) != ESP_OK) {
30 session->mac[0] = '\0';
31 }
32}
33
34session_t *session_create(uint32_t client_ip, uint64_t allotment_ms) 19session_t *session_create(uint32_t client_ip, uint64_t allotment_ms)
35{ 20{
36 session_t *existing = session_find_by_ip(client_ip); 21 return (session_t *)tollgate_core_session_create(client_ip, allotment_ms);
37 if (existing) {
38 session_extend(existing, allotment_ms);
39 return existing;
40 }
41
42 if (s_session_count >= SESSION_MAX_CLIENTS) {
43 for (int i = 0; i < SESSION_MAX_CLIENTS; i++) {
44 if (!s_sessions[i].active || session_is_expired(&s_sessions[i])) {
45 session_revoke(&s_sessions[i]);
46 break;
47 }
48 }
49 }
50
51 for (int i = 0; i < SESSION_MAX_CLIENTS; i++) {
52 if (!s_sessions[i].active) {
53 s_sessions[i].client_ip = client_ip;
54 s_sessions[i].allotment_ms = allotment_ms;
55 s_sessions[i].start_time_ms = get_time_ms();
56 s_sessions[i].active = true;
57 s_sessions[i].payment_method = PAYMENT_METHOD_CASHU;
58 populate_mac(&s_sessions[i], client_ip);
59
60 s_session_count++;
61 firewall_grant_access(client_ip);
62
63 esp_ip4_addr_t ip = { .addr = client_ip };
64 ESP_LOGI(TAG, "Session created: " IPSTR " mac=%s allotment=%llums", IP2STR(&ip),
65 s_sessions[i].mac[0] ? s_sessions[i].mac : "unknown",
66 (unsigned long long)allotment_ms);
67 return &s_sessions[i];
68 }
69 }
70
71 ESP_LOGW(TAG, "No free session slots");
72 return NULL;
73} 22}
74 23
75session_t *session_create_bytes(uint32_t client_ip, uint64_t allotment_bytes) 24session_t *session_create_bytes(uint32_t client_ip, uint64_t allotment_bytes)
76{ 25{
77 session_t *s = session_create(client_ip, 0); 26 return (session_t *)tollgate_core_session_create_bytes(client_ip, allotment_bytes);
78 if (s) {
79 s->allotment_bytes = allotment_bytes;
80 s->bytes_consumed = 0;
81 s->allotment_ms = INT64_MAX;
82 s->payment_method = PAYMENT_METHOD_BYTES;
83 esp_ip4_addr_t ip = { .addr = client_ip };
84 ESP_LOGI(TAG, "Bytes session created: " IPSTR " allotment=%llu bytes", IP2STR(&ip),
85 (unsigned long long)allotment_bytes);
86 }
87 return s;
88} 27}
89 28
90void session_add_bytes(uint32_t client_ip, uint64_t bytes) 29void session_add_bytes(uint32_t client_ip, uint64_t bytes)
91{ 30{
92 session_t *s = session_find_by_ip(client_ip); 31 tollgate_core_session_add_bytes(client_ip, bytes);
93 if (s && s->active) {
94 s->bytes_consumed += bytes;
95 }
96} 32}
97 33
98session_t *session_find_by_ip(uint32_t client_ip) 34session_t *session_find_by_ip(uint32_t client_ip)
99{ 35{
100 for (int i = 0; i < SESSION_MAX_CLIENTS; i++) { 36 return (session_t *)tollgate_core_session_find_by_ip(client_ip);
101 if (s_sessions[i].active && s_sessions[i].client_ip == client_ip) {
102 return &s_sessions[i];
103 }
104 }
105 return NULL;
106} 37}
107 38
108session_t *session_find_by_mac(const char *mac) 39session_t *session_find_by_mac(const char *mac)
109{ 40{
110 for (int i = 0; i < SESSION_MAX_CLIENTS; i++) { 41 return (session_t *)tollgate_core_session_find_by_mac(mac);
111 if (s_sessions[i].active && s_sessions[i].mac[0] != '\0' &&
112 strcmp(s_sessions[i].mac, mac) == 0) {
113 return &s_sessions[i];
114 }
115 }
116 return NULL;
117} 42}
118 43
119void session_extend(session_t *session, uint64_t additional_ms) 44void session_extend(session_t *session, uint64_t additional_ms)
120{ 45{
121 if (!session || !session->active) return; 46 tollgate_core_session_extend((tg_session_t *)session, additional_ms);
122 session->allotment_ms += additional_ms;
123 esp_ip4_addr_t ip = { .addr = session->client_ip };
124 ESP_LOGI(TAG, "Session extended: " IPSTR " +%llums (total=%llu)", IP2STR(&ip),
125 (unsigned long long)additional_ms, (unsigned long long)session->allotment_ms);
126} 47}
127 48
128bool session_is_expired(const session_t *session) 49bool session_is_expired(const session_t *session)
129{ 50{
130 if (!session || !session->active) return true; 51 return tollgate_core_session_is_expired((const tg_session_t *)session);
131
132 const tollgate_config_t *cfg = tollgate_config_get();
133 if (cfg && strcmp(cfg->metric, "bytes") == 0) {
134 return session->bytes_consumed >= session->allotment_bytes;
135 }
136
137 int64_t elapsed = get_time_ms() - session->start_time_ms;
138 return elapsed >= (int64_t)session->allotment_ms;
139} 52}
140 53
141void session_check_expiry(void) 54void session_check_expiry(void)
142{ 55{
143 for (int i = 0; i < SESSION_MAX_CLIENTS; i++) {
144 if (s_sessions[i].active && session_is_expired(&s_sessions[i])) {
145 esp_ip4_addr_t ip = { .addr = s_sessions[i].client_ip };
146 ESP_LOGI(TAG, "Session expired: " IPSTR " mac=%s", IP2STR(&ip),
147 s_sessions[i].mac[0] ? s_sessions[i].mac : "unknown");
148 session_revoke(&s_sessions[i]);
149 }
150 }
151} 56}
152 57
153void session_revoke(session_t *session) 58void session_revoke(session_t *session)
154{ 59{
155 if (!session || !session->active) return; 60 tollgate_core_session_revoke((tg_session_t *)session);
156 firewall_revoke_access(session->client_ip);
157 session->active = false;
158 s_session_count--;
159} 61}
160 62
161void session_revoke_all(void) 63void session_revoke_all(void)
162{ 64{
163 for (int i = 0; i < SESSION_MAX_CLIENTS; i++) { 65 tollgate_core_session_revoke_all();
164 if (s_sessions[i].active) {
165 session_revoke(&s_sessions[i]);
166 }
167 }
168} 66}
169 67
170int session_active_count(void) 68int session_active_count(void)
171{ 69{
172 int count = 0; 70 return tollgate_core_active_session_count();
173 for (int i = 0; i < SESSION_MAX_CLIENTS; i++) {
174 if (s_sessions[i].active) count++;
175 }
176 return count;
177} 71}
178 72
179void session_tick(void) 73void session_tick(void)
180{ 74{
181 session_check_expiry(); 75 tollgate_core_tick();
182} 76}
183 77
184session_t *cvm_get_sessions_array(void) 78session_t *cvm_get_sessions_array(void)
185{ 79{
186 return s_sessions; 80 return (session_t *)tollgate_core_session_get_array();
187} 81}
188 82
189int cvm_get_sessions_count(void) 83int cvm_get_sessions_count(void)
190{ 84{
191 return SESSION_MAX_CLIENTS; 85 return tollgate_core_session_get_array_size();
192} 86}
diff --git a/main/session.h b/main/session.h
index d3a61bb..8f6b991 100644
--- a/main/session.h
+++ b/main/session.h
@@ -26,30 +26,18 @@ typedef struct {
26} session_t; 26} session_t;
27 27
28esp_err_t session_manager_init(void); 28esp_err_t session_manager_init(void);
29
30session_t *session_create(uint32_t client_ip, uint64_t allotment_ms); 29session_t *session_create(uint32_t client_ip, uint64_t allotment_ms);
31
32session_t *session_create_bytes(uint32_t client_ip, uint64_t allotment_bytes); 30session_t *session_create_bytes(uint32_t client_ip, uint64_t allotment_bytes);
33
34void session_add_bytes(uint32_t client_ip, uint64_t bytes); 31void session_add_bytes(uint32_t client_ip, uint64_t bytes);
35
36session_t *session_find_by_ip(uint32_t client_ip); 32session_t *session_find_by_ip(uint32_t client_ip);
37session_t *session_find_by_mac(const char *mac); 33session_t *session_find_by_mac(const char *mac);
38
39void session_extend(session_t *session, uint64_t additional_ms); 34void session_extend(session_t *session, uint64_t additional_ms);
40
41bool session_is_expired(const session_t *session); 35bool session_is_expired(const session_t *session);
42
43void session_check_expiry(void); 36void session_check_expiry(void);
44
45void session_revoke(session_t *session); 37void session_revoke(session_t *session);
46
47void session_revoke_all(void); 38void session_revoke_all(void);
48
49int session_active_count(void); 39int session_active_count(void);
50
51void session_tick(void); 40void session_tick(void);
52
53session_t *cvm_get_sessions_array(void); 41session_t *cvm_get_sessions_array(void);
54int cvm_get_sessions_count(void); 42int cvm_get_sessions_count(void);
55 43
diff --git a/main/tollgate_main.c b/main/tollgate_main.c
index 2d4fa22..2d1f657 100644
--- a/main/tollgate_main.c
+++ b/main/tollgate_main.c
@@ -12,6 +12,8 @@
12#include "lwip/dns.h" 12#include "lwip/dns.h"
13#include "esp_sntp.h" 13#include "esp_sntp.h"
14#include "dhcpserver/dhcpserver.h" 14#include "dhcpserver/dhcpserver.h"
15#include "tollgate_core.h"
16#include "tollgate_esp_platform.h"
15#include "config.h" 17#include "config.h"
16#include "identity.h" 18#include "identity.h"
17#include "dns_server.h" 19#include "dns_server.h"
@@ -233,6 +235,7 @@ static void start_services(void)
233 IP2STR(&(esp_ip4_addr_t){.addr=dns_getserver(1)->addr}), 235 IP2STR(&(esp_ip4_addr_t){.addr=dns_getserver(1)->addr}),
234 IP2STR(&(esp_ip4_addr_t){.addr=dns_getserver(2)->addr})); 236 IP2STR(&(esp_ip4_addr_t){.addr=dns_getserver(2)->addr}));
235 237
238 tollgate_core_init(tollgate_esp_get_platform(), ap_ip_info.ip);
236 firewall_init(ap_ip_info.ip); 239 firewall_init(ap_ip_info.ip);
237 session_manager_init(); 240 session_manager_init();
238 241