diff --git a/mongoose.c b/mongoose.c index acad42a1..f53044b2 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4157,6 +4157,7 @@ void mg_mgr_init(struct mg_mgr *mgr) { #endif + #if MG_ENABLE_TCPIP #define MG_EPHEMERAL_PORT_BASE 32768 #define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a)))) @@ -4315,6 +4316,25 @@ struct pkt { }; static void mg_tcpip_call(struct mg_tcpip_if *ifp, int ev, void *ev_data) { +#if MG_ENABLE_PROFILE + const char *names[] = { + "TCPIP_EV_ST_CHG", + "TCPIP_EV_DHCP_DNS", + "TCPIP_EV_DHCP_SNTP", + "TCPIP_EV_ARP", + "TCPIP_EV_TIMER_1S", + "TCPIP_EV_WIFI_SCAN_RESULT", + "TCPIP_EV_WIFI_SCAN_END", + "TCPIP_EV_WIFI_CONNECT_ERR", + "TCPIP_EV_DRIVER", + "TCPIP_EV_USER" + }; + if (ev != MG_TCPIP_EV_POLL && ev < (int) (sizeof(names) / sizeof(names[0]))) { + MG_PROF_ADD(c, names[ev]); + } +#endif + // Fire protocol handler first, user handler second. See #2559 + if (ifp->pfn != NULL) ifp->pfn(ifp, ev, ev_data); if (ifp->fn != NULL) ifp->fn(ifp, ev, ev_data); } @@ -20177,9 +20197,8 @@ bool mg_wifi_scan(void) { return false; } -bool mg_wifi_connect(char *ssid, char *pass) { - (void) ssid; - (void) pass; +bool mg_wifi_connect(struct mg_wifi_data *wifi) { + (void) wifi; return mg_wifi_scan(); } @@ -20187,10 +20206,8 @@ bool mg_wifi_disconnect(void) { return mg_wifi_scan(); } -bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) { - (void) ssid; - (void) pass; - (void) channel; +bool mg_wifi_ap_start(struct mg_wifi_data *wifi) { + (void) wifi; return mg_wifi_scan(); } @@ -20651,28 +20668,44 @@ static size_t cmsis_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) { #endif static struct mg_tcpip_if *s_ifp; +static uint32_t s_ip, s_mask; static bool s_link, s_auth, s_join; +static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) { + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_data *) ifp->driver_data)->wifi; + if (wifi->apmode && ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) { + MG_DEBUG(("Access Point started")); + s_ip = ifp->ip, ifp->ip = wifi->apip; + s_mask = ifp->mask, ifp->mask = wifi->apmask; + ifp->enable_dhcp_client = false; + ifp->enable_dhcp_server = true; + } +} + static bool cyw_init(uint8_t *mac); static void cyw_poll(void); static bool mg_tcpip_driver_cyw_init(struct mg_tcpip_if *ifp) { struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; + struct mg_wifi_data *wifi = &d->wifi; if (MG_BIG_ENDIAN) { MG_ERROR(("Big-endian host")); return false; } s_ifp = ifp; + s_ip = ifp->ip; + s_mask = ifp->mask; s_link = s_auth = s_join = false; + ifp->pfn = wifi_cb; if (!cyw_init(ifp->mac)) return false; - if (d->apmode) { - MG_DEBUG(("Starting AP '%s' (%u)", d->apssid, d->apchannel)); - return mg_wifi_ap_start(d->apssid, d->appass, d->apchannel); - } else if (d->ssid != NULL && d->pass != NULL) { - MG_DEBUG(("Connecting to '%s'", d->ssid)); - return mg_wifi_connect(d->ssid, d->pass); + if (wifi->apmode) { + MG_DEBUG(("Starting AP '%s' (%u)", wifi->apssid, wifi->apchannel)); + return mg_wifi_ap_start(wifi); + } else if (wifi->ssid != NULL && wifi->pass != NULL) { + MG_DEBUG(("Connecting to '%s'", wifi->ssid)); + return mg_wifi_connect(wifi); } return true; } @@ -20682,7 +20715,7 @@ size_t mg_tcpip_driver_cyw_output(const void *buf, size_t len, struct mg_tcpip_if *ifp) { struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - return mg_cyw_tx(d->apmode ? 1 : 0, (void *) buf, len) >= len ? len : 0; + return mg_cyw_tx(d->wifi.apmode ? 1 : 0, (void *) buf, len) >= len ? len : 0; } static bool mg_tcpip_driver_cyw_poll(struct mg_tcpip_if *ifp, bool s1) { @@ -20690,7 +20723,7 @@ static bool mg_tcpip_driver_cyw_poll(struct mg_tcpip_if *ifp, bool s1) { if (!s1) return false; struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - return d->apmode ? s_link : s_link && s_auth && s_join; + return d->wifi.apmode ? s_link : s_link && s_auth && s_join; } struct mg_tcpip_driver mg_tcpip_driver_cyw = {mg_tcpip_driver_cyw_init, @@ -21673,7 +21706,7 @@ static size_t cyw_spi_poll(uint8_t *response) { cyw_spi_write(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_INT, &val, sizeof(val)); return 0; } - cyw_spi_read(CYW_SPID_FUNC_WLAN, 0, response, len); + cyw_spi_read(CYW_SPID_FUNC_WLAN, 0, response, (uint16_t)len); return len; } @@ -21736,7 +21769,7 @@ static bool cyw_spi_init() { cyw_set_backplane_window(CYW_CHIP_CHIPCOMMON); // set backplane window to start of CHIPCOMMON area cyw_spi_read(CYW_SPID_FUNC_CHIP, (CYW_CHIP_CHIPCOMMON + 0x00) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 2); if (val == 43430) val = 4343; - MG_INFO(("WLAN chip is CYW%u%c", val), val == 4343 ? 'W' : ' ')); + MG_INFO(("WLAN chip is CYW%u%c", val, val == 4343 ? 'W' : ' ')); // Load firmware (code and NVRAM) if (!cyw_load_firmware(d->fw)) return false; @@ -22014,16 +22047,21 @@ bool mg_wifi_scan(void) { return cyw_wifi_scan(); } -bool mg_wifi_connect(char *ssid, char *pass) { - return cyw_wifi_connect(ssid, pass); +bool mg_wifi_connect(struct mg_wifi_data *wifi) { + s_ifp->ip = s_ip; + s_ifp->mask = s_mask; + if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true; + s_ifp->enable_dhcp_server = false; + MG_DEBUG(("Connecting to %s", wifi->ssid)); + return cyw_wifi_connect(wifi->ssid, wifi->pass); } bool mg_wifi_disconnect(void) { return cyw_wifi_disconnect(); } -bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) { - return cyw_wifi_ap_start(ssid, pass, channel); +bool mg_wifi_ap_start(struct mg_wifi_data *wifi) { + return cyw_wifi_ap_start(wifi->apssid, wifi->appass, wifi->apchannel); } bool mg_wifi_ap_stop(void) { @@ -22419,23 +22457,43 @@ bool mg_phy_up(struct mg_phy *phy, uint8_t phy_addr, bool *full_duplex, static struct mg_tcpip_if *s_ifp; +static uint32_t s_ip, s_mask; +static bool s_aplink = false, s_scanning = false; +static bool s_stalink = false, s_connecting = false; + +static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) { + struct mg_wifi_data *wifi = + &((struct mg_tcpip_driver_pico_w_data *) ifp->driver_data)->wifi; + if (wifi->apmode && ev == MG_TCPIP_EV_ST_CHG && + *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) { + MG_DEBUG(("Access Point started")); + s_ip = ifp->ip, ifp->ip = wifi->apip; + s_mask = ifp->mask, ifp->mask = wifi->apmask; + ifp->enable_dhcp_client = false; + ifp->enable_dhcp_server = true; + } +} static bool mg_tcpip_driver_pico_w_init(struct mg_tcpip_if *ifp) { struct mg_tcpip_driver_pico_w_data *d = (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data; + struct mg_wifi_data *wifi = &d->wifi; s_ifp = ifp; + s_ip = ifp->ip; + s_mask = ifp->mask; + ifp->pfn = wifi_cb; if (cyw43_arch_init() != 0) return false; // initialize async_context and WiFi chip - if (d->apmode && d->apssid != NULL) { - MG_DEBUG(("Starting AP '%s' (%u)", d->apssid, d->apchannel)); - if (!mg_wifi_ap_start(d->apssid, d->appass, d->apchannel)) return false; + if (wifi->apmode && wifi->apssid != NULL) { + MG_DEBUG(("Starting AP '%s' (%u)", wifi->apssid, wifi->apchannel)); + if (!mg_wifi_ap_start(wifi)) return false; cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac); // same MAC } else { cyw43_arch_enable_sta_mode(); cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac); - if (d->ssid != NULL) { - MG_DEBUG(("Connecting to '%s'", d->ssid)); - return mg_wifi_connect(d->ssid, d->pass); + if (wifi->ssid != NULL) { + MG_DEBUG(("Connecting to '%s'", wifi->ssid)); + return mg_wifi_connect(wifi); } else { cyw43_arch_disable_sta_mode(); } @@ -22448,35 +22506,33 @@ static size_t mg_tcpip_driver_pico_w_tx(const void *buf, size_t len, struct mg_tcpip_driver_pico_w_data *d = (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data; return cyw43_send_ethernet(&cyw43_state, - d->apmode ? CYW43_ITF_AP : CYW43_ITF_STA, len, buf, - false) == 0 + d->wifi.apmode ? CYW43_ITF_AP : CYW43_ITF_STA, len, + buf, false) == 0 ? len : 0; } -static bool s_aplink = false, s_scanning = false; -static bool s_stalink = false, s_connecting = false; - static bool mg_tcpip_driver_pico_w_poll(struct mg_tcpip_if *ifp, bool s1) { cyw43_arch_poll(); // not necessary, except when IRQs are disabled (OTA) if (s_scanning && !cyw43_wifi_scan_active(&cyw43_state)) { MG_VERBOSE(("scan complete")); s_scanning = 0; - mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL); + mg_tcpip_call(ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL); } if (ifp->update_mac_hash_table) { // first call to _poll() is after _init(), so this is safe - cyw43_wifi_update_multicast_filter(&cyw43_state, (uint8_t *)mcast_addr, true); + cyw43_wifi_update_multicast_filter(&cyw43_state, (uint8_t *) mcast_addr, + true); ifp->update_mac_hash_table = false; } if (!s1) return false; struct mg_tcpip_driver_pico_w_data *d = (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data; - if (d->apmode) return s_aplink; + if (d->wifi.apmode) return s_aplink; int sdkstate = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA); MG_VERBOSE(("conn: %c state: %d", s_connecting ? '1' : '0', sdkstate)); if (sdkstate < 0 && s_connecting) { - mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, &sdkstate); + mg_tcpip_call(ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, &sdkstate); s_connecting = false; } return s_stalink; @@ -22507,7 +22563,7 @@ void cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf) { } void cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf) { if (itf == CYW43_ITF_AP) { - s_aplink = false; + s_aplink = false; } else { s_stalink = false; // SDK calls this before we check status, don't clear s_connecting here @@ -22547,9 +22603,15 @@ bool mg_wifi_scan(void) { return res; } -bool mg_wifi_connect(char *ssid, char *pass) { +bool mg_wifi_connect(struct mg_wifi_data *wifi) { + s_ifp->ip = s_ip; + s_ifp->mask = s_mask; + if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true; + s_ifp->enable_dhcp_server = false; cyw43_arch_enable_sta_mode(); - int res = cyw43_arch_wifi_connect_async(ssid, pass, CYW43_AUTH_WPA2_AES_PSK); + MG_DEBUG(("Connecting to %s", wifi->ssid)); + int res = cyw43_arch_wifi_connect_async(wifi->ssid, wifi->pass, + CYW43_AUTH_WPA2_AES_PSK); MG_VERBOSE(("res: %d", res)); if (res == 0) s_connecting = true; return (res == 0); @@ -22561,9 +22623,10 @@ bool mg_wifi_disconnect(void) { return true; } -bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) { - cyw43_wifi_ap_set_channel(&cyw43_state, channel); - cyw43_arch_enable_ap_mode(ssid, pass, CYW43_AUTH_WPA2_AES_PSK); +bool mg_wifi_ap_start(struct mg_wifi_data *wifi) { + cyw43_wifi_ap_set_channel(&cyw43_state, wifi->apchannel); + cyw43_arch_enable_ap_mode(wifi->apssid, wifi->appass, + CYW43_AUTH_WPA2_AES_PSK); return true; } diff --git a/mongoose.h b/mongoose.h index 1918c80f..4c3857e4 100644 --- a/mongoose.h +++ b/mongoose.h @@ -3028,28 +3028,37 @@ bool mg_ota_flash_end(struct mg_flash *flash); -struct mg_wifi_scan_bss_data { - struct mg_str SSID; - char *BSSID; - int16_t RSSI; - uint8_t security; -#define MG_WIFI_SECURITY_OPEN 0 -#define MG_WIFI_SECURITY_WEP MG_BIT(0) -#define MG_WIFI_SECURITY_WPA MG_BIT(1) -#define MG_WIFI_SECURITY_WPA2 MG_BIT(2) -#define MG_WIFI_SECURITY_WPA3 MG_BIT(3) - uint8_t channel; - unsigned band :2; -#define MG_WIFI_BAND_2G 0 -#define MG_WIFI_BAND_5G 1 - unsigned has_n :1; +struct mg_wifi_data { + char *ssid, *pass; // STA mode, SSID to connect to + char *apssid, *appass; // AP mode, our SSID + uint32_t apip, apmask; // AP mode, our IP address and mask + uint8_t security; // STA mode, TBD + uint8_t apsecurity; // AP mode, TBD + uint8_t apchannel; // AP mode, channel to use + bool apmode; // start in AP mode; 'false' -> connect to 'ssid' != NULL }; +struct mg_wifi_scan_bss_data { + struct mg_str SSID; + char *BSSID; + int16_t RSSI; + uint8_t security; +#define MG_WIFI_SECURITY_OPEN 0 +#define MG_WIFI_SECURITY_WEP MG_BIT(0) +#define MG_WIFI_SECURITY_WPA MG_BIT(1) +#define MG_WIFI_SECURITY_WPA2 MG_BIT(2) +#define MG_WIFI_SECURITY_WPA3 MG_BIT(3) + uint8_t channel; + unsigned band : 2; +#define MG_WIFI_BAND_2G 0 +#define MG_WIFI_BAND_5G 1 + unsigned has_n : 1; +}; bool mg_wifi_scan(void); -bool mg_wifi_connect(char *ssid, char *pass); +bool mg_wifi_connect(struct mg_wifi_data *); bool mg_wifi_disconnect(void); -bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel); +bool mg_wifi_ap_start(struct mg_wifi_data *); bool mg_wifi_ap_stop(void); @@ -3101,6 +3110,7 @@ struct mg_tcpip_if { bool update_mac_hash_table; // Signal drivers to update MAC controller struct mg_tcpip_driver *driver; // Low level driver void *driver_data; // Driver-specific data + mg_tcpip_event_handler_t pfn; // Driver-specific event handler function mg_tcpip_event_handler_t fn; // User-specified event handler function struct mg_mgr *mgr; // Mongoose event manager struct mg_queue recv_queue; // Receive queue @@ -3191,16 +3201,9 @@ struct mg_tcpip_driver_cyw_firmware { }; struct mg_tcpip_driver_cyw_data { + struct mg_wifi_data wifi; void *bus; struct mg_tcpip_driver_cyw_firmware *fw; - char *ssid; - char *pass; - char *apssid; - char *appass; - uint8_t security; // TBD - uint8_t apsecurity; // TBD - uint8_t apchannel; - bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL bool hs; // use chip "high-speed" mode; otherwise SPI CPOL0 CPHA0 (DS 4.2.3 Table 6) }; @@ -3303,14 +3306,7 @@ bool mg_phy_up(struct mg_phy *, uint8_t addr, bool *full_duplex, #include "pico/unique_id.h" // keep this include struct mg_tcpip_driver_pico_w_data { - char *ssid; - char *pass; - char *apssid; - char *appass; - uint8_t security; // TBD - uint8_t apsecurity; // TBD - uint8_t apchannel; - bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL + struct mg_wifi_data wifi; }; #define MG_TCPIP_DRIVER_INIT(mgr) \ diff --git a/src/drivers/cyw.c b/src/drivers/cyw.c index e493bc87..895d67d1 100644 --- a/src/drivers/cyw.c +++ b/src/drivers/cyw.c @@ -13,28 +13,44 @@ #endif static struct mg_tcpip_if *s_ifp; +static uint32_t s_ip, s_mask; static bool s_link, s_auth, s_join; +static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) { + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_data *) ifp->driver_data)->wifi; + if (wifi->apmode && ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) { + MG_DEBUG(("Access Point started")); + s_ip = ifp->ip, ifp->ip = wifi->apip; + s_mask = ifp->mask, ifp->mask = wifi->apmask; + ifp->enable_dhcp_client = false; + ifp->enable_dhcp_server = true; + } +} + static bool cyw_init(uint8_t *mac); static void cyw_poll(void); static bool mg_tcpip_driver_cyw_init(struct mg_tcpip_if *ifp) { struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; + struct mg_wifi_data *wifi = &d->wifi; if (MG_BIG_ENDIAN) { MG_ERROR(("Big-endian host")); return false; } s_ifp = ifp; + s_ip = ifp->ip; + s_mask = ifp->mask; s_link = s_auth = s_join = false; + ifp->pfn = wifi_cb; if (!cyw_init(ifp->mac)) return false; - if (d->apmode) { - MG_DEBUG(("Starting AP '%s' (%u)", d->apssid, d->apchannel)); - return mg_wifi_ap_start(d->apssid, d->appass, d->apchannel); - } else if (d->ssid != NULL && d->pass != NULL) { - MG_DEBUG(("Connecting to '%s'", d->ssid)); - return mg_wifi_connect(d->ssid, d->pass); + if (wifi->apmode) { + MG_DEBUG(("Starting AP '%s' (%u)", wifi->apssid, wifi->apchannel)); + return mg_wifi_ap_start(wifi); + } else if (wifi->ssid != NULL && wifi->pass != NULL) { + MG_DEBUG(("Connecting to '%s'", wifi->ssid)); + return mg_wifi_connect(wifi); } return true; } @@ -44,7 +60,7 @@ size_t mg_tcpip_driver_cyw_output(const void *buf, size_t len, struct mg_tcpip_if *ifp) { struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - return mg_cyw_tx(d->apmode ? 1 : 0, (void *) buf, len) >= len ? len : 0; + return mg_cyw_tx(d->wifi.apmode ? 1 : 0, (void *) buf, len) >= len ? len : 0; } static bool mg_tcpip_driver_cyw_poll(struct mg_tcpip_if *ifp, bool s1) { @@ -52,7 +68,7 @@ static bool mg_tcpip_driver_cyw_poll(struct mg_tcpip_if *ifp, bool s1) { if (!s1) return false; struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - return d->apmode ? s_link : s_link && s_auth && s_join; + return d->wifi.apmode ? s_link : s_link && s_auth && s_join; } struct mg_tcpip_driver mg_tcpip_driver_cyw = {mg_tcpip_driver_cyw_init, @@ -1035,7 +1051,7 @@ static size_t cyw_spi_poll(uint8_t *response) { cyw_spi_write(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_INT, &val, sizeof(val)); return 0; } - cyw_spi_read(CYW_SPID_FUNC_WLAN, 0, response, len); + cyw_spi_read(CYW_SPID_FUNC_WLAN, 0, response, (uint16_t)len); return len; } @@ -1098,7 +1114,7 @@ static bool cyw_spi_init() { cyw_set_backplane_window(CYW_CHIP_CHIPCOMMON); // set backplane window to start of CHIPCOMMON area cyw_spi_read(CYW_SPID_FUNC_CHIP, (CYW_CHIP_CHIPCOMMON + 0x00) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 2); if (val == 43430) val = 4343; - MG_INFO(("WLAN chip is CYW%u%c", val), val == 4343 ? 'W' : ' ')); + MG_INFO(("WLAN chip is CYW%u%c", val, val == 4343 ? 'W' : ' ')); // Load firmware (code and NVRAM) if (!cyw_load_firmware(d->fw)) return false; @@ -1376,16 +1392,21 @@ bool mg_wifi_scan(void) { return cyw_wifi_scan(); } -bool mg_wifi_connect(char *ssid, char *pass) { - return cyw_wifi_connect(ssid, pass); +bool mg_wifi_connect(struct mg_wifi_data *wifi) { + s_ifp->ip = s_ip; + s_ifp->mask = s_mask; + if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true; + s_ifp->enable_dhcp_server = false; + MG_DEBUG(("Connecting to %s", wifi->ssid)); + return cyw_wifi_connect(wifi->ssid, wifi->pass); } bool mg_wifi_disconnect(void) { return cyw_wifi_disconnect(); } -bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) { - return cyw_wifi_ap_start(ssid, pass, channel); +bool mg_wifi_ap_start(struct mg_wifi_data *wifi) { + return cyw_wifi_ap_start(wifi->apssid, wifi->appass, wifi->apchannel); } bool mg_wifi_ap_stop(void) { diff --git a/src/drivers/cyw.h b/src/drivers/cyw.h index e2160997..e7cfb5a1 100644 --- a/src/drivers/cyw.h +++ b/src/drivers/cyw.h @@ -22,16 +22,9 @@ struct mg_tcpip_driver_cyw_firmware { }; struct mg_tcpip_driver_cyw_data { + struct mg_wifi_data wifi; void *bus; struct mg_tcpip_driver_cyw_firmware *fw; - char *ssid; - char *pass; - char *apssid; - char *appass; - uint8_t security; // TBD - uint8_t apsecurity; // TBD - uint8_t apchannel; - bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL bool hs; // use chip "high-speed" mode; otherwise SPI CPOL0 CPHA0 (DS 4.2.3 Table 6) }; diff --git a/src/drivers/pico-w.c b/src/drivers/pico-w.c index f54d8010..87540199 100644 --- a/src/drivers/pico-w.c +++ b/src/drivers/pico-w.c @@ -6,23 +6,43 @@ #include "pico/stdlib.h" static struct mg_tcpip_if *s_ifp; +static uint32_t s_ip, s_mask; +static bool s_aplink = false, s_scanning = false; +static bool s_stalink = false, s_connecting = false; + +static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) { + struct mg_wifi_data *wifi = + &((struct mg_tcpip_driver_pico_w_data *) ifp->driver_data)->wifi; + if (wifi->apmode && ev == MG_TCPIP_EV_ST_CHG && + *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) { + MG_DEBUG(("Access Point started")); + s_ip = ifp->ip, ifp->ip = wifi->apip; + s_mask = ifp->mask, ifp->mask = wifi->apmask; + ifp->enable_dhcp_client = false; + ifp->enable_dhcp_server = true; + } +} static bool mg_tcpip_driver_pico_w_init(struct mg_tcpip_if *ifp) { struct mg_tcpip_driver_pico_w_data *d = (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data; + struct mg_wifi_data *wifi = &d->wifi; s_ifp = ifp; + s_ip = ifp->ip; + s_mask = ifp->mask; + ifp->pfn = wifi_cb; if (cyw43_arch_init() != 0) return false; // initialize async_context and WiFi chip - if (d->apmode && d->apssid != NULL) { - MG_DEBUG(("Starting AP '%s' (%u)", d->apssid, d->apchannel)); - if (!mg_wifi_ap_start(d->apssid, d->appass, d->apchannel)) return false; + if (wifi->apmode && wifi->apssid != NULL) { + MG_DEBUG(("Starting AP '%s' (%u)", wifi->apssid, wifi->apchannel)); + if (!mg_wifi_ap_start(wifi)) return false; cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac); // same MAC } else { cyw43_arch_enable_sta_mode(); cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac); - if (d->ssid != NULL) { - MG_DEBUG(("Connecting to '%s'", d->ssid)); - return mg_wifi_connect(d->ssid, d->pass); + if (wifi->ssid != NULL) { + MG_DEBUG(("Connecting to '%s'", wifi->ssid)); + return mg_wifi_connect(wifi); } else { cyw43_arch_disable_sta_mode(); } @@ -35,35 +55,33 @@ static size_t mg_tcpip_driver_pico_w_tx(const void *buf, size_t len, struct mg_tcpip_driver_pico_w_data *d = (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data; return cyw43_send_ethernet(&cyw43_state, - d->apmode ? CYW43_ITF_AP : CYW43_ITF_STA, len, buf, - false) == 0 + d->wifi.apmode ? CYW43_ITF_AP : CYW43_ITF_STA, len, + buf, false) == 0 ? len : 0; } -static bool s_aplink = false, s_scanning = false; -static bool s_stalink = false, s_connecting = false; - static bool mg_tcpip_driver_pico_w_poll(struct mg_tcpip_if *ifp, bool s1) { cyw43_arch_poll(); // not necessary, except when IRQs are disabled (OTA) if (s_scanning && !cyw43_wifi_scan_active(&cyw43_state)) { MG_VERBOSE(("scan complete")); s_scanning = 0; - mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL); + mg_tcpip_call(ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL); } if (ifp->update_mac_hash_table) { // first call to _poll() is after _init(), so this is safe - cyw43_wifi_update_multicast_filter(&cyw43_state, (uint8_t *)mcast_addr, true); + cyw43_wifi_update_multicast_filter(&cyw43_state, (uint8_t *) mcast_addr, + true); ifp->update_mac_hash_table = false; } if (!s1) return false; struct mg_tcpip_driver_pico_w_data *d = (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data; - if (d->apmode) return s_aplink; + if (d->wifi.apmode) return s_aplink; int sdkstate = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA); MG_VERBOSE(("conn: %c state: %d", s_connecting ? '1' : '0', sdkstate)); if (sdkstate < 0 && s_connecting) { - mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, &sdkstate); + mg_tcpip_call(ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, &sdkstate); s_connecting = false; } return s_stalink; @@ -94,7 +112,7 @@ void cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf) { } void cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf) { if (itf == CYW43_ITF_AP) { - s_aplink = false; + s_aplink = false; } else { s_stalink = false; // SDK calls this before we check status, don't clear s_connecting here @@ -134,9 +152,15 @@ bool mg_wifi_scan(void) { return res; } -bool mg_wifi_connect(char *ssid, char *pass) { +bool mg_wifi_connect(struct mg_wifi_data *wifi) { + s_ifp->ip = s_ip; + s_ifp->mask = s_mask; + if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true; + s_ifp->enable_dhcp_server = false; cyw43_arch_enable_sta_mode(); - int res = cyw43_arch_wifi_connect_async(ssid, pass, CYW43_AUTH_WPA2_AES_PSK); + MG_DEBUG(("Connecting to %s", wifi->ssid)); + int res = cyw43_arch_wifi_connect_async(wifi->ssid, wifi->pass, + CYW43_AUTH_WPA2_AES_PSK); MG_VERBOSE(("res: %d", res)); if (res == 0) s_connecting = true; return (res == 0); @@ -148,9 +172,10 @@ bool mg_wifi_disconnect(void) { return true; } -bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) { - cyw43_wifi_ap_set_channel(&cyw43_state, channel); - cyw43_arch_enable_ap_mode(ssid, pass, CYW43_AUTH_WPA2_AES_PSK); +bool mg_wifi_ap_start(struct mg_wifi_data *wifi) { + cyw43_wifi_ap_set_channel(&cyw43_state, wifi->apchannel); + cyw43_arch_enable_ap_mode(wifi->apssid, wifi->appass, + CYW43_AUTH_WPA2_AES_PSK); return true; } diff --git a/src/drivers/pico-w.h b/src/drivers/pico-w.h index fd0b5046..65ddb8be 100644 --- a/src/drivers/pico-w.h +++ b/src/drivers/pico-w.h @@ -8,14 +8,7 @@ #include "pico/unique_id.h" // keep this include struct mg_tcpip_driver_pico_w_data { - char *ssid; - char *pass; - char *apssid; - char *appass; - uint8_t security; // TBD - uint8_t apsecurity; // TBD - uint8_t apchannel; - bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL + struct mg_wifi_data wifi; }; #define MG_TCPIP_DRIVER_INIT(mgr) \ diff --git a/src/net_builtin.c b/src/net_builtin.c index b2dad5da..9c4b1eae 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -1,4 +1,5 @@ #include "net_builtin.h" +#include "profile.h" #if MG_ENABLE_TCPIP #define MG_EPHEMERAL_PORT_BASE 32768 @@ -158,6 +159,25 @@ struct pkt { }; static void mg_tcpip_call(struct mg_tcpip_if *ifp, int ev, void *ev_data) { +#if MG_ENABLE_PROFILE + const char *names[] = { + "TCPIP_EV_ST_CHG", + "TCPIP_EV_DHCP_DNS", + "TCPIP_EV_DHCP_SNTP", + "TCPIP_EV_ARP", + "TCPIP_EV_TIMER_1S", + "TCPIP_EV_WIFI_SCAN_RESULT", + "TCPIP_EV_WIFI_SCAN_END", + "TCPIP_EV_WIFI_CONNECT_ERR", + "TCPIP_EV_DRIVER", + "TCPIP_EV_USER" + }; + if (ev != MG_TCPIP_EV_POLL && ev < (int) (sizeof(names) / sizeof(names[0]))) { + MG_PROF_ADD(c, names[ev]); + } +#endif + // Fire protocol handler first, user handler second. See #2559 + if (ifp->pfn != NULL) ifp->pfn(ifp, ev, ev_data); if (ifp->fn != NULL) ifp->fn(ifp, ev, ev_data); } diff --git a/src/net_builtin.h b/src/net_builtin.h index c4316d21..6907f0f0 100644 --- a/src/net_builtin.h +++ b/src/net_builtin.h @@ -48,6 +48,7 @@ struct mg_tcpip_if { bool update_mac_hash_table; // Signal drivers to update MAC controller struct mg_tcpip_driver *driver; // Low level driver void *driver_data; // Driver-specific data + mg_tcpip_event_handler_t pfn; // Driver-specific event handler function mg_tcpip_event_handler_t fn; // User-specified event handler function struct mg_mgr *mgr; // Mongoose event manager struct mg_queue recv_queue; // Receive queue diff --git a/src/wifi.h b/src/wifi.h index c63da152..e8dabd6c 100644 --- a/src/wifi.h +++ b/src/wifi.h @@ -4,26 +4,35 @@ #include "log.h" #include "str.h" -struct mg_wifi_scan_bss_data { - struct mg_str SSID; - char *BSSID; - int16_t RSSI; - uint8_t security; -#define MG_WIFI_SECURITY_OPEN 0 -#define MG_WIFI_SECURITY_WEP MG_BIT(0) -#define MG_WIFI_SECURITY_WPA MG_BIT(1) -#define MG_WIFI_SECURITY_WPA2 MG_BIT(2) -#define MG_WIFI_SECURITY_WPA3 MG_BIT(3) - uint8_t channel; - unsigned band :2; -#define MG_WIFI_BAND_2G 0 -#define MG_WIFI_BAND_5G 1 - unsigned has_n :1; +struct mg_wifi_data { + char *ssid, *pass; // STA mode, SSID to connect to + char *apssid, *appass; // AP mode, our SSID + uint32_t apip, apmask; // AP mode, our IP address and mask + uint8_t security; // STA mode, TBD + uint8_t apsecurity; // AP mode, TBD + uint8_t apchannel; // AP mode, channel to use + bool apmode; // start in AP mode; 'false' -> connect to 'ssid' != NULL }; +struct mg_wifi_scan_bss_data { + struct mg_str SSID; + char *BSSID; + int16_t RSSI; + uint8_t security; +#define MG_WIFI_SECURITY_OPEN 0 +#define MG_WIFI_SECURITY_WEP MG_BIT(0) +#define MG_WIFI_SECURITY_WPA MG_BIT(1) +#define MG_WIFI_SECURITY_WPA2 MG_BIT(2) +#define MG_WIFI_SECURITY_WPA3 MG_BIT(3) + uint8_t channel; + unsigned band : 2; +#define MG_WIFI_BAND_2G 0 +#define MG_WIFI_BAND_5G 1 + unsigned has_n : 1; +}; bool mg_wifi_scan(void); -bool mg_wifi_connect(char *ssid, char *pass); +bool mg_wifi_connect(struct mg_wifi_data *); bool mg_wifi_disconnect(void); -bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel); +bool mg_wifi_ap_start(struct mg_wifi_data *); bool mg_wifi_ap_stop(void); diff --git a/src/wifi_dummy.c b/src/wifi_dummy.c index 84886509..d2154323 100644 --- a/src/wifi_dummy.c +++ b/src/wifi_dummy.c @@ -10,9 +10,8 @@ bool mg_wifi_scan(void) { return false; } -bool mg_wifi_connect(char *ssid, char *pass) { - (void) ssid; - (void) pass; +bool mg_wifi_connect(struct mg_wifi_data *wifi) { + (void) wifi; return mg_wifi_scan(); } @@ -20,10 +19,8 @@ bool mg_wifi_disconnect(void) { return mg_wifi_scan(); } -bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) { - (void) ssid; - (void) pass; - (void) channel; +bool mg_wifi_ap_start(struct mg_wifi_data *wifi) { + (void) wifi; return mg_wifi_scan(); } diff --git a/tutorials/pico-sdk/pico-2-w-picosdk-baremetal-builtin-ap/main.c b/tutorials/pico-sdk/pico-2-w-picosdk-baremetal-builtin-ap/main.c index 47e77dd4..f1dfccf1 100644 --- a/tutorials/pico-sdk/pico-2-w-picosdk-baremetal-builtin-ap/main.c +++ b/tutorials/pico-sdk/pico-2-w-picosdk-baremetal-builtin-ap/main.c @@ -7,7 +7,6 @@ #define WIFI_SSID "YOUR_WIFI_NETWORK_NAME" // SET THIS! #define WIFI_PASS "YOUR_WIFI_PASSWORD" // SET THIS! -static uint32_t s_ip, s_mask; // mif user states @@ -21,13 +20,7 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *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_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) { - MG_INFO(("Access Point started")); - s_ip = ifp->ip, ifp->ip = MG_IPV4(192, 168, 169, 1); - s_mask = ifp->mask, ifp->mask = MG_IPV4(255, 255, 255, 0); - ifp->enable_dhcp_client = false; - ifp->enable_dhcp_server = true; - } else if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { + if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { MG_INFO(("Access Point READY !")); // simulate user request to scan for networks @@ -53,18 +46,14 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { break; case STOPPING_AP: if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_pico_w_data *d = (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data; - d->apmode = false; + 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(d->ssid, d->pass); + bool res = mg_wifi_connect(wifi); MG_INFO(("Manually connecting: %s", res ? "OK":"FAIL")); if (res) { state = CONNECTING; - ifp->ip = s_ip; - ifp->mask = s_mask; - if (ifp->ip == 0) ifp->enable_dhcp_client = true; - ifp->enable_dhcp_server = false; } // else manually start AP as below } break; @@ -84,13 +73,13 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { case READY: // go back to AP mode after a disconnection (simulation 2/2), you could retry if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_pico_w_data *d = (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data; - bool res = mg_wifi_ap_start(d->apssid, d->appass, d->apchannel); + 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; - d->apmode = true; + wifi->apmode = true; } } break; @@ -108,17 +97,19 @@ int main(void) { // Initialise WiFi creds struct mg_tcpip_driver_pico_w_data driver_data = { - .ssid = WIFI_SSID, - .pass = WIFI_PASS, - .apssid = "mongoose", - .appass = "eightchars", - .security = 0, - .apsecurity = 0, - .apchannel = 10, - .apmode = true + .wifi.ssid = WIFI_SSID, + .wifi.pass = WIFI_PASS, + .wifi.apssid = "mongoose", + .wifi.appass = "eightchars", + .wifi.apip = MG_IPV4(192, 168, 169, 1), + .wifi.apmask = MG_IPV4(255, 255, 255, 0), + .wifi.security = 0, + .wifi.apsecurity = 0, + .wifi.apchannel = 10, + .wifi.apmode = true }; - state = driver_data.apmode ? AP : CONNECTING; + state = driver_data.wifi.apmode ? AP : CONNECTING; // Initialise Mongoose network stack // Either set use_dhcp or enter a static config. diff --git a/tutorials/stm32/portenta-h7-make-baremetal-builtin/main.c b/tutorials/stm32/portenta-h7-make-baremetal-builtin/main.c index 025fc6d5..2190b49c 100644 --- a/tutorials/stm32/portenta-h7-make-baremetal-builtin/main.c +++ b/tutorials/stm32/portenta-h7-make-baremetal-builtin/main.c @@ -50,23 +50,15 @@ static const struct mg_tcpip_driver_cyw_firmware fw = { // mif user states enum {AP, SCANNING, STOPPING_AP, CONNECTING, READY}; static unsigned int state; -static uint32_t s_ip, s_mask; 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_ST_CHG) { 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_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) { - MG_INFO(("Access Point started")); - s_ip = ifp->ip, ifp->ip = MG_IPV4(192, 168, 169, 1); - s_mask = ifp->mask, ifp->mask = MG_IPV4(255, 255, 255, 0); - ifp->enable_dhcp_client = false; - ifp->enable_dhcp_server = true; - } else if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { + if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { MG_INFO(("Access Point READY !")); // simulate user request to scan for networks @@ -80,7 +72,6 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { 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_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; MG_INFO(("Wi-Fi scan finished")); // simulate user selection of a network (1/2: stop AP) @@ -92,18 +83,14 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { break; case STOPPING_AP: if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - d->apmode = false; + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_data *) ifp->driver_data)->wifi; + wifi->apmode = false; // simulate user selection of a network (2/2: actual connect) - bool res = mg_wifi_connect(d->ssid, d->pass); + bool res = mg_wifi_connect(wifi); MG_INFO(("Manually connecting: %s", res ? "OK":"FAIL")); if (res) { state = CONNECTING; - ifp->ip = s_ip; - ifp->mask = s_mask; - if (ifp->ip == 0) ifp->enable_dhcp_client = true; - ifp->enable_dhcp_server = false; } // else manually start AP as below } break; @@ -123,13 +110,13 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { case READY: // go back to AP mode after a disconnection (simulation 2/2), you could retry if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - bool res = mg_wifi_ap_start(d->apssid, d->appass, d->apchannel); + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_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; - d->apmode = true; + wifi->apmode = true; } } break; @@ -138,14 +125,16 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { static struct mg_tcpip_driver_cyw_data d = { - (void *)&sdio, (struct mg_tcpip_driver_cyw_firmware *)&fw, WIFI_SSID, WIFI_PASS, "mongoose", "mongoose", 0, 0, 10, true, false}; + {WIFI_SSID, WIFI_PASS, "mongoose", "mongoose", 0, 0, 0, 0, 10, true}, (void *)&sdio, (struct mg_tcpip_driver_cyw_firmware *)&fw, false}; int main(void) { hal_init(); hwspecific_sdio_init(); - state = d.apmode ? AP : CONNECTING; + d.wifi.apip = MG_IPV4(192, 168, 169, 1), + d.wifi.apmask = MG_IPV4(255, 255, 255, 0), + state = d.wifi.apmode ? AP : CONNECTING; struct mg_mgr mgr; // Initialise Mongoose event manager mg_mgr_init(&mgr); // and attach it to the interface diff --git a/tutorials/stm32/rm2-nucleo-f429zi-make-baremetal-builtin/main.c b/tutorials/stm32/rm2-nucleo-f429zi-make-baremetal-builtin/main.c index 4570a6a3..f722bcf5 100644 --- a/tutorials/stm32/rm2-nucleo-f429zi-make-baremetal-builtin/main.c +++ b/tutorials/stm32/rm2-nucleo-f429zi-make-baremetal-builtin/main.c @@ -81,7 +81,6 @@ static const struct mg_tcpip_driver_cyw_firmware fw = { // mif user states enum {AP, SCANNING, STOPPING_AP, CONNECTING, READY}; static unsigned int state; -static uint32_t s_ip, s_mask; static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { @@ -95,13 +94,7 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *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_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) { - MG_INFO(("Access Point started")); - s_ip = ifp->ip, ifp->ip = MG_IPV4(192, 168, 169, 1); - s_mask = ifp->mask, ifp->mask = MG_IPV4(255, 255, 255, 0); - ifp->enable_dhcp_client = false; - ifp->enable_dhcp_server = true; - } else if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { + if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { MG_INFO(("Access Point READY !")); // simulate user request to scan for networks @@ -115,7 +108,7 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { 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_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; + //struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; MG_INFO(("Wi-Fi scan finished")); // simulate user selection of a network (1/2: stop AP) @@ -127,18 +120,14 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { break; case STOPPING_AP: if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - d->apmode = false; + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_data *) ifp->driver_data)->wifi; + wifi->apmode = false; // simulate user selection of a network (2/2: actual connect) - bool res = mg_wifi_connect(d->ssid, d->pass); + bool res = mg_wifi_connect(wifi); MG_INFO(("Manually connecting: %s", res ? "OK":"FAIL")); if (res) { state = CONNECTING; - ifp->ip = s_ip; - ifp->mask = s_mask; - if (ifp->ip == 0) ifp->enable_dhcp_client = true; - ifp->enable_dhcp_server = false; } // else manually start AP as below } break; @@ -158,13 +147,13 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { case READY: // go back to AP mode after a disconnection (simulation 2/2), you could retry if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - bool res = mg_wifi_ap_start(d->apssid, d->appass, d->apchannel); + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_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; - d->apmode = true; + wifi->apmode = true; } } break; @@ -173,14 +162,16 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { static struct mg_tcpip_driver_cyw_data d = { - (struct mg_tcpip_spi_ *)&spi, (struct mg_tcpip_driver_cyw_firmware *)&fw, WIFI_SSID, WIFI_PASS, "mongoose", "mongoose", 0, 0, 10, true, false}; + {WIFI_SSID, WIFI_PASS, "mongoose", "mongoose", 0, 0, 0, 0, 10, true}, (struct mg_tcpip_spi_ *)&spi, (struct mg_tcpip_driver_cyw_firmware *)&fw, false}; int main(void) { uart_init(UART_DEBUG, 115200); // Initialise debug printf hwspecific_spi_init(); - state = d.apmode ? AP : CONNECTING; + d.wifi.apip = MG_IPV4(192, 168, 169, 1), + d.wifi.apmask = MG_IPV4(255, 255, 255, 0), + state = d.wifi.apmode ? AP : CONNECTING; struct mg_mgr mgr; // Initialise Mongoose event manager mg_mgr_init(&mgr); // and attach it to the interface diff --git a/tutorials/stm32/rm2-nucleo-f746zg-make-baremetal-builtin/main.c b/tutorials/stm32/rm2-nucleo-f746zg-make-baremetal-builtin/main.c index ffa38ad2..d92cca26 100644 --- a/tutorials/stm32/rm2-nucleo-f746zg-make-baremetal-builtin/main.c +++ b/tutorials/stm32/rm2-nucleo-f746zg-make-baremetal-builtin/main.c @@ -81,7 +81,6 @@ static const struct mg_tcpip_driver_cyw_firmware fw = { // mif user states enum {AP, SCANNING, STOPPING_AP, CONNECTING, READY}; static unsigned int state; -static uint32_t s_ip, s_mask; static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { @@ -95,13 +94,7 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *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_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) { - MG_INFO(("Access Point started")); - s_ip = ifp->ip, ifp->ip = MG_IPV4(192, 168, 169, 1); - s_mask = ifp->mask, ifp->mask = MG_IPV4(255, 255, 255, 0); - ifp->enable_dhcp_client = false; - ifp->enable_dhcp_server = true; - } else if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { + if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { MG_INFO(("Access Point READY !")); // simulate user request to scan for networks @@ -115,7 +108,7 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { 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_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; + //struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; MG_INFO(("Wi-Fi scan finished")); // simulate user selection of a network (1/2: stop AP) @@ -127,18 +120,14 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { break; case STOPPING_AP: if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - d->apmode = false; + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_data *) ifp->driver_data)->wifi; + wifi->apmode = false; // simulate user selection of a network (2/2: actual connect) - bool res = mg_wifi_connect(d->ssid, d->pass); + bool res = mg_wifi_connect(wifi); MG_INFO(("Manually connecting: %s", res ? "OK":"FAIL")); if (res) { state = CONNECTING; - ifp->ip = s_ip; - ifp->mask = s_mask; - if (ifp->ip == 0) ifp->enable_dhcp_client = true; - ifp->enable_dhcp_server = false; } // else manually start AP as below } break; @@ -158,13 +147,13 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { case READY: // go back to AP mode after a disconnection (simulation 2/2), you could retry if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - bool res = mg_wifi_ap_start(d->apssid, d->appass, d->apchannel); + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_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; - d->apmode = true; + wifi->apmode = true; } } break; @@ -173,14 +162,16 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { static struct mg_tcpip_driver_cyw_data d = { - (struct mg_tcpip_spi_ *)&spi, (struct mg_tcpip_driver_cyw_firmware *)&fw, WIFI_SSID, WIFI_PASS, "mongoose", "mongoose", 0, 0, 10, true, false}; + {WIFI_SSID, WIFI_PASS, "mongoose", "mongoose", 0, 0, 0, 0, 10, true}, (struct mg_tcpip_spi_ *)&spi, (struct mg_tcpip_driver_cyw_firmware *)&fw, false}; int main(void) { uart_init(UART_DEBUG, 115200); // Initialise debug printf hwspecific_spi_init(); - state = d.apmode ? AP : CONNECTING; + d.wifi.apip = MG_IPV4(192, 168, 169, 1), + d.wifi.apmask = MG_IPV4(255, 255, 255, 0), + state = d.wifi.apmode ? AP : CONNECTING; struct mg_mgr mgr; // Initialise Mongoose event manager mg_mgr_init(&mgr); // and attach it to the interface