mirror of
https://github.com/tio/tio.git
synced 2026-05-01 14:57:59 +02:00
Remove options --response-wait, --response-timeout
Remove options and rework input handling so it is possible to do the
same thing but via script which is much more flexible.
These options were always a bit of a hardcoded solution. With the new
script expect feature we can wait for any type of response.
For example, pipe command to serial device and wait for line response within 1 second:
$ echo "*IDN?" | tio /dev/ttyACM0 --script "expect('\r\n', 1000)" --mute
This commit is contained in:
parent
e1e3e298bf
commit
97537853a8
9 changed files with 46 additions and 116 deletions
|
|
@ -52,7 +52,6 @@ when used in combination with [tmux](https://tmux.github.io).
|
||||||
* Activate sub-configurations by name or pattern
|
* Activate sub-configurations by name or pattern
|
||||||
* Redirect I/O to UNIX socket or IPv4/v6 network socket for scripting or TTY sharing
|
* Redirect I/O to UNIX socket or IPv4/v6 network socket for scripting or TTY sharing
|
||||||
* Pipe input and/or output
|
* Pipe input and/or output
|
||||||
* Support for simple line request/response handling
|
|
||||||
* Bash completion on options, serial device names, and sub-configuration names
|
* Bash completion on options, serial device names, and sub-configuration names
|
||||||
* Configurable text color
|
* Configurable text color
|
||||||
* Visual or audible alert on connect/disconnect
|
* Visual or audible alert on connect/disconnect
|
||||||
|
|
@ -104,8 +103,6 @@ Options:
|
||||||
-m, --map <flags> Map characters
|
-m, --map <flags> Map characters
|
||||||
-c, --color 0..255|bold|none|list Colorize tio text (default: bold)
|
-c, --color 0..255|bold|none|list Colorize tio text (default: bold)
|
||||||
-S, --socket <socket> Redirect I/O to socket
|
-S, --socket <socket> Redirect I/O to socket
|
||||||
-r, --response-wait Wait for line response then quit
|
|
||||||
--response-timeout <ms> Response timeout (default: 100)
|
|
||||||
--rs-485 Enable RS-485 mode
|
--rs-485 Enable RS-485 mode
|
||||||
--rs-485-config <config> Set RS-485 configuration
|
--rs-485-config <config> Set RS-485 configuration
|
||||||
--alert bell|blink|none Alert on connect/disconnect (default: none)
|
--alert bell|blink|none Alert on connect/disconnect (default: none)
|
||||||
|
|
@ -171,14 +168,14 @@ Redirect I/O to IPv4 network socket on port 4242:
|
||||||
$ tio --socket inet:4242 /dev/ttyUSB0
|
$ tio --socket inet:4242 /dev/ttyUSB0
|
||||||
```
|
```
|
||||||
|
|
||||||
Inject data to the serial device:
|
Pipe data to the serial device:
|
||||||
```
|
```
|
||||||
$ cat data.bin | tio /dev/ttyUSB0
|
$ cat data.bin | tio /dev/ttyUSB0
|
||||||
```
|
```
|
||||||
|
|
||||||
Send command to serial device and wait for line response:
|
Pipe command to serial device and wait for line response within 1 second:
|
||||||
```
|
```
|
||||||
$ echo "*IDN?" | tio /dev/ttyACM0 --response-wait
|
$ echo "*IDN?" | tio /dev/ttyACM0 --script "expect('\r\n', 1000)" --mute
|
||||||
KORAD KD3305P V4.2 SN:32475045
|
KORAD KD3305P V4.2 SN:32475045
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ log-strip = disable
|
||||||
local-echo = disable
|
local-echo = disable
|
||||||
color = bold
|
color = bold
|
||||||
rs-485 = disable
|
rs-485 = disable
|
||||||
response-wait = disable
|
|
||||||
alert = none
|
alert = none
|
||||||
script-run = always
|
script-run = always
|
||||||
|
|
||||||
|
|
|
||||||
24
man/tio.1.in
24
man/tio.1.in
|
|
@ -245,21 +245,6 @@ If port is 0 or no port is provided default port 3333 is used.
|
||||||
At present there is a hardcoded limit of 16 clients connected at one time.
|
At present there is a hardcoded limit of 16 clients connected at one time.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.TP
|
|
||||||
.BR \-r ", " \-\-response\-wait
|
|
||||||
|
|
||||||
Wait for line response then quit. A line is considered any string terminated
|
|
||||||
with a NL character. If no line is received tio will quit after response
|
|
||||||
timeout.
|
|
||||||
|
|
||||||
Any tio text is automatically muted when piping a string to tio while in
|
|
||||||
response mode to make it easy to parse the response.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.BR " \-\-response\-timeout " \fI<ms>
|
|
||||||
|
|
||||||
Set timeout [ms] of line response (default: 100).
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR " \-\-rs\-485"
|
.BR " \-\-rs\-485"
|
||||||
|
|
||||||
|
|
@ -494,10 +479,6 @@ Set output mode.
|
||||||
Set socket to redirect I/O to
|
Set socket to redirect I/O to
|
||||||
.IP "\fBprefix-ctrl-key"
|
.IP "\fBprefix-ctrl-key"
|
||||||
Set prefix ctrl key (a..z or 'none', default: t)
|
Set prefix ctrl key (a..z or 'none', default: t)
|
||||||
.IP "\fBresponse-wait"
|
|
||||||
Enable wait for line response
|
|
||||||
.IP "\fBresponse-timeout"
|
|
||||||
Set line response timeout
|
|
||||||
.IP "\fBrs-485"
|
.IP "\fBrs-485"
|
||||||
Enable RS-485 mode
|
Enable RS-485 mode
|
||||||
.IP "\fBrs-485-config"
|
.IP "\fBrs-485-config"
|
||||||
|
|
@ -648,11 +629,10 @@ Pipe command to the serial device:
|
||||||
$ echo "ls -la" | tio /dev/serial/by\-id/usb\-FTDI_TTL232R-3V3_FTGQVXBL\-if00\-port0
|
$ echo "ls -la" | tio /dev/serial/by\-id/usb\-FTDI_TTL232R-3V3_FTGQVXBL\-if00\-port0
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
Pipe command to the serial device and wait for line response (string ending with CR or NL):
|
Pipe command to serial device and wait for line response within 1 second:
|
||||||
|
|
||||||
$ echo "*IDN?" | tio /dev/ttyACM0 --response-wait
|
$ echo "*IDN?" | tio /dev/ttyACM0 --script "expect('\\r\\n', 1000)" --mute
|
||||||
.TP
|
.TP
|
||||||
In this mode, only the response will be printed.
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
Likewise, to pipe data from file to the serial device:
|
Likewise, to pipe data from file to the serial device:
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,6 @@ _tio()
|
||||||
-S --socket \
|
-S --socket \
|
||||||
--input-mode \
|
--input-mode \
|
||||||
--output-mode \
|
--output-mode \
|
||||||
-r --response-wait \
|
|
||||||
--response-timeout \
|
|
||||||
--rs-485 \
|
--rs-485 \
|
||||||
--rs-485-config \
|
--rs-485-config \
|
||||||
--alert \
|
--alert \
|
||||||
|
|
@ -140,14 +138,6 @@ _tio()
|
||||||
COMPREPLY=( $(compgen -W "normal hex" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "normal hex" -- ${cur}) )
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
-r | --response-wait)
|
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
--response-timeout)
|
|
||||||
COMPREPLY=( $(compgen -W "1 10 100" -- ${cur}) )
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
--rs-485)
|
--rs-485)
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||||
return 0
|
return 0
|
||||||
|
|
|
||||||
|
|
@ -276,14 +276,6 @@ static int data_handler(void *user, const char *section, const char *name,
|
||||||
option.prefix_key = value[0];
|
option.prefix_key = value[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp(name, "response-wait"))
|
|
||||||
{
|
|
||||||
option.response_wait = read_boolean(value, name);
|
|
||||||
}
|
|
||||||
else if (!strcmp(name, "response-timeout"))
|
|
||||||
{
|
|
||||||
option.response_timeout = read_integer(value, name, 0, LONG_MAX);
|
|
||||||
}
|
|
||||||
else if (!strcmp(name, "rs-485"))
|
else if (!strcmp(name, "rs-485"))
|
||||||
{
|
{
|
||||||
option.rs485 = read_boolean(value, name);
|
option.rs485 = read_boolean(value, name);
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,6 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// Enter non interactive mode
|
// Enter non interactive mode
|
||||||
interactive_mode = false;
|
interactive_mode = false;
|
||||||
|
|
||||||
// Mute tio text in response mode
|
|
||||||
if (option.response_wait)
|
|
||||||
{
|
|
||||||
option.mute = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure output terminal */
|
/* Configure output terminal */
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ enum opt_t
|
||||||
OPT_LOG_STRIP,
|
OPT_LOG_STRIP,
|
||||||
OPT_LOG_APPEND,
|
OPT_LOG_APPEND,
|
||||||
OPT_LINE_PULSE_DURATION,
|
OPT_LINE_PULSE_DURATION,
|
||||||
OPT_RESPONSE_TIMEOUT,
|
|
||||||
OPT_RS485,
|
OPT_RS485,
|
||||||
OPT_RS485_CONFIG,
|
OPT_RS485_CONFIG,
|
||||||
OPT_ALERT,
|
OPT_ALERT,
|
||||||
|
|
@ -96,8 +95,6 @@ struct option_t option =
|
||||||
.prefix_code = 20, // ctrl-t
|
.prefix_code = 20, // ctrl-t
|
||||||
.prefix_key = 't',
|
.prefix_key = 't',
|
||||||
.prefix_enabled = true,
|
.prefix_enabled = true,
|
||||||
.response_wait = false,
|
|
||||||
.response_timeout = 100,
|
|
||||||
.mute = false,
|
.mute = false,
|
||||||
.rs485 = false,
|
.rs485 = false,
|
||||||
.rs485_config_flags = 0,
|
.rs485_config_flags = 0,
|
||||||
|
|
@ -142,8 +139,6 @@ void print_help(char *argv[])
|
||||||
printf(" -m, --map <flags> Map characters\n");
|
printf(" -m, --map <flags> Map characters\n");
|
||||||
printf(" -c, --color 0..255|bold|none|list Colorize tio text (default: bold)\n");
|
printf(" -c, --color 0..255|bold|none|list Colorize tio text (default: bold)\n");
|
||||||
printf(" -S, --socket <socket> Redirect I/O to socket\n");
|
printf(" -S, --socket <socket> Redirect I/O to socket\n");
|
||||||
printf(" -r, --response-wait Wait for line response then quit\n");
|
|
||||||
printf(" --response-timeout <ms> Response timeout (default: 100)\n");
|
|
||||||
printf(" --rs-485 Enable RS-485 mode\n");
|
printf(" --rs-485 Enable RS-485 mode\n");
|
||||||
printf(" --rs-485-config <config> Set RS-485 configuration\n");
|
printf(" --rs-485-config <config> Set RS-485 configuration\n");
|
||||||
printf(" --alert bell|blink|none Alert on connect/disconnect (default: none)\n");
|
printf(" --alert bell|blink|none Alert on connect/disconnect (default: none)\n");
|
||||||
|
|
@ -375,8 +370,6 @@ void options_parse(int argc, char *argv[])
|
||||||
{"color", required_argument, 0, 'c' },
|
{"color", required_argument, 0, 'c' },
|
||||||
{"input-mode", required_argument, 0, OPT_INPUT_MODE },
|
{"input-mode", required_argument, 0, OPT_INPUT_MODE },
|
||||||
{"output-mode", required_argument, 0, OPT_OUTPUT_MODE },
|
{"output-mode", required_argument, 0, OPT_OUTPUT_MODE },
|
||||||
{"response-wait", no_argument, 0, 'r' },
|
|
||||||
{"response-timeout", required_argument, 0, OPT_RESPONSE_TIMEOUT },
|
|
||||||
{"rs-485", no_argument, 0, OPT_RS485 },
|
{"rs-485", no_argument, 0, OPT_RS485 },
|
||||||
{"rs-485-config", required_argument, 0, OPT_RS485_CONFIG },
|
{"rs-485-config", required_argument, 0, OPT_RS485_CONFIG },
|
||||||
{"alert", required_argument, 0, OPT_ALERT },
|
{"alert", required_argument, 0, OPT_ALERT },
|
||||||
|
|
@ -531,14 +524,6 @@ void options_parse(int argc, char *argv[])
|
||||||
option.output_mode = output_mode_option_parse(optarg);
|
option.output_mode = output_mode_option_parse(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
|
||||||
option.response_wait = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPT_RESPONSE_TIMEOUT:
|
|
||||||
option.response_timeout = string_to_long(optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPT_RS485:
|
case OPT_RS485:
|
||||||
option.rs485 = true;
|
option.rs485 = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,6 @@ struct option_t
|
||||||
unsigned char prefix_code;
|
unsigned char prefix_code;
|
||||||
unsigned char prefix_key;
|
unsigned char prefix_key;
|
||||||
bool prefix_enabled;
|
bool prefix_enabled;
|
||||||
bool response_wait;
|
|
||||||
int response_timeout;
|
|
||||||
bool mute;
|
bool mute;
|
||||||
bool rs485;
|
bool rs485;
|
||||||
uint32_t rs485_config_flags;
|
uint32_t rs485_config_flags;
|
||||||
|
|
|
||||||
87
src/tty.c
87
src/tty.c
|
|
@ -1536,9 +1536,6 @@ int tty_connect(void)
|
||||||
int status;
|
int status;
|
||||||
bool next_timestamp = false;
|
bool next_timestamp = false;
|
||||||
char* now = NULL;
|
char* now = NULL;
|
||||||
struct timeval tv;
|
|
||||||
struct timeval *tv_p = &tv;
|
|
||||||
bool ignore_stdin = false;
|
|
||||||
|
|
||||||
/* Open tty device */
|
/* Open tty device */
|
||||||
fd = open(option.tty_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
fd = open(option.tty_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||||
|
|
@ -1629,6 +1626,35 @@ int tty_connect(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If stdin is a pipe forward all input to tty device */
|
||||||
|
if (interactive_mode == false)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int ret = read(pipefd[0], &input_char, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
tio_error_printf("Could not read from pipe (%s)", strerror(errno));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else if (ret > 0)
|
||||||
|
{
|
||||||
|
// Forward to tty device
|
||||||
|
ret = write(fd, &input_char, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
tio_error_printf("Could not write to serial device (%s)", strerror(errno));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// EOF - finished forwarding
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Manage script activation */
|
/* Manage script activation */
|
||||||
if (option.script_run != SCRIPT_RUN_NEVER)
|
if (option.script_run != SCRIPT_RUN_NEVER)
|
||||||
{
|
{
|
||||||
|
|
@ -1640,33 +1666,24 @@ int tty_connect(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exit if piped input
|
||||||
|
if (interactive_mode == false)
|
||||||
|
{
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/* Input loop */
|
/* Input loop */
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
FD_ZERO(&rdfs);
|
FD_ZERO(&rdfs);
|
||||||
FD_SET(fd, &rdfs);
|
FD_SET(fd, &rdfs);
|
||||||
if (!ignore_stdin)
|
FD_SET(pipefd[0], &rdfs);
|
||||||
{
|
|
||||||
FD_SET(pipefd[0], &rdfs);
|
|
||||||
}
|
|
||||||
maxfd = MAX(fd, pipefd[0]);
|
maxfd = MAX(fd, pipefd[0]);
|
||||||
maxfd = MAX(maxfd, socket_add_fds(&rdfs, true));
|
maxfd = MAX(maxfd, socket_add_fds(&rdfs, true));
|
||||||
|
|
||||||
/* Manage timeout */
|
|
||||||
if ((option.response_wait) && (option.response_timeout != 0))
|
|
||||||
{
|
|
||||||
// Set response timeout
|
|
||||||
tv_p->tv_sec = 0;
|
|
||||||
tv_p->tv_usec = option.response_timeout * 1000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No timeout
|
|
||||||
tv_p = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Block until input becomes available */
|
/* Block until input becomes available */
|
||||||
status = select(maxfd + 1, &rdfs, NULL, NULL, tv_p);
|
status = select(maxfd + 1, &rdfs, NULL, NULL, NULL);
|
||||||
if (status > 0)
|
if (status > 0)
|
||||||
{
|
{
|
||||||
bool forward = false;
|
bool forward = false;
|
||||||
|
|
@ -1750,15 +1767,6 @@ int tty_connect(void)
|
||||||
{
|
{
|
||||||
next_timestamp = true;
|
next_timestamp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option.response_wait)
|
|
||||||
{
|
|
||||||
if (input_char == '\n')
|
|
||||||
{
|
|
||||||
tty_sync(fd);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (FD_ISSET(pipefd[0], &rdfs))
|
else if (FD_ISSET(pipefd[0], &rdfs))
|
||||||
|
|
@ -1772,22 +1780,9 @@ int tty_connect(void)
|
||||||
}
|
}
|
||||||
else if (bytes_read == 0)
|
else if (bytes_read == 0)
|
||||||
{
|
{
|
||||||
/* Reached EOF (when piping to stdin) */
|
/* Reached EOF (when piping to stdin, never reached) */
|
||||||
if (option.response_wait)
|
tty_sync(fd);
|
||||||
{
|
exit(EXIT_SUCCESS);
|
||||||
/* Stdin pipe closed but not blocking so stop listening
|
|
||||||
* to stdin in response mode.
|
|
||||||
*
|
|
||||||
* Note: select() really indicates not if data is ready
|
|
||||||
* but if file descriptor is non-blocking for I/O
|
|
||||||
* operation. */
|
|
||||||
ignore_stdin = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tty_sync(fd);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process input byte by byte */
|
/* Process input byte by byte */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue