Added Software
This commit is contained in:
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
YOUR_SSID
|
||||
YOUR_PSK
|
@ -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();
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
Reference in New Issue
Block a user