{"id":21893491,"url":"https://github.com/yasheena/telnetspy","last_synced_at":"2025-09-03T23:37:16.529Z","repository":{"id":38985017,"uuid":"107565090","full_name":"yasheena/telnetspy","owner":"yasheena","description":"Telnet Server For ESP8266:  Cloning the serial port via Telnet. \"Debugging over the air\"","archived":false,"fork":false,"pushed_at":"2024-07-03T19:38:00.000Z","size":63,"stargazers_count":61,"open_issues_count":6,"forks_count":31,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-07T06:42:20.472Z","etag":null,"topics":["arduino","arduino-library","debugging-tool","esp32","esp8266","over-the-air","rfc854","serial","telnet-server"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yasheena.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-10-19T15:31:55.000Z","updated_at":"2024-12-24T19:26:20.000Z","dependencies_parsed_at":"2023-01-17T16:16:00.335Z","dependency_job_id":"ef509bcb-a77f-4fbb-be7e-e203c5920478","html_url":"https://github.com/yasheena/telnetspy","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/yasheena/telnetspy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yasheena%2Ftelnetspy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yasheena%2Ftelnetspy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yasheena%2Ftelnetspy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yasheena%2Ftelnetspy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yasheena","download_url":"https://codeload.github.com/yasheena/telnetspy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yasheena%2Ftelnetspy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273528781,"owners_count":25121820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","arduino-library","debugging-tool","esp32","esp8266","over-the-air","rfc854","serial","telnet-server"],"created_at":"2024-11-28T13:14:31.439Z","updated_at":"2025-09-03T23:37:16.483Z","avatar_url":"https://github.com/yasheena.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch3 align=\"center\"\u003eTelnet server for ESP8266 / ESP32\u003c/h3\u003e\n\n---\n\n\u003cp align=\"center\"\u003e Cloning the serial port via Telnet.\n    \u003cbr\u003e \n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n  [![GitHub Issues](https://img.shields.io/github/issues/yasheena/telnetspy.svg)](https://github.com/yasheena/telnetspy/issues)\n  [![GitHub Pull Requests](https://img.shields.io/github/issues-pr/yasheena/telnetspy.svg)](https://github.com/yasheena/telnetspy/pulls)\n\n\u003c/div\u003e\n\n## 📝 Table of Contents\n- [Description](#description)\n- [Usage](#usage)\n  - [General](#general)\n  - [Functions](#functions)\n  - [Hint](#hint)\n  - [Important](#important)\n- [License](#license)\n\n\n## 🎈 Description \u003ca name = \"description\"\u003e\u003c/a\u003e\n\n- This module allows you to do \"debugging over the air\". So if you already use ArduinoOTA, this is a helpful extension for wireless development. Use ```TelnetSpy``` instead of ```Serial``` to send data to the serial port and a copy to a Telnet connection. \n- There is a circular buffer which allows to store the data while the Telnet connection is not established. So it's possible to collect data even when the WiFi and Telnet connections are not yet established.\n- It's also possible to create a Telnet session only if it is neccessary: then you will get the already collected data as far as it is still stored in the circular buffer. Data sent from Telnet terminal to ESP8266 / ESP32 will be handled as data received by serial port.\n- It is also possible to use more than one instance of TelnetSpy. For example - To send control information on the first instance and data dumps on the second instance.\n- Now a rudimentary implementation of the telnet NVT protocol (see RFC854) is included. You can use this functions in PuTTY via its menu \"Special Command\" i.e. for restarting the ESP.  \n\n## 🚀 Usage \u003ca name = \"usage\"\u003e\u003c/a\u003e\n\n### General \u003ca name = \"general\"\u003e\u003c/a\u003e\n\nAdd the following line to your sketch:\n```\n#include \u003cTelnetSpy.h\u003e\nTelnetSpy LOG;\n```\n\nAdd the following line to your initialisation block ```void setup()```:\n```\nLOG.begin();\n```\n\nAdd the following line at the beginning of your main loop ```void loop()```:\n```\nLOG.handle();\n```\n\n### Use the following functions of the TelnetSpy object to modify behavior \u003ca name = \"functions\"\u003e\u003c/a\u003e\n\n1. [void setPort(uint16_t portToUse)](#setPort)\n2. [void setWelcomeMsg(const char* msg) / void setWelcomeMsg(const String\u0026 msg)](#setWelcomeMsg)\n3. [void setRejectMsg(const char* msg) / void setRejectMsg(const String\u0026 msg)](#setRejectMsg)\n4. [void setMinBlockSize(uint16_t minSize)](#setMinBlockSize)\n5. [void setCollectingTime(uint16_t colTime)](#setCollectingTime)\n6. [void setMaxBlockSize(uint16_t maxSize)](#setMaxBlockSize)\n7. [bool setBufferSize(uint16_t newSize)](#setBufferSize)\n8. [uint16_t getBufferSize()](#getBufferSize)\n9. [void setStoreOffline(bool store)](#setStoreOffline)\n10. [bool getStoreOffline()](#getStoreOffline)\n11. [void setPingTime(uint16_t pngTime)](#setPingTime)\n12. [bool setRecBufferSize(uint16_t newSize)](#setRecBufferSize)\n13. [uint16_t getRecBufferSize()](#getRecBufferSize)\n14. [void setSerial(HardwareSerial* usedSerial)](#setSerial)\n15. [bool isClientConnected()](#isClientConnected)\n16. [void setCallbackOnConnect(void (*callback)())](#setCallbackOnConnect)\n17. [void setCallbackOnDisconnect(void (*callback)())](#setCallbackOnDisconnect)\n18. [void disconnectClient()](#disconnectClient)\n19. [void clearBuffer()](#clearBuffer)\n20. [void setFilter(char ch, const char* msg, void (*callback()) / void setFilter(char ch, const String\u0026 msg, void (*callback())](#setFilter)\n21. [char getFilter()](#getFilter)\n22. [void setCallbackOnNvtBRK(void (*callback)())](#setCallbackOnNvtBRK)\n23. [void setCallbackOnNvtIP)(void (*callback)())](#setCallbackOnNvtIP)\n24. [void setCallbackOnNvtAO)(void (*callback)())](#setCallbackOnNvtAO)\n25. [void setCallbackOnNvtAYT)(void (*callback)())](#setCallbackOnNvtAYT)\n26. [void setCallbackOnNvtEC)(void (*callback)())](#setCallbackOnNvtEC)\n27. [void setCallbackOnNvtEL)(void (*callback)())](#setCallbackOnNvtEL)\n28. [void setCallbackOnNvtGA)(void (*callback)())](#setCallbackOnNvtGA)\n29. [void setCallbackOnNvtWWDD(void (*callback)(char command, char option))](#setCallbackOnNvtWWDD)\n---\n\n### 1. void setPort(uint16_t portToUse) \u003ca name = \"setPort\"\u003e\u003c/a\u003e\n\nChange the port number of this Telnet server. If a client is already connected, it will be disconnected.\n\nDefault: 23\n\n```\nvoid setPort(uint16_t portToUse)\n```\n\n### 2. void setWelcomeMsg(const char* msg) / void setWelcomeMsg(const String\u0026 msg) \u003ca name = \"setWelcomeMsg\"\u003e\u003c/a\u003e\n\nChange the message which will be sent to the Telnet client after a session is established.\n\nDefault: \"Connection established via TelnetSpy.\\n\"\n\n```\nvoid setWelcomeMsg(const char* msg)\nvoid setWelcomeMsg(const String\u0026 msg)\n```\n\n### 3. void setRejectMsg(const char* msg) / void setRejectMsg(const String\u0026 msg) \u003ca name = \"setRejectMsg\"\u003e\u003c/a\u003e\n\nChange the message which will be sent to the Telnet client if another session is already established.\n\nDefault: \"TelnetSpy: Only one connection possible.\\n\"\n\n```\nvoid setRejectMsg(const char* msg)\nvoid setRejectMsg(const String\u0026 msg)\n```\n\n### 4. void setMinBlockSize(uint16_t minSize) \u003ca name = \"setMinBlockSize\"\u003e\u003c/a\u003e\n\nChange the amount of characters to collect before sending a Telnet block.\n\nDefault: 64 \n\n```\nvoid setMinBlockSize(uint16_t minSize)\n```\n\n### 5. void setCollectingTime(uint16_t colTime) \u003ca name = \"setCollectingTime\"\u003e\u003c/a\u003e\n\nChange the time (in ms) to wait before sending a Telnet block if it's size is less than \u003cminSize\u003e (defined by ```setMinBlockSize```).\n\nDefault: 100\n\n```\nvoid setCollectingTime(uint16_t colTime)\n```\n\n### 6. void setMaxBlockSize(uint16_t maxSize) \u003ca name = \"setMaxBlockSize\"\u003e\u003c/a\u003e\n\nChange the maximum size of the Telnet packets to send.\n\nDefault: 512\n\n```\nvoid setMaxBlockSize(uint16_t maxSize)\n```\n\n### 7. bool setBufferSize(uint16_t newSize) \u003ca name = \"setBufferSize\"\u003e\u003c/a\u003e\n\nChange the size of the ring buffer. Set it to ```0``` to disable buffering. If buffering is disabled, the system's debug output (see setDebugOutput) cannot be send via telnet, it will be send to serial output only. Changing size tries to preserve the already collected data. If the new buffer size is too small, only the latest data will be preserved. Returns ```false``` if the requested buffer size cannot be set.\n\nDefault: 3000\n\n```\nbool setBufferSize(uint16_t newSize)\n```\n\n### 8. uint16_t getBufferSize() \u003ca name = \"getBufferSize\"\u003e\u003c/a\u003e\n\nThis function returns the actual size of the ring buffer.\n\n```\nuint16_t getBufferSize()\n```\n\n### 9. void setStoreOffline(bool store) \u003ca name = \"setStoreOffline\"\u003e\u003c/a\u003e\n\nEnable / disable storing new data in the ring buffer if no Telnet connection is established. This function allows you to store important data only. You can do this by disabling ```storeOffline``` for sending unimportant data.\n\nDefault: true\n\n```\nvoid setStoreOffline(bool store)\n```\n\n### 10. bool getStoreOffline() \u003ca name = \"getStoreOffline\"\u003e\u003c/a\u003e\n\nGet actual state of storing data when offline.\n\n```\nbool getStoreOffline()\n```\n\n### 11. void setPingTime(uint16_t pngTime) \u003ca name = \"setPingTime\"\u003e\u003c/a\u003e\n\nIf no data is sent via TelnetSpy, the detection of a disconnected client has a long timeout. Use ```setPingTime``` to define the time (in ms) without traffic after which a ping aka a ```chr(0)``` is sent to the Telnet client to detect a disconnect earlier. Use ```0``` as parameter to disable pings.\n\nDefault: 1500  \n\n```\nvoid setPingTime(uint16_t pngTime)\n```\n\n### 12. bool setRecBufferSize(uint16_t newSize) \u003ca name = \"setRecBufferSize\"\u003e\u003c/a\u003e\n    \nChange the size of the receive buffer. Set it to 0 to disable buffering in TelnetSpy (there is still a buffer in the underlayed WifiClient component).\nReturns false if the requested buffer size cannot be set.\n- If the receive buffer is used and it is full, additional received data will be lost. But all telnet NVT protocol data and the \"filter character\" is still handled (see \"setFilter\" and the NVT callbacks below).\n- If no receive buffer is used and the received characters are not retrieved by your app, the handling of the NVT protocol and the \"filter character\" will not work. If no receive buffer is used, you cannot receive the code 0xff (it will be lost because of a limitation of the WiFiAPI).\n    \nDefault: 64\n\n```\nbool setRecBufferSize(uint16_t newSize);    \n```\n   \n### 13. uint16_t getRecBufferSize() \u003ca name = \"getRecBufferSize\"\u003e\u003c/a\u003e\n\nThis function returns the actual size of the receive buffer.\n    \n```\nuint16_t getRecBufferSize()\n```\n    \n### 14. void setSerial(HardwareSerial* usedSerial) \u003ca name = \"setSerial\"\u003e\u003c/a\u003e\n\nSet the serial port you want to use with this object (especially for ESP32) or ```NULL``` if no serial port should be used (Telnet only).\n\nDefault: Serial\n\n```\nvoid setSerial(HardwareSerial* usedSerial)\n```\n\n### 15. bool isClientConnected() \u003ca name = \"isClientConnected\"\u003e\u003c/a\u003e\n\nThis function returns true if a Telnet client is connected.\n\n```\nbool isClientConnected()\n```\n\n### 16. void setCallbackOnConnect(void (*callback)()) \u003ca name = \"setCallbackOnConnect\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called on every Telnet connect of this object (except rejected connect tries). Use ```NULL``` to remove the callback.\n\nDefault: NULL\n\n```\nvoid setCallbackOnConnect(void (*callback)())\n```\n\n### 17. void setCallbackOnDisconnect(void (*callback)()) \u003ca name = \"setCallbackOnDisconnect\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called on every Telnet disconnect of this object (except rejected connect tries). Use ```NULL``` to remove the callback.\n\nDefault: NULL\n\n```\nvoid setCallbackOnDisconnect(void (*callback)())\n```\n\n### 18. void disconnectClient() \u003ca name = \"disconnectClient\"\u003e\u003c/a\u003e\n\nThis function disconnects an active client connection.\n    \n```\nvoid disconnectClient()\n```\n\n### 19. void clearBuffer() \u003ca name = \"clearBuffer\"\u003e\u003c/a\u003e\n\nThis function clears the transmit buffer of TelnetSpy, so all waiting data to send via a telnet connection will be discard.\n\n```\nvoid clearBuffer()\n```\n\n### 20. void setFilter(char ch, const char* msg, void (*callback()) / void setFilter(char ch, const String\u0026 msg, void (*callback()) \u003ca name = \"setFilter\"\u003e\u003c/a\u003e\n\nThis function allows to filter the character given by \"ch\" out of the receiving telnet data stream. If this character is detected, the following happens:\n- If a \"msg\" is given (not NULL), this message will be send back via the telnet connection.\n- If the \"callback\" is set (not NULL), the given function is called.    \n\n```\nvoid setFilter(char ch, const char* msg, void (*callback())\nvoid setFilter(char ch, const String\u0026 msg, void (*callback())\n```\n\n### 21. char getFilter() \u003ca name = \"getFilter\"\u003e\u003c/a\u003e\n    \nThis function returns the actual filter character (0 =\u003e not set).\n\n```\nchar getFilter()\n```\n\n### 22. void setCallbackOnNvtBRK(void (*callback)()) \u003ca name = \"setCallbackOnNvtBRK\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called whenever the telnet command \"BRK\" (Break) is received. Use NULL to remove the callback.\n    \nDefault: NULL\n \n```\nvoid setCallbackOnNvtBRK(void (*callback)())\n```\n    \n### 23. void setCallbackOnNvtIP(void (*callback)()) \u003ca name = \"setCallbackOnNvtIP\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called whenever the telnet command \"IP\" (Interrupt Process) is received. Use NULL to remove the callback.\n    \nDefault: 1 (=\u003e ESP.restart will be called)\n    \n```\nvoid setCallbackOnNvtIP(void (*callback)())\n```\n    \n### 24. void setCallbackOnNvtAO(void (*callback)()) \u003ca name = \"setCallbackOnNvtAO\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called whenever the telnet command \"AO\" (Abort Output) is received. Use NULL to remove the callback.\n    \nDefault: 1 (=\u003e disconnectClient of TelnerSpy will be called)\n \n```\nvoid setCallbackOnNvtAO(void (*callback)())\n```\n    \n### 25. void setCallbackOnNvtAYT(void (*callback)()) \u003ca name = \"setCallbackOnNvtAYT\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called whenever the telnet command \"AYT\" (Are you there) is received. Use NULL to remove the callback.\n\nDefault: NULL\n \n```\nvoid setCallbackOnNvtAYT(void (*callback)())\n```\n    \n### 26. void setCallbackOnNvtEC(void (*callback)()) \u003ca name = \"setCallbackOnNvtEC\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called whenever the telnet command \"EC\" (Erase Character) is received. Use NULL to remove the callback.\n\nDefault: NULL\n \n```\nvoid setCallbackOnNvtEC(void (*callback)())\n```\n    \n### 27. void setCallbackOnNvtEL(void (*callback)()) \u003ca name = \"setCallbackOnNvtEL\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called whenever the telnet command \"EL\" (Erase Line) is received. Use NULL to remove the callback.\n    \nDefault: NULL\n \n```\nvoid setCallbackOnNvtEL(void (*callback)())\n```\n    \n### 28. void setCallbackOnNvtGA(void (*callback)()) \u003ca name = \"setCallbackOnNvtGA\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called whenever the telnet command \"GA\" (Go Ahead) is received. Use NULL to remove the callback.\n    \nDefault: NULL\n \n```\nvoid setCallbackOnNvtGA(void (*callback)())\n```\n    \n### 29. void setCallbackOnNvtWWDD(void (*callback)()) \u003ca name = \"setCallbackOnNvtWWDD\"\u003e\u003c/a\u003e\n\nThis function installs a callback function which will be called whenever the telnet commands \"WILL\", \"WON'T\", \"DO\" or \"DON'T\" are received. Use NULL to remove the callback.\n    \nDefault: NULL\n \n```\nvoid setCallbackOnNvtWWDD(void (*callback)())\n```\n    \n## 💡 Hint \u003ca name = \"hint\"\u003e\u003c/a\u003e\n\nAdd the following lines to your sketch:\n\n```\nTelnetSpy SerialAndTelnet;\n#define SERIAL SerialAndTelnet\n// #define SERIAL Serial\n```\n\nReplace ```Serial``` with ```SERIAL``` in your sketch. Now you can switch between serial only and serial with Telnet by only changing the comments of the defines.\n \n## 🔔 Important \u003ca name = \"important\"\u003e\u003c/a\u003e\n\n- To connect to the Telnet server you have to:\n    1. Establish the WiFi connection.\n    2. Execute ```SerialAndTelnet.begin(WhatEverYouWant)```.\n \n💡 **Note:** The order is not important.\n\n- Everything you do with ```Serial```, you can do with ```TelnetSpy``` too. But remember: Transfering data also via Telnet will need more performance than the serial port only. So time critical things may be influenced.\n\n- It is not possible to establish more than one Telnet connection at the same time. But it's possible to use more than one instance of TelnetSpy.\n\n- If you have problems with low memory, you may reduce the value of the ```define TELNETSPY_BUFFER_LEN``` for a smaller ring buffer on initialisation.    \n\n- Usage of ```void setDebugOutput(bool)``` to enable / disable of capturing of os_print calls when you have more than one TelnetSpy instance: That TelnetSpy object will handle this functionality where you used ```setDebugOutput``` at last.\nOn default, TelnetSpy has the capturing of OS_print calls enabled. So if you have more instances the last created instance will handle the capturing. \n \n## 📖 License \u003ca name = \"license\"\u003e\u003c/a\u003e\n\nThis library is open-source and licensed under the [MIT license](http://opensource.org/licenses/MIT).\n\nDo whatever you like with it, but contributions are appreciated!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyasheena%2Ftelnetspy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyasheena%2Ftelnetspy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyasheena%2Ftelnetspy/lists"}