mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
parent
faf59f5190
commit
a3281fe2f3
@ -32,6 +32,13 @@
|
|||||||
struct ip_addr: ipv4_addr { };
|
struct ip_addr: ipv4_addr { };
|
||||||
#endif // !LWIP_IPV6
|
#endif // !LWIP_IPV6
|
||||||
|
|
||||||
|
// to display a netif id with printf:
|
||||||
|
#define NETIFID_STR "%c%c%u"
|
||||||
|
#define NETIFID_VAL(netif) \
|
||||||
|
((netif)? (netif)->name[0]: '-'), \
|
||||||
|
((netif)? (netif)->name[1]: '-'), \
|
||||||
|
((netif)? netif_get_index(netif): 42)
|
||||||
|
|
||||||
// A class to make it easier to handle and pass around IP addresses
|
// A class to make it easier to handle and pass around IP addresses
|
||||||
// IPv6 update:
|
// IPv6 update:
|
||||||
// IPAddress is now a decorator class for lwIP's ip_addr_t
|
// IPAddress is now a decorator class for lwIP's ip_addr_t
|
||||||
|
26
cores/esp8266/LwipIntf.h
Normal file
26
cores/esp8266/LwipIntf.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
#ifndef _LWIPINTF_H
|
||||||
|
#define _LWIPINTF_H
|
||||||
|
|
||||||
|
#include <lwip/netif.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class LwipIntf
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using CBType = std::function <void(netif*)>;
|
||||||
|
|
||||||
|
static bool stateUpCB (LwipIntf::CBType&& cb);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
LwipIntf () { } // private, cannot be directly allocated
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
static bool stateChangeSysCB (LwipIntf::CBType&& cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _LWIPINTF_H
|
42
cores/esp8266/LwipIntfCB.cpp
Normal file
42
cores/esp8266/LwipIntfCB.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
#include <LwipIntf.h>
|
||||||
|
#include <Schedule.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#define NETIF_STATUS_CB_SIZE 3
|
||||||
|
|
||||||
|
static int netifStatusChangeListLength = 0;
|
||||||
|
LwipIntf::CBType netifStatusChangeList [NETIF_STATUS_CB_SIZE];
|
||||||
|
|
||||||
|
extern "C" void netif_status_changed (struct netif* netif)
|
||||||
|
{
|
||||||
|
// override the default empty weak function
|
||||||
|
for (int i = 0; i < netifStatusChangeListLength; i++)
|
||||||
|
netifStatusChangeList[i](netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LwipIntf::stateChangeSysCB (LwipIntf::CBType&& cb)
|
||||||
|
{
|
||||||
|
if (netifStatusChangeListLength >= NETIF_STATUS_CB_SIZE)
|
||||||
|
{
|
||||||
|
#if defined(DEBUG_ESP_CORE)
|
||||||
|
DEBUGV("NETIF_STATUS_CB_SIZE is too low\n");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
netifStatusChangeList[netifStatusChangeListLength++] = cb;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LwipIntf::stateUpCB (LwipIntf::CBType&& cb)
|
||||||
|
{
|
||||||
|
return stateChangeSysCB([cb](netif* nif)
|
||||||
|
{
|
||||||
|
if (netif_is_up(nif))
|
||||||
|
schedule_function([cb, nif]()
|
||||||
|
{
|
||||||
|
cb(nif);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -117,4 +117,36 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
strrstr (static)
|
||||||
|
|
||||||
|
Backwards search for p_pcPattern in p_pcString
|
||||||
|
Based on: https://stackoverflow.com/a/1634398/2778898
|
||||||
|
|
||||||
|
*/
|
||||||
|
const char* strrstr(const char*__restrict p_pcString,
|
||||||
|
const char*__restrict p_pcPattern)
|
||||||
|
{
|
||||||
|
const char* pcResult = 0;
|
||||||
|
|
||||||
|
size_t stStringLength = (p_pcString ? strlen(p_pcString) : 0);
|
||||||
|
size_t stPatternLength = (p_pcPattern ? strlen(p_pcPattern) : 0);
|
||||||
|
|
||||||
|
if ((stStringLength) &&
|
||||||
|
(stPatternLength) &&
|
||||||
|
(stPatternLength <= stStringLength))
|
||||||
|
{
|
||||||
|
// Pattern is shorter or has the same length than the string
|
||||||
|
for (const char* s = (p_pcString + stStringLength - stPatternLength); s >= p_pcString; --s)
|
||||||
|
{
|
||||||
|
if (0 == strncmp(s, p_pcPattern, stPatternLength))
|
||||||
|
{
|
||||||
|
pcResult = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pcResult;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -44,6 +44,9 @@ char* dtostrf (double val, signed char width, unsigned char prec, char *s);
|
|||||||
|
|
||||||
void reverse(char* begin, char* end);
|
void reverse(char* begin, char* end);
|
||||||
|
|
||||||
|
const char* strrstr(const char*__restrict p_pcString,
|
||||||
|
const char*__restrict p_pcPattern);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
@ -30,6 +30,7 @@ void esp_schedule();
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include <AddrList.h>
|
#include <AddrList.h>
|
||||||
|
#include <PolledTimeout.h>
|
||||||
|
|
||||||
#define PBUF_ALIGNER_ADJUST 4
|
#define PBUF_ALIGNER_ADJUST 4
|
||||||
#define PBUF_ALIGNER(x) ((void*)((((intptr_t)(x))+3)&~3))
|
#define PBUF_ALIGNER(x) ((void*)((((intptr_t)(x))+3)&~3))
|
||||||
@ -390,14 +391,39 @@ public:
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cancelBuffer ()
|
||||||
|
{
|
||||||
|
if (_tx_buf_head)
|
||||||
|
pbuf_free(_tx_buf_head);
|
||||||
|
_tx_buf_head = 0;
|
||||||
|
_tx_buf_cur = 0;
|
||||||
|
_tx_buf_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool send(const ip_addr_t* addr = 0, uint16_t port = 0)
|
bool send(const ip_addr_t* addr = 0, uint16_t port = 0)
|
||||||
|
{
|
||||||
|
return trySend(addr, port, /* don't keep buffer */false) == ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sendTimeout(const ip_addr_t* addr, uint16_t port,
|
||||||
|
esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
|
||||||
|
{
|
||||||
|
err_t err;
|
||||||
|
esp8266::polledTimeout::oneShotFastMs timeout(timeoutMs);
|
||||||
|
while (((err = trySend(addr, port, /* keep buffer on error */true)) != ERR_OK) && !timeout)
|
||||||
|
delay(0);
|
||||||
|
if (err != ERR_OK)
|
||||||
|
cancelBuffer(); // get rid of buffer kept on error after timeout
|
||||||
|
return err == ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
err_t trySend(const ip_addr_t* addr, uint16_t port, bool keepBufferOnError)
|
||||||
{
|
{
|
||||||
size_t data_size = _tx_buf_offset;
|
size_t data_size = _tx_buf_offset;
|
||||||
pbuf* tx_copy = pbuf_alloc(PBUF_TRANSPORT, data_size, PBUF_RAM);
|
pbuf* tx_copy = pbuf_alloc(PBUF_TRANSPORT, data_size, PBUF_RAM);
|
||||||
if(!tx_copy){
|
if (tx_copy) {
|
||||||
DEBUGV("failed pbuf_alloc");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
uint8_t* dst = reinterpret_cast<uint8_t*>(tx_copy->payload);
|
uint8_t* dst = reinterpret_cast<uint8_t*>(tx_copy->payload);
|
||||||
for (pbuf* p = _tx_buf_head; p; p = p->next) {
|
for (pbuf* p = _tx_buf_head; p; p = p->next) {
|
||||||
size_t will_copy = (data_size < p->len) ? data_size : p->len;
|
size_t will_copy = (data_size < p->len) ? data_size : p->len;
|
||||||
@ -406,38 +432,32 @@ public:
|
|||||||
data_size -= will_copy;
|
data_size -= will_copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_tx_buf_head)
|
|
||||||
pbuf_free(_tx_buf_head);
|
|
||||||
_tx_buf_head = 0;
|
|
||||||
_tx_buf_cur = 0;
|
|
||||||
_tx_buf_offset = 0;
|
|
||||||
if(!tx_copy){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!keepBufferOnError)
|
||||||
|
cancelBuffer();
|
||||||
|
|
||||||
|
if (!tx_copy){
|
||||||
|
DEBUGV("failed pbuf_alloc");
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
addr = &_pcb->remote_ip;
|
addr = &_pcb->remote_ip;
|
||||||
port = _pcb->remote_port;
|
port = _pcb->remote_port;
|
||||||
}
|
}
|
||||||
#ifdef LWIP_MAYBE_XCC
|
|
||||||
uint16_t old_ttl = _pcb->ttl;
|
|
||||||
if (ip_addr_ismulticast(addr)) {
|
|
||||||
_pcb->ttl = _mcast_ttl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
err_t err = udp_sendto(_pcb, tx_copy, addr, port);
|
err_t err = udp_sendto(_pcb, tx_copy, addr, port);
|
||||||
if (err != ERR_OK) {
|
if (err != ERR_OK) {
|
||||||
DEBUGV(":ust rc=%d\r\n", (int) err);
|
DEBUGV(":ust rc=%d\r\n", (int) err);
|
||||||
}
|
}
|
||||||
#ifdef LWIP_MAYBE_XCC
|
|
||||||
_pcb->ttl = old_ttl;
|
|
||||||
#endif
|
|
||||||
pbuf_free(tx_copy);
|
|
||||||
return err == ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
pbuf_free(tx_copy);
|
||||||
|
|
||||||
|
if (err == ERR_OK)
|
||||||
|
cancelBuffer(); // no error: get rid of buffer
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
size_t _processSize (const pbuf* pb)
|
size_t _processSize (const pbuf* pb)
|
||||||
{
|
{
|
||||||
|
@ -36,21 +36,9 @@
|
|||||||
#include <WiFiClient.h>
|
#include <WiFiClient.h>
|
||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
/*
|
|
||||||
Include the MDNSResponder (the library needs to be included also)
|
|
||||||
As LEA MDNSResponder is experimantal in the ESP8266 environment currently, the
|
|
||||||
legacy MDNSResponder is defaulted in th include file.
|
|
||||||
There are two ways to access LEA MDNSResponder:
|
|
||||||
1. Prepend every declaration and call to global declarations or functions with the namespace, like:
|
|
||||||
'LEAmDNS::MDNSResponder::hMDNSService hMDNSService;'
|
|
||||||
This way is used in the example. But be careful, if the namespace declaration is missing
|
|
||||||
somewhere, the call might go to the legacy implementation...
|
|
||||||
2. Open 'ESP8266mDNS.h' and set LEAmDNS to default.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include <ESP8266mDNS.h>
|
|
||||||
#include <PolledTimeout.h>
|
#include <PolledTimeout.h>
|
||||||
|
#include <ESP8266mDNS.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Global defines and vars
|
Global defines and vars
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,269 @@
|
|||||||
|
/*
|
||||||
|
ESP8266 mDNS responder clock
|
||||||
|
|
||||||
|
This example demonstrates two features of the LEA clsLEAMDNSHost:
|
||||||
|
1. The host and service domain negotiation process that ensures
|
||||||
|
the uniqueness of the finally chosen host and service domain name.
|
||||||
|
2. The dynamic MDNS service TXT feature
|
||||||
|
|
||||||
|
A 'clock' service in announced via the MDNS responder and the current
|
||||||
|
time is set as a TXT item (eg. 'curtime=Mon Oct 15 19:54:35 2018').
|
||||||
|
The time value is updated every second!
|
||||||
|
|
||||||
|
The ESP is initially announced to clients as 'esp8266.local', if this host domain
|
||||||
|
is already used in the local network, another host domain is negotiated. Keep an
|
||||||
|
eye on the serial output to learn the final host domain for the clock service.
|
||||||
|
The service itself is is announced as 'host domain'._espclk._tcp.local.
|
||||||
|
As the service uses port 80, a very simple HTTP server is also installed to deliver
|
||||||
|
a small web page containing a greeting and the current time (not updated).
|
||||||
|
The web server code is taken nearly 1:1 from the 'mDNS_Web_Server.ino' example.
|
||||||
|
Point your browser to 'host domain'.local to see this web page.
|
||||||
|
|
||||||
|
Instructions:
|
||||||
|
- Update WiFi SSID and password as necessary.
|
||||||
|
- Flash the sketch to the ESP8266 board
|
||||||
|
- Install host software:
|
||||||
|
- For Linux, install Avahi (http://avahi.org/).
|
||||||
|
- For Windows, install Bonjour (http://www.apple.com/support/bonjour/).
|
||||||
|
- For Mac OSX and iOS support is built in through Bonjour already.
|
||||||
|
- Use a MDNS/Bonjour browser like 'Discovery' to find the clock service in your local
|
||||||
|
network and see the current time updates.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
#include <ESP8266WebServer.h>
|
||||||
|
#include <LwipIntf.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <PolledTimeout.h>
|
||||||
|
|
||||||
|
// uses API MDNSApiVersion::LEAv2
|
||||||
|
#define NO_GLOBAL_MDNS // our MDNS is defined below
|
||||||
|
#include <ESP8266mDNS.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Global defines and vars
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TIMEZONE_OFFSET 1 // CET
|
||||||
|
#define DST_OFFSET 1 // CEST
|
||||||
|
#define UPDATE_CYCLE (1 * 1000) // every second
|
||||||
|
|
||||||
|
#define START_AP_AFTER_MS 10000 // start AP after delay
|
||||||
|
#define SERVICE_PORT 80 // HTTP port
|
||||||
|
|
||||||
|
#ifndef STASSID
|
||||||
|
#define STASSID "your-ssid"
|
||||||
|
#define STAPSK "your-password"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef APSSID
|
||||||
|
#define APSSID "ap4mdnsClock"
|
||||||
|
#define APPSK "mdnsClock"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* ssid = STASSID;
|
||||||
|
const char* password = STAPSK;
|
||||||
|
|
||||||
|
clsLEAMDNSHost MDNSRESP; // MDNS responder
|
||||||
|
bool bHostDomainConfirmed = false; // Flags the confirmation of the host domain
|
||||||
|
clsLEAMDNSHost::clsService* hMDNSService = 0; // The handle of the clock service in the MDNS responder
|
||||||
|
|
||||||
|
// HTTP server at port 'SERVICE_PORT' will respond to HTTP requests
|
||||||
|
ESP8266WebServer server(SERVICE_PORT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
getTimeString
|
||||||
|
*/
|
||||||
|
const char* getTimeString(void) {
|
||||||
|
|
||||||
|
static char acTimeString[32];
|
||||||
|
time_t now = time(nullptr);
|
||||||
|
ctime_r(&now, acTimeString);
|
||||||
|
size_t stLength;
|
||||||
|
while (((stLength = strlen(acTimeString))) &&
|
||||||
|
('\n' == acTimeString[stLength - 1])) {
|
||||||
|
acTimeString[stLength - 1] = 0; // Remove trailing line break...
|
||||||
|
}
|
||||||
|
return acTimeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
setClock
|
||||||
|
|
||||||
|
Set time via NTP
|
||||||
|
*/
|
||||||
|
void setClock(void) {
|
||||||
|
configTime((TIMEZONE_OFFSET * 3600), (DST_OFFSET * 3600), "pool.ntp.org", "time.nist.gov", "time.windows.com");
|
||||||
|
|
||||||
|
Serial.print("Waiting for NTP time sync: ");
|
||||||
|
time_t now = time(nullptr); // Secs since 01.01.1970 (when uninitalized starts with (8 * 3600 = 28800)
|
||||||
|
while (now < 8 * 3600 * 2) { // Wait for realistic value
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
now = time(nullptr);
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
Serial.printf("Current time: %s\n", getTimeString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
setStationHostname
|
||||||
|
*/
|
||||||
|
bool setStationHostname(const char* p_pcHostname) {
|
||||||
|
|
||||||
|
if (p_pcHostname) {
|
||||||
|
WiFi.hostname(p_pcHostname);
|
||||||
|
Serial.printf("setDeviceHostname: Station hostname is set to '%s'\n", p_pcHostname);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
MDNSDynamicServiceTxtCallback
|
||||||
|
|
||||||
|
Add a dynamic MDNS TXT item 'ct' to the clock service.
|
||||||
|
The callback function is called every time, the TXT items for the clock service
|
||||||
|
are needed.
|
||||||
|
This can be triggered by calling MDNSRESP.announce().
|
||||||
|
|
||||||
|
*/
|
||||||
|
void MDNSDynamicServiceTxtCallback(const clsLEAMDNSHost::hMDNSService& p_hService) {
|
||||||
|
Serial.println("MDNSDynamicServiceTxtCallback");
|
||||||
|
|
||||||
|
if (hMDNSService == &p_hService) {
|
||||||
|
Serial.printf("Updating curtime TXT item to: %s\n", getTimeString());
|
||||||
|
hMDNSService->addDynamicServiceTxt("curtime", getTimeString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
handleHTTPClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
void handleHTTPRequest() {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("HTTP Request");
|
||||||
|
|
||||||
|
// Get current time
|
||||||
|
time_t now = time(nullptr);;
|
||||||
|
struct tm timeinfo;
|
||||||
|
gmtime_r(&now, &timeinfo);
|
||||||
|
|
||||||
|
String s;
|
||||||
|
s.reserve(300);
|
||||||
|
|
||||||
|
s = "<!DOCTYPE HTML>\r\n<html>Hello from ";
|
||||||
|
s += WiFi.hostname() + " at " + WiFi.localIP().toString();
|
||||||
|
// Simple addition of the current time
|
||||||
|
s += "\r\nCurrent time is: ";
|
||||||
|
s += getTimeString();
|
||||||
|
// done :-)
|
||||||
|
s += "</html>\r\n\r\n";
|
||||||
|
Serial.println("Sending 200");
|
||||||
|
server.send(200, "text/html", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
setup
|
||||||
|
*/
|
||||||
|
void setup(void) {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
// Connect to WiFi network
|
||||||
|
|
||||||
|
WiFi.persistent(false);
|
||||||
|
|
||||||
|
// useless informative callback
|
||||||
|
if (!LwipIntf::stateUpCB([](netif * nif) {
|
||||||
|
Serial.printf("New interface %c%c/%d is up\n",
|
||||||
|
nif->name[0],
|
||||||
|
nif->name[1],
|
||||||
|
netif_get_index(nif));
|
||||||
|
})) {
|
||||||
|
Serial.println("Error: could not add informative callback\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
Serial.println("");
|
||||||
|
|
||||||
|
// Wait for connection
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print("Connected to ");
|
||||||
|
Serial.println(ssid);
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
// Sync clock
|
||||||
|
setClock();
|
||||||
|
|
||||||
|
// Setup MDNS responder
|
||||||
|
// Init the (currently empty) host domain string with 'leamdnsv2'
|
||||||
|
if (MDNSRESP.begin("leamdnsv2",
|
||||||
|
[](clsLEAMDNSHost & p_rMDNSHost, const char* p_pcDomainName, bool p_bProbeResult)->void {
|
||||||
|
if (p_bProbeResult) {
|
||||||
|
Serial.printf("mDNSHost_AP::ProbeResultCallback: '%s' is %s\n", p_pcDomainName, (p_bProbeResult ? "FREE" : "USED!"));
|
||||||
|
// Unattended added service
|
||||||
|
hMDNSService = p_rMDNSHost.addService(0, "espclk", "tcp", 80);
|
||||||
|
hMDNSService->addDynamicServiceTxt("curtime", getTimeString());
|
||||||
|
hMDNSService->setDynamicServiceTxtCallback(MDNSDynamicServiceTxtCallback);
|
||||||
|
} else {
|
||||||
|
// Change hostname, use '-' as divider between base name and index
|
||||||
|
MDNSRESP.setHostName(clsLEAMDNSHost::indexDomainName(p_pcDomainName, "-", 0));
|
||||||
|
}
|
||||||
|
})) {
|
||||||
|
Serial.println("mDNS-AP started");
|
||||||
|
} else {
|
||||||
|
Serial.println("FAILED to start mDNS-AP");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup HTTP server
|
||||||
|
server.on("/", handleHTTPRequest);
|
||||||
|
server.begin();
|
||||||
|
Serial.println("HTTP server started");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
loop
|
||||||
|
*/
|
||||||
|
void loop(void) {
|
||||||
|
|
||||||
|
// Check if a request has come in
|
||||||
|
server.handleClient();
|
||||||
|
// Allow MDNS processing
|
||||||
|
MDNSRESP.update();
|
||||||
|
|
||||||
|
static esp8266::polledTimeout::periodicMs timeout(UPDATE_CYCLE);
|
||||||
|
if (timeout.expired()) {
|
||||||
|
|
||||||
|
if (hMDNSService) {
|
||||||
|
// Just trigger a new MDNS announcement, this will lead to a call to
|
||||||
|
// 'MDNSDynamicServiceTxtCallback', which will update the time TXT item
|
||||||
|
Serial.printf("Announce trigger from user\n");
|
||||||
|
MDNSRESP.announce();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool AP_started = false;
|
||||||
|
if (!AP_started && millis() > START_AP_AFTER_MS) {
|
||||||
|
AP_started = true;
|
||||||
|
Serial.printf("Starting AP...\n");
|
||||||
|
WiFi.mode(WIFI_AP_STA);
|
||||||
|
WiFi.softAP(APSSID, APPSK);
|
||||||
|
Serial.printf("AP started...(%s:%s, %s)\n",
|
||||||
|
WiFi.softAPSSID().c_str(),
|
||||||
|
WiFi.softAPPSK().c_str(),
|
||||||
|
WiFi.softAPIP().toString().c_str());
|
||||||
|
}
|
||||||
|
}
|
@ -33,19 +33,6 @@
|
|||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <WiFiClient.h>
|
#include <WiFiClient.h>
|
||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
|
|
||||||
/*
|
|
||||||
Include the MDNSResponder (the library needs to be included also)
|
|
||||||
As LEA MDNSResponder is experimantal in the ESP8266 environment currently, the
|
|
||||||
legacy MDNSResponder is defaulted in th include file.
|
|
||||||
There are two ways to access LEA MDNSResponder:
|
|
||||||
1. Prepend every declaration and call to global declarations or functions with the namespace, like:
|
|
||||||
'LEAmDNS:MDNSResponder::hMDNSService hMDNSService;'
|
|
||||||
This way is used in the example. But be careful, if the namespace declaration is missing
|
|
||||||
somewhere, the call might go to the legacy implementation...
|
|
||||||
2. Open 'ESP8266mDNS.h' and set LEAmDNS to default.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
ESP8266 mDNS Responder Service Monitor
|
||||||
|
|
||||||
|
This example demonstrates two features of the LEA clsLEAMDNSHost:
|
||||||
|
1. The host and service domain negotiation process that ensures
|
||||||
|
the uniqueness of the finally choosen host and service domain name.
|
||||||
|
2. The dynamic MDNS service lookup/query feature.
|
||||||
|
|
||||||
|
A list of 'HTTP' services in the local network is created and kept up to date.
|
||||||
|
In addition to this, a (very simple) HTTP server is set up on port 80
|
||||||
|
and announced as a service.
|
||||||
|
|
||||||
|
The ESP itself is initially announced to clients as 'esp8266.local', if this host domain
|
||||||
|
is already used in the local network, another host domain is negociated. Keep an
|
||||||
|
eye to the serial output to learn the final host domain for the HTTP service.
|
||||||
|
The service itself is is announced as 'host domain'._http._tcp.local.
|
||||||
|
The HTTP server delivers a short greeting and the current list of other 'HTTP' services (not updated).
|
||||||
|
The web server code is taken nearly 1:1 from the 'mDNS_Web_Server.ino' example.
|
||||||
|
Point your browser to 'host domain'.local to see this web page.
|
||||||
|
|
||||||
|
Instructions:
|
||||||
|
- Update WiFi SSID and password as necessary.
|
||||||
|
- Flash the sketch to the ESP8266 board
|
||||||
|
- Install host software:
|
||||||
|
- For Linux, install Avahi (http://avahi.org/).
|
||||||
|
- For Windows, install Bonjour (http://www.apple.com/support/bonjour/).
|
||||||
|
- For Mac OSX and iOS support is built in through Bonjour already.
|
||||||
|
- Use a browser like 'Safari' to see the page at http://'host domain'.local.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// THIS IS A WORK IN PROGRESS: some TODOs need completion
|
||||||
|
|
||||||
|
#ifndef STASSID
|
||||||
|
#define STASSID "ssid"
|
||||||
|
#define STAPSK "psk"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef APSSID
|
||||||
|
#define APSSID "esp8266"
|
||||||
|
//#define APPSK "psk"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
#include <ESP8266WebServer.h>
|
||||||
|
|
||||||
|
#define NO_GLOBAL_MDNS // our MDNS is defined below
|
||||||
|
#include <ESP8266mDNS.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Global defines and vars
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SERVICE_PORT 80 // HTTP port
|
||||||
|
clsLEAMDNSHost MDNS; // MDNS responder
|
||||||
|
|
||||||
|
char* pcHostDomain = 0; // Negociated host domain
|
||||||
|
bool bHostDomainConfirmed = false; // Flags the confirmation of the host domain
|
||||||
|
clsLEAMDNSHost::clsService* hMDNSService = 0; // The handle of the http service in the MDNS responder
|
||||||
|
clsLEAMDNSHost::clsQuery* hMDNSServiceQuery = 0; // The handle of the 'http.tcp' service query in the MDNS responder
|
||||||
|
|
||||||
|
const String cstrNoHTTPServices = "Currently no 'http.tcp' services in the local network!<br/>";
|
||||||
|
String strHTTPServices = cstrNoHTTPServices;
|
||||||
|
|
||||||
|
// HTTP server at port 'SERVICE_PORT' will respond to HTTP requests
|
||||||
|
ESP8266WebServer server(SERVICE_PORT);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
setStationHostname
|
||||||
|
*/
|
||||||
|
bool setStationHostname(const char* p_pcHostname) {
|
||||||
|
|
||||||
|
if (p_pcHostname) {
|
||||||
|
WiFi.hostname(p_pcHostname);
|
||||||
|
Serial.printf("setStationHostname: Station hostname is set to '%s'\n", p_pcHostname);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MDNSServiceQueryCallback(const clsLEAMDNSHost::clsQuery& p_Query,
|
||||||
|
const clsLEAMDNSHost::clsQuery::clsAnswer& p_Answer,
|
||||||
|
clsLEAMDNSHost::clsQuery::clsAnswer::typeQueryAnswerType p_QueryAnswerTypeFlags,
|
||||||
|
bool p_bSetContent) {
|
||||||
|
(void)p_Query;
|
||||||
|
|
||||||
|
String answerInfo;
|
||||||
|
switch (p_QueryAnswerTypeFlags) {
|
||||||
|
case static_cast<clsLEAMDNSHost::clsQuery::clsAnswer::typeQueryAnswerType>(clsLEAMDNSHost::clsQuery::clsAnswer::enuQueryAnswerType::ServiceDomain):
|
||||||
|
answerInfo = "ServiceDomain " + String(p_Answer.m_ServiceDomain.c_str());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case static_cast<clsLEAMDNSHost::clsQuery::clsAnswer::typeQueryAnswerType>(clsLEAMDNSHost::clsQuery::clsAnswer::enuQueryAnswerType::HostDomainPort):
|
||||||
|
answerInfo = "HostDomainAndPort " + String(p_Answer.m_HostDomain.c_str()) + ":" + String(p_Answer.m_u16Port);
|
||||||
|
break;
|
||||||
|
case static_cast<clsLEAMDNSHost::clsQuery::clsAnswer::typeQueryAnswerType>(clsLEAMDNSHost::clsQuery::clsAnswer::enuQueryAnswerType::IPv4Address):
|
||||||
|
answerInfo = "IP4Address ";
|
||||||
|
for (auto ip : p_Answer.m_IPv4Addresses) {
|
||||||
|
answerInfo += "- " + ip->m_IPAddress.toString();
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case static_cast<clsLEAMDNSHost::clsQuery::clsAnswer::typeQueryAnswerType>(clsLEAMDNSHost::clsQuery::clsAnswer::enuQueryAnswerType::Txts):
|
||||||
|
answerInfo = "TXT ";
|
||||||
|
for (auto kv : p_Answer.m_Txts.m_Txts) {
|
||||||
|
answerInfo += "\nkv : " + String(kv->m_pcKey) + " : " + String(kv->m_pcValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
answerInfo = "Unknown Answertype " + String(p_QueryAnswerTypeFlags);
|
||||||
|
|
||||||
|
}
|
||||||
|
Serial.printf("Answer %s %s\n", answerInfo.c_str(), p_bSetContent ? "Modified" : "Deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
MDNSServiceProbeResultCallback
|
||||||
|
Probe result callback for Services
|
||||||
|
*/
|
||||||
|
|
||||||
|
void serviceProbeResult(clsLEAMDNSHost::clsService& p_rMDNSService,
|
||||||
|
const char* p_pcInstanceName,
|
||||||
|
bool p_bProbeResult) {
|
||||||
|
(void)p_rMDNSService;
|
||||||
|
Serial.printf("MDNSServiceProbeResultCallback: Service %s probe %s\n", p_pcInstanceName, (p_bProbeResult ? "succeeded." : "failed!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
MDNSHostProbeResultCallback
|
||||||
|
|
||||||
|
Probe result callback for the host domain.
|
||||||
|
If the domain is free, the host domain is set and the http service is
|
||||||
|
added.
|
||||||
|
If the domain is already used, a new name is created and the probing is
|
||||||
|
restarted via p_pclsLEAMDNSHost->setHostname().
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void hostProbeResult(clsLEAMDNSHost & p_rMDNSHost, String p_pcDomainName, bool p_bProbeResult) {
|
||||||
|
|
||||||
|
(void)p_rMDNSHost;
|
||||||
|
Serial.printf("MDNSHostProbeResultCallback: Host domain '%s.local' is %s\n", p_pcDomainName.c_str(), (p_bProbeResult ? "free" : "already USED!"));
|
||||||
|
|
||||||
|
if (true == p_bProbeResult) {
|
||||||
|
// Set station hostname
|
||||||
|
setStationHostname(pcHostDomain);
|
||||||
|
|
||||||
|
if (!bHostDomainConfirmed) {
|
||||||
|
// Hostname free -> setup clock service
|
||||||
|
bHostDomainConfirmed = true;
|
||||||
|
|
||||||
|
if (!hMDNSService) {
|
||||||
|
// Add a 'http.tcp' service to port 'SERVICE_PORT', using the host domain as instance domain
|
||||||
|
hMDNSService = MDNS.addService(0, "http", "tcp", SERVICE_PORT, serviceProbeResult);
|
||||||
|
|
||||||
|
if (hMDNSService) {
|
||||||
|
hMDNSService->setProbeResultCallback(serviceProbeResult);
|
||||||
|
// MDNS.setServiceProbeResultCallback(hMDNSService, serviceProbeResult);
|
||||||
|
|
||||||
|
// Add some '_http._tcp' protocol specific MDNS service TXT items
|
||||||
|
// See: http://www.dns-sd.org/txtrecords.html#http
|
||||||
|
hMDNSService->addServiceTxt("user", "");
|
||||||
|
hMDNSService->addServiceTxt("password", "");
|
||||||
|
hMDNSService->addServiceTxt("path", "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install dynamic 'http.tcp' service query
|
||||||
|
if (!hMDNSServiceQuery) {
|
||||||
|
hMDNSServiceQuery = MDNS.installServiceQuery("http", "tcp", MDNSServiceQueryCallback);
|
||||||
|
if (hMDNSServiceQuery) {
|
||||||
|
Serial.printf("MDNSProbeResultCallback: Service query for 'http.tcp' services installed.\n");
|
||||||
|
} else {
|
||||||
|
Serial.printf("MDNSProbeResultCallback: FAILED to install service query for 'http.tcp' services!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Change hostname, use '-' as divider between base name and index
|
||||||
|
MDNS.setHostName(clsLEAMDNSHost::indexDomainName(p_pcDomainName.c_str(), "-", 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
HTTP request function (not found is handled by server)
|
||||||
|
*/
|
||||||
|
void handleHTTPRequest() {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("HTTP Request");
|
||||||
|
|
||||||
|
IPAddress ip = server.client().localIP();
|
||||||
|
String ipStr = ip.toString();
|
||||||
|
String s;
|
||||||
|
s.reserve(200 /* + service listed */);
|
||||||
|
s = "<!DOCTYPE HTML>\r\n<html><h3><head>Hello from ";
|
||||||
|
s += WiFi.hostname() + ".local at " + server.client().localIP().toString() + "</h3></head>";
|
||||||
|
s += "<br/><h4>Local HTTP services are :</h4>";
|
||||||
|
s += "<ol>";
|
||||||
|
|
||||||
|
// TODO: list services
|
||||||
|
|
||||||
|
s += "</ol><br/>";
|
||||||
|
|
||||||
|
Serial.println("Sending 200");
|
||||||
|
server.send(200, "text/html", s);
|
||||||
|
Serial.println("Done with request");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
setup
|
||||||
|
*/
|
||||||
|
void setup(void) {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.setDebugOutput(false);
|
||||||
|
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("THIS IS A WORK IN PROGRESS: some TODOs need completion");
|
||||||
|
Serial.println("");
|
||||||
|
|
||||||
|
// Connect to WiFi network
|
||||||
|
WiFi.mode(WIFI_AP_STA);
|
||||||
|
WiFi.softAP(APSSID);
|
||||||
|
WiFi.begin(STASSID, STAPSK);
|
||||||
|
Serial.println("");
|
||||||
|
|
||||||
|
// Wait for connection
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print("Connected to ");
|
||||||
|
Serial.println(STASSID);
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
// Setup HTTP server
|
||||||
|
server.on("/", handleHTTPRequest);
|
||||||
|
|
||||||
|
// Setup MDNS responders
|
||||||
|
MDNS.setProbeResultCallback(hostProbeResult);
|
||||||
|
|
||||||
|
// Init the (currently empty) host domain string with 'leamdnsv2'
|
||||||
|
MDNS.begin("leamdnsv2");
|
||||||
|
Serial.println("MDNS responder started");
|
||||||
|
|
||||||
|
// Start HTTP server
|
||||||
|
server.begin();
|
||||||
|
Serial.println("HTTP server started");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(void) {
|
||||||
|
// Check if a request has come in
|
||||||
|
server.handleClient();
|
||||||
|
// Allow MDNS processing
|
||||||
|
MDNS.update();
|
||||||
|
}
|
@ -12,33 +12,38 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef APSSID
|
||||||
|
#define APSSID "your-apssid"
|
||||||
|
#define APPSK "your-password"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef STASSID
|
#ifndef STASSID
|
||||||
#define STASSID "your-ssid"
|
#define STASSID "your-sta"
|
||||||
#define STAPSK "your-password"
|
#define STAPSK "your-password"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// includes
|
// includes
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <ESP8266mDNS.h>
|
|
||||||
#include <WiFiUdp.h>
|
#include <WiFiUdp.h>
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
#include <ArduinoOTA.h>
|
#include <ArduinoOTA.h>
|
||||||
|
#include <ESP8266mDNS.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief mDNS and OTA Constants
|
@brief mDNS and OTA Constants
|
||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
#define HOSTNAME "ESP8266-OTA-" ///< Hostename. The setup function adds the Chip ID at the end.
|
#define HOSTNAME "ESP8266-OTA-" ///< Hostname. The setup function adds the Chip ID at the end.
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Default WiFi connection information.
|
@brief Default WiFi connection information.
|
||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
const char* ap_default_ssid = STASSID; ///< Default SSID.
|
const char* ap_default_ssid = APSSID; ///< Default SSID.
|
||||||
const char* ap_default_psk = STAPSK; ///< Default PSK.
|
const char* ap_default_psk = APPSK; ///< Default PSK.
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// Uncomment the next line for verbose output over UART.
|
/// Uncomment the next line for verbose output over UART.
|
||||||
@ -166,8 +171,8 @@ void setup() {
|
|||||||
|
|
||||||
// Load wifi connection information.
|
// Load wifi connection information.
|
||||||
if (! loadConfig(&station_ssid, &station_psk)) {
|
if (! loadConfig(&station_ssid, &station_psk)) {
|
||||||
station_ssid = "";
|
station_ssid = STASSID;
|
||||||
station_psk = "";
|
station_psk = STAPSK;
|
||||||
|
|
||||||
Serial.println("No WiFi connection information available.");
|
Serial.println("No WiFi connection information available.");
|
||||||
}
|
}
|
@ -1,3 +1,25 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
License (MIT license):
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
- 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 supported 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)
|
||||||
@ -42,15 +42,18 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ESP8266mDNS_Legacy.h"
|
enum class MDNSApiVersion { LEA, LEAv2 };
|
||||||
#include "LEAmDNS.h"
|
|
||||||
|
|
||||||
|
#include "LEAmDNS.h" // LEA
|
||||||
|
#include "LEAmDNS2Host.h" // LEAv2 - API updated
|
||||||
|
|
||||||
|
// clsLEAMDNSHost replaces MDNSResponder in LEAv2
|
||||||
|
using clsLEAMDNSHost = esp8266::experimental::clsLEAMDNSHost;
|
||||||
|
|
||||||
#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 = esp8266::MDNSImplementation::MDNSResponder; // LEA
|
||||||
using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; //new
|
//using MDNSResponder = clsLEAMDNSHost; // LEAv2
|
||||||
|
|
||||||
extern MDNSResponder MDNS;
|
extern MDNSResponder MDNS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,166 +0,0 @@
|
|||||||
/*
|
|
||||||
ESP8266 Multicast DNS (port of CC3000 Multicast DNS library)
|
|
||||||
Version 1.1
|
|
||||||
Copyright (c) 2013 Tony DiCola (tony@tonydicola.com)
|
|
||||||
ESP8266 port (c) 2015 Ivan Grokhotkov (ivan@esp8266.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
|
|
||||||
running on ESP8266 chip. Only support for resolving address queries is currently
|
|
||||||
implemented.
|
|
||||||
|
|
||||||
Requirements:
|
|
||||||
- ESP8266WiFi library
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
- Include the ESP8266 Multicast DNS library in the sketch.
|
|
||||||
- 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
|
|
||||||
Adafruit CC3000 class instance. Optionally provide a time to live (in seconds)
|
|
||||||
for the DNS record--the default is 1 hour.
|
|
||||||
- Call the update method in each iteration of the sketch's loop function.
|
|
||||||
|
|
||||||
License (MIT license):
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef ESP8266MDNS_LEGACY_H
|
|
||||||
#define ESP8266MDNS_LEGACY_H
|
|
||||||
|
|
||||||
#include "ESP8266WiFi.h"
|
|
||||||
#include "WiFiUdp.h"
|
|
||||||
|
|
||||||
//this should be defined at build time
|
|
||||||
#ifndef ARDUINO_BOARD
|
|
||||||
#define ARDUINO_BOARD "generic"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class UdpContext;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Legacy_MDNSResponder
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
struct MDNSService;
|
|
||||||
struct MDNSTxt;
|
|
||||||
struct MDNSAnswer;
|
|
||||||
|
|
||||||
class MDNSResponder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MDNSResponder();
|
|
||||||
~MDNSResponder();
|
|
||||||
bool begin(const char* hostName);
|
|
||||||
bool begin(const String& hostName)
|
|
||||||
{
|
|
||||||
return begin(hostName.c_str());
|
|
||||||
}
|
|
||||||
//for compatibility
|
|
||||||
bool begin(const char* hostName, IPAddress ip, uint32_t ttl = 120)
|
|
||||||
{
|
|
||||||
(void) ip;
|
|
||||||
(void) ttl;
|
|
||||||
return begin(hostName);
|
|
||||||
}
|
|
||||||
bool begin(const String& hostName, IPAddress ip, uint32_t ttl = 120)
|
|
||||||
{
|
|
||||||
return begin(hostName.c_str(), ip, ttl);
|
|
||||||
}
|
|
||||||
/* Application should call this whenever AP is configured/disabled */
|
|
||||||
void notifyAPChange();
|
|
||||||
void update();
|
|
||||||
|
|
||||||
void addService(char *service, char *proto, uint16_t port);
|
|
||||||
void addService(const char *service, const char *proto, uint16_t port)
|
|
||||||
{
|
|
||||||
addService((char *)service, (char *)proto, port);
|
|
||||||
}
|
|
||||||
void addService(const String& service, const String& proto, uint16_t port)
|
|
||||||
{
|
|
||||||
addService(service.c_str(), proto.c_str(), port);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool addServiceTxt(char *name, char *proto, char * key, 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);
|
|
||||||
}
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
int queryService(char *service, char *proto);
|
|
||||||
int queryService(const char *service, const char *proto)
|
|
||||||
{
|
|
||||||
return queryService((char *)service, (char *)proto);
|
|
||||||
}
|
|
||||||
int queryService(const String& service, const String& proto)
|
|
||||||
{
|
|
||||||
return queryService(service.c_str(), proto.c_str());
|
|
||||||
}
|
|
||||||
String hostname(int idx);
|
|
||||||
IPAddress IP(int idx);
|
|
||||||
uint16_t port(int idx);
|
|
||||||
|
|
||||||
void enableArduino(uint16_t port, bool auth = false);
|
|
||||||
|
|
||||||
void setInstanceName(String name);
|
|
||||||
void setInstanceName(const char * name)
|
|
||||||
{
|
|
||||||
setInstanceName(String(name));
|
|
||||||
}
|
|
||||||
void setInstanceName(char * name)
|
|
||||||
{
|
|
||||||
setInstanceName(String(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct MDNSService * _services;
|
|
||||||
UdpContext* _conn;
|
|
||||||
String _hostName;
|
|
||||||
String _instanceName;
|
|
||||||
struct MDNSAnswer * _answers;
|
|
||||||
struct MDNSQuery * _query;
|
|
||||||
bool _newQuery;
|
|
||||||
bool _waitingForAnswers;
|
|
||||||
WiFiEventHandler _disconnectedHandler;
|
|
||||||
WiFiEventHandler _gotIPHandler;
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t _getServicePort(char *service, char *proto);
|
|
||||||
MDNSTxt * _getServiceTxt(char *name, char *proto);
|
|
||||||
uint16_t _getServiceTxtLen(char *name, char *proto);
|
|
||||||
IPAddress _getRequestMulticastInterface();
|
|
||||||
void _parsePacket();
|
|
||||||
void _replyToTypeEnumRequest(IPAddress multicastInterface);
|
|
||||||
void _replyToInstanceRequest(uint8_t questionMask, uint8_t responseMask, char * service, char *proto, uint16_t port, IPAddress multicastInterface);
|
|
||||||
MDNSAnswer* _getAnswerFromIdx(int idx);
|
|
||||||
int _getNumAnswers();
|
|
||||||
bool _listen();
|
|
||||||
void _restart();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Legacy_MDNSResponder
|
|
||||||
|
|
||||||
#endif //ESP8266MDNS_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
|||||||
#include <Schedule.h>
|
#include <Schedule.h>
|
||||||
#include <AddrList.h>
|
#include <AddrList.h>
|
||||||
|
|
||||||
|
#include "ESP8266mDNS.h"
|
||||||
#include "LEAmDNS_Priv.h"
|
#include "LEAmDNS_Priv.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
- 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 supported 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)
|
||||||
@ -172,6 +172,7 @@ class MDNSResponder
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* INTERFACE */
|
/* INTERFACE */
|
||||||
|
|
||||||
MDNSResponder(void);
|
MDNSResponder(void);
|
||||||
virtual ~MDNSResponder(void);
|
virtual ~MDNSResponder(void);
|
||||||
|
|
||||||
|
1331
libraries/ESP8266mDNS/src/LEAmDNS2Host.cpp
Normal file
1331
libraries/ESP8266mDNS/src/LEAmDNS2Host.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1584
libraries/ESP8266mDNS/src/LEAmDNS2Host.h
Normal file
1584
libraries/ESP8266mDNS/src/LEAmDNS2Host.h
Normal file
File diff suppressed because it is too large
Load Diff
2219
libraries/ESP8266mDNS/src/LEAmDNS2Host_Control.cpp
Normal file
2219
libraries/ESP8266mDNS/src/LEAmDNS2Host_Control.cpp
Normal file
File diff suppressed because it is too large
Load Diff
328
libraries/ESP8266mDNS/src/LEAmDNS2Host_Debug.cpp
Normal file
328
libraries/ESP8266mDNS/src/LEAmDNS2Host_Debug.cpp
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
/*
|
||||||
|
LEAmDNS2Host_Debug.h
|
||||||
|
|
||||||
|
License (MIT license):
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ESP8266mDNS.h"
|
||||||
|
#include "LEAmDNS2Host.h"
|
||||||
|
#include "LEAmDNS2_Priv.h"
|
||||||
|
|
||||||
|
namespace esp8266
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
namespace experimental
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG_ESP_PORT
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::_DH
|
||||||
|
|
||||||
|
*/
|
||||||
|
const char* clsLEAMDNSHost::_DH(const clsLEAMDNSHost::clsService* p_pService /*= 0*/) const
|
||||||
|
{
|
||||||
|
static char acBuffer[16 + 64];
|
||||||
|
|
||||||
|
*acBuffer = 0;
|
||||||
|
sprintf_P(acBuffer, PSTR("[mDNS]"));
|
||||||
|
if (p_pService)
|
||||||
|
{
|
||||||
|
strcat_P(acBuffer, PSTR(">"));
|
||||||
|
strcat(acBuffer, _service2String(p_pService));
|
||||||
|
}
|
||||||
|
return acBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::_service2String
|
||||||
|
|
||||||
|
*/
|
||||||
|
const char* clsLEAMDNSHost::_service2String(const clsLEAMDNSHost::clsService* p_pService) const
|
||||||
|
{
|
||||||
|
static char acBuffer[64];
|
||||||
|
|
||||||
|
*acBuffer = 0;
|
||||||
|
if (p_pService)
|
||||||
|
{
|
||||||
|
sprintf_P(acBuffer, PSTR("%s.%s%s.%s%s.local"),
|
||||||
|
(p_pService->m_pcInstanceName ? : "-"),
|
||||||
|
(p_pService->m_pcType ? ('_' == *(p_pService->m_pcType) ? "" : "_") : "-"),
|
||||||
|
(p_pService->m_pcType ? : "-"),
|
||||||
|
(p_pService->m_pcProtocol ? ('_' == *(p_pService->m_pcProtocol) ? "" : "_") : "-"),
|
||||||
|
(p_pService->m_pcProtocol ? : "-"));
|
||||||
|
}
|
||||||
|
return acBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::_printRRDomain
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool clsLEAMDNSHost::_printRRDomain(const clsLEAMDNSHost::clsRRDomain& p_RRDomain) const
|
||||||
|
{
|
||||||
|
//DEBUG_OUTPUT.printf_P(PSTR("Domain: "));
|
||||||
|
|
||||||
|
const char* pCursor = p_RRDomain.m_acName;
|
||||||
|
uint8_t u8Length = *pCursor++;
|
||||||
|
if (u8Length)
|
||||||
|
{
|
||||||
|
while (u8Length)
|
||||||
|
{
|
||||||
|
for (uint8_t u = 0; u < u8Length; ++u)
|
||||||
|
{
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("%c"), *(pCursor++));
|
||||||
|
}
|
||||||
|
u8Length = *pCursor++;
|
||||||
|
if (u8Length)
|
||||||
|
{
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // empty domain
|
||||||
|
{
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("-empty-"));
|
||||||
|
}
|
||||||
|
//DEBUG_OUTPUT.printf_P(PSTR("\n"));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::_printRRAnswer
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool clsLEAMDNSHost::_printRRAnswer(const clsLEAMDNSHost::clsRRAnswer& p_RRAnswer) const
|
||||||
|
{
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("%s RRAnswer: "), _DH());
|
||||||
|
_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);
|
||||||
|
switch (p_RRAnswer.m_Header.m_Attributes.m_u16Type & (~0x8000)) // Topmost bit might carry 'cache flush' flag
|
||||||
|
{
|
||||||
|
#ifdef MDNS_IPV4_SUPPORT
|
||||||
|
case DNS_RRTYPE_A:
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("A IP:%s"), ((const clsRRAnswerA*)&p_RRAnswer)->m_IPAddress.toString().c_str());
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case DNS_RRTYPE_PTR:
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("PTR "));
|
||||||
|
_printRRDomain(((const clsRRAnswerPTR*)&p_RRAnswer)->m_PTRDomain);
|
||||||
|
break;
|
||||||
|
case DNS_RRTYPE_TXT:
|
||||||
|
{
|
||||||
|
size_t stTxtLength = ((const clsRRAnswerTXT*)&p_RRAnswer)->m_Txts.c_strLength();
|
||||||
|
char* pTxts = new char[stTxtLength];
|
||||||
|
if (pTxts)
|
||||||
|
{
|
||||||
|
((/*const c_str()!!*/clsRRAnswerTXT*)&p_RRAnswer)->m_Txts.c_str(pTxts);
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("TXT(%u) %s"), stTxtLength, pTxts);
|
||||||
|
delete[] pTxts;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef MDNS_IPV6_SUPPORT
|
||||||
|
case DNS_RRTYPE_AAAA:
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((clsRRAnswerAAAA*&)p_RRAnswer)->m_IPAddress.toString().c_str());
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case DNS_RRTYPE_SRV:
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("SRV Port:%u "), ((const clsRRAnswerSRV*)&p_RRAnswer)->m_u16Port);
|
||||||
|
_printRRDomain(((const clsRRAnswerSRV*)&p_RRAnswer)->m_SRVDomain);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("generic "));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("\n"));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::_RRType2Name
|
||||||
|
|
||||||
|
*/
|
||||||
|
const char* clsLEAMDNSHost::_RRType2Name(uint16_t p_u16RRType) const
|
||||||
|
{
|
||||||
|
static char acRRName[16];
|
||||||
|
*acRRName = 0;
|
||||||
|
|
||||||
|
switch (p_u16RRType & (~0x8000)) // Topmost bit might carry 'cache flush' flag
|
||||||
|
{
|
||||||
|
#ifdef MDNS_IPV4_SUPPORT
|
||||||
|
case DNS_RRTYPE_A: strcpy_P(acRRName, PSTR("A")); break;
|
||||||
|
#endif
|
||||||
|
case DNS_RRTYPE_PTR: strcpy_P(acRRName, PSTR("PTR")); break;
|
||||||
|
case DNS_RRTYPE_TXT: strcpy_P(acRRName, PSTR("TXT")); break;
|
||||||
|
#ifdef MDNS_IPV6_SUPPORT
|
||||||
|
case DNS_RRTYPE_AAAA: strcpy_P(acRRName, PSTR("AAAA")); break;
|
||||||
|
#endif
|
||||||
|
case DNS_RRTYPE_SRV: strcpy_P(acRRName, PSTR("SRV")); break;
|
||||||
|
case clsConsts::u8DNS_RRTYPE_NSEC: strcpy_P(acRRName, PSTR("NSEC")); break;
|
||||||
|
case DNS_RRTYPE_ANY: strcpy_P(acRRName, PSTR("ANY")); break;
|
||||||
|
default: sprintf_P(acRRName, PSTR("Unknown(0x%04X"), p_u16RRType); // MAX 15!
|
||||||
|
}
|
||||||
|
return acRRName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::_RRClass2String
|
||||||
|
|
||||||
|
*/
|
||||||
|
const char* clsLEAMDNSHost::_RRClass2String(uint16_t p_u16RRClass,
|
||||||
|
bool p_bIsQuery) const
|
||||||
|
{
|
||||||
|
static char acClassString[16];
|
||||||
|
*acClassString = 0;
|
||||||
|
|
||||||
|
if (p_u16RRClass & 0x0001)
|
||||||
|
{
|
||||||
|
strcat_P(acClassString, PSTR("IN ")); // 3
|
||||||
|
}
|
||||||
|
if (p_u16RRClass & 0x8000)
|
||||||
|
{
|
||||||
|
strcat_P(acClassString, (p_bIsQuery ? PSTR("UNICAST ") : PSTR("FLUSH "))); // 8/6
|
||||||
|
}
|
||||||
|
|
||||||
|
return acClassString; // 11
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::_replyFlags2String
|
||||||
|
|
||||||
|
*/
|
||||||
|
const char* clsLEAMDNSHost::_replyFlags2String(uint32_t p_u32ReplyFlags) const
|
||||||
|
{
|
||||||
|
static char acFlagsString[64];
|
||||||
|
|
||||||
|
*acFlagsString = 0;
|
||||||
|
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::A))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("A ")); // 2
|
||||||
|
}
|
||||||
|
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::PTR_IPv4))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("PTR_IPv4 ")); // 7
|
||||||
|
}
|
||||||
|
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::PTR_IPv6))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("PTR_IPv6 ")); // 7
|
||||||
|
}
|
||||||
|
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::AAAA))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("AAAA ")); // 5
|
||||||
|
}
|
||||||
|
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::PTR_TYPE))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("PTR_TYPE ")); // 9
|
||||||
|
}
|
||||||
|
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::PTR_NAME))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("PTR_NAME ")); // 9
|
||||||
|
}
|
||||||
|
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::TXT))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("TXT ")); // 4
|
||||||
|
}
|
||||||
|
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::SRV))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("SRV ")); // 4
|
||||||
|
}
|
||||||
|
if (p_u32ReplyFlags & static_cast<uint32_t>(enuContentFlag::NSEC))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("NSEC ")); // 5
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == p_u32ReplyFlags)
|
||||||
|
{
|
||||||
|
strcpy_P(acFlagsString, PSTR("none"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove trailing spaces
|
||||||
|
while ((*acFlagsString) &&
|
||||||
|
(' ' == acFlagsString[strlen(acFlagsString) - 1]))
|
||||||
|
{
|
||||||
|
acFlagsString[strlen(acFlagsString) - 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acFlagsString; // 63
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::_NSECBitmap2String
|
||||||
|
|
||||||
|
*/
|
||||||
|
const char* clsLEAMDNSHost::_NSECBitmap2String(const clsNSECBitmap* p_pNSECBitmap) const
|
||||||
|
{
|
||||||
|
static char acFlagsString[32];
|
||||||
|
|
||||||
|
*acFlagsString = 0;
|
||||||
|
#ifdef MDNS_IPV4_SUPPORT
|
||||||
|
if (p_pNSECBitmap->getBit(DNS_RRTYPE_A))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("A ")); // 2
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (p_pNSECBitmap->getBit(DNS_RRTYPE_PTR))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("PTR ")); // 4
|
||||||
|
}
|
||||||
|
#ifdef MDNS_IPV6_SUPPORT
|
||||||
|
if (p_pNSECBitmap->getBit(DNS_RRTYPE_AAAA))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("AAAA ")); // 5
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (p_pNSECBitmap->getBit(DNS_RRTYPE_TXT))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("TXT ")); // 4
|
||||||
|
}
|
||||||
|
if (p_pNSECBitmap->getBit(DNS_RRTYPE_SRV))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("SRV ")); // 4
|
||||||
|
}
|
||||||
|
if (p_pNSECBitmap->getBit(clsConsts::u8DNS_RRTYPE_NSEC))
|
||||||
|
{
|
||||||
|
strcat_P(acFlagsString, PSTR("NSEC ")); // 5
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*acFlagsString)
|
||||||
|
{
|
||||||
|
strcpy_P(acFlagsString, PSTR("none"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return acFlagsString; // 31
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG_ESP_PORT
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace MDNSImplementation
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace esp8266
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
3185
libraries/ESP8266mDNS/src/LEAmDNS2Host_Structs.cpp
Normal file
3185
libraries/ESP8266mDNS/src/LEAmDNS2Host_Structs.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2451
libraries/ESP8266mDNS/src/LEAmDNS2Host_Transfer.cpp
Normal file
2451
libraries/ESP8266mDNS/src/LEAmDNS2Host_Transfer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
262
libraries/ESP8266mDNS/src/LEAmDNS2_Backbone.cpp
Normal file
262
libraries/ESP8266mDNS/src/LEAmDNS2_Backbone.cpp
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
LEAmDNS2_Backbone.cpp
|
||||||
|
|
||||||
|
License (MIT license):
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ESP8266mDNS.h"
|
||||||
|
#include "LEAmDNS2Host.h"
|
||||||
|
#include "LEAmDNS2_Priv.h"
|
||||||
|
|
||||||
|
namespace esp8266
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
namespace experimental
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::clsBackbone constructor
|
||||||
|
|
||||||
|
*/
|
||||||
|
clsLEAMDNSHost::clsBackbone::clsBackbone(void)
|
||||||
|
: m_pUDPContext(0),
|
||||||
|
m_bDelayUDPProcessing(false),
|
||||||
|
m_u32DelayedDatagrams(0),
|
||||||
|
m_uniqueHost(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::clsBackbone destructor
|
||||||
|
|
||||||
|
*/
|
||||||
|
clsLEAMDNSHost::clsBackbone::~clsBackbone(void)
|
||||||
|
{
|
||||||
|
_releaseUDPContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::init
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool clsLEAMDNSHost::clsBackbone::init(void)
|
||||||
|
{
|
||||||
|
return _allocUDPContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::addHost
|
||||||
|
|
||||||
|
*/
|
||||||
|
UdpContext* clsLEAMDNSHost::clsBackbone::addHost(clsLEAMDNSHost* p_pHost)
|
||||||
|
{
|
||||||
|
UdpContext* pUDPContext = nullptr;
|
||||||
|
|
||||||
|
if ((m_pUDPContext) && (p_pHost) && (m_uniqueHost == nullptr))
|
||||||
|
{
|
||||||
|
m_uniqueHost = p_pHost;
|
||||||
|
pUDPContext = m_pUDPContext;
|
||||||
|
}
|
||||||
|
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s addHost: %s to add host!\n"), _DH(), (pUDPContext ? "Succeeded" : "FAILED")););
|
||||||
|
return pUDPContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::removeHost
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool clsLEAMDNSHost::clsBackbone::removeHost(clsLEAMDNSHost* p_pHost)
|
||||||
|
{
|
||||||
|
bool bResult = false;
|
||||||
|
|
||||||
|
if ((p_pHost) && (m_uniqueHost == p_pHost))
|
||||||
|
{
|
||||||
|
m_uniqueHost = nullptr;
|
||||||
|
bResult = true;
|
||||||
|
}
|
||||||
|
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s removeHost: %s to remove host!\n"), _DH(), (bResult ? "Succeeded" : "FAILED")););
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::hostCount
|
||||||
|
|
||||||
|
*/
|
||||||
|
size_t clsLEAMDNSHost::clsBackbone::hostCount(void) const
|
||||||
|
{
|
||||||
|
return m_uniqueHost == nullptr ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAMDNSHost::clsBackbone::::setDelayUDPProcessing
|
||||||
|
|
||||||
|
When executing _sendMessage, with multiple or larger messages, sometimes the ESP IP stack seems
|
||||||
|
to need a small delay to get the job done. To allow for this delay, a 'delay' was added after one
|
||||||
|
send operation. However, while 'taking' this delay, sometimes a UDP datagram is received and
|
||||||
|
processed (which might cause another send operation or change global states).
|
||||||
|
To avoid 're-entry-like' problems, UDP processing might be blocked for a short period of time.
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool clsLEAMDNSHost::clsBackbone::setDelayUDPProcessing(bool p_bDelayUDPProcessing)
|
||||||
|
{
|
||||||
|
if (m_bDelayUDPProcessing != p_bDelayUDPProcessing)
|
||||||
|
{
|
||||||
|
m_bDelayUDPProcessing = p_bDelayUDPProcessing;
|
||||||
|
|
||||||
|
if ((!m_bDelayUDPProcessing) &&
|
||||||
|
(m_u32DelayedDatagrams))
|
||||||
|
{
|
||||||
|
DEBUG_EX_INFO2(if (6 <= m_u32DelayedDatagrams) DEBUG_OUTPUT.printf_P(PSTR("%s setDelayUDPProcessing: Processing %u delayed datagram(s)\n"), _DH(), m_u32DelayedDatagrams););
|
||||||
|
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s setDelayUDPProcessing: Processing %u delayed datagram(s)\n"), _DH(), m_u32DelayedDatagrams););
|
||||||
|
_processUDPInput();
|
||||||
|
}
|
||||||
|
m_u32DelayedDatagrams = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::_allocUDPContext
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool clsLEAMDNSHost::clsBackbone::_allocUDPContext(void)
|
||||||
|
{
|
||||||
|
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext\n"), _DH()););
|
||||||
|
if (_releaseUDPContext())
|
||||||
|
{
|
||||||
|
m_pUDPContext = new UdpContext;
|
||||||
|
if (m_pUDPContext)
|
||||||
|
{
|
||||||
|
m_pUDPContext->ref();
|
||||||
|
|
||||||
|
//ip_set_option(m_pUDPContext->pcb(), SOF_REUSEADDR);
|
||||||
|
//udp_bind_netif(m_pUDPContext->pcb(), m_pNetIf);
|
||||||
|
|
||||||
|
if (m_pUDPContext->listen(IP_ANY_TYPE, DNS_MQUERY_PORT))
|
||||||
|
{
|
||||||
|
// This is NOT the TTL (Time-To-Live) for MDNS records, but the subnet level distance MDNS records should travel.
|
||||||
|
// 1 sets the subnet distance to 'local', which is default for MDNS.
|
||||||
|
// (Btw.: 255 would set it to 'as far as possible' -> internet), however, RFC 3171 seems to force 255 instead
|
||||||
|
const uint8_t c_u8MulticastTTL = 255;//1;//255;
|
||||||
|
|
||||||
|
m_pUDPContext->setMulticastTTL(c_u8MulticastTTL);
|
||||||
|
m_pUDPContext->onRx(std::bind(&clsLEAMDNSHost::clsBackbone::_processUDPInput, this));
|
||||||
|
/* m_pUDPContext->onRx([&](void)->void
|
||||||
|
{
|
||||||
|
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext::onRx Received data!\n"), _DH()););
|
||||||
|
});*/
|
||||||
|
m_pUDPContext->connect(IP_ANY_TYPE, DNS_MQUERY_PORT);
|
||||||
|
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext: Succeeded to alloc UDPContext!\n"), _DH()););
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext: FAILED to make UDPContext listening!\n"), _DH()););
|
||||||
|
_releaseUDPContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext: FAILED to alloc UDPContext!\n"), _DH()););
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_EX_ERR(if (!m_pUDPContext) DEBUG_OUTPUT.printf_P(PSTR("%s _allocUDPContext: FAILED!\n"), _DH()););
|
||||||
|
return (0 != m_pUDPContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::_releaseUDPContext
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool clsLEAMDNSHost::clsBackbone::_releaseUDPContext(void)
|
||||||
|
{
|
||||||
|
if (m_pUDPContext)
|
||||||
|
{
|
||||||
|
m_pUDPContext->unref();
|
||||||
|
m_pUDPContext = nullptr;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::_processUDPInput
|
||||||
|
|
||||||
|
Called in SYS context!
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool clsLEAMDNSHost::clsBackbone::_processUDPInput(void)
|
||||||
|
{
|
||||||
|
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _processUDPInput\n"), _DH()););
|
||||||
|
|
||||||
|
bool bResult = true;
|
||||||
|
|
||||||
|
if (!m_bDelayUDPProcessing)
|
||||||
|
{
|
||||||
|
while ((m_pUDPContext) &&
|
||||||
|
(m_pUDPContext->next()))
|
||||||
|
{
|
||||||
|
clsLEAMDNSHost* pHost = _findHost();
|
||||||
|
|
||||||
|
bResult = pHost->_processUDPInput();
|
||||||
|
|
||||||
|
DEBUG_EX_INFO2_IF(!bResult,
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("%s _processUDPInput: FAILED to process UDP input!\n"), _DH()));
|
||||||
|
DEBUG_EX_ERR_IF((-1) != m_pUDPContext->peek(),
|
||||||
|
DEBUG_OUTPUT.printf_P(PSTR("%s _processUDPInput: !!!! CONTENT LEFT IN UDP BUFFER !!!!\n"),
|
||||||
|
_DH()));
|
||||||
|
m_pUDPContext->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("%s _processUDPInput: Delaying datagram!\n"), _DH()););
|
||||||
|
++m_u32DelayedDatagrams;
|
||||||
|
}
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
MISC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if not defined ESP_8266_MDNS_INCLUDE || defined DEBUG_ESP_PORT
|
||||||
|
|
||||||
|
/*
|
||||||
|
clsLEAmDNS2_Host::clsBackbone::_DH
|
||||||
|
*/
|
||||||
|
const char* clsLEAMDNSHost::clsBackbone::_DH(void) const
|
||||||
|
{
|
||||||
|
static char acBuffer[20] = { 0, };
|
||||||
|
if (!acBuffer[0])
|
||||||
|
{
|
||||||
|
strcpy_P(acBuffer, PSTR("[mDNS::backbone]"));
|
||||||
|
}
|
||||||
|
return acBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace MDNSImplementation
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace esp8266
|
115
libraries/ESP8266mDNS/src/LEAmDNS2_Priv.h
Normal file
115
libraries/ESP8266mDNS/src/LEAmDNS2_Priv.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
LEAmDNS_Priv.h
|
||||||
|
|
||||||
|
License (MIT license):
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MDNS2_PRIV_H
|
||||||
|
#define MDNS2_PRIV_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
LWIP_OPEN_SRC
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_OPEN_SRC
|
||||||
|
#define LWIP_OPEN_SRC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Enable class debug functions
|
||||||
|
*/
|
||||||
|
#define ESP_8266_MDNS_INCLUDE
|
||||||
|
//#define DEBUG_ESP_MDNS_RESPONDER // force debug, arduino IDE uses DEBUG_ESP_MDNS
|
||||||
|
|
||||||
|
/*
|
||||||
|
Enable/disable debug trace macros
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(DEBUG_ESP_PORT)
|
||||||
|
#define DEBUG_ESP_MDNS_ERR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(DEBUG_ESP_PORT) && (defined(DEBUG_ESP_MDNS) || defined(DEBUG_ESP_MDNS_RESPONDER))
|
||||||
|
#define DEBUG_ESP_MDNS_INFO
|
||||||
|
#define DEBUG_ESP_MDNS_INFO2
|
||||||
|
//#define DEBUG_ESP_MDNS_TX
|
||||||
|
//#define DEBUG_ESP_MDNS_RX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_ESP_PORT
|
||||||
|
#define DEBUG_OUTPUT DEBUG_ESP_PORT
|
||||||
|
#else
|
||||||
|
#define DEBUG_OUTPUT Serialx
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_ESP_MDNS_INFO
|
||||||
|
#define DEBUG_EX_INFO(A) A
|
||||||
|
#define DEBUG_EX_INFO_IF(C,A...) do if (C) { A; } while (0)
|
||||||
|
#else
|
||||||
|
#define DEBUG_EX_INFO(A)
|
||||||
|
#define DEBUG_EX_INFO_IF(C,A...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_ESP_MDNS_INFO2
|
||||||
|
#define DEBUG_EX_INFO2(A) A
|
||||||
|
#define DEBUG_EX_INFO2_IF(C,A...) do if (C) { A; } while (0)
|
||||||
|
#else
|
||||||
|
#define DEBUG_EX_INFO2(A)
|
||||||
|
#define DEBUG_EX_INFO2_IF(C,A...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_ESP_MDNS_ERR
|
||||||
|
#define DEBUG_EX_ERR(A) A
|
||||||
|
#define DEBUG_EX_ERR_IF(C,A...) do if (C) { A; } while (0)
|
||||||
|
#else
|
||||||
|
#define DEBUG_EX_ERR(A)
|
||||||
|
#define DEBUG_EX_ERR_IF(C,A...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_ESP_MDNS_TX
|
||||||
|
#define DEBUG_EX_TX(A) do { A; } while (0)
|
||||||
|
#else
|
||||||
|
#define DEBUG_EX_TX(A)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_ESP_MDNS_RX
|
||||||
|
#define DEBUG_EX_RX(A) do { A; } while (0)
|
||||||
|
#else
|
||||||
|
#define DEBUG_EX_RX(A)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
USE_PGM_PRINTF and F
|
||||||
|
*/
|
||||||
|
#define USE_PGM_PRINTF
|
||||||
|
|
||||||
|
#ifdef USE_PGM_PRINTF
|
||||||
|
#else
|
||||||
|
#ifdef F
|
||||||
|
#undef F
|
||||||
|
#endif
|
||||||
|
#define F(A) A
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MDNS2_PRIV_H
|
31
libraries/ESP8266mDNS/src/LEAmDNS2_lwIPdefs.h
Normal file
31
libraries/ESP8266mDNS/src/LEAmDNS2_lwIPdefs.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
LEAmDNS2_lwIPdefs.h
|
||||||
|
|
||||||
|
License (MIT license):
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LEAMDNS2_LWIPDEFS_H
|
||||||
|
#define LEAMDNS2_LWIPDEFS_H
|
||||||
|
|
||||||
|
#include <lwip/init.h>
|
||||||
|
#include <lwip/prot/dns.h> // DNS_RRTYPE_xxx, DNS_MQUERY_PORT
|
||||||
|
|
||||||
|
#endif // LEAMDNS2_LWIPDEFS_H
|
@ -37,6 +37,7 @@ extern "C" {
|
|||||||
#include "user_interface.h"
|
#include "user_interface.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "ESP8266mDNS.h"
|
||||||
#include "LEAmDNS_lwIPdefs.h"
|
#include "LEAmDNS_lwIPdefs.h"
|
||||||
#include "LEAmDNS_Priv.h"
|
#include "LEAmDNS_Priv.h"
|
||||||
|
|
||||||
@ -1982,7 +1983,7 @@ bool MDNSResponder::_checkServiceQueryCache(void)
|
|||||||
/*
|
/*
|
||||||
MDNSResponder::_replyMaskForHost
|
MDNSResponder::_replyMaskForHost
|
||||||
|
|
||||||
Determines the relavant host answers for the given question.
|
Determines the relevant host answers for the given question.
|
||||||
- A question for the hostname (eg. esp8266.local) will result in an A/AAAA (eg. 192.168.2.129) reply.
|
- A question for the hostname (eg. esp8266.local) will result in an A/AAAA (eg. 192.168.2.129) reply.
|
||||||
- A question for the reverse IP address (eg. 192-168.2.120.inarpa.arpa) will result in an PTR_IP4 (eg. esp8266.local) reply.
|
- A question for the reverse IP address (eg. 192-168.2.120.inarpa.arpa) will result in an PTR_IP4 (eg. esp8266.local) reply.
|
||||||
|
|
||||||
|
@ -22,55 +22,13 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lwip/igmp.h"
|
#include <lwip/igmp.h>
|
||||||
|
#include <stdlib_noniso.h> // strrstr()
|
||||||
|
|
||||||
|
#include "ESP8266mDNS.h"
|
||||||
#include "LEAmDNS_lwIPdefs.h"
|
#include "LEAmDNS_lwIPdefs.h"
|
||||||
#include "LEAmDNS_Priv.h"
|
#include "LEAmDNS_Priv.h"
|
||||||
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
strrstr (static)
|
|
||||||
|
|
||||||
Backwards search for p_pcPattern in p_pcString
|
|
||||||
Based on: https://stackoverflow.com/a/1634398/2778898
|
|
||||||
|
|
||||||
*/
|
|
||||||
const char* strrstr(const char*__restrict p_pcString, const char*__restrict p_pcPattern)
|
|
||||||
{
|
|
||||||
|
|
||||||
const char* pcResult = 0;
|
|
||||||
|
|
||||||
size_t stStringLength = (p_pcString ? strlen(p_pcString) : 0);
|
|
||||||
size_t stPatternLength = (p_pcPattern ? strlen(p_pcPattern) : 0);
|
|
||||||
|
|
||||||
if ((stStringLength) &&
|
|
||||||
(stPatternLength) &&
|
|
||||||
(stPatternLength <= stStringLength))
|
|
||||||
{
|
|
||||||
// Pattern is shorter or has the same length tham the string
|
|
||||||
|
|
||||||
for (const char* s = (p_pcString + stStringLength - stPatternLength); s >= p_pcString; --s)
|
|
||||||
{
|
|
||||||
if (0 == strncmp(s, p_pcPattern, stPatternLength))
|
|
||||||
{
|
|
||||||
pcResult = s;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pcResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // anonymous
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace esp8266
|
namespace esp8266
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ namespace MDNSImplementation
|
|||||||
//#define ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE
|
//#define ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE
|
||||||
|
|
||||||
// Enable/disable debug trace macros
|
// Enable/disable debug trace macros
|
||||||
#ifdef DEBUG_ESP_MDNS_RESPONDER
|
#if defined(DEBUG_ESP_PORT) && defined(DEBUG_ESP_MDNS_RESPONDER)
|
||||||
#define DEBUG_ESP_MDNS_INFO
|
#define DEBUG_ESP_MDNS_INFO
|
||||||
#define DEBUG_ESP_MDNS_ERR
|
#define DEBUG_ESP_MDNS_ERR
|
||||||
#define DEBUG_ESP_MDNS_TX
|
#define DEBUG_ESP_MDNS_TX
|
||||||
@ -64,22 +64,22 @@ namespace MDNSImplementation
|
|||||||
#ifdef DEBUG_ESP_MDNS_INFO
|
#ifdef DEBUG_ESP_MDNS_INFO
|
||||||
#define DEBUG_EX_INFO(A) A
|
#define DEBUG_EX_INFO(A) A
|
||||||
#else
|
#else
|
||||||
#define DEBUG_EX_INFO(A) do { (void)0; } while (0)
|
#define DEBUG_EX_INFO(A)
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG_ESP_MDNS_ERR
|
#ifdef DEBUG_ESP_MDNS_ERR
|
||||||
#define DEBUG_EX_ERR(A) A
|
#define DEBUG_EX_ERR(A) A
|
||||||
#else
|
#else
|
||||||
#define DEBUG_EX_ERR(A) do { (void)0; } while (0)
|
#define DEBUG_EX_ERR(A)
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG_ESP_MDNS_TX
|
#ifdef DEBUG_ESP_MDNS_TX
|
||||||
#define DEBUG_EX_TX(A) A
|
#define DEBUG_EX_TX(A) A
|
||||||
#else
|
#else
|
||||||
#define DEBUG_EX_TX(A) do { (void)0; } while (0)
|
#define DEBUG_EX_TX(A)
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG_ESP_MDNS_RX
|
#ifdef DEBUG_ESP_MDNS_RX
|
||||||
#define DEBUG_EX_RX(A) A
|
#define DEBUG_EX_RX(A) A
|
||||||
#else
|
#else
|
||||||
#define DEBUG_EX_RX(A) do { (void)0; } while (0)
|
#define DEBUG_EX_RX(A)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_ESP_PORT
|
#ifdef DEBUG_ESP_PORT
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "ESP8266mDNS.h"
|
||||||
#include "LEAmDNS_Priv.h"
|
#include "LEAmDNS_Priv.h"
|
||||||
#include "LEAmDNS_lwIPdefs.h"
|
#include "LEAmDNS_lwIPdefs.h"
|
||||||
|
|
||||||
@ -787,7 +788,7 @@ bool MDNSResponder::stcMDNS_RRDomain::compare(const stcMDNS_RRDomain& p_Other) c
|
|||||||
{
|
{
|
||||||
if (*((unsigned char*)pT)) // Not 0
|
if (*((unsigned char*)pT)) // Not 0
|
||||||
{
|
{
|
||||||
pT += (1 + * ((unsigned char*)pT)); // Shift by length byte and lenght
|
pT += (1 + * ((unsigned char*)pT)); // Shift by length byte and length
|
||||||
pO += (1 + * ((unsigned char*)pO));
|
pO += (1 + * ((unsigned char*)pO));
|
||||||
}
|
}
|
||||||
else // Is 0 -> Successfully reached the end
|
else // Is 0 -> Successfully reached the end
|
||||||
|
@ -26,6 +26,7 @@ extern "C" {
|
|||||||
#include "user_interface.h"
|
#include "user_interface.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "ESP8266mDNS.h"
|
||||||
#include "LEAmDNS_lwIPdefs.h"
|
#include "LEAmDNS_lwIPdefs.h"
|
||||||
#include "LEAmDNS_Priv.h"
|
#include "LEAmDNS_Priv.h"
|
||||||
|
|
||||||
|
@ -295,6 +295,12 @@ OPT_ARDUINO_LIBS ?= $(addprefix ../../libraries/,\
|
|||||||
LEAmDNS_Structs.cpp \
|
LEAmDNS_Structs.cpp \
|
||||||
LEAmDNS_Transfer.cpp \
|
LEAmDNS_Transfer.cpp \
|
||||||
ESP8266mDNS.cpp \
|
ESP8266mDNS.cpp \
|
||||||
|
LEAmDNS2Host.cpp \
|
||||||
|
LEAmDNS2Host_Control.cpp \
|
||||||
|
LEAmDNS2Host_Debug.cpp \
|
||||||
|
LEAmDNS2Host_Structs.cpp \
|
||||||
|
LEAmDNS2Host_Transfer.cpp \
|
||||||
|
LEAmDNS2_Backbone.cpp \
|
||||||
) \
|
) \
|
||||||
ArduinoOTA/ArduinoOTA.cpp \
|
ArduinoOTA/ArduinoOTA.cpp \
|
||||||
DNSServer/src/DNSServer.cpp \
|
DNSServer/src/DNSServer.cpp \
|
||||||
|
@ -270,3 +270,10 @@ extern "C" void configTime(long timezone, int daylightOffset_sec,
|
|||||||
#include "pins_arduino.h"
|
#include "pins_arduino.h"
|
||||||
|
|
||||||
#endif /* Arduino_h */
|
#endif /* Arduino_h */
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
#include <WString.h>
|
||||||
|
#include <map>
|
||||||
|
#define MOCKARGS 1
|
||||||
|
extern std::map<String,String> mockArgs;
|
||||||
|
#endif
|
||||||
|
@ -56,6 +56,8 @@ const char* fspath = nullptr;
|
|||||||
|
|
||||||
static struct termios initial_settings;
|
static struct termios initial_settings;
|
||||||
|
|
||||||
|
std::map<String,String> mockArgs;
|
||||||
|
|
||||||
int mockverbose (const char* fmt, ...)
|
int mockverbose (const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@ -135,6 +137,8 @@ void help (const char* argv0, int exitcode)
|
|||||||
"\t-S - spiffs size in KBytes (default: %zd)\n"
|
"\t-S - spiffs size in KBytes (default: %zd)\n"
|
||||||
"\t-L - littlefs size in KBytes (default: %zd)\n"
|
"\t-L - littlefs size in KBytes (default: %zd)\n"
|
||||||
"\t (spiffs, littlefs: negative value will force mismatched size)\n"
|
"\t (spiffs, littlefs: negative value will force mismatched size)\n"
|
||||||
|
"\t-K - key\n"
|
||||||
|
"\t-V - value\n"
|
||||||
"\tgeneral:\n"
|
"\tgeneral:\n"
|
||||||
"\t-c - ignore CTRL-C (send it via Serial)\n"
|
"\t-c - ignore CTRL-C (send it via Serial)\n"
|
||||||
"\t-f - no throttle (possibly 100%%CPU)\n"
|
"\t-f - no throttle (possibly 100%%CPU)\n"
|
||||||
@ -158,6 +162,8 @@ static struct option options[] =
|
|||||||
{ "spiffskb", required_argument, NULL, 'S' },
|
{ "spiffskb", required_argument, NULL, 'S' },
|
||||||
{ "littlefskb", required_argument, NULL, 'L' },
|
{ "littlefskb", required_argument, NULL, 'L' },
|
||||||
{ "portshifter", required_argument, NULL, 's' },
|
{ "portshifter", required_argument, NULL, 's' },
|
||||||
|
{ "key", required_argument, NULL, 'K' },
|
||||||
|
{ "value", required_argument, NULL, 'V' },
|
||||||
{ "once", no_argument, NULL, '1' },
|
{ "once", no_argument, NULL, '1' },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -209,10 +215,11 @@ int main (int argc, char* const argv [])
|
|||||||
mock_port_shifter = 0;
|
mock_port_shifter = 0;
|
||||||
else
|
else
|
||||||
mock_port_shifter = MOCK_PORT_SHIFTER;
|
mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||||
|
String key;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:1", options, NULL);
|
int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:1K:V:", options, NULL);
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
break;
|
break;
|
||||||
switch (n)
|
switch (n)
|
||||||
@ -253,6 +260,12 @@ int main (int argc, char* const argv [])
|
|||||||
case 'T':
|
case 'T':
|
||||||
serial_timestamp = true;
|
serial_timestamp = true;
|
||||||
break;
|
break;
|
||||||
|
case 'K':
|
||||||
|
key = optarg;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
mockArgs[key] = optarg;
|
||||||
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
run_once = true;
|
run_once = true;
|
||||||
break;
|
break;
|
||||||
|
@ -29,11 +29,6 @@
|
|||||||
DEALINGS WITH THE SOFTWARE.
|
DEALINGS WITH THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
|
||||||
#include "lwip/udp.h"
|
|
||||||
#include "lwip/inet.h"
|
|
||||||
#include "lwip/igmp.h"
|
|
||||||
#include "lwip/mem.h"
|
|
||||||
#include <include/UdpContext.h>
|
#include <include/UdpContext.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
#include <AddrList.h>
|
#include <AddrList.h>
|
||||||
#include <lwip/netif.h>
|
|
||||||
|
#include "MocklwIP.h"
|
||||||
|
|
||||||
esp8266::AddressListImplementation::AddressList addrList;
|
esp8266::AddressListImplementation::AddressList addrList;
|
||||||
|
|
||||||
|
15
tests/host/common/MocklwIP.h
Normal file
15
tests/host/common/MocklwIP.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#ifndef __MOCKLWIP_H
|
||||||
|
#define __MOCKLWIP_H
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
#include <user_interface.h>
|
||||||
|
#include <lwip/netif.h>
|
||||||
|
|
||||||
|
extern netif netif0;
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
#endif // __MOCKLWIP_H
|
@ -23,6 +23,10 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include <MocklwIP.h>
|
||||||
|
#include <IPAddress.h>
|
||||||
|
#include <PolledTimeout.h>
|
||||||
|
|
||||||
class UdpContext;
|
class UdpContext;
|
||||||
|
|
||||||
#define GET_IP_HDR(pb) reinterpret_cast<ip_hdr*>(((uint8_t*)((pb)->payload)) - UDP_HLEN - IP_HLEN);
|
#define GET_IP_HDR(pb) reinterpret_cast<ip_hdr*>(((uint8_t*)((pb)->payload)) - UDP_HLEN - IP_HLEN);
|
||||||
@ -52,7 +56,8 @@ public:
|
|||||||
|
|
||||||
void unref()
|
void unref()
|
||||||
{
|
{
|
||||||
if(--_refcnt == 0) {
|
if (--_refcnt == 0)
|
||||||
|
{
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +113,8 @@ public:
|
|||||||
|
|
||||||
// warning: handler is called from tcp stack context
|
// warning: handler is called from tcp stack context
|
||||||
// esp_yield and non-reentrant functions which depend on it will fail
|
// esp_yield and non-reentrant functions which depend on it will fail
|
||||||
void onRx(rxhandler_t handler) {
|
void onRx(rxhandler_t handler)
|
||||||
|
{
|
||||||
_on_rx = handler;
|
_on_rx = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,11 +138,12 @@ public:
|
|||||||
mockUDPSwallow(pos, _inbuf, _inbufsize);
|
mockUDPSwallow(pos, _inbuf, _inbufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValidOffset(const size_t pos) const {
|
bool isValidOffset(const size_t pos) const
|
||||||
|
{
|
||||||
return pos <= _inbufsize;
|
return pos <= _inbufsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getRemoteAddress()
|
IPAddress getRemoteAddress()
|
||||||
{
|
{
|
||||||
return _dst.addr;
|
return _dst.addr;
|
||||||
}
|
}
|
||||||
@ -146,7 +153,7 @@ public:
|
|||||||
return _dstport;
|
return _dstport;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getDestAddress()
|
IPAddress getDestAddress()
|
||||||
{
|
{
|
||||||
mockverbose("TODO: implement UDP getDestAddress\n");
|
mockverbose("TODO: implement UDP getDestAddress\n");
|
||||||
return 0; //ip_hdr* iphdr = GET_IP_HDR(_rx_buf);
|
return 0; //ip_hdr* iphdr = GET_IP_HDR(_rx_buf);
|
||||||
@ -208,13 +215,37 @@ public:
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool send (ip_addr_t* addr = 0, uint16_t port = 0)
|
err_t trySend(ip_addr_t* addr = 0, uint16_t port = 0, bool keepBuffer = true)
|
||||||
{
|
{
|
||||||
uint32_t dst = addr ? addr->addr : _dst.addr;
|
uint32_t dst = addr ? addr->addr : _dst.addr;
|
||||||
uint16_t dstport = port ? : _dstport;
|
uint16_t dstport = port ? : _dstport;
|
||||||
size_t ret = mockUDPWrite(_sock, (const uint8_t*)_outbuf, _outbufsize, _timeout_ms, dst, dstport);
|
size_t wrt = mockUDPWrite(_sock, (const uint8_t*)_outbuf, _outbufsize, _timeout_ms, dst, dstport);
|
||||||
|
err_t ret = _outbufsize ? ERR_OK : ERR_ABRT;
|
||||||
|
if (!keepBuffer || wrt == _outbufsize)
|
||||||
|
cancelBuffer();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cancelBuffer()
|
||||||
|
{
|
||||||
_outbufsize = 0;
|
_outbufsize = 0;
|
||||||
return ret > 0;
|
}
|
||||||
|
|
||||||
|
bool send(ip_addr_t* addr = 0, uint16_t port = 0)
|
||||||
|
{
|
||||||
|
return trySend(addr, port, false) == ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sendTimeout(ip_addr_t* addr, uint16_t port,
|
||||||
|
esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
|
||||||
|
{
|
||||||
|
err_t err;
|
||||||
|
esp8266::polledTimeout::oneShotFastMs timeout(timeoutMs);
|
||||||
|
while (((err = trySend(addr, port)) != ERR_OK) && !timeout)
|
||||||
|
delay(0);
|
||||||
|
if (err != ERR_OK)
|
||||||
|
cancelBuffer();
|
||||||
|
return err == ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mock_cb(void)
|
void mock_cb(void)
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "MocklwIP.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -138,6 +139,7 @@ extern "C"
|
|||||||
|
|
||||||
if (host_interface)
|
if (host_interface)
|
||||||
mockverbose("host: looking for interface '%s':\n", host_interface);
|
mockverbose("host: looking for interface '%s':\n", host_interface);
|
||||||
|
|
||||||
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
|
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
|
||||||
{
|
{
|
||||||
mockverbose("host: interface: %s", ifa->ifa_name);
|
mockverbose("host: interface: %s", ifa->ifa_name);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user