mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
parent
52bc1df424
commit
9bdcd4f36a
@ -1,10 +1,10 @@
|
|||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNS responder global instance
|
MDNS responder global instance
|
||||||
*
|
|
||||||
* Class type that is instantiated depends on the type mapping in ESP8266mDNS.h
|
Class type that is instantiated depends on the type mapping in ESP8266mDNS.h
|
||||||
*/
|
*/
|
||||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS)
|
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS)
|
||||||
MDNSResponder MDNS;
|
MDNSResponder MDNS;
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,10 +47,10 @@
|
|||||||
|
|
||||||
|
|
||||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS)
|
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS)
|
||||||
// Maps the implementation to use to the global namespace type
|
// Maps the implementation to use to the global namespace type
|
||||||
//using MDNSResponder = Legacy_MDNSResponder::MDNSResponder; //legacy
|
//using MDNSResponder = Legacy_MDNSResponder::MDNSResponder; //legacy
|
||||||
using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; //new
|
using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; //new
|
||||||
|
|
||||||
extern MDNSResponder MDNS;
|
extern MDNSResponder MDNS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,26 +1,26 @@
|
|||||||
/*
|
/*
|
||||||
ESP8266 Multicast DNS (port of CC3000 Multicast DNS library)
|
ESP8266 Multicast DNS (port of CC3000 Multicast DNS library)
|
||||||
Version 1.1
|
Version 1.1
|
||||||
Copyright (c) 2013 Tony DiCola (tony@tonydicola.com)
|
Copyright (c) 2013 Tony DiCola (tony@tonydicola.com)
|
||||||
ESP8266 port (c) 2015 Ivan Grokhotkov (ivan@esp8266.com)
|
ESP8266 port (c) 2015 Ivan Grokhotkov (ivan@esp8266.com)
|
||||||
Extended MDNS-SD support 2016 Lars Englund (lars.englund@gmail.com)
|
Extended MDNS-SD support 2016 Lars Englund (lars.englund@gmail.com)
|
||||||
|
|
||||||
This is a simple implementation of multicast DNS query support for an Arduino
|
This is a simple implementation of multicast DNS query support for an Arduino
|
||||||
running on ESP8266 chip. Only support for resolving address queries is currently
|
running on ESP8266 chip. Only support for resolving address queries is currently
|
||||||
implemented.
|
implemented.
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
- ESP8266WiFi library
|
- ESP8266WiFi library
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
- Include the ESP8266 Multicast DNS library in the sketch.
|
- Include the ESP8266 Multicast DNS library in the sketch.
|
||||||
- Call the begin method in the sketch's setup and provide a domain name (without
|
- Call the begin method in the sketch's setup and provide a domain name (without
|
||||||
the '.local' suffix, i.e. just provide 'foo' to resolve 'foo.local'), and the
|
the '.local' suffix, i.e. just provide 'foo' to resolve 'foo.local'), and the
|
||||||
Adafruit CC3000 class instance. Optionally provide a time to live (in seconds)
|
Adafruit CC3000 class instance. Optionally provide a time to live (in seconds)
|
||||||
for the DNS record--the default is 1 hour.
|
for the DNS record--the default is 1 hour.
|
||||||
- Call the update method in each iteration of the sketch's loop function.
|
- Call the update method in each iteration of the sketch's loop function.
|
||||||
|
|
||||||
License (MIT license):
|
License (MIT license):
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
@ -54,28 +54,33 @@ License (MIT license):
|
|||||||
class UdpContext;
|
class UdpContext;
|
||||||
|
|
||||||
|
|
||||||
namespace Legacy_MDNSResponder {
|
namespace Legacy_MDNSResponder
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
struct MDNSService;
|
struct MDNSService;
|
||||||
struct MDNSTxt;
|
struct MDNSTxt;
|
||||||
struct MDNSAnswer;
|
struct MDNSAnswer;
|
||||||
|
|
||||||
class MDNSResponder {
|
class MDNSResponder
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
MDNSResponder();
|
MDNSResponder();
|
||||||
~MDNSResponder();
|
~MDNSResponder();
|
||||||
bool begin(const char* hostName);
|
bool begin(const char* hostName);
|
||||||
bool begin(const String& hostName) {
|
bool begin(const String& hostName)
|
||||||
|
{
|
||||||
return begin(hostName.c_str());
|
return begin(hostName.c_str());
|
||||||
}
|
}
|
||||||
//for compatibility
|
//for compatibility
|
||||||
bool begin(const char* hostName, IPAddress ip, uint32_t ttl=120){
|
bool begin(const char* hostName, IPAddress ip, uint32_t ttl = 120)
|
||||||
|
{
|
||||||
(void) ip;
|
(void) ip;
|
||||||
(void) ttl;
|
(void) ttl;
|
||||||
return begin(hostName);
|
return begin(hostName);
|
||||||
}
|
}
|
||||||
bool begin(const String& hostName, IPAddress ip, uint32_t ttl=120) {
|
bool begin(const String& hostName, IPAddress ip, uint32_t ttl = 120)
|
||||||
|
{
|
||||||
return begin(hostName.c_str(), ip, ttl);
|
return begin(hostName.c_str(), ip, ttl);
|
||||||
}
|
}
|
||||||
/* Application should call this whenever AP is configured/disabled */
|
/* Application should call this whenever AP is configured/disabled */
|
||||||
@ -83,39 +88,47 @@ public:
|
|||||||
void update();
|
void update();
|
||||||
|
|
||||||
void addService(char *service, char *proto, uint16_t port);
|
void addService(char *service, char *proto, uint16_t port);
|
||||||
void addService(const char *service, const char *proto, uint16_t port){
|
void addService(const char *service, const char *proto, uint16_t port)
|
||||||
|
{
|
||||||
addService((char *)service, (char *)proto, port);
|
addService((char *)service, (char *)proto, port);
|
||||||
}
|
}
|
||||||
void addService(const String& service, const String& proto, uint16_t port){
|
void addService(const String& service, const String& proto, uint16_t port)
|
||||||
|
{
|
||||||
addService(service.c_str(), proto.c_str(), port);
|
addService(service.c_str(), proto.c_str(), port);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addServiceTxt(char *name, char *proto, char * key, char * value);
|
bool addServiceTxt(char *name, char *proto, char * key, char * value);
|
||||||
bool addServiceTxt(const char *name, const char *proto, const char *key,const char * value){
|
bool addServiceTxt(const char *name, const char *proto, const char *key, const char * value)
|
||||||
|
{
|
||||||
return addServiceTxt((char *)name, (char *)proto, (char *)key, (char *)value);
|
return addServiceTxt((char *)name, (char *)proto, (char *)key, (char *)value);
|
||||||
}
|
}
|
||||||
bool addServiceTxt(const String& name, const String& proto, const String& key, const String& value){
|
bool addServiceTxt(const String& name, const String& proto, const String& key, const String& value)
|
||||||
|
{
|
||||||
return addServiceTxt(name.c_str(), proto.c_str(), key.c_str(), value.c_str());
|
return addServiceTxt(name.c_str(), proto.c_str(), key.c_str(), value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
int queryService(char *service, char *proto);
|
int queryService(char *service, char *proto);
|
||||||
int queryService(const char *service, const char *proto){
|
int queryService(const char *service, const char *proto)
|
||||||
|
{
|
||||||
return queryService((char *)service, (char *)proto);
|
return queryService((char *)service, (char *)proto);
|
||||||
}
|
}
|
||||||
int queryService(const String& service, const String& proto){
|
int queryService(const String& service, const String& proto)
|
||||||
|
{
|
||||||
return queryService(service.c_str(), proto.c_str());
|
return queryService(service.c_str(), proto.c_str());
|
||||||
}
|
}
|
||||||
String hostname(int idx);
|
String hostname(int idx);
|
||||||
IPAddress IP(int idx);
|
IPAddress IP(int idx);
|
||||||
uint16_t port(int idx);
|
uint16_t port(int idx);
|
||||||
|
|
||||||
void enableArduino(uint16_t port, bool auth=false);
|
void enableArduino(uint16_t port, bool auth = false);
|
||||||
|
|
||||||
void setInstanceName(String name);
|
void setInstanceName(String name);
|
||||||
void setInstanceName(const char * name){
|
void setInstanceName(const char * name)
|
||||||
|
{
|
||||||
setInstanceName(String(name));
|
setInstanceName(String(name));
|
||||||
}
|
}
|
||||||
void setInstanceName(char * name){
|
void setInstanceName(char * name)
|
||||||
|
{
|
||||||
setInstanceName(String(name));
|
setInstanceName(String(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,103 +1,103 @@
|
|||||||
/*
|
/*
|
||||||
* LEAmDNS.h
|
LEAmDNS.h
|
||||||
* (c) 2018, LaborEtArs
|
(c) 2018, LaborEtArs
|
||||||
*
|
|
||||||
* Version 0.9 beta
|
Version 0.9 beta
|
||||||
*
|
|
||||||
* Some notes (from LaborEtArs, 2018):
|
Some notes (from LaborEtArs, 2018):
|
||||||
* Essentially, this is an rewrite of the original EPS8266 Multicast DNS code (ESP8266mDNS).
|
Essentially, this is an rewrite of the original EPS8266 Multicast DNS code (ESP8266mDNS).
|
||||||
* The target of this rewrite was to keep the existing interface as stable as possible while
|
The target of this rewrite was to keep the existing interface as stable as possible while
|
||||||
* adding and extending the supported set of mDNS features.
|
adding and extending the supported set of mDNS features.
|
||||||
* A lot of the additions were basicly taken from Erik Ekman's lwIP mdns app code.
|
A lot of the additions were basicly taken from Erik Ekman's lwIP mdns app code.
|
||||||
*
|
|
||||||
* Supported mDNS features (in some cases somewhat limited):
|
Supported mDNS features (in some cases somewhat limited):
|
||||||
* - Presenting a DNS-SD service to interested observers, eg. a http server by presenting _http._tcp service
|
- Presenting a DNS-SD service to interested observers, eg. a http server by presenting _http._tcp service
|
||||||
* - Support for multi-level compressed names in input; in output only a very simple one-leven full-name compression is implemented
|
- Support for multi-level compressed names in input; in output only a very simple one-leven full-name compression is implemented
|
||||||
* - Probing host and service domains for uniqueness in the local network
|
- Probing host and service domains for uniqueness in the local network
|
||||||
* - Tiebreaking while probing is supportet in a very minimalistic way (the 'higher' IP address wins the tiebreak)
|
- Tiebreaking while probing is supportet in a very minimalistic way (the 'higher' IP address wins the tiebreak)
|
||||||
* - Announcing available services after successful probing
|
- Announcing available services after successful probing
|
||||||
* - Using fixed service TXT items or
|
- Using fixed service TXT items or
|
||||||
* - Using dynamic service TXT items for presented services (via callback)
|
- Using dynamic service TXT items for presented services (via callback)
|
||||||
* - Remove services (and un-announcing them to the observers by sending goodbye-messages)
|
- Remove services (and un-announcing them to the observers by sending goodbye-messages)
|
||||||
* - Static queries for DNS-SD services (creating a fixed answer set after a certain timeout period)
|
- Static queries for DNS-SD services (creating a fixed answer set after a certain timeout period)
|
||||||
* - Dynamic queries for DNS-SD services with cached and updated answers and user notifications
|
- Dynamic queries for DNS-SD services with cached and updated answers and user notifications
|
||||||
*
|
|
||||||
*
|
|
||||||
* Usage:
|
Usage:
|
||||||
* In most cases, this implementation should work as a 'drop-in' replacement for the original
|
In most cases, this implementation should work as a 'drop-in' replacement for the original
|
||||||
* ESP8266 Multicast DNS code. Adjustments to the existing code would only be needed, if some
|
ESP8266 Multicast DNS code. Adjustments to the existing code would only be needed, if some
|
||||||
* of the new features should be used.
|
of the new features should be used.
|
||||||
*
|
|
||||||
* For presenting services:
|
For presenting services:
|
||||||
* In 'setup()':
|
In 'setup()':
|
||||||
* Install a callback for the probing of host (and service) domains via 'MDNS.setProbeResultCallback(probeResultCallback, &userData);'
|
Install a callback for the probing of host (and service) domains via 'MDNS.setProbeResultCallback(probeResultCallback, &userData);'
|
||||||
* Register DNS-SD services with 'MDNSResponder::hMDNSService hService = MDNS.addService("MyESP", "http", "tcp", 5000);'
|
Register DNS-SD services with 'MDNSResponder::hMDNSService hService = MDNS.addService("MyESP", "http", "tcp", 5000);'
|
||||||
* (Install additional callbacks for the probing of these service domains via 'MDNS.setServiceProbeResultCallback(hService, probeResultCallback, &userData);')
|
(Install additional callbacks for the probing of these service domains via 'MDNS.setServiceProbeResultCallback(hService, probeResultCallback, &userData);')
|
||||||
* Add service TXT items with 'MDNS.addServiceTxt(hService, "c#", "1");' or by installing a service TXT callback
|
Add service TXT items with 'MDNS.addServiceTxt(hService, "c#", "1");' or by installing a service TXT callback
|
||||||
* using 'MDNS.setDynamicServiceTxtCallback(dynamicServiceTxtCallback, &userData);' or service specific
|
using 'MDNS.setDynamicServiceTxtCallback(dynamicServiceTxtCallback, &userData);' or service specific
|
||||||
* 'MDNS.setDynamicServiceTxtCallback(hService, dynamicServiceTxtCallback, &userData);'
|
'MDNS.setDynamicServiceTxtCallback(hService, dynamicServiceTxtCallback, &userData);'
|
||||||
* Call MDNS.begin("MyHostname");
|
Call MDNS.begin("MyHostname");
|
||||||
*
|
|
||||||
* In 'probeResultCallback(MDNSResponder* p_MDNSResponder, const char* p_pcDomain, MDNSResponder:hMDNSService p_hService, bool p_bProbeResult, void* p_pUserdata)':
|
In 'probeResultCallback(MDNSResponder* p_MDNSResponder, const char* p_pcDomain, MDNSResponder:hMDNSService p_hService, bool p_bProbeResult, void* p_pUserdata)':
|
||||||
* Check the probe result and update the host or service domain name if the probe failed
|
Check the probe result and update the host or service domain name if the probe failed
|
||||||
*
|
|
||||||
* In 'dynamicServiceTxtCallback(MDNSResponder* p_MDNSResponder, const hMDNSService p_hService, void* p_pUserdata)':
|
In 'dynamicServiceTxtCallback(MDNSResponder* p_MDNSResponder, const hMDNSService p_hService, void* p_pUserdata)':
|
||||||
* Add dynamic TXT items by calling 'MDNS.addDynamicServiceTxt(p_hService, "c#", "1");'
|
Add dynamic TXT items by calling 'MDNS.addDynamicServiceTxt(p_hService, "c#", "1");'
|
||||||
*
|
|
||||||
* In loop():
|
In loop():
|
||||||
* Call 'MDNS.update();'
|
Call 'MDNS.update();'
|
||||||
*
|
|
||||||
*
|
|
||||||
* For querying services:
|
For querying services:
|
||||||
* Static:
|
Static:
|
||||||
* Call 'uint32_t u32AnswerCount = MDNS.queryService("http", "tcp");'
|
Call 'uint32_t u32AnswerCount = MDNS.queryService("http", "tcp");'
|
||||||
* Iterate answers by: 'for (uint32_t u=0; u<u32AnswerCount; ++u) { const char* pHostname = MDNS.answerHostname(u); }'
|
Iterate answers by: 'for (uint32_t u=0; u<u32AnswerCount; ++u) { const char* pHostname = MDNS.answerHostname(u); }'
|
||||||
* You should call MDNS.removeQuery() sometimes later (when the answers are nott needed anymore)
|
You should call MDNS.removeQuery() sometimes later (when the answers are nott needed anymore)
|
||||||
*
|
|
||||||
* Dynamic:
|
Dynamic:
|
||||||
* Install a dynamic query by calling 'DNSResponder::hMDNSServiceQuery hServiceQuery = MDNS.installServiceQuery("http", "tcp", serviceQueryCallback, &userData);'
|
Install a dynamic query by calling 'DNSResponder::hMDNSServiceQuery hServiceQuery = MDNS.installServiceQuery("http", "tcp", serviceQueryCallback, &userData);'
|
||||||
* The callback 'serviceQueryCallback(MDNSResponder* p_MDNSResponder, const hMDNSServiceQuery p_hServiceQuery, uint32_t p_u32AnswerIndex,
|
The callback 'serviceQueryCallback(MDNSResponder* p_MDNSResponder, const hMDNSServiceQuery p_hServiceQuery, uint32_t p_u32AnswerIndex,
|
||||||
* enuServiceQueryAnswerType p_ServiceQueryAnswerType, bool p_bSetContent, void* p_pUserdata)'
|
enuServiceQueryAnswerType p_ServiceQueryAnswerType, bool p_bSetContent, void* p_pUserdata)'
|
||||||
* is called for any change in the answer set.
|
is called for any change in the answer set.
|
||||||
* Call 'MDNS.removeServiceQuery(hServiceQuery);' when the answers are not needed anymore
|
Call 'MDNS.removeServiceQuery(hServiceQuery);' when the answers are not needed anymore
|
||||||
*
|
|
||||||
*
|
|
||||||
* Reference:
|
Reference:
|
||||||
* Used mDNS messages:
|
Used mDNS messages:
|
||||||
* A (0x01): eg. esp8266.local A OP TTL 123.456.789.012
|
A (0x01): eg. esp8266.local A OP TTL 123.456.789.012
|
||||||
* AAAA (0x1C): eg. esp8266.local AAAA OP TTL 1234:5678::90
|
AAAA (0x1C): eg. esp8266.local AAAA OP TTL 1234:5678::90
|
||||||
* PTR (0x0C, srv name): eg. _http._tcp.local PTR OP TTL MyESP._http._tcp.local
|
PTR (0x0C, srv name): eg. _http._tcp.local PTR OP TTL MyESP._http._tcp.local
|
||||||
* PTR (0x0C, srv type): eg. _services._dns-sd._udp.local PTR OP TTL _http._tcp.local
|
PTR (0x0C, srv type): eg. _services._dns-sd._udp.local PTR OP TTL _http._tcp.local
|
||||||
* PTR (0x0C, IP4): eg. 012.789.456.123.in-addr.arpa PTR OP TTL esp8266.local
|
PTR (0x0C, IP4): eg. 012.789.456.123.in-addr.arpa PTR OP TTL esp8266.local
|
||||||
* PTR (0x0C, IP6): eg. 90.0.0.0.0.0.0.0.0.0.0.0.78.56.34.12.ip6.arpa PTR OP TTL esp8266.local
|
PTR (0x0C, IP6): eg. 90.0.0.0.0.0.0.0.0.0.0.0.78.56.34.12.ip6.arpa PTR OP TTL esp8266.local
|
||||||
* SRV (0x21): eg. MyESP._http._tcp.local SRV OP TTL PRIORITY WEIGHT PORT esp8266.local
|
SRV (0x21): eg. MyESP._http._tcp.local SRV OP TTL PRIORITY WEIGHT PORT esp8266.local
|
||||||
* TXT (0x10): eg. MyESP._http._tcp.local TXT OP TTL c#=1
|
TXT (0x10): eg. MyESP._http._tcp.local TXT OP TTL c#=1
|
||||||
*
|
|
||||||
* Some NOT used message types:
|
Some NOT used message types:
|
||||||
* OPT (0x29): eDNS
|
OPT (0x29): eDNS
|
||||||
* NSEC (0x2F): DNSSEC
|
NSEC (0x2F): DNSSEC
|
||||||
*
|
|
||||||
*
|
|
||||||
* License (MIT license):
|
License (MIT license):
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MDNS_H
|
#ifndef MDNS_H
|
||||||
#define MDNS_H
|
#define MDNS_H
|
||||||
@ -115,12 +115,14 @@
|
|||||||
#include "ESP8266WiFi.h"
|
#include "ESP8266WiFi.h"
|
||||||
|
|
||||||
|
|
||||||
namespace esp8266 {
|
namespace esp8266
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LEAmDNS
|
LEAmDNS
|
||||||
*/
|
*/
|
||||||
namespace MDNSImplementation {
|
namespace MDNSImplementation
|
||||||
|
{
|
||||||
|
|
||||||
//this should be defined at build time
|
//this should be defined at build time
|
||||||
#ifndef ARDUINO_BOARD
|
#ifndef ARDUINO_BOARD
|
||||||
@ -132,41 +134,42 @@ namespace MDNSImplementation {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef MDNS_IP4_SUPPORT
|
#ifdef MDNS_IP4_SUPPORT
|
||||||
#define MDNS_IP4_SIZE 4
|
#define MDNS_IP4_SIZE 4
|
||||||
#endif
|
#endif
|
||||||
#ifdef MDNS_IP6_SUPPORT
|
#ifdef MDNS_IP6_SUPPORT
|
||||||
#define MDNS_IP6_SIZE 16
|
#define MDNS_IP6_SIZE 16
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* Maximum length for all service txts for one service
|
Maximum length for all service txts for one service
|
||||||
*/
|
*/
|
||||||
#define MDNS_SERVICE_TXT_MAXLENGTH 1300
|
#define MDNS_SERVICE_TXT_MAXLENGTH 1300
|
||||||
/*
|
/*
|
||||||
* Maximum length for a full domain name eg. MyESP._http._tcp.local
|
Maximum length for a full domain name eg. MyESP._http._tcp.local
|
||||||
*/
|
*/
|
||||||
#define MDNS_DOMAIN_MAXLENGTH 256
|
#define MDNS_DOMAIN_MAXLENGTH 256
|
||||||
/*
|
/*
|
||||||
* Maximum length of on label in a domain name (length info fits into 6 bits)
|
Maximum length of on label in a domain name (length info fits into 6 bits)
|
||||||
*/
|
*/
|
||||||
#define MDNS_DOMAIN_LABEL_MAXLENGTH 63
|
#define MDNS_DOMAIN_LABEL_MAXLENGTH 63
|
||||||
/*
|
/*
|
||||||
* Maximum length of a service name eg. http
|
Maximum length of a service name eg. http
|
||||||
*/
|
*/
|
||||||
#define MDNS_SERVICE_NAME_LENGTH 15
|
#define MDNS_SERVICE_NAME_LENGTH 15
|
||||||
/*
|
/*
|
||||||
* Maximum length of a service protocol name eg. tcp
|
Maximum length of a service protocol name eg. tcp
|
||||||
*/
|
*/
|
||||||
#define MDNS_SERVICE_PROTOCOL_LENGTH 3
|
#define MDNS_SERVICE_PROTOCOL_LENGTH 3
|
||||||
/*
|
/*
|
||||||
* Default timeout for static service queries
|
Default timeout for static service queries
|
||||||
*/
|
*/
|
||||||
#define MDNS_QUERYSERVICES_WAIT_TIME 1000
|
#define MDNS_QUERYSERVICES_WAIT_TIME 1000
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MDNSResponder
|
MDNSResponder
|
||||||
*/
|
*/
|
||||||
class MDNSResponder {
|
class MDNSResponder
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/* INTERFACE */
|
/* INTERFACE */
|
||||||
MDNSResponder(void);
|
MDNSResponder(void);
|
||||||
@ -177,7 +180,10 @@ public:
|
|||||||
// (probing, announcing, responding, ...)
|
// (probing, announcing, responding, ...)
|
||||||
// if interfaceAddress is not specified, default interface is STA, or AP when STA is not set
|
// if interfaceAddress is not specified, default interface is STA, or AP when STA is not set
|
||||||
bool begin(const char* p_pcHostname, const IPAddress& p_IPAddress = INADDR_ANY, uint32_t p_u32TTL = 120 /*ignored*/);
|
bool begin(const char* p_pcHostname, const IPAddress& p_IPAddress = INADDR_ANY, uint32_t p_u32TTL = 120 /*ignored*/);
|
||||||
bool begin(const String& p_strHostname, const IPAddress& p_IPAddress = INADDR_ANY, uint32_t p_u32TTL = 120 /*ignored*/) {return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL);}
|
bool begin(const String& p_strHostname, const IPAddress& p_IPAddress = INADDR_ANY, uint32_t p_u32TTL = 120 /*ignored*/)
|
||||||
|
{
|
||||||
|
return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL);
|
||||||
|
}
|
||||||
|
|
||||||
// Finish MDNS processing
|
// Finish MDNS processing
|
||||||
bool close(void);
|
bool close(void);
|
||||||
@ -189,7 +195,7 @@ public:
|
|||||||
bool setHostname(String p_strHostname);
|
bool setHostname(String p_strHostname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hMDNSService (opaque handle to access the service)
|
hMDNSService (opaque handle to access the service)
|
||||||
*/
|
*/
|
||||||
typedef const void* hMDNSService;
|
typedef const void* hMDNSService;
|
||||||
|
|
||||||
@ -218,12 +224,18 @@ public:
|
|||||||
//for compatibility
|
//for compatibility
|
||||||
//Warning: this has the side effect of changing the hostname.
|
//Warning: this has the side effect of changing the hostname.
|
||||||
//TODO: implement instancename different from hostname
|
//TODO: implement instancename different from hostname
|
||||||
void setInstanceName(const char* p_pcHostname) {setHostname(p_pcHostname);}
|
void setInstanceName(const char* p_pcHostname)
|
||||||
|
{
|
||||||
|
setHostname(p_pcHostname);
|
||||||
|
}
|
||||||
// for esp32 compatibilty
|
// for esp32 compatibilty
|
||||||
void setInstanceName(const String& s_pcHostname) {setInstanceName(s_pcHostname.c_str());}
|
void setInstanceName(const String& s_pcHostname)
|
||||||
|
{
|
||||||
|
setInstanceName(s_pcHostname.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hMDNSTxt (opaque handle to access the TXT items)
|
hMDNSTxt (opaque handle to access the TXT items)
|
||||||
*/
|
*/
|
||||||
typedef void* hMDNSTxt;
|
typedef void* hMDNSTxt;
|
||||||
|
|
||||||
@ -270,8 +282,8 @@ public:
|
|||||||
String p_strValue);
|
String p_strValue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MDNSDynamicServiceTxtCallbackFn
|
MDNSDynamicServiceTxtCallbackFn
|
||||||
* Callback function for dynamic MDNS TXT items
|
Callback function for dynamic MDNS TXT items
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef std::function<void(const hMDNSService p_hService)> MDNSDynamicServiceTxtCallbackFunc;
|
typedef std::function<void(const hMDNSService p_hService)> MDNSDynamicServiceTxtCallbackFunc;
|
||||||
@ -331,14 +343,15 @@ public:
|
|||||||
uint16_t port(const uint32_t p_u32AnswerIndex);
|
uint16_t port(const uint32_t p_u32AnswerIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hMDNSServiceQuery (opaque handle to access dynamic service queries)
|
hMDNSServiceQuery (opaque handle to access dynamic service queries)
|
||||||
*/
|
*/
|
||||||
typedef const void* hMDNSServiceQuery;
|
typedef const void* hMDNSServiceQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enuServiceQueryAnswerType
|
enuServiceQueryAnswerType
|
||||||
*/
|
*/
|
||||||
typedef enum _enuServiceQueryAnswerType {
|
typedef enum _enuServiceQueryAnswerType
|
||||||
|
{
|
||||||
ServiceQueryAnswerType_ServiceDomain = (1 << 0), // Service instance name
|
ServiceQueryAnswerType_ServiceDomain = (1 << 0), // Service instance name
|
||||||
ServiceQueryAnswerType_HostDomainAndPort = (1 << 1), // Host domain and service port
|
ServiceQueryAnswerType_HostDomainAndPort = (1 << 1), // Host domain and service port
|
||||||
ServiceQueryAnswerType_Txts = (1 << 2), // TXT items
|
ServiceQueryAnswerType_Txts = (1 << 2), // TXT items
|
||||||
@ -350,7 +363,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
} enuServiceQueryAnswerType;
|
} enuServiceQueryAnswerType;
|
||||||
|
|
||||||
enum class AnswerType : uint32_t {
|
enum class AnswerType : uint32_t
|
||||||
|
{
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
ServiceDomain = ServiceQueryAnswerType_ServiceDomain,
|
ServiceDomain = ServiceQueryAnswerType_ServiceDomain,
|
||||||
HostDomainAndPort = ServiceQueryAnswerType_HostDomainAndPort,
|
HostDomainAndPort = ServiceQueryAnswerType_HostDomainAndPort,
|
||||||
@ -364,12 +378,12 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MDNSServiceQueryCallbackFn
|
MDNSServiceQueryCallbackFn
|
||||||
* Callback function for received answers for dynamic service queries
|
Callback function for received answers for dynamic service queries
|
||||||
*/
|
*/
|
||||||
struct MDNSServiceInfo; // forward declaration
|
struct MDNSServiceInfo; // forward declaration
|
||||||
typedef std::function<void(const MDNSServiceInfo& mdnsServiceInfo,
|
typedef std::function<void(const MDNSServiceInfo& mdnsServiceInfo,
|
||||||
AnswerType answerType , // flag for the updated answer item
|
AnswerType answerType, // flag for the updated answer item
|
||||||
bool p_bSetContent // true: Answer component set, false: component deleted
|
bool p_bSetContent // true: Answer component set, false: component deleted
|
||||||
)> MDNSServiceQueryCallbackFunc;
|
)> MDNSServiceQueryCallbackFunc;
|
||||||
|
|
||||||
@ -391,7 +405,7 @@ public:
|
|||||||
bool removeServiceQuery(hMDNSServiceQuery p_hServiceQuery);
|
bool removeServiceQuery(hMDNSServiceQuery p_hServiceQuery);
|
||||||
|
|
||||||
uint32_t answerCount(const hMDNSServiceQuery p_hServiceQuery);
|
uint32_t answerCount(const hMDNSServiceQuery p_hServiceQuery);
|
||||||
std::vector<MDNSResponder::MDNSServiceInfo> answerInfo (const MDNSResponder::hMDNSServiceQuery p_hServiceQuery);
|
std::vector<MDNSResponder::MDNSServiceInfo> answerInfo(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery);
|
||||||
|
|
||||||
const char* answerServiceDomain(const hMDNSServiceQuery p_hServiceQuery,
|
const char* answerServiceDomain(const hMDNSServiceQuery p_hServiceQuery,
|
||||||
const uint32_t p_u32AnswerIndex);
|
const uint32_t p_u32AnswerIndex);
|
||||||
@ -428,8 +442,8 @@ public:
|
|||||||
const uint32_t p_u32AnswerIndex);
|
const uint32_t p_u32AnswerIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MDNSProbeResultCallbackFn
|
MDNSProbeResultCallbackFn
|
||||||
* Callback function for (host and service domain) probe results
|
Callback function for (host and service domain) probe results
|
||||||
*/
|
*/
|
||||||
typedef std::function<void(const char* p_pcDomainName,
|
typedef std::function<void(const char* p_pcDomainName,
|
||||||
bool p_bProbeResult)> MDNSHostProbeFn;
|
bool p_bProbeResult)> MDNSHostProbeFn;
|
||||||
@ -484,11 +498,11 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* MDNSServiceInfo, used in application callbacks
|
MDNSServiceInfo, used in application callbacks
|
||||||
*/
|
*/
|
||||||
struct MDNSServiceInfo
|
struct MDNSServiceInfo
|
||||||
{
|
{
|
||||||
MDNSServiceInfo(MDNSResponder& p_pM,MDNSResponder::hMDNSServiceQuery p_hS,uint32_t p_u32A)
|
MDNSServiceInfo(MDNSResponder& p_pM, MDNSResponder::hMDNSServiceQuery p_hS, uint32_t p_u32A)
|
||||||
: p_pMDNSResponder(p_pM),
|
: p_pMDNSResponder(p_pM),
|
||||||
p_hServiceQuery(p_hS),
|
p_hServiceQuery(p_hS),
|
||||||
p_u32AnswerIndex(p_u32A)
|
p_u32AnswerIndex(p_u32A)
|
||||||
@ -507,14 +521,16 @@ public:
|
|||||||
uint32_t p_u32AnswerIndex;
|
uint32_t p_u32AnswerIndex;
|
||||||
KeyValueMap keyValueMap;
|
KeyValueMap keyValueMap;
|
||||||
public:
|
public:
|
||||||
const char* serviceDomain(){
|
const char* serviceDomain()
|
||||||
|
{
|
||||||
return p_pMDNSResponder.answerServiceDomain(p_hServiceQuery, p_u32AnswerIndex);
|
return p_pMDNSResponder.answerServiceDomain(p_hServiceQuery, p_u32AnswerIndex);
|
||||||
};
|
};
|
||||||
bool hostDomainAvailable()
|
bool hostDomainAvailable()
|
||||||
{
|
{
|
||||||
return (p_pMDNSResponder.hasAnswerHostDomain(p_hServiceQuery, p_u32AnswerIndex));
|
return (p_pMDNSResponder.hasAnswerHostDomain(p_hServiceQuery, p_u32AnswerIndex));
|
||||||
}
|
}
|
||||||
const char* hostDomain(){
|
const char* hostDomain()
|
||||||
|
{
|
||||||
return (hostDomainAvailable()) ?
|
return (hostDomainAvailable()) ?
|
||||||
p_pMDNSResponder.answerHostDomain(p_hServiceQuery, p_u32AnswerIndex) : nullptr;
|
p_pMDNSResponder.answerHostDomain(p_hServiceQuery, p_u32AnswerIndex) : nullptr;
|
||||||
};
|
};
|
||||||
@ -522,19 +538,23 @@ public:
|
|||||||
{
|
{
|
||||||
return (p_pMDNSResponder.hasAnswerPort(p_hServiceQuery, p_u32AnswerIndex));
|
return (p_pMDNSResponder.hasAnswerPort(p_hServiceQuery, p_u32AnswerIndex));
|
||||||
}
|
}
|
||||||
uint16_t hostPort(){
|
uint16_t hostPort()
|
||||||
|
{
|
||||||
return (hostPortAvailable()) ?
|
return (hostPortAvailable()) ?
|
||||||
p_pMDNSResponder.answerPort(p_hServiceQuery, p_u32AnswerIndex) : 0;
|
p_pMDNSResponder.answerPort(p_hServiceQuery, p_u32AnswerIndex) : 0;
|
||||||
};
|
};
|
||||||
bool IP4AddressAvailable()
|
bool IP4AddressAvailable()
|
||||||
{
|
{
|
||||||
return (p_pMDNSResponder.hasAnswerIP4Address(p_hServiceQuery,p_u32AnswerIndex ));
|
return (p_pMDNSResponder.hasAnswerIP4Address(p_hServiceQuery, p_u32AnswerIndex));
|
||||||
}
|
}
|
||||||
std::vector<IPAddress> IP4Adresses(){
|
std::vector<IPAddress> IP4Adresses()
|
||||||
|
{
|
||||||
std::vector<IPAddress> internalIP;
|
std::vector<IPAddress> internalIP;
|
||||||
if (IP4AddressAvailable()) {
|
if (IP4AddressAvailable())
|
||||||
|
{
|
||||||
uint16_t cntIP4Adress = p_pMDNSResponder.answerIP4AddressCount(p_hServiceQuery, p_u32AnswerIndex);
|
uint16_t cntIP4Adress = p_pMDNSResponder.answerIP4AddressCount(p_hServiceQuery, p_u32AnswerIndex);
|
||||||
for (uint32_t u2 = 0; u2 < cntIP4Adress; ++u2) {
|
for (uint32_t u2 = 0; u2 < cntIP4Adress; ++u2)
|
||||||
|
{
|
||||||
internalIP.emplace_back(p_pMDNSResponder.answerIP4Address(p_hServiceQuery, p_u32AnswerIndex, u2));
|
internalIP.emplace_back(p_pMDNSResponder.answerIP4Address(p_hServiceQuery, p_u32AnswerIndex, u2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -544,7 +564,8 @@ public:
|
|||||||
{
|
{
|
||||||
return (p_pMDNSResponder.hasAnswerTxts(p_hServiceQuery, p_u32AnswerIndex));
|
return (p_pMDNSResponder.hasAnswerTxts(p_hServiceQuery, p_u32AnswerIndex));
|
||||||
}
|
}
|
||||||
const char* strKeyValue (){
|
const char* strKeyValue()
|
||||||
|
{
|
||||||
return (txtAvailable()) ?
|
return (txtAvailable()) ?
|
||||||
p_pMDNSResponder.answerTxts(p_hServiceQuery, p_u32AnswerIndex) : nullptr;
|
p_pMDNSResponder.answerTxts(p_hServiceQuery, p_u32AnswerIndex) : nullptr;
|
||||||
};
|
};
|
||||||
@ -552,8 +573,9 @@ public:
|
|||||||
{
|
{
|
||||||
if (txtAvailable() && keyValueMap.size() == 0)
|
if (txtAvailable() && keyValueMap.size() == 0)
|
||||||
{
|
{
|
||||||
for (auto kv = p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex);kv != nullptr;kv = kv->m_pNext) {
|
for (auto kv = p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex); kv != nullptr; kv = kv->m_pNext)
|
||||||
keyValueMap.emplace(std::pair<const char*,const char*>(kv->m_pcKey,kv->m_pcValue));
|
{
|
||||||
|
keyValueMap.emplace(std::pair<const char*, const char*>(kv->m_pcKey, kv->m_pcValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return keyValueMap;
|
return keyValueMap;
|
||||||
@ -562,9 +584,11 @@ public:
|
|||||||
{
|
{
|
||||||
char* result = nullptr;
|
char* result = nullptr;
|
||||||
|
|
||||||
for (stcMDNSServiceTxt* pTxt=p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex); pTxt; pTxt=pTxt->m_pNext) {
|
for (stcMDNSServiceTxt* pTxt = p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex); pTxt; pTxt = pTxt->m_pNext)
|
||||||
|
{
|
||||||
if ((key) &&
|
if ((key) &&
|
||||||
(0 == strcmp(pTxt->m_pcKey, key))) {
|
(0 == strcmp(pTxt->m_pcKey, key)))
|
||||||
|
{
|
||||||
result = pTxt->m_pcValue;
|
result = pTxt->m_pcValue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -575,9 +599,10 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNSServiceTxt
|
stcMDNSServiceTxt
|
||||||
*/
|
*/
|
||||||
struct stcMDNSServiceTxt {
|
struct stcMDNSServiceTxt
|
||||||
|
{
|
||||||
stcMDNSServiceTxt* m_pNext;
|
stcMDNSServiceTxt* m_pNext;
|
||||||
char* m_pcKey;
|
char* m_pcKey;
|
||||||
char* m_pcValue;
|
char* m_pcValue;
|
||||||
@ -614,9 +639,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNSTxts
|
stcMDNSTxts
|
||||||
*/
|
*/
|
||||||
struct stcMDNSServiceTxts {
|
struct stcMDNSServiceTxts
|
||||||
|
{
|
||||||
stcMDNSServiceTxt* m_pTxts;
|
stcMDNSServiceTxt* m_pTxts;
|
||||||
|
|
||||||
stcMDNSServiceTxts(void);
|
stcMDNSServiceTxts(void);
|
||||||
@ -650,9 +676,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enuContentFlags
|
enuContentFlags
|
||||||
*/
|
*/
|
||||||
typedef enum _enuContentFlags {
|
typedef enum _enuContentFlags
|
||||||
|
{
|
||||||
// Host
|
// Host
|
||||||
ContentFlag_A = 0x01,
|
ContentFlag_A = 0x01,
|
||||||
ContentFlag_PTR_IP4 = 0x02,
|
ContentFlag_PTR_IP4 = 0x02,
|
||||||
@ -666,9 +693,10 @@ protected:
|
|||||||
} enuContentFlags;
|
} enuContentFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_MsgHeader
|
stcMDNS_MsgHeader
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_MsgHeader {
|
struct stcMDNS_MsgHeader
|
||||||
|
{
|
||||||
uint16_t m_u16ID; // Identifier
|
uint16_t m_u16ID; // Identifier
|
||||||
bool m_1bQR : 1; // Query/Response flag
|
bool m_1bQR : 1; // Query/Response flag
|
||||||
unsigned char m_4bOpcode : 4; // Operation code
|
unsigned char m_4bOpcode : 4; // Operation code
|
||||||
@ -698,9 +726,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRDomain
|
stcMDNS_RRDomain
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRDomain {
|
struct stcMDNS_RRDomain
|
||||||
|
{
|
||||||
char m_acName[MDNS_DOMAIN_MAXLENGTH]; // Encoded domain name
|
char m_acName[MDNS_DOMAIN_MAXLENGTH]; // Encoded domain name
|
||||||
uint16_t m_u16NameLength; // Length (incl. '\0')
|
uint16_t m_u16NameLength; // Length (incl. '\0')
|
||||||
|
|
||||||
@ -724,9 +753,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRAttributes
|
stcMDNS_RRAttributes
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRAttributes {
|
struct stcMDNS_RRAttributes
|
||||||
|
{
|
||||||
uint16_t m_u16Type; // Type
|
uint16_t m_u16Type; // Type
|
||||||
uint16_t m_u16Class; // Class, nearly always 'IN'
|
uint16_t m_u16Class; // Class, nearly always 'IN'
|
||||||
|
|
||||||
@ -738,9 +768,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRHeader
|
stcMDNS_RRHeader
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRHeader {
|
struct stcMDNS_RRHeader
|
||||||
|
{
|
||||||
stcMDNS_RRDomain m_Domain;
|
stcMDNS_RRDomain m_Domain;
|
||||||
stcMDNS_RRAttributes m_Attributes;
|
stcMDNS_RRAttributes m_Attributes;
|
||||||
|
|
||||||
@ -753,9 +784,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRQuestion
|
stcMDNS_RRQuestion
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRQuestion {
|
struct stcMDNS_RRQuestion
|
||||||
|
{
|
||||||
stcMDNS_RRQuestion* m_pNext;
|
stcMDNS_RRQuestion* m_pNext;
|
||||||
stcMDNS_RRHeader m_Header;
|
stcMDNS_RRHeader m_Header;
|
||||||
bool m_bUnicast; // Unicast reply requested
|
bool m_bUnicast; // Unicast reply requested
|
||||||
@ -764,9 +796,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enuAnswerType
|
enuAnswerType
|
||||||
*/
|
*/
|
||||||
typedef enum _enuAnswerType {
|
typedef enum _enuAnswerType
|
||||||
|
{
|
||||||
AnswerType_A,
|
AnswerType_A,
|
||||||
AnswerType_PTR,
|
AnswerType_PTR,
|
||||||
AnswerType_TXT,
|
AnswerType_TXT,
|
||||||
@ -776,9 +809,10 @@ protected:
|
|||||||
} enuAnswerType;
|
} enuAnswerType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRAnswer
|
stcMDNS_RRAnswer
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRAnswer {
|
struct stcMDNS_RRAnswer
|
||||||
|
{
|
||||||
stcMDNS_RRAnswer* m_pNext;
|
stcMDNS_RRAnswer* m_pNext;
|
||||||
const enuAnswerType m_AnswerType;
|
const enuAnswerType m_AnswerType;
|
||||||
stcMDNS_RRHeader m_Header;
|
stcMDNS_RRHeader m_Header;
|
||||||
@ -799,9 +833,10 @@ protected:
|
|||||||
|
|
||||||
#ifdef MDNS_IP4_SUPPORT
|
#ifdef MDNS_IP4_SUPPORT
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRAnswerA
|
stcMDNS_RRAnswerA
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRAnswerA : public stcMDNS_RRAnswer {
|
struct stcMDNS_RRAnswerA : public stcMDNS_RRAnswer
|
||||||
|
{
|
||||||
IPAddress m_IPAddress;
|
IPAddress m_IPAddress;
|
||||||
|
|
||||||
stcMDNS_RRAnswerA(const stcMDNS_RRHeader& p_Header,
|
stcMDNS_RRAnswerA(const stcMDNS_RRHeader& p_Header,
|
||||||
@ -813,9 +848,10 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRAnswerPTR
|
stcMDNS_RRAnswerPTR
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRAnswerPTR : public stcMDNS_RRAnswer {
|
struct stcMDNS_RRAnswerPTR : public stcMDNS_RRAnswer
|
||||||
|
{
|
||||||
stcMDNS_RRDomain m_PTRDomain;
|
stcMDNS_RRDomain m_PTRDomain;
|
||||||
|
|
||||||
stcMDNS_RRAnswerPTR(const stcMDNS_RRHeader& p_Header,
|
stcMDNS_RRAnswerPTR(const stcMDNS_RRHeader& p_Header,
|
||||||
@ -826,9 +862,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRAnswerTXT
|
stcMDNS_RRAnswerTXT
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRAnswerTXT : public stcMDNS_RRAnswer {
|
struct stcMDNS_RRAnswerTXT : public stcMDNS_RRAnswer
|
||||||
|
{
|
||||||
stcMDNSServiceTxts m_Txts;
|
stcMDNSServiceTxts m_Txts;
|
||||||
|
|
||||||
stcMDNS_RRAnswerTXT(const stcMDNS_RRHeader& p_Header,
|
stcMDNS_RRAnswerTXT(const stcMDNS_RRHeader& p_Header,
|
||||||
@ -840,9 +877,10 @@ protected:
|
|||||||
|
|
||||||
#ifdef MDNS_IP6_SUPPORT
|
#ifdef MDNS_IP6_SUPPORT
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRAnswerAAAA
|
stcMDNS_RRAnswerAAAA
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRAnswerAAAA : public stcMDNS_RRAnswer {
|
struct stcMDNS_RRAnswerAAAA : public stcMDNS_RRAnswer
|
||||||
|
{
|
||||||
//TODO: IP6Address m_IPAddress;
|
//TODO: IP6Address m_IPAddress;
|
||||||
|
|
||||||
stcMDNS_RRAnswerAAAA(const stcMDNS_RRHeader& p_Header,
|
stcMDNS_RRAnswerAAAA(const stcMDNS_RRHeader& p_Header,
|
||||||
@ -854,9 +892,10 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRAnswerSRV
|
stcMDNS_RRAnswerSRV
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRAnswerSRV : public stcMDNS_RRAnswer {
|
struct stcMDNS_RRAnswerSRV : public stcMDNS_RRAnswer
|
||||||
|
{
|
||||||
uint16_t m_u16Priority;
|
uint16_t m_u16Priority;
|
||||||
uint16_t m_u16Weight;
|
uint16_t m_u16Weight;
|
||||||
uint16_t m_u16Port;
|
uint16_t m_u16Port;
|
||||||
@ -870,9 +909,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNS_RRAnswerGeneric
|
stcMDNS_RRAnswerGeneric
|
||||||
*/
|
*/
|
||||||
struct stcMDNS_RRAnswerGeneric : public stcMDNS_RRAnswer {
|
struct stcMDNS_RRAnswerGeneric : public stcMDNS_RRAnswer
|
||||||
|
{
|
||||||
uint16_t m_u16RDLength; // Length of variable answer
|
uint16_t m_u16RDLength; // Length of variable answer
|
||||||
uint8_t* m_pu8RDData; // Offset of start of variable answer in packet
|
uint8_t* m_pu8RDData; // Offset of start of variable answer in packet
|
||||||
|
|
||||||
@ -885,9 +925,10 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enuProbingStatus
|
enuProbingStatus
|
||||||
*/
|
*/
|
||||||
typedef enum _enuProbingStatus {
|
typedef enum _enuProbingStatus
|
||||||
|
{
|
||||||
ProbingStatus_WaitingForData,
|
ProbingStatus_WaitingForData,
|
||||||
ProbingStatus_ReadyToStart,
|
ProbingStatus_ReadyToStart,
|
||||||
ProbingStatus_InProgress,
|
ProbingStatus_InProgress,
|
||||||
@ -895,9 +936,10 @@ protected:
|
|||||||
} enuProbingStatus;
|
} enuProbingStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcProbeInformation
|
stcProbeInformation
|
||||||
*/
|
*/
|
||||||
struct stcProbeInformation {
|
struct stcProbeInformation
|
||||||
|
{
|
||||||
enuProbingStatus m_ProbingStatus;
|
enuProbingStatus m_ProbingStatus;
|
||||||
uint8_t m_u8SentCount; // Used for probes and announcements
|
uint8_t m_u8SentCount; // Used for probes and announcements
|
||||||
esp8266::polledTimeout::oneShotMs m_Timeout; // Used for probes and announcements
|
esp8266::polledTimeout::oneShotMs m_Timeout; // Used for probes and announcements
|
||||||
@ -914,9 +956,10 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNSService
|
stcMDNSService
|
||||||
*/
|
*/
|
||||||
struct stcMDNSService {
|
struct stcMDNSService
|
||||||
|
{
|
||||||
stcMDNSService* m_pNext;
|
stcMDNSService* m_pNext;
|
||||||
char* m_pcName;
|
char* m_pcName;
|
||||||
bool m_bAutoName; // Name was set automatically to hostname (if no name was supplied)
|
bool m_bAutoName; // Name was set automatically to hostname (if no name was supplied)
|
||||||
@ -944,23 +987,26 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNSServiceQuery
|
stcMDNSServiceQuery
|
||||||
*/
|
*/
|
||||||
struct stcMDNSServiceQuery {
|
struct stcMDNSServiceQuery
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* stcAnswer
|
stcAnswer
|
||||||
*/
|
*/
|
||||||
struct stcAnswer {
|
struct stcAnswer
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* stcTTL
|
stcTTL
|
||||||
*/
|
*/
|
||||||
struct stcTTL {
|
struct stcTTL
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* timeoutLevel_t
|
timeoutLevel_t
|
||||||
*/
|
*/
|
||||||
typedef uint8_t timeoutLevel_t;
|
typedef uint8_t timeoutLevel_t;
|
||||||
/**
|
/**
|
||||||
* TIMEOUTLEVELs
|
TIMEOUTLEVELs
|
||||||
*/
|
*/
|
||||||
const timeoutLevel_t TIMEOUTLEVEL_UNSET = 0;
|
const timeoutLevel_t TIMEOUTLEVEL_UNSET = 0;
|
||||||
const timeoutLevel_t TIMEOUTLEVEL_BASE = 80;
|
const timeoutLevel_t TIMEOUTLEVEL_BASE = 80;
|
||||||
@ -984,9 +1030,10 @@ protected:
|
|||||||
};
|
};
|
||||||
#ifdef MDNS_IP4_SUPPORT
|
#ifdef MDNS_IP4_SUPPORT
|
||||||
/**
|
/**
|
||||||
* stcIP4Address
|
stcIP4Address
|
||||||
*/
|
*/
|
||||||
struct stcIP4Address {
|
struct stcIP4Address
|
||||||
|
{
|
||||||
stcIP4Address* m_pNext;
|
stcIP4Address* m_pNext;
|
||||||
IPAddress m_IPAddress;
|
IPAddress m_IPAddress;
|
||||||
stcTTL m_TTL;
|
stcTTL m_TTL;
|
||||||
@ -997,9 +1044,10 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
#ifdef MDNS_IP6_SUPPORT
|
#ifdef MDNS_IP6_SUPPORT
|
||||||
/**
|
/**
|
||||||
* stcIP6Address
|
stcIP6Address
|
||||||
*/
|
*/
|
||||||
struct stcIP6Address {
|
struct stcIP6Address
|
||||||
|
{
|
||||||
stcIP6Address* m_pNext;
|
stcIP6Address* m_pNext;
|
||||||
IP6Address m_IPAddress;
|
IP6Address m_IPAddress;
|
||||||
stcTTL m_TTL;
|
stcTTL m_TTL;
|
||||||
@ -1093,14 +1141,16 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stcMDNSSendParameter
|
stcMDNSSendParameter
|
||||||
*/
|
*/
|
||||||
struct stcMDNSSendParameter {
|
struct stcMDNSSendParameter
|
||||||
|
{
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* stcDomainCacheItem
|
stcDomainCacheItem
|
||||||
*/
|
*/
|
||||||
struct stcDomainCacheItem {
|
struct stcDomainCacheItem
|
||||||
|
{
|
||||||
stcDomainCacheItem* m_pNext;
|
stcDomainCacheItem* m_pNext;
|
||||||
const void* m_pHostnameOrService; // Opaque id for host or service domain (pointer)
|
const void* m_pHostnameOrService; // Opaque id for host or service domain (pointer)
|
||||||
bool m_bAdditionalData; // Opaque flag for special info (service domain included)
|
bool m_bAdditionalData; // Opaque flag for special info (service domain included)
|
||||||
@ -1203,7 +1253,10 @@ protected:
|
|||||||
uint16_t p_u16QueryType,
|
uint16_t p_u16QueryType,
|
||||||
stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0);
|
stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0);
|
||||||
|
|
||||||
const IPAddress _getResponseMulticastInterface() const { return IPAddress(m_netif->ip_addr); }
|
const IPAddress _getResponseMulticastInterface() const
|
||||||
|
{
|
||||||
|
return IPAddress(m_netif->ip_addr);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader,
|
uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader,
|
||||||
bool* p_pbFullNameMatch = 0) const;
|
bool* p_pbFullNameMatch = 0) const;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,26 +1,26 @@
|
|||||||
/*
|
/*
|
||||||
* LEAmDNS_Helpers.cpp
|
LEAmDNS_Helpers.cpp
|
||||||
*
|
|
||||||
* License (MIT license):
|
License (MIT license):
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lwip/igmp.h"
|
#include "lwip/igmp.h"
|
||||||
|
|
||||||
@ -28,16 +28,18 @@
|
|||||||
#include "LEAmDNS_Priv.h"
|
#include "LEAmDNS_Priv.h"
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* strrstr (static)
|
strrstr (static)
|
||||||
*
|
|
||||||
* Backwards search for p_pcPattern in p_pcString
|
Backwards search for p_pcPattern in p_pcString
|
||||||
* Based on: https://stackoverflow.com/a/1634398/2778898
|
Based on: https://stackoverflow.com/a/1634398/2778898
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
const char* strrstr(const char*__restrict p_pcString, const char*__restrict p_pcPattern) {
|
const char* strrstr(const char*__restrict p_pcString, const char*__restrict p_pcPattern)
|
||||||
|
{
|
||||||
|
|
||||||
const char* pcResult = 0;
|
const char* pcResult = 0;
|
||||||
|
|
||||||
@ -46,11 +48,14 @@ const char* strrstr(const char*__restrict p_pcString, const char*__restrict p_pc
|
|||||||
|
|
||||||
if ((stStringLength) &&
|
if ((stStringLength) &&
|
||||||
(stPatternLength) &&
|
(stPatternLength) &&
|
||||||
(stPatternLength <= stStringLength)) {
|
(stPatternLength <= stStringLength))
|
||||||
|
{
|
||||||
// Pattern is shorter or has the same length tham the string
|
// Pattern is shorter or has the same length tham the string
|
||||||
|
|
||||||
for (const char* s=(p_pcString + stStringLength - stPatternLength); s>=p_pcString; --s) {
|
for (const char* s = (p_pcString + stStringLength - stPatternLength); s >= p_pcString; --s)
|
||||||
if (0 == strncmp(s, p_pcPattern, stPatternLength)) {
|
{
|
||||||
|
if (0 == strncmp(s, p_pcPattern, stPatternLength))
|
||||||
|
{
|
||||||
pcResult = s;
|
pcResult = s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -66,52 +71,59 @@ const char* strrstr(const char*__restrict p_pcString, const char*__restrict p_pc
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace esp8266 {
|
namespace esp8266
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LEAmDNS
|
LEAmDNS
|
||||||
*/
|
*/
|
||||||
namespace MDNSImplementation {
|
namespace MDNSImplementation
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HELPERS
|
HELPERS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::indexDomain (static)
|
MDNSResponder::indexDomain (static)
|
||||||
*
|
|
||||||
* Updates the given domain 'p_rpcHostname' by appending a delimiter and an index number.
|
Updates the given domain 'p_rpcHostname' by appending a delimiter and an index number.
|
||||||
*
|
|
||||||
* If the given domain already hasa numeric index (after the given delimiter), this index
|
If the given domain already hasa numeric index (after the given delimiter), this index
|
||||||
* incremented. If not, the delimiter and index '2' is added.
|
incremented. If not, the delimiter and index '2' is added.
|
||||||
*
|
|
||||||
* If 'p_rpcHostname' is empty (==0), the given default name 'p_pcDefaultHostname' is used,
|
If 'p_rpcHostname' is empty (==0), the given default name 'p_pcDefaultHostname' is used,
|
||||||
* if no default is given, 'esp8266' is used.
|
if no default is given, 'esp8266' is used.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
/*static*/ bool MDNSResponder::indexDomain(char*& p_rpcDomain,
|
/*static*/ bool MDNSResponder::indexDomain(char*& p_rpcDomain,
|
||||||
const char* p_pcDivider /*= "-"*/,
|
const char* p_pcDivider /*= "-"*/,
|
||||||
const char* p_pcDefaultDomain /*= 0*/) {
|
const char* p_pcDefaultDomain /*= 0*/)
|
||||||
|
{
|
||||||
|
|
||||||
bool bResult = false;
|
bool bResult = false;
|
||||||
|
|
||||||
// Ensure a divider exists; use '-' as default
|
// Ensure a divider exists; use '-' as default
|
||||||
const char* pcDivider = (p_pcDivider ?: "-");
|
const char* pcDivider = (p_pcDivider ? : "-");
|
||||||
|
|
||||||
if (p_rpcDomain) {
|
if (p_rpcDomain)
|
||||||
|
{
|
||||||
const char* pFoundDivider = strrstr(p_rpcDomain, pcDivider);
|
const char* pFoundDivider = strrstr(p_rpcDomain, pcDivider);
|
||||||
if (pFoundDivider) { // maybe already extended
|
if (pFoundDivider) // maybe already extended
|
||||||
|
{
|
||||||
char* pEnd = 0;
|
char* pEnd = 0;
|
||||||
unsigned long ulIndex = strtoul((pFoundDivider + strlen(pcDivider)), &pEnd, 10);
|
unsigned long ulIndex = strtoul((pFoundDivider + strlen(pcDivider)), &pEnd, 10);
|
||||||
if ((ulIndex) &&
|
if ((ulIndex) &&
|
||||||
((pEnd - p_rpcDomain) == (ptrdiff_t)strlen(p_rpcDomain)) &&
|
((pEnd - p_rpcDomain) == (ptrdiff_t)strlen(p_rpcDomain)) &&
|
||||||
(!*pEnd)) { // Valid (old) index found
|
(!*pEnd)) // Valid (old) index found
|
||||||
|
{
|
||||||
|
|
||||||
char acIndexBuffer[16];
|
char acIndexBuffer[16];
|
||||||
sprintf(acIndexBuffer, "%lu", (++ulIndex));
|
sprintf(acIndexBuffer, "%lu", (++ulIndex));
|
||||||
size_t stLength = ((pFoundDivider - p_rpcDomain + strlen(pcDivider)) + strlen(acIndexBuffer) + 1);
|
size_t stLength = ((pFoundDivider - p_rpcDomain + strlen(pcDivider)) + strlen(acIndexBuffer) + 1);
|
||||||
char* pNewHostname = new char[stLength];
|
char* pNewHostname = new char[stLength];
|
||||||
if (pNewHostname) {
|
if (pNewHostname)
|
||||||
|
{
|
||||||
memcpy(pNewHostname, p_rpcDomain, (pFoundDivider - p_rpcDomain + strlen(pcDivider)));
|
memcpy(pNewHostname, p_rpcDomain, (pFoundDivider - p_rpcDomain + strlen(pcDivider)));
|
||||||
pNewHostname[pFoundDivider - p_rpcDomain + strlen(pcDivider)] = 0;
|
pNewHostname[pFoundDivider - p_rpcDomain + strlen(pcDivider)] = 0;
|
||||||
strcat(pNewHostname, acIndexBuffer);
|
strcat(pNewHostname, acIndexBuffer);
|
||||||
@ -121,19 +133,23 @@ namespace MDNSImplementation {
|
|||||||
|
|
||||||
bResult = true;
|
bResult = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
|
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
pFoundDivider = 0; // Flag the need to (base) extend the hostname
|
pFoundDivider = 0; // Flag the need to (base) extend the hostname
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pFoundDivider) { // not yet extended (or failed to increment extension) -> start indexing
|
if (!pFoundDivider) // not yet extended (or failed to increment extension) -> start indexing
|
||||||
|
{
|
||||||
size_t stLength = strlen(p_rpcDomain) + (strlen(pcDivider) + 1 + 1); // Name + Divider + '2' + '\0'
|
size_t stLength = strlen(p_rpcDomain) + (strlen(pcDivider) + 1 + 1); // Name + Divider + '2' + '\0'
|
||||||
char* pNewHostname = new char[stLength];
|
char* pNewHostname = new char[stLength];
|
||||||
if (pNewHostname) {
|
if (pNewHostname)
|
||||||
|
{
|
||||||
sprintf(pNewHostname, "%s%s2", p_rpcDomain, pcDivider);
|
sprintf(pNewHostname, "%s%s2", p_rpcDomain, pcDivider);
|
||||||
|
|
||||||
delete[] p_rpcDomain;
|
delete[] p_rpcDomain;
|
||||||
@ -141,22 +157,26 @@ namespace MDNSImplementation {
|
|||||||
|
|
||||||
bResult = true;
|
bResult = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
|
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
// No given host domain, use base or default
|
// No given host domain, use base or default
|
||||||
const char* cpcDefaultName = (p_pcDefaultDomain ?: "esp8266");
|
const char* cpcDefaultName = (p_pcDefaultDomain ? : "esp8266");
|
||||||
|
|
||||||
size_t stLength = strlen(cpcDefaultName) + 1; // '\0'
|
size_t stLength = strlen(cpcDefaultName) + 1; // '\0'
|
||||||
p_rpcDomain = new char[stLength];
|
p_rpcDomain = new char[stLength];
|
||||||
if (p_rpcDomain) {
|
if (p_rpcDomain)
|
||||||
|
{
|
||||||
strncpy(p_rpcDomain, cpcDefaultName, stLength);
|
strncpy(p_rpcDomain, cpcDefaultName, stLength);
|
||||||
bResult = true;
|
bResult = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
|
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,26 +186,28 @@ namespace MDNSImplementation {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UDP CONTEXT
|
UDP CONTEXT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool MDNSResponder::_callProcess(void) {
|
bool MDNSResponder::_callProcess(void)
|
||||||
|
{
|
||||||
DEBUG_EX_INFO(DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(), IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str()););
|
DEBUG_EX_INFO(DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(), IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str()););
|
||||||
|
|
||||||
return _process(false);
|
return _process(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_allocUDPContext
|
MDNSResponder::_allocUDPContext
|
||||||
*
|
|
||||||
* (Re-)Creates the one-and-only UDP context for the MDNS responder.
|
(Re-)Creates the one-and-only UDP context for the MDNS responder.
|
||||||
* The context is added to the 'multicast'-group and listens to the MDNS port (5353).
|
The context is added to the 'multicast'-group and listens to the MDNS port (5353).
|
||||||
* The travel-distance for multicast messages is set to 1 (local, via MDNS_MULTICAST_TTL).
|
The travel-distance for multicast messages is set to 1 (local, via MDNS_MULTICAST_TTL).
|
||||||
* Messages are received via the MDNSResponder '_update' function. CAUTION: This function
|
Messages are received via the MDNSResponder '_update' function. CAUTION: This function
|
||||||
* is called from the WiFi stack side of the ESP stack system.
|
is called from the WiFi stack side of the ESP stack system.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_allocUDPContext(void) {
|
bool MDNSResponder::_allocUDPContext(void)
|
||||||
|
{
|
||||||
DEBUG_EX_INFO(DEBUG_OUTPUT.println("[MDNSResponder] _allocUDPContext"););
|
DEBUG_EX_INFO(DEBUG_OUTPUT.println("[MDNSResponder] _allocUDPContext"););
|
||||||
|
|
||||||
bool bResult = false;
|
bool bResult = false;
|
||||||
@ -199,11 +221,13 @@ bool MDNSResponder::_allocUDPContext(void) {
|
|||||||
//TODO: set multicast address (lwip_joingroup() is IPv4 only at the time of writing)
|
//TODO: set multicast address (lwip_joingroup() is IPv4 only at the time of writing)
|
||||||
multicast_addr.addr = DNS_MQUERY_IPV6_GROUP_INIT;
|
multicast_addr.addr = DNS_MQUERY_IPV6_GROUP_INIT;
|
||||||
#endif
|
#endif
|
||||||
if (ERR_OK == igmp_joingroup(ip_2_ip4(&m_netif->ip_addr), ip_2_ip4(&multicast_addr))) {
|
if (ERR_OK == igmp_joingroup(ip_2_ip4(&m_netif->ip_addr), ip_2_ip4(&multicast_addr)))
|
||||||
|
{
|
||||||
m_pUDPContext = new UdpContext;
|
m_pUDPContext = new UdpContext;
|
||||||
m_pUDPContext->ref();
|
m_pUDPContext->ref();
|
||||||
|
|
||||||
if (m_pUDPContext->listen(IP4_ADDR_ANY, DNS_MQUERY_PORT)) {
|
if (m_pUDPContext->listen(IP4_ADDR_ANY, DNS_MQUERY_PORT))
|
||||||
|
{
|
||||||
m_pUDPContext->setMulticastTTL(MDNS_MULTICAST_TTL);
|
m_pUDPContext->setMulticastTTL(MDNS_MULTICAST_TTL);
|
||||||
m_pUDPContext->onRx(std::bind(&MDNSResponder::_callProcess, this));
|
m_pUDPContext->onRx(std::bind(&MDNSResponder::_callProcess, this));
|
||||||
|
|
||||||
@ -214,11 +238,13 @@ bool MDNSResponder::_allocUDPContext(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_releaseUDPContext
|
MDNSResponder::_releaseUDPContext
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_releaseUDPContext(void) {
|
bool MDNSResponder::_releaseUDPContext(void)
|
||||||
|
{
|
||||||
|
|
||||||
if (m_pUDPContext) {
|
if (m_pUDPContext)
|
||||||
|
{
|
||||||
m_pUDPContext->unref();
|
m_pUDPContext->unref();
|
||||||
m_pUDPContext = 0;
|
m_pUDPContext = 0;
|
||||||
}
|
}
|
||||||
@ -227,16 +253,18 @@ bool MDNSResponder::_releaseUDPContext(void) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SERVICE QUERY
|
SERVICE QUERY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_allocServiceQuery
|
MDNSResponder::_allocServiceQuery
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_allocServiceQuery(void) {
|
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_allocServiceQuery(void)
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSServiceQuery* pServiceQuery = new stcMDNSServiceQuery;
|
stcMDNSServiceQuery* pServiceQuery = new stcMDNSServiceQuery;
|
||||||
if (pServiceQuery) {
|
if (pServiceQuery)
|
||||||
|
{
|
||||||
// Link to query list
|
// Link to query list
|
||||||
pServiceQuery->m_pNext = m_pServiceQueries;
|
pServiceQuery->m_pNext = m_pServiceQueries;
|
||||||
m_pServiceQueries = pServiceQuery;
|
m_pServiceQueries = pServiceQuery;
|
||||||
@ -245,30 +273,37 @@ MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_allocServiceQuery(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_removeServiceQuery
|
MDNSResponder::_removeServiceQuery
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_removeServiceQuery(MDNSResponder::stcMDNSServiceQuery* p_pServiceQuery) {
|
bool MDNSResponder::_removeServiceQuery(MDNSResponder::stcMDNSServiceQuery* p_pServiceQuery)
|
||||||
|
{
|
||||||
|
|
||||||
bool bResult = false;
|
bool bResult = false;
|
||||||
|
|
||||||
if (p_pServiceQuery) {
|
if (p_pServiceQuery)
|
||||||
|
{
|
||||||
stcMDNSServiceQuery* pPred = m_pServiceQueries;
|
stcMDNSServiceQuery* pPred = m_pServiceQueries;
|
||||||
while ((pPred) &&
|
while ((pPred) &&
|
||||||
(pPred->m_pNext != p_pServiceQuery)) {
|
(pPred->m_pNext != p_pServiceQuery))
|
||||||
|
{
|
||||||
pPred = pPred->m_pNext;
|
pPred = pPred->m_pNext;
|
||||||
}
|
}
|
||||||
if (pPred) {
|
if (pPred)
|
||||||
|
{
|
||||||
pPred->m_pNext = p_pServiceQuery->m_pNext;
|
pPred->m_pNext = p_pServiceQuery->m_pNext;
|
||||||
delete p_pServiceQuery;
|
delete p_pServiceQuery;
|
||||||
bResult = true;
|
bResult = true;
|
||||||
}
|
}
|
||||||
else { // No predecesor
|
else // No predecesor
|
||||||
if (m_pServiceQueries == p_pServiceQuery) {
|
{
|
||||||
|
if (m_pServiceQueries == p_pServiceQuery)
|
||||||
|
{
|
||||||
m_pServiceQueries = p_pServiceQuery->m_pNext;
|
m_pServiceQueries = p_pServiceQuery->m_pNext;
|
||||||
delete p_pServiceQuery;
|
delete p_pServiceQuery;
|
||||||
bResult = true;
|
bResult = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
DEBUG_EX_ERR(DEBUG_OUTPUT.println("[MDNSResponder] _releaseServiceQuery: INVALID service query!"););
|
DEBUG_EX_ERR(DEBUG_OUTPUT.println("[MDNSResponder] _releaseServiceQuery: INVALID service query!"););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,25 +312,29 @@ bool MDNSResponder::_removeServiceQuery(MDNSResponder::stcMDNSServiceQuery* p_pS
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_removeLegacyServiceQuery
|
MDNSResponder::_removeLegacyServiceQuery
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_removeLegacyServiceQuery(void) {
|
bool MDNSResponder::_removeLegacyServiceQuery(void)
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSServiceQuery* pLegacyServiceQuery = _findLegacyServiceQuery();
|
stcMDNSServiceQuery* pLegacyServiceQuery = _findLegacyServiceQuery();
|
||||||
return (pLegacyServiceQuery ? _removeServiceQuery(pLegacyServiceQuery) : true);
|
return (pLegacyServiceQuery ? _removeServiceQuery(pLegacyServiceQuery) : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_findServiceQuery
|
MDNSResponder::_findServiceQuery
|
||||||
*
|
|
||||||
* 'Convert' hMDNSServiceQuery to stcMDNSServiceQuery* (ensure existance)
|
'Convert' hMDNSServiceQuery to stcMDNSServiceQuery* (ensure existance)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findServiceQuery(MDNSResponder::hMDNSServiceQuery p_hServiceQuery) {
|
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findServiceQuery(MDNSResponder::hMDNSServiceQuery p_hServiceQuery)
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries;
|
stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries;
|
||||||
while (pServiceQuery) {
|
while (pServiceQuery)
|
||||||
if ((hMDNSServiceQuery)pServiceQuery == p_hServiceQuery) {
|
{
|
||||||
|
if ((hMDNSServiceQuery)pServiceQuery == p_hServiceQuery)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pServiceQuery = pServiceQuery->m_pNext;
|
pServiceQuery = pServiceQuery->m_pNext;
|
||||||
@ -304,13 +343,16 @@ MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findServiceQuery(MDNSRespond
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_findLegacyServiceQuery
|
MDNSResponder::_findLegacyServiceQuery
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findLegacyServiceQuery(void) {
|
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findLegacyServiceQuery(void)
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries;
|
stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries;
|
||||||
while (pServiceQuery) {
|
while (pServiceQuery)
|
||||||
if (pServiceQuery->m_bLegacyQuery) {
|
{
|
||||||
|
if (pServiceQuery->m_bLegacyQuery)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pServiceQuery = pServiceQuery->m_pNext;
|
pServiceQuery = pServiceQuery->m_pNext;
|
||||||
@ -319,10 +361,12 @@ MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findLegacyServiceQuery(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_releaseServiceQueries
|
MDNSResponder::_releaseServiceQueries
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_releaseServiceQueries(void) {
|
bool MDNSResponder::_releaseServiceQueries(void)
|
||||||
while (m_pServiceQueries) {
|
{
|
||||||
|
while (m_pServiceQueries)
|
||||||
|
{
|
||||||
stcMDNSServiceQuery* pNext = m_pServiceQueries->m_pNext;
|
stcMDNSServiceQuery* pNext = m_pServiceQueries->m_pNext;
|
||||||
delete m_pServiceQueries;
|
delete m_pServiceQueries;
|
||||||
m_pServiceQueries = pNext;
|
m_pServiceQueries = pNext;
|
||||||
@ -331,15 +375,18 @@ bool MDNSResponder::_releaseServiceQueries(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_findNextServiceQueryByServiceType
|
MDNSResponder::_findNextServiceQueryByServiceType
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findNextServiceQueryByServiceType(const stcMDNS_RRDomain& p_ServiceTypeDomain,
|
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findNextServiceQueryByServiceType(const stcMDNS_RRDomain& p_ServiceTypeDomain,
|
||||||
const stcMDNSServiceQuery* p_pPrevServiceQuery) {
|
const stcMDNSServiceQuery* p_pPrevServiceQuery)
|
||||||
|
{
|
||||||
stcMDNSServiceQuery* pMatchingServiceQuery = 0;
|
stcMDNSServiceQuery* pMatchingServiceQuery = 0;
|
||||||
|
|
||||||
stcMDNSServiceQuery* pServiceQuery = (p_pPrevServiceQuery ? p_pPrevServiceQuery->m_pNext : m_pServiceQueries);
|
stcMDNSServiceQuery* pServiceQuery = (p_pPrevServiceQuery ? p_pPrevServiceQuery->m_pNext : m_pServiceQueries);
|
||||||
while (pServiceQuery) {
|
while (pServiceQuery)
|
||||||
if (p_ServiceTypeDomain == pServiceQuery->m_ServiceTypeDomain) {
|
{
|
||||||
|
if (p_ServiceTypeDomain == pServiceQuery->m_ServiceTypeDomain)
|
||||||
|
{
|
||||||
pMatchingServiceQuery = pServiceQuery;
|
pMatchingServiceQuery = pServiceQuery;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -350,13 +397,14 @@ MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findNextServiceQueryByServic
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HOSTNAME
|
HOSTNAME
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_setHostname
|
MDNSResponder::_setHostname
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_setHostname(const char* p_pcHostname) {
|
bool MDNSResponder::_setHostname(const char* p_pcHostname)
|
||||||
|
{
|
||||||
//DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _allocHostname (%s)\n"), p_pcHostname););
|
//DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _allocHostname (%s)\n"), p_pcHostname););
|
||||||
|
|
||||||
bool bResult = false;
|
bool bResult = false;
|
||||||
@ -365,12 +413,15 @@ bool MDNSResponder::_setHostname(const char* p_pcHostname) {
|
|||||||
|
|
||||||
size_t stLength = 0;
|
size_t stLength = 0;
|
||||||
if ((p_pcHostname) &&
|
if ((p_pcHostname) &&
|
||||||
(MDNS_DOMAIN_LABEL_MAXLENGTH >= (stLength = strlen(p_pcHostname)))) { // char max size for a single label
|
(MDNS_DOMAIN_LABEL_MAXLENGTH >= (stLength = strlen(p_pcHostname)))) // char max size for a single label
|
||||||
|
{
|
||||||
// Copy in hostname characters as lowercase
|
// Copy in hostname characters as lowercase
|
||||||
if ((bResult = (0 != (m_pcHostname = new char[stLength + 1])))) {
|
if ((bResult = (0 != (m_pcHostname = new char[stLength + 1]))))
|
||||||
|
{
|
||||||
#ifdef MDNS_FORCE_LOWERCASE_HOSTNAME
|
#ifdef MDNS_FORCE_LOWERCASE_HOSTNAME
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (; i<stLength; ++i) {
|
for (; i < stLength; ++i)
|
||||||
|
{
|
||||||
m_pcHostname[i] = (isupper(p_pcHostname[i]) ? tolower(p_pcHostname[i]) : p_pcHostname[i]);
|
m_pcHostname[i] = (isupper(p_pcHostname[i]) ? tolower(p_pcHostname[i]) : p_pcHostname[i]);
|
||||||
}
|
}
|
||||||
m_pcHostname[i] = 0;
|
m_pcHostname[i] = 0;
|
||||||
@ -383,11 +434,13 @@ bool MDNSResponder::_setHostname(const char* p_pcHostname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_releaseHostname
|
MDNSResponder::_releaseHostname
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_releaseHostname(void) {
|
bool MDNSResponder::_releaseHostname(void)
|
||||||
|
{
|
||||||
|
|
||||||
if (m_pcHostname) {
|
if (m_pcHostname)
|
||||||
|
{
|
||||||
delete[] m_pcHostname;
|
delete[] m_pcHostname;
|
||||||
m_pcHostname = 0;
|
m_pcHostname = 0;
|
||||||
}
|
}
|
||||||
@ -396,16 +449,17 @@ bool MDNSResponder::_releaseHostname(void) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SERVICE
|
SERVICE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_allocService
|
MDNSResponder::_allocService
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName,
|
MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName,
|
||||||
const char* p_pcService,
|
const char* p_pcService,
|
||||||
const char* p_pcProtocol,
|
const char* p_pcProtocol,
|
||||||
uint16_t p_u16Port) {
|
uint16_t p_u16Port)
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSService* pService = 0;
|
stcMDNSService* pService = 0;
|
||||||
if (((!p_pcName) ||
|
if (((!p_pcName) ||
|
||||||
@ -416,9 +470,10 @@ MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName
|
|||||||
(MDNS_SERVICE_PROTOCOL_LENGTH >= strlen(p_pcProtocol)) &&
|
(MDNS_SERVICE_PROTOCOL_LENGTH >= strlen(p_pcProtocol)) &&
|
||||||
(p_u16Port) &&
|
(p_u16Port) &&
|
||||||
(0 != (pService = new stcMDNSService)) &&
|
(0 != (pService = new stcMDNSService)) &&
|
||||||
(pService->setName(p_pcName ?: m_pcHostname)) &&
|
(pService->setName(p_pcName ? : m_pcHostname)) &&
|
||||||
(pService->setService(p_pcService)) &&
|
(pService->setService(p_pcService)) &&
|
||||||
(pService->setProtocol(p_pcProtocol))) {
|
(pService->setProtocol(p_pcProtocol)))
|
||||||
|
{
|
||||||
|
|
||||||
pService->m_bAutoName = (0 == p_pcName);
|
pService->m_bAutoName = (0 == p_pcName);
|
||||||
pService->m_u16Port = p_u16Port;
|
pService->m_u16Port = p_u16Port;
|
||||||
@ -431,30 +486,37 @@ MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_releaseService
|
MDNSResponder::_releaseService
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_releaseService(MDNSResponder::stcMDNSService* p_pService) {
|
bool MDNSResponder::_releaseService(MDNSResponder::stcMDNSService* p_pService)
|
||||||
|
{
|
||||||
|
|
||||||
bool bResult = false;
|
bool bResult = false;
|
||||||
|
|
||||||
if (p_pService) {
|
if (p_pService)
|
||||||
|
{
|
||||||
stcMDNSService* pPred = m_pServices;
|
stcMDNSService* pPred = m_pServices;
|
||||||
while ((pPred) &&
|
while ((pPred) &&
|
||||||
(pPred->m_pNext != p_pService)) {
|
(pPred->m_pNext != p_pService))
|
||||||
|
{
|
||||||
pPred = pPred->m_pNext;
|
pPred = pPred->m_pNext;
|
||||||
}
|
}
|
||||||
if (pPred) {
|
if (pPred)
|
||||||
|
{
|
||||||
pPred->m_pNext = p_pService->m_pNext;
|
pPred->m_pNext = p_pService->m_pNext;
|
||||||
delete p_pService;
|
delete p_pService;
|
||||||
bResult = true;
|
bResult = true;
|
||||||
}
|
}
|
||||||
else { // No predecesor
|
else // No predecesor
|
||||||
if (m_pServices == p_pService) {
|
{
|
||||||
|
if (m_pServices == p_pService)
|
||||||
|
{
|
||||||
m_pServices = p_pService->m_pNext;
|
m_pServices = p_pService->m_pNext;
|
||||||
delete p_pService;
|
delete p_pService;
|
||||||
bResult = true;
|
bResult = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
DEBUG_EX_ERR(DEBUG_OUTPUT.println("[MDNSResponder] _releaseService: INVALID service!"););
|
DEBUG_EX_ERR(DEBUG_OUTPUT.println("[MDNSResponder] _releaseService: INVALID service!"););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,12 +525,14 @@ bool MDNSResponder::_releaseService(MDNSResponder::stcMDNSService* p_pService) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_releaseServices
|
MDNSResponder::_releaseServices
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_releaseServices(void) {
|
bool MDNSResponder::_releaseServices(void)
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSService* pService = m_pServices;
|
stcMDNSService* pService = m_pServices;
|
||||||
while (pService) {
|
while (pService)
|
||||||
|
{
|
||||||
_releaseService(pService);
|
_releaseService(pService);
|
||||||
pService = m_pServices;
|
pService = m_pServices;
|
||||||
}
|
}
|
||||||
@ -476,17 +540,20 @@ bool MDNSResponder::_releaseServices(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_findService
|
MDNSResponder::_findService
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSService* MDNSResponder::_findService(const char* p_pcName,
|
MDNSResponder::stcMDNSService* MDNSResponder::_findService(const char* p_pcName,
|
||||||
const char* p_pcService,
|
const char* p_pcService,
|
||||||
const char* p_pcProtocol) {
|
const char* p_pcProtocol)
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSService* pService = m_pServices;
|
stcMDNSService* pService = m_pServices;
|
||||||
while (pService) {
|
while (pService)
|
||||||
|
{
|
||||||
if ((0 == strcmp(pService->m_pcName, p_pcName)) &&
|
if ((0 == strcmp(pService->m_pcName, p_pcName)) &&
|
||||||
(0 == strcmp(pService->m_pcService, p_pcService)) &&
|
(0 == strcmp(pService->m_pcService, p_pcService)) &&
|
||||||
(0 == strcmp(pService->m_pcProtocol, p_pcProtocol))) {
|
(0 == strcmp(pService->m_pcProtocol, p_pcProtocol)))
|
||||||
|
{
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -496,13 +563,16 @@ MDNSResponder::stcMDNSService* MDNSResponder::_findService(const char* p_pcName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_findService
|
MDNSResponder::_findService
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSService* MDNSResponder::_findService(const MDNSResponder::hMDNSService p_hService) {
|
MDNSResponder::stcMDNSService* MDNSResponder::_findService(const MDNSResponder::hMDNSService p_hService)
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSService* pService = m_pServices;
|
stcMDNSService* pService = m_pServices;
|
||||||
while (pService) {
|
while (pService)
|
||||||
if (p_hService == (hMDNSService)pService) {
|
{
|
||||||
|
if (p_hService == (hMDNSService)pService)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pService = pService->m_pNext;
|
pService = pService->m_pNext;
|
||||||
@ -512,16 +582,17 @@ MDNSResponder::stcMDNSService* MDNSResponder::_findService(const MDNSResponder::
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SERVICE TXT
|
SERVICE TXT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_allocServiceTxt
|
MDNSResponder::_allocServiceTxt
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
||||||
const char* p_pcKey,
|
const char* p_pcKey,
|
||||||
const char* p_pcValue,
|
const char* p_pcValue,
|
||||||
bool p_bTemp) {
|
bool p_bTemp)
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSServiceTxt* pTxt = 0;
|
stcMDNSServiceTxt* pTxt = 0;
|
||||||
|
|
||||||
@ -531,20 +602,25 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder:
|
|||||||
1 + // Length byte
|
1 + // Length byte
|
||||||
(p_pcKey ? strlen(p_pcKey) : 0) +
|
(p_pcKey ? strlen(p_pcKey) : 0) +
|
||||||
1 + // '='
|
1 + // '='
|
||||||
(p_pcValue ? strlen(p_pcValue) : 0)))) {
|
(p_pcValue ? strlen(p_pcValue) : 0))))
|
||||||
|
{
|
||||||
|
|
||||||
pTxt = new stcMDNSServiceTxt;
|
pTxt = new stcMDNSServiceTxt;
|
||||||
if (pTxt) {
|
if (pTxt)
|
||||||
|
{
|
||||||
size_t stLength = (p_pcKey ? strlen(p_pcKey) : 0);
|
size_t stLength = (p_pcKey ? strlen(p_pcKey) : 0);
|
||||||
pTxt->m_pcKey = new char[stLength + 1];
|
pTxt->m_pcKey = new char[stLength + 1];
|
||||||
if (pTxt->m_pcKey) {
|
if (pTxt->m_pcKey)
|
||||||
|
{
|
||||||
strncpy(pTxt->m_pcKey, p_pcKey, stLength); pTxt->m_pcKey[stLength] = 0;
|
strncpy(pTxt->m_pcKey, p_pcKey, stLength); pTxt->m_pcKey[stLength] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_pcValue) {
|
if (p_pcValue)
|
||||||
|
{
|
||||||
stLength = (p_pcValue ? strlen(p_pcValue) : 0);
|
stLength = (p_pcValue ? strlen(p_pcValue) : 0);
|
||||||
pTxt->m_pcValue = new char[stLength + 1];
|
pTxt->m_pcValue = new char[stLength + 1];
|
||||||
if (pTxt->m_pcValue) {
|
if (pTxt->m_pcValue)
|
||||||
|
{
|
||||||
strncpy(pTxt->m_pcValue, p_pcValue, stLength); pTxt->m_pcValue[stLength] = 0;
|
strncpy(pTxt->m_pcValue, p_pcValue, stLength); pTxt->m_pcValue[stLength] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -558,10 +634,11 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_releaseServiceTxt
|
MDNSResponder::_releaseServiceTxt
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_releaseServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
bool MDNSResponder::_releaseServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
||||||
MDNSResponder::stcMDNSServiceTxt* p_pTxt) {
|
MDNSResponder::stcMDNSServiceTxt* p_pTxt)
|
||||||
|
{
|
||||||
|
|
||||||
return ((p_pService) &&
|
return ((p_pService) &&
|
||||||
(p_pTxt) &&
|
(p_pTxt) &&
|
||||||
@ -569,18 +646,20 @@ bool MDNSResponder::_releaseServiceTxt(MDNSResponder::stcMDNSService* p_pService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_updateServiceTxt
|
MDNSResponder::_updateServiceTxt
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_updateServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_updateServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
||||||
MDNSResponder::stcMDNSServiceTxt* p_pTxt,
|
MDNSResponder::stcMDNSServiceTxt* p_pTxt,
|
||||||
const char* p_pcValue,
|
const char* p_pcValue,
|
||||||
bool p_bTemp) {
|
bool p_bTemp)
|
||||||
|
{
|
||||||
|
|
||||||
if ((p_pService) &&
|
if ((p_pService) &&
|
||||||
(p_pTxt) &&
|
(p_pTxt) &&
|
||||||
(MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() -
|
(MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() -
|
||||||
(p_pTxt->m_pcValue ? strlen(p_pTxt->m_pcValue) : 0) +
|
(p_pTxt->m_pcValue ? strlen(p_pTxt->m_pcValue) : 0) +
|
||||||
(p_pcValue ? strlen(p_pcValue) : 0)))) {
|
(p_pcValue ? strlen(p_pcValue) : 0))))
|
||||||
|
{
|
||||||
p_pTxt->update(p_pcValue);
|
p_pTxt->update(p_pcValue);
|
||||||
p_pTxt->m_bTemp = p_bTemp;
|
p_pTxt->m_bTemp = p_bTemp;
|
||||||
}
|
}
|
||||||
@ -588,41 +667,47 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_updateServiceTxt(MDNSResponder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_findServiceTxt
|
MDNSResponder::_findServiceTxt
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
||||||
const char* p_pcKey) {
|
const char* p_pcKey)
|
||||||
|
{
|
||||||
|
|
||||||
return (p_pService ? p_pService->m_Txts.find(p_pcKey) : 0);
|
return (p_pService ? p_pService->m_Txts.find(p_pcKey) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_findServiceTxt
|
MDNSResponder::_findServiceTxt
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
||||||
const hMDNSTxt p_hTxt) {
|
const hMDNSTxt p_hTxt)
|
||||||
|
{
|
||||||
|
|
||||||
return (((p_pService) && (p_hTxt)) ? p_pService->m_Txts.find((stcMDNSServiceTxt*)p_hTxt) : 0);
|
return (((p_pService) && (p_hTxt)) ? p_pService->m_Txts.find((stcMDNSServiceTxt*)p_hTxt) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_addServiceTxt
|
MDNSResponder::_addServiceTxt
|
||||||
*/
|
*/
|
||||||
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_addServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_addServiceTxt(MDNSResponder::stcMDNSService* p_pService,
|
||||||
const char* p_pcKey,
|
const char* p_pcKey,
|
||||||
const char* p_pcValue,
|
const char* p_pcValue,
|
||||||
bool p_bTemp) {
|
bool p_bTemp)
|
||||||
|
{
|
||||||
stcMDNSServiceTxt* pResult = 0;
|
stcMDNSServiceTxt* pResult = 0;
|
||||||
|
|
||||||
if ((p_pService) &&
|
if ((p_pService) &&
|
||||||
(p_pcKey) &&
|
(p_pcKey) &&
|
||||||
(strlen(p_pcKey))) {
|
(strlen(p_pcKey)))
|
||||||
|
{
|
||||||
|
|
||||||
stcMDNSServiceTxt* pTxt = p_pService->m_Txts.find(p_pcKey);
|
stcMDNSServiceTxt* pTxt = p_pService->m_Txts.find(p_pcKey);
|
||||||
if (pTxt) {
|
if (pTxt)
|
||||||
|
{
|
||||||
pResult = _updateServiceTxt(p_pService, pTxt, p_pcValue, p_bTemp);
|
pResult = _updateServiceTxt(p_pService, pTxt, p_pcValue, p_bTemp);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
pResult = _allocServiceTxt(p_pService, p_pcKey, p_pcValue, p_bTemp);
|
pResult = _allocServiceTxt(p_pService, p_pcKey, p_pcValue, p_bTemp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,7 +715,8 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_addServiceTxt(MDNSResponder::s
|
|||||||
}
|
}
|
||||||
|
|
||||||
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_answerKeyValue(const hMDNSServiceQuery p_hServiceQuery,
|
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_answerKeyValue(const hMDNSServiceQuery p_hServiceQuery,
|
||||||
const uint32_t p_u32AnswerIndex) {
|
const uint32_t p_u32AnswerIndex)
|
||||||
|
{
|
||||||
stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery);
|
stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery);
|
||||||
stcMDNSServiceQuery::stcAnswer* pSQAnswer = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0);
|
stcMDNSServiceQuery::stcAnswer* pSQAnswer = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0);
|
||||||
// Fill m_pcTxts (if not already done)
|
// Fill m_pcTxts (if not already done)
|
||||||
@ -638,71 +724,83 @@ MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_answerKeyValue(const hMDNSServ
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_collectServiceTxts
|
MDNSResponder::_collectServiceTxts
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_collectServiceTxts(MDNSResponder::stcMDNSService& p_rService) {
|
bool MDNSResponder::_collectServiceTxts(MDNSResponder::stcMDNSService& p_rService)
|
||||||
|
{
|
||||||
|
|
||||||
// Call Dynamic service callbacks
|
// Call Dynamic service callbacks
|
||||||
if (m_fnServiceTxtCallback) {
|
if (m_fnServiceTxtCallback)
|
||||||
|
{
|
||||||
m_fnServiceTxtCallback((hMDNSService)&p_rService);
|
m_fnServiceTxtCallback((hMDNSService)&p_rService);
|
||||||
}
|
}
|
||||||
if (p_rService.m_fnTxtCallback) {
|
if (p_rService.m_fnTxtCallback)
|
||||||
|
{
|
||||||
p_rService.m_fnTxtCallback((hMDNSService)&p_rService);
|
p_rService.m_fnTxtCallback((hMDNSService)&p_rService);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_releaseTempServiceTxts
|
MDNSResponder::_releaseTempServiceTxts
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_releaseTempServiceTxts(MDNSResponder::stcMDNSService& p_rService) {
|
bool MDNSResponder::_releaseTempServiceTxts(MDNSResponder::stcMDNSService& p_rService)
|
||||||
|
{
|
||||||
|
|
||||||
return (p_rService.m_Txts.removeTempTxts());
|
return (p_rService.m_Txts.removeTempTxts());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MISC
|
MISC
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG_ESP_MDNS_RESPONDER
|
#ifdef DEBUG_ESP_MDNS_RESPONDER
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_printRRDomain
|
MDNSResponder::_printRRDomain
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_printRRDomain(const MDNSResponder::stcMDNS_RRDomain& p_RRDomain) const {
|
bool MDNSResponder::_printRRDomain(const MDNSResponder::stcMDNS_RRDomain& p_RRDomain) const
|
||||||
|
{
|
||||||
|
|
||||||
//DEBUG_OUTPUT.printf_P(PSTR("Domain: "));
|
//DEBUG_OUTPUT.printf_P(PSTR("Domain: "));
|
||||||
|
|
||||||
const char* pCursor = p_RRDomain.m_acName;
|
const char* pCursor = p_RRDomain.m_acName;
|
||||||
uint8_t u8Length = *pCursor++;
|
uint8_t u8Length = *pCursor++;
|
||||||
if (u8Length) {
|
if (u8Length)
|
||||||
while (u8Length) {
|
{
|
||||||
for (uint8_t u=0; u<u8Length; ++u) {
|
while (u8Length)
|
||||||
|
{
|
||||||
|
for (uint8_t u = 0; u < u8Length; ++u)
|
||||||
|
{
|
||||||
DEBUG_OUTPUT.printf_P(PSTR("%c"), *(pCursor++));
|
DEBUG_OUTPUT.printf_P(PSTR("%c"), *(pCursor++));
|
||||||
}
|
}
|
||||||
u8Length = *pCursor++;
|
u8Length = *pCursor++;
|
||||||
if (u8Length) {
|
if (u8Length)
|
||||||
|
{
|
||||||
DEBUG_OUTPUT.printf_P(PSTR("."));
|
DEBUG_OUTPUT.printf_P(PSTR("."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // empty domain
|
else // empty domain
|
||||||
|
{
|
||||||
DEBUG_OUTPUT.printf_P(PSTR("-empty-"));
|
DEBUG_OUTPUT.printf_P(PSTR("-empty-"));
|
||||||
}
|
}
|
||||||
//DEBUG_OUTPUT.printf_P(PSTR("\n"));
|
//DEBUG_OUTPUT.printf_P(PSTR("\n"));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNSResponder::_printRRAnswer
|
MDNSResponder::_printRRAnswer
|
||||||
*/
|
*/
|
||||||
bool MDNSResponder::_printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAnswer) const {
|
bool MDNSResponder::_printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAnswer) const
|
||||||
|
{
|
||||||
|
|
||||||
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] RRAnswer: "));
|
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] RRAnswer: "));
|
||||||
_printRRDomain(p_RRAnswer.m_Header.m_Domain);
|
_printRRDomain(p_RRAnswer.m_Header.m_Domain);
|
||||||
DEBUG_OUTPUT.printf_P(PSTR(" Type:0x%04X Class:0x%04X TTL:%u, "), p_RRAnswer.m_Header.m_Attributes.m_u16Type, p_RRAnswer.m_Header.m_Attributes.m_u16Class, p_RRAnswer.m_u32TTL);
|
DEBUG_OUTPUT.printf_P(PSTR(" Type:0x%04X Class:0x%04X TTL:%u, "), p_RRAnswer.m_Header.m_Attributes.m_u16Type, p_RRAnswer.m_Header.m_Attributes.m_u16Class, p_RRAnswer.m_u32TTL);
|
||||||
switch (p_RRAnswer.m_Header.m_Attributes.m_u16Type & (~0x8000)) { // Topmost bit might carry 'cache flush' flag
|
switch (p_RRAnswer.m_Header.m_Attributes.m_u16Type & (~0x8000)) // Topmost bit might carry 'cache flush' flag
|
||||||
|
{
|
||||||
#ifdef MDNS_IP4_SUPPORT
|
#ifdef MDNS_IP4_SUPPORT
|
||||||
case DNS_RRTYPE_A:
|
case DNS_RRTYPE_A:
|
||||||
DEBUG_OUTPUT.printf_P(PSTR("A IP:%s"), ((const stcMDNS_RRAnswerA*)&p_RRAnswer)->m_IPAddress.toString().c_str());
|
DEBUG_OUTPUT.printf_P(PSTR("A IP:%s"), ((const stcMDNS_RRAnswerA*)&p_RRAnswer)->m_IPAddress.toString().c_str());
|
||||||
@ -712,10 +810,12 @@ bool MDNSResponder::_releaseTempServiceTxts(MDNSResponder::stcMDNSService& p_rSe
|
|||||||
DEBUG_OUTPUT.printf_P(PSTR("PTR "));
|
DEBUG_OUTPUT.printf_P(PSTR("PTR "));
|
||||||
_printRRDomain(((const stcMDNS_RRAnswerPTR*)&p_RRAnswer)->m_PTRDomain);
|
_printRRDomain(((const stcMDNS_RRAnswerPTR*)&p_RRAnswer)->m_PTRDomain);
|
||||||
break;
|
break;
|
||||||
case DNS_RRTYPE_TXT: {
|
case DNS_RRTYPE_TXT:
|
||||||
|
{
|
||||||
size_t stTxtLength = ((const stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_strLength();
|
size_t stTxtLength = ((const stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_strLength();
|
||||||
char* pTxts = new char[stTxtLength];
|
char* pTxts = new char[stTxtLength];
|
||||||
if (pTxts) {
|
if (pTxts)
|
||||||
|
{
|
||||||
((/*const c_str()!!*/stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_str(pTxts);
|
((/*const c_str()!!*/stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_str(pTxts);
|
||||||
DEBUG_OUTPUT.printf_P(PSTR("TXT(%u) %s"), stTxtLength, pTxts);
|
DEBUG_OUTPUT.printf_P(PSTR("TXT(%u) %s"), stTxtLength, pTxts);
|
||||||
delete[] pTxts;
|
delete[] pTxts;
|
||||||
@ -738,7 +838,7 @@ bool MDNSResponder::_releaseTempServiceTxts(MDNSResponder::stcMDNSService& p_rSe
|
|||||||
DEBUG_OUTPUT.printf_P(PSTR("\n"));
|
DEBUG_OUTPUT.printf_P(PSTR("\n"));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace MDNSImplementation
|
} // namespace MDNSImplementation
|
||||||
|
@ -1,37 +1,39 @@
|
|||||||
/*
|
/*
|
||||||
* LEAmDNS_Priv.h
|
LEAmDNS_Priv.h
|
||||||
*
|
|
||||||
* License (MIT license):
|
License (MIT license):
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MDNS_PRIV_H
|
#ifndef MDNS_PRIV_H
|
||||||
#define MDNS_PRIV_H
|
#define MDNS_PRIV_H
|
||||||
|
|
||||||
namespace esp8266 {
|
namespace esp8266
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LEAmDNS
|
LEAmDNS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace MDNSImplementation {
|
namespace MDNSImplementation
|
||||||
|
{
|
||||||
|
|
||||||
// Enable class debug functions
|
// Enable class debug functions
|
||||||
#define ESP_8266_MDNS_INCLUDE
|
#define ESP_8266_MDNS_INCLUDE
|
||||||
@ -42,7 +44,7 @@ namespace MDNSImplementation {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LWIP_OPEN_SRC
|
#ifndef LWIP_OPEN_SRC
|
||||||
#define LWIP_OPEN_SRC
|
#define LWIP_OPEN_SRC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -59,87 +61,87 @@ namespace MDNSImplementation {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_ESP_MDNS_RESPONDER
|
#ifdef DEBUG_ESP_MDNS_RESPONDER
|
||||||
#ifdef DEBUG_ESP_MDNS_INFO
|
#ifdef DEBUG_ESP_MDNS_INFO
|
||||||
#define DEBUG_EX_INFO(A) A
|
#define DEBUG_EX_INFO(A) A
|
||||||
#else
|
|
||||||
#define DEBUG_EX_INFO(A) do { (void)0; } while (0)
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_ESP_MDNS_ERR
|
|
||||||
#define DEBUG_EX_ERR(A) A
|
|
||||||
#else
|
|
||||||
#define DEBUG_EX_ERR(A) do { (void)0; } while (0)
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_ESP_MDNS_TX
|
|
||||||
#define DEBUG_EX_TX(A) A
|
|
||||||
#else
|
|
||||||
#define DEBUG_EX_TX(A) do { (void)0; } while (0)
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_ESP_MDNS_RX
|
|
||||||
#define DEBUG_EX_RX(A) A
|
|
||||||
#else
|
|
||||||
#define DEBUG_EX_RX(A) do { (void)0; } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_ESP_PORT
|
|
||||||
#define DEBUG_OUTPUT DEBUG_ESP_PORT
|
|
||||||
#else
|
|
||||||
#define DEBUG_OUTPUT Serial
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#define DEBUG_EX_INFO(A) do { (void)0; } while (0)
|
#define DEBUG_EX_INFO(A) do { (void)0; } while (0)
|
||||||
#define DEBUG_EX_ERR(A) do { (void)0; } while (0)
|
#endif
|
||||||
#define DEBUG_EX_TX(A) do { (void)0; } while (0)
|
#ifdef DEBUG_ESP_MDNS_ERR
|
||||||
#define DEBUG_EX_RX(A) do { (void)0; } while (0)
|
#define DEBUG_EX_ERR(A) A
|
||||||
|
#else
|
||||||
|
#define DEBUG_EX_ERR(A) do { (void)0; } while (0)
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG_ESP_MDNS_TX
|
||||||
|
#define DEBUG_EX_TX(A) A
|
||||||
|
#else
|
||||||
|
#define DEBUG_EX_TX(A) do { (void)0; } while (0)
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG_ESP_MDNS_RX
|
||||||
|
#define DEBUG_EX_RX(A) A
|
||||||
|
#else
|
||||||
|
#define DEBUG_EX_RX(A) do { (void)0; } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_ESP_PORT
|
||||||
|
#define DEBUG_OUTPUT DEBUG_ESP_PORT
|
||||||
|
#else
|
||||||
|
#define DEBUG_OUTPUT Serial
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define DEBUG_EX_INFO(A) do { (void)0; } while (0)
|
||||||
|
#define DEBUG_EX_ERR(A) do { (void)0; } while (0)
|
||||||
|
#define DEBUG_EX_TX(A) do { (void)0; } while (0)
|
||||||
|
#define DEBUG_EX_RX(A) do { (void)0; } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Replaced by 'lwip/prot/dns.h' definitions
|
/* Replaced by 'lwip/prot/dns.h' definitions
|
||||||
#ifdef MDNS_IP4_SUPPORT
|
#ifdef MDNS_IP4_SUPPORT
|
||||||
#define MDNS_MULTICAST_ADDR_IP4 (IPAddress(224, 0, 0, 251)) // ip_addr_t v4group = DNS_MQUERY_IPV4_GROUP_INIT
|
#define MDNS_MULTICAST_ADDR_IP4 (IPAddress(224, 0, 0, 251)) // ip_addr_t v4group = DNS_MQUERY_IPV4_GROUP_INIT
|
||||||
#endif
|
#endif
|
||||||
#ifdef MDNS_IP6_SUPPORT
|
#ifdef MDNS_IP6_SUPPORT
|
||||||
#define MDNS_MULTICAST_ADDR_IP6 (IPAddress("FF02::FB")) // ip_addr_t v6group = DNS_MQUERY_IPV6_GROUP_INIT
|
#define MDNS_MULTICAST_ADDR_IP6 (IPAddress("FF02::FB")) // ip_addr_t v6group = DNS_MQUERY_IPV6_GROUP_INIT
|
||||||
#endif*/
|
#endif*/
|
||||||
//#define MDNS_MULTICAST_PORT 5353
|
//#define MDNS_MULTICAST_PORT 5353
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is NOT the TTL (Time-To-Live) for MDNS records, but the
|
This is NOT the TTL (Time-To-Live) for MDNS records, but the
|
||||||
* subnet level distance MDNS records should travel.
|
subnet level distance MDNS records should travel.
|
||||||
* 1 sets the subnet distance to 'local', which is default for MDNS.
|
1 sets the subnet distance to 'local', which is default for MDNS.
|
||||||
* (Btw.: 255 would set it to 'as far as possible' -> internet)
|
(Btw.: 255 would set it to 'as far as possible' -> internet)
|
||||||
*
|
|
||||||
* However, RFC 3171 seems to force 255 instead
|
However, RFC 3171 seems to force 255 instead
|
||||||
*/
|
*/
|
||||||
#define MDNS_MULTICAST_TTL 255/*1*/
|
#define MDNS_MULTICAST_TTL 255/*1*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the MDNS record TTL
|
This is the MDNS record TTL
|
||||||
* Host level records are set to 2min (120s)
|
Host level records are set to 2min (120s)
|
||||||
* service level records are set to 75min (4500s)
|
service level records are set to 75min (4500s)
|
||||||
*/
|
*/
|
||||||
#define MDNS_HOST_TTL 120
|
#define MDNS_HOST_TTL 120
|
||||||
#define MDNS_SERVICE_TTL 4500
|
#define MDNS_SERVICE_TTL 4500
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compressed labels are flaged by the two topmost bits of the length byte being set
|
Compressed labels are flaged by the two topmost bits of the length byte being set
|
||||||
*/
|
*/
|
||||||
#define MDNS_DOMAIN_COMPRESS_MARK 0xC0
|
#define MDNS_DOMAIN_COMPRESS_MARK 0xC0
|
||||||
/*
|
/*
|
||||||
* Avoid endless recursion because of malformed compressed labels
|
Avoid endless recursion because of malformed compressed labels
|
||||||
*/
|
*/
|
||||||
#define MDNS_DOMAIN_MAX_REDIRCTION 6
|
#define MDNS_DOMAIN_MAX_REDIRCTION 6
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default service priority and weight in SRV answers
|
Default service priority and weight in SRV answers
|
||||||
*/
|
*/
|
||||||
#define MDNS_SRV_PRIORITY 0
|
#define MDNS_SRV_PRIORITY 0
|
||||||
#define MDNS_SRV_WEIGHT 0
|
#define MDNS_SRV_WEIGHT 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delay between and number of probes for host and service domains
|
Delay between and number of probes for host and service domains
|
||||||
* Delay between and number of announces for host and service domains
|
Delay between and number of announces for host and service domains
|
||||||
* Delay between and number of service queries; the delay is multiplied by the resent number in '_checkServiceQueryCache'
|
Delay between and number of service queries; the delay is multiplied by the resent number in '_checkServiceQueryCache'
|
||||||
*/
|
*/
|
||||||
#define MDNS_PROBE_DELAY 250
|
#define MDNS_PROBE_DELAY 250
|
||||||
#define MDNS_PROBE_COUNT 3
|
#define MDNS_PROBE_COUNT 3
|
||||||
#define MDNS_ANNOUNCE_DELAY 1000
|
#define MDNS_ANNOUNCE_DELAY 1000
|
||||||
@ -149,24 +151,24 @@ namespace MDNSImplementation {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force host domain to use only lowercase letters
|
Force host domain to use only lowercase letters
|
||||||
*/
|
*/
|
||||||
//#define MDNS_FORCE_LOWERCASE_HOSTNAME
|
//#define MDNS_FORCE_LOWERCASE_HOSTNAME
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable/disable the usage of the F() macro in debug trace printf calls.
|
Enable/disable the usage of the F() macro in debug trace printf calls.
|
||||||
* There needs to be an PGM comptible printf function to use this.
|
There needs to be an PGM comptible printf function to use this.
|
||||||
*
|
|
||||||
* USE_PGM_PRINTF and F
|
USE_PGM_PRINTF and F
|
||||||
*/
|
*/
|
||||||
#define USE_PGM_PRINTF
|
#define USE_PGM_PRINTF
|
||||||
|
|
||||||
#ifdef USE_PGM_PRINTF
|
#ifdef USE_PGM_PRINTF
|
||||||
#else
|
#else
|
||||||
#ifdef F
|
#ifdef F
|
||||||
#undef F
|
#undef F
|
||||||
#endif
|
#endif
|
||||||
#define F(A) A
|
#define F(A) A
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace MDNSImplementation
|
} // namespace MDNSImplementation
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,26 +1,26 @@
|
|||||||
/*
|
/*
|
||||||
* LEAmDNS_Priv.h
|
LEAmDNS_Priv.h
|
||||||
*
|
|
||||||
* License (MIT license):
|
License (MIT license):
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MDNS_LWIPDEFS_H
|
#ifndef MDNS_LWIPDEFS_H
|
||||||
#define MDNS_LWIPDEFS_H
|
#define MDNS_LWIPDEFS_H
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
org=$(cd ${0%/*}; pwd)
|
|
||||||
cd ${org}/..
|
|
||||||
pwd
|
|
||||||
test -d cores/esp8266
|
|
||||||
test -d libraries
|
|
||||||
|
|
||||||
# this warning question will be removed after restyle-all.sh is renamed to restyle.sh
|
|
||||||
echo "This is dangerous if you have modified your local repository"
|
|
||||||
echo "type iknowwhatido to continue"
|
|
||||||
read ans
|
|
||||||
test "$ans" = iknowwhatido || exit 1
|
|
||||||
|
|
||||||
for d in cores/esp8266 libraries; do
|
|
||||||
for e in c cpp h; do
|
|
||||||
find $d -name "*.$e" -exec \
|
|
||||||
astyle \
|
|
||||||
--suffix=none \
|
|
||||||
--options=${org}/astyle_core.conf {} \;
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
for d in libraries; do
|
|
||||||
find $d -name "*.ino" -exec \
|
|
||||||
astyle \
|
|
||||||
--suffix=none \
|
|
||||||
--options=${org}/astyle_examples.conf {} \;
|
|
||||||
done
|
|
19
tests/restyle-examples-only.sh
Executable file
19
tests/restyle-examples-only.sh
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
org=$(cd ${0%/*}; pwd)
|
||||||
|
cd ${org}/..
|
||||||
|
pwd
|
||||||
|
test -d cores/esp8266
|
||||||
|
test -d libraries
|
||||||
|
|
||||||
|
# in a near future, restyle-all.sh will be renamed to restyle.sh
|
||||||
|
# and will be checked against CI
|
||||||
|
|
||||||
|
for d in libraries; do
|
||||||
|
find $d -name "*.ino" -exec \
|
||||||
|
astyle \
|
||||||
|
--suffix=none \
|
||||||
|
--options=${org}/astyle_examples.conf {} \;
|
||||||
|
done
|
@ -8,8 +8,17 @@ pwd
|
|||||||
test -d cores/esp8266
|
test -d cores/esp8266
|
||||||
test -d libraries
|
test -d libraries
|
||||||
|
|
||||||
# in a near future, restyle-all.sh will be renamed to restyle.sh
|
#all="cores/esp8266 libraries"
|
||||||
# and will be checked against CI
|
all="libraries/ESP8266mDNS"
|
||||||
|
|
||||||
|
for d in $all; do
|
||||||
|
for e in c cpp h; do
|
||||||
|
find $d -name "*.$e" -exec \
|
||||||
|
astyle \
|
||||||
|
--suffix=none \
|
||||||
|
--options=${org}/astyle_core.conf {} \;
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
for d in libraries; do
|
for d in libraries; do
|
||||||
find $d -name "*.ino" -exec \
|
find $d -name "*.ino" -exec \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user