Skip to content

Commit 30c7aa8

Browse files
authored
Merge pull request #4650 from anecdata/ap
wifi.radio Access Point modes
2 parents a2ae503 + eebcd2e commit 30c7aa8

File tree

9 files changed

+330
-25
lines changed

9 files changed

+330
-25
lines changed

locale/circuitpython.pot

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,10 @@ msgstr ""
441441
msgid "Attempted heap allocation when VM not running."
442442
msgstr ""
443443

444+
#: shared-bindings/wifi/Radio.c
445+
msgid "AuthMode.OPEN is not used with password"
446+
msgstr ""
447+
444448
#: shared-bindings/wifi/Radio.c
445449
msgid "Authentication failure"
446450
msgstr ""
@@ -1197,6 +1201,10 @@ msgstr ""
11971201
msgid "Invalid ADC Unit value"
11981202
msgstr ""
11991203

1204+
#: ports/esp32s2/common-hal/wifi/Radio.c
1205+
msgid "Invalid AuthMode"
1206+
msgstr ""
1207+
12001208
#: shared-module/displayio/OnDiskBitmap.c
12011209
msgid "Invalid BMP file"
12021210
msgstr ""

ports/esp32s2/common-hal/wifi/Network.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
#include <string.h>
2828

29-
#include "py/enum.h"
3029
#include "shared-bindings/wifi/Network.h"
3130
#include "shared-bindings/wifi/AuthMode.h"
3231

ports/esp32s2/common-hal/wifi/Radio.c

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,26 +35,50 @@
3535
#include "py/runtime.h"
3636
#include "shared-bindings/ipaddress/IPv4Address.h"
3737
#include "shared-bindings/wifi/ScannedNetworks.h"
38+
#include "shared-bindings/wifi/AuthMode.h"
3839
#include "shared-module/ipaddress/__init__.h"
3940

4041
#include "components/esp_wifi/include/esp_wifi.h"
4142
#include "components/lwip/include/apps/ping/ping_sock.h"
4243

4344
#define MAC_ADDRESS_LENGTH 6
4445

45-
static void start_station(wifi_radio_obj_t *self) {
46-
if (self->sta_mode) {
47-
return;
48-
}
46+
static void set_mode_station(wifi_radio_obj_t *self, bool state) {
4947
wifi_mode_t next_mode;
50-
if (self->ap_mode) {
51-
next_mode = WIFI_MODE_APSTA;
48+
if (state) {
49+
if (self->ap_mode) {
50+
next_mode = WIFI_MODE_APSTA;
51+
} else {
52+
next_mode = WIFI_MODE_STA;
53+
}
5254
} else {
53-
next_mode = WIFI_MODE_STA;
55+
if (self->ap_mode) {
56+
next_mode = WIFI_MODE_AP;
57+
} else {
58+
next_mode = WIFI_MODE_NULL;
59+
}
5460
}
5561
esp_wifi_set_mode(next_mode);
62+
self->sta_mode = state;
63+
}
5664

57-
self->sta_mode = 1;
65+
static void set_mode_ap(wifi_radio_obj_t *self, bool state) {
66+
wifi_mode_t next_mode;
67+
if (state) {
68+
if (self->sta_mode) {
69+
next_mode = WIFI_MODE_APSTA;
70+
} else {
71+
next_mode = WIFI_MODE_AP;
72+
}
73+
} else {
74+
if (self->sta_mode) {
75+
next_mode = WIFI_MODE_STA;
76+
} else {
77+
next_mode = WIFI_MODE_NULL;
78+
}
79+
}
80+
esp_wifi_set_mode(next_mode);
81+
self->ap_mode = state;
5882
}
5983

6084
bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self) {
@@ -71,8 +95,6 @@ void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) {
7195
return;
7296
}
7397
if (!self->started && enabled) {
74-
// esp_wifi_start() would default to soft-AP, thus setting it to station
75-
start_station(self);
7698
ESP_ERROR_CHECK(esp_wifi_start());
7799
self->started = true;
78100
return;
@@ -85,14 +107,20 @@ mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) {
85107
return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH);
86108
}
87109

110+
mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self) {
111+
uint8_t mac[MAC_ADDRESS_LENGTH];
112+
esp_wifi_get_mac(ESP_IF_WIFI_AP, mac);
113+
return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH);
114+
}
115+
88116
mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) {
89117
if (self->current_scan != NULL) {
90118
mp_raise_RuntimeError(translate("Already scanning for wifi networks"));
91119
}
92120
if (!common_hal_wifi_radio_get_enabled(self)) {
93121
mp_raise_RuntimeError(translate("wifi is not enabled"));
94122
}
95-
start_station(self);
123+
set_mode_station(self, true);
96124

97125
wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t);
98126
scan->base.type = &wifi_scannednetworks_type;
@@ -127,6 +155,50 @@ void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *host
127155
esp_netif_set_hostname(self->netif, hostname);
128156
}
129157

158+
void common_hal_wifi_radio_start_station(wifi_radio_obj_t *self) {
159+
set_mode_station(self, true);
160+
}
161+
162+
void common_hal_wifi_radio_stop_station(wifi_radio_obj_t *self) {
163+
set_mode_station(self, false);
164+
}
165+
166+
void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint8_t authmode) {
167+
set_mode_ap(self, true);
168+
169+
switch (authmode) {
170+
case (1 << AUTHMODE_OPEN):
171+
authmode = WIFI_AUTH_OPEN;
172+
break;
173+
case ((1 << AUTHMODE_WPA) | (1 << AUTHMODE_PSK)):
174+
authmode = WIFI_AUTH_WPA_PSK;
175+
break;
176+
case ((1 << AUTHMODE_WPA2) | (1 << AUTHMODE_PSK)):
177+
authmode = WIFI_AUTH_WPA2_PSK;
178+
break;
179+
case ((1 << AUTHMODE_WPA) | (1 << AUTHMODE_WPA2) | (1 << AUTHMODE_PSK)):
180+
authmode = WIFI_AUTH_WPA_WPA2_PSK;
181+
break;
182+
default:
183+
mp_raise_ValueError(translate("Invalid AuthMode"));
184+
break;
185+
}
186+
187+
wifi_config_t *config = &self->ap_config;
188+
memcpy(&config->ap.ssid, ssid, ssid_len);
189+
config->ap.ssid[ssid_len] = 0;
190+
memcpy(&config->ap.password, password, password_len);
191+
config->ap.password[password_len] = 0;
192+
config->ap.channel = channel;
193+
config->ap.authmode = authmode;
194+
config->ap.max_connection = 4; // kwarg?
195+
esp_wifi_set_config(WIFI_IF_AP, config);
196+
}
197+
198+
void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self) {
199+
set_mode_ap(self, false);
200+
}
201+
130202
wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, mp_float_t timeout, uint8_t *bssid, size_t bssid_len) {
131203
if (!common_hal_wifi_radio_get_enabled(self)) {
132204
mp_raise_RuntimeError(translate("wifi is not enabled"));
@@ -147,7 +219,7 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t
147219
// explicitly clear bits since xEventGroupWaitBits may have timed out
148220
xEventGroupClearBits(self->event_group_handle, WIFI_CONNECTED_BIT);
149221
xEventGroupClearBits(self->event_group_handle, WIFI_DISCONNECTED_BIT);
150-
start_station(self);
222+
set_mode_station(self, true);
151223

152224
wifi_config_t *config = &self->sta_config;
153225
memcpy(&config->sta.ssid, ssid, ssid_len);
@@ -239,6 +311,14 @@ mp_obj_t common_hal_wifi_radio_get_ipv4_gateway(wifi_radio_obj_t *self) {
239311
return common_hal_ipaddress_new_ipv4address(self->ip_info.gw.addr);
240312
}
241313

314+
mp_obj_t common_hal_wifi_radio_get_ipv4_gateway_ap(wifi_radio_obj_t *self) {
315+
if (!esp_netif_is_netif_up(self->ap_netif)) {
316+
return mp_const_none;
317+
}
318+
esp_netif_get_ip_info(self->ap_netif, &self->ap_ip_info);
319+
return common_hal_ipaddress_new_ipv4address(self->ap_ip_info.gw.addr);
320+
}
321+
242322
mp_obj_t common_hal_wifi_radio_get_ipv4_subnet(wifi_radio_obj_t *self) {
243323
if (!esp_netif_is_netif_up(self->netif)) {
244324
return mp_const_none;
@@ -247,6 +327,14 @@ mp_obj_t common_hal_wifi_radio_get_ipv4_subnet(wifi_radio_obj_t *self) {
247327
return common_hal_ipaddress_new_ipv4address(self->ip_info.netmask.addr);
248328
}
249329

330+
mp_obj_t common_hal_wifi_radio_get_ipv4_subnet_ap(wifi_radio_obj_t *self) {
331+
if (!esp_netif_is_netif_up(self->ap_netif)) {
332+
return mp_const_none;
333+
}
334+
esp_netif_get_ip_info(self->ap_netif, &self->ap_ip_info);
335+
return common_hal_ipaddress_new_ipv4address(self->ap_ip_info.netmask.addr);
336+
}
337+
250338
mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) {
251339
if (!esp_netif_is_netif_up(self->netif)) {
252340
return mp_const_none;
@@ -255,6 +343,14 @@ mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) {
255343
return common_hal_ipaddress_new_ipv4address(self->ip_info.ip.addr);
256344
}
257345

346+
mp_obj_t common_hal_wifi_radio_get_ipv4_address_ap(wifi_radio_obj_t *self) {
347+
if (!esp_netif_is_netif_up(self->ap_netif)) {
348+
return mp_const_none;
349+
}
350+
esp_netif_get_ip_info(self->ap_netif, &self->ap_ip_info);
351+
return common_hal_ipaddress_new_ipv4address(self->ap_ip_info.ip.addr);
352+
}
353+
258354
mp_obj_t common_hal_wifi_radio_get_ipv4_dns(wifi_radio_obj_t *self) {
259355
if (!esp_netif_is_netif_up(self->netif)) {
260356
return mp_const_none;

ports/esp32s2/common-hal/wifi/Radio.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ typedef struct {
5757
uint8_t retries_left;
5858
uint8_t starting_retries;
5959
uint8_t last_disconnect_reason;
60+
61+
wifi_config_t ap_config;
62+
esp_netif_ip_info_t ap_ip_info;
63+
esp_netif_t *ap_netif;
6064
} wifi_radio_obj_t;
6165

6266
extern void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self);

ports/esp32s2/common-hal/wifi/__init__.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,21 @@ static void event_handler(void *arg, esp_event_base_t event_base,
5050
ESP_LOGW(TAG, "scan");
5151
xEventGroupSetBits(radio->event_group_handle, WIFI_SCAN_DONE_BIT);
5252
break;
53+
case WIFI_EVENT_AP_START:
54+
ESP_LOGW(TAG, "ap start");
55+
break;
56+
case WIFI_EVENT_AP_STOP:
57+
ESP_LOGW(TAG, "ap stop");
58+
break;
59+
case WIFI_EVENT_AP_STACONNECTED:
60+
break;
61+
case WIFI_EVENT_AP_STADISCONNECTED:
62+
break;
5363
case WIFI_EVENT_STA_START:
54-
ESP_LOGW(TAG, "start");
64+
ESP_LOGW(TAG, "sta start");
5565
break;
5666
case WIFI_EVENT_STA_STOP:
57-
ESP_LOGW(TAG, "stop");
67+
ESP_LOGW(TAG, "sta stop");
5868
break;
5969
case WIFI_EVENT_STA_CONNECTED:
6070
ESP_LOGW(TAG, "connected");
@@ -109,6 +119,7 @@ void common_hal_wifi_init(void) {
109119

110120
wifi_radio_obj_t *self = &common_hal_wifi_radio_obj;
111121
self->netif = esp_netif_create_default_wifi_sta();
122+
self->ap_netif = esp_netif_create_default_wifi_ap();
112123
self->started = false;
113124

114125
// Even though we just called esp_netif_create_default_wifi_sta,
@@ -137,6 +148,9 @@ void common_hal_wifi_init(void) {
137148
} else if (result != ESP_OK) {
138149
mp_raise_RuntimeError(translate("Failed to init wifi"));
139150
}
151+
// set station mode to avoid the default SoftAP
152+
esp_wifi_set_mode(WIFI_MODE_STA);
153+
// start wifi
140154
common_hal_wifi_radio_set_enabled(self, true);
141155
}
142156

@@ -155,6 +169,8 @@ void wifi_reset(void) {
155169
ESP_ERROR_CHECK(esp_wifi_deinit());
156170
esp_netif_destroy(radio->netif);
157171
radio->netif = NULL;
172+
esp_netif_destroy(radio->ap_netif);
173+
radio->ap_netif = NULL;
158174
}
159175

160176
void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t *esp_ip_address) {

shared-bindings/wifi/AuthMode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_AUTHMODE_H
2828
#define MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_AUTHMODE_H
2929

30+
#include "py/enum.h"
31+
3032
typedef enum {
3133
AUTHMODE_OPEN,
3234
AUTHMODE_WEP,
@@ -38,5 +40,6 @@ typedef enum {
3840
} wifi_authmode_t;
3941

4042
extern const mp_obj_type_t wifi_authmode_type;
43+
extern const cp_enum_obj_t authmode_OPEN_obj;
4144

4245
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_AUTHMODE_H

0 commit comments

Comments
 (0)