patty/src/if.c

370 lines
8.1 KiB
C
Raw Normal View History

2015-07-24 21:49:57 -05:00
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
2015-07-24 21:49:57 -05:00
#include <errno.h>
#include <patty/ax25.h>
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
2020-09-13 16:56:10 -04:00
#include <patty/kiss.h>
2015-07-24 21:49:57 -05:00
patty_ax25_if *patty_ax25_if_new(patty_ax25_addr *addr,
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
2020-09-13 16:56:10 -04:00
patty_ax25_if_driver *driver,
patty_ax25_if_info *info) {
patty_ax25_if *iface;
2015-07-24 21:49:57 -05:00
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
2020-09-13 16:56:10 -04:00
if (addr->callsign[0] == '\0') {
errno = EINVAL;
2015-07-24 21:49:57 -05:00
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
2020-09-13 16:56:10 -04:00
goto error_invalid_address;
}
2015-07-24 21:49:57 -05:00
if ((iface = malloc(sizeof(*iface))) == NULL) {
goto error_malloc_iface;
}
memset(iface, '\0', sizeof(*iface));
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
2020-09-13 16:56:10 -04:00
if ((iface->phy = driver->create(info)) == NULL) {
goto error_phy_create;
}
Implement bin/pattyd.c Changes: * Implement src/conf.c, patty_conf_read(), to read a configuration file to support a OpenBSD-style configuration file format * Implement bin/pattyd.c to use patty_conf_read() to read a configuration file and apply its settings to a patty_daemon object as it is read; also implement a --standalone|-s flag to allow the user to start a patty server without having to write a configuration file * Refactor patty_daemon_if_add() to accept a patty_ax25_if object; this is necessary as bin/pattyd.c needs to be able to validate the addresses given in a configuration file 'if' statement * Refactor patty_ax25_server_new() to no longer accept a client socket path; instead, patty_ax25_server_start() now accepts the client socket path * Remove the client socket 'path' member from patty_ax25_server in src/server.c * Refactor patty_kiss_tnc_new() to accept only one argument, a patty_kiss_tnc_info object containing flags and settings needed to open a device, use an existing file descriptor, or change termios settings as appropriate * Remove patty_kiss_tnc_new_fd(), as its functionality now exists in patty_kiss_tnc_new() itself * Add a 'flags' field to patty_kiss_tnc_info; use this bit field to determine whether a path or file descriptor is provided by the caller * Make patty_ax25_if_new() accept an interface name argument, as names are explicitly required when declaring new interfaces in configuration files * Make patty_kiss_tnc_new() able to accept /dev/ptmx as a device name, regardless of whether this character device exists on a given platform; when provided, a pseudo TTY pair is allocated with openpty() * Refactor examples/ax25dump.c to use the new patty_kiss_tnc_new() calling convention * Refactor examples/decode.c to use the new patty_kiss_tnc_new() calling convention * Remove examples/daemon.c in favor of bin/pattyd.c * Rename examples/patty.conf to examples/pattyd.conf; modify to provide values which would actually function
2020-09-01 16:38:02 -05:00
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
2020-09-13 16:56:10 -04:00
iface->driver = driver;
/*
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
2020-09-13 16:56:10 -04:00
* TODO: Eventually inherit the half/full-duplex flag from the PHY this
* interface is bound to
*/
iface->flags_classes = PATTY_AX25_IF_DEFAULT_CLASSES;
if ((iface->rx_buf = malloc(PATTY_AX25_IF_DEFAULT_MRU)) == NULL) {
goto error_malloc_rx_buf;
} else {
iface->mru = PATTY_AX25_IF_DEFAULT_MRU;
}
if ((iface->tx_buf = malloc(PATTY_AX25_IF_DEFAULT_MTU)) == NULL) {
goto error_malloc_tx_buf;
} else {
iface->mtu = PATTY_AX25_IF_DEFAULT_MTU;
}
if ((iface->aliases = patty_list_new()) == NULL) {
goto error_list_new_aliases;
}
if ((iface->promisc_fds = patty_dict_new()) == NULL) {
goto error_dict_new_promisc_fds;
}
memcpy(&iface->addr, addr, sizeof(iface->addr));
return iface;
2015-07-24 21:49:57 -05:00
error_dict_new_promisc_fds:
patty_list_destroy(iface->aliases);
2015-07-24 21:49:57 -05:00
error_list_new_aliases:
free(iface->tx_buf);
error_malloc_tx_buf:
free(iface->rx_buf);
error_malloc_rx_buf:
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
2020-09-13 16:56:10 -04:00
driver->destroy(iface->phy);
error_phy_create:
free(iface);
2015-07-24 21:49:57 -05:00
error_malloc_iface:
error_invalid_address:
2015-07-24 21:49:57 -05:00
return NULL;
}
void patty_ax25_if_destroy(patty_ax25_if *iface) {
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
2020-09-13 16:56:10 -04:00
if (iface->driver->destroy) {
iface->driver->destroy(iface->phy);
2015-07-24 21:49:57 -05:00
}
patty_dict_destroy(iface->promisc_fds);
patty_list_destroy(iface->aliases);
free(iface->tx_buf);
free(iface->rx_buf);
free(iface);
2015-07-24 21:49:57 -05:00
}
2015-07-25 00:26:23 -05:00
2020-06-25 20:37:12 -04:00
int patty_ax25_if_addr_each(patty_ax25_if *iface,
int (*callback)(patty_ax25_addr *, void *),
void *ctx) {
patty_list_item *item = iface->aliases->first;
2015-07-25 00:26:23 -05:00
if (callback(&iface->addr, ctx) < 0) {
goto error_callback;
}
while (item) {
patty_ax25_addr *addr = item->value;
2015-07-25 00:26:23 -05:00
if (callback(addr, ctx) < 0) {
2015-07-25 00:26:23 -05:00
goto error_callback;
}
item = item->next;
}
2015-07-25 00:26:23 -05:00
return 0;
error_callback:
return -1;
}
2020-06-07 02:46:12 -04:00
static patty_ax25_addr *find_addr(patty_ax25_if *iface,
patty_ax25_addr *addr) {
patty_list_item *item = iface->aliases->first;
2015-07-25 00:26:23 -05:00
while (item) {
patty_ax25_addr *cur = item->value;
2015-07-25 00:26:23 -05:00
if (memcmp(&addr->callsign,
&cur->callsign,
sizeof(addr->callsign)) == 0) {
return addr;
2020-06-07 02:46:12 -04:00
}
item = item->next;
2015-07-25 00:26:23 -05:00
}
return NULL;
}
2020-06-25 20:37:12 -04:00
int patty_ax25_if_addr_add(patty_ax25_if *iface,
patty_ax25_addr *addr) {
patty_ax25_addr *alias;
2015-07-25 00:26:23 -05:00
if (find_addr(iface, addr) != NULL) {
errno = EADDRINUSE;
2015-07-25 00:26:23 -05:00
goto error_exists;
}
if ((alias = malloc(sizeof(*alias))) == NULL) {
goto error_malloc_alias;
2015-07-25 00:26:23 -05:00
}
memcpy(&alias->callsign, &addr->callsign, sizeof(alias->callsign));
2015-07-25 00:26:23 -05:00
addr->ssid = 0;
if ((patty_list_append(iface->aliases, alias)) == NULL) {
2015-07-25 00:26:23 -05:00
goto error_list_append;
}
return 0;
error_list_append:
free(alias);
2015-07-25 00:26:23 -05:00
error_malloc_alias:
2015-07-25 00:26:23 -05:00
error_exists:
return -1;
}
int patty_ax25_if_addr_delete(patty_ax25_if *iface, patty_ax25_addr *addr) {
patty_list_item *item = iface->aliases->first;
2015-07-25 00:26:23 -05:00
int i = 0;
while (item) {
patty_ax25_addr *alias = item->value;
2015-07-25 00:26:23 -05:00
if (memcmp(&addr->callsign,
&alias->callsign,
sizeof(addr->callsign)) == 0) {
if (patty_list_splice(iface->aliases, i) == NULL) {
2015-07-25 00:26:23 -05:00
goto error_list_splice;
}
}
item = item->next;
i++;
}
return 0;
error_list_splice:
return -1;
}
int patty_ax25_if_addr_match(patty_ax25_if *iface,
patty_ax25_addr *addr) {
patty_list_item *item;
if (memcmp(&iface->addr.callsign,
&addr->callsign,
sizeof(addr->callsign)) == 0) {
return 1;
}
item = iface->aliases->first;
while (item) {
patty_ax25_addr *alias = item->value;
if (memcmp(&alias->callsign,
&addr->callsign,
sizeof(addr->callsign)) == 0) {
return 1;
}
item = item->next;
}
return 0;
}
int patty_ax25_if_promisc_add(patty_ax25_if *iface,
int fd) {
if (patty_dict_get(iface->promisc_fds, (uint32_t)fd)) {
errno = EEXIST;
goto error_exists;
}
if (patty_dict_set(iface->promisc_fds,
(uint32_t)fd,
NULL) == NULL) {
errno = ENOMEM;
goto error_dict_set;
}
return 0;
error_dict_set:
error_exists:
return -1;
}
int patty_ax25_if_promisc_delete(patty_ax25_if *iface,
int fd) {
return patty_dict_delete(iface->promisc_fds, (uint32_t)fd);
}
struct promisc_frame {
const void *buf;
size_t len;
patty_ax25_if *iface;
};
static int handle_promisc_frame(uint32_t key,
void *value,
void *ctx) {
int fd = (int)key;
struct promisc_frame *frame = ctx;
return patty_kiss_frame_send(fd, frame->buf, frame->len, 0);
}
void patty_ax25_if_drop(patty_ax25_if *iface) {
iface->driver->stats(iface->phy)->dropped++;
}
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
2020-09-13 16:56:10 -04:00
int patty_ax25_if_fd(patty_ax25_if *iface) {
return iface->driver->fd(iface->phy);
}
ssize_t patty_ax25_if_fill(patty_ax25_if *iface) {
return iface->driver->fill(iface->phy);
}
ssize_t patty_ax25_if_drain(patty_ax25_if *iface, void *buf, size_t len) {
return iface->driver->drain(iface->phy, buf, len);
}
int patty_ax25_if_ready(patty_ax25_if *iface) {
return iface->driver->ready(iface->phy);
}
ssize_t patty_ax25_if_flush(patty_ax25_if *iface) {
ssize_t len = iface->driver->flush(iface->phy);
2020-06-29 00:29:05 -04:00
if (len > 0) {
struct promisc_frame frame = {
.buf = iface->rx_buf,
.len = len,
.iface = iface
};
patty_ax25_if_stats *stats = iface->driver->stats(iface->phy);
stats->rx_frames++;
stats->rx_bytes += len;
if (patty_dict_each(iface->promisc_fds,
handle_promisc_frame,
&frame) < 0) {
goto error_handle_promisc_frame;
}
}
return len;
error_handle_promisc_frame:
return -1;
}
ssize_t patty_ax25_if_recv(patty_ax25_if *iface, void *buf, size_t len) {
while (!patty_ax25_if_ready(iface)) {
ssize_t drained;
if ((drained = patty_ax25_if_drain(iface, buf, len)) < 0) {
goto error_drain;
} else if (drained == 0) {
ssize_t filled;
if ((filled = patty_ax25_if_fill(iface)) < 0) {
goto error_fill;
} else if (filled == 0) {
return 0;
}
}
}
return patty_ax25_if_flush(iface);
error_drain:
error_fill:
return -1;
}
2020-09-22 16:35:35 -04:00
ssize_t patty_ax25_if_send(patty_ax25_if *iface, const void *buf, size_t len) {
struct promisc_frame frame;
patty_ax25_if_stats *stats;
ssize_t wrlen;
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
2020-09-13 16:56:10 -04:00
if ((wrlen = iface->driver->send(iface->phy, buf, len)) < 0) {
goto error_driver_send;
}
stats = iface->driver->stats(iface->phy);
stats->tx_frames++;
stats->tx_bytes += wrlen;
2020-06-29 00:29:05 -04:00
frame.buf = buf;
frame.len = wrlen;
frame.iface = iface;
if (patty_dict_each(iface->promisc_fds,
handle_promisc_frame,
&frame) < 0) {
goto error_handle_promisc_frame;
}
return wrlen;
error_handle_promisc_frame:
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
2020-09-13 16:56:10 -04:00
error_driver_send:
return -1;
}