Fix hex buffer mode and add it to the readme

This commit is contained in:
Aaron Cook 2022-10-16 14:22:24 -05:00
commit d7b0c80f56
4 changed files with 65 additions and 28 deletions

View file

@ -110,14 +110,24 @@ The help prompt lists the available commands.
Commands (lead with ctrl-b):
c: print available quick commands
0-9: load the given quick command (0 is 10)
p, 0-9: select a different quick commands page (0 is 10)
p: select a different quick commands page
i: view info/stats
x: start XModem upload with 128B payloads
X: start XModem upload with 1024B payloads
H: enter/exit hex buffer mode
h: view this help
q: quit Bytenuts
```
### Hex Buffer Mode
When the `ctrl+b H` command has been issued for the first time, you will enter hex buffer mode. In this mode, the input buffer is interpreted as a hex string and will be converted to its byte equivalent before it gets sent to the target. Example inputs:
- `746573740d0a` gets sent as `test\r\n`
- `d0a` gets sent as `\r\n` as it assumed the trailing `0` has been omitted
- `74657374xd0a` gets sent as `test` since the `xd` byte contains an invalid hex character
Hex buffer mode can be turned off with a second `ctrl+b H`.
## Quick Commands
You can provide multiple pages of quick commands you can easily load in with `ctrl+b [0-9]` in the files `~/.config/bytenuts/commands<idx>`. Bytenuts will load pages starting from `commands1` until a `commands<idx>` no longer exists. The commands should be newline separated. When a command is loaded, the entire contents of the line is loaded into the input buffer.

View file

@ -143,25 +143,10 @@ cheerios_stop()
}
int
cheerios_input(const char *line)
cheerios_input(const char *buf, size_t len)
{
size_t line_len = strlen(line);
pthread_mutex_lock(&cheerios.lock);
if (cheerios.config->echo) {
char *line_parsed = calloc(1, line_len + 5 + 1);
sprintf(line_parsed, ">> %s\r\n", line);
insert_buf(&cheerios.lines, line_parsed, strlen(line_parsed));
free(line_parsed);
}
write(cheerios.ser_fd, line, strlen(line));
if (cheerios.config->no_crlf)
write(cheerios.ser_fd, "\n", 1);
else
write(cheerios.ser_fd, "\r\n", 2);
write(cheerios.ser_fd, buf, len);
pthread_mutex_unlock(&cheerios.lock);
return 0;
}

View file

@ -62,9 +62,8 @@ int cheerios_gofwd(int lines);
/* stop the thread and release memory */
int cheerios_stop();
/* send over a line of user input to the output
* do not terminate with a newline! */
int cheerios_input(const char *line);
/* send over a line of user input to the output */
int cheerios_input(const char *buf, size_t len);
/* output a line only to the terminal for info/prompt purposes
* do not terminate with a newline! */

View file

@ -378,6 +378,7 @@ ingest_thread(void *arg)
" i: view info/stats\r\n"
" x: start XModem upload with 128B payloads\r\n"
" X: start XModem upload with 1024B payloads\r\n"
" H: enter/exit hex buffer mode\r\n"
" h: view this help\r\n"
" q: quit Bytenuts\r\n",
ingest.config->escape
@ -429,9 +430,21 @@ mode_normal(int ch)
return 0;
switch (ch) {
case '\n': /* send inputs */
if (cheerios_input(ingest.inbuf)) {
break;
case '\n': { /* send inputs */
size_t inlen = strlen(ingest.inbuf);
const char *ending;
if (ingest.config->no_crlf)
ending = "\n";
else
ending = "\r\n";
cheerios_input(ingest.inbuf, inlen);
cheerios_input(ending, strlen(ending));
if (ingest.config->echo) {
cheerios_insert(">> ", 3);
cheerios_insert(ingest.inbuf, inlen);
cheerios_insert("\r\n", 2);
}
/* store in history */
@ -453,6 +466,7 @@ mode_normal(int ch)
ingest_refresh();
break;
}
case KEY_UP: /* load in history */
if (ingest.history_pos == 0) { /* top of history */
break;
@ -617,17 +631,46 @@ mode_hex(int ch)
case '\n': { /* send inputs */
char hexbuf[sizeof(ingest.inbuf)/2];
size_t inbuflen = strlen(ingest.inbuf);
size_t hexlen = 0;
/* assume leading 0 on odd length buffers */
if (inbuflen % 2 != 0) {
memmove(&ingest.inbuf[1], ingest.inbuf, inbuflen);
ingest.inbuf[0] = '0';
inbuflen++;
}
for (int i = 0; i < inbuflen; i += 2) {
char tmp = ingest.inbuf[i+2];
char *inval;
long ch;
ingest.inbuf[i+2] = '\0';
hexbuf[i/2] = strtol(&ingest.inbuf[i], NULL, 16);
// cheerios_print("HEX 0x%02X (%c)\r\n", hexbuf[i/2], hexbuf[i/2]);
ch = strtol(&ingest.inbuf[i], &inval, 16);
ingest.inbuf[i+2] = tmp;
/* strtol could not parse a character */
if (inval != &ingest.inbuf[i+2])
break;
hexbuf[i/2] = ch;
hexlen++;
}
if (cheerios_insert(hexbuf, inbuflen/2)) {
break;
cheerios_input(hexbuf, hexlen);
if (ingest.config->echo) {
cheerios_insert(">> (hex)\r\n", 10);
for (int i = 0; i < hexlen; i++) {
if (
i > 0 &&
i != hexlen-1 &&
i % 16 == 0
) {
cheerios_insert("\r\n", 2);
}
cheerios_insert(&ingest.inbuf[i*2], 2);
cheerios_insert(" ", 1);
}
cheerios_insert("\r\n", 2);
}
/* store in history */