diff --git a/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino b/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino new file mode 100644 index 00000000..6821b057 --- /dev/null +++ b/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino @@ -0,0 +1,131 @@ +/* + WiFiTelnetToSerial - Example Transparent UART to Telnet Server for ESP32 + + Copyright (c) 2017 Hristo Gochkov. All rights reserved. + This file is part of the ESP32 WiFi library for Arduino environment. + + 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 +*/ +#include +#include + +WiFiMulti wifiMulti; + +//how many clients should be able to telnet to this ESP32 +#define MAX_SRV_CLIENTS 1 +const char* ssid = "**********"; +const char* password = "**********"; + +WiFiServer server(23); +WiFiClient serverClients[MAX_SRV_CLIENTS]; + +HardwareSerial Serial1(2); // UART1/Serial1 pins 16,17 + +void setup() { + Serial.begin(115200); + Serial.println("\nConnecting"); + + wifiMulti.addAP(ssid, password); + wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); + wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); + + Serial.println("Connecting Wifi "); + for (int loops = 10; loops > 0; loops--) { + if (wifiMulti.run() == WL_CONNECTED) { + Serial.println(""); + Serial.print("WiFi connected "); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + break; + } + else { + Serial.println(loops); + delay(1000); + } + } + if (wifiMulti.run() != WL_CONNECTED) { + Serial.println("WiFi connect failed"); + delay(1000); + ESP.restart(); + } + + //start UART and the server + Serial1.begin(9600); + server.begin(); + server.setNoDelay(true); + + Serial.print("Ready! Use 'telnet "); + Serial.print(WiFi.localIP()); + Serial.println(" 23' to connect"); +} + +void loop() { + uint8_t i; + if (wifiMulti.run() == WL_CONNECTED) { + //check if there are any new clients + if (server.hasClient()){ + for(i = 0; i < MAX_SRV_CLIENTS; i++){ + //find free/disconnected spot + if (!serverClients[i] || !serverClients[i].connected()){ + if(serverClients[i]) serverClients[i].stop(); + serverClients[i] = server.available(); + if (!serverClients[i]) Serial.println("available broken"); + Serial.print("New client: "); + Serial.print(i); Serial.print(' '); + Serial.println(serverClients[i].remoteIP()); + break; + } + } + if (i >= MAX_SRV_CLIENTS) { + //no free/disconnected spot so reject + server.available().stop(); + } + } + //check clients for data + for(i = 0; i < MAX_SRV_CLIENTS; i++){ + if (serverClients[i] && serverClients[i].connected()){ + if(serverClients[i].available()){ + //get data from the telnet client and push it to the UART + while(serverClients[i].available()) Serial1.write(serverClients[i].read()); + } + } + else { + if (serverClients[i]) { + serverClients[i].stop(); + } + } + } + //check UART for data + if(Serial1.available()){ + size_t len = Serial1.available(); + uint8_t sbuf[len]; + Serial1.readBytes(sbuf, len); + //push UART data to all connected telnet clients + for(i = 0; i < MAX_SRV_CLIENTS; i++){ + if (serverClients[i] && serverClients[i].connected()){ + serverClients[i].write(sbuf, len); + delay(1); + } + } + } + } + else { + Serial.println("WiFi not connected!"); + for(i = 0; i < MAX_SRV_CLIENTS; i++) { + if (serverClients[i]) serverClients[i].stop(); + } + delay(1000); + } +} diff --git a/libraries/WiFi/src/WiFiServer.cpp b/libraries/WiFi/src/WiFiServer.cpp index 1174697a..2e20d444 100644 --- a/libraries/WiFi/src/WiFiServer.cpp +++ b/libraries/WiFi/src/WiFiServer.cpp @@ -40,9 +40,16 @@ void WiFiServer::stopAll(){} WiFiClient WiFiServer::available(){ if(!_listening) return WiFiClient(); + int client_sock; + if (_accepted_sockfd >= 0) { + client_sock = _accepted_sockfd; + _accepted_sockfd = -1; + } + else { struct sockaddr_in _client; int cs = sizeof(struct sockaddr_in); - int client_sock = accept(sockfd, (struct sockaddr *)&_client, (socklen_t*)&cs); + client_sock = accept(sockfd, (struct sockaddr *)&_client, (socklen_t*)&cs); + } if(client_sock >= 0){ int val = 1; if(setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&val, sizeof(int)) == ESP_OK) { @@ -70,6 +77,8 @@ void WiFiServer::begin(){ return; fcntl(sockfd, F_SETFL, O_NONBLOCK); _listening = true; + _noDelay = false; + _accepted_sockfd = -1; } void WiFiServer::setNoDelay(bool nodelay) { @@ -80,6 +89,19 @@ bool WiFiServer::getNoDelay() { return _noDelay; } +bool WiFiServer::hasClient() { + if (_accepted_sockfd >= 0) { + return true; + } + struct sockaddr_in _client; + int cs = sizeof(struct sockaddr_in); + _accepted_sockfd = accept(sockfd, (struct sockaddr *)&_client, (socklen_t*)&cs); + if (_accepted_sockfd >= 0) { + return true; + } + return false; +} + void WiFiServer::end(){ close(sockfd); sockfd = -1; diff --git a/libraries/WiFi/src/WiFiServer.h b/libraries/WiFi/src/WiFiServer.h index 38433a06..31fc7e3e 100644 --- a/libraries/WiFi/src/WiFiServer.h +++ b/libraries/WiFi/src/WiFiServer.h @@ -26,6 +26,7 @@ class WiFiServer : public Server { private: int sockfd; + int _accepted_sockfd = -1; uint16_t _port; uint8_t _max_clients; bool _listening; @@ -34,13 +35,14 @@ class WiFiServer : public Server { public: void listenOnLocalhost(){} - WiFiServer(uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_port(port),_max_clients(max_clients),_listening(false){} + WiFiServer(uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false){} ~WiFiServer(){ end();} WiFiClient available(); WiFiClient accept(){return available();} void begin(); void setNoDelay(bool nodelay); bool getNoDelay(); + bool hasClient(); size_t write(const uint8_t *data, size_t len); size_t write(uint8_t data){ return write(&data, 1);