mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-06 05:21:22 +03:00
lwIP on ethernet: examples (#8395)
* ethernet: examples * remove duplicate * styling * fix comment restyle + comment eth.setdefault() * comment and add comments about eth.setDefault() * update comments when using interface::setDefault() * repair bad merge * fix default interface case * factorize * change comment
This commit is contained in:
parent
f5ef02d643
commit
5f2af1945b
@ -59,7 +59,17 @@ public:
|
||||
return IPAddress(ip4_addr_get_u32(ip_2_ip4(&_netif.gw)));
|
||||
}
|
||||
|
||||
void setDefault();
|
||||
// 1. Currently when no default is set, esp8266-Arduino uses the first
|
||||
// DHCP client interface receiving a valid address and gateway to
|
||||
// become the new lwIP default interface.
|
||||
// 2. Otherwise - when using static addresses - lwIP for every packets by
|
||||
// defaults selects automatically the best suited output interface
|
||||
// matching the destination address. If several interfaces match,
|
||||
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
|
||||
// checked first.
|
||||
// 3. Or, use `::setDefault(true)` to force using this interface's gateway
|
||||
// as default router.
|
||||
void setDefault(bool deflt = true);
|
||||
|
||||
// true if interface has a valid IPv4 address
|
||||
bool connected()
|
||||
@ -67,12 +77,18 @@ public:
|
||||
return !!ip4_addr_get_u32(ip_2_ip4(&_netif.ip_addr));
|
||||
}
|
||||
|
||||
bool routable()
|
||||
{
|
||||
return !ip_addr_isany(&_netif.gw);
|
||||
}
|
||||
|
||||
// ESP8266WiFi API compatibility
|
||||
|
||||
wl_status_t status();
|
||||
|
||||
protected:
|
||||
err_t netif_init();
|
||||
void check_route();
|
||||
void netif_status_callback();
|
||||
|
||||
static err_t netif_init_s(netif* netif);
|
||||
@ -184,10 +200,10 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
|
||||
return false;
|
||||
}
|
||||
|
||||
_netif.flags |= NETIF_FLAG_UP;
|
||||
|
||||
if (localIP().v4() == 0)
|
||||
{
|
||||
// IP not set, starting DHCP
|
||||
_netif.flags |= NETIF_FLAG_UP;
|
||||
switch (dhcp_start(&_netif))
|
||||
{
|
||||
case ERR_OK:
|
||||
@ -201,6 +217,12 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// IP is set, static config
|
||||
netif_set_link_up(&_netif);
|
||||
netif_set_up(&_netif);
|
||||
}
|
||||
|
||||
_started = true;
|
||||
|
||||
@ -301,17 +323,26 @@ err_t LwipIntfDev<RawDev>::netif_init()
|
||||
template<class RawDev>
|
||||
void LwipIntfDev<RawDev>::netif_status_callback()
|
||||
{
|
||||
check_route();
|
||||
if (connected())
|
||||
{
|
||||
if (_default || (netif_default == nullptr && !ip_addr_isany(&_netif.gw)))
|
||||
{
|
||||
// on user request,
|
||||
// or if there is no current default interface, but a gateway is valid
|
||||
netif_set_default(&_netif);
|
||||
}
|
||||
sntp_stop();
|
||||
sntp_init();
|
||||
}
|
||||
}
|
||||
|
||||
template<class RawDev>
|
||||
void LwipIntfDev<RawDev>::check_route()
|
||||
{
|
||||
if (connected())
|
||||
{
|
||||
if (_default || (netif_default == nullptr && routable()))
|
||||
{
|
||||
// on user request,
|
||||
// or if there is no current default interface, but our gateway is valid
|
||||
netif_set_default(&_netif);
|
||||
}
|
||||
}
|
||||
else if (netif_default == &_netif)
|
||||
{
|
||||
netif_set_default(nullptr);
|
||||
@ -386,13 +417,10 @@ err_t LwipIntfDev<RawDev>::handlePackets()
|
||||
}
|
||||
|
||||
template<class RawDev>
|
||||
void LwipIntfDev<RawDev>::setDefault()
|
||||
void LwipIntfDev<RawDev>::setDefault(bool deflt)
|
||||
{
|
||||
_default = true;
|
||||
if (connected())
|
||||
{
|
||||
netif_set_default(&_netif);
|
||||
}
|
||||
_default = deflt;
|
||||
check_route();
|
||||
}
|
||||
|
||||
#endif // _LWIPINTFDEV_H
|
||||
|
@ -1766,9 +1766,11 @@ namespace MDNSImplementation
|
||||
stcMDNS_RRAttributes attributes(DNS_RRTYPE_AAAA,
|
||||
((p_rSendParameter.m_bCacheFlush ? 0x8000 : 0)
|
||||
| DNS_RRCLASS_IN)); // Cache flush? & INternet
|
||||
bool bResult = ((_writeMDNSHostDomain(m_pcHostname, false, p_rSendParameter)) && // esp8266.local
|
||||
bool bResult
|
||||
= ((_writeMDNSHostDomain(m_pcHostname, false, p_rSendParameter)) && // esp8266.local
|
||||
(_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS
|
||||
(_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter)) && // TTL
|
||||
(_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter))
|
||||
&& // TTL
|
||||
(_write16(MDNS_IP6_SIZE, p_rSendParameter)) && // RDLength
|
||||
(false /*TODO: IP6 version of: _udpAppendBuffer((uint32_t)p_IPAddress, MDNS_IP4_SIZE)*/)); // RData
|
||||
|
||||
|
89
libraries/lwIP_Ethernet/examples/EthClient/EthClient.ino
Normal file
89
libraries/lwIP_Ethernet/examples/EthClient/EthClient.ino
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
This sketch establishes a TCP connection to a "quote of the day" service.
|
||||
It sends a "hello" message, and then prints received data.
|
||||
|
||||
This is Ethernet version of:
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino
|
||||
*/
|
||||
|
||||
#include <LwipEthernet.h>
|
||||
|
||||
Wiznet5500lwIP eth(/*SS*/ 16); // <== adapt to your hardware
|
||||
|
||||
const char* host = "djxmmx.net";
|
||||
const uint16_t port = 17;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
Serial.println("\nEthernet\n");
|
||||
|
||||
// 1. Currently when no default is set, esp8266-Arduino uses the first
|
||||
// DHCP client interface receiving a valid address and gateway to
|
||||
// become the new lwIP default interface.
|
||||
// 2. Otherwise - when using static addresses - lwIP for every packets by
|
||||
// defaults selects automatically the best suited output interface
|
||||
// matching the destination address. If several interfaces match,
|
||||
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
|
||||
// checked first.
|
||||
// 3. Or, use `::setDefault()` to force routing through this interface.
|
||||
// eth.setDefault(); // default route set through this interface
|
||||
|
||||
if (!ethInitDHCP(eth)) {
|
||||
Serial.printf("no hardware found\n");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
while (!eth.connected()) {
|
||||
Serial.printf(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.printf("Ethernet: IP Address: %s\n",
|
||||
eth.localIP().toString().c_str());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
Serial.print("connecting to ");
|
||||
Serial.print(host);
|
||||
Serial.print(':');
|
||||
Serial.println(port);
|
||||
|
||||
// Use WiFiClient class to create TCP connections
|
||||
// (this class could have been named TCPClient)
|
||||
WiFiClient client;
|
||||
if (!client.connect(host, port)) {
|
||||
Serial.println("connection failed");
|
||||
delay(5000);
|
||||
return;
|
||||
}
|
||||
|
||||
// This will send a string to the server
|
||||
Serial.println("sending data to server");
|
||||
if (client.connected()) { client.println("hello from ESP8266"); }
|
||||
|
||||
// wait for data to be available
|
||||
unsigned long timeout = millis();
|
||||
while (client.available() == 0) {
|
||||
if (millis() - timeout > 5000) {
|
||||
Serial.println(">>> Client Timeout !");
|
||||
client.stop();
|
||||
delay(60000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read all the lines of the reply from server and print them to Serial
|
||||
Serial.println("receiving from remote server");
|
||||
client.sendAll(Serial); // this peer closes once all data are sent
|
||||
|
||||
// Close the connection
|
||||
Serial.println();
|
||||
Serial.println("closing connection");
|
||||
client.stop();
|
||||
|
||||
delay(300000); // execute once every 5 minutes, don't flood remote service
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
This sketch establishes a TCP connection to a "quote of the day" service.
|
||||
It sends a "hello" message, and then prints received data.
|
||||
|
||||
This is Ethernet version of:
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino
|
||||
*/
|
||||
|
||||
#include <LwipEthernet.h>
|
||||
|
||||
#define LOCAL_IP IPAddress(192, 168, 0, 233)
|
||||
#define LOCAL_GW IPAddress(192, 168, 0, 254) // <== adapt to your network
|
||||
#define LOCAL_MASK IPAddress(255, 255, 255, 0)
|
||||
#define DNS IPAddress(8, 8, 8, 8)
|
||||
|
||||
Wiznet5500lwIP eth(/*SS*/ 16); // <== adapt to your hardware
|
||||
|
||||
const char* host = "djxmmx.net";
|
||||
const uint16_t port = 17;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
Serial.println("\nEthernet\n");
|
||||
|
||||
// 1. Currently when no default is set, esp8266-Arduino uses the first
|
||||
// DHCP client interface receiving a valid address and gateway to
|
||||
// become the new lwIP default interface.
|
||||
// 2. Otherwise - when using static addresses - lwIP for every packets by
|
||||
// defaults selects automatically the best suited output interface
|
||||
// matching the destination address. If several interfaces match,
|
||||
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
|
||||
// checked first.
|
||||
// 3. Or, use `::setDefault()` to force routing through this interface.
|
||||
// eth.setDefault(true); // default route set through this interface
|
||||
|
||||
if (!ethInitStatic(eth, LOCAL_IP, LOCAL_GW, LOCAL_MASK, DNS)) {
|
||||
// enabling debug message will show the real cause
|
||||
Serial.printf("no hardware found or bad network configuration\n");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.printf("Ethernet: IP Address: %s\n",
|
||||
eth.localIP().toString().c_str());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
Serial.print("connecting to ");
|
||||
Serial.print(host);
|
||||
Serial.print(':');
|
||||
Serial.println(port);
|
||||
|
||||
// Use WiFiClient class to create TCP connections
|
||||
// (this class could have been named TCPClient)
|
||||
WiFiClient client;
|
||||
if (!client.connect(host, port)) {
|
||||
Serial.println("connection failed");
|
||||
delay(5000);
|
||||
return;
|
||||
}
|
||||
|
||||
// This will send a string to the server
|
||||
Serial.println("sending data to server");
|
||||
if (client.connected()) {
|
||||
client.println("hello from ESP8266");
|
||||
}
|
||||
|
||||
// wait for data to be available
|
||||
unsigned long timeout = millis();
|
||||
while (client.available() == 0) {
|
||||
if (millis() - timeout > 5000) {
|
||||
Serial.println(">>> Client Timeout !");
|
||||
client.stop();
|
||||
delay(60000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read all the lines of the reply from server and print them to Serial
|
||||
Serial.println("receiving from remote server");
|
||||
client.sendAll(Serial); // this peer closes once all data are sent
|
||||
|
||||
// Close the connection
|
||||
Serial.println();
|
||||
Serial.println("closing connection");
|
||||
client.stop();
|
||||
|
||||
delay(600000); // execute once every 10 minutes, don't flood remote service
|
||||
}
|
@ -0,0 +1,238 @@
|
||||
// Example of the different modes of the X.509 validation options
|
||||
// in the WiFiClientBearSSL object
|
||||
//
|
||||
// Mar 2018 by Earle F. Philhower, III
|
||||
// Released to the public domain
|
||||
//
|
||||
// This is Ethernet version of:
|
||||
// https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino
|
||||
|
||||
#include <LwipEthernet.h>
|
||||
|
||||
Wiznet5500lwIP eth(/*SS*/ 16); // <== adapt to your hardware
|
||||
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <StackThunk.h>
|
||||
#include <time.h>
|
||||
#include "certs.h"
|
||||
|
||||
const char *path = "/";
|
||||
|
||||
// Set time via NTP, as required for x.509 validation
|
||||
void setClock() {
|
||||
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
|
||||
|
||||
Serial.print("Waiting for NTP time sync: ");
|
||||
time_t now = time(nullptr);
|
||||
while (now < 8 * 3600 * 2) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
now = time(nullptr);
|
||||
}
|
||||
Serial.println("");
|
||||
struct tm timeinfo;
|
||||
gmtime_r(&now, &timeinfo);
|
||||
Serial.print("Current time: ");
|
||||
Serial.print(asctime(&timeinfo));
|
||||
}
|
||||
|
||||
// Try and connect using a WiFiClientBearSSL to specified host:port and dump HTTP response
|
||||
void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_t port, const char *path) {
|
||||
if (!path) {
|
||||
path = "/";
|
||||
}
|
||||
|
||||
ESP.resetFreeContStack();
|
||||
uint32_t freeStackStart = ESP.getFreeContStack();
|
||||
Serial.printf("Trying: %s:443...", host);
|
||||
client->connect(host, port);
|
||||
if (!client->connected()) {
|
||||
Serial.printf("*** Can't connect. ***\n-------\n");
|
||||
return;
|
||||
}
|
||||
Serial.printf("Connected!\n-------\n");
|
||||
client->write("GET ");
|
||||
client->write(path);
|
||||
client->write(" HTTP/1.0\r\nHost: ");
|
||||
client->write(host);
|
||||
client->write("\r\nUser-Agent: ESP8266\r\n");
|
||||
client->write("\r\n");
|
||||
uint32_t to = millis() + 5000;
|
||||
if (client->connected()) {
|
||||
do {
|
||||
char tmp[32];
|
||||
memset(tmp, 0, 32);
|
||||
int rlen = client->read((uint8_t *)tmp, sizeof(tmp) - 1);
|
||||
yield();
|
||||
if (rlen < 0) {
|
||||
break;
|
||||
}
|
||||
// Only print out first line up to \r, then abort connection
|
||||
char *nl = strchr(tmp, '\r');
|
||||
if (nl) {
|
||||
*nl = 0;
|
||||
Serial.print(tmp);
|
||||
break;
|
||||
}
|
||||
Serial.print(tmp);
|
||||
} while (millis() < to);
|
||||
}
|
||||
client->stop();
|
||||
uint32_t freeStackEnd = ESP.getFreeContStack();
|
||||
Serial.printf("\nCONT stack used: %d\n", freeStackStart - freeStackEnd);
|
||||
Serial.printf("BSSL stack used: %d\n-------\n\n", stack_thunk_get_max_usage());
|
||||
}
|
||||
|
||||
void fetchNoConfig() {
|
||||
Serial.printf(R"EOF(
|
||||
If there are no CAs or insecure options specified, BearSSL will not connect.
|
||||
Expect the following call to fail as none have been configured.
|
||||
)EOF");
|
||||
BearSSL::WiFiClientSecure client;
|
||||
fetchURL(&client, gitlab_host, gitlab_port, path);
|
||||
}
|
||||
|
||||
void fetchInsecure() {
|
||||
Serial.printf(R"EOF(
|
||||
This is absolutely *insecure*, but you can tell BearSSL not to check the
|
||||
certificate of the server. In this mode it will accept ANY certificate,
|
||||
which is subject to man-in-the-middle (MITM) attacks.
|
||||
)EOF");
|
||||
BearSSL::WiFiClientSecure client;
|
||||
client.setInsecure();
|
||||
fetchURL(&client, gitlab_host, gitlab_port, path);
|
||||
}
|
||||
|
||||
void fetchFingerprint() {
|
||||
Serial.printf(R"EOF(
|
||||
The SHA-1 fingerprint of an X.509 certificate can be used to validate it
|
||||
instead of the while certificate. This is not nearly as secure as real
|
||||
X.509 validation, but is better than nothing. Also be aware that these
|
||||
fingerprints will change if anything changes in the certificate chain
|
||||
(i.e. re-generating the certificate for a new end date, any updates to
|
||||
the root authorities, etc.).
|
||||
)EOF");
|
||||
BearSSL::WiFiClientSecure client;
|
||||
client.setFingerprint(fingerprint_gitlab_com);
|
||||
fetchURL(&client, gitlab_host, gitlab_port, path);
|
||||
}
|
||||
|
||||
void fetchSelfSigned() {
|
||||
Serial.printf(R"EOF(
|
||||
It is also possible to accept *any* self-signed certificate. This is
|
||||
absolutely insecure as anyone can make a self-signed certificate.
|
||||
)EOF");
|
||||
BearSSL::WiFiClientSecure client;
|
||||
Serial.printf("First, try and connect to a badssl.com self-signed website (will fail):\n");
|
||||
fetchURL(&client, "self-signed.badssl.com", 443, "/");
|
||||
Serial.printf("Now we'll enable self-signed certs (will pass)\n");
|
||||
client.allowSelfSignedCerts();
|
||||
fetchURL(&client, "self-signed.badssl.com", 443, "/");
|
||||
}
|
||||
|
||||
void fetchKnownKey() {
|
||||
Serial.printf(R"EOF(
|
||||
The server certificate can be completely ignored and its public key
|
||||
hardcoded in your application. This should be secure as the public key
|
||||
needs to be paired with the private key of the site, which is obviously
|
||||
private and not shared. A MITM without the private key would not be
|
||||
able to establish communications.
|
||||
)EOF");
|
||||
BearSSL::WiFiClientSecure client;
|
||||
BearSSL::PublicKey key(pubkey_gitlab_com);
|
||||
client.setKnownKey(&key);
|
||||
fetchURL(&client, gitlab_host, gitlab_port, path);
|
||||
}
|
||||
|
||||
void fetchCertAuthority() {
|
||||
Serial.printf(R"EOF(
|
||||
A specific certification authority can be passed in and used to validate
|
||||
a chain of certificates from a given server. These will be validated
|
||||
using BearSSL's rules, which do NOT include certificate revocation lists.
|
||||
A specific server's certificate, or your own self-signed root certificate
|
||||
can also be used. ESP8266 time needs to be valid for checks to pass as
|
||||
BearSSL does verify the notValidBefore/After fields.
|
||||
)EOF");
|
||||
|
||||
BearSSL::WiFiClientSecure client;
|
||||
BearSSL::X509List cert(cert_USERTrust_RSA_Certification_Authority);
|
||||
client.setTrustAnchors(&cert);
|
||||
Serial.printf("Try validating without setting the time (should fail)\n");
|
||||
fetchURL(&client, gitlab_host, gitlab_port, path);
|
||||
|
||||
Serial.printf("Try again after setting NTP time (should pass)\n");
|
||||
setClock();
|
||||
fetchURL(&client, gitlab_host, gitlab_port, path);
|
||||
}
|
||||
|
||||
void fetchFaster() {
|
||||
Serial.printf(R"EOF(
|
||||
The ciphers used to set up the SSL connection can be configured to
|
||||
only support faster but less secure ciphers. If you care about security
|
||||
you won't want to do this. If you need to maximize battery life, these
|
||||
may make sense
|
||||
)EOF");
|
||||
BearSSL::WiFiClientSecure client;
|
||||
client.setInsecure();
|
||||
uint32_t now = millis();
|
||||
fetchURL(&client, gitlab_host, gitlab_port, path);
|
||||
uint32_t delta = millis() - now;
|
||||
client.setInsecure();
|
||||
client.setCiphersLessSecure();
|
||||
now = millis();
|
||||
fetchURL(&client, gitlab_host, gitlab_port, path);
|
||||
uint32_t delta2 = millis() - now;
|
||||
std::vector<uint16_t> myCustomList = { BR_TLS_RSA_WITH_AES_256_CBC_SHA256, BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA };
|
||||
client.setInsecure();
|
||||
client.setCiphers(myCustomList);
|
||||
now = millis();
|
||||
fetchURL(&client, gitlab_host, gitlab_port, path);
|
||||
uint32_t delta3 = millis() - now;
|
||||
Serial.printf("Using more secure: %dms\nUsing less secure ciphers: %dms\nUsing custom cipher list: %dms\n", delta, delta2, delta3);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.println("\nEthernet\n");
|
||||
|
||||
// 1. Currently when no default is set, esp8266-Arduino uses the first
|
||||
// DHCP client interface receiving a valid address and gateway to
|
||||
// become the new lwIP default interface.
|
||||
// 2. Otherwise - when using static addresses - lwIP for every packets by
|
||||
// defaults selects automatically the best suited output interface
|
||||
// matching the destination address. If several interfaces match,
|
||||
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
|
||||
// checked first.
|
||||
// 3. Or, use `::setDefault()` to force routing through this interface.
|
||||
// eth.setDefault(true); // default route set through this interface
|
||||
|
||||
if (!ethInitDHCP(eth)) {
|
||||
Serial.printf("no hardware found\n");
|
||||
while (1)
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
while (!eth.connected()) {
|
||||
Serial.printf(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.printf("Ethernet: IP Address: %s\n",
|
||||
eth.localIP().toString().c_str());
|
||||
|
||||
fetchNoConfig();
|
||||
fetchInsecure();
|
||||
fetchFingerprint();
|
||||
fetchSelfSigned();
|
||||
fetchKnownKey();
|
||||
fetchCertAuthority();
|
||||
fetchFaster();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
// Nothing to do here
|
||||
}
|
2
libraries/lwIP_Ethernet/examples/EthSSLValidation/certUpdate
Executable file
2
libraries/lwIP_Ethernet/examples/EthSSLValidation/certUpdate
Executable file
@ -0,0 +1,2 @@
|
||||
cd ${0%/*} 2>/dev/null
|
||||
python3 ../../../../tools/cert.py -s www.gitlab.com -n gitlab > certs.h
|
114
libraries/lwIP_Ethernet/examples/EthSSLValidation/certs.h
Normal file
114
libraries/lwIP_Ethernet/examples/EthSSLValidation/certs.h
Normal file
@ -0,0 +1,114 @@
|
||||
|
||||
// this file is autogenerated - any modification will be overwritten
|
||||
// unused symbols will not be linked in the final binary
|
||||
// generated on 2021-11-30 02:13:11
|
||||
// by ['../../../../tools/cert.py', '-s', 'www.gitlab.com', '-n', 'gitlab']
|
||||
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// certificate chain for www.gitlab.com:443
|
||||
|
||||
const char* gitlab_host = "www.gitlab.com";
|
||||
const uint16_t gitlab_port = 443;
|
||||
|
||||
// CN: gitlab.com => name: gitlab_com
|
||||
// not valid before: 2021-04-12 00:00:00
|
||||
// not valid after: 2022-05-11 23:59:59
|
||||
const char fingerprint_gitlab_com[] PROGMEM
|
||||
= "71:55:5e:29:68:99:43:98:c8:85:35:bd:4c:10:4c:f5:cf:17:09:e6";
|
||||
const char pubkey_gitlab_com[] PROGMEM = R"PUBKEY(
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1eeFy86Xbz3ygyCVprHp
|
||||
sPP3zyg0yldkIfqwjsXPH0b+KwQ85s3pzI/5+MVrR2/BGY4ed6mTZ6hvNwQJ2B0E
|
||||
sJrsTb2nuUsXQ0UVO4hvnZ7Dnx8r/bT1cndqa+Mn+bms8/TS4etP72+TLaORBRCz
|
||||
O4L1Hi8r61+zZLnP3DqqHeHAgl5wKHNYpx7yFFl2I71LuLH/pk2ICDBjaHwCIbRW
|
||||
u484no9s1c4VROxqMrQQ/wDMl80MiO9YeNQ5rBHfnabh4rFe9eb2Sd0H/DWBj3SO
|
||||
YBD0kiLI6b5CWYfA76pBSlZg7G3ledvQ+n9FEcS3EOCPKBBZqMDCzEahvHqwJ/r6
|
||||
pwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
)PUBKEY";
|
||||
|
||||
// http://crt.sectigo.com/SectigoRSADomainValidationSecureServerCA.crt
|
||||
// CN: Sectigo RSA Domain Validation Secure Server CA => name: Sectigo_RSA_Domain_Validation_Secure_Server_CA
|
||||
// not valid before: 2018-11-02 00:00:00
|
||||
// not valid after: 2030-12-31 23:59:59
|
||||
const char cert_Sectigo_RSA_Domain_Validation_Secure_Server_CA[] PROGMEM = R"CERT(
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGEzCCA/ugAwIBAgIQfVtRJrR2uhHbdBYLvFMNpzANBgkqhkiG9w0BAQwFADCB
|
||||
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
|
||||
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
|
||||
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx
|
||||
MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBjzELMAkGA1UEBhMCR0IxGzAZBgNV
|
||||
BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE
|
||||
ChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIFJTQSBEb21haW4g
|
||||
VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEA1nMz1tc8INAA0hdFuNY+B6I/x0HuMjDJsGz99J/LEpgPLT+N
|
||||
TQEMgg8Xf2Iu6bhIefsWg06t1zIlk7cHv7lQP6lMw0Aq6Tn/2YHKHxYyQdqAJrkj
|
||||
eocgHuP/IJo8lURvh3UGkEC0MpMWCRAIIz7S3YcPb11RFGoKacVPAXJpz9OTTG0E
|
||||
oKMbgn6xmrntxZ7FN3ifmgg0+1YuWMQJDgZkW7w33PGfKGioVrCSo1yfu4iYCBsk
|
||||
Haswha6vsC6eep3BwEIc4gLw6uBK0u+QDrTBQBbwb4VCSmT3pDCg/r8uoydajotY
|
||||
uK3DGReEY+1vVv2Dy2A0xHS+5p3b4eTlygxfFQIDAQABo4IBbjCCAWowHwYDVR0j
|
||||
BBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFI2MXsRUrYrhd+mb
|
||||
+ZsF4bgBjWHhMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G
|
||||
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAbBgNVHSAEFDASMAYGBFUdIAAw
|
||||
CAYGZ4EMAQIBMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0
|
||||
LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2Bggr
|
||||
BgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNv
|
||||
bS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDov
|
||||
L29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAMr9hvQ5Iw0/H
|
||||
ukdN+Jx4GQHcEx2Ab/zDcLRSmjEzmldS+zGea6TvVKqJjUAXaPgREHzSyrHxVYbH
|
||||
7rM2kYb2OVG/Rr8PoLq0935JxCo2F57kaDl6r5ROVm+yezu/Coa9zcV3HAO4OLGi
|
||||
H19+24rcRki2aArPsrW04jTkZ6k4Zgle0rj8nSg6F0AnwnJOKf0hPHzPE/uWLMUx
|
||||
RP0T7dWbqWlod3zu4f+k+TY4CFM5ooQ0nBnzvg6s1SQ36yOoeNDT5++SR2RiOSLv
|
||||
xvcRviKFxmZEJCaOEDKNyJOuB56DPi/Z+fVGjmO+wea03KbNIaiGCpXZLoUmGv38
|
||||
sbZXQm2V0TP2ORQGgkE49Y9Y3IBbpNV9lXj9p5v//cWoaasm56ekBYdbqbe4oyAL
|
||||
l6lFhd2zi+WJN44pDfwGF/Y4QA5C5BIG+3vzxhFoYt/jmPQT2BVPi7Fp2RBgvGQq
|
||||
6jG35LWjOhSbJuMLe/0CjraZwTiXWTb2qHSihrZe68Zk6s+go/lunrotEbaGmAhY
|
||||
LcmsJWTyXnW0OMGuf1pGg+pRyrbxmRE1a6Vqe8YAsOf4vmSyrcjC8azjUeqkk+B5
|
||||
yOGBQMkKW+ESPMFgKuOXwIlCypTPRpgSabuY0MLTDXJLR27lk8QyKGOHQ+SwMj4K
|
||||
00u/I5sUKUErmgQfky3xxzlIPK1aEn8=
|
||||
-----END CERTIFICATE-----
|
||||
)CERT";
|
||||
|
||||
// http://crt.usertrust.com/USERTrustRSAAddTrustCA.crt
|
||||
// CN: USERTrust RSA Certification Authority => name: USERTrust_RSA_Certification_Authority
|
||||
// not valid before: 2019-03-12 00:00:00
|
||||
// not valid after: 2028-12-31 23:59:59
|
||||
const char cert_USERTrust_RSA_Certification_Authority[] PROGMEM = R"CERT(
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFgTCCBGmgAwIBAgIQOXJEOvkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7
|
||||
MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD
|
||||
VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE
|
||||
AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4
|
||||
MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5
|
||||
MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO
|
||||
ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0
|
||||
aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sI
|
||||
s9CsVw127c0n00ytUINh4qogTQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnG
|
||||
vDoZtF+mvX2do2NCtnbyqTsrkfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQ
|
||||
Ijy8/hPwhxR79uQfjtTkUcYRZ0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfb
|
||||
IWax1Jt4A8BQOujM8Ny8nkz+rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0
|
||||
tyA9yn8iNK5+O2hmAUTnAU5GU5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97E
|
||||
xwzf4TKuzJM7UXiVZ4vuPVb+DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNV
|
||||
icQNwZNUMBkTrNN9N6frXTpsNVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5
|
||||
D9kCnusSTJV882sFqV4Wg8y4Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJ
|
||||
WBp/kjbmUZIO8yZ9HE0XvMnsQybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ
|
||||
5lhCLkMaTLTwJUdZ+gQek9QmRkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzG
|
||||
KAgEJTm4Diup8kyXHAc/DVL17e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSg
|
||||
EQojPpbxB+zirynvgqV/0DCktDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rID
|
||||
ZsswDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAG
|
||||
BgRVHSAAMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29t
|
||||
L0FBQUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggr
|
||||
BgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUA
|
||||
A4IBAQAYh1HcdCE9nIrgJ7cz0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+
|
||||
rvSNb3I8QzvAP+u431yqqcau8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+
|
||||
/czSAaF9ffgZGclCKxO/WIu6pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gA
|
||||
CiIDEOUMsfnNkjcZ7Tvx5Dq2+UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1F
|
||||
zZOFli9d31kWTz9RvdVFGD/tSo7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyA
|
||||
vGp4z7h/jnZymQyd/teRCBaho1+V
|
||||
-----END CERTIFICATE-----
|
||||
)CERT";
|
||||
|
||||
// end of certificate chain for www.gitlab.com:443
|
||||
////////////////////////////////////////////////////////////
|
@ -0,0 +1,282 @@
|
||||
/*
|
||||
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 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 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:
|
||||
- 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.
|
||||
|
||||
This is the Ethernet version of:
|
||||
https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266mDNS/examples/LEAmDNS/mDNS_Clock
|
||||
*/
|
||||
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <time.h>
|
||||
#include <PolledTimeout.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <LwipEthernet.h>
|
||||
|
||||
Wiznet5500lwIP eth(/*SS*/ 16); // <== adapt to your hardware
|
||||
|
||||
/*
|
||||
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; // Negotiated 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 uninitialized 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);
|
||||
|
||||
Serial.println("\nEthernet\n");
|
||||
|
||||
// 1. Currently when no default is set, esp8266-Arduino uses the first
|
||||
// DHCP client interface receiving a valid address and gateway to
|
||||
// become the new lwIP default interface.
|
||||
// 2. Otherwise - when using static addresses - lwIP for every packets by
|
||||
// defaults selects automatically the best suited output interface
|
||||
// matching the destination address. If several interfaces match,
|
||||
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
|
||||
// checked first.
|
||||
// 3. Or, use `::setDefault()` to force routing through this interface.
|
||||
// eth.setDefault(); // default route set through this interface
|
||||
|
||||
if (!ethInitDHCP(eth)) {
|
||||
Serial.printf("no hardware found\n");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
while (!eth.connected()) {
|
||||
Serial.printf(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.printf("Ethernet: IP Address: %s\n",
|
||||
eth.localIP().toString().c_str());
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
}
|
10
libraries/lwIP_Ethernet/library.properties
Normal file
10
libraries/lwIP_Ethernet/library.properties
Normal file
@ -0,0 +1,10 @@
|
||||
name=lwIP-Ethernet
|
||||
version=1
|
||||
author=esp8266/Arduino
|
||||
maintainer=esp8266/Arduino
|
||||
sentence=Helper for ethernet drivers
|
||||
paragraph=Example repository for Ethernet drivers
|
||||
category=Communication
|
||||
url=https://github.com/esp8266/Arduino
|
||||
architectures=esp8266
|
||||
dot_a_linkage=true
|
15
libraries/lwIP_Ethernet/src/LwipEthernet.cpp
Normal file
15
libraries/lwIP_Ethernet/src/LwipEthernet.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
#include <LwipEthernet.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#ifndef ETHERNET_SPI_CLOCK_DIV
|
||||
#define ETHERNET_SPI_CLOCK_DIV SPI_CLOCK_DIV4 // 4MHz (SPI.h)
|
||||
#endif
|
||||
|
||||
void SPI4EthInit()
|
||||
{
|
||||
SPI.begin();
|
||||
SPI.setClockDivider(ETHERNET_SPI_CLOCK_DIV);
|
||||
SPI.setBitOrder(MSBFIRST);
|
||||
SPI.setDataMode(SPI_MODE0);
|
||||
}
|
53
libraries/lwIP_Ethernet/src/LwipEthernet.h
Normal file
53
libraries/lwIP_Ethernet/src/LwipEthernet.h
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
#include <ESP8266WiFi.h> // tcp API
|
||||
#include <debug.h>
|
||||
|
||||
#include <W5100lwIP.h>
|
||||
#include <W5500lwIP.h>
|
||||
#include <ENC28J60lwIP.h>
|
||||
|
||||
// One of them is to be declared in the main sketch
|
||||
// and passed to ethInitDHCP() or ethInitStatic():
|
||||
// Wiznet5500lwIP eth(CSPIN);
|
||||
// Wiznet5100lwIP eth(CSPIN);
|
||||
// ENC28J60lwIP eth(CSPIN);
|
||||
|
||||
void SPI4EthInit();
|
||||
|
||||
template<class EthImpl>
|
||||
bool ethInitDHCP(EthImpl& eth)
|
||||
{
|
||||
SPI4EthInit();
|
||||
|
||||
if (!eth.begin())
|
||||
{
|
||||
// hardware not responding
|
||||
DEBUGV("ethInitDHCP: hardware not responding\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class EthImpl>
|
||||
bool ethInitStatic(EthImpl& eth, IPAddress IP, IPAddress gateway, IPAddress netmask, IPAddress dns1,
|
||||
IPAddress dns2 = IPADDR_NONE)
|
||||
{
|
||||
SPI4EthInit();
|
||||
|
||||
if (!eth.config(IP, gateway, netmask, dns1, dns2))
|
||||
{
|
||||
// invalid arguments
|
||||
DEBUGV("ethInitStatic: invalid arguments\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eth.begin())
|
||||
{
|
||||
// hardware not responding
|
||||
DEBUGV("ethInitStatic: hardware not responding\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
This sketch establishes a TCP connection to a "quote of the day" service.
|
||||
It sends a "hello" message, and then prints received data.
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <W5500lwIP.h>
|
||||
// or #include <W5100lwIP.h>
|
||||
// or #include <ENC28J60lwIP.h>
|
||||
|
||||
#include <WiFiClient.h> // WiFiClient (-> TCPClient)
|
||||
|
||||
const char* host = "djxmmx.net";
|
||||
const uint16_t port = 17;
|
||||
|
||||
using TCPClient = WiFiClient;
|
||||
|
||||
#define CSPIN 16 // wemos/lolin/nodemcu D0
|
||||
Wiznet5500lwIP eth(CSPIN);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
SPI.begin();
|
||||
SPI.setClockDivider(SPI_CLOCK_DIV4); // 4 MHz?
|
||||
SPI.setBitOrder(MSBFIRST);
|
||||
SPI.setDataMode(SPI_MODE0);
|
||||
eth.setDefault(); // use ethernet for default route
|
||||
if (!eth.begin()) {
|
||||
Serial.println("ethernet hardware not found ... sleeping");
|
||||
while (1) { delay(1000); }
|
||||
} else {
|
||||
Serial.print("connecting ethernet");
|
||||
while (!eth.connected()) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
Serial.println();
|
||||
Serial.print("ethernet IP address: ");
|
||||
Serial.println(eth.localIP());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
static bool wait = false;
|
||||
|
||||
Serial.print("connecting to ");
|
||||
Serial.print(host);
|
||||
Serial.print(':');
|
||||
Serial.println(port);
|
||||
|
||||
TCPClient client;
|
||||
if (!client.connect(host, port)) {
|
||||
Serial.println("connection failed");
|
||||
delay(5000);
|
||||
return;
|
||||
}
|
||||
|
||||
// This will send a string to the server
|
||||
Serial.println("sending data to server");
|
||||
if (client.connected()) { client.println("hello from ESP8266"); }
|
||||
|
||||
// wait for data to be available
|
||||
unsigned long timeout = millis();
|
||||
while (client.available() == 0) {
|
||||
if (millis() - timeout > 5000) {
|
||||
Serial.println(">>> Client Timeout !");
|
||||
client.stop();
|
||||
delay(60000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Read all the lines of the reply from server and print them to Serial
|
||||
Serial.println("receiving from remote server");
|
||||
// not testing 'client.connected()' since we do not need to send data here
|
||||
while (client.available()) {
|
||||
char ch = static_cast<char>(client.read());
|
||||
Serial.print(ch);
|
||||
}
|
||||
|
||||
// Close the connection
|
||||
Serial.println();
|
||||
Serial.println("closing connection");
|
||||
client.stop();
|
||||
|
||||
if (wait) {
|
||||
delay(300000); // execute once every 5 minutes, don't flood remote service
|
||||
}
|
||||
wait = true;
|
||||
}
|
@ -27,3 +27,4 @@ NamespaceIndentation: Inner
|
||||
BreakBeforeBraces: Allman
|
||||
IndentWidth: 4
|
||||
IndentCaseLabels: false
|
||||
ReflowComments: false
|
||||
|
Loading…
x
Reference in New Issue
Block a user