Re-establish broken APRS-IS connections

Re-establish broken APRS-IS connections in src/aprs_is.c; when read() or
write() sets errno to EIO, attempt at most 3 times to re-establish the
APRS-IS connection per read()/write() failure; if the maximum number of
attempts is met, the I/O operation is considered a total failure
This commit is contained in:
XANTRONIX 2020-10-01 15:41:43 -04:00 committed by XANTRONIX Industrial
parent 88743a5754
commit 65ae821342
2 changed files with 39 additions and 15 deletions

View file

@ -12,7 +12,7 @@
#define PATTY_AX25_APRS_IS_PACKET_MAX 512
#define PATTY_AX25_APRS_IS_FRAME_MAX PATTY_AX25_APRS_IS_PACKET_MAX
typedef struct _patty_ax25_aprs_is patty_ax25_aprs_is;
#define PATTY_AX25_APRS_IS_ATTEMPTS_MAX 3
typedef struct _patty_ax25_aprs_is_info {
const char *host,
@ -24,6 +24,8 @@ typedef struct _patty_ax25_aprs_is_info {
*filter;
} patty_ax25_aprs_is_info;
typedef struct _patty_ax25_aprs_is patty_ax25_aprs_is;
ssize_t patty_ax25_aprs_is_encode(void *dest,
const char *src,
size_t len,

View file

@ -19,25 +19,26 @@ enum state {
struct _patty_ax25_aprs_is {
patty_ax25_if_stats stats;
patty_ax25_aprs_is_info info;
int fd;
char rx_buf[PATTY_AX25_APRS_IS_PACKET_MAX],
tx_buf[PATTY_AX25_APRS_IS_FRAME_MAX],
call[PATTY_AX25_ADDRSTRLEN+1],
info[PATTY_AX25_APRS_IS_PAYLOAD_MAX];
body[PATTY_AX25_APRS_IS_PAYLOAD_MAX];
patty_ax25_frame frame;
size_t rx_bufsz,
tx_bufsz,
infosz;
bodysz;
enum state state;
size_t offset_i,
offset_call,
offset_info;
offset_body;
ssize_t readlen,
encoded;
@ -138,13 +139,15 @@ patty_ax25_aprs_is *patty_ax25_aprs_is_new(patty_ax25_aprs_is_info *info) {
aprs->rx_bufsz = PATTY_AX25_APRS_IS_PACKET_MAX;
aprs->tx_bufsz = PATTY_AX25_APRS_IS_FRAME_MAX;
aprs->infosz = PATTY_AX25_APRS_IS_PAYLOAD_MAX;
aprs->bodysz = PATTY_AX25_APRS_IS_PAYLOAD_MAX;
aprs->state = APRS_IS_HEADER;
if (aprs_is_connect(aprs, info) < 0) {
goto error_connect;
}
memcpy(&aprs->info, info, sizeof(aprs->info));
return aprs;
error_connect:
@ -175,8 +178,16 @@ ssize_t patty_ax25_aprs_is_pending(patty_ax25_aprs_is *aprs) {
}
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;
int attempt = 0;
while ((aprs->readlen = read(aprs->fd, aprs->rx_buf, aprs->rx_bufsz)) < 0) {
if (errno == EIO) {
if (++attempt == PATTY_AX25_APRS_IS_ATTEMPTS_MAX) {
(void)aprs_is_connect(aprs, &aprs->info);
}
} else {
goto error_read;
}
}
aprs->offset_i = 0;
@ -260,8 +271,8 @@ ssize_t patty_ax25_aprs_is_drain(patty_ax25_aprs_is *aprs,
aprs->frame.control = PATTY_AX25_FRAME_UI;
aprs->frame.cr = PATTY_AX25_FRAME_COMMAND;
aprs->frame.proto = PATTY_AX25_PROTO_NONE;
aprs->frame.info = aprs->info;
aprs->frame.infolen = aprs->offset_info;
aprs->frame.info = aprs->body;
aprs->frame.infolen = aprs->offset_body;
if ((aprs->encoded = patty_ax25_frame_encode(&aprs->frame,
buf,
@ -271,11 +282,11 @@ ssize_t patty_ax25_aprs_is_drain(patty_ax25_aprs_is *aprs,
goto done;
} else {
if (aprs->offset_info == aprs->infosz) {
if (aprs->offset_body == aprs->bodysz) {
goto drop;
}
aprs->info[aprs->offset_info++] = c;
aprs->body[aprs->offset_body++] = c;
}
break;
@ -307,7 +318,7 @@ ssize_t patty_ax25_aprs_is_flush(patty_ax25_aprs_is *aprs) {
aprs->state = APRS_IS_HEADER;
aprs->offset_i = aprs->readlen;
aprs->offset_call = 0;
aprs->offset_info = 0;
aprs->offset_body = 0;
aprs->encoded = 0;
memset(&aprs->frame, '\0', sizeof(aprs->frame));
@ -326,7 +337,8 @@ ssize_t patty_ax25_aprs_is_send(patty_ax25_aprs_is *aprs,
ssize_t decoded;
int formatted;
int formatted,
attempt;
char call[PATTY_AX25_ADDRSTRLEN+1];
@ -408,8 +420,18 @@ ssize_t patty_ax25_aprs_is_send(patty_ax25_aprs_is *aprs,
aprs->tx_buf[o++] = '\r';
aprs->tx_buf[o++] = '\n';
if (write(aprs->fd, aprs->tx_buf, o) < 0) {
goto error;
attempt = 0;
while (write(aprs->fd, aprs->tx_buf, o) < 0) {
if (++attempt == PATTY_AX25_APRS_IS_ATTEMPTS_MAX) {
goto error;
}
if (errno == EIO) {
(void)aprs_is_connect(aprs, &aprs->info);
} else {
goto error;
}
}
return i;