From a50c2b0760214221b98fef12ff4bf01866793067 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Thu, 12 Dec 2024 10:04:00 -0800 Subject: [PATCH 1/3] Add MDNS.addServiceTxt() to SimpleMDNS Fixes #2678 A simple mapping allows for basic service text addition even when using SimpleMDNS and ArduinoOTA. --- libraries/SimpleMDNS/src/SimpleMDNS.cpp | 68 +++++++++++++++++++++++-- libraries/SimpleMDNS/src/SimpleMDNS.h | 35 ++++++++++++- 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/libraries/SimpleMDNS/src/SimpleMDNS.cpp b/libraries/SimpleMDNS/src/SimpleMDNS.cpp index 6eeeb5d25..6472e03e1 100644 --- a/libraries/SimpleMDNS/src/SimpleMDNS.cpp +++ b/libraries/SimpleMDNS/src/SimpleMDNS.cpp @@ -52,18 +52,21 @@ void SimpleMDNS::enableArduino(unsigned int port, bool passwd) { } } -void SimpleMDNS::addService(const char *service, const char *proto, unsigned int port) { +hMDNSService SimpleMDNS::addService(const char *service, const char *proto, unsigned int port) { if (!_running) { - return; + return nullptr; } char s[128]; snprintf(s, sizeof(s), "_%s", service); s[sizeof(s) - 1] = 0; + SimpleMDNSService *svc = new SimpleMDNSService(); + _svcMap.insert({strdup(service), svc}); struct netif *n = netif_list; while (n) { - mdns_resp_add_service(n, _hostname, s, !strcasecmp("tcp", proto) ? DNSSD_PROTO_TCP : DNSSD_PROTO_UDP, port, _nullGetTxt, nullptr); + mdns_resp_add_service(n, _hostname, s, !strcasecmp("tcp", proto) ? DNSSD_PROTO_TCP : DNSSD_PROTO_UDP, port, SimpleMDNSService::callback, (void *)svc); n = n->next; } + return (hMDNSService*) service; } void SimpleMDNS::update() { @@ -89,10 +92,65 @@ void SimpleMDNS::_arduinoGetTxt(struct mdns_service *service, void *txt_userdata _addServiceTxt(service, (bool)txt_userdata ? "auth_upload=yes" : "auth_upload=no"); } -void SimpleMDNS::_nullGetTxt(struct mdns_service *service, void *txt_userdata) { - /* nop */ + +SimpleMDNSService::SimpleMDNSService() { +} + +void SimpleMDNSService::callback(struct mdns_service *service, void *txt_userdata) { + SimpleMDNSService *obj = (SimpleMDNSService *)txt_userdata; + for (auto s : obj->txt) { + mdns_resp_add_service_txtitem(service, s, strlen(s)); + } +} + +hMDNSTxt SimpleMDNSService::add(const char *key, const char *value) { + char s[128]; + snprintf(s, sizeof(s), "%s=%s", key, value); + s[sizeof(s) - 1] = 0; + char *copy = strdup(s); + txt.push_back(copy); + return (void *)copy; // Do not use... +}; + +// Add a (static) MDNS TXT item ('key' = 'value') to the service +hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, const char* p_pcValue) { + const char *s = (const char *)p_hService; + auto o = _svcMap.find(s); + if (o != _svcMap.end()) { + return o->second->add(p_pcKey, p_pcValue); + } + return nullptr; +} + +hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, uint32_t p_u32Value) { + char s[16]; + sprintf(s, "%lu", p_u32Value); + return addServiceTxt(p_hService, p_pcKey, s); } +hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, uint16_t p_u16Value) { + return addServiceTxt(p_hService, p_pcKey, (uint32_t)p_u16Value); +} + +hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, uint8_t p_u8Value) { + return addServiceTxt(p_hService, p_pcKey, (uint32_t)p_u8Value); +} + +hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, int32_t p_i32Value) { + char s[16]; + sprintf(s, "%ld", p_i32Value); + return addServiceTxt(p_hService, p_pcKey, s); +} + +hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, int16_t p_i16Value) { + return addServiceTxt(p_hService, p_pcKey, (int32_t)p_i16Value); +} + +hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, int8_t p_i8Value) { + return addServiceTxt(p_hService, p_pcKey, (int32_t)p_i8Value); +} + + const char *SimpleMDNS::_hostname = nullptr; SimpleMDNS MDNS; diff --git a/libraries/SimpleMDNS/src/SimpleMDNS.h b/libraries/SimpleMDNS/src/SimpleMDNS.h index 0e7c8ab9e..e67044300 100644 --- a/libraries/SimpleMDNS/src/SimpleMDNS.h +++ b/libraries/SimpleMDNS/src/SimpleMDNS.h @@ -21,13 +21,44 @@ #pragma once #include +#include +#include +#include + +typedef void* hMDNSTxt; // Unusable in SimpleMDNS, for signature compatibilty only + +class SimpleMDNSService { +public: + SimpleMDNSService(); + static void callback(struct mdns_service *service, void *txt_userdata); + hMDNSTxt add(const char *key, const char *val); +private: + std::vector txt; +}; + +// hMDNSService (opaque handle to access the service) +typedef const void* hMDNSService; class SimpleMDNS { public: bool begin(const char *hostname, unsigned int ttl = 60); void enableArduino(unsigned int port, bool passwd = false); - void addService(const char *service, const char *proto, unsigned int port); + + hMDNSService addService(const char *service, const char *proto, unsigned int port); + hMDNSService addService(const char *name, const char *service, const char *proto, unsigned int port) { + (void) name; // Ignored + return addService(service, proto, port); + } + + // Add a (static) MDNS TXT item ('key' = 'value') to the service + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, const char* p_pcValue); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, uint32_t p_u32Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, uint16_t p_u16Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, uint8_t p_u8Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, int32_t p_i32Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, int16_t p_i16Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, int8_t p_i8Value); // No-ops here void end(); @@ -37,10 +68,10 @@ class SimpleMDNS { static void _statusCB(struct netif *netif); static void _addServiceTxt(struct mdns_service *service, const char *str); static void _arduinoGetTxt(struct mdns_service *service, void *txt_userdata); - static void _nullGetTxt(struct mdns_service *service, void *txt_userdata); bool _running = false; static const char *_hostname; + std::map _svcMap; }; extern SimpleMDNS MDNS; From 4b161d85211c17a7c235bd397e7b0eff50839dd1 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Thu, 12 Dec 2024 10:14:13 -0800 Subject: [PATCH 2/3] Spelling --- libraries/SimpleMDNS/src/SimpleMDNS.cpp | 4 ++-- libraries/SimpleMDNS/src/SimpleMDNS.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/SimpleMDNS/src/SimpleMDNS.cpp b/libraries/SimpleMDNS/src/SimpleMDNS.cpp index 6472e03e1..9e98b71b6 100644 --- a/libraries/SimpleMDNS/src/SimpleMDNS.cpp +++ b/libraries/SimpleMDNS/src/SimpleMDNS.cpp @@ -143,11 +143,11 @@ hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_ } hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, int16_t p_i16Value) { - return addServiceTxt(p_hService, p_pcKey, (int32_t)p_i16Value); + return addServiceTxt(p_hService, p_pcKey, (int32_t)p_i16Value); } hMDNSTxt SimpleMDNS::addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, int8_t p_i8Value) { - return addServiceTxt(p_hService, p_pcKey, (int32_t)p_i8Value); + return addServiceTxt(p_hService, p_pcKey, (int32_t)p_i8Value); } diff --git a/libraries/SimpleMDNS/src/SimpleMDNS.h b/libraries/SimpleMDNS/src/SimpleMDNS.h index e67044300..eb6114596 100644 --- a/libraries/SimpleMDNS/src/SimpleMDNS.h +++ b/libraries/SimpleMDNS/src/SimpleMDNS.h @@ -25,7 +25,7 @@ #include #include -typedef void* hMDNSTxt; // Unusable in SimpleMDNS, for signature compatibilty only +typedef void* hMDNSTxt; // Unusable in SimpleMDNS, for signature compatibility only class SimpleMDNSService { public: From d61a714aea421e1663cfd679a792eeb8ab7f33e2 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Thu, 12 Dec 2024 11:10:25 -0800 Subject: [PATCH 3/3] Protection against duplicate services addition --- libraries/SimpleMDNS/src/SimpleMDNS.cpp | 7 ++++++- libraries/SimpleMDNS/src/SimpleMDNS.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/SimpleMDNS/src/SimpleMDNS.cpp b/libraries/SimpleMDNS/src/SimpleMDNS.cpp index 9e98b71b6..700d8bd68 100644 --- a/libraries/SimpleMDNS/src/SimpleMDNS.cpp +++ b/libraries/SimpleMDNS/src/SimpleMDNS.cpp @@ -42,7 +42,7 @@ bool SimpleMDNS::begin(const char *hostname, unsigned int ttl) { } void SimpleMDNS::enableArduino(unsigned int port, bool passwd) { - if (!_running) { + if (!_running || _arduinoAdded) { return; } struct netif *n = netif_list; @@ -50,12 +50,17 @@ void SimpleMDNS::enableArduino(unsigned int port, bool passwd) { mdns_resp_add_service(n, _hostname, "_arduino", DNSSD_PROTO_TCP, port, _arduinoGetTxt, (void *)passwd); n = n->next; } + _arduinoAdded = true; } hMDNSService SimpleMDNS::addService(const char *service, const char *proto, unsigned int port) { if (!_running) { return nullptr; } + if (_svcMap.find(service) != _svcMap.end()) { + // Duplicates = error + return nullptr; + } char s[128]; snprintf(s, sizeof(s), "_%s", service); s[sizeof(s) - 1] = 0; diff --git a/libraries/SimpleMDNS/src/SimpleMDNS.h b/libraries/SimpleMDNS/src/SimpleMDNS.h index eb6114596..eb70b5481 100644 --- a/libraries/SimpleMDNS/src/SimpleMDNS.h +++ b/libraries/SimpleMDNS/src/SimpleMDNS.h @@ -72,6 +72,7 @@ class SimpleMDNS { bool _running = false; static const char *_hostname; std::map _svcMap; + bool _arduinoAdded = false; }; extern SimpleMDNS MDNS;