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:
parent
88743a5754
commit
65ae821342
2 changed files with 39 additions and 15 deletions
|
@ -12,7 +12,7 @@
|
||||||
#define PATTY_AX25_APRS_IS_PACKET_MAX 512
|
#define PATTY_AX25_APRS_IS_PACKET_MAX 512
|
||||||
#define PATTY_AX25_APRS_IS_FRAME_MAX PATTY_AX25_APRS_IS_PACKET_MAX
|
#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 {
|
typedef struct _patty_ax25_aprs_is_info {
|
||||||
const char *host,
|
const char *host,
|
||||||
|
@ -24,6 +24,8 @@ typedef struct _patty_ax25_aprs_is_info {
|
||||||
*filter;
|
*filter;
|
||||||
} patty_ax25_aprs_is_info;
|
} patty_ax25_aprs_is_info;
|
||||||
|
|
||||||
|
typedef struct _patty_ax25_aprs_is patty_ax25_aprs_is;
|
||||||
|
|
||||||
ssize_t patty_ax25_aprs_is_encode(void *dest,
|
ssize_t patty_ax25_aprs_is_encode(void *dest,
|
||||||
const char *src,
|
const char *src,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
|
|
@ -19,25 +19,26 @@ enum state {
|
||||||
|
|
||||||
struct _patty_ax25_aprs_is {
|
struct _patty_ax25_aprs_is {
|
||||||
patty_ax25_if_stats stats;
|
patty_ax25_if_stats stats;
|
||||||
|
patty_ax25_aprs_is_info info;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
char rx_buf[PATTY_AX25_APRS_IS_PACKET_MAX],
|
char rx_buf[PATTY_AX25_APRS_IS_PACKET_MAX],
|
||||||
tx_buf[PATTY_AX25_APRS_IS_FRAME_MAX],
|
tx_buf[PATTY_AX25_APRS_IS_FRAME_MAX],
|
||||||
call[PATTY_AX25_ADDRSTRLEN+1],
|
call[PATTY_AX25_ADDRSTRLEN+1],
|
||||||
info[PATTY_AX25_APRS_IS_PAYLOAD_MAX];
|
body[PATTY_AX25_APRS_IS_PAYLOAD_MAX];
|
||||||
|
|
||||||
patty_ax25_frame frame;
|
patty_ax25_frame frame;
|
||||||
|
|
||||||
size_t rx_bufsz,
|
size_t rx_bufsz,
|
||||||
tx_bufsz,
|
tx_bufsz,
|
||||||
infosz;
|
bodysz;
|
||||||
|
|
||||||
enum state state;
|
enum state state;
|
||||||
|
|
||||||
size_t offset_i,
|
size_t offset_i,
|
||||||
offset_call,
|
offset_call,
|
||||||
offset_info;
|
offset_body;
|
||||||
|
|
||||||
ssize_t readlen,
|
ssize_t readlen,
|
||||||
encoded;
|
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->rx_bufsz = PATTY_AX25_APRS_IS_PACKET_MAX;
|
||||||
aprs->tx_bufsz = PATTY_AX25_APRS_IS_FRAME_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;
|
aprs->state = APRS_IS_HEADER;
|
||||||
|
|
||||||
if (aprs_is_connect(aprs, info) < 0) {
|
if (aprs_is_connect(aprs, info) < 0) {
|
||||||
goto error_connect;
|
goto error_connect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(&aprs->info, info, sizeof(aprs->info));
|
||||||
|
|
||||||
return aprs;
|
return aprs;
|
||||||
|
|
||||||
error_connect:
|
error_connect:
|
||||||
|
@ -175,9 +178,17 @@ ssize_t patty_ax25_aprs_is_pending(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) {
|
||||||
if ((aprs->readlen = read(aprs->fd, aprs->rx_buf, aprs->rx_bufsz)) < 0) {
|
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;
|
goto error_read;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
aprs->offset_i = 0;
|
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.control = PATTY_AX25_FRAME_UI;
|
||||||
aprs->frame.cr = PATTY_AX25_FRAME_COMMAND;
|
aprs->frame.cr = PATTY_AX25_FRAME_COMMAND;
|
||||||
aprs->frame.proto = PATTY_AX25_PROTO_NONE;
|
aprs->frame.proto = PATTY_AX25_PROTO_NONE;
|
||||||
aprs->frame.info = aprs->info;
|
aprs->frame.info = aprs->body;
|
||||||
aprs->frame.infolen = aprs->offset_info;
|
aprs->frame.infolen = aprs->offset_body;
|
||||||
|
|
||||||
if ((aprs->encoded = patty_ax25_frame_encode(&aprs->frame,
|
if ((aprs->encoded = patty_ax25_frame_encode(&aprs->frame,
|
||||||
buf,
|
buf,
|
||||||
|
@ -271,11 +282,11 @@ ssize_t patty_ax25_aprs_is_drain(patty_ax25_aprs_is *aprs,
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
if (aprs->offset_info == aprs->infosz) {
|
if (aprs->offset_body == aprs->bodysz) {
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
aprs->info[aprs->offset_info++] = c;
|
aprs->body[aprs->offset_body++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -307,7 +318,7 @@ ssize_t patty_ax25_aprs_is_flush(patty_ax25_aprs_is *aprs) {
|
||||||
aprs->state = APRS_IS_HEADER;
|
aprs->state = APRS_IS_HEADER;
|
||||||
aprs->offset_i = aprs->readlen;
|
aprs->offset_i = aprs->readlen;
|
||||||
aprs->offset_call = 0;
|
aprs->offset_call = 0;
|
||||||
aprs->offset_info = 0;
|
aprs->offset_body = 0;
|
||||||
aprs->encoded = 0;
|
aprs->encoded = 0;
|
||||||
|
|
||||||
memset(&aprs->frame, '\0', sizeof(aprs->frame));
|
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;
|
ssize_t decoded;
|
||||||
|
|
||||||
int formatted;
|
int formatted,
|
||||||
|
attempt;
|
||||||
|
|
||||||
char call[PATTY_AX25_ADDRSTRLEN+1];
|
char call[PATTY_AX25_ADDRSTRLEN+1];
|
||||||
|
|
||||||
|
@ -408,10 +420,20 @@ ssize_t patty_ax25_aprs_is_send(patty_ax25_aprs_is *aprs,
|
||||||
aprs->tx_buf[o++] = '\r';
|
aprs->tx_buf[o++] = '\r';
|
||||||
aprs->tx_buf[o++] = '\n';
|
aprs->tx_buf[o++] = '\n';
|
||||||
|
|
||||||
if (write(aprs->fd, aprs->tx_buf, o) < 0) {
|
attempt = 0;
|
||||||
|
|
||||||
|
while (write(aprs->fd, aprs->tx_buf, o) < 0) {
|
||||||
|
if (++attempt == PATTY_AX25_APRS_IS_ATTEMPTS_MAX) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errno == EIO) {
|
||||||
|
(void)aprs_is_connect(aprs, &aprs->info);
|
||||||
|
} else {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
Loading…
Add table
Reference in a new issue