|
@@ -19,13 +19,22 @@
|
19
|
19
|
#include "pico/cyw43_arch.h"
|
20
|
20
|
#include "lwip/netif.h"
|
21
|
21
|
#include "lwip/ip4_addr.h"
|
|
22
|
+#include "dhcpserver.h"
|
22
|
23
|
|
23
|
24
|
#include "config.h"
|
24
|
25
|
#include "log.h"
|
25
|
26
|
#include "mem.h"
|
|
27
|
+#include "usb_descriptors.h"
|
26
|
28
|
#include "wifi.h"
|
27
|
29
|
|
28
|
|
-#define CONNECT_TIMEOUT (5 * 1000)
|
|
30
|
+#define CONNECT_TIMEOUT_MS (8UL * 1000UL)
|
|
31
|
+#define SCAN_AP_TIMEOUT_MS (20UL * 1000UL)
|
|
32
|
+
|
|
33
|
+#define WIFI_AP_SSID_PREFIX "Volcano-"
|
|
34
|
+#define WIFI_AP_SSID_LEN 4
|
|
35
|
+#define WIFI_AP_PASS_LEN 8
|
|
36
|
+static_assert((WIFI_AP_SSID_LEN + WIFI_AP_PASS_LEN) <= (2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES),
|
|
37
|
+ "SSID and Password parts for AP need to fit Pico serial number");
|
29
|
38
|
|
30
|
39
|
enum wifi_state {
|
31
|
40
|
WS_IDLE = 0,
|
|
@@ -36,12 +45,58 @@ enum wifi_state {
|
36
|
45
|
};
|
37
|
46
|
|
38
|
47
|
static enum wifi_state state = WS_IDLE;
|
39
|
|
-static uint32_t start_time = 0;
|
|
48
|
+static uint32_t start_scan_time = 0;
|
|
49
|
+static uint32_t start_connect_time = 0;
|
|
50
|
+static uint32_t start_ip_time = 0;
|
|
51
|
+static dhcp_server_t dhcp_server;
|
|
52
|
+static bool enabled_ap = false;
|
|
53
|
+static char curr_ssid[WIFI_MAX_NAME_LEN + 1] = {0};
|
|
54
|
+static char curr_pass[WIFI_MAX_PASS_LEN + 1] = {0};
|
|
55
|
+
|
|
56
|
+static void wifi_ap(void) {
|
|
57
|
+ cyw43_thread_enter();
|
|
58
|
+
|
|
59
|
+ // last N chars of serial for ssid and password
|
|
60
|
+ const size_t prefix_len = strlen(WIFI_AP_SSID_PREFIX);
|
|
61
|
+ char wifi_ssid[prefix_len + WIFI_AP_SSID_LEN + 1];
|
|
62
|
+ memcpy(wifi_ssid, WIFI_AP_SSID_PREFIX, prefix_len);
|
|
63
|
+ memcpy(wifi_ssid + prefix_len,
|
|
64
|
+ string_pico_serial + (2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES) - WIFI_AP_SSID_LEN,
|
|
65
|
+ WIFI_AP_SSID_LEN);
|
|
66
|
+ wifi_ssid[prefix_len + WIFI_AP_SSID_LEN] = '\0';
|
|
67
|
+ strncpy(curr_ssid, wifi_ssid, WIFI_MAX_NAME_LEN);
|
|
68
|
+
|
|
69
|
+ char wifi_pass[WIFI_AP_PASS_LEN + 1] = {0};
|
|
70
|
+ memcpy(wifi_pass,
|
|
71
|
+ string_pico_serial + (2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES) - WIFI_AP_SSID_LEN - WIFI_AP_PASS_LEN,
|
|
72
|
+ WIFI_AP_PASS_LEN);
|
|
73
|
+ strncpy(curr_pass, wifi_pass, WIFI_MAX_PASS_LEN);
|
|
74
|
+
|
|
75
|
+ debug("disable sta");
|
|
76
|
+ cyw43_arch_disable_sta_mode();
|
|
77
|
+
|
|
78
|
+ debug("enable ap '%s' '%s'", wifi_ssid, wifi_pass);
|
|
79
|
+ cyw43_arch_enable_ap_mode(wifi_ssid, wifi_pass, CYW43_AUTH_WPA2_AES_PSK);
|
|
80
|
+
|
|
81
|
+ ip4_addr_t gw, mask;
|
|
82
|
+ IP4_ADDR(&gw, 192, 168, 4, 1);
|
|
83
|
+ IP4_ADDR(&mask, 255, 255, 255, 0);
|
|
84
|
+
|
|
85
|
+ debug("enable dhcp");
|
|
86
|
+ dhcp_server_init(&dhcp_server, &gw, &mask);
|
|
87
|
+
|
|
88
|
+ state = WS_READY;
|
|
89
|
+ enabled_ap = true;
|
|
90
|
+
|
|
91
|
+ cyw43_thread_exit();
|
|
92
|
+}
|
40
|
93
|
|
41
|
94
|
static void wifi_connect(const char *ssid, const char *pw, uint32_t auth) {
|
|
95
|
+ cyw43_thread_enter();
|
|
96
|
+
|
42
|
97
|
debug("connecting to '%s'", ssid);
|
43
|
|
- start_time = to_ms_since_boot(get_absolute_time());
|
44
|
|
- state = WS_CONNECT;
|
|
98
|
+ strncpy(curr_ssid, ssid, WIFI_MAX_NAME_LEN);
|
|
99
|
+ strncpy(curr_pass, pw, WIFI_MAX_PASS_LEN);
|
45
|
100
|
|
46
|
101
|
// https://github.com/raspberrypi/pico-sdk/issues/1413
|
47
|
102
|
uint32_t a = 0;
|
|
@@ -55,7 +110,12 @@ static void wifi_connect(const char *ssid, const char *pw, uint32_t auth) {
|
55
|
110
|
if (r != 0) {
|
56
|
111
|
debug("failed to connect %d", r);
|
57
|
112
|
state = WS_SCAN;
|
|
113
|
+ } else {
|
|
114
|
+ start_connect_time = to_ms_since_boot(get_absolute_time());
|
|
115
|
+ state = WS_CONNECT;
|
58
|
116
|
}
|
|
117
|
+
|
|
118
|
+ cyw43_thread_exit();
|
59
|
119
|
}
|
60
|
120
|
|
61
|
121
|
static int scan_result(void *env, const cyw43_ev_scan_result_t *result) {
|
|
@@ -96,15 +156,27 @@ void wifi_init(void) {
|
96
|
156
|
}
|
97
|
157
|
|
98
|
158
|
cyw43_thread_enter();
|
|
159
|
+
|
99
|
160
|
cyw43_arch_enable_sta_mode();
|
|
161
|
+
|
100
|
162
|
wifi_scan();
|
|
163
|
+ start_scan_time = to_ms_since_boot(get_absolute_time());
|
|
164
|
+
|
101
|
165
|
cyw43_thread_exit();
|
102
|
166
|
}
|
103
|
167
|
|
104
|
168
|
void wifi_deinit(void) {
|
105
|
169
|
cyw43_thread_enter();
|
|
170
|
+
|
106
|
171
|
cyw43_arch_disable_sta_mode();
|
|
172
|
+ cyw43_arch_disable_ap_mode();
|
107
|
173
|
state = WS_IDLE;
|
|
174
|
+
|
|
175
|
+ if (enabled_ap) {
|
|
176
|
+ enabled_ap = false;
|
|
177
|
+ dhcp_server_deinit(&dhcp_server);
|
|
178
|
+ }
|
|
179
|
+
|
108
|
180
|
cyw43_thread_exit();
|
109
|
181
|
}
|
110
|
182
|
|
|
@@ -131,11 +203,21 @@ const char *wifi_state(void) {
|
131
|
203
|
return "Waiting for IP";
|
132
|
204
|
|
133
|
205
|
case WS_READY: {
|
134
|
|
- cyw43_arch_lwip_begin();
|
135
|
|
- const ip4_addr_t *ip = netif_ip4_addr(netif_default);
|
136
|
|
- cyw43_arch_lwip_end();
|
137
|
|
-
|
138
|
|
- return ip4addr_ntoa(ip);
|
|
206
|
+ uint32_t now = to_ms_since_boot(get_absolute_time()) % (enabled_ap ? 9000 : 6000);
|
|
207
|
+ if (now < 3000) {
|
|
208
|
+ // show SSID
|
|
209
|
+ return curr_ssid;
|
|
210
|
+ } else if (now < 6000) {
|
|
211
|
+ // show IP
|
|
212
|
+ cyw43_arch_lwip_begin();
|
|
213
|
+ const ip4_addr_t *ip = netif_ip4_addr(netif_default);
|
|
214
|
+ cyw43_arch_lwip_end();
|
|
215
|
+
|
|
216
|
+ return ip4addr_ntoa(ip);
|
|
217
|
+ } else {
|
|
218
|
+ // show Pass (only AP)
|
|
219
|
+ return curr_pass;
|
|
220
|
+ }
|
139
|
221
|
}
|
140
|
222
|
}
|
141
|
223
|
|
|
@@ -150,6 +232,12 @@ void wifi_run(void) {
|
150
|
232
|
debug("restarting scan");
|
151
|
233
|
wifi_scan();
|
152
|
234
|
}
|
|
235
|
+
|
|
236
|
+ uint32_t now = to_ms_since_boot(get_absolute_time());
|
|
237
|
+ if ((now - start_scan_time) >= SCAN_AP_TIMEOUT_MS) {
|
|
238
|
+ debug("wifi sta timeout. opening ap.");
|
|
239
|
+ wifi_ap();
|
|
240
|
+ }
|
153
|
241
|
} else if (state == WS_CONNECT) {
|
154
|
242
|
int link = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA);
|
155
|
243
|
|
|
@@ -161,7 +249,7 @@ void wifi_run(void) {
|
161
|
249
|
|
162
|
250
|
if (link == CYW43_LINK_JOIN) {
|
163
|
251
|
debug("joined network");
|
164
|
|
- start_time = to_ms_since_boot(get_absolute_time());
|
|
252
|
+ start_ip_time = to_ms_since_boot(get_absolute_time());
|
165
|
253
|
state = WS_WAIT_FOR_IP;
|
166
|
254
|
} else if (link < CYW43_LINK_DOWN) {
|
167
|
255
|
debug("net connection failed. retry.");
|
|
@@ -169,7 +257,7 @@ void wifi_run(void) {
|
169
|
257
|
}
|
170
|
258
|
|
171
|
259
|
uint32_t now = to_ms_since_boot(get_absolute_time());
|
172
|
|
- if ((now - start_time) >= CONNECT_TIMEOUT) {
|
|
260
|
+ if ((now - start_connect_time) >= CONNECT_TIMEOUT_MS) {
|
173
|
261
|
debug("net connection timeout. retry.");
|
174
|
262
|
wifi_scan();
|
175
|
263
|
}
|
|
@@ -184,9 +272,8 @@ void wifi_run(void) {
|
184
|
272
|
}
|
185
|
273
|
|
186
|
274
|
uint32_t now = to_ms_since_boot(get_absolute_time());
|
187
|
|
- if ((now - start_time) >= CONNECT_TIMEOUT) {
|
|
275
|
+ if ((now - start_ip_time) >= CONNECT_TIMEOUT_MS) {
|
188
|
276
|
debug("net dhcp timeout. retry.");
|
189
|
|
- start_time = now;
|
190
|
277
|
|
191
|
278
|
//cyw43_arch_lwip_begin();
|
192
|
279
|
//dhcp_renew(netif_default);
|