|
|
@@ -2,11 +2,27 @@ |
|
|
|
|
|
|
|
#include <strobe_rng_init.h> |
|
|
|
|
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
#include <board.h> |
|
|
|
#include <misc.h> |
|
|
|
#include <radio.h> |
|
|
|
#include <delay.h> |
|
|
|
|
|
|
|
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; |
|
|
|
} |