nodemcu-firmware/lua_examples/telnet
Nathaniel Wesley Filardo dcc1ea2a49 A generic fifo and fifosock wrapper, under telnet and http server (#2650)
* lua_modules/fifo: a generic queue & socket wrapper

One occasionally wants a generic fifo, so here's a plausible
implementation that's reasonably flexible in its usage.

One possible consumer of this is a variant of TerryE's two-level fifo
trick currently in the telnetd example.  Factor that out to fifosock for
more general use.

* lua_examples/telnet: use factored out fifosock

* lua_modules/http: improve implementation

Switch to fifosock for in-order sending and waiting for everything to be
sent before closing.

Fix header callback by moving the invocation of the handler higher

* fifosock: optimistically cork and delay tx

If we just pushed a little bit of data into a fifosock that had idled,
wait a tick (1 ms) before transmitting.  Hopefully, this means that
we let the rest of the system push more data in before we send the first
packet.  But in a high-throughput situation, where we are streaming data
without idling the fifo, there won't be any additional delay and we'll
coalesce during operation as usual.

The fifosocktest mocks up enough of tmr for this to run, but assumes
an arbitrarily slow processor. ;)
2019-02-16 13:51:40 +01:00
..
README.md lua_examples/telnet: small tweaks (#2455) 2018-08-27 12:46:39 +01:00
simple_telnet.lua New Telnet module 2018-07-01 23:42:45 +01:00
telnet.lua A generic fifo and fifosock wrapper, under telnet and http server (#2650) 2019-02-16 13:51:40 +01:00

README.md

Telnet Module

Since Origin / Contributor Maintainer Source
2014-12-22 Zeroday Terry Ellison simple_telnet.lua
2018-05-24 Terry Ellison Terry Ellison telnet.lua

The Lua telnet example previously provided in our distro has been moved to this file simple_telnet.lua in this folder. This README discusses the version complex implementation at the Lua module telnet.lua. The main reason for this complex alternative is that a single Lua command can produce a LOT of output, and the telnet server has to work within four constraints:

  • The SDK rules are that you can only issue one send per task invocation, so any overflow must be buffered, and the buffer emptied using an on:sent callback (CB).

  • Since the interpeter invokes a node.output CB per field, you have a double whammy that these fields are typically small, so using a simple array FIFO would rapidly exhaust RAM.

  • For network efficiency, the module aggregates any FIFO buffered into sensible sized packet, say 1024 bytes, but it must also need to handle the case when larger string span multiple packets. However, you must flush the buffer if necessary.

  • The overall buffering strategy needs to be reasonably memory efficient and avoid hitting the GC too hard, so where practical avoid aggregating small strings to more than 256 chars (as NodeMCU handles <256 using stack buffers), and avoid serial aggregation such as buf = buf .. str as this hammers the GC.

So this server adopts a simple buffering scheme using a two level FIFO. The node.output CB adds records to the 1st level FIFO until the #recs is > 32 or the total size would exceed 256 bytes. Once over this threashold, the contents of the FIFO are concatenated into a 2nd level FIFO entry of upto 256 bytes, and the 1st level FIFO cleared down to any residue.

The sender dumps the 2nd level FIFO aggregating records up to 1024 bytes and once this is empty dumps an aggrate of the 1st level.

Lastly remember that owing to architectural limitations of the firmware, this server can only service stdin and stdout. Lua errors are still sent to stderr which is the UART0 device. Hence errors will fail silently. If you want to capture errors then you will need to wrap any commands in a pcall() and print any error return.

telnet:open()

Open a telnet server based on the provided parameters.

Syntax

telnet:open(ssid, pwd, port)

Parameters

ssid and password. Strings. SSID and Password for the Wifi network. If these are nil then the wifi is assumed to be configured or autoconfigured.

port. Integer TCP listenting port for the Telnet service. The default is 2323

Returns

Nothing returned (this is evaluted as nil in a scalar context).

telnet:close()

Close a telnet server and release all resources.

Syntax

telnet:close()

Parameters

None

Returns

Nothing returned (this is evaluted as nil in a scalar context).