Go to hell and back to get valid frames off the wire, and keep track of error counts

This commit is contained in:
XANTRONIX Development 2015-07-15 21:59:08 -05:00
parent 6a427c4097
commit 9af63066b6
2 changed files with 43 additions and 20 deletions

View file

@ -31,6 +31,8 @@ patty_kiss_tnc *patty_kiss_tnc_open(const char *device, size_t bufsize);
void patty_kiss_tnc_close(patty_kiss_tnc *tnc); void patty_kiss_tnc_close(patty_kiss_tnc *tnc);
int patty_kiss_tnc_errors(patty_kiss_tnc *tnc);
ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc, ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
void **frame, int *port); void **frame, int *port);

View file

@ -17,6 +17,7 @@ enum kiss_flags {
struct _patty_kiss_tnc { struct _patty_kiss_tnc {
int fd; int fd;
int errors;
void * frame; void * frame;
void * buf; void * buf;
size_t bufsz; size_t bufsz;
@ -42,6 +43,7 @@ patty_kiss_tnc *patty_kiss_tnc_open(const char *device, size_t bufsz) {
goto error_open; goto error_open;
} }
tnc->errors = 0;
tnc->bufsz = bufsz; tnc->bufsz = bufsz;
tnc->buflen = 0; tnc->buflen = 0;
@ -113,7 +115,7 @@ static ssize_t tnc_decode(patty_kiss_tnc *tnc, void *frame, size_t *len, int *po
* Not all KISS TNCs will emit a type byte at the start of a frame * Not all KISS TNCs will emit a type byte at the start of a frame
* to the host; if the low nybble has a value of zero, then presume * to the host; if the low nybble has a value of zero, then presume
* the high nybble to be the radio port number from which the * the high nybble to be the radio port number from which the
* packet originated. * frame originated.
*/ */
if (i == 1 && (c & 0x0f) == 0) { if (i == 1 && (c & 0x0f) == 0) {
*port = (c & 0xf0) >> 4; *port = (c & 0xf0) >> 4;
@ -180,6 +182,18 @@ error_io:
return -1; return -1;
} }
static void tnc_drop(patty_kiss_tnc *tnc) {
memset(tnc->buf, '\0', tnc->bufsz);
memset(tnc->frame, '\0', tnc->bufsz);
tnc->buflen = 0;
tnc->errors++;
}
int patty_kiss_tnc_errors(patty_kiss_tnc *tnc) {
return tnc->errors;
}
static void tnc_flush(patty_kiss_tnc *tnc, size_t len) { static void tnc_flush(patty_kiss_tnc *tnc, size_t len) {
/* /*
* Move everything from the buffer not processed up to this point, to the * Move everything from the buffer not processed up to this point, to the
@ -195,35 +209,42 @@ static void tnc_flush(patty_kiss_tnc *tnc, size_t len) {
} }
ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc, void **frame, int *port) { ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc, void **frame, int *port) {
ssize_t decoded; ssize_t buffered, decoded;
size_t framelen; size_t framelen;
/*
* Fill the buffer with something to parse!
*/
if (tnc_buffer(tnc) < 0) {
goto error_io;
}
/* /*
* Initialize the frame to be returned to the caller. * Initialize the frame to be returned to the caller.
*/ */
memset(tnc->frame, '\0', tnc->bufsz); memset(tnc->frame, '\0', tnc->bufsz);
/* do {
* Try to decode the TNC buffer into the packet. /*
*/ * Fill the buffer with something to parse.
if ((decoded = tnc_decode(tnc, tnc->frame, &framelen, port)) < 0) { */
goto error_io; if ((buffered = tnc_buffer(tnc)) < 0) {
} goto error_io;
}
/*
* Try to decode the TNC buffer into the frame.
*/
if ((decoded = tnc_decode(tnc, tnc->frame, &framelen, port)) < 0) {
goto error_io;
}
/*
* If we can no longer buffer nor decode any data, then drop the whole
* frame.
*/
if (decoded == 0 && buffered == 0) {
tnc_drop(tnc);
}
} while (decoded == 0);
/* /*
* If we have decoded frame data, then flush the buffer up to the point of * Flush the buffer up to the point of the next frame start.
* the next frame start, if present.
*/ */
if (decoded) { tnc_flush(tnc, decoded);
tnc_flush(tnc, decoded);
}
*frame = tnc->frame; *frame = tnc->frame;