Added Software

This commit is contained in:
Joachim Hummel
2022-06-19 11:10:04 +00:00
parent c729e2062b
commit e76db08b77
199 changed files with 69643 additions and 0 deletions

View File

@ -0,0 +1,268 @@
/*
ESP8266 mDNS responder clock
This example demonstrates two features of the LEA MDNSResponder:
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>
#include <PolledTimeout.h>
#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 SERVICE_PORT 80 // HTTP port
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
char* pcHostDomain = 0; // Negociated host domain
bool bHostDomainConfirmed = false; // Flags the confirmation of the host domain
MDNSResponder::hMDNSService 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 MDNS.announce().
*/
void MDNSDynamicServiceTxtCallback(const MDNSResponder::hMDNSService p_hService) {
Serial.println("MDNSDynamicServiceTxtCallback");
if (hMDNSService == p_hService) {
Serial.printf("Updating curtime TXT item to: %s\n", getTimeString());
MDNS.addDynamicServiceTxt(p_hService, "curtime", getTimeString());
}
}
/*
MDNSProbeResultCallback
Probe result callback for the host domain.
If the domain is free, the host domain is set and the clock service is
added.
If the domain is already used, a new name is created and the probing is
restarted via p_pMDNSResponder->setHostname().
*/
void hostProbeResult(String p_pcDomainName, bool p_bProbeResult) {
Serial.println("MDNSProbeResultCallback");
Serial.printf("MDNSProbeResultCallback: 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 'clock.tcp' service to port 'SERVICE_PORT', using the host domain as instance domain
hMDNSService = MDNS.addService(0, "espclk", "tcp", SERVICE_PORT);
if (hMDNSService) {
// Add a simple static MDNS service TXT item
MDNS.addServiceTxt(hMDNSService, "port#", SERVICE_PORT);
// Set the callback function for dynamic service TXTs
MDNS.setDynamicServiceTxtCallback(MDNSDynamicServiceTxtCallback);
}
}
}
} else {
// Change hostname, use '-' as divider between base name and index
if (MDNSResponder::indexDomain(pcHostDomain, "-", 0)) {
MDNS.setHostname(pcHostDomain);
} else {
Serial.println("MDNSProbeResultCallback: FAILED to update hostname!");
}
}
}
/*
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
MDNS.setHostProbeResultCallback(hostProbeResult);
// Init the (currently empty) host domain string with 'esp8266'
if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) ||
(!MDNS.begin(pcHostDomain))) {
Serial.println("Error setting up MDNS responder!");
while (1) { // STOP
delay(1000);
}
}
Serial.println("MDNS responder started");
// 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
MDNS.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
MDNS.announce();
}
}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,270 @@
/*
ESP8266 mDNS Responder Service Monitor
This example demonstrates two features of the LEA MDNSResponder:
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.
*/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
/*
Global defines and vars
*/
#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;
char* pcHostDomain = 0; // Negociated host domain
bool bHostDomainConfirmed = false; // Flags the confirmation of the host domain
MDNSResponder::hMDNSService hMDNSService = 0; // The handle of the http service in the MDNS responder
MDNSResponder::hMDNSServiceQuery 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;
}
/*
MDNSServiceQueryCallback
*/
void MDNSServiceQueryCallback(MDNSResponder::MDNSServiceInfo serviceInfo, MDNSResponder::AnswerType answerType, bool p_bSetContent) {
String answerInfo;
switch (answerType) {
case MDNSResponder::AnswerType::ServiceDomain :
answerInfo = "ServiceDomain " + String(serviceInfo.serviceDomain());
break;
case MDNSResponder::AnswerType::HostDomainAndPort :
answerInfo = "HostDomainAndPort " + String(serviceInfo.hostDomain()) + ":" + String(serviceInfo.hostPort());
break;
case MDNSResponder::AnswerType::IP4Address :
answerInfo = "IP4Address ";
for (IPAddress ip : serviceInfo.IP4Adresses()) {
answerInfo += "- " + ip.toString();
};
break;
case MDNSResponder::AnswerType::Txt :
answerInfo = "TXT " + String(serviceInfo.strKeyValue());
for (auto kv : serviceInfo.keyValues()) {
answerInfo += "\nkv : " + String(kv.first) + " : " + String(kv.second);
}
break;
default :
answerInfo = "Unknown Answertype";
}
Serial.printf("Answer %s %s\n", answerInfo.c_str(), p_bSetContent ? "Modified" : "Deleted");
}
/*
MDNSServiceProbeResultCallback
Probe result callback for Services
*/
void serviceProbeResult(String p_pcServiceName,
const MDNSResponder::hMDNSService p_hMDNSService,
bool p_bProbeResult) {
(void) p_hMDNSService;
Serial.printf("MDNSServiceProbeResultCallback: Service %s probe %s\n", p_pcServiceName.c_str(), (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_pMDNSResponder->setHostname().
*/
void hostProbeResult(String p_pcDomainName, bool p_bProbeResult) {
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);
if (hMDNSService) {
MDNS.setServiceProbeResultCallback(hMDNSService, serviceProbeResult);
// Add some '_http._tcp' protocol specific MDNS service TXT items
// See: http://www.dns-sd.org/txtrecords.html#http
MDNS.addServiceTxt(hMDNSService, "user", "");
MDNS.addServiceTxt(hMDNSService, "password", "");
MDNS.addServiceTxt(hMDNSService, "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
if (MDNSResponder::indexDomain(pcHostDomain, "-", 0)) {
MDNS.setHostname(pcHostDomain);
} else {
Serial.println("MDNSProbeResultCallback: FAILED to update hostname!");
}
}
}
/*
HTTP request function (not found is handled by server)
*/
void handleHTTPRequest() {
Serial.println("");
Serial.println("HTTP Request");
IPAddress ip = WiFi.localIP();
String ipStr = ip.toString();
String s = "<!DOCTYPE HTML>\r\n<html><h3><head>Hello from ";
s += WiFi.hostname() + ".local at " + WiFi.localIP().toString() + "</h3></head>";
s += "<br/><h4>Local HTTP services are :</h4>";
s += "<ol>";
for (auto info : MDNS.answerInfo(hMDNSServiceQuery)) {
s += "<li>";
s += info.serviceDomain();
if (info.hostDomainAvailable()) {
s += "<br/>Hostname: ";
s += String(info.hostDomain());
s += (info.hostPortAvailable()) ? (":" + String(info.hostPort())) : "";
}
if (info.IP4AddressAvailable()) {
s += "<br/>IP4:";
for (auto ip : info.IP4Adresses()) {
s += " " + ip.toString();
}
}
if (info.txtAvailable()) {
s += "<br/>TXT:<br/>";
for (auto kv : info.keyValues()) {
s += "\t" + String(kv.first) + " : " + String(kv.second) + "<br/>";
}
}
s += "</li>";
}
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);
// 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());
// Setup HTTP server
server.on("/", handleHTTPRequest);
// Setup MDNS responders
MDNS.setHostProbeResultCallback(hostProbeResult);
// Init the (currently empty) host domain string with 'esp8266'
if ((!MDNSResponder::indexDomain(pcHostDomain, 0, "esp8266")) ||
(!MDNS.begin(pcHostDomain))) {
Serial.println(" Error setting up MDNS responder!");
while (1) { // STOP
delay(1000);
}
}
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();
}

View File

@ -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();
}

View File

@ -0,0 +1,248 @@
/**
@file OTA-mDNS-LittleFS.ino
@author Pascal Gollor (http://www.pgollor.de/cms/)
@date 2015-09-18
changelog:
2015-10-22:
- Use new ArduinoOTA library.
- loadConfig function can handle different line endings
- remove mDNS studd. ArduinoOTA handle it.
*/
#ifndef APSSID
#define APSSID "your-apssid"
#define APPSK "your-password"
#endif
#ifndef STASSID
#define STASSID "your-sta"
#define STAPSK "your-password"
#endif
// includes
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <FS.h>
#include <LittleFS.h>
#include <ArduinoOTA.h>
#include <ESP8266mDNS.h>
/**
@brief mDNS and OTA Constants
@{
*/
#define HOSTNAME "ESP8266-OTA-" ///< Hostname. The setup function adds the Chip ID at the end.
/// @}
/**
@brief Default WiFi connection information.
@{
*/
const char* ap_default_ssid = APSSID; ///< Default SSID.
const char* ap_default_psk = APPSK; ///< Default PSK.
/// @}
/// Uncomment the next line for verbose output over UART.
//#define SERIAL_VERBOSE
/**
@brief Read WiFi connection information from file system.
@param ssid String pointer for storing SSID.
@param pass String pointer for storing PSK.
@return True or False.
The config file have to containt the WiFi SSID in the first line
and the WiFi PSK in the second line.
Line seperator can be \r\n (CR LF) \r or \n.
*/
bool loadConfig(String *ssid, String *pass) {
// open file for reading.
File configFile = LittleFS.open("/cl_conf.txt", "r");
if (!configFile) {
Serial.println("Failed to open cl_conf.txt.");
return false;
}
// Read content from config file.
String content = configFile.readString();
configFile.close();
content.trim();
// Check if ther is a second line available.
int8_t pos = content.indexOf("\r\n");
uint8_t le = 2;
// check for linux and mac line ending.
if (pos == -1) {
le = 1;
pos = content.indexOf("\n");
if (pos == -1) {
pos = content.indexOf("\r");
}
}
// If there is no second line: Some information is missing.
if (pos == -1) {
Serial.println("Infvalid content.");
Serial.println(content);
return false;
}
// Store SSID and PSK into string vars.
*ssid = content.substring(0, pos);
*pass = content.substring(pos + le);
ssid->trim();
pass->trim();
#ifdef SERIAL_VERBOSE
Serial.println("----- file content -----");
Serial.println(content);
Serial.println("----- file content -----");
Serial.println("ssid: " + *ssid);
Serial.println("psk: " + *pass);
#endif
return true;
} // loadConfig
/**
@brief Save WiFi SSID and PSK to configuration file.
@param ssid SSID as string pointer.
@param pass PSK as string pointer,
@return True or False.
*/
bool saveConfig(String *ssid, String *pass) {
// Open config file for writing.
File configFile = LittleFS.open("/cl_conf.txt", "w");
if (!configFile) {
Serial.println("Failed to open cl_conf.txt for writing");
return false;
}
// Save SSID and PSK.
configFile.println(*ssid);
configFile.println(*pass);
configFile.close();
return true;
} // saveConfig
/**
@brief Arduino setup function.
*/
void setup() {
String station_ssid = "";
String station_psk = "";
Serial.begin(115200);
delay(100);
Serial.println("\r\n");
Serial.print("Chip ID: 0x");
Serial.println(ESP.getChipId(), HEX);
// Set Hostname.
String hostname(HOSTNAME);
hostname += String(ESP.getChipId(), HEX);
WiFi.hostname(hostname);
// Print hostname.
Serial.println("Hostname: " + hostname);
//Serial.println(WiFi.hostname());
// Initialize file system.
if (!LittleFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
// Load wifi connection information.
if (! loadConfig(&station_ssid, &station_psk)) {
station_ssid = STASSID;
station_psk = STAPSK;
Serial.println("No WiFi connection information available.");
}
// Check WiFi connection
// ... check mode
if (WiFi.getMode() != WIFI_STA) {
WiFi.mode(WIFI_STA);
delay(10);
}
// ... Compare file config with sdk config.
if (WiFi.SSID() != station_ssid || WiFi.psk() != station_psk) {
Serial.println("WiFi config changed.");
// ... Try to connect to WiFi station.
WiFi.begin(station_ssid.c_str(), station_psk.c_str());
// ... Pritn new SSID
Serial.print("new SSID: ");
Serial.println(WiFi.SSID());
// ... Uncomment this for debugging output.
//WiFi.printDiag(Serial);
} else {
// ... Begin with sdk config.
WiFi.begin();
}
Serial.println("Wait for WiFi connection.");
// ... Give ESP 10 seconds to connect to station.
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) {
Serial.write('.');
//Serial.print(WiFi.status());
delay(500);
}
Serial.println();
// Check connection
if (WiFi.status() == WL_CONNECTED) {
// ... print IP Address
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("Can not connect to WiFi station. Go into AP mode.");
// Go into software AP mode.
WiFi.mode(WIFI_AP);
delay(10);
WiFi.softAP(ap_default_ssid, ap_default_psk);
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP());
}
// Start OTA server.
ArduinoOTA.setHostname((const char *)hostname.c_str());
ArduinoOTA.begin();
}
/**
@brief Arduino loop function.
*/
void loop() {
// Handle OTA server.
ArduinoOTA.handle();
}

View File

@ -0,0 +1,2 @@
YOUR_SSID
YOUR_PSK

View File

@ -0,0 +1,80 @@
/*
ESP8266 mDNS-SD responder and query sample
This is an example of announcing and finding services.
Instructions:
- Update WiFi SSID and password as necessary.
- Flash the sketch to two ESP8266 boards
- The last one powered on should now find the other.
*/
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
char hostString[16] = {0};
void setup() {
Serial.begin(115200);
delay(100);
Serial.println("\r\nsetup()");
sprintf(hostString, "ESP_%06X", ESP.getChipId());
Serial.print("Hostname: ");
Serial.println(hostString);
WiFi.hostname(hostString);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (!MDNS.begin(hostString)) {
Serial.println("Error setting up MDNS responder!");
}
Serial.println("mDNS responder started");
MDNS.addService("esp", "tcp", 8080); // Announce esp tcp service on port 8080
Serial.println("Sending mDNS query");
int n = MDNS.queryService("esp", "tcp"); // Send out query for esp tcp services
Serial.println("mDNS query done");
if (n == 0) {
Serial.println("no services found");
} else {
Serial.print(n);
Serial.println(" service(s) found");
for (int i = 0; i < n; ++i) {
// Print details for each service found
Serial.print(i + 1);
Serial.print(": ");
Serial.print(MDNS.hostname(i));
Serial.print(" (");
Serial.print(MDNS.IP(i));
Serial.print(":");
Serial.print(MDNS.port(i));
Serial.println(")");
}
}
Serial.println();
Serial.println("loop() next");
}
void loop() {
// put your main code here, to run repeatedly:
MDNS.update();
}

View File

@ -0,0 +1,124 @@
/*
ESP8266 mDNS responder sample
This is an example of an HTTP server that is accessible
via http://esp8266.local URL thanks to mDNS responder.
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.
- Point your browser to http://esp8266.local, you should see a response.
*/
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
// TCP server at port 80 will respond to HTTP requests
WiFiServer server(80);
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());
// Set up mDNS responder:
// - first argument is the domain name, in this example
// the fully-qualified domain name is "esp8266.local"
// - second argument is the IP address to advertise
// we send our IP address on the WiFi network
if (!MDNS.begin("esp8266")) {
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
// Start TCP (HTTP) server
server.begin();
Serial.println("TCP server started");
// Add service to MDNS-SD
MDNS.addService("http", "tcp", 80);
}
void loop(void) {
MDNS.update();
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.println("");
Serial.println("New client");
// Wait for data from client to become available
while (client.connected() && !client.available()) {
delay(1);
}
// Read the first line of HTTP request
String req = client.readStringUntil('\r');
// First line of HTTP request looks like "GET /path HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
Serial.print("Request: ");
Serial.println(req);
client.flush();
String s;
if (req == "/") {
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
s += ipStr;
s += "</html>\r\n\r\n";
Serial.println("Sending 200");
} else {
s = "HTTP/1.1 404 Not Found\r\n\r\n";
Serial.println("Sending 404");
}
client.print(s);
Serial.println("Done with client");
}