From f122db4e7a25ad05624043f040ba621682d3f6a1 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sat, 22 May 2021 17:30:15 +0200 Subject: [PATCH 01/28] README update - notes for ESP --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9b997bf..9fbdcd7 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,22 @@ The modernization includes: * calls yield() in blocking functions * Arduino 1.5 library format built with dot_a_linkage option for optimal build result +
+ Notes for ESP (click to expand) + +* *For esp8266 Arduino there is a much better option for enc28j60 than using this library. Use the lwIP_enc28j60 library bundled with esp8266 Arduino boards support package 3. (There is also a lwIP_w5500 and lwIP_w5100 library.)* +* *For ESP32 it is better than using a MAC layer module like the enc28j60 to use a PHY layer LAN module like LAN8720 supported by the ESP32 MAC peripheral and the Arduino boards support package.* +
+ [The documentation of Arduino Ethernet library](https://www.arduino.cc/en/Reference/Ethernet) applies for classes and functions descriptions. Limitations: * UDP.beginMulticast is not supported, because the uIP stack doesn't support multicast * UDP broadcasts receiving is turned off on ENC to lower the processing load on the library -This library doesn't have examples, because examples of the Arduino Ethernet library apply. You can find them in the Arduino IDE Examples menu Ethernet section. Only change `#include ` to `#include `. Some examples require [a little change](https://github.com/jandrassy/EthernetENC/wiki/Examples). +This library doesn't have examples, because examples of the Arduino Ethernet library apply. You can find them in the Arduino IDE Examples menu Ethernet section. Only change `#include ` to `#include `. Some examples require [a little change](https://github.com/jandrassy/EthernetENC/wiki/Examples). -This library is based on the Norbert Truchsess's arduino-uip original source code repository and uses experience from the development of the multi-architecture support by Cassy. Applicable fixes and enhancements from developed of EthernetENC were transfered to Cassy's UIPEthernet. +This library is based on the Norbert Truchsess's arduino-uip original source code repository and uses experience from the development of the multi-architecture support by Cassy. Applicable fixes and enhancements from development of EthernetENC were transfered to Cassy's UIPEthernet. **You can find more information in project's [Wiki](https://github.com/jandrassy/EthernetENC/wiki).** From 89788e366220601c4d60d8c2f44315a2cfabdb33 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 18 Jul 2021 19:41:42 +0200 Subject: [PATCH 02/28] EthernetUdp.cpp beginPacket fix IPAddress check --- src/EthernetUdp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EthernetUdp.cpp b/src/EthernetUdp.cpp index bbfd2ae..e3d7cd1 100644 --- a/src/EthernetUdp.cpp +++ b/src/EthernetUdp.cpp @@ -81,7 +81,7 @@ int UIPUDP::beginPacket(IPAddress ip, uint16_t port) { UIPEthernetClass::tick(); - if (ip && port) + if ((ip[0] || ip[1] || ip[2] || ip[3]) && port) { uip_ipaddr_t ripaddr; uip_ip_addr(&ripaddr, ip); From c735fd4cf6821a166ef6b36dd56bd861ba61c400 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Wed, 13 Oct 2021 20:08:34 +0200 Subject: [PATCH 03/28] Dhcp.cpp - fix reset_DHCP_lease() --- src/Dhcp.cpp | 7 +++++-- src/Dhcp.h | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Dhcp.cpp b/src/Dhcp.cpp index 74280a3..cc71c68 100644 --- a/src/Dhcp.cpp +++ b/src/Dhcp.cpp @@ -24,8 +24,11 @@ int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long } void DhcpClass::reset_DHCP_lease(){ - // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp - memset(_dhcpLocalIp, 0, 20); + memset(_dhcpLocalIp, 0, 4); + memset(_dhcpSubnetMask, 0, 4); + memset(_dhcpGatewayIp, 0, 4); + memset(_dhcpDhcpServerIp, 0, 4); + memset(_dhcpDnsServerIp, 0, 4); } //return:0 on error, 1 if request is sent and response is received diff --git a/src/Dhcp.h b/src/Dhcp.h index 35760f8..febdd20 100644 --- a/src/Dhcp.h +++ b/src/Dhcp.h @@ -141,11 +141,19 @@ class DhcpClass { uint32_t _dhcpInitialTransactionId; uint32_t _dhcpTransactionId; uint8_t _dhcpMacAddr[6]; +#ifdef __arm__ + uint8_t _dhcpLocalIp[4] __attribute__((aligned(4))); + uint8_t _dhcpSubnetMask[4] __attribute__((aligned(4))); + uint8_t _dhcpGatewayIp[4] __attribute__((aligned(4))); + uint8_t _dhcpDhcpServerIp[4] __attribute__((aligned(4))); + uint8_t _dhcpDnsServerIp[4] __attribute__((aligned(4))); +#else uint8_t _dhcpLocalIp[4]; uint8_t _dhcpSubnetMask[4]; uint8_t _dhcpGatewayIp[4]; uint8_t _dhcpDhcpServerIp[4]; uint8_t _dhcpDnsServerIp[4]; +#endif uint32_t _dhcpLeaseTime; uint32_t _dhcpT1, _dhcpT2; signed long _renewInSec; From b40a04c68d4f899b450cb010dec3a4a85a0bc644 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 21 Nov 2021 20:08:35 +0100 Subject: [PATCH 04/28] EthernetClient._allocateData - fix data clear --- src/EthernetClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index 30a4ce3..a666ef0 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -532,9 +532,9 @@ UIPClient::_allocateData() uip_userdata_t* data = &UIPClient::all_data[sock]; if (!data->state) { + memset(data, 0, sizeof(uip_userdata_t)); data->conn_index = uip_conn - uip_conns; // pointer arithmetics data->state = UIP_CLIENT_CONNECTED; - memset(&data->packets_in[0],0,sizeof(uip_userdata_t)-sizeof(data->state)); return data; } } From b6dfa0fc718a203362d6029c1455b3e19f965b64 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Tue, 23 Nov 2021 20:37:12 +0100 Subject: [PATCH 05/28] Enc28J60Network::writePacket - don't write zero length --- src/utility/Enc28J60Network.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/utility/Enc28J60Network.cpp b/src/utility/Enc28J60Network.cpp index 97ff438..065230c 100644 --- a/src/utility/Enc28J60Network.cpp +++ b/src/utility/Enc28J60Network.cpp @@ -302,12 +302,16 @@ Enc28J60Network::writePacket(memhandle handle, memaddress position, uint8_t* buf memblock *packet = &blocks[handle]; uint16_t start = packet->begin + position; + if (len > packet->size - position) + len = packet->size - position; + + if (len == 0) + return 0; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); writeRegPair(EWRPTL, start); - if (len > packet->size - position) - len = packet->size - position; writeBuffer(len, buffer); SPI.endTransaction(); From f450c59fe36c5b013354f4993c6cc19ffb3533a9 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Tue, 23 Nov 2021 20:42:18 +0100 Subject: [PATCH 06/28] EthernetClient::_currentBlock - revert to Norbert's version --- src/EthernetClient.cpp | 12 +++--------- src/EthernetClient.h | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index a666ef0..5ddbbd9 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -170,7 +170,7 @@ UIPClient::write(const uint8_t *buf, size_t size) UIPEthernetClass::tick(); if (u && u->state && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) { - uint8_t p = _currentBlock(u->packets_out, u->out_pos); + uint8_t p = _currentBlock(u->packets_out); if (u->packets_out[p] == NOBLOCK) { newpacket: @@ -240,7 +240,7 @@ UIPClient::availableForWrite() UIPEthernetClass::tick(); if (data->packets_out[0] == NOBLOCK) return MAX_AVAILABLE; - uint8_t p = _currentBlock(data->packets_out, data->out_pos); + uint8_t p = _currentBlock(data->packets_out); int used = UIP_SOCKET_DATALEN * p + data->out_pos; return MAX_AVAILABLE - used; } @@ -542,18 +542,12 @@ UIPClient::_allocateData() } uint8_t -UIPClient::_currentBlock(memhandle* block, uint16_t out_pos) +UIPClient::_currentBlock(memhandle* block) { - if (block[0] == NOBLOCK) - return 0; for (uint8_t i = 1; i < UIP_SOCKET_NUMPACKETS; i++) { if (block[i] == NOBLOCK) - { - if (out_pos == Enc28J60Network::blockSize(block[i-1])) // block is full - return i; return i-1; - } } return UIP_SOCKET_NUMPACKETS-1; } diff --git a/src/EthernetClient.h b/src/EthernetClient.h index 324cfac..d78c769 100644 --- a/src/EthernetClient.h +++ b/src/EthernetClient.h @@ -87,7 +87,7 @@ class EthernetClient : public Client { static uip_userdata_t all_data[UIP_CONNS]; static uip_userdata_t* _allocateData(); - static uint8_t _currentBlock(memhandle* blocks, uint16_t out_pos); + static uint8_t _currentBlock(memhandle* blocks); static void _eatBlock(memhandle* blocks); static void _flushBlocks(memhandle* blocks); From 84cfba035e502d772874145d92a7073d9da8d4d3 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sat, 27 Nov 2021 15:32:31 +0100 Subject: [PATCH 07/28] EthernetClient - fix NULL data field checks --- src/EthernetClient.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index 5ddbbd9..274c1e8 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -268,7 +268,7 @@ UIPClient::flush() int UIPClient::available() { - if (!(*this)) + if (!data) return 0; int len = 0; @@ -286,7 +286,7 @@ UIPClient::available() int UIPClient::read(uint8_t *buf, size_t size) { - if (*this) + if (data) { uint16_t remain = size; if (data->packets_in[0] == NOBLOCK) @@ -338,7 +338,7 @@ UIPClient::read() int UIPClient::peek() { - if (*this) + if (data) { if (data->packets_in[0] != NOBLOCK) { @@ -353,7 +353,7 @@ UIPClient::peek() void UIPClient::discardReceived() { - if (*this) + if (data) { _flushBlocks(data->packets_in); } From 2c5376f33b7219d754dca9ca092f72fbe857376c Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Thu, 30 Dec 2021 17:41:39 +0100 Subject: [PATCH 08/28] EthernetClient.cpp _dumpAllData debug fnc improved --- src/EthernetClient.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index 274c1e8..1b526e0 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -598,10 +598,22 @@ void UIPClient::_dumpAllData() { for (uint8_t i=0; i < UIP_CONNS; i++) { + if (!all_data[i].state) + continue; Serial.print(F("UIPClient::all_data[")); Serial.print(i); Serial.print(F("], state:")); Serial.println(all_data[i].state, BIN); + struct uip_conn& conn = uip_conns[all_data[i].conn_index]; + Serial.println(ip_addr_uip(conn.ripaddr)); + Serial.print(F("ix: ")); + Serial.print(all_data[i].conn_index); + Serial.print(F(" tcp flags: 0x")); + Serial.print(conn.tcpstateflags, HEX); + Serial.print(F(" retransmission: timer ")); + Serial.print(conn.timer); + Serial.print(F(" nrtx ")); + Serial.println(conn.nrtx); Serial.print(F("packets_in: ")); for (uint8_t j=0; j < UIP_SOCKET_NUMPACKETS; j++) { @@ -626,6 +638,24 @@ UIPClient::_dumpAllData() { Serial.print(F("out_pos: ")); Serial.println(all_data[i].out_pos); } + Serial.println(); + } + for (uint8_t i=0; i < UIP_CONNS; i++) + { + struct uip_conn& conn = uip_conns[i]; + Serial.print(i); + Serial.print(' '); + Serial.print(ip_addr_uip(conn.ripaddr)); + Serial.print(':'); + Serial.print(ntohs(conn.rport)); + Serial.print(' '); + Serial.print(ntohs(conn.lport)); + Serial.print(F(" tcp flags: 0x")); + Serial.print(conn.tcpstateflags, HEX); + Serial.print(F(" retransmission: timer ")); + Serial.print(conn.timer); + Serial.print(F(" nrtx ")); + Serial.println(conn.nrtx); } } #endif From 27d8af8b1a705c28cfebe69ab693c0b006a98000 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Mon, 3 Jan 2022 18:50:44 +0100 Subject: [PATCH 09/28] version 2.0.2 --- README.md | 1 + library.properties | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9fbdcd7..7b0433b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ The modernization includes: * SPI communication at 20 MHz if the MCU supports it, else on the maximum supported by the MCU * client.flush() to send the packet immediately * calls yield() in blocking functions +* has UDP backlog to receive more than one message at time * Arduino 1.5 library format built with dot_a_linkage option for optimal build result
diff --git a/library.properties b/library.properties index 6c53862..71d1c35 100644 --- a/library.properties +++ b/library.properties @@ -5,7 +5,7 @@ sentence=Ethernet library for ENC28J60. Only include EthernetENC.h instead of Et paragraph=This is a modern version of the UIPEthernet library. EthernetENC library is compatible with all Arduino architectures with Arduino SPI library with transactions support. url=https://github.com/jandrassy/EthernetENC/wiki architectures=* -version=2.0.1 +version=2.0.2 category=Communication includes=EthernetENC.h dot_a_linkage=true From fe7e7b9c0bca0a13de121d5061258ddafaf67d09 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Thu, 3 Feb 2022 21:07:54 +0100 Subject: [PATCH 10/28] buymeacoffee --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7b0433b..22e8478 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +Buy Me A Coffee EthernetENC is the Ethernet library for ENC28J60. It is a modern version of [the UIPEthernet library](https://github.com/jandrassy/EthernetENC/wiki/UIPEthernet). From a0393889ea90ea17e7ab8c33c759e1d6f16748e1 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 20 Feb 2022 15:37:33 +0100 Subject: [PATCH 11/28] Revert "EthernetClient - fix NULL data field checks" This reverts commit 84cfba035e502d772874145d92a7073d9da8d4d3. --- src/EthernetClient.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index 1b526e0..0e75552 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -268,7 +268,7 @@ UIPClient::flush() int UIPClient::available() { - if (!data) + if (!(*this)) return 0; int len = 0; @@ -286,7 +286,7 @@ UIPClient::available() int UIPClient::read(uint8_t *buf, size_t size) { - if (data) + if (*this) { uint16_t remain = size; if (data->packets_in[0] == NOBLOCK) @@ -338,7 +338,7 @@ UIPClient::read() int UIPClient::peek() { - if (data) + if (*this) { if (data->packets_in[0] != NOBLOCK) { @@ -353,7 +353,7 @@ UIPClient::peek() void UIPClient::discardReceived() { - if (data) + if (*this) { _flushBlocks(data->packets_in); } From 9428b5e970dbc9882ac2aeed94725a1dd87615b9 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 15 May 2022 12:35:26 +0200 Subject: [PATCH 12/28] version 2.0.3 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 71d1c35..b54648c 100644 --- a/library.properties +++ b/library.properties @@ -5,7 +5,7 @@ sentence=Ethernet library for ENC28J60. Only include EthernetENC.h instead of Et paragraph=This is a modern version of the UIPEthernet library. EthernetENC library is compatible with all Arduino architectures with Arduino SPI library with transactions support. url=https://github.com/jandrassy/EthernetENC/wiki architectures=* -version=2.0.2 +version=2.0.3 category=Communication includes=EthernetENC.h dot_a_linkage=true From 7809a0f8a8bb3e08cdad3b53c9b0cf293e9744ec Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 5 Feb 2023 07:58:25 +0100 Subject: [PATCH 13/28] Revert "buymeacoffee" This reverts commit fe7e7b9c0bca0a13de121d5061258ddafaf67d09. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 22e8478..7b0433b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -Buy Me A Coffee EthernetENC is the Ethernet library for ENC28J60. It is a modern version of [the UIPEthernet library](https://github.com/jandrassy/EthernetENC/wiki/UIPEthernet). From d043333cfef70e094c53cd598daa3d40ef8babcd Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 7 May 2023 15:17:44 +0200 Subject: [PATCH 14/28] uip_arp.c - workaround for weird crash on RP2040 in uip_arp_update any attempt to retrieve value from ipaddr location crashes. memcmp works. --- src/utility/uip_arp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utility/uip_arp.c b/src/utility/uip_arp.c index 44ca7c4..86b4df8 100644 --- a/src/utility/uip_arp.c +++ b/src/utility/uip_arp.c @@ -170,8 +170,7 @@ uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) /* Check if the source IP address of the incoming packet matches the IP address in this ARP table entry. */ - if(ipaddr[0] == tabptr->ipaddr[0] && - ipaddr[1] == tabptr->ipaddr[1]) { + if(memcmp(ipaddr, tabptr->ipaddr, 4) == 0) { /* An old entry found, update this and return. */ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); From 441a30acc07abbed19002ea6636e93944e090e09 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Tue, 29 Aug 2023 20:19:50 +0200 Subject: [PATCH 15/28] ARP table cleanup was not invoked --- src/Ethernet.cpp | 14 ++++++++++++++ src/Ethernet.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/Ethernet.cpp b/src/Ethernet.cpp index 919003d..5f2013e 100644 --- a/src/Ethernet.cpp +++ b/src/Ethernet.cpp @@ -40,6 +40,7 @@ IPAddress UIPEthernetClass::_dnsServerAddress; DhcpClass* UIPEthernetClass::_dhcp(NULL); unsigned long UIPEthernetClass::periodic_timer; +unsigned long UIPEthernetClass::arp_timer; // Because uIP isn't encapsulated within a class we have to use global // variables, so we can only have one TCP/IP stack per program. @@ -178,6 +179,13 @@ UIPEthernetClass::tick() { if (!initialized) return; + + // run ARP table cleanup every 10 seconds as required by a comment in uip_arp.h + if (millis() - arp_timer > 10000) { + arp_timer = millis(); + uip_arp_timer(); + } + if (in_packet == NOBLOCK) { in_packet = Enc28J60Network::receivePacket(); @@ -488,3 +496,9 @@ uip_udpchksum(void) #endif UIPEthernetClass Ethernet; + +extern "C" void serialPrint(int i); +void serialPrint(int i) { + Serial.println(i); + Serial.flush(); +} diff --git a/src/Ethernet.h b/src/Ethernet.h index 62d2c35..48143b1 100644 --- a/src/Ethernet.h +++ b/src/Ethernet.h @@ -109,6 +109,7 @@ class UIPEthernetClass static DhcpClass* _dhcp; static unsigned long periodic_timer; + static unsigned long arp_timer; static void init(const uint8_t* mac); static void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); From bdc6ad1ebb43d420f960cbab99abb5ae6c201ac2 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Tue, 29 Aug 2023 20:21:07 +0200 Subject: [PATCH 16/28] version 2.0.4 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index b54648c..09ee74a 100644 --- a/library.properties +++ b/library.properties @@ -5,7 +5,7 @@ sentence=Ethernet library for ENC28J60. Only include EthernetENC.h instead of Et paragraph=This is a modern version of the UIPEthernet library. EthernetENC library is compatible with all Arduino architectures with Arduino SPI library with transactions support. url=https://github.com/jandrassy/EthernetENC/wiki architectures=* -version=2.0.3 +version=2.0.4 category=Communication includes=EthernetENC.h dot_a_linkage=true From 73bb4c9d37759b9a34dea745956a4b81eb96a557 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Wed, 27 Sep 2023 20:50:34 +0200 Subject: [PATCH 17/28] EthernetServer - added begin(port) and ctor without parameters --- src/EthernetServer.cpp | 6 ++++++ src/EthernetServer.h | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/EthernetServer.cpp b/src/EthernetServer.cpp index 4a51a4f..9237ad9 100644 --- a/src/EthernetServer.cpp +++ b/src/EthernetServer.cpp @@ -64,6 +64,12 @@ void UIPServer::begin() listening = true; } +void UIPServer::begin(uint16_t port) +{ + _port = port; + begin(); +} + void UIPServer::end() { uip_unlisten(_port); listening = false; diff --git a/src/EthernetServer.h b/src/EthernetServer.h index 1dae460..fec7006 100644 --- a/src/EthernetServer.h +++ b/src/EthernetServer.h @@ -24,10 +24,11 @@ class EthernetServer { public: - EthernetServer(uint16_t); + EthernetServer(uint16_t port = 80); EthernetClient available(); EthernetClient accept(); void begin(); + void begin(uint16_t port); void end(); operator bool(); @@ -42,7 +43,7 @@ class EthernetServer { class EthernetServerPrint : public EthernetServer, public Print { public: - EthernetServerPrint(uint16_t port) : EthernetServer(port) {} + EthernetServerPrint(uint16_t port = 80) : EthernetServer(port) {} virtual size_t write(uint8_t); virtual size_t write(const uint8_t *buf, size_t size); From 2535523e332c2dc7f1261c7239d5121bf779bbb5 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Wed, 27 Sep 2023 20:56:23 +0200 Subject: [PATCH 18/28] Ethernet.h setDnsServerIP added --- src/Ethernet.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Ethernet.h b/src/Ethernet.h index 48143b1..ec097d4 100644 --- a/src/Ethernet.h +++ b/src/Ethernet.h @@ -98,6 +98,8 @@ class UIPEthernetClass IPAddress gatewayIP(); IPAddress dnsServerIP(); + void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; } + private: static bool initialized; static memhandle in_packet; From 3088294bd4c4baa46fb7fc97656b0ddae4e0cc04 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Fri, 29 Sep 2023 19:55:06 +0200 Subject: [PATCH 19/28] EthernetClient - status() added --- src/EthernetClient.cpp | 8 +++++++- src/EthernetClient.h | 2 ++ src/tcp_states.h | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/tcp_states.h diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index 0e75552..0b619a1 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -369,7 +369,13 @@ uint16_t UIPClient::remotePort(void) { return data ? ntohs(uip_conns[data->conn_index].rport) : 0; -} +} + +uint8_t +UIPClient::status() +{ + return !data ? UIP_CLOSED : uip_conns[data->conn_index].tcpstateflags & UIP_TS_MASK; +} void uipclient_appcall(void) diff --git a/src/EthernetClient.h b/src/EthernetClient.h index d78c769..094eca7 100644 --- a/src/EthernetClient.h +++ b/src/EthernetClient.h @@ -77,6 +77,8 @@ class EthernetClient : public Client { IPAddress remoteIP(); uint16_t remotePort(); + + uint8_t status(); private: EthernetClient(struct uip_conn *_conn); diff --git a/src/tcp_states.h b/src/tcp_states.h new file mode 100644 index 0000000..02864da --- /dev/null +++ b/src/tcp_states.h @@ -0,0 +1,21 @@ + +#ifndef UIP_TCP_STATES_H +#define UIP_TCP_STATES_H + +#include + +// common constants for client.state() return values +enum uip_tcp_state { + CLOSED = UIP_CLOSED, + SYN_SENT = UIP_SYN_SENT, + SYN_RCVD = UIP_SYN_RCVD, + ESTABLISHED = UIP_ESTABLISHED, + FIN_WAIT_1 = UIP_FIN_WAIT_1, + FIN_WAIT_2 = UIP_FIN_WAIT_2, + CLOSE_WAIT = 10, // not used + CLOSING = UIP_CLOSING, + LAST_ACK = UIP_LAST_ACK, + TIME_WAIT = UIP_TIME_WAIT +}; + +#endif From f233296787af62d939127f2c48017e3c39fe898b Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 1 Oct 2023 13:54:20 +0200 Subject: [PATCH 20/28] Ethernet - getter macAddress and dnsIP and settter setDNS --- src/Ethernet.cpp | 10 ++++++++++ src/Ethernet.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/Ethernet.cpp b/src/Ethernet.cpp index 5f2013e..a79911e 100644 --- a/src/Ethernet.cpp +++ b/src/Ethernet.cpp @@ -145,6 +145,12 @@ EthernetHardwareStatus UIPEthernetClass::hardwareStatus() return EthernetENC28J60; } +uint8_t* UIPEthernetClass::macAddress(uint8_t* mac) +{ + memcpy(mac, uip_ethaddr.addr, 6); + return mac; +} + IPAddress UIPEthernetClass::localIP() { IPAddress ret; @@ -174,6 +180,10 @@ IPAddress UIPEthernetClass::dnsServerIP() return _dnsServerAddress; } +IPAddress UIPEthernetClass::dnsIP(int n) { + return (n == 0) ? _dnsServerAddress : IPAddress(); +} + void UIPEthernetClass::tick() { diff --git a/src/Ethernet.h b/src/Ethernet.h index ec097d4..dd8c299 100644 --- a/src/Ethernet.h +++ b/src/Ethernet.h @@ -92,13 +92,17 @@ class UIPEthernetClass EthernetLinkStatus linkStatus(); EthernetHardwareStatus hardwareStatus(); + + uint8_t* macAddress(uint8_t* mac); IPAddress localIP(); IPAddress subnetMask(); IPAddress gatewayIP(); IPAddress dnsServerIP(); + IPAddress dnsIP(int n = 0); void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; } + void setDNS(IPAddress dns_server) { _dnsServerAddress = dns_server; } private: static bool initialized; From e2b3a8ec9a027c78e35db9b804cb3d490b76d1f9 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 1 Oct 2023 15:13:47 +0200 Subject: [PATCH 21/28] Ethernet.hostByName added --- src/Ethernet.cpp | 13 +++++++++++++ src/Ethernet.h | 2 ++ src/EthernetClient.cpp | 6 +----- src/EthernetUdp.cpp | 6 +----- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/Ethernet.cpp b/src/Ethernet.cpp index a79911e..227620e 100644 --- a/src/Ethernet.cpp +++ b/src/Ethernet.cpp @@ -19,6 +19,7 @@ #include #include "Ethernet.h" +#include "Dns.h" #include "utility/Enc28J60Network.h" extern "C" @@ -184,6 +185,18 @@ IPAddress UIPEthernetClass::dnsIP(int n) { return (n == 0) ? _dnsServerAddress : IPAddress(); } +int UIPEthernetClass::hostByName(const char* hostname, IPAddress& result) +{ + // Look up the host first + int ret = 0; +#if UIP_UDP + DNSClient dns; + dns.begin(_dnsServerAddress); + ret = dns.getHostByName(hostname, result); +#endif + return ret; +} + void UIPEthernetClass::tick() { diff --git a/src/Ethernet.h b/src/Ethernet.h index dd8c299..4a9482a 100644 --- a/src/Ethernet.h +++ b/src/Ethernet.h @@ -104,6 +104,8 @@ class UIPEthernetClass void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; } void setDNS(IPAddress dns_server) { _dnsServerAddress = dns_server; } + int hostByName(const char* hostname, IPAddress& result); + private: static bool initialized; static memhandle in_packet; diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index 0b619a1..2d36150 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -25,7 +25,6 @@ extern "C" } #include "Ethernet.h" #include "EthernetClient.h" -#include "Dns.h" #define UIP_TCP_PHYH_LEN UIP_LLH_LEN+UIP_IPTCPH_LEN @@ -87,11 +86,8 @@ UIPClient::connect(const char *host, uint16_t port) // Look up the host first int ret = 0; #if UIP_UDP - DNSClient dns; IPAddress remote_addr; - - dns.begin(UIPEthernetClass::_dnsServerAddress); - ret = dns.getHostByName(host, remote_addr); + ret = Ethernet.hostByName(host, remote_addr); if (ret == 1) { return connect(remote_addr, port); } diff --git a/src/EthernetUdp.cpp b/src/EthernetUdp.cpp index e3d7cd1..242042c 100644 --- a/src/EthernetUdp.cpp +++ b/src/EthernetUdp.cpp @@ -19,7 +19,6 @@ #include "Ethernet.h" #include "EthernetUdp.h" -#include "Dns.h" extern "C" { #include "utility/uip-conf.h" @@ -149,11 +148,8 @@ UIPUDP::beginPacket(const char *host, uint16_t port) { // Look up the host first int ret = 0; - DNSClient dns; IPAddress remote_addr; - - dns.begin(Ethernet.dnsServerIP()); - ret = dns.getHostByName(host, remote_addr); + ret = Ethernet.hostByName(host, remote_addr); if (ret == 1) { return beginPacket(remote_addr, port); } else { From 323c226d9a2c9b2d8ef4a222434335bcd8cf4983 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 1 Oct 2023 15:57:05 +0200 Subject: [PATCH 22/28] EthernetClient.setConnectionTimeout added --- src/EthernetClient.cpp | 2 +- src/EthernetClient.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index 2d36150..2ab226a 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -52,7 +52,7 @@ UIPClient::connect(IPAddress ip, uint16_t port) if (conn) { #if UIP_CONNECT_TIMEOUT > 0 - uint32_t timeout = millis() + 1000 * UIP_CONNECT_TIMEOUT; + uint32_t timeout = millis() + connectTimeout; #endif while((conn->tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { diff --git a/src/EthernetClient.h b/src/EthernetClient.h index 094eca7..8807ece 100644 --- a/src/EthernetClient.h +++ b/src/EthernetClient.h @@ -79,12 +79,15 @@ class EthernetClient : public Client { uint16_t remotePort(); uint8_t status(); + + void setConnectionTimeout(uint16_t millis) {connectTimeout = millis;} private: EthernetClient(struct uip_conn *_conn); EthernetClient(uip_userdata_t* conn_data); uip_userdata_t* data; + uint16_t connectTimeout = 1000 * UIP_CONNECT_TIMEOUT; static uip_userdata_t all_data[UIP_CONNS]; static uip_userdata_t* _allocateData(); From 433dd3a0e4f88fe0a254f473fc489f7efa7f6a98 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 1 Oct 2023 19:03:48 +0200 Subject: [PATCH 23/28] Ethernet.setHostname added (hostname to send with DHCP request) --- src/Dhcp.cpp | 11 +++++++++++ src/Dhcp.h | 3 +++ src/Ethernet.cpp | 14 ++++++++++++-- src/Ethernet.h | 2 ++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Dhcp.cpp b/src/Dhcp.cpp index cc71c68..cfcd2f6 100644 --- a/src/Dhcp.cpp +++ b/src/Dhcp.cpp @@ -204,6 +204,7 @@ void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) // OPT - host name buffer[16] = hostName; + if (_hostname == nullptr) { buffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address strcpy((char*)&(buffer[18]), HOST_NAME); @@ -213,6 +214,12 @@ void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) //put data in W5100 transmit buffer _dhcpUdpSocket.write(buffer, 30); + } else { + uint8_t len = strlen(_hostname); + buffer[17] = len; + _dhcpUdpSocket.write(buffer, 18); + _dhcpUdpSocket.write(_hostname, len); + } if(messageType == DHCP_REQUEST) { @@ -468,6 +475,10 @@ IPAddress DhcpClass::getDnsServerIp() return IPAddress(_dhcpDnsServerIp); } +void DhcpClass::setHostname(const char* hostname) { + _hostname = hostname; +} + void DhcpClass::printByte(char * buf, uint8_t n ) { char *str = &buf[1]; buf[0]='0'; diff --git a/src/Dhcp.h b/src/Dhcp.h index febdd20..ec99072 100644 --- a/src/Dhcp.h +++ b/src/Dhcp.h @@ -141,6 +141,7 @@ class DhcpClass { uint32_t _dhcpInitialTransactionId; uint32_t _dhcpTransactionId; uint8_t _dhcpMacAddr[6]; + const char* _hostname = nullptr; #ifdef __arm__ uint8_t _dhcpLocalIp[4] __attribute__((aligned(4))); uint8_t _dhcpSubnetMask[4] __attribute__((aligned(4))); @@ -181,6 +182,8 @@ class DhcpClass { int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); int checkLease(); + + void setHostname(const char* hostname); }; #endif diff --git a/src/Ethernet.cpp b/src/Ethernet.cpp index 227620e..4b9df3e 100644 --- a/src/Ethernet.cpp +++ b/src/Ethernet.cpp @@ -56,11 +56,21 @@ void UIPEthernetClass::init(uint8_t csPin) } #if UIP_UDP +void +UIPEthernetClass::setHostname(const char* hostname) +{ + if (_dhcp == NULL) { + _dhcp = new DhcpClass(); + } + _dhcp->setHostname(hostname); +} + int UIPEthernetClass::begin(const uint8_t* mac, unsigned long timeout, unsigned long responseTimeout) { - static DhcpClass s_dhcp; - _dhcp = &s_dhcp; + if (_dhcp == NULL) { + _dhcp = new DhcpClass(); + } // Initialise the basic info init(mac); diff --git a/src/Ethernet.h b/src/Ethernet.h index 4a9482a..fc11500 100644 --- a/src/Ethernet.h +++ b/src/Ethernet.h @@ -104,6 +104,8 @@ class UIPEthernetClass void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; } void setDNS(IPAddress dns_server) { _dnsServerAddress = dns_server; } + void setHostname(const char* hostname); // only the pointer is stored! + int hostByName(const char* hostname, IPAddress& result); private: From ed0050a7427b3fee0a19e925be14f87870114532 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Fri, 6 Oct 2023 07:13:19 +0200 Subject: [PATCH 24/28] Ethernet - MACAddress as alias for macAddress getter --- src/Ethernet.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Ethernet.h b/src/Ethernet.h index fc11500..e9e0427 100644 --- a/src/Ethernet.h +++ b/src/Ethernet.h @@ -94,6 +94,7 @@ class UIPEthernetClass EthernetHardwareStatus hardwareStatus(); uint8_t* macAddress(uint8_t* mac); + void MACAddress(uint8_t *mac_address) { macAddress(mac_address); } IPAddress localIP(); IPAddress subnetMask(); From 3a50d3aa9c1510e4090d1763ec3e91c700b764a1 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 5 Nov 2023 14:52:43 +0100 Subject: [PATCH 25/28] Ethernet.end() added --- src/Ethernet.cpp | 22 ++++++++++++++++++++++ src/Ethernet.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/src/Ethernet.cpp b/src/Ethernet.cpp index 4b9df3e..df1c77f 100644 --- a/src/Ethernet.cpp +++ b/src/Ethernet.cpp @@ -117,7 +117,29 @@ UIPEthernetClass::begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddre configure(ip,dns,gateway,subnet); } +void UIPEthernetClass::end() +{ + //close all clients + for (int i = 0; i < UIP_CONNS; i++) + { + if (EthernetClient::all_data[i].state) { + EthernetClient client(&EthernetClient::all_data[i]); + client.stop(); + } + } + // handle clients closings + uint32_t st = millis(); + while (millis() - st < 3000) + { + tick(); + } + initialized = false; + configure(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE); +} + int UIPEthernetClass::maintain(){ + if (!initialized) + return 0; tick(); int rc = DHCP_CHECK_NONE; #if UIP_UDP diff --git a/src/Ethernet.h b/src/Ethernet.h index e9e0427..3f9ddbf 100644 --- a/src/Ethernet.h +++ b/src/Ethernet.h @@ -85,6 +85,8 @@ class UIPEthernetClass void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway); void begin(const uint8_t* mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); + void end(); + // maintain() must be called at regular intervals to process the incoming serial // data and issue IP events to the sketch. It does not return until all IP // events have been processed. Renews dhcp-lease if required. From d06811e7a195310321b4cf2d8a44d76e2ac0fc6e Mon Sep 17 00:00:00 2001 From: Hideaki Tai Date: Wed, 10 Jan 2024 14:45:10 +0900 Subject: [PATCH 26/28] fix: compile error on esp32 github actions (#58) good fix. thank you --- src/EthernetClient.cpp | 6 +++--- src/EthernetUdp.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index 2ab226a..636bc1d 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -534,9 +534,9 @@ UIPClient::_allocateData() uip_userdata_t* data = &UIPClient::all_data[sock]; if (!data->state) { - memset(data, 0, sizeof(uip_userdata_t)); - data->conn_index = uip_conn - uip_conns; // pointer arithmetics - data->state = UIP_CLIENT_CONNECTED; + *data = uip_userdata_t(); + data->conn_index = uip_conn - uip_conns; // pointer arithmetics + data->state = UIP_CLIENT_CONNECTED; return data; } } diff --git a/src/EthernetUdp.cpp b/src/EthernetUdp.cpp index 242042c..979037b 100644 --- a/src/EthernetUdp.cpp +++ b/src/EthernetUdp.cpp @@ -34,9 +34,9 @@ extern "C" { // Constructor UIPUDP::UIPUDP() : - _uip_udp_conn(NULL) + _uip_udp_conn(NULL), + appdata() { - memset(&appdata,0,sizeof(appdata)); } // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use @@ -68,7 +68,7 @@ UIPUDP::stop() Enc28J60Network::freeBlock(appdata.packet_in); _flushBlocks(appdata.packet_next); Enc28J60Network::freeBlock(appdata.packet_out); - memset(&appdata,0,sizeof(appdata)); + appdata = uip_udp_userdata_t(); } } From 20aff984d9eb6b0aa616410a2e9f2e6e8e090a24 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sat, 1 Jun 2024 12:00:19 +0200 Subject: [PATCH 27/28] README update - section about newer ENC28J60 libraries --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7b0433b..c7d7411 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ +First an important note: There are more suitable libraries for ENC28J60 with ESP8266, RP2040, ESP32 and Mbed Arduino platforms: + +* With ESP8266 and RP2040 platform you can use the EthernetCompat.h from the lwIP_enc28j60 bundled library. +* With ESP32 platform version 3 you can use the [EthernetESP32](https://github.com/Networking-for-Arduino/EthernetESP32) library which integrates with networking on the ESP32 platform. +* With Arduino Mbed Core boards you can use the [ENC28J60-EMAC](https://github.com/Networking-for-Arduino/ENC28J60-EMAC) library with the platforms Ethernet library + +--- + +# EthernetENC EthernetENC is the Ethernet library for ENC28J60. It is a modern version of [the UIPEthernet library](https://github.com/jandrassy/EthernetENC/wiki/UIPEthernet). @@ -12,13 +21,6 @@ The modernization includes: * has UDP backlog to receive more than one message at time * Arduino 1.5 library format built with dot_a_linkage option for optimal build result -
- Notes for ESP (click to expand) - -* *For esp8266 Arduino there is a much better option for enc28j60 than using this library. Use the lwIP_enc28j60 library bundled with esp8266 Arduino boards support package 3. (There is also a lwIP_w5500 and lwIP_w5100 library.)* -* *For ESP32 it is better than using a MAC layer module like the enc28j60 to use a PHY layer LAN module like LAN8720 supported by the ESP32 MAC peripheral and the Arduino boards support package.* -
- [The documentation of Arduino Ethernet library](https://www.arduino.cc/en/Reference/Ethernet) applies for classes and functions descriptions. Limitations: From 19664f609b9b864bd772b048f992afff4f75c214 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sat, 1 Jun 2024 12:00:37 +0200 Subject: [PATCH 28/28] version 2.0.5 --- library.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library.properties b/library.properties index 09ee74a..eecd621 100644 --- a/library.properties +++ b/library.properties @@ -3,9 +3,9 @@ author=Norbert Truchsess, Juraj Andrassy maintainer=Juraj Andrassy sentence=Ethernet library for ENC28J60. Only include EthernetENC.h instead of Ethernet.h paragraph=This is a modern version of the UIPEthernet library. EthernetENC library is compatible with all Arduino architectures with Arduino SPI library with transactions support. -url=https://github.com/jandrassy/EthernetENC/wiki +url=https://github.com/Networking-for-Arduino/EthernetENC/wiki architectures=* -version=2.0.4 +version=2.0.5 category=Communication includes=EthernetENC.h dot_a_linkage=true