Skip to content

Commit

Permalink
support for multiple connected clients
Browse files Browse the repository at this point in the history
and more networking libraries supported
  • Loading branch information
JAndrassy committed Sep 27, 2020
1 parent b1a24a0 commit f78e3dd
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 42 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# TelnetStream

The library creates a TelnetStream object, which can be used the same way as Serial, but the output is sent to a connected telnet client. It enables remote logging or debugging.
The library creates a TelnetStream object, which can be used the same way as Serial, but the output is sent to all connected telnet clients. It enables remote logging or debugging.

TelnetStream.h can be included not only in the ino file, but in cpp files of the sketch or in libraries to add debug prints for troubleshooting.

TelnetStream works as it is with esp8266 and esp32 WiFi library, with the Ethernet library, with WiFiNINA and with WiFiEspAT library.
TelnetStream works as it is with esp8266 and esp32 WiFi library, with the Ethernet, EthernetENC and UIPEthernet library, with WiFiNINA, WiFi101 and with WiFiEspAT library.

The library is in Library Manager. You can install it there.

Output of example:

Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=TelnetStream
version=1.0.0
version=1.1.0
author=Juraj Andrassy
maintainer=Juraj Andrassy <[email protected]>
sentence=Stream implementation over telnet for OTA debuging
Expand Down
100 changes: 100 additions & 0 deletions src/ArduinoWiFiServer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
ArduinoWiFiServer.h - Arduino compatible WiFiServer
implementation for ESP8266/ESP32 Arduino Wifi library.
Copyright (c) 2020 Juraj Andrassy
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef arduinowifiserver_h
#define arduinowifiserver_h

#ifdef ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif

#ifndef MAX_MONITORED_CLIENTS
#define MAX_MONITORED_CLIENTS 5
#endif

class ArduinoWiFiServer : public WiFiServer {
public:

ArduinoWiFiServer(const IPAddress& addr, uint16_t port) : WiFiServer(addr, port) {}
ArduinoWiFiServer(uint16_t port) : WiFiServer(port) {}
virtual ~ArduinoWiFiServer() {}

// https://www.arduino.cc/en/Reference/EthernetServerAccept
WiFiClient accept() {return WiFiServer::available();}

// https://www.arduino.cc/en/Reference/WiFiServerAvailable
WiFiClient available() {

// update connected clients
for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
if (!connectedClients[i]) {
connectedClients[i] = accept();
}
}
// find next client with data available
for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
if (index == MAX_MONITORED_CLIENTS) {
index = 0;
}
WiFiClient& client = connectedClients[index];
index++;
if (client.available())
return client;
}
return WiFiClient(); // no client with data found
}

virtual size_t write(uint8_t b) override {
return write(&b, 1);
}

virtual size_t write(const uint8_t *buf, size_t size) override {
size_t ret = 0;
for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
WiFiClient& client = connectedClients[i];
if (client) {
ret = client.write(buf, size);
}
}
return ret;
}

using Print::write;

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

#ifdef ESP8266
operator bool() {return (status() == LISTEN);}
#endif

private:
WiFiClient connectedClients[MAX_MONITORED_CLIENTS];
uint8_t index = 0;
};

#endif
49 changes: 18 additions & 31 deletions src/TelnetStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ TelnetStreamClass::TelnetStreamClass(uint16_t port) :server(port) {

void TelnetStreamClass::begin(int port) {
if (port) {
#if USE_ETHERNET
server = EthernetServer(port);
#else
server = WiFiServer(port);
#endif
server = NetServer(port);
}
#if defined(_WIFI_ESP_AT_H_)
server.begin(3, 3600);
#else
server.begin();
#endif
client = server.available();
}

Expand All @@ -21,31 +21,18 @@ void TelnetStreamClass::stop() {
}

boolean TelnetStreamClass::disconnected() {
#if defined(ESP32) || defined(USE_ETHERNET)
if (!server)
return true;
#else
#if __has_include(<WiFiNINA.h>) || __has_include(<WiFi101.h>)
if (server.status() == 0) // 0 is CLOSED
return true;
#endif
if (!client) {
#if defined(USE_ETHERNET)
client = server.accept();
#else
client = server.available();
#endif
}
if (client) {
if (client.connected())
return false;
client.stop();
#if defined(USE_ETHERNET)
client = server.accept();
#else
client = server.available();
if (!server)
return true;
#endif

if (!client || !client.available()) {
client = server.available(); // try to get next client with data
}
return true;
return !client;
}

int TelnetStreamClass::read() {
Expand All @@ -67,15 +54,15 @@ int TelnetStreamClass::peek() {
}

size_t TelnetStreamClass::write(uint8_t val) {
if (disconnected())
return 1;
return client.write(val);
return server.write(val);
}

size_t TelnetStreamClass::write(const uint8_t *buf, size_t size) {
return server.write(buf, size);
}

void TelnetStreamClass::flush() {
if (disconnected())
return;
client.flush();
server.flush();
}

TelnetStreamClass TelnetStream(23);
30 changes: 22 additions & 8 deletions src/TelnetStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,36 @@ repository https://github.com/jandrassy

#if __has_include(<Ethernet.h>)
#include <Ethernet.h>
#define USE_ETHERNET 1
#define NetClient EthernetClient
#define NetServer EthernetServer
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#define NetClient WiFiClient
#elif __has_include(<WiFi101.h>)
#include <WiFi101.h>
#define NetClient WiFiClient
#define NetServer WiFiServer
#else
#include <WiFi.h>
#define NetClient WiFiClient
#define NetServer WiFiServer
#endif

// special server types
#if defined(ESP32) || defined(ESP8266)
#include "ArduinoWiFiServer.h"
#define NetServer ArduinoWiFiServer
#elif defined(_WIFI_ESP_AT_H_) // from WiFi.h
#define NetServer WiFiServerPrint
#elif __has_include(<EthernetENC.h>)
#define NetServer EthernetServerPrint
#endif

class TelnetStreamClass : public Stream {

private:
#if USE_ETHERNET
EthernetServer server;
EthernetClient client;
#else
WiFiServer server;
WiFiClient client;
#endif
NetServer server;
NetClient client;

boolean disconnected();

Expand All @@ -55,6 +68,7 @@ class TelnetStreamClass : public Stream {

// Print implementation
virtual size_t write(uint8_t val);
virtual size_t write(const uint8_t *buf, size_t size);
using Print::write; // pull in write(str) and write(buf, size) from Print
virtual void flush();

Expand Down

0 comments on commit f78e3dd

Please sign in to comment.