Implement patty_kiss_frame_send()

Implement patty_kiss_frame_send() as a means of sending a KISS frame
without requiring a patty_kiss_tnc object
This commit is contained in:
XANTRONIX Development 2020-08-05 00:48:58 -04:00 committed by XANTRONIX Industrial
parent f96017bc10
commit c417461a0b
2 changed files with 88 additions and 76 deletions

View file

@ -27,6 +27,11 @@ enum patty_kiss_command {
PATTY_KISS_RETURN = 0xff
};
ssize_t patty_kiss_frame_send(int fd,
const void *buf,
size_t len,
int port);
typedef struct _patty_kiss_tnc patty_kiss_tnc;
patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd);

View file

@ -42,6 +42,88 @@ struct _patty_kiss_tnc {
ssize_t readlen;
};
static inline ssize_t write_byte(int fd, uint8_t c) {
return write(fd, &c, sizeof(c));
}
static inline ssize_t write_start(int fd,
enum patty_kiss_command command,
int port) {
uint8_t start[2] = {
PATTY_KISS_FEND,
((port & 0x0f) << 4) | (command & 0x0f)
};
return write(fd, start, sizeof(start));
}
static uint8_t escape_fend[2] = { PATTY_KISS_FESC, PATTY_KISS_TFEND };
static uint8_t escape_fesc[2] = { PATTY_KISS_FESC, PATTY_KISS_TFESC };
ssize_t patty_kiss_frame_send(int fd,
const void *buf,
size_t len,
int port) {
size_t i, start = 0, end = 0;
if (write_start(fd, PATTY_KISS_DATA, port) < 0) {
goto error_io;
}
for (i=0; i<len; i++) {
uint8_t c = ((uint8_t *)buf)[i];
uint8_t *escape = NULL;
switch (c) {
case PATTY_KISS_FEND:
escape = escape_fend;
break;
case PATTY_KISS_FESC:
escape = escape_fesc;
break;
default:
end = i + 1;
break;
}
if (escape) {
if (write(fd, ((uint8_t *)buf) + start, end - start) < 0) {
goto error_io;
}
if (write(fd, escape, 2) < 0) {
goto error_io;
}
escape = NULL;
start = i + 1;
end = start;
}
}
if (end - start) {
if (write(fd, ((uint8_t *)buf) + start, end - start) < 0) {
goto error_io;
}
}
if (write_byte(fd, PATTY_KISS_FEND) < 0) {
goto error_io;
}
if (tcdrain(fd) < 0) {
goto error_io;
}
return len;
error_io:
return -1;
}
patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd) {
patty_kiss_tnc *tnc;
@ -304,84 +386,9 @@ error_io:
return -1;
}
static inline ssize_t write_byte(int fd, uint8_t c) {
return write(fd, &c, sizeof(c));
}
static inline ssize_t write_start(int fd,
enum patty_kiss_command command,
int port) {
uint8_t start[2] = {
PATTY_KISS_FEND,
((port & 0x0f) << 4) | (command & 0x0f)
};
return write(fd, start, sizeof(start));
}
static uint8_t escape_fend[2] = { PATTY_KISS_FESC, PATTY_KISS_TFEND };
static uint8_t escape_fesc[2] = { PATTY_KISS_FESC, PATTY_KISS_TFESC };
ssize_t patty_kiss_tnc_send(patty_kiss_tnc *tnc,
const void *buf,
size_t len,
int port) {
size_t i, start = 0, end = 0;
if (write_start(tnc->fd, PATTY_KISS_DATA, port) < 0) {
goto error_io;
}
for (i=0; i<len; i++) {
uint8_t c = ((uint8_t *)buf)[i];
uint8_t *escape = NULL;
switch (c) {
case PATTY_KISS_FEND:
escape = escape_fend;
break;
case PATTY_KISS_FESC:
escape = escape_fesc;
break;
default:
end = i + 1;
break;
}
if (escape) {
if (write(tnc->fd, ((uint8_t *)buf) + start, end - start) < 0) {
goto error_io;
}
if (write(tnc->fd, escape, 2) < 0) {
goto error_io;
}
escape = NULL;
start = i + 1;
end = start;
}
}
if (end - start) {
if (write(tnc->fd, ((uint8_t *)buf) + start, end - start) < 0) {
goto error_io;
}
}
if (write_byte(tnc->fd, PATTY_KISS_FEND) < 0) {
goto error_io;
}
if (tcdrain(tnc->fd) < 0) {
goto error_io;
}
return len;
error_io:
return -1;
return patty_kiss_frame_send(tnc->fd, buf, len, port);
}