diff --git a/include/hasp_conf.h b/include/hasp_conf.h index c6990546..7eefc3a4 100644 --- a/include/hasp_conf.h +++ b/include/hasp_conf.h @@ -11,7 +11,7 @@ #define HASP_USE_HTTP 1 #define HASP_USE_MDNS 0 #define HASP_USE_SYSLOG 0 -#define HASP_USE_TELNET 0 +#define HASP_USE_TELNET 1 #define HASP_USE_SPIFFS 1 #define HASP_USE_EEPROM 0 diff --git a/include/lv_conf.h b/include/lv_conf.h index a3f5de9e..868e3dd3 100644 --- a/include/lv_conf.h +++ b/include/lv_conf.h @@ -80,7 +80,7 @@ typedef int16_t lv_coord_t; /* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ #ifdef ESP8266 -# define LV_MEM_SIZE (12U * 1024U) // 4KB +# define LV_MEM_SIZE (10U * 1024U) // 10kb with telnet, 12kb without telnet #endif #ifndef LV_MEM_SIZE # define LV_MEM_SIZE (48 * 1024U) // 40KB diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index a538a83d..83be806a 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -16,6 +16,10 @@ #include "hasp_config.h" #include "hasp_dispatch.h" +#if HASP_USE_TELNET != 0 +#include "hasp_telnet.h" +#endif + #ifdef USE_CONFIG_OVERRIDE #include "user_config_override.h" #endif @@ -105,6 +109,11 @@ void serialPrintln(const char * debugText) Serial.print(debugTimeText); Serial.println(debugText); + +#if HASP_USE_TELNET != 0 + telnetPrint(debugTimeText.c_str()); + telnetPrintln(debugText); +#endif } void serialPrintln(String & debugText) diff --git a/src/hasp_telnet.cpp b/src/hasp_telnet.cpp new file mode 100644 index 00000000..25a17091 --- /dev/null +++ b/src/hasp_telnet.cpp @@ -0,0 +1,121 @@ +#include "Arduino.h" +#include "ArduinoJson.h" + +#include "hasp_conf.h" +#include "hasp_log.h" +#include "hasp_config.h" +#include "hasp_dispatch.h" +#include "hasp_telnet.h" + +#if HASP_USE_TELNET > 0 + +#if defined(ARDUINO_ARCH_ESP32) +#include +#else +#include +#endif + +//#define telnetInputMax 128; // Size of user input buffer for user telnet session +static char telnetInputBuffer[128]; + +uint8_t telnetEnabled = true; // Enable telnet debug output +WiFiServer * telnetServer; //(23); +WiFiClient * telnetClient; + +void telnetSetup(const JsonObject & settings) +{ + telnetSetConfig(settings); + + if(telnetEnabled) { // Setup telnet server for remote debug output + telnetServer = new WiFiServer(23); + telnetClient = new WiFiClient; + if(telnetServer) { + telnetServer->setNoDelay(true); + telnetServer->begin(); + debugPrintln(String(F("TELNET: debug server enabled at telnet:")) + WiFi.localIP().toString()); + } else { + errorPrintln(F("TELNET: %sFailed to create telnet server")); + } + } +} + +void telnetLoop(bool isConnected) +{ // Basic telnet client handling code from: https://gist.github.com/tablatronix/4793677ca748f5f584c95ec4a2b10303 + if(!isConnected) return; + + static unsigned long telnetInputIndex = 0; + if(telnetServer && telnetServer->hasClient()) { // client is connected + if(!*telnetClient || !telnetClient->connected()) { + if(telnetClient) { + telnetClient->stop(); // client disconnected + } + *telnetClient = telnetServer->available(); // ready for new client + telnetInputIndex = 0; // reset input buffer index + } else { + telnetServer->available().stop(); // have client, block new connections + } + } + + // Handle client input from telnet connection. + if(telnetClient && telnetClient->connected() && telnetClient->available()) { // client input processing + + if(telnetClient->available()) { + char telnetInputByte = telnetClient->read(); // Read client byte + // debugPrintln(String("telnet in: 0x") + String(telnetInputByte, HEX)); + switch(telnetInputByte) { + case 0x3: + case 0x5: + case 0xff: + case 0xf1: + telnetInputIndex = 0; + break; + case 10: + case 13: + telnetInputBuffer[telnetInputIndex] = 0; // null terminate our char array + if(telnetInputIndex > 0) dispatchCommand(telnetInputBuffer); + telnetInputIndex = 0; + break; + + default: + if(telnetInputIndex < + sizeof(telnetInputBuffer)) { // If we have room left in our buffer add the current byte + telnetInputBuffer[telnetInputIndex] = telnetInputByte; + telnetInputIndex++; + } + } + } + } +} + +void telnetPrintln(const char * msg) +{ + if(telnetEnabled && telnetClient && telnetClient->connected()) { + telnetClient->println(msg); + } +} +void telnetPrint(const char * msg) +{ + if(telnetEnabled && telnetClient && telnetClient->connected()) { + telnetClient->print(msg); + } +} + +bool telnetGetConfig(const JsonObject & settings) +{ + settings[FPSTR(F_CONFIG_ENABLE)] = telnetEnabled; + + configOutput(settings); + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool telnetSetConfig(const JsonObject & settings) +{ + configOutput(settings); + bool changed = false; + + return changed; +} + +#endif \ No newline at end of file diff --git a/src/hasp_telnet.h b/src/hasp_telnet.h new file mode 100644 index 00000000..c73d7c44 --- /dev/null +++ b/src/hasp_telnet.h @@ -0,0 +1,21 @@ +#include "hasp_conf.h" + +#ifndef HASP_TELNET_H +#define HASP_TELNET_H + +#if HASP_USE_TELNET > 0 + +#include "ArduinoJson.h" + +void telnetSetup(const JsonObject & settings); +void telnetLoop(bool isConnected); +void telnetStop(void); + +void telnetPrint(const char * msg); +void telnetPrintln(const char * msg); + +bool telnetSetConfig(const JsonObject & settings); +bool telnetGetConfig(const JsonObject & settings); + +#endif +#endif diff --git a/src/main.cpp b/src/main.cpp index 9004a1b7..f665d35d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,6 +35,10 @@ #include "hasp_http.h" #endif +#if HASP_USE_TELNET +#include "hasp_telnet.h" +#endif + #if HASP_USE_MDNS #include "hasp_mdns.h" #endif @@ -47,8 +51,10 @@ bool isConnected; void setup() { +#if defined(ARDUINO_ARCH_ESP8266) pinMode(D1, OUTPUT); pinMode(D2, INPUT_PULLUP); +#endif /* Init Storage */ #if HASP_USE_EEPROM @@ -84,6 +90,10 @@ void setup() mqttSetup(settings[F("mqtt")]); #endif +#if HASP_USE_TELNET + telnetSetup(settings[F("telnet")]); +#endif + #if HASP_USE_MDNS mdnsSetup(settings[F("mdns")]); #endif @@ -132,6 +142,10 @@ void loop() httpLoop(isConnected); #endif +#if HASP_USE_TELNET + telnetLoop(isConnected); +#endif + #if HASP_USE_MDNS mdnsLoop(isConnected); #endif