Implement interface resetting

Changes:

    * Implement patty_ax25_if_reset() to allow pattyd(8) to attempt to
      reset the network interface in the event of an I/O error

    * Move existing link resetting code in src/aprs_is.c to
      patty_ax25_aprs_is_reset(); allow src/server.c to call this rather
      than within src/aprs_is.c itself

    * Implement patty_kiss_tnc_reset(); this simply sets errno to ENOSYS
      and returns -1 for the time being
This commit is contained in:
XANTRONIX Development 2020-10-30 22:44:57 -04:00 committed by XANTRONIX Industrial
parent 021eca720d
commit f80cc4055f
7 changed files with 54 additions and 11 deletions

View file

@ -37,6 +37,8 @@ int patty_ax25_aprs_is_fd(patty_ax25_aprs_is *aprs);
int patty_ax25_aprs_is_ready(patty_ax25_aprs_is *aprs, fd_set *fds); int patty_ax25_aprs_is_ready(patty_ax25_aprs_is *aprs, fd_set *fds);
int patty_ax25_aprs_is_reset(patty_ax25_aprs_is *aprs);
ssize_t patty_ax25_aprs_is_fill(patty_ax25_aprs_is *aprs); ssize_t patty_ax25_aprs_is_fill(patty_ax25_aprs_is *aprs);
ssize_t patty_ax25_aprs_is_drain(patty_ax25_aprs_is *aprs, ssize_t patty_ax25_aprs_is_drain(patty_ax25_aprs_is *aprs,

View file

@ -41,6 +41,8 @@ typedef int (patty_ax25_if_driver_fd)(void *);
typedef int (patty_ax25_if_driver_ready)(void *, fd_set *); typedef int (patty_ax25_if_driver_ready)(void *, fd_set *);
typedef int (patty_ax25_if_driver_reset)(void *);
typedef ssize_t (patty_ax25_if_driver_fill)(void *); typedef ssize_t (patty_ax25_if_driver_fill)(void *);
typedef ssize_t (patty_ax25_if_driver_drain)(void *, void *, size_t); typedef ssize_t (patty_ax25_if_driver_drain)(void *, void *, size_t);
@ -57,6 +59,7 @@ typedef struct _patty_ax25_if_driver {
patty_ax25_if_driver_stats *stats; patty_ax25_if_driver_stats *stats;
patty_ax25_if_driver_fd *fd; patty_ax25_if_driver_fd *fd;
patty_ax25_if_driver_ready *ready; patty_ax25_if_driver_ready *ready;
patty_ax25_if_driver_reset *reset;
patty_ax25_if_driver_fill *fill; patty_ax25_if_driver_fill *fill;
patty_ax25_if_driver_drain *drain; patty_ax25_if_driver_drain *drain;
patty_ax25_if_driver_pending *pending; patty_ax25_if_driver_pending *pending;
@ -123,6 +126,8 @@ int patty_ax25_if_fd(patty_ax25_if *iface);
int patty_ax25_if_ready(patty_ax25_if *iface, fd_set *fds); int patty_ax25_if_ready(patty_ax25_if *iface, fd_set *fds);
int patty_ax25_if_reset(patty_ax25_if *iface);
ssize_t patty_ax25_if_fill(patty_ax25_if *iface); ssize_t patty_ax25_if_fill(patty_ax25_if *iface);
ssize_t patty_ax25_if_drain(patty_ax25_if *iface, void *buf, size_t len); ssize_t patty_ax25_if_drain(patty_ax25_if *iface, void *buf, size_t len);

View file

@ -37,6 +37,8 @@ int patty_kiss_tnc_fd(patty_kiss_tnc *tnc);
int patty_kiss_tnc_ready(patty_kiss_tnc *tnc, fd_set *fds); int patty_kiss_tnc_ready(patty_kiss_tnc *tnc, fd_set *fds);
int patty_kiss_tnc_reset(patty_kiss_tnc *tnc);
void patty_kiss_tnc_destroy(patty_kiss_tnc *tnc); void patty_kiss_tnc_destroy(patty_kiss_tnc *tnc);
ssize_t patty_kiss_tnc_fill(patty_kiss_tnc *tnc); ssize_t patty_kiss_tnc_fill(patty_kiss_tnc *tnc);

View file

@ -161,7 +161,7 @@ error_malloc_aprs:
} }
void patty_ax25_aprs_is_destroy(patty_ax25_aprs_is *aprs) { void patty_ax25_aprs_is_destroy(patty_ax25_aprs_is *aprs) {
(void)close(aprs->fd); close(aprs->fd);
free(aprs); free(aprs);
} }
@ -178,18 +178,24 @@ int patty_ax25_aprs_is_ready(patty_ax25_aprs_is *aprs, fd_set *fds) {
return FD_ISSET(aprs->fd, fds); return FD_ISSET(aprs->fd, fds);
} }
ssize_t patty_ax25_aprs_is_fill(patty_ax25_aprs_is *aprs) { int patty_ax25_aprs_is_reset(patty_ax25_aprs_is *aprs) {
int attempt = 0; int attempt;
while ((aprs->readlen = read(aprs->fd, aprs->rx_buf, aprs->rx_bufsz)) < 0) { close(aprs->fd);
if (errno == EIO) {
if (++attempt == PATTY_AX25_APRS_IS_ATTEMPTS_MAX) { for (attempt=0; attempt<PATTY_AX25_APRS_IS_ATTEMPTS_MAX; attempt++) {
(void)aprs_is_connect(aprs, &aprs->info); if (aprs_is_connect(aprs, &aprs->info) == 0) {
return aprs->fd;
} }
} else { }
return -1;
}
ssize_t patty_ax25_aprs_is_fill(patty_ax25_aprs_is *aprs) {
if ((aprs->readlen = read(aprs->fd, aprs->rx_buf, aprs->rx_bufsz)) < 0) {
goto error_read; goto error_read;
} }
}
aprs->offset_i = 0; aprs->offset_i = 0;
@ -450,6 +456,7 @@ patty_ax25_if_driver *patty_ax25_aprs_is_driver() {
.stats = (patty_ax25_if_driver_stats *)patty_ax25_aprs_is_stats, .stats = (patty_ax25_if_driver_stats *)patty_ax25_aprs_is_stats,
.fd = (patty_ax25_if_driver_fd *)patty_ax25_aprs_is_fd, .fd = (patty_ax25_if_driver_fd *)patty_ax25_aprs_is_fd,
.ready = (patty_ax25_if_driver_ready *)patty_ax25_aprs_is_ready, .ready = (patty_ax25_if_driver_ready *)patty_ax25_aprs_is_ready,
.reset = (patty_ax25_if_driver_reset *)patty_ax25_aprs_is_reset,
.fill = (patty_ax25_if_driver_fill *)patty_ax25_aprs_is_fill, .fill = (patty_ax25_if_driver_fill *)patty_ax25_aprs_is_fill,
.drain = (patty_ax25_if_driver_drain *)patty_ax25_aprs_is_drain, .drain = (patty_ax25_if_driver_drain *)patty_ax25_aprs_is_drain,
.pending = (patty_ax25_if_driver_pending *)patty_ax25_aprs_is_pending, .pending = (patty_ax25_if_driver_pending *)patty_ax25_aprs_is_pending,

View file

@ -286,6 +286,18 @@ int patty_ax25_if_ready(patty_ax25_if *iface, fd_set *fds) {
iface->driver->ready(iface->phy, fds): 0; iface->driver->ready(iface->phy, fds): 0;
} }
int patty_ax25_if_reset(patty_ax25_if *iface) {
int ret;
if ((ret = iface->driver->reset(iface->phy)) < 0) {
iface->status = PATTY_AX25_IF_ERROR;
} else {
iface->status = PATTY_AX25_IF_UP;
}
return ret;
}
ssize_t patty_ax25_if_fill(patty_ax25_if *iface) { ssize_t patty_ax25_if_fill(patty_ax25_if *iface) {
return iface->driver->fill(iface->phy); return iface->driver->fill(iface->phy);
} }

View file

@ -2044,7 +2044,15 @@ static int handle_iface(patty_ax25_server *server, struct if_entry *entry) {
} }
if ((len = patty_ax25_if_fill(entry->iface)) < 0) { if ((len = patty_ax25_if_fill(entry->iface)) < 0) {
int fd;
fd_clear(server, entry->fd);
if ((fd = patty_ax25_if_reset(entry->iface)) < 0) {
goto error_io; goto error_io;
}
fd_watch(server, entry->fd = fd);
} else if (len == 0) { } else if (len == 0) {
close(entry->fd); close(entry->fd);

View file

@ -239,6 +239,12 @@ int patty_kiss_tnc_ready(patty_kiss_tnc *tnc, fd_set *fds) {
return FD_ISSET(tnc->fd, fds); return FD_ISSET(tnc->fd, fds);
} }
int patty_kiss_tnc_reset(patty_kiss_tnc *tnc) {
errno = ENOSYS;
return -1;
}
static void tnc_drop(patty_kiss_tnc *tnc) { static void tnc_drop(patty_kiss_tnc *tnc) {
tnc->state = KISS_NONE; tnc->state = KISS_NONE;
tnc->command = PATTY_KISS_RETURN; tnc->command = PATTY_KISS_RETURN;
@ -410,6 +416,7 @@ patty_ax25_if_driver *patty_kiss_tnc_driver() {
.stats = (patty_ax25_if_driver_stats *)patty_kiss_tnc_stats, .stats = (patty_ax25_if_driver_stats *)patty_kiss_tnc_stats,
.fd = (patty_ax25_if_driver_fd *)patty_kiss_tnc_fd, .fd = (patty_ax25_if_driver_fd *)patty_kiss_tnc_fd,
.ready = (patty_ax25_if_driver_ready *)patty_kiss_tnc_ready, .ready = (patty_ax25_if_driver_ready *)patty_kiss_tnc_ready,
.reset = (patty_ax25_if_driver_reset *)patty_kiss_tnc_reset,
.fill = (patty_ax25_if_driver_fill *)patty_kiss_tnc_fill, .fill = (patty_ax25_if_driver_fill *)patty_kiss_tnc_fill,
.drain = (patty_ax25_if_driver_drain *)patty_kiss_tnc_drain, .drain = (patty_ax25_if_driver_drain *)patty_kiss_tnc_drain,
.pending = (patty_ax25_if_driver_pending *)patty_kiss_tnc_pending, .pending = (patty_ax25_if_driver_pending *)patty_kiss_tnc_pending,