Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lwIP on ethernet: examples #8395

Merged
merged 19 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 40 additions & 13 deletions cores/esp8266/LwipIntfDev.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,35 @@ class LwipIntfDev: public LwipIntf, public RawDev
return IPAddress(ip4_addr_get_u32(ip_2_ip4(&_netif.gw)));
}

void setDefault();
// 1. Currently when no default is set, esp8266-Arduino uses the first
// DHCP client interface receiving a valid address and gateway to
// become the new lwIP default interface.
// 2. Otherwise - when using static addresses - lwIP for every packets by
// defaults selects automatically the best suited output interface
// matching the destination address. If several interfaces match,
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
// checked first.
// 3. Or, use `::setDefault()` to force routing through this interface.
void setDefault(bool deflt = true);

// true if interface has a valid IPv4 address
bool connected()
{
return !!ip4_addr_get_u32(ip_2_ip4(&_netif.ip_addr));
}

bool routable()
{
return !ip_addr_isany(&_netif.gw);
}

// ESP8266WiFi API compatibility

wl_status_t status();

protected:
err_t netif_init();
void check_route();
void netif_status_callback();

static err_t netif_init_s(netif* netif);
Expand Down Expand Up @@ -184,10 +199,10 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
return false;
}

_netif.flags |= NETIF_FLAG_UP;

if (localIP().v4() == 0)
{
// IP not set, starting DHCP
_netif.flags |= NETIF_FLAG_UP;
switch (dhcp_start(&_netif))
{
case ERR_OK:
Expand All @@ -201,6 +216,12 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
return false;
}
}
else
{
// IP is set, static config
netif_set_link_up(&_netif);
netif_set_up(&_netif);
}

_started = true;

Expand Down Expand Up @@ -301,16 +322,25 @@ err_t LwipIntfDev<RawDev>::netif_init()
template<class RawDev>
void LwipIntfDev<RawDev>::netif_status_callback()
{
check_route();
if (connected())
{
if (_default || (netif_default == nullptr && !ip_addr_isany(&_netif.gw)))
sntp_stop();
sntp_init();
}
}

template<class RawDev>
void LwipIntfDev<RawDev>::check_route()
{
if (connected())
{
if (_default || (netif_default == nullptr && routable()))
{
// on user request,
// or if there is no current default interface, but a gateway is valid
// or if there is no current default interface, but our gateway is valid
netif_set_default(&_netif);
}
sntp_stop();
sntp_init();
}
else if (netif_default == &_netif)
{
Expand Down Expand Up @@ -386,13 +416,10 @@ err_t LwipIntfDev<RawDev>::handlePackets()
}

template<class RawDev>
void LwipIntfDev<RawDev>::setDefault()
void LwipIntfDev<RawDev>::setDefault(bool deflt)
{
_default = true;
if (connected())
{
netif_set_default(&_netif);
}
_default = deflt;
mcspr marked this conversation as resolved.
Show resolved Hide resolved
check_route();
}

#endif // _LWIPINTFDEV_H
14 changes: 8 additions & 6 deletions libraries/ESP8266mDNS/src/LEAmDNS_Transfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1766,11 +1766,13 @@ namespace MDNSImplementation
stcMDNS_RRAttributes attributes(DNS_RRTYPE_AAAA,
((p_rSendParameter.m_bCacheFlush ? 0x8000 : 0)
| DNS_RRCLASS_IN)); // Cache flush? & INternet
bool bResult = ((_writeMDNSHostDomain(m_pcHostname, false, p_rSendParameter)) && // esp8266.local
(_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS
(_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter)) && // TTL
(_write16(MDNS_IP6_SIZE, p_rSendParameter)) && // RDLength
(false /*TODO: IP6 version of: _udpAppendBuffer((uint32_t)p_IPAddress, MDNS_IP4_SIZE)*/)); // RData
bool bResult
= ((_writeMDNSHostDomain(m_pcHostname, false, p_rSendParameter)) && // esp8266.local
(_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS
(_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter))
&& // TTL
(_write16(MDNS_IP6_SIZE, p_rSendParameter)) && // RDLength
(false /*TODO: IP6 version of: _udpAppendBuffer((uint32_t)p_IPAddress, MDNS_IP4_SIZE)*/)); // RData

DEBUG_EX_ERR(if (!bResult) {
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_AAAA: FAILED!\n"));
Expand Down Expand Up @@ -1855,7 +1857,7 @@ namespace MDNSImplementation
p_rSendParameter.m_u16Offset))
&& (_writeMDNSRRDomain(hostDomain,
p_rSendParameter))) // Host, eg. esp8266.local
// Cache available for domain
// Cache available for domain
: ((MDNS_DOMAIN_COMPRESS_MARK
> ((u16CachedDomainOffset >> 8) & ~MDNS_DOMAIN_COMPRESS_MARK))
&& // Valid offset
Expand Down
89 changes: 89 additions & 0 deletions libraries/lwIP_Ethernet/examples/EthClient/EthClient.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
This sketch establishes a TCP connection to a "quote of the day" service.
It sends a "hello" message, and then prints received data.

This is Ethernet version of:
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino
*/

#include <LwipEthernet.h>

Wiznet5500lwIP eth(/*SS*/ 16); // <== adapt to your hardware

const char* host = "djxmmx.net";
const uint16_t port = 17;

void setup() {
Serial.begin(115200);

Serial.println("\nEthernet\n");

// 1. Currently when no default is set, esp8266-Arduino uses the first
// DHCP client interface receiving a valid address and gateway to
// become the new lwIP default interface.
// 2. Otherwise - when using static addresses - lwIP for every packets by
// defaults selects automatically the best suited output interface
// matching the destination address. If several interfaces match,
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
// checked first.
// 3. Or, use `::setDefault()` to force routing through this interface.
// eth.setDefault(); // default route set through this interface

if (!ethInitDHCP(eth)) {
Serial.printf("no hardware found\n");
while (1) {
delay(1000);
}
}

while (!eth.connected()) {
Serial.printf(".");
delay(1000);
}

Serial.printf("Ethernet: IP Address: %s\n",
eth.localIP().toString().c_str());
}

void loop() {

Serial.print("connecting to ");
Serial.print(host);
Serial.print(':');
Serial.println(port);

// Use WiFiClient class to create TCP connections
// (this class could have been named TCPClient)
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("connection failed");
delay(5000);
return;
}

// This will send a string to the server
Serial.println("sending data to server");
if (client.connected()) { client.println("hello from ESP8266"); }

// wait for data to be available
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
delay(60000);
return;
}
}

// Read all the lines of the reply from server and print them to Serial
Serial.println("receiving from remote server");
client.sendAll(Serial); // this peer closes once all data are sent

// Close the connection
Serial.println();
Serial.println("closing connection");
client.stop();

delay(300000); // execute once every 5 minutes, don't flood remote service
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
This sketch establishes a TCP connection to a "quote of the day" service.
It sends a "hello" message, and then prints received data.

This is Ethernet version of:
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino
*/

#include <LwipEthernet.h>

#define LOCAL_IP IPAddress(192, 168, 0, 233)
#define LOCAL_GW IPAddress(192, 168, 0, 254) // <== adapt to your network
#define LOCAL_MASK IPAddress(255, 255, 255, 0)
#define DNS IPAddress(8, 8, 8, 8)

Wiznet5500lwIP eth(/*SS*/ 16); // <== adapt to your hardware

const char* host = "djxmmx.net";
const uint16_t port = 17;

void setup() {
Serial.begin(115200);

Serial.println("\nEthernet\n");

// 1. Currently when no default is set, esp8266-Arduino uses the first
// DHCP client interface receiving a valid address and gateway to
// become the new lwIP default interface.
// 2. Otherwise - when using static addresses - lwIP for every packets by
// defaults selects automatically the best suited output interface
// matching the destination address. If several interfaces match,
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
// checked first.
// 3. Or, use `::setDefault()` to force routing through this interface.
// eth.setDefault(true); // default route set through this interface

if (!ethInitStatic(eth, LOCAL_IP, LOCAL_GW, LOCAL_MASK, DNS)) {
// enabling debug message will show the real cause
Serial.printf("no hardware found or bad network configuration\n");
while (1) {
delay(1000);
}
}

Serial.printf("Ethernet: IP Address: %s\n",
eth.localIP().toString().c_str());
}

void loop() {

Serial.print("connecting to ");
Serial.print(host);
Serial.print(':');
Serial.println(port);

// Use WiFiClient class to create TCP connections
// (this class could have been named TCPClient)
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("connection failed");
delay(5000);
return;
}

// This will send a string to the server
Serial.println("sending data to server");
if (client.connected()) {
client.println("hello from ESP8266");
}

// wait for data to be available
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
delay(60000);
return;
}
}

// Read all the lines of the reply from server and print them to Serial
Serial.println("receiving from remote server");
client.sendAll(Serial); // this peer closes once all data are sent

// Close the connection
Serial.println();
Serial.println("closing connection");
client.stop();

delay(600000); // execute once every 10 minutes, don't flood remote service
}
Loading