Skip to content

Commit c1ef477

Browse files
authored
Merge pull request #3266 from cesanta/wifi
Move interface stuff out of user handlers
2 parents 4be3a96 + 387f875 commit c1ef477

File tree

14 files changed

+311
-231
lines changed

14 files changed

+311
-231
lines changed

mongoose.c

Lines changed: 105 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4157,6 +4157,7 @@ void mg_mgr_init(struct mg_mgr *mgr) {
41574157
#endif
41584158

41594159

4160+
41604161
#if MG_ENABLE_TCPIP
41614162
#define MG_EPHEMERAL_PORT_BASE 32768
41624163
#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
@@ -4315,6 +4316,25 @@ struct pkt {
43154316
};
43164317

43174318
static void mg_tcpip_call(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
4319+
#if MG_ENABLE_PROFILE
4320+
const char *names[] = {
4321+
"TCPIP_EV_ST_CHG",
4322+
"TCPIP_EV_DHCP_DNS",
4323+
"TCPIP_EV_DHCP_SNTP",
4324+
"TCPIP_EV_ARP",
4325+
"TCPIP_EV_TIMER_1S",
4326+
"TCPIP_EV_WIFI_SCAN_RESULT",
4327+
"TCPIP_EV_WIFI_SCAN_END",
4328+
"TCPIP_EV_WIFI_CONNECT_ERR",
4329+
"TCPIP_EV_DRIVER",
4330+
"TCPIP_EV_USER"
4331+
};
4332+
if (ev != MG_TCPIP_EV_POLL && ev < (int) (sizeof(names) / sizeof(names[0]))) {
4333+
MG_PROF_ADD(c, names[ev]);
4334+
}
4335+
#endif
4336+
// Fire protocol handler first, user handler second. See #2559
4337+
if (ifp->pfn != NULL) ifp->pfn(ifp, ev, ev_data);
43184338
if (ifp->fn != NULL) ifp->fn(ifp, ev, ev_data);
43194339
}
43204340

@@ -20177,20 +20197,17 @@ bool mg_wifi_scan(void) {
2017720197
return false;
2017820198
}
2017920199

20180-
bool mg_wifi_connect(char *ssid, char *pass) {
20181-
(void) ssid;
20182-
(void) pass;
20200+
bool mg_wifi_connect(struct mg_wifi_data *wifi) {
20201+
(void) wifi;
2018320202
return mg_wifi_scan();
2018420203
}
2018520204

2018620205
bool mg_wifi_disconnect(void) {
2018720206
return mg_wifi_scan();
2018820207
}
2018920208

20190-
bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) {
20191-
(void) ssid;
20192-
(void) pass;
20193-
(void) channel;
20209+
bool mg_wifi_ap_start(struct mg_wifi_data *wifi) {
20210+
(void) wifi;
2019420211
return mg_wifi_scan();
2019520212
}
2019620213

@@ -20651,28 +20668,44 @@ static size_t cmsis_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
2065120668
#endif
2065220669

2065320670
static struct mg_tcpip_if *s_ifp;
20671+
static uint32_t s_ip, s_mask;
2065420672
static bool s_link, s_auth, s_join;
2065520673

20674+
static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
20675+
struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_data *) ifp->driver_data)->wifi;
20676+
if (wifi->apmode && ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) {
20677+
MG_DEBUG(("Access Point started"));
20678+
s_ip = ifp->ip, ifp->ip = wifi->apip;
20679+
s_mask = ifp->mask, ifp->mask = wifi->apmask;
20680+
ifp->enable_dhcp_client = false;
20681+
ifp->enable_dhcp_server = true;
20682+
}
20683+
}
20684+
2065620685
static bool cyw_init(uint8_t *mac);
2065720686
static void cyw_poll(void);
2065820687

2065920688
static bool mg_tcpip_driver_cyw_init(struct mg_tcpip_if *ifp) {
2066020689
struct mg_tcpip_driver_cyw_data *d =
2066120690
(struct mg_tcpip_driver_cyw_data *) ifp->driver_data;
20691+
struct mg_wifi_data *wifi = &d->wifi;
2066220692
if (MG_BIG_ENDIAN) {
2066320693
MG_ERROR(("Big-endian host"));
2066420694
return false;
2066520695
}
2066620696
s_ifp = ifp;
20697+
s_ip = ifp->ip;
20698+
s_mask = ifp->mask;
2066720699
s_link = s_auth = s_join = false;
20700+
ifp->pfn = wifi_cb;
2066820701
if (!cyw_init(ifp->mac)) return false;
2066920702

20670-
if (d->apmode) {
20671-
MG_DEBUG(("Starting AP '%s' (%u)", d->apssid, d->apchannel));
20672-
return mg_wifi_ap_start(d->apssid, d->appass, d->apchannel);
20673-
} else if (d->ssid != NULL && d->pass != NULL) {
20674-
MG_DEBUG(("Connecting to '%s'", d->ssid));
20675-
return mg_wifi_connect(d->ssid, d->pass);
20703+
if (wifi->apmode) {
20704+
MG_DEBUG(("Starting AP '%s' (%u)", wifi->apssid, wifi->apchannel));
20705+
return mg_wifi_ap_start(wifi);
20706+
} else if (wifi->ssid != NULL && wifi->pass != NULL) {
20707+
MG_DEBUG(("Connecting to '%s'", wifi->ssid));
20708+
return mg_wifi_connect(wifi);
2067620709
}
2067720710
return true;
2067820711
}
@@ -20682,15 +20715,15 @@ size_t mg_tcpip_driver_cyw_output(const void *buf, size_t len,
2068220715
struct mg_tcpip_if *ifp) {
2068320716
struct mg_tcpip_driver_cyw_data *d =
2068420717
(struct mg_tcpip_driver_cyw_data *) ifp->driver_data;
20685-
return mg_cyw_tx(d->apmode ? 1 : 0, (void *) buf, len) >= len ? len : 0;
20718+
return mg_cyw_tx(d->wifi.apmode ? 1 : 0, (void *) buf, len) >= len ? len : 0;
2068620719
}
2068720720

2068820721
static bool mg_tcpip_driver_cyw_poll(struct mg_tcpip_if *ifp, bool s1) {
2068920722
cyw_poll();
2069020723
if (!s1) return false;
2069120724
struct mg_tcpip_driver_cyw_data *d =
2069220725
(struct mg_tcpip_driver_cyw_data *) ifp->driver_data;
20693-
return d->apmode ? s_link : s_link && s_auth && s_join;
20726+
return d->wifi.apmode ? s_link : s_link && s_auth && s_join;
2069420727
}
2069520728

2069620729
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) {
2167321706
cyw_spi_write(CYW_SPID_FUNC_BUS, CYW_BUS_SPI_INT, &val, sizeof(val));
2167421707
return 0;
2167521708
}
21676-
cyw_spi_read(CYW_SPID_FUNC_WLAN, 0, response, len);
21709+
cyw_spi_read(CYW_SPID_FUNC_WLAN, 0, response, (uint16_t)len);
2167721710
return len;
2167821711
}
2167921712

@@ -21736,7 +21769,7 @@ static bool cyw_spi_init() {
2173621769
cyw_set_backplane_window(CYW_CHIP_CHIPCOMMON); // set backplane window to start of CHIPCOMMON area
2173721770
cyw_spi_read(CYW_SPID_FUNC_CHIP, (CYW_CHIP_CHIPCOMMON + 0x00) & CYW_CHIP_BCKPLN_ADDRMSK, &val, 2);
2173821771
if (val == 43430) val = 4343;
21739-
MG_INFO(("WLAN chip is CYW%u%c", val), val == 4343 ? 'W' : ' '));
21772+
MG_INFO(("WLAN chip is CYW%u%c", val, val == 4343 ? 'W' : ' '));
2174021773

2174121774
// Load firmware (code and NVRAM)
2174221775
if (!cyw_load_firmware(d->fw)) return false;
@@ -22014,16 +22047,21 @@ bool mg_wifi_scan(void) {
2201422047
return cyw_wifi_scan();
2201522048
}
2201622049

22017-
bool mg_wifi_connect(char *ssid, char *pass) {
22018-
return cyw_wifi_connect(ssid, pass);
22050+
bool mg_wifi_connect(struct mg_wifi_data *wifi) {
22051+
s_ifp->ip = s_ip;
22052+
s_ifp->mask = s_mask;
22053+
if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true;
22054+
s_ifp->enable_dhcp_server = false;
22055+
MG_DEBUG(("Connecting to %s", wifi->ssid));
22056+
return cyw_wifi_connect(wifi->ssid, wifi->pass);
2201922057
}
2202022058

2202122059
bool mg_wifi_disconnect(void) {
2202222060
return cyw_wifi_disconnect();
2202322061
}
2202422062

22025-
bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) {
22026-
return cyw_wifi_ap_start(ssid, pass, channel);
22063+
bool mg_wifi_ap_start(struct mg_wifi_data *wifi) {
22064+
return cyw_wifi_ap_start(wifi->apssid, wifi->appass, wifi->apchannel);
2202722065
}
2202822066

2202922067
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,
2241922457

2242022458

2242122459
static struct mg_tcpip_if *s_ifp;
22460+
static uint32_t s_ip, s_mask;
22461+
static bool s_aplink = false, s_scanning = false;
22462+
static bool s_stalink = false, s_connecting = false;
22463+
22464+
static void wifi_cb(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
22465+
struct mg_wifi_data *wifi =
22466+
&((struct mg_tcpip_driver_pico_w_data *) ifp->driver_data)->wifi;
22467+
if (wifi->apmode && ev == MG_TCPIP_EV_ST_CHG &&
22468+
*(uint8_t *) ev_data == MG_TCPIP_STATE_UP) {
22469+
MG_DEBUG(("Access Point started"));
22470+
s_ip = ifp->ip, ifp->ip = wifi->apip;
22471+
s_mask = ifp->mask, ifp->mask = wifi->apmask;
22472+
ifp->enable_dhcp_client = false;
22473+
ifp->enable_dhcp_server = true;
22474+
}
22475+
}
2242222476

2242322477
static bool mg_tcpip_driver_pico_w_init(struct mg_tcpip_if *ifp) {
2242422478
struct mg_tcpip_driver_pico_w_data *d =
2242522479
(struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
22480+
struct mg_wifi_data *wifi = &d->wifi;
2242622481
s_ifp = ifp;
22482+
s_ip = ifp->ip;
22483+
s_mask = ifp->mask;
22484+
ifp->pfn = wifi_cb;
2242722485
if (cyw43_arch_init() != 0)
2242822486
return false; // initialize async_context and WiFi chip
22429-
if (d->apmode && d->apssid != NULL) {
22430-
MG_DEBUG(("Starting AP '%s' (%u)", d->apssid, d->apchannel));
22431-
if (!mg_wifi_ap_start(d->apssid, d->appass, d->apchannel)) return false;
22487+
if (wifi->apmode && wifi->apssid != NULL) {
22488+
MG_DEBUG(("Starting AP '%s' (%u)", wifi->apssid, wifi->apchannel));
22489+
if (!mg_wifi_ap_start(wifi)) return false;
2243222490
cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac); // same MAC
2243322491
} else {
2243422492
cyw43_arch_enable_sta_mode();
2243522493
cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac);
22436-
if (d->ssid != NULL) {
22437-
MG_DEBUG(("Connecting to '%s'", d->ssid));
22438-
return mg_wifi_connect(d->ssid, d->pass);
22494+
if (wifi->ssid != NULL) {
22495+
MG_DEBUG(("Connecting to '%s'", wifi->ssid));
22496+
return mg_wifi_connect(wifi);
2243922497
} else {
2244022498
cyw43_arch_disable_sta_mode();
2244122499
}
@@ -22448,35 +22506,33 @@ static size_t mg_tcpip_driver_pico_w_tx(const void *buf, size_t len,
2244822506
struct mg_tcpip_driver_pico_w_data *d =
2244922507
(struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
2245022508
return cyw43_send_ethernet(&cyw43_state,
22451-
d->apmode ? CYW43_ITF_AP : CYW43_ITF_STA, len, buf,
22452-
false) == 0
22509+
d->wifi.apmode ? CYW43_ITF_AP : CYW43_ITF_STA, len,
22510+
buf, false) == 0
2245322511
? len
2245422512
: 0;
2245522513
}
2245622514

22457-
static bool s_aplink = false, s_scanning = false;
22458-
static bool s_stalink = false, s_connecting = false;
22459-
2246022515
static bool mg_tcpip_driver_pico_w_poll(struct mg_tcpip_if *ifp, bool s1) {
2246122516
cyw43_arch_poll(); // not necessary, except when IRQs are disabled (OTA)
2246222517
if (s_scanning && !cyw43_wifi_scan_active(&cyw43_state)) {
2246322518
MG_VERBOSE(("scan complete"));
2246422519
s_scanning = 0;
22465-
mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL);
22520+
mg_tcpip_call(ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL);
2246622521
}
2246722522
if (ifp->update_mac_hash_table) {
2246822523
// first call to _poll() is after _init(), so this is safe
22469-
cyw43_wifi_update_multicast_filter(&cyw43_state, (uint8_t *)mcast_addr, true);
22524+
cyw43_wifi_update_multicast_filter(&cyw43_state, (uint8_t *) mcast_addr,
22525+
true);
2247022526
ifp->update_mac_hash_table = false;
2247122527
}
2247222528
if (!s1) return false;
2247322529
struct mg_tcpip_driver_pico_w_data *d =
2247422530
(struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
22475-
if (d->apmode) return s_aplink;
22531+
if (d->wifi.apmode) return s_aplink;
2247622532
int sdkstate = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA);
2247722533
MG_VERBOSE(("conn: %c state: %d", s_connecting ? '1' : '0', sdkstate));
2247822534
if (sdkstate < 0 && s_connecting) {
22479-
mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, &sdkstate);
22535+
mg_tcpip_call(ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, &sdkstate);
2248022536
s_connecting = false;
2248122537
}
2248222538
return s_stalink;
@@ -22507,7 +22563,7 @@ void cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf) {
2250722563
}
2250822564
void cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf) {
2250922565
if (itf == CYW43_ITF_AP) {
22510-
s_aplink = false;
22566+
s_aplink = false;
2251122567
} else {
2251222568
s_stalink = false;
2251322569
// SDK calls this before we check status, don't clear s_connecting here
@@ -22547,9 +22603,15 @@ bool mg_wifi_scan(void) {
2254722603
return res;
2254822604
}
2254922605

22550-
bool mg_wifi_connect(char *ssid, char *pass) {
22606+
bool mg_wifi_connect(struct mg_wifi_data *wifi) {
22607+
s_ifp->ip = s_ip;
22608+
s_ifp->mask = s_mask;
22609+
if (s_ifp->ip == 0) s_ifp->enable_dhcp_client = true;
22610+
s_ifp->enable_dhcp_server = false;
2255122611
cyw43_arch_enable_sta_mode();
22552-
int res = cyw43_arch_wifi_connect_async(ssid, pass, CYW43_AUTH_WPA2_AES_PSK);
22612+
MG_DEBUG(("Connecting to %s", wifi->ssid));
22613+
int res = cyw43_arch_wifi_connect_async(wifi->ssid, wifi->pass,
22614+
CYW43_AUTH_WPA2_AES_PSK);
2255322615
MG_VERBOSE(("res: %d", res));
2255422616
if (res == 0) s_connecting = true;
2255522617
return (res == 0);
@@ -22561,9 +22623,10 @@ bool mg_wifi_disconnect(void) {
2256122623
return true;
2256222624
}
2256322625

22564-
bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) {
22565-
cyw43_wifi_ap_set_channel(&cyw43_state, channel);
22566-
cyw43_arch_enable_ap_mode(ssid, pass, CYW43_AUTH_WPA2_AES_PSK);
22626+
bool mg_wifi_ap_start(struct mg_wifi_data *wifi) {
22627+
cyw43_wifi_ap_set_channel(&cyw43_state, wifi->apchannel);
22628+
cyw43_arch_enable_ap_mode(wifi->apssid, wifi->appass,
22629+
CYW43_AUTH_WPA2_AES_PSK);
2256722630
return true;
2256822631
}
2256922632

mongoose.h

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3028,28 +3028,37 @@ bool mg_ota_flash_end(struct mg_flash *flash);
30283028

30293029

30303030

3031+
struct mg_wifi_data {
3032+
char *ssid, *pass; // STA mode, SSID to connect to
3033+
char *apssid, *appass; // AP mode, our SSID
3034+
uint32_t apip, apmask; // AP mode, our IP address and mask
3035+
uint8_t security; // STA mode, TBD
3036+
uint8_t apsecurity; // AP mode, TBD
3037+
uint8_t apchannel; // AP mode, channel to use
3038+
bool apmode; // start in AP mode; 'false' -> connect to 'ssid' != NULL
3039+
};
3040+
30313041
struct mg_wifi_scan_bss_data {
3032-
struct mg_str SSID;
3033-
char *BSSID;
3034-
int16_t RSSI;
3035-
uint8_t security;
3042+
struct mg_str SSID;
3043+
char *BSSID;
3044+
int16_t RSSI;
3045+
uint8_t security;
30363046
#define MG_WIFI_SECURITY_OPEN 0
3037-
#define MG_WIFI_SECURITY_WEP MG_BIT(0)
3038-
#define MG_WIFI_SECURITY_WPA MG_BIT(1)
3047+
#define MG_WIFI_SECURITY_WEP MG_BIT(0)
3048+
#define MG_WIFI_SECURITY_WPA MG_BIT(1)
30393049
#define MG_WIFI_SECURITY_WPA2 MG_BIT(2)
30403050
#define MG_WIFI_SECURITY_WPA3 MG_BIT(3)
3041-
uint8_t channel;
3042-
unsigned band :2;
3051+
uint8_t channel;
3052+
unsigned band : 2;
30433053
#define MG_WIFI_BAND_2G 0
30443054
#define MG_WIFI_BAND_5G 1
3045-
unsigned has_n :1;
3055+
unsigned has_n : 1;
30463056
};
30473057

3048-
30493058
bool mg_wifi_scan(void);
3050-
bool mg_wifi_connect(char *ssid, char *pass);
3059+
bool mg_wifi_connect(struct mg_wifi_data *);
30513060
bool mg_wifi_disconnect(void);
3052-
bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel);
3061+
bool mg_wifi_ap_start(struct mg_wifi_data *);
30533062
bool mg_wifi_ap_stop(void);
30543063

30553064

@@ -3101,6 +3110,7 @@ struct mg_tcpip_if {
31013110
bool update_mac_hash_table; // Signal drivers to update MAC controller
31023111
struct mg_tcpip_driver *driver; // Low level driver
31033112
void *driver_data; // Driver-specific data
3113+
mg_tcpip_event_handler_t pfn; // Driver-specific event handler function
31043114
mg_tcpip_event_handler_t fn; // User-specified event handler function
31053115
struct mg_mgr *mgr; // Mongoose event manager
31063116
struct mg_queue recv_queue; // Receive queue
@@ -3191,16 +3201,9 @@ struct mg_tcpip_driver_cyw_firmware {
31913201
};
31923202

31933203
struct mg_tcpip_driver_cyw_data {
3204+
struct mg_wifi_data wifi;
31943205
void *bus;
31953206
struct mg_tcpip_driver_cyw_firmware *fw;
3196-
char *ssid;
3197-
char *pass;
3198-
char *apssid;
3199-
char *appass;
3200-
uint8_t security; // TBD
3201-
uint8_t apsecurity; // TBD
3202-
uint8_t apchannel;
3203-
bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL
32043207
bool hs; // use chip "high-speed" mode; otherwise SPI CPOL0 CPHA0 (DS 4.2.3 Table 6)
32053208
};
32063209

@@ -3303,14 +3306,7 @@ bool mg_phy_up(struct mg_phy *, uint8_t addr, bool *full_duplex,
33033306
#include "pico/unique_id.h" // keep this include
33043307

33053308
struct mg_tcpip_driver_pico_w_data {
3306-
char *ssid;
3307-
char *pass;
3308-
char *apssid;
3309-
char *appass;
3310-
uint8_t security; // TBD
3311-
uint8_t apsecurity; // TBD
3312-
uint8_t apchannel;
3313-
bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL
3309+
struct mg_wifi_data wifi;
33143310
};
33153311

33163312
#define MG_TCPIP_DRIVER_INIT(mgr) \

0 commit comments

Comments
 (0)