diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 70432cff8e..456f9ac58b 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -682,6 +682,10 @@ msgstr "" msgid "Can't set CCCD on local Characteristic" msgstr "" +#: ports/espressif/common-hal/wifi/Radio.c +msgid "Can't change MAC address while station is started" +msgstr "" + #: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c #: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c msgid "Cannot change USB devices now" @@ -1349,6 +1353,10 @@ msgstr "" msgid "Invalid format chunk size" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid ""Invalid MAC address"" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Invalid memory access." msgstr "" @@ -1461,6 +1469,10 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass." msgstr "" +#: ports/espressif/common-hal/wifi/Radio.c +msgid "MAC address can't be a multicast address" +msgstr "" + #: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -4445,6 +4457,10 @@ msgstr "" msgid "wifi is not enabled" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "wifi ssid must be between 1 and 32 characters" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" diff --git a/ports/espressif/common-hal/wifi/Radio.c b/ports/espressif/common-hal/wifi/Radio.c index bf75cb7624..2861f64d76 100644 --- a/ports/espressif/common-hal/wifi/Radio.c +++ b/ports/espressif/common-hal/wifi/Radio.c @@ -120,6 +120,16 @@ mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) { return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH); } +void common_hal_wifi_radio_set_mac_address(wifi_radio_obj_t *self, const uint8_t *mac) { + if (self->sta_mode) { + mp_raise_RuntimeError(translate("Can't change MAC address while station is started")); + } + if ((mac[0] & 0b1) == 0b1) { + mp_raise_RuntimeError(translate("MAC address can't be a multicast address")); + } + esp_wifi_set_mac(ESP_IF_WIFI_STA, mac); +} + mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self) { uint8_t mac[MAC_ADDRESS_LENGTH]; esp_wifi_get_mac(ESP_IF_WIFI_AP, mac); diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index 9f6c62fce9..0828aac6b5 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -33,6 +33,8 @@ #include "py/runtime.h" #include "py/objproperty.h" +#define MAC_ADDRESS_LENGTH 6 + //| class Radio: //| """Native wifi radio. //| @@ -115,23 +117,38 @@ const mp_obj_property_t wifi_radio_hostname_obj = { MP_ROM_NONE}, }; -//| mac_address: bytes -//| """MAC address of the wifi radio station. (read-only)""" +//| mac_address: ReadableBuffer +//| """MAC address of the wifi radio station. +//| Can only be set while the Station is not started.""" //| -STATIC mp_obj_t wifi_radio_get_mac_address(mp_obj_t self) { +STATIC mp_obj_t wifi_radio_get_mac_address(mp_obj_t self_in) { + wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_FROM_PTR(common_hal_wifi_radio_get_mac_address(self)); - } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_mac_address_obj, wifi_radio_get_mac_address); +STATIC mp_obj_t wifi_radio_set_mac_address(mp_obj_t self_in, mp_obj_t mac_address_in) { + mp_buffer_info_t mac_address; + mp_get_buffer_raise(mac_address_in, &mac_address, MP_BUFFER_READ); + + if (mac_address.len != MAC_ADDRESS_LENGTH) { + mp_raise_ValueError(translate("Invalid MAC address")); + } + + wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_wifi_radio_set_mac_address(self, mac_address.buf); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_set_mac_address_obj, wifi_radio_set_mac_address); + const mp_obj_property_t wifi_radio_mac_address_obj = { .base.type = &mp_type_property, .proxy = { (mp_obj_t)&wifi_radio_get_mac_address_obj, - MP_ROM_NONE, + (mp_obj_t)&wifi_radio_set_mac_address_obj, MP_ROM_NONE }, }; - //| mac_address_ap: bytes //| """MAC address of the wifi radio access point. (read-only)""" //| @@ -307,7 +324,11 @@ STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_m } mp_buffer_info_t ssid; + ssid.len = 0; mp_get_buffer_raise(args[ARG_ssid].u_obj, &ssid, MP_BUFFER_READ); + if (ssid.len > 32) { + mp_raise_ValueError(translate("wifi ssid must be between 1 and 32 characters")); + } mp_buffer_info_t password; password.len = 0; diff --git a/shared-bindings/wifi/Radio.h b/shared-bindings/wifi/Radio.h index eeeffa2f94..19b3ff55e1 100644 --- a/shared-bindings/wifi/Radio.h +++ b/shared-bindings/wifi/Radio.h @@ -78,6 +78,7 @@ extern mp_obj_t common_hal_wifi_radio_get_hostname(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *hostname); extern mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self); +extern void common_hal_wifi_radio_set_mac_address(wifi_radio_obj_t *self, const uint8_t *mac); extern mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self); extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self);