earlephilhower / arduino-pico

Raspberry Pi Pico Arduino core, for all RP2040 and RP2350 boards
GNU Lesser General Public License v2.1
2.08k stars 433 forks source link

[Feature Request] Port these libraries lwIP_w5100, lwIP_w5500 and lwIP_enc28j60 from ESP8266 #775

Closed khoih-prog closed 1 year ago

khoih-prog commented 2 years ago

Hi @earlephilhower

As you've done so great work for lwIP_CYW43, lwIP_Ethenet and cyw43 WiFi libraries, could you please, when having time, port these libraries :

  1. lwIP_w5100
  2. lwIP_w5500
  3. lwIP_enc28j60

from ESP826 to this powerful and popular core.

Those LwIP-based libraries would be used in newly-created Async-related libraries, similar to those for RP2040W, as in Libraries created / updated to support RASPBERRY_PI_PICO_W using CYW43439 WiFi #757

earlephilhower commented 2 years ago

I have an ENC28 and a W5500S(thanks, WizNet!), but not the other two. Do you have a W5100 or W5500 to test on? It's in the queue, but only so many hours in the day.

When they get ported everything WiFi can do, they will be able to do (i.e. SSL connections, UDP, servers, NTP, etc.). You'll still need to use a WiFiClient or WiFiServer object, but they are really LWIPClientand LWIPServer under the hood and have no WiFi constraints (or at least, they shouldn't!)

khoih-prog commented 2 years ago

Good news the tasks are in the queue.

It's in the queue, but only so many hours in the day.

Totally understand. I get the same constraint, even if I'd like to help port them.

I have W5100 and W5500 to test.


BTW, is that possible to add DNSServer library or code into the core or WiFi lib ?

I'm trying to port DNSServer library, but having some issue with UDP packet receiving.

Everything will be done much faster by you, as previous maintainer of ESP8266 core.

earlephilhower commented 2 years ago

@khoih-prog Try #779. DNSServer just built fine with trivial fixes (WDT reset ignore, remove obsolete BIT() macro).

khoih-prog commented 2 years ago

Thanks for the DNSServer.

Still have the same issue in WiFiUDP::parsePacket() : _ctx->next is always NULL. Some missing config in LwIP stack relating to DNSServer ??

https://github.com/earlephilhower/arduino-pico/blob/7be472932b7ac1c179b79a10ae882c3b88f00e42/libraries/WiFi/src/WiFiUdp.cpp#L182-L184


Test code

#define USE_WIFI_NINA         false
#define USE_WIFI101           false
#define USE_WIFI_CUSTOM       false

#include <WiFi.h>
#include <DNSServer.h>
#include <WiFiWebServer.h>

const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 42, 1);

DNSServer dnsServer;
WiFiWebServer webServer(80);

String responseHTML = ""
                      "<!DOCTYPE html><html lang='en'><head>"
                      "<meta name='viewport' content='width=device-width'>"
                      "<title>CaptivePortal</title></head><body>"
                      "<h1>Hello World!</h1><p>This is a captive portal example."
                      " All requests will be redirected here.</p></body></html>";

void setup()
{
  // Debug console
  Serial.begin(115200);
  while (!Serial && millis() < 5000);

  delay(1000);

  Serial.print("\nStart CaptivePortal on "); Serial.println(BOARD_NAME);

  WiFi.mode(WIFI_AP);

  WiFi.beginAP("DNSServer CaptivePortal example");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  bool dnsServer_OK = false;

  dnsServer_OK = dnsServer.start(DNS_PORT, "*", apIP);

  if (dnsServer_OK)
    Serial.println("dnsServer starting OK");
  else
    Serial.println("dnsServer starting failure");  

  // replay to all requests with same HTML
  webServer.onNotFound([]()
  {
    webServer.send(200, "text/html", responseHTML);
  });

  webServer.begin();
}

void loop()
{
  dnsServer.processNextRequest();
  webServer.handleClient();
}
khoih-prog commented 2 years ago

Strange, WiFiUDP::parsePacket() is OK when I'm running UdpNTPClient

No more problem with _ctx->next is always NULL.

https://github.com/earlephilhower/arduino-pico/blob/7be472932b7ac1c179b79a10ae882c3b88f00e42/libraries/WiFi/src/WiFiUdp.cpp#L182-L184

earlephilhower commented 2 years ago

Yeah, I just went back and checked the WiFiUDP example to make sure things were good.

At this point I think it may be "routing" related since the UDP code doesn't know or care if in AP or STA mode. This looks to take some digging.

An easy verification would to make the WiFiUDP example run over an AP not STA and verify failure. Plus that would be a simpler test on a known good code block for any fix (i.e. I did not dig into the DNS server guts so maybe there are 8266-specific assumptions somewhere).

earlephilhower commented 2 years ago

Thinking out loud, LWIP UDP while in AP mode can't be completely borked. The DHCP server does give addresses out therefore it is able to receive and send UDP packets. So something in this core is looking at a received UDP packet and saying, "nope...not for me."

earlephilhower commented 2 years ago

@khoih-prog well, that was obvious. DHCP server gave 8.8.8.8 hardcoded as DNS server, not the GW IP. Check the latest DNSServer PR for the update. I now see DNS requests being processed by the AP.

khoih-prog commented 2 years ago

@earlephilhower

Wow. Amazingly quick and the bug is fixed.

Now Captive Portal for DNSServer is working now when entering any non-existing site, such as example.ca.

Selection_026

Would you like me to make a PR for the examples for DNSServer


Captive Portal Code used for the test

#define USE_WIFI_NINA         false
#define USE_WIFI101           false
#define USE_WIFI_CUSTOM       false

#include <WiFi.h>
#include <DNSServer.h>
#include <WiFiWebServer.h>

const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 42, 1);

DNSServer dnsServer;
WiFiWebServer webServer(80);

String responseHTML = ""
                      "<!DOCTYPE html><html lang='en'><head>"
                      "<meta name='viewport' content='width=device-width'>"
                      "<title>CaptivePortal</title></head><body>"
                      "<h1>Hello World!</h1><p>This is a captive portal example."
                      " All requests will be redirected here.</p></body></html>";

void setup()
{
  // Debug console
  Serial.begin(115200);
  while (!Serial && millis() < 5000);

  delay(1000);

  Serial.print("\nStart CaptivePortal on "); Serial.println(BOARD_NAME);

  WiFi.mode(WIFI_AP);

  WiFi.beginAP("DNSServer CaptivePortal example");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
 if (dnsServer.start(DNS_PORT, "*", apIP))
    Serial.println("dnsServer starting OK");
  else
    Serial.println("dnsServer starting failure");

  // replay to all requests with same HTML
  webServer.onNotFound([]()
  {
    webServer.send(200, "text/html", responseHTML);
  });

  webServer.begin();
}

void loop()
{
  dnsServer.processNextRequest();
  webServer.handleClient();
}
khoih-prog commented 2 years ago

@earlephilhower

Is that possible to add WebServer library, similar to ESP8266WebServer into the core ?

It's required for certain WebServer apps, with simpler way to use, such as

server.on("/", handleRoot);

I can help if you'd like.

earlephilhower commented 2 years ago

It's in the queue. First I'm looking into HTTPClient (and want to fix the odd requirements we have on the 8266/32 which catch folks by surprise) then the web server. Lots of stuff in this here queue. :)

khoih-prog commented 2 years ago

Wow. Glad to know.

Ing-Dom commented 1 year ago

I'm interested in this. Is it possible atm to use w5500 together with this core and the core's lwip ?