Add tty_raw_write function and reorganize roles of them.
tty_raw_write:
Performs any processing that must be done character-by-character on the
fly. That is, output delays and ONULBRK processing.
tty_write :
Converts input data using output mapping and passes it to tty_raw_write.
forward_to_tty :
Converts input data according to the input/output mode and passes it to
tty_write. (output-mapping function move to tty_write. tx_total
statistics counting move to tty_raw_write and tty_sync.)
On exit, do not reset the tty device settings to the state they were in
before the program started.
This is effective when sending characters at a low baud rate and then
immediately exiting, to ensure that the last character is output
correctly.
Typing "@repl" after Ctrl-t r, enter Lua REPL mode.
Typing "@exit" in REPL mode will return you to normal mode.
Note:
- the determination of continuation lines is not done automatically, and
if the end of a line is \, it is determined to be a continuation
instruction.
- In REPL mode, tio's main loop is blocked. (Ctrl-t q works.)
Example:
>> t = {1,2,3,4,5}
>> for _,v in ipairs(t) do\
>> print(v,"\r")\
>> end
Implementation improvements:
- Add tty_init() and script_interp_init() in order to only once
initialization.
- Fix script function to work without device_fd.
bidir_cmd_herlper.sh: Bidirectional command helper by socat.
bidir_cmd_helper.py: Bidirectional command helper by python and netcat.
pexpect-ping.py, pexpect-pong.py: Scripts for throwing Ping-Pong between
cross-connected tios.
When calling the Lua interpreter with Ctrl-t r, change to start with the
previous call state.
This allows you to use it like REPL:
(example)
Ctrl-t r : my_library.lua
Ctrl-t r : !result1 = my_func("test1"); result2 = my_func("test2")
Ctrl-t r : !if (result1 == result2) then print("OK") else print("NG")
Ctrl-t r : @new
When you enter strings using Ctrl-t r, the string is interpreted as
follows:
- If the string does not begin with either "!" or "@", the string is
assumed to be the file name of a script and is executed.
- If the string begins with "!", the string excluding the "!" is
interpreted as Lua commands.
- If the string begins with "@", Strings beginning with "@" are
considered instructions to the interpreter. Currently valid instructions
are:
@new: Clear the Lua state. (== reset the Lua interpreter.)
@doopt: Execute the Lua script action specified by the option that start
with clearing the Lua state.
@nuldo=opt: do @doopt action when an empty string is entered (default).
@nuldo=none: Do nothing when an empty string is entered.
And now, lua interpreter start with GC.
If you need to stop GC, do lua function collectgarbage("stop").
Ctrl-t r/R/x/y commands require string input. To reduce the hassle of
repeatedly entering this information, I apply readline functions
(line-editing and history) to the string input.
Now tio have two histories: one for the line input-mode and one for the
ctrl-t command's string input.
And the following changes are made to the line input:
- Add prompts.
"> ": line input-mode, ">> " Ctrl-t string input.
- Omits duplicate lines from the history.
To implement the above functionality, we will modify the readline
functions to use the multi-instance style.
tio.expect[s]() performs pattern matching for each character received,
but there are cases where the character reception speed exceeds the
pattern matching speed, resulting in characters being missed.
Add non-blocking reads to read all characters that have been received at
that time.
Change timeout argument of tio.read / readline / expect[s] to be similar
to the timeout specification for poll(2) and LuaSocket.
If timeout is negative value or not provided or nil, it will wait
indefinitely until data is ready to read.
If timeout is 0, it will read data that has arrived with non-blocking.
Prior to this fix, non-blocking reads could not be specified.
Add tio.expects() which has a table of patterns in the arguments to
support "OR" pattern waiting.
The return values of tio.expects() are:
1st: index of the matched pattern in the table. nil if unmatched.
2nd: a table of captures if one of the patterns are matched.
nil if any of the patterns are unmatched and timeout.
3rd: all received strings in tio.expects() to treat the strings after
match.
Add all received string to tio.expect()'s return values too.
For example,
idx, captures, all_received = tio.expects( {"\nOK", "\nERROR"}, 1000 )
captures, all_received = tio.expect( "\nPROMPT>", 1000 )
Lua regular expressions do not have an OR specification, so the current
tio.expect() cannot wait until any of multiple patterns match.
This will cause OR waiting behavior when a table of multiple regular
expressions is passed as a pattern.
If you pass a string as a pattern, it will treats a table has single
regular expression.
and this will change return values.
1st: table of captures if one of the patterns matched
nil if any pattern unmatched and timeout.
2nd: whole input strings
3rd: index of the matched pattern. 0 if unmatched.
For example,
captures, whole, idx = tio.expect( {"\nOK", "\nERROR"} )
captures, whole, idx = tio.expect( "\nOK" )
The twrite Lua API is a variation of the write API, with the output
character mapping and output-delay / output-line-delay features enabled.
Since it processes each character internally, writing speed is slower
than the write API.
~~~~~~~~~~~~~~~~~~~~~~~
twrite(string)
Translate string with output character mapping and write the
translated string to serial device with output-delay /
output-line-delay.
If output-line-delay is non-zero and output-delay is any, line delay
time set output-line-delay.
If output-line-delay is zero and output-delay is non-zero, line delay
time set output-delay.
It was previously (output-line-delay + output-delay) in any case.
Also, since the buffer was flushed after the line delay, there was a
possibility that the delay would be reduced or not applied at all.
Lua API moved into a tio library table and names adjusted to Lua stdlib style.
Regex in expect() replaced with Lua patterns so binary data can be handled.
New tio.alwaysecho variable allows enabling and disabling echo to console.
Read and write functions now manage complex retry and timeout logic internally,
giving the user a simple "nil if fail" API like the rest of Lua.
exit() was removed, os.exit() already exists in the Lua standard library.
This commit only effects Linux.
The description field of the `device_list`, populated by
`tty_search_for_serial_devices()`, was either incorrect or less than ideal
for CDC ACM virtual com ports. For instance:
(i) Some devices incorrectly have the description field populated by
the 'product' property of USB hub they are connected via.
(ii) Other devices have description fields populated with the interface,
e.g. CDC, when there is a 'product' property available that would give a
clearer description.
To solve these issues, we first prioritise searching for the 'product' property
of the device over the 'interface' property. We also look for the
'product' property in an additional directory.
This timestamp format will print the seconds since epoch along with
subdivision in microseconds.
Example:
[1748009585.087083] tio v3.9-8-g2fb788f-dirty
[1748009585.087156] Press ctrl-t q to quit
[1748009585.087683] Connected to /dev/ttyUSB0
Git is being dumb about
67c071633d This PR is identical to that one and will supercede it.
Fix --auto new and --auto latest on MacOS.
'device_list' was both a global (eww!) and a local inside
tty_search_for_serial_devices(). The local got set and
returned, so it looked sane, but the caller used the global
instead of the return value of the function it had just
called, meaning (global) device_list was NULL while
(ignored, local) device_list held a perfectly lovely
linked list.
Tested:
tio --auto new waits for a new device to appare and connects
tio --latest will connect to the most recently attached device
which, in most worlds, is the most recently enumerated USB
device, conveniently skipping all the bluetooth nonsense.
If the lone USB device is disconnected, it then connects to
one of those, meaning you really do have to restart tio.
for MacOS
- Added error handling and memory management
- Improved code readability and consistency
- Updated coding style to match project conventions
- Added robust error checking for CoreFoundation property retrieval
- Implemented more defensive memory allocation and type checking
- Switched to using callout device key for more reliable device discovery
- Added single-line block bracing consistent with project style
- Improved comments and code formatting
- Used `kIOCalloutDeviceKey` instead of `kIODialinDeviceKey` for device path retrieval
- Enhanced type checking for CoreFoundation objects
- Simplified memory management and error handling
- Added additional logging and error reporting
- Verified functionality on MacOS 10.11 and 10.15. Tested with ESP32-P4 and ESP32-BOX
Resolves potential device discovery and memory management issues in the MacOS serial device detection code.