From 193e936807e086fca6f73ad2d0c7f5625a63fd0e Mon Sep 17 00:00:00 2001
From: anecdata <16617689+anecdata@users.noreply.github.com>
Date: Tue, 16 Nov 2021 12:21:50 -0600
Subject: [PATCH] like #5571, but for AP

---
 locale/circuitpython.pot                |  2 +-
 ports/espressif/common-hal/wifi/Radio.c | 13 +++++++++++-
 shared-bindings/wifi/Radio.c            | 27 +++++++++++++++++++------
 shared-bindings/wifi/Radio.h            |  1 +
 4 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index 945ac7c336a5f..f7614caa2f29d 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -2143,7 +2143,7 @@ msgid "Stack size must be at least 256"
 msgstr ""
 
 #: ports/espressif/common-hal/wifi/Radio.c
-msgid "Station must be started"
+msgid "Interface must be started"
 msgstr ""
 
 #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c
diff --git a/ports/espressif/common-hal/wifi/Radio.c b/ports/espressif/common-hal/wifi/Radio.c
index d3feb261f7668..9e4b7165a4d23 100644
--- a/ports/espressif/common-hal/wifi/Radio.c
+++ b/ports/espressif/common-hal/wifi/Radio.c
@@ -112,6 +112,7 @@ mp_obj_t common_hal_wifi_radio_get_hostname(wifi_radio_obj_t *self) {
 
 void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *hostname) {
     esp_netif_set_hostname(self->netif, hostname);
+    esp_netif_set_hostname(self->ap_netif, hostname);
 }
 
 mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) {
@@ -122,7 +123,7 @@ mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) {
 
 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("Station must be started"));
+        mp_raise_RuntimeError(translate("Interface must be started"));
     }
     if ((mac[0] & 0b1) == 0b1) {
         mp_raise_RuntimeError(translate("Invalid multicast MAC address"));
@@ -136,6 +137,16 @@ mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self) {
     return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH);
 }
 
+void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, const uint8_t *mac) {
+    if (!self->ap_mode) {
+        mp_raise_RuntimeError(translate("Interface must be started"));
+    }
+    if ((mac[0] & 0b1) == 0b1) {
+        mp_raise_RuntimeError(translate("Invalid multicast MAC address"));
+    }
+    esp_wifi_set_mac(ESP_IF_WIFI_AP, mac);
+}
+
 mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) {
     if (self->current_scan != NULL) {
         mp_raise_RuntimeError(translate("Already scanning for wifi networks"));
diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c
index 332188539f04a..93d92630ca74c 100644
--- a/shared-bindings/wifi/Radio.c
+++ b/shared-bindings/wifi/Radio.c
@@ -149,23 +149,38 @@ const mp_obj_property_t wifi_radio_mac_address_obj = {
                MP_ROM_NONE },
 };
 
-//|     mac_address_ap: bytes
-//|     """MAC address of the wifi radio access point. (read-only)"""
+//|     mac_address_ap: ReadableBuffer
+//|     """MAC address for the AP. When the address is altered after interface is started
+//|        the changes would only be reflected once the interface restarts."""
 //|
-STATIC mp_obj_t wifi_radio_get_mac_address_ap(mp_obj_t self) {
+STATIC mp_obj_t wifi_radio_get_mac_address_ap(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_ap(self));
-
 }
 MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_mac_address_ap_obj, wifi_radio_get_mac_address_ap);
 
+STATIC mp_obj_t wifi_radio_set_mac_address_ap(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_ap(self, mac_address.buf);
+
+    return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_set_mac_address_ap_obj, wifi_radio_set_mac_address_ap);
+
 const mp_obj_property_t wifi_radio_mac_address_ap_obj = {
     .base.type = &mp_type_property,
     .proxy = { (mp_obj_t)&wifi_radio_get_mac_address_ap_obj,
-               MP_ROM_NONE,
+               (mp_obj_t)&wifi_radio_set_mac_address_ap_obj,
                MP_ROM_NONE },
 };
 
-
 //|     def start_scanning_networks(self, *, start_channel: int = 1, stop_channel: int = 11) -> Iterable[Network]:
 //|         """Scans for available wifi networks over the given channel range. Make sure the channels are allowed in your country."""
 //|         ...
diff --git a/shared-bindings/wifi/Radio.h b/shared-bindings/wifi/Radio.h
index 19b3ff55e1843..78a0c333cde28 100644
--- a/shared-bindings/wifi/Radio.h
+++ b/shared-bindings/wifi/Radio.h
@@ -80,6 +80,7 @@ extern void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const cha
 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 void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, const uint8_t *mac);
 
 extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self);
 extern void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self);