From 0835e1670600776801dc276bc086b585433cf2b4 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Sun, 25 Apr 2021 22:58:55 -0700 Subject: [PATCH] add ability to send arbitrary packets that are hex encoded.. --- main.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/main.c b/main.c index 257c41e..de948a8 100644 --- a/main.c +++ b/main.c @@ -2,11 +2,27 @@ #include +#include + #include #include #include #include +char * +findeol(char *pos, size_t len) +{ + + while (len) { + if (*pos == '\r' || *pos == '\n') + return pos; + pos++; + len--; + } + + return NULL; +} + void hexdump(uint8_t *ptr, size_t len) { @@ -60,6 +76,86 @@ RadioEvents_t revents = { .RxError = rxerr, }; +static uint8_t +hexchartonib(char s) +{ + + switch (s) { + case '0'...'9': + return s - '0'; + case 'a'...'f': + return s - 'a' + 10; + case 'A'...'F': + return s - 'A' + 10; + default: + return -1; + } +} + +static bool +hexdecode(char *buf, size_t len, uint8_t *out) +{ + uint8_t topchr, botchr; + + if (len % 2) + return -1; + + /* NB: only needed to silence a bad gcc warning */ + topchr = -1; + + while (len) { + if (len % 2) { + /* bottom nibble */ + botchr = hexchartonib(*buf); + if (topchr == -1 || botchr == -1) + return false; + + *out = topchr << 4 | botchr; + out++; + } else { + /* top nibble */ + topchr = hexchartonib(*buf); + } + len--; + buf++; + } + + return true; +} + +static const char pktstart[] = "pkt:"; +static const size_t pktstartlen = sizeof pktstart - 1; +static uint8_t pktbuf[128]; + +static void +process_line(char *start, char *end) +{ + size_t len; + + /* trim off leading CR/NL */ + while (start < end && (*start == '\r' || *start == '\n')) + start++; + + len = end - start; + + if (len >= pktstartlen && memcmp(start, pktstart, sizeof pktstart - 1) == 0) { + start += pktstartlen; + len -= pktstartlen; + + if (len % 2) { + usb_printf("invalid pkt len\r\n"); + return; + } + if (!hexdecode(start, len, pktbuf)) { + usb_printf("invalid pkt\r\n"); + return; + } + Radio.Send(pktbuf, len / 2); + return; + } + usb_printf("line: %.*s", end - start, start); +} + int main(void) { @@ -148,10 +244,70 @@ main(void) usb_printf("rx(0)...\r\n"); Radio.Rx(0); + char inpbuf[1024]; + char *lastcheck; + char *endchr; + int inpbufpos = 0; + int cpylen; + loop: BoardLowPowerHandler(); if (Radio.IrqProcess != NULL) Radio.IrqProcess(); + /* while we have data */ + while (CDC_RX_LEN) { + /* store last position */ + lastcheck = &inpbuf[inpbufpos]; + + /* calculate how much space left */ + cpylen = MIN(sizeof inpbuf - inpbufpos, CDC_RX_LEN); + + /* copy into buffer */ + memcpy(&inpbuf[inpbufpos], CDC_RX_BUFFER, cpylen); + + /* and point to end of buffer */ + inpbufpos += cpylen; + + do { + /* find first end of line characters */ + endchr = findeol(lastcheck, cpylen); + + if (endchr != NULL) { + /* if so, process it */ + process_line(inpbuf, endchr); + + /* skip end of line char */ + endchr++; + + /* move remaining buffer to the beginning */ + memmove(inpbuf, endchr, inpbufpos - (endchr - inpbuf)); + + /* and store new length */ + inpbufpos = inpbufpos - (endchr - inpbuf); + + /* mark begining of stream as last checked */ + lastcheck = inpbuf; + + /* and try to process another line */ + continue; + } else if (inpbufpos == sizeof inpbuf) { + /* we overflowed the buffer */ + /* XXX - best way is to throw away this line */ + inpbufpos = 0; + } + } while (0); + + /* if we copied all the data */ + if (cpylen == CDC_RX_LEN) { + /* declare that we are ready to receive more data */ + CDC_RX_LEN = 0; + USBD_CDC_ReceivePacket(&hUsbDeviceFS); + } else { + /* if not, move the remaining to the begining and try again */ + memmove(CDC_RX_BUFFER, &CDC_RX_BUFFER[cpylen], CDC_RX_LEN - cpylen); + CDC_RX_LEN -= cpylen; + } + } goto loop; }