Refactor patty_kiss_tnc_recv()
Refactor patty_kiss_tnc_recv() to always read a fixed number of bytes into a circular buffer Other changes: * Avoid needing memmove() per packet processed * Allow processing packets larger than the internal read buffer
This commit is contained in:
parent
153dc17c7b
commit
750ab452d2
1 changed files with 62 additions and 44 deletions
106
src/kiss.c
106
src/kiss.c
|
@ -24,8 +24,13 @@ struct _patty_kiss_tnc {
|
|||
*frame;
|
||||
|
||||
size_t bufsz,
|
||||
buflen,
|
||||
offset,
|
||||
dropped;
|
||||
|
||||
ssize_t readlen,
|
||||
left;
|
||||
|
||||
int eof;
|
||||
};
|
||||
|
||||
patty_kiss_tnc *patty_kiss_tnc_open_fd(int fd) {
|
||||
|
@ -41,8 +46,11 @@ patty_kiss_tnc *patty_kiss_tnc_open_fd(int fd) {
|
|||
|
||||
tnc->fd = fd;
|
||||
tnc->bufsz = PATTY_KISS_BUFSZ;
|
||||
tnc->buflen = 0;
|
||||
tnc->offset = 0;
|
||||
tnc->dropped = 0;
|
||||
tnc->readlen = 0;
|
||||
tnc->left = 0;
|
||||
tnc->eof = 0;
|
||||
|
||||
return tnc;
|
||||
|
||||
|
@ -84,36 +92,11 @@ void patty_kiss_tnc_close(patty_kiss_tnc *tnc) {
|
|||
free(tnc);
|
||||
}
|
||||
|
||||
static ssize_t tnc_buffer(patty_kiss_tnc *tnc) {
|
||||
ssize_t readlen;
|
||||
|
||||
if (tnc->buflen == tnc->bufsz) {
|
||||
goto full;
|
||||
}
|
||||
|
||||
if ((readlen = read(tnc->fd, tnc->buf, tnc->bufsz - tnc->buflen)) < 0) {
|
||||
goto error_read;
|
||||
}
|
||||
|
||||
tnc->buflen += readlen;
|
||||
|
||||
return readlen;
|
||||
|
||||
full:
|
||||
return 0;
|
||||
|
||||
error_read:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void tnc_flush(patty_kiss_tnc *tnc, size_t len) {
|
||||
memmove(tnc->buf, ((uint8_t *)tnc->buf) + len, tnc->buflen - len);
|
||||
|
||||
tnc->buflen -= len;
|
||||
}
|
||||
|
||||
static void tnc_drop(patty_kiss_tnc *tnc) {
|
||||
tnc->buflen = 0;
|
||||
tnc->offset = 0;
|
||||
tnc->readlen = 0;
|
||||
tnc->left = 0;
|
||||
tnc->eof = 0;
|
||||
tnc->dropped++;
|
||||
}
|
||||
|
||||
|
@ -125,17 +108,46 @@ ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
|
|||
void *buf,
|
||||
size_t len,
|
||||
int *port) {
|
||||
size_t i = 0,
|
||||
b = 0;
|
||||
size_t r = 0, /* Number of bytes read */
|
||||
w = 0; /* Number of bytes written to buf */
|
||||
|
||||
enum kiss_flags flags = KISS_NONE;
|
||||
|
||||
if (tnc_buffer(tnc) < 0) {
|
||||
goto error_io;
|
||||
if (tnc->eof) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (i < tnc->buflen && b < len) {
|
||||
uint8_t c = ((uint8_t *)tnc->buf)[i++];
|
||||
while (1) {
|
||||
uint8_t c;
|
||||
|
||||
r++;
|
||||
|
||||
if (w == len) {
|
||||
tnc_drop(tnc);
|
||||
|
||||
flags &= ~KISS_FRAME;
|
||||
w = 0;
|
||||
}
|
||||
|
||||
if (tnc->offset == 0) {
|
||||
if ((tnc->readlen = read(tnc->fd, tnc->buf, tnc->bufsz)) < 0) {
|
||||
goto error_io;
|
||||
} else if (tnc->readlen == 0) {
|
||||
if (errno) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
tnc->left = tnc->readlen;
|
||||
}
|
||||
|
||||
c = ((uint8_t *)tnc->buf)[tnc->offset++];
|
||||
|
||||
if (tnc->offset == tnc->bufsz) {
|
||||
tnc->offset = 0;
|
||||
}
|
||||
|
||||
if (!(flags & KISS_FRAME)) {
|
||||
if (c == PATTY_KISS_FEND) {
|
||||
|
@ -149,7 +161,7 @@ ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
|
|||
}
|
||||
} else {
|
||||
if (c == PATTY_KISS_FEND) {
|
||||
if (b > 0) {
|
||||
if (w > 0) {
|
||||
flags &= ~KISS_FRAME;
|
||||
|
||||
goto done;
|
||||
|
@ -182,12 +194,12 @@ ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
|
|||
} else {
|
||||
switch (c) {
|
||||
case PATTY_KISS_TFEND:
|
||||
((uint8_t *)buf)[b++] = PATTY_KISS_FEND;
|
||||
((uint8_t *)buf)[w++] = PATTY_KISS_FEND;
|
||||
flags &= ~KISS_ESCAPE;
|
||||
continue;
|
||||
|
||||
case PATTY_KISS_TFESC:
|
||||
((uint8_t *)buf)[b++] = PATTY_KISS_FESC;
|
||||
((uint8_t *)buf)[w++] = PATTY_KISS_FESC;
|
||||
flags &= ~KISS_ESCAPE;
|
||||
continue;
|
||||
|
||||
|
@ -198,17 +210,23 @@ ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
|
|||
}
|
||||
}
|
||||
|
||||
((uint8_t *)buf)[b++] = c;
|
||||
((uint8_t *)buf)[w++] = c;
|
||||
}
|
||||
|
||||
done:
|
||||
if (flags & KISS_FRAME) {
|
||||
tnc_drop(tnc);
|
||||
} else {
|
||||
tnc_flush(tnc, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (ssize_t)b;
|
||||
tnc->left -= r;
|
||||
|
||||
if (tnc->readlen < tnc->bufsz && tnc->left == 0) {
|
||||
tnc->eof = 1;
|
||||
}
|
||||
|
||||
return (ssize_t)w;
|
||||
|
||||
error_io:
|
||||
return -1;
|
||||
|
|
Loading…
Add table
Reference in a new issue