mirror of
				https://github.com/esp8266/Arduino.git
				synced 2025-10-28 17:15:26 +03:00 
			
		
		
		
	| @@ -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); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user