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);
|
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);
|
||||||
|
|
||||||
|
|
49
src/kiss.c
49
src/kiss.c
|
@ -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 ((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) {
|
if ((decoded = tnc_decode(tnc, tnc->frame, &framelen, port)) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have decoded frame data, then flush the buffer up to the point of
|
* If we can no longer buffer nor decode any data, then drop the whole
|
||||||
* the next frame start, if present.
|
* frame.
|
||||||
*/
|
*/
|
||||||
if (decoded) {
|
if (decoded == 0 && buffered == 0) {
|
||||||
tnc_flush(tnc, decoded);
|
tnc_drop(tnc);
|
||||||
}
|
}
|
||||||
|
} while (decoded == 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush the buffer up to the point of the next frame start.
|
||||||
|
*/
|
||||||
|
tnc_flush(tnc, decoded);
|
||||||
|
|
||||||
*frame = tnc->frame;
|
*frame = tnc->frame;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue