Add MDNS support to Pico W
This adds both cpy-MAC.local and circuitpython.local support. Fixes #7214
This commit is contained in:
parent
ad2d190507
commit
c13ca95da1
|
@ -312,10 +312,12 @@
|
|||
url = https://github.com/adafruit/esp32-camera/
|
||||
[submodule "ports/raspberrypi/lib/cyw43-driver"]
|
||||
path = ports/raspberrypi/lib/cyw43-driver
|
||||
url = https://github.com/georgerobotics/cyw43-driver.git
|
||||
url = https://github.com/adafruit/cyw43-driver.git
|
||||
branch = circuitpython8
|
||||
[submodule "ports/raspberrypi/lib/lwip"]
|
||||
path = ports/raspberrypi/lib/lwip
|
||||
url = https://github.com/lwip-tcpip/lwip.git
|
||||
url = https://github.com/adafruit/lwip.git
|
||||
branch = circuitpython8
|
||||
[submodule "lib/mbedtls"]
|
||||
path = lib/mbedtls
|
||||
url = https://github.com/ARMmbed/mbedtls.git
|
||||
|
|
|
@ -106,7 +106,7 @@ msgstr ""
|
|||
msgid "%q in use"
|
||||
msgstr ""
|
||||
|
||||
#: py/obj.c py/objstr.c py/objstrunicode.c
|
||||
#: py/objstr.c py/objstrunicode.c
|
||||
msgid "%q index out of range"
|
||||
msgstr ""
|
||||
|
||||
|
@ -171,7 +171,7 @@ msgstr ""
|
|||
msgid "%q must be an int"
|
||||
msgstr ""
|
||||
|
||||
#: py/argcheck.c
|
||||
#: py/argcheck.c py/obj.c
|
||||
msgid "%q must be of type %q"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1663,6 +1663,10 @@ msgstr ""
|
|||
msgid "Operation timed out"
|
||||
msgstr ""
|
||||
|
||||
#: ports/raspberrypi/common-hal/mdns/Server.c
|
||||
msgid "Out of MDNS service slots"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c
|
||||
msgid "Out of memory"
|
||||
msgstr ""
|
||||
|
@ -2192,6 +2196,7 @@ msgid "Unable to read color palette data"
|
|||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/mdns/Server.c
|
||||
#: ports/raspberrypi/common-hal/mdns/Server.c
|
||||
msgid "Unable to start mDNS query"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3153,7 +3158,7 @@ msgid "index is out of bounds"
|
|||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c
|
||||
#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c
|
||||
#: ports/espressif/common-hal/pulseio/PulseIn.c
|
||||
#: shared-bindings/bitmaptools/__init__.c
|
||||
msgid "index out of range"
|
||||
msgstr ""
|
||||
|
@ -3405,10 +3410,12 @@ msgid "loopback + silent mode not supported by peripheral"
|
|||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/mdns/Server.c
|
||||
#: ports/raspberrypi/common-hal/mdns/Server.c
|
||||
msgid "mDNS already initialized"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/mdns/Server.c
|
||||
#: ports/raspberrypi/common-hal/mdns/Server.c
|
||||
msgid "mDNS only works with built-in WiFi"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ SRC_SDK_CYW43 := \
|
|||
|
||||
SRC_LWIP := \
|
||||
shared/netutils/netutils.c \
|
||||
$(wildcard lib/lwip/src/apps/mdns/*.c) \
|
||||
$(wildcard lib/lwip/src/core/*.c) \
|
||||
$(wildcard lib/lwip/src/core/ipv4/*.c) \
|
||||
lib/lwip/src/netif/ethernet.c \
|
||||
|
|
|
@ -15,7 +15,7 @@ CIRCUITPY_SSL = 1
|
|||
CIRCUITPY_SSL_MBEDTLS = 1
|
||||
CIRCUITPY_HASHLIB = 1
|
||||
CIRCUITPY_WEB_WORKFLOW = 1
|
||||
CIRCUITPY_MDNS = 0
|
||||
CIRCUITPY_MDNS = 1
|
||||
CIRCUITPY_SOCKETPOOL = 1
|
||||
CIRCUITPY_WIFI = 1
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "shared-bindings/mdns/RemoteService.h"
|
||||
|
||||
#include "shared-bindings/ipaddress/IPv4Address.h"
|
||||
|
||||
const char *common_hal_mdns_remoteservice_get_service_type(mdns_remoteservice_obj_t *self) {
|
||||
return self->service_name;
|
||||
}
|
||||
|
||||
const char *common_hal_mdns_remoteservice_get_protocol(mdns_remoteservice_obj_t *self) {
|
||||
return self->protocol;
|
||||
}
|
||||
|
||||
const char *common_hal_mdns_remoteservice_get_instance_name(mdns_remoteservice_obj_t *self) {
|
||||
return self->instance_name;
|
||||
}
|
||||
|
||||
const char *common_hal_mdns_remoteservice_get_hostname(mdns_remoteservice_obj_t *self) {
|
||||
return self->hostname;
|
||||
}
|
||||
|
||||
mp_int_t common_hal_mdns_remoteservice_get_port(mdns_remoteservice_obj_t *self) {
|
||||
return self->port;
|
||||
}
|
||||
|
||||
uint32_t mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self) {
|
||||
return self->ipv4_address;
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self) {
|
||||
uint32_t addr = mdns_remoteservice_get_ipv4_address(self);
|
||||
if (addr == 0) {
|
||||
return mp_const_none;
|
||||
}
|
||||
return common_hal_ipaddress_new_ipv4address(addr);
|
||||
}
|
||||
|
||||
void common_hal_mdns_remoteservice_deinit(mdns_remoteservice_obj_t *self) {
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lwip/apps/mdns.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
uint32_t ipv4_address;
|
||||
uint16_t port;
|
||||
char protocol[5]; // RFC 6763 Section 7.2 - 4 bytes + 1 for NUL
|
||||
char service_name[17]; // RFC 6763 Section 7.2 - 16 bytes + 1 for NUL
|
||||
char instance_name[64]; // RFC 6763 Section 7.2 - 63 bytes + 1 for NUL
|
||||
char hostname[64]; // RFC 6762 Appendix A - 63 bytes for label + 1 for NUL
|
||||
mp_obj_t next;
|
||||
} mdns_remoteservice_obj_t;
|
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "shared-bindings/mdns/Server.h"
|
||||
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
#include "shared-bindings/mdns/RemoteService.h"
|
||||
#include "shared-bindings/wifi/__init__.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
#include "lwip/apps/mdns.h"
|
||||
#include "lwip/prot/dns.h"
|
||||
|
||||
STATIC bool inited = false;
|
||||
|
||||
#define NETIF_STA (&cyw43_state.netif[CYW43_ITF_STA])
|
||||
#define NETIF_AP (&cyw43_state.netif[CYW43_ITF_AP])
|
||||
|
||||
void mdns_server_construct(mdns_server_obj_t *self, bool workflow) {
|
||||
if (inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
mdns_resp_init();
|
||||
inited = true;
|
||||
|
||||
uint8_t mac[6];
|
||||
wifi_radio_get_mac_address(&common_hal_wifi_radio_obj, mac);
|
||||
snprintf(self->default_hostname, sizeof(self->default_hostname), "cpy-%02x%02x%02x", mac[3], mac[4], mac[5]);
|
||||
common_hal_mdns_server_set_hostname(self, self->default_hostname);
|
||||
|
||||
if (workflow) {
|
||||
// Add a second host entry to respond to "circuitpython.local" queries as well.
|
||||
|
||||
#if MDNS_MAX_SECONDARY_HOSTNAMES > 0
|
||||
mdns_resp_add_secondary_hostname(NETIF_STA, "circuitpython");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_mdns_server_construct(mdns_server_obj_t *self, mp_obj_t network_interface) {
|
||||
if (network_interface != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) {
|
||||
mp_raise_ValueError(translate("mDNS only works with built-in WiFi"));
|
||||
return;
|
||||
}
|
||||
if (inited) {
|
||||
mp_raise_RuntimeError(translate("mDNS already initialized"));
|
||||
}
|
||||
mdns_server_construct(self, false);
|
||||
}
|
||||
|
||||
void common_hal_mdns_server_deinit(mdns_server_obj_t *self) {
|
||||
inited = false;
|
||||
mdns_resp_remove_netif(NETIF_STA);
|
||||
}
|
||||
|
||||
bool common_hal_mdns_server_deinited(mdns_server_obj_t *self) {
|
||||
return !mdns_resp_netif_active(NETIF_STA);
|
||||
}
|
||||
|
||||
const char *common_hal_mdns_server_get_hostname(mdns_server_obj_t *self) {
|
||||
return self->hostname;
|
||||
}
|
||||
|
||||
void common_hal_mdns_server_set_hostname(mdns_server_obj_t *self, const char *hostname) {
|
||||
if (mdns_resp_netif_active(NETIF_STA)) {
|
||||
mdns_resp_rename_netif(NETIF_STA, hostname);
|
||||
} else {
|
||||
mdns_resp_add_netif(NETIF_STA, hostname);
|
||||
}
|
||||
|
||||
self->hostname = hostname;
|
||||
}
|
||||
|
||||
const char *common_hal_mdns_server_get_instance_name(mdns_server_obj_t *self) {
|
||||
return self->instance_name;
|
||||
}
|
||||
|
||||
void common_hal_mdns_server_set_instance_name(mdns_server_obj_t *self, const char *instance_name) {
|
||||
self->instance_name = instance_name;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t request_id;
|
||||
size_t i;
|
||||
mdns_remoteservice_obj_t *out;
|
||||
size_t out_len;
|
||||
} nonalloc_search_state_t;
|
||||
|
||||
STATIC void copy_data_into_remote_service(struct mdns_answer *answer, const char *varpart, int varlen, mdns_remoteservice_obj_t *out) {
|
||||
if (varlen > 0) {
|
||||
if (answer->info.type == DNS_RRTYPE_A) {
|
||||
char *hostname = out->hostname;
|
||||
size_t len = MIN(63, answer->info.domain.name[0]);
|
||||
memcpy(hostname, answer->info.domain.name + 1, len);
|
||||
hostname[len] = '\0';
|
||||
out->ipv4_address = varpart[0] | varpart[1] << 8 | varpart[2] << 16 | varpart[3] << 24;
|
||||
}
|
||||
if (answer->info.type == DNS_RRTYPE_SRV) {
|
||||
// This isn't a null terminated string. Its length encoded.
|
||||
uint8_t *domain = answer->info.domain.name;
|
||||
char *instance_name = out->instance_name;
|
||||
size_t offset = 0;
|
||||
uint8_t iname_len = domain[offset++];
|
||||
size_t len = MIN(63, iname_len);
|
||||
memcpy(instance_name, domain + offset, len);
|
||||
offset += iname_len;
|
||||
instance_name[len] = '\0';
|
||||
|
||||
uint8_t sn_len = domain[offset++];
|
||||
char *service_name = out->service_name;
|
||||
len = MIN(16, sn_len);
|
||||
memcpy(service_name, domain + offset, len);
|
||||
offset += sn_len;
|
||||
service_name[len] = '\0';
|
||||
|
||||
uint8_t proto_len = domain[offset++];
|
||||
char *protocol = out->protocol;
|
||||
len = MIN(4, proto_len);
|
||||
memcpy(protocol, domain + offset, len);
|
||||
offset += proto_len;
|
||||
protocol[len] = '\0';
|
||||
|
||||
out->port = varpart[4] << 8 | varpart[5];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void search_result_cb(struct mdns_answer *answer, const char *varpart, int varlen, int flags, void *arg) {
|
||||
nonalloc_search_state_t *state = arg;
|
||||
state->out[state->i].base.type = &mdns_remoteservice_type;
|
||||
|
||||
copy_data_into_remote_service(answer, varpart, varlen, &state->out[state->i]);
|
||||
|
||||
if ((flags & MDNS_SEARCH_RESULT_LAST) != 0) {
|
||||
state->i += 1;
|
||||
}
|
||||
|
||||
if (state->i == state->out_len) {
|
||||
mdns_search_stop(state->request_id);
|
||||
state->request_id = MDNS_MAX_REQUESTS;
|
||||
}
|
||||
}
|
||||
|
||||
size_t mdns_server_find(mdns_server_obj_t *self, const char *service_type, const char *protocol,
|
||||
mp_float_t timeout, mdns_remoteservice_obj_t *out, size_t out_len) {
|
||||
|
||||
enum mdns_sd_proto proto = DNSSD_PROTO_UDP;
|
||||
if (strcmp(protocol, "_tcp") == 0) {
|
||||
proto = DNSSD_PROTO_TCP;
|
||||
}
|
||||
|
||||
nonalloc_search_state_t state;
|
||||
state.i = 0;
|
||||
state.out = out;
|
||||
state.out_len = out_len;
|
||||
|
||||
err_t err = mdns_search_service(NULL, service_type, proto,
|
||||
NETIF_STA, &search_result_cb, &state,
|
||||
&state.request_id);
|
||||
if (err != ERR_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t start_ticks = supervisor_ticks_ms64();
|
||||
uint64_t timeout_ms = timeout * 1000;
|
||||
|
||||
while (state.request_id < MDNS_MAX_REQUESTS &&
|
||||
!mp_hal_is_interrupted() &&
|
||||
supervisor_ticks_ms64() - start_ticks < timeout_ms) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
}
|
||||
if (state.request_id < MDNS_MAX_REQUESTS) {
|
||||
mdns_search_stop(state.request_id);
|
||||
state.request_id = MDNS_MAX_REQUESTS;
|
||||
}
|
||||
|
||||
return state.i;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t request_id;
|
||||
mdns_remoteservice_obj_t *head;
|
||||
size_t count;
|
||||
} alloc_search_state_t;
|
||||
|
||||
STATIC void alloc_search_result_cb(struct mdns_answer *answer, const char *varpart, int varlen, int flags, void *arg) {
|
||||
alloc_search_state_t *state = arg;
|
||||
|
||||
if ((flags & MDNS_SEARCH_RESULT_FIRST) != 0) {
|
||||
// first
|
||||
mdns_remoteservice_obj_t *service = gc_alloc(sizeof(mdns_remoteservice_obj_t), 0, false);
|
||||
mp_printf(&mp_plat_print, "found service %p\n", service);
|
||||
if (service == NULL) {
|
||||
// alloc fails
|
||||
mdns_search_stop(state->request_id);
|
||||
state->request_id = MDNS_MAX_REQUESTS;
|
||||
if (state->count == 0) {
|
||||
m_malloc_fail(sizeof(mdns_remoteservice_obj_t));
|
||||
}
|
||||
return;
|
||||
}
|
||||
service->base.type = &mdns_remoteservice_type;
|
||||
state->count++;
|
||||
service->next = state->head;
|
||||
state->head = service;
|
||||
}
|
||||
|
||||
copy_data_into_remote_service(answer, varpart, varlen, state->head);
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_mdns_server_find(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_float_t timeout) {
|
||||
enum mdns_sd_proto proto = DNSSD_PROTO_UDP;
|
||||
if (strcmp(protocol, "_tcp") == 0) {
|
||||
proto = DNSSD_PROTO_TCP;
|
||||
}
|
||||
|
||||
alloc_search_state_t state;
|
||||
state.count = 0;
|
||||
state.head = NULL;
|
||||
|
||||
err_t err = mdns_search_service(NULL, service_type, proto,
|
||||
NETIF_STA, &alloc_search_result_cb, &state,
|
||||
&state.request_id);
|
||||
if (err != ERR_OK) {
|
||||
mp_raise_RuntimeError(translate("Unable to start mDNS query"));
|
||||
}
|
||||
|
||||
uint64_t start_ticks = supervisor_ticks_ms64();
|
||||
uint64_t timeout_ms = timeout * 1000;
|
||||
|
||||
while (state.request_id < MDNS_MAX_REQUESTS &&
|
||||
!mp_hal_is_interrupted() &&
|
||||
supervisor_ticks_ms64() - start_ticks < timeout_ms) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
}
|
||||
if (state.request_id < MDNS_MAX_REQUESTS) {
|
||||
mdns_search_stop(state.request_id);
|
||||
state.request_id = MDNS_MAX_REQUESTS;
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(state.count, NULL));
|
||||
mdns_remoteservice_obj_t *next = state.head;
|
||||
uint8_t added = 0;
|
||||
while (next != NULL) {
|
||||
mdns_remoteservice_obj_t *cur = next;
|
||||
tuple->items[added] = MP_OBJ_FROM_PTR(cur);
|
||||
next = cur->next;
|
||||
// Set next back to NULL so that each service object is independently
|
||||
// tracked for GC.
|
||||
cur->next = NULL;
|
||||
added++;
|
||||
}
|
||||
|
||||
return MP_OBJ_FROM_PTR(tuple);
|
||||
}
|
||||
|
||||
void common_hal_mdns_server_advertise_service(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_int_t port) {
|
||||
enum mdns_sd_proto proto = DNSSD_PROTO_UDP;
|
||||
if (strcmp(protocol, "_tcp") == 0) {
|
||||
proto = DNSSD_PROTO_TCP;
|
||||
}
|
||||
// Remove the existing service if it was already added.
|
||||
int8_t existing_slot = MDNS_MAX_SERVICES;
|
||||
for (int i = 0; i < MDNS_MAX_SERVICES; i++) {
|
||||
if (self->service_type[i] != NULL &&
|
||||
(service_type == self->service_type[i] ||
|
||||
strcmp(service_type, self->service_type[i]) == 0)) {
|
||||
existing_slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (existing_slot < MDNS_MAX_SERVICES) {
|
||||
mdns_resp_del_service(NETIF_STA, existing_slot);
|
||||
}
|
||||
int8_t slot = mdns_resp_add_service(NETIF_STA, self->instance_name, service_type, proto, port, NULL, NULL);
|
||||
if (slot < 0) {
|
||||
mp_raise_RuntimeError(translate("Out of MDNS service slots"));
|
||||
return;
|
||||
}
|
||||
self->service_type[slot] = service_type;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
#include "lwip/apps/mdns_opts.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const char *hostname;
|
||||
const char *instance_name;
|
||||
// "cpy-" "XXXXXX" "\0"
|
||||
char default_hostname[4 + 6 + 1];
|
||||
const char *service_type[MDNS_MAX_SERVICES];
|
||||
} mdns_server_obj_t;
|
|
@ -0,0 +1 @@
|
|||
// No mdns module functions.
|
|
@ -42,10 +42,6 @@
|
|||
#include "shared-bindings/time/__init__.h"
|
||||
#include "shared-module/ipaddress/__init__.h"
|
||||
|
||||
#if CIRCUITPY_MDNS
|
||||
#include "components/mdns/include/mdns.h"
|
||||
#endif
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/dns.h"
|
||||
#include "lwip/icmp.h"
|
||||
|
@ -95,6 +91,10 @@ void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *host
|
|||
netif_set_hostname(NETIF_AP, self->hostname);
|
||||
}
|
||||
|
||||
void wifi_radio_get_mac_address(wifi_radio_obj_t *self, uint8_t *mac) {
|
||||
memcpy(mac, cyw43_state.mac, MAC_ADDRESS_LENGTH);
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) {
|
||||
return mp_obj_new_bytes(cyw43_state.mac, MAC_ADDRESS_LENGTH);
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 195dfcc10bb6f379e3dea45147590db2203d3c7b
|
||||
Subproject commit 746e0636033d0550b7652688124a77a6a1639cf9
|
|
@ -1 +1 @@
|
|||
Subproject commit 239918ccc173cb2c2a62f41a40fd893f57faf1d6
|
||||
Subproject commit d26459c32c83aa14a6d4e30237d91cee36e0adbd
|
|
@ -54,6 +54,14 @@
|
|||
#define LWIP_DHCP_DOES_ACD_CHECK 0
|
||||
#define SO_REUSE 1
|
||||
|
||||
#if CIRCUITPY_MDNS
|
||||
#define LWIP_IGMP 1
|
||||
#define LWIP_MDNS_RESPONDER 1
|
||||
#define LWIP_NUM_NETIF_CLIENT_DATA 1
|
||||
#define LWIP_NETIF_EXT_STATUS_CALLBACK 1
|
||||
#define MDNS_MAX_SECONDARY_HOSTNAMES 1
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define LWIP_DEBUG 1
|
||||
#define LWIP_STATS 1
|
||||
|
@ -88,6 +96,7 @@
|
|||
#define PPP_DEBUG LWIP_DBG_OFF
|
||||
#define SLIP_DEBUG LWIP_DBG_OFF
|
||||
#define DHCP_DEBUG LWIP_DBG_OFF
|
||||
#define MDNS_DEBUG LWIP_DBG_OFF
|
||||
|
||||
#define LWIP_TIMEVAL_PRIVATE 0
|
||||
|
||||
|
|
|
@ -140,11 +140,11 @@ MP_PROPERTY_GETSET(wifi_radio_hostname_obj,
|
|||
//| mac_address: ReadableBuffer
|
||||
//| """MAC address for the station. When the address is altered after interface is connected
|
||||
//| the changes would only be reflected once the interface reconnects."""
|
||||
STATIC mp_obj_t wifi_radio_get_mac_address(mp_obj_t self_in) {
|
||||
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);
|
||||
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;
|
||||
|
|
|
@ -77,6 +77,8 @@ extern void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabl
|
|||
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 void wifi_radio_get_mac_address(wifi_radio_obj_t *self, uint8_t *mac);
|
||||
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);
|
||||
|
|
|
@ -428,7 +428,6 @@ static bool _endswith(const char *str, const char *suffix) {
|
|||
}
|
||||
|
||||
const char *ok_hosts[] = {
|
||||
"code.circuitpython.org",
|
||||
"127.0.0.1",
|
||||
"localhost",
|
||||
};
|
||||
|
@ -1393,38 +1392,44 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request)
|
|||
|
||||
|
||||
void supervisor_web_workflow_background(void) {
|
||||
// If we have a request in progress, continue working on it. Do this first
|
||||
// so that we can accept another socket after finishing this request.
|
||||
if (common_hal_socketpool_socket_get_connected(&active)) {
|
||||
_process_request(&active, &active_request);
|
||||
} else {
|
||||
// Close the active socket if it is no longer connected.
|
||||
common_hal_socketpool_socket_close(&active);
|
||||
}
|
||||
|
||||
// Otherwise, see if we have another socket to accept.
|
||||
if ((!common_hal_socketpool_socket_get_connected(&active) ||
|
||||
(!active_request.in_progress && !active_request.new_socket)) &&
|
||||
!common_hal_socketpool_socket_get_closed(&listening)) {
|
||||
uint32_t ip;
|
||||
uint32_t port;
|
||||
int newsoc = socketpool_socket_accept(&listening, (uint8_t *)&ip, &port, &active);
|
||||
if (newsoc == -EBADF) {
|
||||
common_hal_socketpool_socket_close(&listening);
|
||||
return;
|
||||
// Track if we have more to do. For example, we should start processing a
|
||||
// request immediately after we accept the socket.
|
||||
bool more_to_do = true;
|
||||
while (more_to_do) {
|
||||
more_to_do = false;
|
||||
// If we have a request in progress, continue working on it. Do this first
|
||||
// so that we can accept another socket after finishing this request.
|
||||
if (common_hal_socketpool_socket_get_connected(&active)) {
|
||||
_process_request(&active, &active_request);
|
||||
} else {
|
||||
// Close the active socket if it is no longer connected.
|
||||
common_hal_socketpool_socket_close(&active);
|
||||
}
|
||||
if (newsoc > 0) {
|
||||
common_hal_socketpool_socket_settimeout(&active, 0);
|
||||
|
||||
_reset_request(&active_request);
|
||||
// Mark new sockets, otherwise we may accept another before the first
|
||||
// could start its request.
|
||||
active_request.new_socket = true;
|
||||
// Otherwise, see if we have another socket to accept.
|
||||
if ((!common_hal_socketpool_socket_get_connected(&active) ||
|
||||
(!active_request.in_progress && !active_request.new_socket)) &&
|
||||
!common_hal_socketpool_socket_get_closed(&listening)) {
|
||||
uint32_t ip;
|
||||
uint32_t port;
|
||||
int newsoc = socketpool_socket_accept(&listening, (uint8_t *)&ip, &port, &active);
|
||||
if (newsoc == -EBADF) {
|
||||
common_hal_socketpool_socket_close(&listening);
|
||||
return;
|
||||
}
|
||||
if (newsoc > 0) {
|
||||
common_hal_socketpool_socket_settimeout(&active, 0);
|
||||
|
||||
_reset_request(&active_request);
|
||||
// Mark new sockets, otherwise we may accept another before the first
|
||||
// could start its request.
|
||||
active_request.new_socket = true;
|
||||
more_to_do = true;
|
||||
}
|
||||
}
|
||||
|
||||
websocket_background();
|
||||
}
|
||||
|
||||
|
||||
websocket_background();
|
||||
}
|
||||
|
||||
void supervisor_stop_web_workflow(void) {
|
||||
|
|
Loading…
Reference in New Issue