Extended hexadecimal mode.

While in hex mode (ctrl-t h) you can output hexadecimal values.
E.g.: to send 0x0A you have to type 0A (always 2 characters).

Added option -x, --hex to start in hexadecimal mode.

Added option --newline-in-hex to interpret newline characters in hex mode.
This is disabled by default, because, in my opinion, hex stream is
fundamentally different from text, so a "new line" is meaningless in this
context.
This commit is contained in:
g0mb4 2021-07-19 11:32:00 +02:00 committed by Martin Lund
parent 7d3b687eb4
commit 0b55981e52
5 changed files with 128 additions and 20 deletions

108
src/tty.c
View file

@ -74,7 +74,60 @@ static bool map_i_nl_crnl = false;
static bool map_o_cr_nl = false;
static bool map_o_nl_crnl = false;
static bool map_o_del_bs = false;
static char hex_chars[2];
static unsigned char hex_char_index = 0;
static void optional_local_echo(char c)
{
if (!option.local_echo)
return;
print(c);
fflush(stdout);
if (option.log)
log_write(c);
}
inline static bool is_valid_hex(char c)
{
return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}
inline static unsigned char char_to_nibble(char c)
{
if(c >= '0' && c <= '9'){
return c - '0';
} else if(c >= 'a' && c <= 'f'){
return c - 'a' + 10;
} else if(c >= 'A' && c <= 'F'){
return c - 'A' + 10;
} else {
return 0;
}
}
static void output_hex(char c)
{
hex_chars[hex_char_index++] = c;
if (hex_char_index == 2)
{
unsigned char hex_value = char_to_nibble(hex_chars[0]) << 4 | (char_to_nibble(hex_chars[1]) & 0x0F);
hex_char_index = 0;
optional_local_echo(hex_value);
ssize_t status = write(fd, &hex_value, 1);
if (status < 0)
{
warning_printf("Could not write to tty device");
} else
{
tx_total++;
}
fsync(fd);
}
}
static void toggle_line(const char *line_name, int mask)
{
@ -585,16 +638,6 @@ void tty_restore(void)
tty_disconnect();
}
static void optional_local_echo(char c)
{
if (!option.local_echo)
return;
print(c);
fflush(stdout);
if (option.log)
log_write(c);
}
int tty_connect(void)
{
fd_set rdfs; /* Read file descriptor set */
@ -644,6 +687,19 @@ int tty_connect(void)
if (option.timestamp)
next_timestamp = true;
if (option.hex_mode)
{
print = print_hex;
print_mode = HEX;
tio_printf("Switched to hexadecimal mode");
}
else
{
print = print_normal;
print_mode = NORMAL;
tio_printf("Switched to normal mode");
}
/* Save current port settings */
if (tcgetattr(fd, &tio_old) < 0)
goto error_tcgetattr;
@ -800,6 +856,15 @@ int tty_connect(void)
if (forward)
{
if (print_mode == HEX)
{
if (!is_valid_hex(input_char))
{
warning_printf("Invalid hex character: '%c' (0x%02x)", input_char, input_char);
continue;
}
}
/* Map output character */
if ((output_char == 127) && (map_o_del_bs))
output_char = '\b';
@ -820,15 +885,22 @@ int tty_connect(void)
delay(option.output_delay);
} else
{
/* Send output to tty device */
optional_local_echo(output_char);
status = write(fd, &output_char, 1);
if (status < 0)
warning_printf("Could not write to tty device");
fsync(fd);
if (print_mode == HEX)
{
output_hex(output_char);
}
else
{
/* Send output to tty device */
optional_local_echo(output_char);
status = write(fd, &output_char, 1);
if (status < 0)
warning_printf("Could not write to tty device");
fsync(fd);
/* Update transmit statistics */
tx_total++;
/* Update transmit statistics */
tx_total++;
}
/* Insert output delay */
delay(option.output_delay);