New lwIP-based Ethernet library for Teensy 4.1

Sure, I can include an HTTP client. I’ll probably do it a little differently, though.

Other changes I’m planning:
1. Decouple the driver initialization from setting the MAC
2. Add a small capabilities API for determining what the driver supports
3. Not sure when or if — support for a more modern TLS library, eg. MbedTLS 3 or maybe even WolfSSL
4. Not sure when or if — more TLS examples
5. Maybe — Even more examples

Nos. 1 & 2 are almost complete, 5 I think about from time to time, and 3 & 4 are on my mind.
 
Some more ideas I’m thinking about:

6. A set of functions that do the things that are very repetitive when starting, and creating, an Ethernet-based app. (I have many thoughts about this for better Arduino app development too.) (Remember Borland’s OWL framework?) (I don’t want to get too far down the “app builder” rabbit hole, however.)

7. IPv6, IEEE 1588 (Precision Time Protocol (PTP)) and associated things, on-device crypto for use with TLS (and an independent crypto library), C++11 support for other boards. (Fun fact: I have all these things working, except for some minor details here and there.)

8. An Arduino API layer of sorts that lets me support all the Arduino API parts but lets me exclude the parts I don’t like.
 
I just released v0.30.0. Here's the Changelog:

Markdown (GitHub flavored):
## [0.30.0]

### Added
* Added a _SimpleHTTPClient_ example.
* Added a way to get the driver capabilities:
  `EthernetClass::driverCapabilities()` and `driver_get_capabilities(dc)`.
* Added a way to get the library version: `EthernetClass::libraryVersion()`.
* New `QNETHERNET_DO_LOOP_IN_YIELD` configuration macro for indicating that
  the library should attempt to hook into or override `yield()` to
  call `Ethernet.loop()`.
* New version of `receiveQueueSize()` in `EthernetUDP` and `EthernetFrame` that
  returns the number of unprocessed packets or frames.
* Added `droppedReceiveCount()` and `totalReceiveCount()` to `EthernetUDP`
  and `EthernetFrame`.
* Added `driver_set_link_speed(speed)` and `driver_set_link_full_duplex(flag)`.
* Added `EthernetClass::renewDHCP()`.
* Added `EthernetClass::interfaceName()`.
* Added `setOutgoingTTL(ttl)` and `outgoingTTL()` functions for modifying and
  accessing the TTL field, respectively, in the outgoing IP header, to
  `EthernetClient` and `EthernetUDP`.
* Added `EthernetUDP::receivedTTL()` for retrieving the TTL value of the last
  received packet.
* Added "Compatibility with other APIs" section to the README.

### Changed
* Separated setting the MAC address from driver initialization.
* Changed the netif name to "en0".
* Added macro-gated calls to `Ethernet.loop()` after any `yield()`s in case an
  overridden version doesn't call this. This affects:
  * `DNSClient::getHostByName()`
  * `EthernetClass::waitForLink()`
  * `EthernetClass::waitForLocalIP()`
  * `EthernetClient::connect()`
  * `EthernetClient::stop()`
* Updated example `yield()` implementation notes for
  non-EventResponder versions.
* Changed `setReceiveQueueSize(size)` to `setReceiveQueueCapacity(capacity)`
  and `receiveQueueSize()` to `receiveQueueCapacity()` in both `EthernetUDP`
  and `EthernetFrame`.
* Updated `QNETHERNET_ENABLE_RAW_FRAME_LOOPBACK` behaviour to also check for
  the broadcast MAC addresses.
* Added `FLASHMEM` to some driver functions.
* Changed `EthernetClass` and `MDNSClass` `hostname()` function to return a
  `const char *` instead of a `String`.
* Now always setting the DNS in `EthernetClass::begin(ip, mask, gateway, dns)`,
  even if it's zero.
* Use rename instead of end-then-start when the netif has already been added,
  in `MDNSClass::begin(hostname)`.
* DHCP is started when just the IP address is the "any" address instead of all
  of the IP address, netmask, and gateway.
* `begin(ip, mask, gateway, dns)` now always sets the DNS address.
* `Ethernet.broadcastIP()` now returns 255.255.255.255 if Ethernet is
  not initialized.

### Removed
* Removed `EthernetClass::isLinkStateDetectable()` in favour of the
  driver capabilities.
* Removed `get_uint32(ip)` utility function because a `static_cast<uint32_t>()`
  is sufficient.

### Fixed
* Fixed iperf v2 tests by commenting out per-block settings compare.
* Fixed restarting the netif by also bringing the link down.
* Fixed a bug related to closing a TCP socket when using altcp.

Highlights:
* New SimpleHTTPClient example
* Driver capabilities API
* yield() call flexibility
* Some new API functions
* Various bug fixes

Link: https://github.com/ssilverman/QNEthernet/releases/tag/v0.30.0
 
Just updated my arduino system. Big mistake.
QNEthernet compile is now complaining that it can't to static case of 32-bit unsigned to IPADDRESS.
Any ideas?
 
Show me the code?

I know this works:
C++:
uint32_t x = static_cast<uint32_t>(addr);

Update: I re-read your post and I think you mean this?
C++:
uint32_t x = 0;
IPAddress y{x};  // Parentheses should also work

IPAddress has a uint32_t constructor. It’s not possible to static cast a uint32_t to an IPAddress.
 
Last edited:
Code:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp: In member function 'bool qindesign::network::EthernetClass::begin(const IPAddress&, const IPAddress&, const IPAddress&, const IPAddress*)':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:225:45: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip4_addr_t ipaddr{static_cast<uint32_t>(ip)};

Several of those messages.


Here's the whole compilation message (long and messy):
Code:
FQBN: teensy:avr:teensy41
Using board 'teensy41' from platform in folder: /Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2
Using core 'teensy4' from platform in folder: /Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2

Detecting libraries used...

Lots of okay stuff snipped...

In file included from /Volumes/Data/Embedded/PPCapture/PPCapture.ino:20:0:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:348:56: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionCount([[maybe_unused]] uint8_t number) const {}
                                                        ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:350:59: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionTimeout([[maybe_unused]] uint16_t milliseconds) const {}
                                                           ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:429:23: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool maybeStartDHCP();
                       ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:435:14: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool start();
              ^
Compiling libraries...

Additional Okay stuff snipped...

In file included from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:7:0:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:348:56: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionCount([[maybe_unused]] uint8_t number) const {}
                                                        ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:350:59: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionTimeout([[maybe_unused]] uint16_t milliseconds) const {}
                                                           ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:429:23: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool maybeStartDHCP();
                       ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:435:14: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool start();
              ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp: In member function 'bool qindesign::network::EthernetClass::begin(const IPAddress&, const IPAddress&, const IPAddress&, const IPAddress*)':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:225:45: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip4_addr_t ipaddr{static_cast<uint32_t>(ip)};
                                             ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:226:48: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip4_addr_t netmask{static_cast<uint32_t>(mask)};
                                                ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:227:46: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip4_addr_t gw{static_cast<uint32_t>(gateway)};
                                              ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp: In member function 'bool qindesign::network::EthernetClass::start()':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:303:3: error: 'snprintf' is not a member of 'std'
   std::snprintf(&ifName_[2], sizeof(ifName_) - 2, "%u", netif_->num);
   ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:303:3: note: suggested alternative:
In file included from /Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/wchar.h:4:0,
                 from /Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/c++/5.4.1/cwchar:44,
                 from /Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/c++/5.4.1/bits/postypes.h:40,
                 from /Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/c++/5.4.1/bits/char_traits.h:40,
                 from /Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/c++/5.4.1/string:40,
                 from /Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/c++/5.4.1/stdexcept:39,
                 from /Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/c++/5.4.1/array:38,
                 from /Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/c++/5.4.1/tuple:39,
                 from /Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/c++/5.4.1/functional:55,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:12,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:7:
/Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/arm-none-eabi/include/stdio.h:266:5: note:   'snprintf'
 int _EXFUN(snprintf, (char *__restrict, size_t, const char *__restrict, ...)
     ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp: In member function 'void qindesign::network::EthernetClass::setLocalIP(const IPAddress&) const':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:613:45: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip4_addr_t ipaddr{static_cast<uint32_t>(ip)};
                                             ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp: In member function 'void qindesign::network::EthernetClass::setSubnetMask(const IPAddress&) const':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:625:54: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip4_addr_t netmask{static_cast<uint32_t>(subnetMask)};
                                                      ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp: In member function 'void qindesign::network::EthernetClass::setGatewayIP(const IPAddress&) const':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:637:41: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip4_addr_t gw{static_cast<uint32_t>(ip)};
                                         ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp: In member function 'bool qindesign::network::EthernetClass::joinGroup(const IPAddress&) const':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:677:48: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip4_addr_t groupaddr{static_cast<uint32_t>(ip)};
                                                ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp: In member function 'bool qindesign::network::EthernetClass::leaveGroup(const IPAddress&) const':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.cpp:696:48: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip4_addr_t groupaddr{static_cast<uint32_t>(ip)};
                                                ^
/Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/bin/arm-none-eabi-gcc -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10607 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/cores/teensy4 -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_GFX_Library -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_BusIO -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/Wire -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/SPI -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_SH110X -I/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/ipv6/mld6.c -o /private/var/folders/13/fqsfj5688xl6n0006s6cl2vh0000gr/T/arduino/sketches/A9CBB7C5FF40034F7475A83204727AB4/libraries/QNEthernet/lwip/ipv6/mld6.c.o
/Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/bin/arm-none-eabi-gcc -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10607 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/cores/teensy4 -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_GFX_Library -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_BusIO -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/Wire -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/SPI -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_SH110X -I/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/ipv6/nd6.c -o /private/var/folders/13/fqsfj5688xl6n0006s6cl2vh0000gr/T/arduino/sketches/A9CBB7C5FF40034F7475A83204727AB4/libraries/QNEthernet/lwip/ipv6/nd6.c.o
/Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/bin/arm-none-eabi-gcc -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10607 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/cores/teensy4 -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_GFX_Library -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_BusIO -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/Wire -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/SPI -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_SH110X -I/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/memp.c -o /private/var/folders/13/fqsfj5688xl6n0006s6cl2vh0000gr/T/arduino/sketches/A9CBB7C5FF40034F7475A83204727AB4/libraries/QNEthernet/lwip/memp.c.o
/Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/bin/arm-none-eabi-gcc -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10607 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/cores/teensy4 -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_GFX_Library -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_BusIO -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/Wire -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/SPI -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_SH110X -I/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/netif.c -o /private/var/folders/13/fqsfj5688xl6n0006s6cl2vh0000gr/T/arduino/sketches/A9CBB7C5FF40034F7475A83204727AB4/libraries/QNEthernet/lwip/netif.c.o
/Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/bin/arm-none-eabi-gcc -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10607 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/cores/teensy4 -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_GFX_Library -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_BusIO -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/Wire -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/SPI -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_SH110X -I/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/mem.c -o /private/var/folders/13/fqsfj5688xl6n0006s6cl2vh0000gr/T/arduino/sketches/A9CBB7C5FF40034F7475A83204727AB4/libraries/QNEthernet/lwip/mem.c.o
/Users/rhyde/Library/Arduino15/packages/teensy/tools/teensy-compile/5.4.1/arm/bin/arm-none-eabi-gcc -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=157 -DARDUINO=10607 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/cores/teensy4 -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_GFX_Library -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_BusIO -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/Wire -I/Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/SPI -I/Users/rhyde/Documents/Arduino/libraries/Adafruit_SH110X -I/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/pbuf.c -o /private/var/folders/13/fqsfj5688xl6n0006s6cl2vh0000gr/T/arduino/sketches/A9CBB7C5FF40034F7475A83204727AB4/libraries/QNEthernet/lwip/pbuf.c.o
In file included from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNDNSClient.cpp:14:0:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:348:56: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionCount([[maybe_unused]] uint8_t number) const {}
                                                        ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:350:59: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionTimeout([[maybe_unused]] uint16_t milliseconds) const {}
                                                           ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:429:23: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool maybeStartDHCP();
                       ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:435:14: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool start();
              ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNDNSClient.cpp:25:59: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
 void DNSClient::dnsFoundFunc([[maybe_unused]] const char *name,
                                                           ^
In file included from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNDNSClient.h:19:0,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNDNSClient.cpp:7:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNDNSClient.cpp: In static member function 'static bool qindesign::network::DNSClient::setServer(int, const IPAddress&)':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNDNSClient.cpp:44:55: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip_addr_t addr IPADDR4_INIT(static_cast<uint32_t>(ip));
                                                       ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/ip_addr.h:295:51: note: in definition of macro 'IPADDR4_INIT'
 #define IPADDR4_INIT(u32val)                    { u32val }
                                                   ^
In file included from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetClient.cpp:17:0:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:348:56: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionCount([[maybe_unused]] uint8_t number) const {}
                                                        ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:350:59: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionTimeout([[maybe_unused]] uint16_t milliseconds) const {}
                                                           ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:429:23: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool maybeStartDHCP();
                       ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:435:14: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool start();
              ^
In file included from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/ip.h:46:0,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/tcp.h:48,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/altcp.h:150,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/internal/ConnectionState.h:17,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/internal/ConnectionHolder.h:16,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetClient.h:22,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetClient.cpp:7:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetClient.cpp: In member function 'bool qindesign::network::EthernetClient::connectNoWait(const IPAddress&, uint16_t)':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetClient.cpp:89:57: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip_addr_t ipaddr IPADDR4_INIT(static_cast<uint32_t>(ip));
                                                         ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/ip_addr.h:295:51: note: in definition of macro 'IPADDR4_INIT'
 #define IPADDR4_INIT(u32val)                    { u32val }
                                                   ^
In file included from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetUDP.cpp:16:0:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:348:56: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionCount([[maybe_unused]] uint8_t number) const {}
                                                        ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:350:59: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionTimeout([[maybe_unused]] uint16_t milliseconds) const {}
                                                           ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:429:23: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool maybeStartDHCP();
                       ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:435:14: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool start();
              ^
In file included from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetUDP.h:23:0,
                 from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetUDP.cpp:7:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetUDP.cpp: In member function 'bool qindesign::network::EthernetUDP::send(const IPAddress&, uint16_t, const uint8_t*, size_t)':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetUDP.cpp:498:57: error: invalid static_cast from type 'const IPAddress' to type 'uint32_t {aka long unsigned int}'
   ip_addr_t ipaddr IPADDR4_INIT(static_cast<uint32_t>(ip));
                                                         ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/lwip/ip_addr.h:295:51: note: in definition of macro 'IPADDR4_INIT'
 #define IPADDR4_INIT(u32val)                    { u32val }
                                                   ^
In file included from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernetServer.cpp:14:0:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:348:56: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionCount([[maybe_unused]] uint8_t number) const {}
                                                        ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:350:59: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionTimeout([[maybe_unused]] uint16_t milliseconds) const {}
                                                           ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:429:23: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool maybeStartDHCP();
                       ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:435:14: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool start();
              ^
In file included from /Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/internal/ConnectionManager.cpp:18:0:
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:348:56: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionCount([[maybe_unused]] uint8_t number) const {}
                                                        ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:350:59: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
   void setRetransmissionTimeout([[maybe_unused]] uint16_t milliseconds) const {}
                                                           ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:429:23: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool maybeStartDHCP();
                       ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/QNEthernet.h:435:14: warning: 'nodiscard' attribute directive ignored [-Wattributes]
   bool start();
              ^
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/internal/ConnectionManager.cpp: In member function 'void qindesign::network::internal::ConnectionManager::addConnection(const std::shared_ptr<qindesign::network::internal::ConnectionHolder>&)':
/Users/rhyde/Documents/Arduino/libraries/QNEthernet/src/internal/ConnectionManager.cpp:253:69: warning: 'maybe_unused' attribute directive ignored [-Wattributes]
                                   [[maybe_unused]] ConnectionState *state) {
                                                                     ^

Using library Adafruit GFX Library at version 1.11.9 in folder: /Users/rhyde/Documents/Arduino/libraries/Adafruit_GFX_Library
Using library Adafruit BusIO at version 1.16.1 in folder: /Users/rhyde/Documents/Arduino/libraries/Adafruit_BusIO
Using library Wire at version 1.0 in folder: /Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/Wire
Using library SPI at version 1.0 in folder: /Users/rhyde/Library/Arduino15/packages/teensy/hardware/avr/1.57.2/libraries/SPI
Using library Adafruit SH110X at version 2.1.10 in folder: /Users/rhyde/Documents/Arduino/libraries/Adafruit_SH110X
Using library QNEthernet at version 0.30.1 in folder: /Users/rhyde/Documents/Arduino/libraries/QNEthernet
exit status 1

Compilation error: exit status 1
 
That code (line 225) is correct. Which version of the Arduino IDE are you using, and which version of Teensyduino? Older versions of Teensyduino don’t yet have support for casting a const IPAddress to a uint32_t. I removed the custom code that fixes this because the last few versions of Teensyduino have the correct thing.
 
This was compiling fine yesterday, before I foolishly allowed Arduino to update itself and the libraries.
 
I can help. But first, which version of Teensyduino are you using? May I suggest updating to 1.59? That should fix the problem.
 
I just released v0.31.0. Here's the changelog:
Code:
## [0.31.0]

### Added
* Added `qnethernet_hal_fill_entropy(buf, size)` for filling a buffer with
  random values.
* Added `EthernetClient::setConnectionTimeoutEnabled(flag)` to enable or disable
  blocking with calls to `connect(...)` and `stop()`. This supersedes calls to
  `connectNoWait(...)` and `close()`. Also added `isConnectionTimeoutEnabled()`.
* Added templated versions of `util::writeFully()` and `util::writeMagic()` that
  use a break function that static_casts a given object to a `bool`.
* Added `EthernetClient::connecting()` for determining if the client is still in
  the process of connecting during a non-blocking connect.

### Changed
* Remove internal uses of `String` from `MDNSClass` and replace them with
  char arrays.
* Updated Mbed TLS version mentions to 2.28.9 from 2.28.8.
* Made `EthernetClient::isNoDelay()` `const`.
* Disallow compilation for Teensyduino < 1.59 because there's no support for
  casting a `const IPAddress` to a `uint32_t` or for equality-comparing them.
* Replaced `EthernetClient::writeFully(const char *, size_t)` and
  `writeFully(const uint8_t *, size_t)` with `writeFully(const void *, size_t)`.
* Updated the file structure to put most sources underneath _src/qnethernet/_.
* Changed `EthernetClient::setConnectionTimeout(timeout)` and
  `connectionTimeout()` to use 32-bit values.
* Renamed `qnethernet_hal_rand()` and `qnethernet_hal_init_rand()` to
  `qnethernet_hal_entropy()` and `qnethernet_hal_init_entropy()`, respectively.
* Changed the non-entropy version of the entropy functions in the HAL to use
  `std::minstd_rand` instead of `std::rand()` and `std::srand()`.
* Changed uses of "www.example.com" to "www.google.com" in the examples
  and tests.

### Fixed
* Now using `(void)` instead of `()` for all C function declarations because
  `()` doesn't mean "no parameters" in C.
* Fixed `driver_unsupported`'s `driver_init(void)` parameters to be empty.

Highlights:
* New `EthernetClient::setConnectionTimeoutEnabled(flag)` function
* New `EthernetClient::connecting()` function
* Now disallowing Teensyduino versions less than 1.59
* New file structure
* C function declaration fixes

Link: https://github.com/ssilverman/QNEthernet/releases/tag/v0.31.0
 
I just released v0.32.0. Here's the changelog:
Code:
## [0.32.0]

### Added
* Added `qnethernet_hal_micros()`.
* Added secure TCP initial sequence numbers (ISNs), enabled with the new
  `QNETHERNET_ENABLE_SECURE_TCP_ISN` macro. The default is enabled.

### Changed
* Changed some functions to take a `void*` instead of a `uint8_t*`.
* Changed definition of `TCP_MSS` to be based on `MTU` instead of being
  a constant.
* Updated _LinkWatcher_ example to only print detectable details.

### Fixed
* Restored automatic entropy initialization when including
  `qnethernet/security/RandomDevice.h`. Calling `qnethernet_hal_entropy()` or
  `qnethernet_hal_fill_entropy()` will generate random values again without a
  prior call to `qnethernet_hal_init_entropy()` or `RandomDevice::instance()`.
  This also affects lwIP's internal `LWIP_RAND()`.

Highlights:
* Secure TCP initial sequence numbers (ISNs)
* void* instead of uint8_t* for some functions
* LinkWatcher example update to print only detectable details
* Fixed automatic entropy initialization

Link: https://github.com/ssilverman/QNEthernet/releases/tag/v0.32.0
 
I just released v0.33.0. Here's the changelog:
Markdown (GitHub flavored):
## [0.33.0]

### Added
* Added a way to iterate over the internal TCP connection PCBs.
* Added calls to `Ethernet.loop()` in more places.
* Added setting `errno` to `ENETDOWN` in `EthernetClass` in more places where
  network initialization is checked.
* Added setting `errno` to `ENOSYS` when some networking feature
  isn't implemented.
* Added support for ping (ICMP echo).
* Added two ping examples: _Ping_ and _SimplePing_.
* Added new configuration and default macros to _qnethernet_opts.h_:
  * `QNETHERNET_ENABLE_PING`
  * `QNETHERNET_DEFAULT_PING_ID`
  * `QNETHERNET_DEFAULT_PING_TIMEOUT`
  * `QNETHERNET_DEFAULT_PING_TTL`

### Changed
* Made `qnethernet_hal_get_system_mac_address(mac)` weak.
* Made `EthernetClass::hostByName(hostname, result)` `const`.
* Made `qnethernet_hal_get_system_mac_address(mac)` weak.
* Improved code style and structure.
* Changed `errno` value in `EthernetClass::joinGroup(ip)` if network is not
  initialized to `ENETDOWN` from `ENOTCONN`.
* Updated lwIP to latest master (4599f551).

Highlights:
* Code style and structure improvements
* Iteration over all connections
* Utilizing ENOSYS when some networking feature isn't implemented
* Ping support, including two examples, _Ping_ and _SimplePing_

Link: https://github.com/ssilverman/QNEthernet/releases/tag/v0.33.0
 
Last edited:
Updated QNEthernet library feature list:
Code:
1. Compatible with the Arduino-style Ethernet API
2. Additional functions and features not in the Arduino-style API
3. Automatic MAC address detection on the Teensy platform; it's not necessary to
   initialize the library with your own MAC address for that platform
4. A DNS client
5. mDNS support
6. Raw Ethernet frame support
7. `stdio` output redirection support for `stdout` and `stderr`
8. VLAN tagging support
9. Zero-length UDP packets
10. UDP and raw frame receive buffering for when data arrives in bursts that are
    faster than the ability of the program to process them
11. Listeners to watch link, network interface, and address state
12. With some additions:
    1. IPv6
    2. IEEE 1588, Precision Time Protocol (PTP)
    3. TLS and TCP proxies
    4. IEEE 802.3az, Energy-Efficient Ethernet (EEE)
13. Client shutdown options: _close_ (start close process without waiting),
    _closeOutput_ (close just the output side, also called a "half-close"),
    _abort_ (shuts down the connection without going through the TCP close
    process), _stop_ (close and wait)
14. Ability to fully write data to a client connection
15. Multicast support
16. Promiscuous mode
17. `SO_REUSEADDR` support (see `EthernetServer` and `EthernetUDP`)
18. `TCP_NODELAY` support
19. Configuration via configuration macros
20. Non-blocking TCP connections
21. Teensy platform: Internal entropy generation functions to avoid the
    _Entropy_ lib dependency; this can be disabled with a configuration macro
22. A "random device" satisfying the _UniformRandomBitGenerator_ C++ named
    requirement that provides access to hardware-generated entropy (see "The
    The `RandomDevice` _UniformRandomBitGenerator_")
23. Driver support for:
    1. Teensy 4.1
    2. W5500
24. Straightforward to add new Ethernet frame drivers
25. Ability to toggle Nagle's algorithm for TCP
26. Ability to set some IP header fields: differentiated services (DiffServ)
    and TTL
27. Secure TCP initial sequence numbers (ISNs)
28. Ping (ICMP echo) support
29. Ability to disable ping replies

Security features:
Code:
1. True entropy, if the system supports it
2. Secure TCP initial sequence numbers (ISNs)
3. Ability to disable ping replies
 
Not sure if it's implemented or even feasible with lwip, but have you given any thought to supporting OOB (out of band) data? It's a bit similar to how USB device can have bulk and interrupt endpoints; the regular, "big" data traffic goes over bulk (regular TCP traffic in this case using read/write) while interrupt data is typically small/time sensitive (goes over the same TCP stream but marked as URGENT).

(It's also rather handy for security/metadata purposes: in the old days it was possible to crash some apps just by connecting to them and sending OOB data, their OS network API expected a signal handler to be registered to handle OOB data and the default handler for unhandled signals performed a task kill... see also: WinNuke)
 
Not sure if it's implemented or even feasible with lwip, but have you given any thought to supporting OOB (out of band) data? It's a bit similar to how USB device can have bulk and interrupt endpoints; the regular, "big" data traffic goes over bulk (regular TCP traffic in this case using read/write) while interrupt data is typically small/time sensitive (goes over the same TCP stream but marked as URGENT).

(It's also rather handy for security/metadata purposes: in the old days it was possible to crash some apps just by connecting to them and sending OOB data, their OS network API expected a signal handler to be registered to handle OOB data and the default handler for unhandled signals performed a task kill... see also: WinNuke)

I just did a little research and lwIP appears to ignore the URG flag and just sends all OOB data inline.
 
Last edited:
I see IEEE 1588, Precision Time Protocol in the features list. Did you add it to the master?
Great question. I’ve been keeping up a local copy of ieee1588-2, rebased onto master. I haven’t pushed it yet because I’m still deciding how I want to release it. Same with the IPv6-capable and EEE (energy-efficient Ethernet) versions.
 
Just checking because I used your ieee 1588-2 branch for my AES67 4.1 implementation. I did modify it to include QoS capabilities. QNEthernet is awesome thanks so much for all your work.
 
Back
Top