Skip to content

Commit 5f2af19

Browse files
authored
lwIP on ethernet: examples (#8395)
* ethernet: examples * remove duplicate * styling * fix comment restyle + comment eth.setdefault() * comment and add comments about eth.setDefault() * update comments when using interface::setDefault() * repair bad merge * fix default interface case * factorize * change comment
1 parent f5ef02d commit 5f2af19

File tree

13 files changed

+945
-110
lines changed

13 files changed

+945
-110
lines changed

cores/esp8266/LwipIntfDev.h

+41-13
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,36 @@ class LwipIntfDev: public LwipIntf, public RawDev
5959
return IPAddress(ip4_addr_get_u32(ip_2_ip4(&_netif.gw)));
6060
}
6161

62-
void setDefault();
62+
// 1. Currently when no default is set, esp8266-Arduino uses the first
63+
// DHCP client interface receiving a valid address and gateway to
64+
// become the new lwIP default interface.
65+
// 2. Otherwise - when using static addresses - lwIP for every packets by
66+
// defaults selects automatically the best suited output interface
67+
// matching the destination address. If several interfaces match,
68+
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
69+
// checked first.
70+
// 3. Or, use `::setDefault(true)` to force using this interface's gateway
71+
// as default router.
72+
void setDefault(bool deflt = true);
6373

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

80+
bool routable()
81+
{
82+
return !ip_addr_isany(&_netif.gw);
83+
}
84+
7085
// ESP8266WiFi API compatibility
7186

7287
wl_status_t status();
7388

7489
protected:
7590
err_t netif_init();
91+
void check_route();
7692
void netif_status_callback();
7793

7894
static err_t netif_init_s(netif* netif);
@@ -184,10 +200,10 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
184200
return false;
185201
}
186202

187-
_netif.flags |= NETIF_FLAG_UP;
188-
189203
if (localIP().v4() == 0)
190204
{
205+
// IP not set, starting DHCP
206+
_netif.flags |= NETIF_FLAG_UP;
191207
switch (dhcp_start(&_netif))
192208
{
193209
case ERR_OK:
@@ -201,6 +217,12 @@ boolean LwipIntfDev<RawDev>::begin(const uint8_t* macAddress, const uint16_t mtu
201217
return false;
202218
}
203219
}
220+
else
221+
{
222+
// IP is set, static config
223+
netif_set_link_up(&_netif);
224+
netif_set_up(&_netif);
225+
}
204226

205227
_started = true;
206228

@@ -301,16 +323,25 @@ err_t LwipIntfDev<RawDev>::netif_init()
301323
template<class RawDev>
302324
void LwipIntfDev<RawDev>::netif_status_callback()
303325
{
326+
check_route();
304327
if (connected())
305328
{
306-
if (_default || (netif_default == nullptr && !ip_addr_isany(&_netif.gw)))
329+
sntp_stop();
330+
sntp_init();
331+
}
332+
}
333+
334+
template<class RawDev>
335+
void LwipIntfDev<RawDev>::check_route()
336+
{
337+
if (connected())
338+
{
339+
if (_default || (netif_default == nullptr && routable()))
307340
{
308341
// on user request,
309-
// or if there is no current default interface, but a gateway is valid
342+
// or if there is no current default interface, but our gateway is valid
310343
netif_set_default(&_netif);
311344
}
312-
sntp_stop();
313-
sntp_init();
314345
}
315346
else if (netif_default == &_netif)
316347
{
@@ -386,13 +417,10 @@ err_t LwipIntfDev<RawDev>::handlePackets()
386417
}
387418

388419
template<class RawDev>
389-
void LwipIntfDev<RawDev>::setDefault()
420+
void LwipIntfDev<RawDev>::setDefault(bool deflt)
390421
{
391-
_default = true;
392-
if (connected())
393-
{
394-
netif_set_default(&_netif);
395-
}
422+
_default = deflt;
423+
check_route();
396424
}
397425

398426
#endif // _LWIPINTFDEV_H

libraries/ESP8266mDNS/src/LEAmDNS_Transfer.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -1766,11 +1766,13 @@ namespace MDNSImplementation
17661766
stcMDNS_RRAttributes attributes(DNS_RRTYPE_AAAA,
17671767
((p_rSendParameter.m_bCacheFlush ? 0x8000 : 0)
17681768
| DNS_RRCLASS_IN)); // Cache flush? & INternet
1769-
bool bResult = ((_writeMDNSHostDomain(m_pcHostname, false, p_rSendParameter)) && // esp8266.local
1770-
(_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS
1771-
(_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter)) && // TTL
1772-
(_write16(MDNS_IP6_SIZE, p_rSendParameter)) && // RDLength
1773-
(false /*TODO: IP6 version of: _udpAppendBuffer((uint32_t)p_IPAddress, MDNS_IP4_SIZE)*/)); // RData
1769+
bool bResult
1770+
= ((_writeMDNSHostDomain(m_pcHostname, false, p_rSendParameter)) && // esp8266.local
1771+
(_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS
1772+
(_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter))
1773+
&& // TTL
1774+
(_write16(MDNS_IP6_SIZE, p_rSendParameter)) && // RDLength
1775+
(false /*TODO: IP6 version of: _udpAppendBuffer((uint32_t)p_IPAddress, MDNS_IP4_SIZE)*/)); // RData
17741776

17751777
DEBUG_EX_ERR(if (!bResult) {
17761778
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_AAAA: FAILED!\n"));
@@ -1855,7 +1857,7 @@ namespace MDNSImplementation
18551857
p_rSendParameter.m_u16Offset))
18561858
&& (_writeMDNSRRDomain(hostDomain,
18571859
p_rSendParameter))) // Host, eg. esp8266.local
1858-
// Cache available for domain
1860+
// Cache available for domain
18591861
: ((MDNS_DOMAIN_COMPRESS_MARK
18601862
> ((u16CachedDomainOffset >> 8) & ~MDNS_DOMAIN_COMPRESS_MARK))
18611863
&& // Valid offset
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
This sketch establishes a TCP connection to a "quote of the day" service.
3+
It sends a "hello" message, and then prints received data.
4+
5+
This is Ethernet version of:
6+
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino
7+
*/
8+
9+
#include <LwipEthernet.h>
10+
11+
Wiznet5500lwIP eth(/*SS*/ 16); // <== adapt to your hardware
12+
13+
const char* host = "djxmmx.net";
14+
const uint16_t port = 17;
15+
16+
void setup() {
17+
Serial.begin(115200);
18+
19+
Serial.println("\nEthernet\n");
20+
21+
// 1. Currently when no default is set, esp8266-Arduino uses the first
22+
// DHCP client interface receiving a valid address and gateway to
23+
// become the new lwIP default interface.
24+
// 2. Otherwise - when using static addresses - lwIP for every packets by
25+
// defaults selects automatically the best suited output interface
26+
// matching the destination address. If several interfaces match,
27+
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
28+
// checked first.
29+
// 3. Or, use `::setDefault()` to force routing through this interface.
30+
// eth.setDefault(); // default route set through this interface
31+
32+
if (!ethInitDHCP(eth)) {
33+
Serial.printf("no hardware found\n");
34+
while (1) {
35+
delay(1000);
36+
}
37+
}
38+
39+
while (!eth.connected()) {
40+
Serial.printf(".");
41+
delay(1000);
42+
}
43+
44+
Serial.printf("Ethernet: IP Address: %s\n",
45+
eth.localIP().toString().c_str());
46+
}
47+
48+
void loop() {
49+
50+
Serial.print("connecting to ");
51+
Serial.print(host);
52+
Serial.print(':');
53+
Serial.println(port);
54+
55+
// Use WiFiClient class to create TCP connections
56+
// (this class could have been named TCPClient)
57+
WiFiClient client;
58+
if (!client.connect(host, port)) {
59+
Serial.println("connection failed");
60+
delay(5000);
61+
return;
62+
}
63+
64+
// This will send a string to the server
65+
Serial.println("sending data to server");
66+
if (client.connected()) { client.println("hello from ESP8266"); }
67+
68+
// wait for data to be available
69+
unsigned long timeout = millis();
70+
while (client.available() == 0) {
71+
if (millis() - timeout > 5000) {
72+
Serial.println(">>> Client Timeout !");
73+
client.stop();
74+
delay(60000);
75+
return;
76+
}
77+
}
78+
79+
// Read all the lines of the reply from server and print them to Serial
80+
Serial.println("receiving from remote server");
81+
client.sendAll(Serial); // this peer closes once all data are sent
82+
83+
// Close the connection
84+
Serial.println();
85+
Serial.println("closing connection");
86+
client.stop();
87+
88+
delay(300000); // execute once every 5 minutes, don't flood remote service
89+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
This sketch establishes a TCP connection to a "quote of the day" service.
3+
It sends a "hello" message, and then prints received data.
4+
5+
This is Ethernet version of:
6+
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino
7+
*/
8+
9+
#include <LwipEthernet.h>
10+
11+
#define LOCAL_IP IPAddress(192, 168, 0, 233)
12+
#define LOCAL_GW IPAddress(192, 168, 0, 254) // <== adapt to your network
13+
#define LOCAL_MASK IPAddress(255, 255, 255, 0)
14+
#define DNS IPAddress(8, 8, 8, 8)
15+
16+
Wiznet5500lwIP eth(/*SS*/ 16); // <== adapt to your hardware
17+
18+
const char* host = "djxmmx.net";
19+
const uint16_t port = 17;
20+
21+
void setup() {
22+
Serial.begin(115200);
23+
24+
Serial.println("\nEthernet\n");
25+
26+
// 1. Currently when no default is set, esp8266-Arduino uses the first
27+
// DHCP client interface receiving a valid address and gateway to
28+
// become the new lwIP default interface.
29+
// 2. Otherwise - when using static addresses - lwIP for every packets by
30+
// defaults selects automatically the best suited output interface
31+
// matching the destination address. If several interfaces match,
32+
// the first one is picked. On esp8266/Arduno: WiFi interfaces are
33+
// checked first.
34+
// 3. Or, use `::setDefault()` to force routing through this interface.
35+
// eth.setDefault(true); // default route set through this interface
36+
37+
if (!ethInitStatic(eth, LOCAL_IP, LOCAL_GW, LOCAL_MASK, DNS)) {
38+
// enabling debug message will show the real cause
39+
Serial.printf("no hardware found or bad network configuration\n");
40+
while (1) {
41+
delay(1000);
42+
}
43+
}
44+
45+
Serial.printf("Ethernet: IP Address: %s\n",
46+
eth.localIP().toString().c_str());
47+
}
48+
49+
void loop() {
50+
51+
Serial.print("connecting to ");
52+
Serial.print(host);
53+
Serial.print(':');
54+
Serial.println(port);
55+
56+
// Use WiFiClient class to create TCP connections
57+
// (this class could have been named TCPClient)
58+
WiFiClient client;
59+
if (!client.connect(host, port)) {
60+
Serial.println("connection failed");
61+
delay(5000);
62+
return;
63+
}
64+
65+
// This will send a string to the server
66+
Serial.println("sending data to server");
67+
if (client.connected()) {
68+
client.println("hello from ESP8266");
69+
}
70+
71+
// wait for data to be available
72+
unsigned long timeout = millis();
73+
while (client.available() == 0) {
74+
if (millis() - timeout > 5000) {
75+
Serial.println(">>> Client Timeout !");
76+
client.stop();
77+
delay(60000);
78+
return;
79+
}
80+
}
81+
82+
// Read all the lines of the reply from server and print them to Serial
83+
Serial.println("receiving from remote server");
84+
client.sendAll(Serial); // this peer closes once all data are sent
85+
86+
// Close the connection
87+
Serial.println();
88+
Serial.println("closing connection");
89+
client.stop();
90+
91+
delay(600000); // execute once every 10 minutes, don't flood remote service
92+
}

0 commit comments

Comments
 (0)