From bd46cc11dcf75d2e03857ed0c9df3e7a7b3d226b Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 20 Jul 2022 03:13:02 +0200 Subject: [PATCH 1/4] make WiFi/Ethernet interface compatible with Arduino Ethernet API provide some minimaly adapted examples from legacy --- cores/esp8266/LwipIntf.h | 2 +- cores/esp8266/LwipIntfDev.h | 53 +++++- .../LegacyAdvancedChatServer.ino | 126 ++++++++++++++ .../LegacyChatServer/LegacyChatServer.ino | 105 ++++++++++++ .../LegacyDhcpAddressPrinter.ino | 101 ++++++++++++ .../LegacyUdpNtpClient/LegacyUdpNtpClient.ino | 155 ++++++++++++++++++ libraries/lwIP_Ethernet/src/EthernetCompat.h | 51 ++++++ 7 files changed, 586 insertions(+), 7 deletions(-) create mode 100644 libraries/lwIP_Ethernet/examples/LegacyAdvancedChatServer/LegacyAdvancedChatServer.ino create mode 100644 libraries/lwIP_Ethernet/examples/LegacyChatServer/LegacyChatServer.ino create mode 100644 libraries/lwIP_Ethernet/examples/LegacyDhcpAddressPrinter/LegacyDhcpAddressPrinter.ino create mode 100644 libraries/lwIP_Ethernet/examples/LegacyUdpNtpClient/LegacyUdpNtpClient.ino create mode 100644 libraries/lwIP_Ethernet/src/EthernetCompat.h diff --git a/cores/esp8266/LwipIntf.h b/cores/esp8266/LwipIntf.h index 43941c4f28..8d0bb1dce7 100644 --- a/cores/esp8266/LwipIntf.h +++ b/cores/esp8266/LwipIntf.h @@ -41,7 +41,7 @@ class LwipIntf // ---- + --------- ------------- // local_ip | local_ip local_ip // arg1 | gateway dns1 - // arg2 | netmask [Agateway + // arg2 | netmask gateway // arg3 | dns1 netmask // // result stored into gateway/netmask/dns1 diff --git a/cores/esp8266/LwipIntfDev.h b/cores/esp8266/LwipIntfDev.h index 15f3f033b1..82a36d2ae0 100644 --- a/cores/esp8266/LwipIntfDev.h +++ b/cores/esp8266/LwipIntfDev.h @@ -46,6 +46,28 @@ #define DEFAULT_MTU 1500 #endif +enum HardwareStatus +{ + EthernetNoHardware, + EthernetHardwareFound, +}; + +enum EthernetLinkStatus +{ + Unknown, + LinkON, + LinkOFF +}; + +enum +{ + DHCP_CHECK_NONE = 0, + DHCP_CHECK_RENEW_FAIL = 1, + DHCP_CHECK_RENEW_OK = 2, + DHCP_CHECK_REBIND_FAIL = 3, + DHCP_CHECK_REBIND_OK = 4, +}; + template class LwipIntfDev: public LwipIntf, public RawDev { @@ -54,6 +76,8 @@ class LwipIntfDev: public LwipIntf, public RawDev RawDev(cs, spi, intr), _mtu(DEFAULT_MTU), _intrPin(intr), _started(false), _default(false) { memset(&_netif, 0, sizeof(_netif)); + _hardwareStatus = EthernetNoHardware; + _linkStatus = Unknown; } boolean config(const IPAddress& local_ip, const IPAddress& arg1, const IPAddress& arg2, @@ -104,9 +128,22 @@ class LwipIntfDev: public LwipIntf, public RawDev } // ESP8266WiFi API compatibility - wl_status_t status(); + // Arduino Ethernet API compatibility + HardwareStatus hardwareStatus() const + { + return _hardwareStatus; + } + EthernetLinkStatus linkStatus() const + { + return _linkStatus; + } + int maintain() const + { + return DHCP_CHECK_NONE; + } + protected: err_t netif_init(); void check_route(); @@ -123,11 +160,13 @@ class LwipIntfDev: public LwipIntf, public RawDev netif _netif; - uint16_t _mtu; - int8_t _intrPin; - uint8_t _macAddress[6]; - bool _started; - bool _default; + uint16_t _mtu; + int8_t _intrPin; + uint8_t _macAddress[6]; + bool _started; + bool _default; + HardwareStatus _hardwareStatus; + EthernetLinkStatus _linkStatus; }; template @@ -203,6 +242,8 @@ boolean LwipIntfDev::begin(const uint8_t* macAddress, const uint16_t mtu { return false; } + _hardwareStatus = EthernetHardwareFound; + _linkStatus = LinkON; // setup lwIP netif diff --git a/libraries/lwIP_Ethernet/examples/LegacyAdvancedChatServer/LegacyAdvancedChatServer.ino b/libraries/lwIP_Ethernet/examples/LegacyAdvancedChatServer/LegacyAdvancedChatServer.ino new file mode 100644 index 0000000000..5726b72feb --- /dev/null +++ b/libraries/lwIP_Ethernet/examples/LegacyAdvancedChatServer/LegacyAdvancedChatServer.ino @@ -0,0 +1,126 @@ +/* + Advanced Chat Server + + A more advanced server that distributes any incoming messages + to all connected clients but the client the message comes from. + To use, telnet to your device's IP address and type. + You can see the client's input in the serial monitor as well. + Using an Arduino Wiznet Ethernet shield. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 18 Dec 2009 + by David A. Mellis + modified 9 Apr 2012 + by Tom Igoe + redesigned to make use of operator== 25 Nov 2013 + by Norbert Truchsess + + */ + +// specific to esp8266 w/lwIP +#include +ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware + + + +// Enter a MAC address and IP address for your controller below. +// The IP address will be dependent on your local network. +// gateway and subnet are optional: +byte notNeededButAllowed_mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; +byte* mac = nullptr; // automatic mac +IPAddress ip(192, 168, 1, 177); +IPAddress myDns(192, 168, 1, 1); +IPAddress gateway(192, 168, 1, 1); +IPAddress subnet(255, 255, 0, 0); + + +// telnet defaults to port 23 +EthernetServer server(23); + +EthernetClient clients[8]; + +void setup() { + // You can use Ethernet.init(pin) to configure the CS pin + // Ethernet.init(10); // Most Arduino shields + // Ethernet.init(5); // MKR ETH shield + // Ethernet.init(0); // Teensy 2.0 + // Ethernet.init(20); // Teensy++ 2.0 + // Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet + // Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet + // // esp8266 w/lwIP: SS set in Ethernet constructor + + // initialize the Ethernet device + Ethernet.begin(mac, ip, myDns, gateway, subnet); + + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + + // start listening for clients + server.begin(); + + Serial.print("Chat server address:"); + Serial.println(Ethernet.localIP()); +} + +void loop() { + // check for any new client connecting, and say hello (before any incoming data) + EthernetClient newClient = server.accept(); + if (newClient) { + for (byte i = 0; i < 8; i++) { + if (!clients[i]) { + Serial.print("We have a new client #"); + Serial.println(i); + newClient.print("Hello, client number: "); + newClient.println(i); + // Once we "accept", the client is no longer tracked by EthernetServer + // so we must store it into our list of clients + clients[i] = newClient; + break; + } + } + } + + // check for incoming data from all clients + for (byte i = 0; i < 8; i++) { + if (clients[i] && clients[i].available() > 0) { + // read bytes from a client + byte buffer[80]; + int count = clients[i].read(buffer, 80); + // write the bytes to all other connected clients + for (byte j = 0; j < 8; j++) { + if (j != i && clients[j].connected()) { + clients[j].write(buffer, count); + } + } + } + } + + // stop any clients which disconnect + for (byte i = 0; i < 8; i++) { + if (clients[i] && !clients[i].connected()) { + Serial.print("disconnect client #"); + Serial.println(i); + clients[i].stop(); + } + } +} diff --git a/libraries/lwIP_Ethernet/examples/LegacyChatServer/LegacyChatServer.ino b/libraries/lwIP_Ethernet/examples/LegacyChatServer/LegacyChatServer.ino new file mode 100644 index 0000000000..1c6ee9e2a5 --- /dev/null +++ b/libraries/lwIP_Ethernet/examples/LegacyChatServer/LegacyChatServer.ino @@ -0,0 +1,105 @@ +/* + Chat Server + + A simple server that distributes any incoming messages to all + connected clients. To use, telnet to your device's IP address and type. + You can see the client's input in the serial monitor as well. + Using an Arduino Wiznet Ethernet shield. + + Circuit: + * Ethernet Wiznet5500/Wiznet5100/ENC28J60 on esp8266 + + created 18 Dec 2009 + by David A. Mellis + modified 9 Apr 2012 + by Tom Igoe + + */ + + +// specific to esp8266 w/lwIP +#include +ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware + + + +// Enter a MAC address and IP address for your controller below. +// The IP address will be dependent on your local network. +// gateway and subnet are optional: +byte notNeededButAllowed_mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; +byte* mac = nullptr; // automatic mac +IPAddress ip(192, 168, 1, 177); +IPAddress myDns(192, 168, 1, 1); +IPAddress gateway(192, 168, 1, 1); +IPAddress subnet(255, 255, 0, 0); + + +// telnet defaults to port 23 +EthernetServer server(23); +bool alreadyConnected = false; // whether or not the client was connected previously + +void setup() { + // You can use Ethernet.init(pin) to configure the CS pin + // Ethernet.init(10); // Most Arduino shields + // Ethernet.init(5); // MKR ETH shield + // Ethernet.init(0); // Teensy 2.0 + // Ethernet.init(20); // Teensy++ 2.0 + // Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet + // Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet + // // esp8266 w/lwIP: SS set in Ethernet constructor + + // initialize the ethernet device + Ethernet.begin(mac, ip, myDns, gateway, subnet); + + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + + // start listening for clients + server.begin(); + + Serial.print("Chat server address:"); + Serial.println(Ethernet.localIP()); +} + +void loop() { + // wait for a new client: + EthernetClient client = server.available(); + + // when the client sends the first byte, say hello: + if (client) { + if (!alreadyConnected) { + // clear out the input buffer: + client.flush(); + Serial.println("We have a new client"); + client.println("Hello, client!"); + alreadyConnected = true; + } + + if (client.available() > 0) { + // read the bytes incoming from the client: + char thisChar = client.read(); + // echo the bytes back to the client: + server.write(thisChar); + // echo the bytes to the server as well: + Serial.write(thisChar); + } + } +} diff --git a/libraries/lwIP_Ethernet/examples/LegacyDhcpAddressPrinter/LegacyDhcpAddressPrinter.ino b/libraries/lwIP_Ethernet/examples/LegacyDhcpAddressPrinter/LegacyDhcpAddressPrinter.ino new file mode 100644 index 0000000000..bdda37d1ad --- /dev/null +++ b/libraries/lwIP_Ethernet/examples/LegacyDhcpAddressPrinter/LegacyDhcpAddressPrinter.ino @@ -0,0 +1,101 @@ +/* + DHCP-based IP printer + + This sketch uses the DHCP extensions to the Ethernet library + to get an IP address via DHCP and print the address obtained. + using an Arduino Wiznet Ethernet shield. + + Circuit: + Ethernet shield attached to pins 10, 11, 12, 13 + + created 12 April 2011 + modified 9 Apr 2012 + by Tom Igoe + modified 02 Sept 2015 + by Arturo Guadalupi + + */ + +// specific to esp8266 w/lwIP +#include +ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware + + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte notNeededButAllowed_mac[] = { + 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 +}; +byte* mac = nullptr; // automatic mac + +void setup() { + // You can use Ethernet.init(pin) to configure the CS pin + // Ethernet.init(10); // Most Arduino shields + // Ethernet.init(5); // MKR ETH shield + // Ethernet.init(0); // Teensy 2.0 + // Ethernet.init(20); // Teensy++ 2.0 + // Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet + // Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet + // // esp8266 w/lwIP: SS set in Ethernet constructor + + + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + } else if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // no point in carrying on, so do nothing forevermore: + while (true) { + delay(1); + } + } + // print your local IP address: + Serial.print("My IP address: "); + Serial.println(Ethernet.localIP()); +} + +void loop() { + switch (Ethernet.maintain()) { + case 1: + // renewed fail + Serial.println("Error: renewed fail"); + break; + + case 2: + // renewed success + Serial.println("Renewed success"); + // print your local IP address: + Serial.print("My IP address: "); + Serial.println(Ethernet.localIP()); + break; + + case 3: + // rebind fail + Serial.println("Error: rebind fail"); + break; + + case 4: + // rebind success + Serial.println("Rebind success"); + // print your local IP address: + Serial.print("My IP address: "); + Serial.println(Ethernet.localIP()); + break; + + default: + // nothing happened + break; + } +} diff --git a/libraries/lwIP_Ethernet/examples/LegacyUdpNtpClient/LegacyUdpNtpClient.ino b/libraries/lwIP_Ethernet/examples/LegacyUdpNtpClient/LegacyUdpNtpClient.ino new file mode 100644 index 0000000000..15ae0b5930 --- /dev/null +++ b/libraries/lwIP_Ethernet/examples/LegacyUdpNtpClient/LegacyUdpNtpClient.ino @@ -0,0 +1,155 @@ +/* + + Udp NTP Client + + Get the time from a Network Time Protocol (NTP) time server + Demonstrates use of UDP sendPacket and ReceivePacket + For more on NTP time servers and the messages needed to communicate with them, + see http://en.wikipedia.org/wiki/Network_Time_Protocol + + created 4 Sep 2010 + by Michael Margolis + modified 9 Apr 2012 + by Tom Igoe + modified 02 Sept 2015 + by Arturo Guadalupi + + This code is in the public domain. + + */ + +// specific to esp8266 w/lwIP +#include +ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware + +using Ethernet = WiFi; + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte notNeededButAllowed_mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; +byte* mac = nullptr; // automatic mac + +unsigned int localPort = 8888; // local port to listen for UDP packets + +const char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server + +const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message + +byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets + +// A UDP instance to let us send and receive packets over UDP +EthernetUDP Udp; + +void setup() { + // You can use Ethernet.init(pin) to configure the CS pin + // Ethernet.init(10); // Most Arduino shields + // Ethernet.init(5); // MKR ETH shield + // Ethernet.init(0); // Teensy 2.0 + // Ethernet.init(20); // Teensy++ 2.0 + // Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet + // Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet + // // esp8266 w/lwIP: SS set in Ethernet constructor + + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + // start Ethernet and UDP + Serial.println("starting with DHCP"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + } else if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // no point in carrying on, so do nothing forevermore: + Serial.println("failure"); + while (true) { + delay(500); + } + } + Serial.print("local IP: "); + Serial.println(Ethernet.localIP()); + Udp.begin(localPort); +} + +void loop() { + sendNTPpacket(timeServer); // send an NTP packet to a time server + + // wait to see if a reply is available + delay(1000); + if (Udp.parsePacket()) { + // We've received a packet, read the data from it + Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer + + // the timestamp starts at byte 40 of the received packet and is four bytes, + // or two words, long. First, extract the two words: + + unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); + unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); + // combine the four bytes (two words) into a long integer + // this is NTP time (seconds since Jan 1 1900): + unsigned long secsSince1900 = highWord << 16 | lowWord; + Serial.print("Seconds since Jan 1 1900 = "); + Serial.println(secsSince1900); + + // now convert NTP time into everyday time: + Serial.print("Unix time = "); + // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: + const unsigned long seventyYears = 2208988800UL; + // subtract seventy years: + unsigned long epoch = secsSince1900 - seventyYears; + // print Unix time: + Serial.println(epoch); + + + // print the hour, minute and second: + Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) + Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day) + Serial.print(':'); + if (((epoch % 3600) / 60) < 10) { + // In the first 10 minutes of each hour, we'll want a leading '0' + Serial.print('0'); + } + Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) + Serial.print(':'); + if ((epoch % 60) < 10) { + // In the first 10 seconds of each minute, we'll want a leading '0' + Serial.print('0'); + } + Serial.println(epoch % 60); // print the second + } + // wait ten seconds before asking for the time again + delay(10000); + Ethernet.maintain(); +} + +// send an NTP request to the time server at the given address +void sendNTPpacket(const char* address) { + // set all bytes in the buffer to 0 + memset(packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + packetBuffer[12] = 49; + packetBuffer[13] = 0x4E; + packetBuffer[14] = 49; + packetBuffer[15] = 52; + + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + Udp.beginPacket(address, 123); // NTP requests are to port 123 + Udp.write(packetBuffer, NTP_PACKET_SIZE); + Udp.endPacket(); +} diff --git a/libraries/lwIP_Ethernet/src/EthernetCompat.h b/libraries/lwIP_Ethernet/src/EthernetCompat.h new file mode 100644 index 0000000000..03367751bb --- /dev/null +++ b/libraries/lwIP_Ethernet/src/EthernetCompat.h @@ -0,0 +1,51 @@ + +#pragma once + +#include +#include +#include +#include + +using EthernetUDP = WiFiUDP; +using EthernetClient = WiFiClient; +using EthernetServer = ArduinoWiFiServer; + +template +class ArduinoEthernet: public LwipIntfDev +{ +public: + ArduinoEthernet(int8_t cs = SS, SPIClass& spi = SPI, int8_t intr = -1) : + LwipIntfDev(cs, spi, intr) + { + } + + // Arduino-Ethernet API compatibility, order can be either: + // mac, ip, gateway, netmask, dns (esp8266 or natural order) + // mac, ip, dns, gateway, netmask (Arduino legacy) + boolean begin(const uint8_t* macAddress, const IPAddress& local_ip = IPADDR_NONE, + const IPAddress& arg1 = IPADDR_NONE, const IPAddress& arg2 = IPADDR_NONE, + const IPAddress& arg3 = IPADDR_NONE) + { + SPI4EthInit(); // Arduino Ethernet self-initializes SPI + bool ret = true; + if (local_ip.isSet()) + ret = LwipIntfDev::config(local_ip, arg1, arg2, arg3); + if (ret) + { + ret = LwipIntfDev::begin(macAddress); + if (!local_ip.isSet()) + { + // Arduino API waits for DHCP answer + while (!LwipIntfDev::connected()) + { + delay(100); + } + } + } + return ret; + } +}; + +using ArduinoWiznet5500lwIP = ArduinoEthernet; +using ArduinoWiznet5100lwIP = ArduinoEthernet; +using ArduinoENC28J60lwIP = ArduinoEthernet; From 7abe4b687fb567b0e8c15a30e9d5e96c5a5c1c44 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 24 Jul 2022 22:56:04 +0200 Subject: [PATCH 2/4] move ethernet compat globals to EthernetCompat.h --- cores/esp8266/LwipIntfDev.h | 52 ++------------------ libraries/lwIP_Ethernet/src/EthernetCompat.h | 50 +++++++++++++++++++ 2 files changed, 55 insertions(+), 47 deletions(-) diff --git a/cores/esp8266/LwipIntfDev.h b/cores/esp8266/LwipIntfDev.h index 82a36d2ae0..00f29e9dfe 100644 --- a/cores/esp8266/LwipIntfDev.h +++ b/cores/esp8266/LwipIntfDev.h @@ -46,28 +46,6 @@ #define DEFAULT_MTU 1500 #endif -enum HardwareStatus -{ - EthernetNoHardware, - EthernetHardwareFound, -}; - -enum EthernetLinkStatus -{ - Unknown, - LinkON, - LinkOFF -}; - -enum -{ - DHCP_CHECK_NONE = 0, - DHCP_CHECK_RENEW_FAIL = 1, - DHCP_CHECK_RENEW_OK = 2, - DHCP_CHECK_REBIND_FAIL = 3, - DHCP_CHECK_REBIND_OK = 4, -}; - template class LwipIntfDev: public LwipIntf, public RawDev { @@ -76,8 +54,6 @@ class LwipIntfDev: public LwipIntf, public RawDev RawDev(cs, spi, intr), _mtu(DEFAULT_MTU), _intrPin(intr), _started(false), _default(false) { memset(&_netif, 0, sizeof(_netif)); - _hardwareStatus = EthernetNoHardware; - _linkStatus = Unknown; } boolean config(const IPAddress& local_ip, const IPAddress& arg1, const IPAddress& arg2, @@ -130,20 +106,6 @@ class LwipIntfDev: public LwipIntf, public RawDev // ESP8266WiFi API compatibility wl_status_t status(); - // Arduino Ethernet API compatibility - HardwareStatus hardwareStatus() const - { - return _hardwareStatus; - } - EthernetLinkStatus linkStatus() const - { - return _linkStatus; - } - int maintain() const - { - return DHCP_CHECK_NONE; - } - protected: err_t netif_init(); void check_route(); @@ -160,13 +122,11 @@ class LwipIntfDev: public LwipIntf, public RawDev netif _netif; - uint16_t _mtu; - int8_t _intrPin; - uint8_t _macAddress[6]; - bool _started; - bool _default; - HardwareStatus _hardwareStatus; - EthernetLinkStatus _linkStatus; + uint16_t _mtu; + int8_t _intrPin; + uint8_t _macAddress[6]; + bool _started; + bool _default; }; template @@ -242,8 +202,6 @@ boolean LwipIntfDev::begin(const uint8_t* macAddress, const uint16_t mtu { return false; } - _hardwareStatus = EthernetHardwareFound; - _linkStatus = LinkON; // setup lwIP netif diff --git a/libraries/lwIP_Ethernet/src/EthernetCompat.h b/libraries/lwIP_Ethernet/src/EthernetCompat.h index 03367751bb..e398d5719d 100644 --- a/libraries/lwIP_Ethernet/src/EthernetCompat.h +++ b/libraries/lwIP_Ethernet/src/EthernetCompat.h @@ -10,6 +10,28 @@ using EthernetUDP = WiFiUDP; using EthernetClient = WiFiClient; using EthernetServer = ArduinoWiFiServer; +enum EthernetLinkStatus +{ + Unknown, + LinkON, + LinkOFF +}; + +enum +{ + DHCP_CHECK_NONE = 0, + DHCP_CHECK_RENEW_FAIL = 1, + DHCP_CHECK_RENEW_OK = 2, + DHCP_CHECK_REBIND_FAIL = 3, + DHCP_CHECK_REBIND_OK = 4, +}; + +enum HardwareStatus +{ + EthernetNoHardware, + EthernetHardwareFound, +}; + template class ArduinoEthernet: public LwipIntfDev { @@ -17,6 +39,8 @@ class ArduinoEthernet: public LwipIntfDev ArduinoEthernet(int8_t cs = SS, SPIClass& spi = SPI, int8_t intr = -1) : LwipIntfDev(cs, spi, intr) { + _hardwareStatus = EthernetNoHardware; + _linkStatus = Unknown; } // Arduino-Ethernet API compatibility, order can be either: @@ -42,8 +66,34 @@ class ArduinoEthernet: public LwipIntfDev } } } + + if (ret) + { + _hardwareStatus = EthernetHardwareFound; + _linkStatus = LinkON; + } + return ret; } + + HardwareStatus hardwareStatus() const + { + return _hardwareStatus; + } + + EthernetLinkStatus linkStatus() const + { + return _linkStatus; + } + + int maintain() const + { + return DHCP_CHECK_NONE; + } + +protected: + HardwareStatus _hardwareStatus; + EthernetLinkStatus _linkStatus; }; using ArduinoWiznet5500lwIP = ArduinoEthernet; From 1a358da3a644e8b88a4fc92940c748e7f05b7ca4 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 24 Jul 2022 23:29:16 +0200 Subject: [PATCH 3/4] LegacyEthernet: add UDP example --- .../LegacyUDPSendReceiveString.ino | 153 +++++++++++++++++ .../LegacyUdpNtpClient/LegacyUdpNtpClient.ino | 155 ------------------ 2 files changed, 153 insertions(+), 155 deletions(-) create mode 100644 libraries/lwIP_Ethernet/examples/LegacyUDPSendReceiveString/LegacyUDPSendReceiveString.ino delete mode 100644 libraries/lwIP_Ethernet/examples/LegacyUdpNtpClient/LegacyUdpNtpClient.ino diff --git a/libraries/lwIP_Ethernet/examples/LegacyUDPSendReceiveString/LegacyUDPSendReceiveString.ino b/libraries/lwIP_Ethernet/examples/LegacyUDPSendReceiveString/LegacyUDPSendReceiveString.ino new file mode 100644 index 0000000000..876a9f8da0 --- /dev/null +++ b/libraries/lwIP_Ethernet/examples/LegacyUDPSendReceiveString/LegacyUDPSendReceiveString.ino @@ -0,0 +1,153 @@ +/* + UDPSendReceiveString: + This sketch receives UDP message strings, prints them to the serial port + and sends an "acknowledge" string back to the sender + + A Processing sketch is included at the end of file that can be used to send + and received messages for testing with a computer. + + created 21 Aug 2010 + by Michael Margolis + + This code is in the public domain. + */ + +// specific to esp8266 w/lwIP +#include +ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware +// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte notNeededButAllowed_mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; +byte* mac = nullptr; // automatic mac +IPAddress ip(192, 168, 1, 177); + +unsigned int localPort = 8888; // local port to listen on + +// buffers for receiving and sending data +char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet, +char ReplyBuffer[] = "acknowledged"; // a string to send back + +// An EthernetUDP instance to let us send and receive packets over UDP +EthernetUDP Udp; + +void setup() { + // You can use Ethernet.init(pin) to configure the CS pin + // Ethernet.init(10); // Most Arduino shields + // Ethernet.init(5); // MKR ETH shield + // Ethernet.init(0); // Teensy 2.0 + // Ethernet.init(20); // Teensy++ 2.0 + // Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet + // Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet + // // esp8266 w/lwIP: SS set in Ethernet constructor + + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // start the Ethernet + // Ethernet.begin(mac, ip); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + while (true) { + delay(1000); // do nothing, no point running without Ethernet hardware + } + } + + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1000); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + + Serial.println("Started and waiting"); + Serial.print("IP Address: "); + Serial.println(Ethernet.localIP()); + Serial.print("UDP port: "); + Serial.println(localPort); + + // start UDP + Udp.begin(localPort); +} + +void loop() { + // if there's data available, read a packet + int packetSize = Udp.parsePacket(); + if (packetSize) { + Serial.print("Received packet of size "); + Serial.println(packetSize); + Serial.print("From "); + IPAddress remote = Udp.remoteIP(); + for (int i = 0; i < 4; i++) { + Serial.print(remote[i], DEC); + if (i < 3) { + Serial.print("."); + } + } + Serial.print(", port "); + Serial.println(Udp.remotePort()); + + // read the packet into packetBufffer + Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); + Serial.println("Contents:"); + Serial.println(packetBuffer); + + // send a reply to the IP address and port that sent us the packet we received + Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); + Udp.write(ReplyBuffer); + Udp.endPacket(); + } + delay(10); +} + + +/* + Processing sketch to run with this example + ===================================================== + + // Processing UDP example to send and receive string data from Arduino + // press any key to send the "Hello Arduino" message + + + import hypermedia.net.*; + + UDP udp; // define the UDP object + + + void setup() { + udp = new UDP( this, 6000 ); // create a new datagram connection on port 6000 + //udp.log( true ); // <-- printout the connection activity + udp.listen( true ); // and wait for incoming message + } + + void draw() + { + } + + void keyPressed() { + String ip = "192.168.1.177"; // the remote IP address + int port = 8888; // the destination port + + udp.send("Hello World", ip, port ); // the message to send + + } + + void receive( byte[] data ) { // <-- default handler + //void receive( byte[] data, String ip, int port ) { // <-- extended handler + + for(int i=0; i < data.length; i++) + print(char(data[i])); + println(); + } + */ diff --git a/libraries/lwIP_Ethernet/examples/LegacyUdpNtpClient/LegacyUdpNtpClient.ino b/libraries/lwIP_Ethernet/examples/LegacyUdpNtpClient/LegacyUdpNtpClient.ino deleted file mode 100644 index 15ae0b5930..0000000000 --- a/libraries/lwIP_Ethernet/examples/LegacyUdpNtpClient/LegacyUdpNtpClient.ino +++ /dev/null @@ -1,155 +0,0 @@ -/* - - Udp NTP Client - - Get the time from a Network Time Protocol (NTP) time server - Demonstrates use of UDP sendPacket and ReceivePacket - For more on NTP time servers and the messages needed to communicate with them, - see http://en.wikipedia.org/wiki/Network_Time_Protocol - - created 4 Sep 2010 - by Michael Margolis - modified 9 Apr 2012 - by Tom Igoe - modified 02 Sept 2015 - by Arturo Guadalupi - - This code is in the public domain. - - */ - -// specific to esp8266 w/lwIP -#include -ArduinoWiznet5500lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware -// ArduinoWiznet5100lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware -// ArduinoENC28J60lwIP Ethernet(/*SS*/ 16); // <== adapt to your hardware - -using Ethernet = WiFi; - -// Enter a MAC address for your controller below. -// Newer Ethernet shields have a MAC address printed on a sticker on the shield -byte notNeededButAllowed_mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED -}; -byte* mac = nullptr; // automatic mac - -unsigned int localPort = 8888; // local port to listen for UDP packets - -const char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server - -const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message - -byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets - -// A UDP instance to let us send and receive packets over UDP -EthernetUDP Udp; - -void setup() { - // You can use Ethernet.init(pin) to configure the CS pin - // Ethernet.init(10); // Most Arduino shields - // Ethernet.init(5); // MKR ETH shield - // Ethernet.init(0); // Teensy 2.0 - // Ethernet.init(20); // Teensy++ 2.0 - // Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet - // Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet - // // esp8266 w/lwIP: SS set in Ethernet constructor - - // Open serial communications and wait for port to open: - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for native USB port only - } - // start Ethernet and UDP - Serial.println("starting with DHCP"); - if (Ethernet.begin(mac) == 0) { - Serial.println("Failed to configure Ethernet using DHCP"); - // Check for Ethernet hardware present - if (Ethernet.hardwareStatus() == EthernetNoHardware) { - Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); - } else if (Ethernet.linkStatus() == LinkOFF) { - Serial.println("Ethernet cable is not connected."); - } - // no point in carrying on, so do nothing forevermore: - Serial.println("failure"); - while (true) { - delay(500); - } - } - Serial.print("local IP: "); - Serial.println(Ethernet.localIP()); - Udp.begin(localPort); -} - -void loop() { - sendNTPpacket(timeServer); // send an NTP packet to a time server - - // wait to see if a reply is available - delay(1000); - if (Udp.parsePacket()) { - // We've received a packet, read the data from it - Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer - - // the timestamp starts at byte 40 of the received packet and is four bytes, - // or two words, long. First, extract the two words: - - unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); - unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); - // combine the four bytes (two words) into a long integer - // this is NTP time (seconds since Jan 1 1900): - unsigned long secsSince1900 = highWord << 16 | lowWord; - Serial.print("Seconds since Jan 1 1900 = "); - Serial.println(secsSince1900); - - // now convert NTP time into everyday time: - Serial.print("Unix time = "); - // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: - const unsigned long seventyYears = 2208988800UL; - // subtract seventy years: - unsigned long epoch = secsSince1900 - seventyYears; - // print Unix time: - Serial.println(epoch); - - - // print the hour, minute and second: - Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) - Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day) - Serial.print(':'); - if (((epoch % 3600) / 60) < 10) { - // In the first 10 minutes of each hour, we'll want a leading '0' - Serial.print('0'); - } - Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) - Serial.print(':'); - if ((epoch % 60) < 10) { - // In the first 10 seconds of each minute, we'll want a leading '0' - Serial.print('0'); - } - Serial.println(epoch % 60); // print the second - } - // wait ten seconds before asking for the time again - delay(10000); - Ethernet.maintain(); -} - -// send an NTP request to the time server at the given address -void sendNTPpacket(const char* address) { - // set all bytes in the buffer to 0 - memset(packetBuffer, 0, NTP_PACKET_SIZE); - // Initialize values needed to form NTP request - // (see URL above for details on the packets) - packetBuffer[0] = 0b11100011; // LI, Version, Mode - packetBuffer[1] = 0; // Stratum, or type of clock - packetBuffer[2] = 6; // Polling Interval - packetBuffer[3] = 0xEC; // Peer Clock Precision - // 8 bytes of zero for Root Delay & Root Dispersion - packetBuffer[12] = 49; - packetBuffer[13] = 0x4E; - packetBuffer[14] = 49; - packetBuffer[15] = 52; - - // all NTP fields have been given values, now - // you can send a packet requesting a timestamp: - Udp.beginPacket(address, 123); // NTP requests are to port 123 - Udp.write(packetBuffer, NTP_PACKET_SIZE); - Udp.endPacket(); -} From a3ab8eb2b3d2170ccc7213de5dba3d0b72b508da Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 25 Jul 2022 22:14:25 +0200 Subject: [PATCH 4/4] adjust comments --- .../LegacyAdvancedChatServer/LegacyAdvancedChatServer.ino | 2 +- .../LegacyDhcpAddressPrinter/LegacyDhcpAddressPrinter.ino | 2 +- .../LegacyUDPSendReceiveString/LegacyUDPSendReceiveString.ino | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/lwIP_Ethernet/examples/LegacyAdvancedChatServer/LegacyAdvancedChatServer.ino b/libraries/lwIP_Ethernet/examples/LegacyAdvancedChatServer/LegacyAdvancedChatServer.ino index 5726b72feb..74b580308f 100644 --- a/libraries/lwIP_Ethernet/examples/LegacyAdvancedChatServer/LegacyAdvancedChatServer.ino +++ b/libraries/lwIP_Ethernet/examples/LegacyAdvancedChatServer/LegacyAdvancedChatServer.ino @@ -8,7 +8,7 @@ Using an Arduino Wiznet Ethernet shield. Circuit: - * Ethernet shield attached to pins 10, 11, 12, 13 + * Ethernet Wiznet5500/Wiznet5100/ENC28J60 on esp8266 created 18 Dec 2009 by David A. Mellis diff --git a/libraries/lwIP_Ethernet/examples/LegacyDhcpAddressPrinter/LegacyDhcpAddressPrinter.ino b/libraries/lwIP_Ethernet/examples/LegacyDhcpAddressPrinter/LegacyDhcpAddressPrinter.ino index bdda37d1ad..e7ab75075b 100644 --- a/libraries/lwIP_Ethernet/examples/LegacyDhcpAddressPrinter/LegacyDhcpAddressPrinter.ino +++ b/libraries/lwIP_Ethernet/examples/LegacyDhcpAddressPrinter/LegacyDhcpAddressPrinter.ino @@ -6,7 +6,7 @@ using an Arduino Wiznet Ethernet shield. Circuit: - Ethernet shield attached to pins 10, 11, 12, 13 + * Ethernet Wiznet5500/Wiznet5100/ENC28J60 on esp8266 created 12 April 2011 modified 9 Apr 2012 diff --git a/libraries/lwIP_Ethernet/examples/LegacyUDPSendReceiveString/LegacyUDPSendReceiveString.ino b/libraries/lwIP_Ethernet/examples/LegacyUDPSendReceiveString/LegacyUDPSendReceiveString.ino index 876a9f8da0..bee4a1f801 100644 --- a/libraries/lwIP_Ethernet/examples/LegacyUDPSendReceiveString/LegacyUDPSendReceiveString.ino +++ b/libraries/lwIP_Ethernet/examples/LegacyUDPSendReceiveString/LegacyUDPSendReceiveString.ino @@ -6,6 +6,9 @@ A Processing sketch is included at the end of file that can be used to send and received messages for testing with a computer. + Circuit: + * Ethernet Wiznet5500/Wiznet5100/ENC28J60 on esp8266 + created 21 Aug 2010 by Michael Margolis