Skip to content

LEAmDNS v2 (optional) from @LaborEtArs #7281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cores/esp8266/IPAddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#define CONST /* nothing: lwIP-v1 does not use const */
#define ip4_addr_netcmp ip_addr_netcmp
#define netif_dhcp_data(netif) ((netif)->dhcp)
#define netif_get_index(netif) ((u8_t)((netif)->num + 1))
#else // lwIP-v2+
#define CONST const
#if !LWIP_IPV6
Expand Down
149 changes: 149 additions & 0 deletions libraries/ESP8266mDNS/examples/LEAmDNS/TwoInterfaces/TwoInterfaces.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@

#include <Arduino.h>
#include <PolledTimeout.h>

#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>

#ifndef STASSID
#define STASSID "ssid"
#define STAPSK "12345678"
#endif

#ifndef APSSID
#define APSSID "espap"
#define APPSK "12345678"
#endif

// uses API MDNSApiVersion::LEAv2

clsMDNSHost mDNSHost_AP;
clsMDNSHost mDNSHost_STA;
ESP8266WebServer server(80);

void connectToWiFi(const char* p_pcSSID,
const char* p_pcPWD,
uint32_t p_u32Timeout = 20) {
WiFi.begin(p_pcSSID, p_pcPWD);
Serial.println("");

// Wait for connection
uint8 u8Tries = p_u32Timeout;
while ((WiFi.status() != WL_CONNECTED) &&
(u8Tries--)) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.print("Connected to ");
Serial.println(p_pcSSID);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
} else {
Serial.printf("FAILED to connect to '%s'!\n", p_pcSSID);
}
}

void setup(void) {
Serial.begin(115200);
Serial.setDebugOutput(false);
delay(2000);
Serial.printf("\nStart\n");

// Setup WiFi and AP
WiFi.setAutoConnect(false);
WiFi.mode(WIFI_AP_STA);
WiFi.softAP(APSSID, APPSK);
Serial.print("Created AP ");
Serial.println("ESP8266");
Serial.print("AP-IP address: ");
Serial.println(WiFi.softAPIP());

if (mDNSHost_AP.begin("ESP8266", WIFI_AP, [](clsMDNSHost & p_rMDNSHost,
const char* p_pcDomainName,
bool p_bProbeResult)->void {
Serial.printf("mDNSHost_AP::ProbeResultCallback: '%s' is %s\n", p_pcDomainName, (p_bProbeResult ? "FREE" : "USED!"));

// Unattended added service
p_rMDNSHost.addService(0, "http", "tcp", 80);
})) {
Serial.println("mDNS-AP started");
} else {
Serial.println("FAILED to start mDNS-AP");
}

// Connect to WiFi network, with WRONG password (timeout 5 seconds)
// (good password will be given in `loop()`)
connectToWiFi(STASSID, "WRONG_PW", 5);

if (mDNSHost_STA.begin("esp8266", WIFI_STA, [](clsMDNSHost & p_rMDNSHost,
const char* p_pcDomainName,
bool p_bProbeResult)->void {
Serial.printf("mDNSHost_STA::ProbeResultCallback: '%s' is %s\n", p_pcDomainName, (p_bProbeResult ? "FREE" : "USED!"));
if (p_bProbeResult) {
p_rMDNSHost.addService("LEA_Weather", "http", "tcp", 80, [](clsMDNSHost::clsService & p_rService,
const char* p_pcInstanceName,
bool p_bProbeResult)->void {
Serial.printf("mDNSHost_STA::HTTP-Service::ProbeResultCallback: '%s' is %s\n", p_pcInstanceName, (p_bProbeResult ? "FREE" : "USED!"));
if (p_bProbeResult) {
if (!p_rService.addServiceTxt("path", "/")) {
Serial.println("FAILED to add service TXT item!");
}
p_rService.setDynamicServiceTxtCallback([](clsMDNSHost::clsService & p_rService)->void {
Serial.printf("mDNSHost_STA::HTTP-Service::DynamicTXTCallback\n");

p_rService.addDynamicServiceTxt("user", "admin");
static uint32_t u32Counter = 0;
p_rService.addDynamicServiceTxt("cnt", ++u32Counter);
});
} else {
if (p_rService.indexInstanceName()) {
Serial.printf("Changed service instance name to '%s'\n", p_rService.instanceName());
} else {
Serial.println("FAILED to index service instance name!");
}
}
});

// Unattended added service
p_rMDNSHost.addService("MQTTInstance", "mqtt", "tcp", 1883);
} else {
p_rMDNSHost.indexHostName();
}
})) {
Serial.println("mDNS-STA started");
} else {
Serial.println("FAILED to start mDNS-STA");
}

// Non-synchronized added service
mDNSHost_STA.addService(0, "test", "tcp", 999);

// Setup HTTP server
server.on("/", [](void) {
Serial.println("server.on");
server.send(200, "text/plain", "test");
});
server.begin();
Serial.println("HTTP server started");
}

void loop(void) {
server.handleClient();
mDNSHost_AP.update();
mDNSHost_STA.update();

static esp8266::polledTimeout::oneShotMs timer2(esp8266::polledTimeout::oneShotMs::alwaysExpired);
if (timer2) {
Serial.println("FIX PASSWORD");
connectToWiFi(STASSID, STAPSK);

timer2.reset(esp8266::polledTimeout::oneShotMs::neverExpires);
}
}





241 changes: 241 additions & 0 deletions libraries/ESP8266mDNS/examples/LEAmDNS/mDNS_Clock_v2/mDNS_Clock_v2.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
/*
ESP8266 mDNS responder clock

This example demonstrates two features of the LEA clsMDNSHost:
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 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 negociated. Keep an
eye to 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 installed also 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 <time.h>

// uses API MDNSApiVersion::LEAv2

/*
Include the clsMDNSHost (the library needs to be included also)
As LEA clsMDNSHost is experimantal in the ESP8266 environment currently, the
legacy clsMDNSHost is defaulted in th include file.
There are two ways to access LEA clsMDNSHost:
1. Prepend every declaration and call to global declarations or functions with the namespace, like:
'LEAmDNS::clsMDNSHost::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>
/*
Global defines and vars
*/


#define TIMEZONE_OFFSET 1 // CET
#define DST_OFFSET 1 // CEST
#define UPDATE_CYCLE (1 * 1000) // every second

#define SERVICE_PORT 80 // HTTP port

#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

clsMDNSHost responder; // MDNS responder
bool bHostDomainConfirmed = false; // Flags the confirmation of the host domain
clsMDNSHost::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 responder.announce().

*/
void MDNSDynamicServiceTxtCallback(const clsMDNSHost::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 = "<!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.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 'esp8266'
if (responder.begin("ESP8266", WIFI_STA, [](clsMDNSHost & p_rMDNSHost,
const char* p_pcDomainName,
bool p_bProbeResult)->void {
Serial.printf("mDNSHost_AP::ProbeResultCallback: '%s' is %s\n", p_pcDomainName, (p_bProbeResult ? "FREE" : "USED!"));
// Unattended added service
p_rMDNSHost.addService(0, "http", "tcp", 80);
})) {
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
responder.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
responder.announce();
}
}
}
Loading