patty/src/kiss.c
XANTRONIX Development cb33d799ff Implement patty_ax25_if_driver
Changes:

    * Implement patty_ax25_if_driver type, providing a vtable with
      pointers to methods implementing an AX.25 interface PHY

    * Implement patty_ax25_if_name() to return a pointer to the name
      string of an AX.25 interface

    * Decouple patty_kiss_tnc from src/if.c using patty_ax25_if_driver

    * Remove port input/output arguments from patty_kiss_tnc_send()
      and patty_kiss_tnc_recv(), respectively; use 0 as the default,
      but keep the port argument in patty_kiss_frame_send()

    * Implement patty_ax25_if_fd() to return file descriptor backing a
      PHY; use this rather than patty_kiss_tnc_fd() in src/server.c to
      further decouple interfaces from their implementation

    * Remove 'enum patty_ax25_if_type' type; refactor constructor
      patty_ax25_if_new() to no longer take this as an argument, but
      rather a patty_ax25_if_driver to use to instantiate the PHY
      with the information pointer passed

    * Break out patty_kiss_tnc code from src/kiss.c into src/tnc.c,
      leaving only patty_kiss_frame_send() in the original; this is
      needed to prevent a cyclic dependency within patty_ax25_sock and
      other areas

    * Rename patty_bin_if_config() to patty_bin_if_create(); a separate
      patty_bin_if_config() will likely be created later as necessary
      to change an existing interface

    * Split PHY-specific interface configuration code into separate
      delegates in bin/if.c

    * Implement usage of patty_error to better capture internal error
      states not currently representable with semantic error numbers
      while configuring and instantiating PHYs

    * Pass patty_error object to patty_bin_kiss_config() to receive
      detailed error information
2024-03-01 00:20:47 -05:00

94 lines
2.1 KiB
C

#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <patty/kiss.h>
#include "config.h"
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;
}
return len;
error_io:
return -1;
}