Open AlbertoLopSie opened 1 year ago
Comment...
I've got the Telnet server working making some dirty changes in ESPTelnetBase.h
:
...
#include <WiFi.h>
#include <Ethernet.h>
...
using TCPClient = EthernetClient; // using TCPClient = WiFiClient;
using TCPServer = EthernetServer; // using TCPServer = WiFiServer;
and tweaking some WiFiServer/Client-related code in ESPTelnetBase.cpp
I still need to make the code to be able to switch between WiFi and Ethernet on runtime but I don't think it would possible to do it without rewriting the whole ESPTelnet class.
Would you consider a PR if I can produce a working code?
Hey Alberto, Thanks for reaching out. As I don't have the Arduino Shield I a hard time replicating your problem. To answer your question: Yes, in general I don't mind reviewing and accepting a PR changes to the lib.
I have a few principles for the libs I share:
If you feel, that your ideas are in line with there, feel free to tinker with it. If not, let's discuss 😀
Also, feel free to describe your solution before changing code if that is faster or easier to do...
Cheers Lennart
Thanks for considering it Lennart,
My first attempt was to replace in ESPTelnetBase.h
, WiFiClient
and WSiFiServer
for its base classes Client
and Server
:
using TCPClient = Client;
using TCPServer = Server;
but, they are abstract classes and cannot be instantiated statically as you do in:
...
protected:
TCPServer server = TCPServer(23); // must be initalized here
TCPClient client;
...
Also, some of the methods that need rewrite are private, so overriding is not possible. For example:
void ESPTelnetBase::connectClient(TCPClient c, bool triggerEvent) {
client = c;
ip = client.remoteIP().toString();
client.setNoDelay(true); // ==> client.setNoDelay() does not exist in EthernetClient
if (triggerEvent && on_connect != NULL) on_connect(ip);
emptyClientStream();
connected = true;
}
The other method I've found that need rewrite is:
void ESPTelnetBase::processClientConnection() {
// if (!server.hasClient()) return; // ===> server.hasClient() does not exist in EthernetServer
TCPClient newClient = server.accept();
if (!newClient) return; // The former check needs to be rewritten this way for an EthernetServer
// Don't really know if works on WiFiServer
if (!connected) {
connectClient(newClient);
} else {
handleExistingConnection(newClient);
}
}
With these changes ESPTelnet works fine over the Ethernet@2.0.2 library in my W5100 shield. Of course these changes broke the WiFi functionality, but I was only trying to probe the concept.
I guess that supporting both libraries would require separate constructors or begin methods, to instruct ESPTelnet library to use one or another backend.
I need this code working ASAP and therefore I'm going to fork and modify it for my project, but as this baby has been grown by you, any suggestion would be greatly appreciated. Of course I'll propose you as PR the results.
Thanks!
Hey Alberto, that when inheritance gets back to haunt me. :-)
I made the base class to share the common methods for either the stream or non-stream version. Adding additional classes and inheritance to implement WiFi or Ethernet sounds complicated.
I think, I‘d then would want to add the code for both wifi and ethernet handling inside the BaseClass and determine the „mode“ via begin() .
This would mean I need to change begin()
and all other places where I do WiFi stuff.
But, then I‘d also check whether the Ethernet class works the same across Arduino, ESP8266 and ESP32. As the WiFi class has slight differences, this might very well be the case for Ethernet as well…
This sounds like the easiest, least complicated way to implement this. What do you think?
Cheers
Hi Lennart!
Hey Alberto, that when inheritance gets back to haunt me. :-) Jajaja!!! Life is just a matter of waiting for the unavoidable!!!
I think, I‘d then would want to add the code for both wifi and ethernet handling inside the BaseClass and determine the „mode“ via begin() . Agreed
This would mean I need to change
begin()
and all other places where I do WiFi stuff. But, then I‘d also check whether the Ethernet class works the same across Arduino, ESP8266 and ESP32. As the WiFi class has slight differences, this might very well be the case for Ethernet as well…This sounds like the easiest, least complicated way to implement this. What do you think?
Agreed. Personally, I would't bother too much avoid Arduino, the library is named ESPTelnet, isn't it ;-) ?
My current work is on a ESP32 and although I do have a couple of ESP8266 somewhere, preparing a test bed would take me a time that I don't have right now. I'd rather let it for later.
I'm not completely aware of some of your thoughts when writing the library so, my suggestions may be invalid. Please let me know if that happens.
On my previous message I pinned the 2 functions that (at least) need to be changed. I agree with you that the matter of switching between WiFi and Ethernet servers should be made at constructor or begin()
I guess that doing it at ESPTelnetBase
constructor would break some of the code in the derived class, but to be able to do it at begin()
you should handle the instantiation of the TCPServer server
and TCPClient client
protected properties different. They cannot be static except if you are willing to keep 2 set of static props, WiFiServer/WiFiClient
and EthernetServer/EthernetClient
.
Tho other way could be dynamic instantiating through new and keeping its pointers as Server * / Client *
. I don't really like dynamic memory on embedded systems but being a CPP environment it is very hard to avoid. On the other hand, this dynamic allocation is done just once, on begin()
I'll start exploring some of these paths today and what I find.
Cheers!
Hi Lennart,
I've created a new PR with the suggested changes fixing the Ethernet support.
Please let me know what do you think about!
Cheers!
Hey, wow! Thank you. Will review the PR next week, as i am on holidays and without a computer. Only brought a tablet :-) Thanks again!
Hey @AlbertoLopSie, please check if the code now still works on your end using this branch and the WS100:
https://github.com/LennartHennigs/ESPTelnet/tree/pr-ethernet-static
I will do the same with the WiFi classes for the ESP32 and the ESP8266
Yes!!!
It works like a charm!! (or... at least as good as it was working with my PR)
Moving the TCPClient class to a new file was the right move, I didn't do it by lazyness ;-)
Good to be able to help!!
Cheers!!
The code does not work with WiFi. I’ll take a stab at it in the next couple of days.
The code does not work with WiFi. I’ll take a stab at it in the next couple of days.
Mmm... I had it tested on Ethernet, WiFi STA and WiFi AP.
What problem did you get?
Hey, The ESP8266 D1 Mini does does not allow connections.
Trying 192.168.0.66...
telnet: connect to address 192.168.0.66: Connection refused
telnet: Unable to connect to remote host
...but it works fine on an ESP32 M5Stack Core 2. Haven't figured out why yet.
Sorry I can’t help… Don’t have any 8266 at hand
:-) let’s see what I can find. I also ordered a W5100 addon board. So I can give that a spin, too.
Hi Lennart!
I'm having troubles trying to start a Telnet Server over a wired Ethernet connection (W5100 shield). Already checked #22 and #27 but I can't find my problem related to them.
I'm passing
false
as second argument totelnet.begin()
and it's avoiding the WiFi check as expected, but later the code throws:The stack trace shows:
Using the debugger I could follow the offending line to the
WiFiServer::begin
method:The full code is huge but the library initialization portion is something like:
Due to some related comment read somewhere I also tried pre-initializing Esp Wifi code with the following code with no luck:
The telnet server is working fine on Wifi either in AP or STA modes.
Any hint would be greatly appreciated!
Alberto