Skip to content

Commit 79b76f7

Browse files
authored
Merge pull request #7445 from tannewt/fix_rpi_mdns
Share the web workflow MDNS object with the user
2 parents 8dffd33 + ee2fe99 commit 79b76f7

File tree

7 files changed

+99
-35
lines changed

7 files changed

+99
-35
lines changed

ports/espressif/common-hal/mdns/Server.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ STATIC bool inited = false;
3737

3838
void mdns_server_construct(mdns_server_obj_t *self, bool workflow) {
3939
if (inited) {
40+
self->inited = false;
4041
return;
4142
}
4243
mdns_init();
@@ -46,6 +47,8 @@ void mdns_server_construct(mdns_server_obj_t *self, bool workflow) {
4647
snprintf(self->default_hostname, sizeof(self->default_hostname), "cpy-%02x%02x%02x", mac[3], mac[4], mac[5]);
4748
common_hal_mdns_server_set_hostname(self, self->default_hostname);
4849

50+
self->inited = true;
51+
4952
if (workflow) {
5053
// Set a delegated entry to ourselves. This allows us to respond to "circuitpython.local"
5154
// queries as well.
@@ -67,21 +70,23 @@ void common_hal_mdns_server_construct(mdns_server_obj_t *self, mp_obj_t network_
6770
mp_raise_ValueError(translate("mDNS only works with built-in WiFi"));
6871
return;
6972
}
70-
if (inited) {
73+
mdns_server_construct(self, false);
74+
if (common_hal_mdns_server_deinited(self)) {
7175
mp_raise_RuntimeError(translate("mDNS already initialized"));
7276
}
73-
mdns_server_construct(self, false);
7477
}
7578

7679
void common_hal_mdns_server_deinit(mdns_server_obj_t *self) {
80+
if (common_hal_mdns_server_deinited(self)) {
81+
return;
82+
}
83+
self->inited = false;
7784
inited = false;
7885
mdns_free();
7986
}
8087

8188
bool common_hal_mdns_server_deinited(mdns_server_obj_t *self) {
82-
// This returns INVALID_STATE when not initialized and INVALID_PARAM when it
83-
// is.
84-
return mdns_instance_name_set(NULL) == ESP_ERR_INVALID_STATE;
89+
return !self->inited;
8590
}
8691

8792
const char *common_hal_mdns_server_get_hostname(mdns_server_obj_t *self) {

ports/espressif/common-hal/mdns/Server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ typedef struct {
3434
const char *instance_name;
3535
// "cpy-" "XXXXXX" "\0"
3636
char default_hostname[4 + 6 + 1];
37+
bool inited;
3738
} mdns_server_obj_t;

ports/raspberrypi/common-hal/mdns/Server.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,29 @@
3636
#include "lwip/apps/mdns.h"
3737
#include "lwip/prot/dns.h"
3838

39+
// Track if we've inited the LWIP MDNS at all. It expects to only init once.
40+
// Subsequent times, we restart it.
3941
STATIC bool inited = false;
42+
// Track if we are globally inited. This essentially forces one inited MDNS
43+
// object at a time. (But ignores MDNS objects that are deinited.)
44+
STATIC bool object_inited = false;
4045

4146
#define NETIF_STA (&cyw43_state.netif[CYW43_ITF_STA])
4247
#define NETIF_AP (&cyw43_state.netif[CYW43_ITF_AP])
4348

4449
void mdns_server_construct(mdns_server_obj_t *self, bool workflow) {
45-
if (inited) {
50+
if (object_inited) {
51+
self->inited = false;
4652
return;
4753
}
4854

49-
mdns_resp_init();
50-
inited = true;
55+
if (!inited) {
56+
mdns_resp_init();
57+
inited = true;
58+
} else {
59+
mdns_resp_restart(NETIF_STA);
60+
}
61+
self->inited = true;
5162

5263
uint8_t mac[6];
5364
wifi_radio_get_mac_address(&common_hal_wifi_radio_obj, mac);
@@ -68,19 +79,23 @@ void common_hal_mdns_server_construct(mdns_server_obj_t *self, mp_obj_t network_
6879
mp_raise_ValueError(translate("mDNS only works with built-in WiFi"));
6980
return;
7081
}
71-
if (inited) {
82+
if (object_inited) {
7283
mp_raise_RuntimeError(translate("mDNS already initialized"));
7384
}
7485
mdns_server_construct(self, false);
7586
}
7687

7788
void common_hal_mdns_server_deinit(mdns_server_obj_t *self) {
78-
inited = false;
89+
if (common_hal_mdns_server_deinited(self)) {
90+
return;
91+
}
92+
self->inited = false;
93+
object_inited = false;
7994
mdns_resp_remove_netif(NETIF_STA);
8095
}
8196

8297
bool common_hal_mdns_server_deinited(mdns_server_obj_t *self) {
83-
return !mdns_resp_netif_active(NETIF_STA);
98+
return !self->inited;
8499
}
85100

86101
const char *common_hal_mdns_server_get_hostname(mdns_server_obj_t *self) {
@@ -215,7 +230,6 @@ STATIC void alloc_search_result_cb(struct mdns_answer *answer, const char *varpa
215230
if ((flags & MDNS_SEARCH_RESULT_FIRST) != 0) {
216231
// first
217232
mdns_remoteservice_obj_t *service = gc_alloc(sizeof(mdns_remoteservice_obj_t), 0, false);
218-
mp_printf(&mp_plat_print, "found service %p\n", service);
219233
if (service == NULL) {
220234
// alloc fails
221235
mdns_search_stop(state->request_id);

ports/raspberrypi/common-hal/mdns/Server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ typedef struct {
3737
// "cpy-" "XXXXXX" "\0"
3838
char default_hostname[4 + 6 + 1];
3939
const char *service_type[MDNS_MAX_SERVICES];
40+
bool inited;
4041
} mdns_server_obj_t;

shared-bindings/mdns/Server.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
#include "shared-bindings/mdns/Server.h"
3434
#include "shared-bindings/util.h"
3535

36+
#if CIRCUITPY_WEB_WORKFLOW
37+
#include "supervisor/shared/web_workflow/web_workflow.h"
38+
#endif
39+
3640
//| class Server:
3741
//| """The MDNS Server responds to queries for this device's information and allows for querying
3842
//| other devices."""
@@ -53,7 +57,14 @@ STATIC mp_obj_t mdns_server_make_new(const mp_obj_type_t *type, size_t n_args, s
5357
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
5458
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
5559

56-
mdns_server_obj_t *self = m_new_obj(mdns_server_obj_t);
60+
#if CIRCUITPY_WEB_WORKFLOW
61+
mdns_server_obj_t *web_workflow_mdns = supervisor_web_workflow_mdns(args[ARG_network_interface].u_obj);
62+
if (web_workflow_mdns != NULL) {
63+
return web_workflow_mdns;
64+
}
65+
#endif
66+
67+
mdns_server_obj_t *self = m_new_obj_with_finaliser(mdns_server_obj_t);
5768
self->base.type = &mdns_server_type;
5869
common_hal_mdns_server_construct(self, args[ARG_network_interface].u_obj);
5970

@@ -194,6 +205,7 @@ STATIC const mp_rom_map_elem_t mdns_server_locals_dict_table[] = {
194205
{ MP_ROM_QSTR(MP_QSTR_find), MP_ROM_PTR(&mdns_server_find_obj) },
195206
{ MP_ROM_QSTR(MP_QSTR_advertise_service), MP_ROM_PTR(&mdns_server_advertise_service_obj) },
196207

208+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mdns_server_deinit_obj) },
197209
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mdns_server_deinit_obj) },
198210
};
199211

supervisor/shared/web_workflow/web_workflow.c

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,16 @@ STATIC void _update_encoded_ip(void) {
200200
}
201201
}
202202

203+
mdns_server_obj_t *supervisor_web_workflow_mdns(mp_obj_t network_interface) {
204+
#if CIRCUITPY_MDNS
205+
if (network_interface == &common_hal_wifi_radio_obj &&
206+
mdns.base.type == &mdns_server_type) {
207+
return &mdns;
208+
}
209+
#endif
210+
return NULL;
211+
}
212+
203213
#if CIRCUITPY_STATUS_BAR
204214
bool supervisor_web_workflow_status_dirty(void) {
205215
return common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) != _last_enabled ||
@@ -300,11 +310,6 @@ void supervisor_start_web_workflow(void) {
300310

301311
if (first_start) {
302312
port_changed = false;
303-
#if CIRCUITPY_MDNS
304-
mdns_server_construct(&mdns, true);
305-
mdns.base.type = &mdns_server_type;
306-
common_hal_mdns_server_set_instance_name(&mdns, MICROPY_HW_BOARD_NAME);
307-
#endif
308313
pool.base.type = &socketpool_socketpool_type;
309314
common_hal_socketpool_socketpool_construct(&pool, &common_hal_wifi_radio_obj);
310315

@@ -313,13 +318,26 @@ void supervisor_start_web_workflow(void) {
313318

314319
websocket_init();
315320
}
321+
#if CIRCUITPY_MDNS
322+
// Try to start MDNS if the user deinited it.
323+
if (mdns.base.type != &mdns_server_type ||
324+
common_hal_mdns_server_deinited(&mdns)) {
325+
mdns_server_construct(&mdns, true);
326+
mdns.base.type = &mdns_server_type;
327+
if (!common_hal_mdns_server_deinited(&mdns)) {
328+
common_hal_mdns_server_set_instance_name(&mdns, MICROPY_HW_BOARD_NAME);
329+
}
330+
}
331+
#endif
316332
if (port_changed) {
317333
common_hal_socketpool_socket_close(&listening);
318334
}
319335
if (first_start || port_changed) {
320336
web_api_port = new_port;
321337
#if CIRCUITPY_MDNS
322-
common_hal_mdns_server_advertise_service(&mdns, "_circuitpython", "_tcp", web_api_port);
338+
if (!common_hal_mdns_server_deinited(&mdns)) {
339+
common_hal_mdns_server_advertise_service(&mdns, "_circuitpython", "_tcp", web_api_port);
340+
}
323341
#endif
324342
socketpool_socket(&pool, SOCKETPOOL_AF_INET, SOCKETPOOL_SOCK_STREAM, &listening);
325343
common_hal_socketpool_socket_settimeout(&listening, 0);
@@ -444,17 +462,18 @@ static bool _origin_ok(const char *origin) {
444462
}
445463
// These are prefix checks up to : so that any port works.
446464
// TODO: Support DHCP hostname in addition to MDNS.
465+
const char *end;
447466
#if CIRCUITPY_MDNS
448-
const char *local = ".local";
449-
const char *hostname = common_hal_mdns_server_get_hostname(&mdns);
450-
const char *end = origin + strlen(http) + strlen(hostname) + strlen(local);
451-
if (strncmp(origin + strlen(http), hostname, strlen(hostname)) == 0 &&
452-
strncmp(origin + strlen(http) + strlen(hostname), local, strlen(local)) == 0 &&
453-
(end[0] == '\0' || end[0] == ':')) {
454-
return true;
467+
if (!common_hal_mdns_server_deinited(&mdns)) {
468+
const char *local = ".local";
469+
const char *hostname = common_hal_mdns_server_get_hostname(&mdns);
470+
end = origin + strlen(http) + strlen(hostname) + strlen(local);
471+
if (strncmp(origin + strlen(http), hostname, strlen(hostname)) == 0 &&
472+
strncmp(origin + strlen(http) + strlen(hostname), local, strlen(local)) == 0 &&
473+
(end[0] == '\0' || end[0] == ':')) {
474+
return true;
475+
}
455476
}
456-
#else
457-
const char *end;
458477
#endif
459478

460479
_update_encoded_ip();
@@ -733,12 +752,13 @@ static void _reply_with_file(socketpool_socket_obj_t *socket, _request *request,
733752
}
734753

735754
static void _reply_with_devices_json(socketpool_socket_obj_t *socket, _request *request) {
755+
size_t total_results = 0;
736756
#if CIRCUITPY_MDNS
737757
mdns_remoteservice_obj_t found_devices[32];
738-
size_t total_results = mdns_server_find(&mdns, "_circuitpython", "_tcp", 1, found_devices, MP_ARRAY_SIZE(found_devices));
758+
if (!common_hal_mdns_server_deinited(&mdns)) {
759+
total_results = mdns_server_find(&mdns, "_circuitpython", "_tcp", 1, found_devices, MP_ARRAY_SIZE(found_devices));
760+
}
739761
size_t count = MIN(total_results, MP_ARRAY_SIZE(found_devices));
740-
#else
741-
size_t total_results = 0;
742762
#endif
743763
socketpool_socket_send(socket, (const uint8_t *)OK_JSON, strlen(OK_JSON));
744764
_cors_header(socket, request);
@@ -775,10 +795,11 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request *
775795
_send_str(socket, "\r\n");
776796
mp_print_t _socket_print = {socket, _print_chunk};
777797

778-
#if CIRCUITPY_MDNS
779-
const char *hostname = common_hal_mdns_server_get_hostname(&mdns);
780-
#else
781798
const char *hostname = "";
799+
#if CIRCUITPY_MDNS
800+
if (!common_hal_mdns_server_deinited(&mdns)) {
801+
hostname = common_hal_mdns_server_get_hostname(&mdns);
802+
}
782803
#endif
783804
_update_encoded_ip();
784805
// Note: this leverages the fact that C concats consecutive string literals together.
@@ -1023,7 +1044,13 @@ static void _decode_percents(char *str) {
10231044
static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
10241045
if (request->redirect) {
10251046
#if CIRCUITPY_MDNS
1026-
_reply_redirect(socket, request, request->path);
1047+
if (!common_hal_mdns_server_deinited(&mdns)) {
1048+
_reply_redirect(socket, request, request->path);
1049+
} else {
1050+
_reply_missing(socket, request);
1051+
}
1052+
#else
1053+
_reply_missing(socket, request);
10271054
#endif
10281055
} else if (strlen(request->origin) > 0 && !_origin_ok(request->origin)) {
10291056
_reply_forbidden(socket, request);

supervisor/shared/web_workflow/web_workflow.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include <stdbool.h>
3030

31+
#include "shared-bindings/mdns/Server.h"
3132
#include "shared-bindings/socketpool/Socket.h"
3233

3334
// This background function should be called repeatedly. It cannot be done based
@@ -38,5 +39,8 @@ void supervisor_web_workflow_status(void);
3839
void supervisor_start_web_workflow(void);
3940
void supervisor_stop_web_workflow(void);
4041

42+
// Share the MDNS object with user code.
43+
mdns_server_obj_t *supervisor_web_workflow_mdns(mp_obj_t network_interface);
44+
4145
// To share with websocket.
4246
void web_workflow_send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len);

0 commit comments

Comments
 (0)