From 6d77201ba09ad7b000c82002e69fc9219db6bab4 Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Mon, 29 Apr 2024 14:45:36 +0200 Subject: [PATCH] Simplify lua line manipulation API Collapses lua high(), low(), toggle(), config_high(), config_low(), config_apply() into one simple function: set{=, ...} Line can be any of DTR, RTS, CTS, DSR, CD, RI. State is high, low, or toggle. Example: script = set{DTR=high, RTS=low}; msleep(100); set{DTR=low, RTS=high}; msleep(100); set{RTS=low} Notice the use of {} instad of () when calling the set function. This is required to pass parameters by name in lua. --- README.md | 27 ++--- examples/lua/control-lines-test.lua | 8 +- man/tio.1.in | 28 ++--- src/script.c | 156 +++++++++++----------------- src/tty.c | 92 ++++------------ src/tty.h | 12 ++- 6 files changed, 112 insertions(+), 211 deletions(-) diff --git a/README.md b/README.md index dd83628..0981663 100644 --- a/README.md +++ b/README.md @@ -343,17 +343,12 @@ read(size, timeout) Returns number of bytes read on success, 0 on timeout, or -1 on error. -exit(code) - Exit with exit code. +set{line=state, ...} + Set state of one or multiple tty modem lines. -high(line) - Set tty line high. + Line can be any of DTR, RTS, CTS, DSR, CD, RI -low(line) - Set tty line low. - -toggle(line) - Toggle the tty line. + State is high, low, or toggle. sleep(seconds) Sleep for seconds. @@ -361,18 +356,8 @@ sleep(seconds) msleep(ms) Sleep for miliseconds. -config_high(line) - Set tty line state configuration to high. - -config_low(line) - Set tty line state configuration to low. - -apply_config() - Apply tty line state configuration. Using the line state configuration - API instead of high()/low() will help to make the lines physically switch as - simultaneously as possible. This may solve timing issues on some platforms. - -Note: Line can be any of DTR, RTS, CTS, DSR, CD, RI +exit(code) + Exit with exit code. ``` ### 3.4 Configuration file diff --git a/examples/lua/control-lines-test.lua b/examples/lua/control-lines-test.lua index 9f0d493..5b54ab4 100644 --- a/examples/lua/control-lines-test.lua +++ b/examples/lua/control-lines-test.lua @@ -1,7 +1,5 @@ -high(DTR) -low(RTS) +set{DTR=high, RTS=low} msleep(100) -low(DTR) -high(RTS) +set{DTR=low, RTS=high} msleep(100) -low(RTS) +set{RTS=toggle} diff --git a/man/tio.1.in b/man/tio.1.in index 87d5180..4b76cfa 100644 --- a/man/tio.1.in +++ b/man/tio.1.in @@ -457,29 +457,19 @@ until data is ready to read. Returns number of bytes read on success, 0 on timeout, or -1 on error. -.IP "\fBexit(code)" -Exit with exit code. -.IP "\fBhigh(line)" -Set tty line high. -.IP "\fBlow(line)" -Set tty line low. -.IP "\fBtoggle(line)" -Toggle the tty line. +.IP "\fBset{line=state, ...}" +Set state of one or multiple tty modem lines. + +Line can be any of DTR, RTS, CTS, DSR, CD, RI + +State is high, low, or toggle. + .IP "\fBsleep(seconds)" Sleep for seconds. .IP "\fBmsleep(ms)" Sleep for miliseconds. -.IP "\fBconfig_high(line)" -Set tty line state configuration to high. -.IP "\fBconfig_low(line)" -Set tty line state configuration to low. -.IP "\fBapply_config()" -Apply tty line state configuration. Using the line state configuration API -instead of high()/low() will help to make the lines physically switch as -simultaneously as possible. This may solve timing issues on some platforms. - -.TP 0n -Note: Line can be any of DTR, RTS, CTS, DSR, CD, RI +.IP "\fBexit(code)" +Exit with exit code. .SH "CONFIGURATION FILE" .PP diff --git a/src/script.c b/src/script.c index 571c58c..f425a1f 100644 --- a/src/script.c +++ b/src/script.c @@ -45,8 +45,16 @@ static char circular_buffer[MAX_BUFFER_SIZE]; static char match_string[MAX_BUFFER_SIZE]; static int buffer_size = 0; -static char init_script[] = -"\n"; +static char script_init[] = +"function set(arg)\n" +" local dtr = arg.DTR or -1\n" +" local rts = arg.RTS or -1\n" +" local cts = arg.CTS or -1\n" +" local dsr = arg.DSR or -1\n" +" local cd = arg.CD or -1\n" +" local ri = arg.RI or -1\n" +" line_set(dtr, rts, cts, dsr, cd, ri)\n" +"end\n"; // lua: sleep(seconds) static int sleep_(lua_State *L) @@ -82,87 +90,56 @@ static int msleep(lua_State *L) return 0; } -// lua: high(line) -static int high(lua_State *L) +// lua: line_set(dtr,rts,cts,dsr,cd,ri) +static int line_set(lua_State *L) { - long line = lua_tointeger(L, 1); + tty_line_config_t line_config[6] = { }; - if (line < 0) + int dtr = lua_tointeger(L, 1); + int rts = lua_tointeger(L, 2); + int cts = lua_tointeger(L, 3); + int dsr = lua_tointeger(L, 4); + int cd = lua_tointeger(L, 5); + int ri = lua_tointeger(L, 6); + + if (dtr != -1) { - return 0; + line_config[0].mask = TIOCM_DTR; + line_config[0].value = dtr; + line_config[0].reserved = true; + } + if (rts != -1) + { + line_config[1].mask = TIOCM_RTS; + line_config[1].value = rts; + line_config[1].reserved = true; + } + if (cts != -1) + { + line_config[2].mask = TIOCM_CTS; + line_config[2].value = cts; + line_config[2].reserved = true; + } + if (dsr != -1) + { + line_config[3].mask = TIOCM_DSR; + line_config[3].value = dsr; + line_config[3].reserved = true; + } + if (cd != -1) + { + line_config[4].mask = TIOCM_CD; + line_config[4].value = cd; + line_config[4].reserved = true; + } + if (ri != -1) + { + line_config[5].mask = TIOCM_RI; + line_config[5].value = ri; + line_config[5].reserved = true; } - tty_line_set(device_fd, line, LINE_HIGH); - - return 0; -} - -// lua: low(line) -static int low(lua_State *L) -{ - long line = lua_tointeger(L, 1); - - if (line < 0) - { - return 0; - } - - tty_line_set(device_fd, line, LINE_LOW); - - return 0; -} - -// lua: toggle(line) -static int toggle(lua_State *L) -{ - long line = lua_tointeger(L, 1); - - if (line < 0) - { - return 0; - } - - tty_line_toggle(device_fd, line); - - return 0; -} - -// lua: config_high(line) -static int config_high(lua_State *L) -{ - long line = lua_tointeger(L, 1); - - if (line < 0) - { - return 0; - } - - tty_line_config(line, true); - - return 0; -} - -// lua: config_low(line) -static int config_low(lua_State *L) -{ - long line = lua_tointeger(L, 1); - - if (line < 0) - { - return 0; - } - - tty_line_config(line, false); - - return 0; -} - -// lua: config_apply(line) -static int config_apply(lua_State *L) -{ - UNUSED(L); - - tty_line_config_apply(); + tty_line_set(device_fd, line_config); return 0; } @@ -472,12 +449,7 @@ static const struct luaL_Reg tio_lib[] = { { "sleep", sleep_}, { "msleep", msleep}, - { "high", high}, - { "low", low}, - { "toggle", toggle}, - { "config_high", config_high}, - { "config_low", config_low}, - { "config_apply", config_apply}, + { "line_set", line_set}, { "modem_send", modem_send}, { "send", send}, { "read", read_string}, @@ -506,11 +478,11 @@ static void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) } #endif -static void load_init_script(lua_State *L) +static void script_load(lua_State *L) { int error; - error = luaL_loadbuffer(L, init_script, strlen(init_script), "tio") || lua_pcall(L, 0, 0, 0); + error = luaL_loadbuffer(L, script_init, strlen(script_init), "tio") || lua_pcall(L, 0, 0, 0); if (error) { tio_error_print("%s\n", lua_tostring(L, -1)); @@ -525,7 +497,8 @@ int lua_register_tio(lua_State *L) luaL_setfuncs(L, tio_lib, 0); lua_pop(L, 1); - load_init_script(L); + // Load lua init script + script_load(L); return 0; } @@ -554,12 +527,9 @@ void script_set_global(lua_State *L, const char *name, long value) void script_set_globals(lua_State *L) { - script_set_global(L, "DTR", TIOCM_DTR); - script_set_global(L, "RTS", TIOCM_RTS); - script_set_global(L, "CTS", TIOCM_CTS); - script_set_global(L, "DSR", TIOCM_DSR); - script_set_global(L, "CD", TIOCM_CD); - script_set_global(L, "RI", TIOCM_RI); + script_set_global(L, "toggle", 2); + script_set_global(L, "high", 1); + script_set_global(L, "low", 0); script_set_global(L, "XMODEM_CRC", XMODEM_CRC); script_set_global(L, "XMODEM_1K", XMODEM_1K); script_set_global(L, "YMODEM", YMODEM); diff --git a/src/tty.c b/src/tty.c index a28ba34..c8f7d7b 100644 --- a/src/tty.c +++ b/src/tty.c @@ -137,13 +137,6 @@ typedef enum SUBCOMMAND_XMODEM, } sub_command_t; -typedef struct -{ - int mask; - bool value; - bool reserved; -} tty_line_config_t; - const char random_array[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x20, 0x28, 0x0A, 0x20, @@ -190,7 +183,6 @@ static pthread_t thread; static int pipefd[2]; static pthread_mutex_t mutex_input_ready = PTHREAD_MUTEX_INITIALIZER; static char line[LINE_SIZE_MAX]; -static tty_line_config_t line_config[6] = { }; static void optional_local_echo(char c) { @@ -483,28 +475,12 @@ static const char *tty_line_name(int mask) } } -void tty_line_config(int mask, bool value) +void tty_line_set(int fd, tty_line_config_t line_config[]) { - int i = 0; - - for (i=0; i<6; i++) - { - if ((line_config[i].mask == mask) || (line_config[i].reserved == false)) - { - line_config[i].mask = mask; - line_config[i].value = value; - line_config[i].reserved = true; - break; - } - } -} - -void tty_line_config_apply(void) -{ - int i = 0; static int state; + int i = 0; - if (ioctl(device_fd, TIOCMGET, &state) < 0) + if (ioctl(fd, TIOCMGET, &state) < 0) { tio_warning_printf("Could not get line state (%s)", strerror(errno)); return; @@ -514,57 +490,35 @@ void tty_line_config_apply(void) { if (line_config[i].reserved) { - if (line_config[i].value) - { - // High - state &= ~line_config[i].mask; - tio_printf("Setting %s to HIGH", tty_line_name(line_config[i].mask)); - } - else + if (line_config[i].value == 0) { // Low state |= line_config[i].mask; tio_printf("Setting %s to LOW", tty_line_name(line_config[i].mask)); } + else if (line_config[i].value == 1) + { + // High + state &= ~line_config[i].mask; + tio_printf("Setting %s to HIGH", tty_line_name(line_config[i].mask)); + } + else if (line_config[i].value == 2) + { + // Toggle + state ^= line_config[i].mask; - line_config[i].reserved = true; + if (state & line_config[i].mask) + { + tio_printf("Setting %s to LOW", tty_line_name(line_config[i].mask)); + } + else + { + tio_printf("Setting %s to HIGH", tty_line_name(line_config[i].mask)); + } + } } } - if (ioctl(device_fd, TIOCMSET, &state) < 0) - { - tio_warning_printf("Could not set line state configuration (%s)", strerror(errno)); - } - - // Reset configuration - for (i=0; i<6; i++) - { - line_config[i].reserved = false; - line_config[i].mask = -1; - } -} - -void tty_line_set(int fd, int mask, bool value) -{ - int state; - - if (ioctl(fd, TIOCMGET, &state) < 0) - { - tio_warning_printf("Could not get line state (%s)", strerror(errno)); - return; - } - - if (value) - { - state &= ~mask; - tio_printf("Setting %s to HIGH", tty_line_name(mask)); - } - else - { - state |= mask; - tio_printf("Setting %s to LOW", tty_line_name(mask)); - } - if (ioctl(fd, TIOCMSET, &state) < 0) { tio_warning_printf("Could not set line state (%s)", strerror(errno)); diff --git a/src/tty.h b/src/tty.h index 140f8dc..b142034 100644 --- a/src/tty.h +++ b/src/tty.h @@ -46,6 +46,13 @@ typedef struct char *description; } device_t; +typedef struct +{ + int mask; + int value; + bool reserved; +} tty_line_config_t; + extern const char *device_name; extern bool interactive_mode; extern bool map_i_nl_cr; @@ -60,9 +67,6 @@ void tty_wait_for_device(void); void list_serial_devices(void); void tty_input_thread_create(void); void tty_input_thread_wait_ready(void); -void tty_line_set(int fd, int mask, bool value); -void tty_line_toggle(int fd, int mask); -void tty_line_config(int mask, bool value); -void tty_line_config_apply(void); +void tty_line_set(int fd, tty_line_config_t line_config[]); void tty_search(void); GList *tty_search_for_serial_devices(void);