diff --git a/include/patty/ax25/aprs_is.h b/include/patty/ax25/aprs_is.h index 8695dfe..3ed26e7 100644 --- a/include/patty/ax25/aprs_is.h +++ b/include/patty/ax25/aprs_is.h @@ -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, diff --git a/src/aprs_is.c b/src/aprs_is.c index 5468cbd..e2981c3 100644 --- a/src/aprs_is.c +++ b/src/aprs_is.c @@ -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;