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
|
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;
|
typedef struct _patty_kiss_tnc patty_kiss_tnc;
|
||||||
|
|
||||||
patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd);
|
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;
|
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 *patty_kiss_tnc_new_fd(int fd) {
|
||||||
patty_kiss_tnc *tnc;
|
patty_kiss_tnc *tnc;
|
||||||
|
|
||||||
|
@ -304,84 +386,9 @@ error_io:
|
||||||
return -1;
|
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,
|
ssize_t patty_kiss_tnc_send(patty_kiss_tnc *tnc,
|
||||||
const void *buf,
|
const void *buf,
|
||||||
size_t len,
|
size_t len,
|
||||||
int port) {
|
int port) {
|
||||||
size_t i, start = 0, end = 0;
|
return patty_kiss_frame_send(tnc->fd, buf, len, port);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue