From dbc9a8e82d9d6141692eb2e8b2bc0b4097e8bcca Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 10 Sep 2022 22:27:31 +0200 Subject: [PATCH] Add visual or audible alert support on connect/disconnect The feature is detailed via the following option: --alert none|bell|blink Set alert action on connect/disconnect. It will sound the bell once or blink once on successful connect. Likewise it will sound the bell twice or blink twice on disconnect. Default value is "none" for no alert. --- example/tiorc | 1 + man/tio.1.in | 12 ++++ src/alert.c | 110 +++++++++++++++++++++++++++++++++++++ src/alert.h | 33 +++++++++++ src/bash-completion/tio.in | 11 +++- src/configfile.c | 6 +- src/meson.build | 3 +- src/misc.c | 1 + src/misc.h | 2 + src/options.c | 12 +++- src/options.h | 3 + src/tty.c | 8 +++ 12 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 src/alert.c create mode 100644 src/alert.h diff --git a/example/tiorc b/example/tiorc index e7f0f18..da6be99 100644 --- a/example/tiorc +++ b/example/tiorc @@ -30,6 +30,7 @@ color = 9 baudrate = 115200 tty = /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_01093176-if01-port0 line-pulse-duration = DTR=200,RTS=300,RI=50 +alert = bell color = 10 [tincan] diff --git a/man/tio.1.in b/man/tio.1.in index 36b0b1c..3cf3d16 100644 --- a/man/tio.1.in +++ b/man/tio.1.in @@ -256,6 +256,16 @@ Receive data even while sending data If defining more than one key or key value pair, they must be comma separated. .RE +.TP +.BR "\-\-alert none|bell|blink" + +Set alert action on connect/disconnect. + +It will sound the bell once or blink once on successful connect. Likewise it +will sound the bell twice or blink twice on disconnect. + +Default value is "none". + .TP .BR \-v ", " \-\-version @@ -389,6 +399,8 @@ Set line response timeout Enable RS-485 mode .IP "\fBrs-485-config" Set RS-485 configuration +.IP "\fBalert" +Set alert action on connect/disconnect .SH "CONFIGURATION FILE EXAMPLES" diff --git a/src/alert.c b/src/alert.c new file mode 100644 index 0000000..4cb0132 --- /dev/null +++ b/src/alert.c @@ -0,0 +1,110 @@ +/* + * tio - a simple serial terminal I/O tool + * + * Copyright (c) 2014-2022 Martin Lund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include "config.h" +#include +#include +#include +#include +#include "error.h" +#include "print.h" +#include "options.h" + +enum alert_t alert_option_parse(const char *arg) +{ + enum alert_t alert = option.alert; // Default + + if (arg != NULL) + { + if (strcmp(arg, "none") == 0) + { + return ALERT_NONE; + } + else if (strcmp(arg, "bell") == 0) + { + return ALERT_BELL; + } + else if (strcmp(arg, "blink") == 0) + { + return ALERT_BLINK; + } + } + + return alert; +} + +void blink_background(void) +{ + // Turn on reverse video + printf("\e[?5h"); + fflush(stdout); + + usleep(200*1000); + + // Turn on normal video + printf("\e[?5l"); + fflush(stdout); +} + +void sound_bell(void) +{ + // Audio bell + printf("\a"); + fflush(stdout); +} + +void alert_connect(void) +{ + switch (option.alert) + { + case ALERT_NONE: + break; + case ALERT_BELL: + sound_bell(); + break; + case ALERT_BLINK: + blink_background(); + break; + default: + break; + } +} + +void alert_disconnect(void) +{ + switch (option.alert) + { + case ALERT_NONE: + break; + case ALERT_BELL: + sound_bell(); + usleep(200*1000); + sound_bell(); + break; + case ALERT_BLINK: + blink_background(); + usleep(200*1000); + blink_background(); + break; + default: + break; + } +} diff --git a/src/alert.h b/src/alert.h new file mode 100644 index 0000000..3fe8679 --- /dev/null +++ b/src/alert.h @@ -0,0 +1,33 @@ +/* + * tio - a simple serial terminal I/O tool + * + * Copyright (c) 2014-2022 Martin Lund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#pragma once + +enum alert_t +{ + ALERT_NONE, + ALERT_BELL, + ALERT_BLINK, + ALERT_END, +}; + +void alert_connect(void); +void alert_disconnect(void); diff --git a/src/bash-completion/tio.in b/src/bash-completion/tio.in index cea90f1..ca115e6 100644 --- a/src/bash-completion/tio.in +++ b/src/bash-completion/tio.in @@ -29,11 +29,12 @@ _tio() -L --list-devices \ -c --color \ -S --socket \ + -x --hexadecimal \ -r --response-wait \ --response-timeout \ --rs-485 \ --rs-485-config \ - -x --hexadecimal \ + --alert \ -v --version \ -h --help" @@ -116,6 +117,10 @@ _tio() COMPREPLY=( $(compgen -W "unix: inet: inet6:" -- ${cur}) ) return 0 ;; + -x | --hexadecimal) + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; -r | --response-wait) COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 @@ -132,8 +137,8 @@ _tio() COMPREPLY=( $(compgen -W "RTS_ON_SEND RTS_AFTER_SEND RTS_DELAY_BEFORE_SEND RTS_DELAY_AFTER_SEND RX_DURING_TX" -- ${cur}) ) return 0 ;; - -x | --hexadecimal) - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + --alert) + COMPREPLY=( $(compgen -W "none bell blink" -- ${cur}) ) return 0 ;; -v | --version) diff --git a/src/configfile.c b/src/configfile.c index e081a70..5375e73 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -280,8 +280,12 @@ static int data_handler(void *user, const char *section, const char *name, { rs485_parse_config(value); } - + else if (!strcmp(name, "alert")) + { + option.alert = alert_option_parse(value); + } } + return 0; } diff --git a/src/meson.build b/src/meson.build index 061d070..f5ee7a3 100644 --- a/src/meson.build +++ b/src/meson.build @@ -15,7 +15,8 @@ tio_sources = [ 'signals.c', 'socket.c', 'setspeed.c', - 'rs485.c' + 'rs485.c', + 'alert.c' ] tio_dep = dependency('inih', required: true, diff --git a/src/misc.c b/src/misc.c index c519c46..22be237 100644 --- a/src/misc.c +++ b/src/misc.c @@ -22,6 +22,7 @@ #include "config.h" #include #include +#include #include #include #include diff --git a/src/misc.h b/src/misc.h index 23208a6..6fe5368 100644 --- a/src/misc.h +++ b/src/misc.h @@ -27,3 +27,5 @@ char * current_time(void); void delay(long ms); long string_to_long(char *string); int ctrl_key_code(unsigned char key); +void alert_connect(void); +void alert_disconnect(void); diff --git a/src/options.c b/src/options.c index b6099ee..633cca4 100644 --- a/src/options.c +++ b/src/options.c @@ -36,6 +36,7 @@ #include "print.h" #include "tty.h" #include "rs485.h" +#include "alert.h" enum opt_t { @@ -47,6 +48,7 @@ enum opt_t OPT_RESPONSE_TIMEOUT, OPT_RS485, OPT_RS485_CONFIG, + OPT_ALERT, }; /* Default options */ @@ -85,6 +87,7 @@ struct option_t option = .rs485_config_flags = 0, .rs485_delay_rts_before_send = -1, .rs485_delay_rts_after_send = -1, + .alert = ALERT_NONE, }; void print_help(char *argv[]) @@ -118,6 +121,7 @@ void print_help(char *argv[]) printf(" --response-timeout Response timeout (default: 100)\n"); printf(" --rs-485 Enable RS-485 mode\n"); printf(" --rs-485-config Set RS-485 configuration\n"); + printf(" --alert none|bell|blink Alert on connect/disconnect (default: none)\n"); printf(" -v, --version Display version\n"); printf(" -h, --help Display help\n"); printf("\n"); @@ -159,7 +163,7 @@ const char* timestamp_state_to_string(enum timestamp_t timestamp) enum timestamp_t timestamp_option_parse(const char *arg) { enum timestamp_t timestamp = TIMESTAMP_24HOUR; // Default - + if (arg != NULL) { if (strcmp(arg, "24hour") == 0) @@ -237,7 +241,6 @@ void line_pulse_duration_option_parse(const char *arg) } } free(buffer); - } void options_print() @@ -306,6 +309,7 @@ void options_parse(int argc, char *argv[]) {"response-timeout", required_argument, 0, OPT_RESPONSE_TIMEOUT }, {"rs-485", no_argument, 0, OPT_RS485 }, {"rs-485-config", required_argument, 0, OPT_RS485_CONFIG }, + {"alert", required_argument, 0, OPT_ALERT }, {"version", no_argument, 0, 'v' }, {"help", no_argument, 0, 'h' }, {0, 0, 0, 0 } @@ -456,6 +460,10 @@ void options_parse(int argc, char *argv[]) rs485_parse_config(optarg); break; + case OPT_ALERT: + option.alert = alert_option_parse(optarg); + break; + case 'v': printf("tio v%s\n", VERSION); exit(EXIT_SUCCESS); diff --git a/src/options.h b/src/options.h index b5e1bca..8ce6ec0 100644 --- a/src/options.h +++ b/src/options.h @@ -26,6 +26,7 @@ #include #include #include +#include "alert.h" enum timestamp_t { @@ -75,6 +76,7 @@ struct option_t uint32_t rs485_config_flags; int32_t rs485_delay_rts_before_send; int32_t rs485_delay_rts_after_send; + enum alert_t alert; }; extern struct option_t option; @@ -84,3 +86,4 @@ void options_parse(int argc, char *argv[]); void options_parse_final(int argc, char *argv[]); void line_pulse_duration_option_parse(const char *arg); +enum alert_t alert_option_parse(const char *arg); diff --git a/src/tty.c b/src/tty.c index 4cbee06..004e52a 100644 --- a/src/tty.c +++ b/src/tty.c @@ -51,6 +51,8 @@ #include "socket.h" #include "setspeed.h" #include "rs485.h" +#include "alert.h" +#include "misc.h" #ifdef __APPLE__ #define PATH_SERIAL_DEVICES "/dev/" @@ -950,6 +952,9 @@ void tty_disconnect(void) flock(fd, LOCK_UN); close(fd); connected = false; + + /* Fire alert action */ + alert_disconnect(); } } @@ -1066,6 +1071,9 @@ int tty_connect(void) connected = true; print_tainted = false; + /* Fire alert action */ + alert_connect(); + if (option.timestamp) { next_timestamp = true;