Go to hell and back to get valid frames off the wire, and keep track of error counts
This commit is contained in:
parent
6a427c4097
commit
9af63066b6
2 changed files with 43 additions and 20 deletions
|
@ -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);
|
||||
|
||||
int patty_kiss_tnc_errors(patty_kiss_tnc *tnc);
|
||||
|
||||
ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
|
||||
void **frame, int *port);
|
||||
|
||||
|
|
61
src/kiss.c
61
src/kiss.c
|
@ -17,6 +17,7 @@ enum kiss_flags {
|
|||
|
||||
struct _patty_kiss_tnc {
|
||||
int fd;
|
||||
int errors;
|
||||
void * frame;
|
||||
void * buf;
|
||||
size_t bufsz;
|
||||
|
@ -42,6 +43,7 @@ patty_kiss_tnc *patty_kiss_tnc_open(const char *device, size_t bufsz) {
|
|||
goto error_open;
|
||||
}
|
||||
|
||||
tnc->errors = 0;
|
||||
tnc->bufsz = bufsz;
|
||||
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
|
||||
* 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
|
||||
* packet originated.
|
||||
* frame originated.
|
||||
*/
|
||||
if (i == 1 && (c & 0x0f) == 0) {
|
||||
*port = (c & 0xf0) >> 4;
|
||||
|
@ -180,6 +182,18 @@ error_io:
|
|||
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) {
|
||||
/*
|
||||
* 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 decoded;
|
||||
ssize_t buffered, decoded;
|
||||
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.
|
||||
*/
|
||||
memset(tnc->frame, '\0', tnc->bufsz);
|
||||
|
||||
/*
|
||||
* Try to decode the TNC buffer into the packet.
|
||||
*/
|
||||
if ((decoded = tnc_decode(tnc, tnc->frame, &framelen, port)) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
do {
|
||||
/*
|
||||
* Fill the buffer with something to parse.
|
||||
*/
|
||||
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
|
||||
* the next frame start, if present.
|
||||
* Flush the buffer up to the point of the next frame start.
|
||||
*/
|
||||
if (decoded) {
|
||||
tnc_flush(tnc, decoded);
|
||||
}
|
||||
tnc_flush(tnc, decoded);
|
||||
|
||||
*frame = tnc->frame;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue