Fix hex buffer mode and add it to the readme
This commit is contained in:
parent
41025fd319
commit
d7b0c80f56
4 changed files with 65 additions and 28 deletions
12
README.md
12
README.md
|
|
@ -110,14 +110,24 @@ The help prompt lists the available commands.
|
||||||
Commands (lead with ctrl-b):
|
Commands (lead with ctrl-b):
|
||||||
c: print available quick commands
|
c: print available quick commands
|
||||||
0-9: load the given quick command (0 is 10)
|
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
|
i: view info/stats
|
||||||
x: start XModem upload with 128B payloads
|
x: start XModem upload with 128B payloads
|
||||||
X: start XModem upload with 1024B payloads
|
X: start XModem upload with 1024B payloads
|
||||||
|
H: enter/exit hex buffer mode
|
||||||
h: view this help
|
h: view this help
|
||||||
q: quit Bytenuts
|
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
|
## 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.
|
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.
|
||||||
|
|
|
||||||
|
|
@ -143,25 +143,10 @@ cheerios_stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
pthread_mutex_lock(&cheerios.lock);
|
||||||
|
write(cheerios.ser_fd, buf, len);
|
||||||
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);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&cheerios.lock);
|
pthread_mutex_unlock(&cheerios.lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,8 @@ int cheerios_gofwd(int lines);
|
||||||
/* stop the thread and release memory */
|
/* stop the thread and release memory */
|
||||||
int cheerios_stop();
|
int cheerios_stop();
|
||||||
|
|
||||||
/* send over a line of user input to the output
|
/* send over a line of user input to the output */
|
||||||
* do not terminate with a newline! */
|
int cheerios_input(const char *buf, size_t len);
|
||||||
int cheerios_input(const char *line);
|
|
||||||
|
|
||||||
/* output a line only to the terminal for info/prompt purposes
|
/* output a line only to the terminal for info/prompt purposes
|
||||||
* do not terminate with a newline! */
|
* do not terminate with a newline! */
|
||||||
|
|
|
||||||
57
src/ingest.c
57
src/ingest.c
|
|
@ -378,6 +378,7 @@ ingest_thread(void *arg)
|
||||||
" i: view info/stats\r\n"
|
" i: view info/stats\r\n"
|
||||||
" x: start XModem upload with 128B payloads\r\n"
|
" x: start XModem upload with 128B payloads\r\n"
|
||||||
" X: start XModem upload with 1024B 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"
|
" h: view this help\r\n"
|
||||||
" q: quit Bytenuts\r\n",
|
" q: quit Bytenuts\r\n",
|
||||||
ingest.config->escape
|
ingest.config->escape
|
||||||
|
|
@ -429,9 +430,21 @@ mode_normal(int ch)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '\n': /* send inputs */
|
case '\n': { /* send inputs */
|
||||||
if (cheerios_input(ingest.inbuf)) {
|
size_t inlen = strlen(ingest.inbuf);
|
||||||
break;
|
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 */
|
/* store in history */
|
||||||
|
|
@ -453,6 +466,7 @@ mode_normal(int ch)
|
||||||
ingest_refresh();
|
ingest_refresh();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case KEY_UP: /* load in history */
|
case KEY_UP: /* load in history */
|
||||||
if (ingest.history_pos == 0) { /* top of history */
|
if (ingest.history_pos == 0) { /* top of history */
|
||||||
break;
|
break;
|
||||||
|
|
@ -617,17 +631,46 @@ mode_hex(int ch)
|
||||||
case '\n': { /* send inputs */
|
case '\n': { /* send inputs */
|
||||||
char hexbuf[sizeof(ingest.inbuf)/2];
|
char hexbuf[sizeof(ingest.inbuf)/2];
|
||||||
size_t inbuflen = strlen(ingest.inbuf);
|
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) {
|
for (int i = 0; i < inbuflen; i += 2) {
|
||||||
char tmp = ingest.inbuf[i+2];
|
char tmp = ingest.inbuf[i+2];
|
||||||
|
char *inval;
|
||||||
|
long ch;
|
||||||
|
|
||||||
ingest.inbuf[i+2] = '\0';
|
ingest.inbuf[i+2] = '\0';
|
||||||
hexbuf[i/2] = strtol(&ingest.inbuf[i], NULL, 16);
|
ch = strtol(&ingest.inbuf[i], &inval, 16);
|
||||||
// cheerios_print("HEX 0x%02X (%c)\r\n", hexbuf[i/2], hexbuf[i/2]);
|
|
||||||
ingest.inbuf[i+2] = tmp;
|
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)) {
|
cheerios_input(hexbuf, hexlen);
|
||||||
break;
|
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 */
|
/* store in history */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue