diff --git a/examples/lua/read.lua b/examples/lua/read.lua new file mode 100644 index 0000000..2ee99db --- /dev/null +++ b/examples/lua/read.lua @@ -0,0 +1,14 @@ +read(1000, 6000) -- initial config +send("\n") +msleep(100) +read(650, 60) -- main menu +send("S") -- S menu +msleep(30) +read(650, 60) +send("t") -- Parallel Value Table +read(650, 60) +while true do + msleep(1000) + send("t") + read(650, 50) -- repeat PVT forever +end diff --git a/examples/lua/read_line.lua b/examples/lua/read_line.lua new file mode 100644 index 0000000..97f157d --- /dev/null +++ b/examples/lua/read_line.lua @@ -0,0 +1,17 @@ +read(1000, 8000) -- read initial config +send("\n") +read(650, 100) -- main menu +send("S") -- S menu +n = 1 +while n > 0 do -- while not empty, read more + n, str = read_line(25) +end +while true do + send("t") -- query PV table + msleep(880) + n = 1 + while n > 0 do -- while not empty, read more + n, str = read_line(60) + msleep(60) + end +end diff --git a/man/tio.1.in b/man/tio.1.in index 631b938..4ad15ed 100644 --- a/man/tio.1.in +++ b/man/tio.1.in @@ -467,7 +467,18 @@ until data is ready to read. Returns number of bytes read on success, 0 on timeout, or -1 on error. -On success, returns read string as second return value. +On success, returns read string as second return value. Also emits a single +timestamp to stdout and log file per options.timestamp and options.log. + +.IP "\fBread_line(timeout)" +Read line from serial device. If timeout is 0 or not provided it will wait +forever until data is ready to read. + +Returns number of bytes read on success, 0 on timeout, or -1 on error. + +On success, returns the string that was read as second return value. Also +emits a single timestamp to stdout and log file per options.timestamp +and options.log. .IP "\fBset{line=state, ...}" Set state of one or multiple tty modem lines. diff --git a/man/tio.1.txt b/man/tio.1.txt index 7c872f5..6debf36 100644 --- a/man/tio.1.txt +++ b/man/tio.1.txt @@ -373,7 +373,14 @@ SCRIPT API Returns number of bytes read on success, 0 on timeout, or -1 on error. - On success, returns read string as second return value. + On success, returns read string as second return value. Also emits a single timestamp to stdout and log file per options.timestamp and options.log. + + read_line(timeout) + Read line from serial device. If timeout is 0 or not provided it will wait forever until data is ready to read. + + Returns number of bytes read on success, 0 on timeout, or -1 on error. + + On success, returns the string that was read as second return value. Also emits a single timestamp to stdout and log file per options.timestamp and options.log. set{line=state, ...} Set state of one or multiple tty modem lines. diff --git a/src/configfile.c b/src/configfile.c index 97fc59f..07da79a 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -209,7 +209,7 @@ static void config_parse_keys(GKeyFile *key_file, char *group) { option.timestamp = TIMESTAMP_24HOUR; } - config_get_string(key_file, group, "timestamp-format", &string, "24hour", "24hour-start", "24hour-delta", "iso8601", NULL); + config_get_string(key_file, group, "timestamp-format", &string, "24hour", "24hour-start", "24hour-delta", "iso8601", "epoch", NULL); if (string != NULL) { option_parse_timestamp(string, &option.timestamp); diff --git a/src/error.c b/src/error.c index f318378..9f6bac2 100644 --- a/src/error.c +++ b/src/error.c @@ -19,8 +19,7 @@ * 02110-1301, USA. */ -#define __STDC_WANT_LIB_EXT2__ 1 // To access vasprintf - +#define _GNU_SOURCE // To access vasprintf #include #include "print.h" diff --git a/src/log.c b/src/log.c index 8966457..4131617 100644 --- a/src/log.c +++ b/src/log.c @@ -19,8 +19,7 @@ * 02110-1301, USA. */ -#define __STDC_WANT_LIB_EXT2__ 1 // To access vasprintf - +#define _GNU_SOURCE // To access vasprintf #include #include #include diff --git a/src/options.c b/src/options.c index 398279f..04d5be6 100644 --- a/src/options.c +++ b/src/options.c @@ -19,6 +19,8 @@ * 02110-1301, USA. */ +#define _GNU_SOURCE // To access vasprintf + #include #include #include diff --git a/src/script.c b/src/script.c index 484c79f..b565741 100644 --- a/src/script.c +++ b/src/script.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "misc.h" #include "print.h" #include "options.h" @@ -37,8 +38,11 @@ #include "log.h" #include "script.h" #include "fs.h" +#include "timestamp.h" +#include "termios.h" #define MAX_BUFFER_SIZE 2000 // Maximum size of circular buffer +#define READ_LINE_SIZE 4096 // read_line buffer length static int device_fd; static char circular_buffer[MAX_BUFFER_SIZE]; @@ -192,6 +196,8 @@ static int send_(lua_State *L) } ret = write(device_fd, string, strlen(string)); + fsync(device_fd); // flush these characters now + tcdrain(device_fd); //ensure we flushed characters to our device lua_pushnumber(L, ret); @@ -248,10 +254,39 @@ static bool match_regex(regex_t *regex) return false; } -// lua: ret,string = read_string(size, timeout) +// Function to echo a buffer to stdout and to the log +// per the option.timestamp and option.log settings +static void echo_buffer(char buffer[], ssize_t len) +{ + if (option.timestamp) + { + char *pTimeStampNow; + pTimeStampNow = timestamp_current_time(); + if (pTimeStampNow) + { + tio_printf("%s", buffer); //does timestamps for us + if (option.log) + { + log_printf("\n[%s] %s", pTimeStampNow, buffer); + } + } + } else { + for (ssize_t i=0; i 0 ? buffer : ""); free(buffer); } + else + { + lua_pushstring(L, ""); // give empty string to caller + } + return 2; +} + +// lua: ret,string = read_line(timeout) +static int read_line(lua_State *L) +{ + static char linebuf[READ_LINE_SIZE]; + int timeout = lua_tointeger(L, 1); //ms + int ret = 0; + int read_result = 1; //enable reading input from device + char ch; + int bytes_read = 0; + + linebuf[0] = '\0'; + if (timeout == 0) + { + timeout = -1; // Wait forever + } + + // loop reading input until a newline seen or timeout + while (true) + { + read_result = read_poll(device_fd, &ch, 1, timeout); + if (read_result < 0) + { + ret = -1; // Error + linebuf[bytes_read] = '\0'; + goto error_rl; + } + else if (!read_result) + { + // Timeout returns a non-empty linebuf as a 'line' + ret = bytes_read; + linebuf[bytes_read] = '\0'; + break; + } + else // we got a character, so handle it + { + if (ch == '\n') + { + linebuf[bytes_read] = '\0'; + break; + } + else if (bytes_read <= (READ_LINE_SIZE-2)) + { + if (isprint(ch)) // store all printable chars + { + linebuf[bytes_read++] = ch; + } + } + } + } + + if (bytes_read) + { + echo_buffer(linebuf, bytes_read); + } + ret = bytes_read; + +error_rl: + lua_pushnumber(L, ret); + lua_pushstring(L, linebuf); return 2; } @@ -457,6 +553,7 @@ static const struct luaL_Reg tio_lib[] = { "modem_send", modem_send}, { "send", send_}, { "read", read_string}, + { "read_line", read_line}, { "expect", expect}, { "exit", exit_}, { "tty_search", tty_search_}, diff --git a/src/timestamp.c b/src/timestamp.c index e81cda2..b5ec306 100644 --- a/src/timestamp.c +++ b/src/timestamp.c @@ -29,8 +29,6 @@ #include "options.h" #include "timestamp.h" -#define TIME_STRING_SIZE_MAX 24 - char *timestamp_current_time(void) { static char time_string[TIME_STRING_SIZE_MAX]; diff --git a/src/timestamp.h b/src/timestamp.h index 48e0a76..6a10d98 100644 --- a/src/timestamp.h +++ b/src/timestamp.h @@ -32,5 +32,7 @@ typedef enum TIMESTAMP_END, } timestamp_t; +#define TIME_STRING_SIZE_MAX 24 + char *timestamp_current_time(void); diff --git a/src/tty.c b/src/tty.c index 74f6ab3..0021396 100644 --- a/src/tty.c +++ b/src/tty.c @@ -1615,6 +1615,7 @@ const char* get_serial_port_type(const char* port_name) const char* get_serial_port_type(const char* port_name) { + (void)port_name; return ""; }