JAndrassy / TelnetStream

Arduino Stream implementation over Telnet for OTA logging and debugging
GNU Affero General Public License v3.0
164 stars 17 forks source link

TelnetStream closes communication already from a flush() instruction. #15

Closed rin67630 closed 2 years ago

rin67630 commented 3 years ago

This code already closes Telnet:

      TelnetStream.println("bye bye");  
      TelnetStream.flush();  
//    TelnetStream.stop();  
      break;  

At other places in my program every time I flush() Telnet closes.

Is is supposed to work that way?

rin67630 commented 3 years ago

I see in the code:

virtual void flush() {
    for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
      if (connectedClients[i]) {
        connectedClients[i].flush();
      }
    }

so flush() kills all connected clients? But that is NOT the meaning of the Stream flush(), is it?

JAndrassy commented 3 years ago

what networking library, what board?

JAndrassy commented 3 years ago

I tested for esp8266 3.0.2 and the telnet client stays open after flush()

rin67630 commented 3 years ago

I am working with several esp32 models. Using your own example slightly simplified (the TimeLib is not required), commenting out the // TelnetStream.stop(); and adding delay(500); TelnetStream.println("Still there?");:


#include <WiFi.h>
#include <TelnetStream.h>

const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
tm*        timeinfo;                 //localtime returns a pointer to a tm struct static int Second;
time_t     now;

const char ssid[] = "PawsAway";    // your network SSID (name)
const char pass[] = "Secret";          // your network password (use for WPA, or use as key for WEP)

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

  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Failed to connect.");
    while (1) {
      delay(10);
    }
  }

  configTime(gmtOffset_sec, daylightOffset_sec, "pool.ntp.org");
  time_t now = time(nullptr);
  while (now < 1629050852) {
    delay(100);
    now = time(nullptr);
  }
  timeinfo  = localtime(&now); 
  IPAddress ip = WiFi.localIP();
  Serial.println();
  Serial.println("Connected to WiFi network.");
  Serial.print("Connect with Telnet client to ");
  Serial.println(ip);

  TelnetStream.begin();
}

void loop() {
  switch (TelnetStream.read()) {
    case 'R':
    TelnetStream.stop();
    delay(100);
    ESP.restart();
      break;
    case 'C':
      TelnetStream.println("bye bye");
      TelnetStream.flush();
//      TelnetStream.stop();
      delay(500);
      TelnetStream.println("Still there?");
      break;
  }

  static unsigned long next;
  if (millis() - next > 5000) {
    next = millis();
    log();
  }
}

void log() {
  static int i = 0;

  char timeStr[20];
  strftime(timeStr, sizeof(timeStr), " %R %d%b ", timeinfo);

  TelnetStream.print(i++);
  TelnetStream.print(" ");
  TelnetStream.println (timeStr);
}

The bootlog on Serial:

Attempting to connect to WPA SSID: PawsAway

Connected to WiFi network.
Connect with Telnet client to 192.168.188.77

Here the Telnet protocol (Debian on WSL)


rin67630@My-Laptop:~$ telnet 192.168.188.77
Trying 192.168.188.77...
Connected to 192.168.188.77.
Escape character is '^]'.
7  20:25 15Aug
8  20:25 15Aug
9  20:25 15Aug
C
bye bye
Connection closed by foreign host.
rin67630@My-Laptop:~$

You see the problem?

rin67630 commented 3 years ago

Tested again from Telnet on a Raspberry Pi. Same Same...

rin67630 commented 3 years ago

Compiled the same program for an ESP8266 (WemosD1) Just changed the first line to

include

and there it would not crash upon flush():

rin67630@My-Laptop:~$ telnet 192.168.188.51
Trying 192.168.188.51...
Connected to 192.168.188.51.
Escape character is '^]'.
3  20:48 15Aug
4  20:48 15Aug
C
bye bye
Still there?
5  20:48 15Aug
6  20:48 15Aug
7  20:48 15Aug
8  20:48 15Aug

The ESP32 appears to be buggy on Stream.flush().