Files
mongoose/tutorials/rp/pico-w/wifi.c
T

121 lines
4.2 KiB
C

// Copyright (c) 2026 Cesanta Software Limited
// All rights reserved
#include "mongoose.h"
#define WIFI_NAME "YOUR_WIFI_NETWORK" // SET THIS!
#define WIFI_PASS "YOUR_WIFI_PASSWORD" // SET THIS!
// Access point setup
#define ENABLE_AP false // Change to true to enable
#define WIFI_AP_NAME "YOUR_AP_NETWORK" // SET THIS!
#define WIFI_AP_PASS "YOUR_AP_PASSWORD" // SET THIS!
// mif user states
enum { AP, SCANNING, STOPPING_AP, CONNECTING, READY };
static unsigned int state;
static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
// TODO(): should we include this inside ifp ? add an fn_data ?
if (ev == MG_TCPIP_EV_STATE_CHANGE) {
MG_INFO(("State change: %u", *(uint8_t *) ev_data));
}
switch (state) {
case AP: // we are in AP mode, wait for a user connection to trigger a scan
// or a connection to a network
if (ev == MG_TCPIP_EV_STATE_CHANGE &&
*(uint8_t *) ev_data == MG_TCPIP_STATE_READY) {
MG_INFO(("Access Point READY !"));
// simulate user request to scan for networks
bool res = mg_wifi_scan();
MG_INFO(("Starting scan: %s", res ? "OK" : "FAIL"));
if (res) state = SCANNING;
}
break;
case SCANNING:
if (ev == MG_TCPIP_EV_WIFI_SCAN_RESULT) {
struct mg_wifi_scan_bss_data *bss =
(struct mg_wifi_scan_bss_data *) ev_data;
MG_INFO(("BSS: %.*s (%u) (%M) %d dBm %u", bss->SSID.len, bss->SSID.buf,
bss->channel, mg_print_mac, bss->BSSID, (int) bss->RSSI,
bss->security));
} else if (ev == MG_TCPIP_EV_WIFI_SCAN_END) {
struct mg_tcpip_driver_pico_w_data *d =
(struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
MG_INFO(("Wi-Fi scan finished"));
// simulate user selection of a network (1/2: stop AP)
bool res = mg_wifi_ap_stop();
MG_INFO(("Manually stopping AP: %s", res ? "OK" : "FAIL"));
if (res) state = STOPPING_AP;
// else we have a hw/fw problem
}
break;
case STOPPING_AP:
if (ev == MG_TCPIP_EV_STATE_CHANGE &&
*(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) {
struct mg_wifi_data *wifi =
&((struct mg_tcpip_driver_pico_w_data *) ifp->driver_data)->wifi;
wifi->apmode = false;
// simulate user selection of a network (2/2: actual connect)
bool res = mg_wifi_connect(wifi);
MG_INFO(("Manually connecting: %s", res ? "OK" : "FAIL"));
if (res) {
state = CONNECTING;
} // else manually start AP as below
}
break;
case CONNECTING:
if (ev == MG_TCPIP_EV_STATE_CHANGE &&
*(uint8_t *) ev_data == MG_TCPIP_STATE_READY) {
MG_INFO(("READY!"));
state = READY;
// simulate user code disconnection and go back to AP mode (1/2:
// disconnect)
bool res = mg_wifi_disconnect();
MG_INFO(("Manually disconnecting: %s", res ? "OK" : "FAIL"));
} else if (ev == MG_TCPIP_EV_WIFI_CONNECT_ERR) {
MG_ERROR(("Wi-Fi connect failed"));
// manually start AP as below
}
break;
case READY:
// go back to AP mode after a disconnection (simulation 2/2), you could
// retry
if (ev == MG_TCPIP_EV_STATE_CHANGE &&
*(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) {
struct mg_wifi_data *wifi =
&((struct mg_tcpip_driver_pico_w_data *) ifp->driver_data)->wifi;
bool res = mg_wifi_ap_start(wifi);
MG_INFO(("Disconnected"));
MG_INFO(("Manually starting AP: %s", res ? "OK" : "FAIL"));
if (res) {
state = AP;
wifi->apmode = true;
}
}
break;
}
}
void wifi_setconfig(void *ifp, void *driver_data) {
struct mg_tcpip_driver_pico_w_data *d =
(struct mg_tcpip_driver_pico_w_data *) driver_data;
struct mg_wifi_data *wifi = &d->wifi;
wifi->ssid = WIFI_NAME;
wifi->pass = WIFI_PASS;
wifi->apssid = WIFI_AP_NAME;
wifi->appass = WIFI_AP_PASS;
wifi->apip = MG_IPV4(192, 168, 111, 1);
wifi->apmask = MG_IPV4(255, 255, 255, 0);
wifi->security = 0;
wifi->apsecurity = 0;
wifi->apchannel = 10;
wifi->apmode = ENABLE_AP;
((struct mg_tcpip_if *) ifp)->fn = mif_fn;
}