Skip to content

Commit 36949cb

Browse files
Call disable function for STA/AP modes. (#387)
If the user presses "d" wifi is disconnected and the example exits. Tests new "disable" functions. Fixes #386
1 parent 77883ed commit 36949cb

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

pico_w/wifi/access_point/picow_access_point.c

+34-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ typedef struct TCP_SERVER_T_ {
3030
struct tcp_pcb *server_pcb;
3131
bool complete;
3232
ip_addr_t gw;
33+
async_context_t *context;
3334
} TCP_SERVER_T;
3435

3536
typedef struct TCP_CONNECT_STATE_T_ {
@@ -236,7 +237,7 @@ static err_t tcp_server_accept(void *arg, struct tcp_pcb *client_pcb, err_t err)
236237
return ERR_OK;
237238
}
238239

239-
static bool tcp_server_open(void *arg) {
240+
static bool tcp_server_open(void *arg, const char *ap_name) {
240241
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
241242
DEBUG_printf("starting server on port %d\n", TCP_PORT);
242243

@@ -264,9 +265,31 @@ static bool tcp_server_open(void *arg) {
264265
tcp_arg(state->server_pcb, state);
265266
tcp_accept(state->server_pcb, tcp_server_accept);
266267

268+
printf("Try connecting to '%s' (press 'd' to disable access point)\n", ap_name);
267269
return true;
268270
}
269271

272+
// This "worker" function is called to safely perform work when instructed by key_pressed_func
273+
void key_pressed_worker_func(async_context_t *context, async_when_pending_worker_t *worker) {
274+
assert(worker->user_data);
275+
printf("Disabling wifi\n");
276+
cyw43_arch_disable_ap_mode();
277+
((TCP_SERVER_T*)(worker->user_data))->complete = true;
278+
}
279+
280+
static async_when_pending_worker_t key_pressed_worker = {
281+
.do_work = key_pressed_worker_func
282+
};
283+
284+
void key_pressed_func(void *param) {
285+
assert(param);
286+
int key = getchar_timeout_us(0); // get any pending key press but don't wait
287+
if (key == 'd' || key == 'D') {
288+
// We are probably in irq context so call wifi in a "worker"
289+
async_context_set_work_pending(((TCP_SERVER_T*)param)->context, &key_pressed_worker);
290+
}
291+
}
292+
270293
int main() {
271294
stdio_init_all();
272295

@@ -280,6 +303,13 @@ int main() {
280303
DEBUG_printf("failed to initialise\n");
281304
return 1;
282305
}
306+
307+
// Get notified if the user presses a key
308+
state->context = cyw43_arch_async_context();
309+
key_pressed_worker.user_data = state;
310+
async_context_add_when_pending_worker(cyw43_arch_async_context(), &key_pressed_worker);
311+
stdio_set_chars_available_callback(key_pressed_func, state);
312+
283313
const char *ap_name = "picow_test";
284314
#if 1
285315
const char *password = "password";
@@ -301,11 +331,12 @@ int main() {
301331
dns_server_t dns_server;
302332
dns_server_init(&dns_server, &state->gw);
303333

304-
if (!tcp_server_open(state)) {
334+
if (!tcp_server_open(state, ap_name)) {
305335
DEBUG_printf("failed to open server\n");
306336
return 1;
307337
}
308338

339+
state->complete = false;
309340
while(!state->complete) {
310341
// the following #ifdef is only here so this same example can be used in multiple modes;
311342
// you do not need it in your code
@@ -323,6 +354,7 @@ int main() {
323354
sleep_ms(1000);
324355
#endif
325356
}
357+
tcp_server_close(state);
326358
dns_server_deinit(&dns_server);
327359
dhcp_server_deinit(&dhcp_server);
328360
cyw43_arch_deinit();

pico_w/wifi/iperf/picow_iperf.c

+25-2
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,38 @@ static void iperf_report(void *arg, enum lwiperf_report_type report_type,
3636
#endif
3737
}
3838

39+
// This "worker" function is called to safely perform work when instructed by key_pressed_func
40+
void key_pressed_worker_func(async_context_t *context, async_when_pending_worker_t *worker) {
41+
printf("Disabling wifi\n");
42+
cyw43_arch_disable_sta_mode();
43+
}
44+
45+
static async_when_pending_worker_t key_pressed_worker = {
46+
.do_work = key_pressed_worker_func
47+
};
48+
49+
void key_pressed_func(void *param) {
50+
int key = getchar_timeout_us(0); // get any pending key press but don't wait
51+
if (key == 'd' || key == 'D') {
52+
// We are probably in irq context so call wifi in a "worker"
53+
async_context_set_work_pending((async_context_t*)param, &key_pressed_worker);
54+
}
55+
}
56+
3957
int main() {
4058
stdio_init_all();
4159

4260
if (cyw43_arch_init()) {
4361
printf("failed to initialise\n");
4462
return 1;
4563
}
64+
65+
// Get notified if the user presses a key
66+
async_context_add_when_pending_worker(cyw43_arch_async_context(), &key_pressed_worker);
67+
stdio_set_chars_available_callback(key_pressed_func, cyw43_arch_async_context());
68+
4669
cyw43_arch_enable_sta_mode();
47-
printf("Connecting to Wi-Fi...\n");
70+
printf("Connecting to Wi-Fi... (press 'd' to disconnect)\n");
4871
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) {
4972
printf("failed to connect.\n");
5073
return 1;
@@ -64,7 +87,7 @@ int main() {
6487
#endif
6588
cyw43_arch_lwip_end();
6689

67-
while(true) {
90+
while(cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_DOWN) {
6891
#if USE_LED
6992
static absolute_time_t led_time;
7093
static int led_on = true;

0 commit comments

Comments
 (0)