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:
parent
f96017bc10
commit
c417461a0b
2 changed files with 88 additions and 76 deletions
|
@ -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);
|
||||
|
|
159
src/kiss.c
159
src/kiss.c
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue