diff --git a/include/patty/ax25/aprs_is.h b/include/patty/ax25/aprs_is.h index 3b792d1..8695dfe 100644 --- a/include/patty/ax25/aprs_is.h +++ b/include/patty/ax25/aprs_is.h @@ -33,12 +33,6 @@ patty_ax25_aprs_is *patty_ax25_aprs_is_new(patty_ax25_aprs_is_info *info); void patty_ax25_aprs_is_destroy(patty_ax25_aprs_is *aprs); -ssize_t patty_ax25_aprs_is_readline(patty_ax25_aprs_is *aprs, - void *buf, - size_t len); - -int patty_ax25_aprs_is_printf(patty_ax25_aprs_is *aprs, const char *fmt, ...); - int patty_ax25_aprs_is_fd(patty_ax25_aprs_is *aprs); ssize_t patty_ax25_aprs_is_pending(patty_ax25_aprs_is *aprs); diff --git a/src/aprs_is.c b/src/aprs_is.c index b4636f1..69cabc5 100644 --- a/src/aprs_is.c +++ b/src/aprs_is.c @@ -41,51 +41,39 @@ struct _patty_ax25_aprs_is { encoded; }; -static ssize_t send_line(patty_ax25_aprs_is *aprs, char *buf, size_t len) { - if (len > PATTY_AX25_APRS_IS_PACKET_MAX - 2) { - len = PATTY_AX25_APRS_IS_PACKET_MAX - 2; - } +static ssize_t aprs_is_vprintf(patty_ax25_aprs_is *aprs, + const char *fmt, + va_list args) { + int len; - buf[len] = '\r'; - buf[len+1] = '\n'; - - return write(aprs->fd, buf, len+2); -} - -static int send_va(patty_ax25_aprs_is *aprs, const char *fmt, va_list args) { - size_t len; - - if (vsnprintf(aprs->tx_buf, PATTY_AX25_APRS_IS_PACKET_MAX, fmt, args) < 0) { + if ((len = vsnprintf(aprs->tx_buf, + PATTY_AX25_APRS_IS_PACKET_MAX, + fmt, + args)) < 0) { goto error_vsnprintf; } - len = strnlen(aprs->tx_buf, PATTY_AX25_APRS_IS_PACKET_MAX); + return write(aprs->fd, aprs->tx_buf, (size_t)len); - if (send_line(aprs, aprs->tx_buf, len) < 0) { - goto error_send_line; - } - - return 0; - -error_send_line: error_vsnprintf: return -1; } -static int send_fmt(patty_ax25_aprs_is *aprs, const char *fmt, ...) { +static ssize_t aprs_is_printf(patty_ax25_aprs_is *aprs, const char *fmt, ...) { + ssize_t len; va_list args; va_start(args, fmt); - if (send_va(aprs, fmt, args) < 0) { - goto error_send_va; + if ((len = aprs_is_vprintf(aprs, fmt, args)) < 0) { + goto error_aprs_is_vprintf; } va_end(args); - return 0; + return len; -error_send_va: +error_aprs_is_vprintf: return -1; } @@ -113,20 +101,20 @@ static int aprs_is_connect(patty_ax25_aprs_is *aprs, freeaddrinfo(ai0); - if (send_fmt(aprs, - "user %s pass %s vers %s %s filter %s", - info->user, - info->pass, - info->appname, - info->version, - info->filter) < 0) { - goto error_send_fmt; + if (aprs_is_printf(aprs, + "user %s pass %s vers %s %s filter %s\r\n", + info->user, + info->pass, + info->appname, + info->version, + info->filter) < 0) { + goto error_aprs_is_printf; } return 0; } -error_send_fmt: +error_aprs_is_printf: close(aprs->fd); error_getaddrinfo: @@ -322,29 +310,97 @@ ssize_t patty_ax25_aprs_is_flush(patty_ax25_aprs_is *aprs) { return ret; } -int patty_ax25_aprs_is_printf(patty_ax25_aprs_is *aprs, const char *fmt, ...) { - va_list args; - - va_start(args, fmt); - - if (send_va(aprs, fmt, args) < 0) { - goto error_send_va; - } - - va_end(args); - - return 0; - -error_send_va: - va_end(args); - - return -1; -} - ssize_t patty_ax25_aprs_is_send(patty_ax25_aprs_is *aprs, const void *buf, size_t len) { - return 0; + patty_ax25_frame frame; + + size_t offset = 0; + ssize_t decoded; + + int formatted, + i; + + char station[PATTY_AX25_ADDRSTRLEN+1]; + + if ((decoded = patty_ax25_frame_decode_address(&frame, buf, len)) < 0) { + goto error; + } + + if (patty_ax25_frame_decode_control(&frame, + PATTY_AX25_FRAME_NORMAL, + buf, + decoded, + len) < 0) { + goto error; + } + + if (!PATTY_AX25_FRAME_CONTROL_UI(frame.control)) { + return 0; + } + + if (patty_ax25_ntop(&frame.src, station, sizeof(station)) < 0) { + goto error; + } + + if ((formatted = snprintf(aprs->tx_buf, + aprs->tx_bufsz, + "%s>", + station)) < 0) { + goto error; + } else { + offset += formatted; + } + + if (patty_ax25_ntop(&frame.dest, station, sizeof(station)) < 0) { + goto error; + } + + if ((formatted = snprintf(aprs->tx_buf + offset, + aprs->tx_bufsz - offset, + "%s", + station)) < 0) { + goto error; + } else { + offset += formatted; + } + + for (i=0; itx_buf + offset, + aprs->tx_bufsz - offset, + ",%s", + station)) < 0) { + goto error; + } else { + offset += formatted; + } + } + + if (aprs->tx_bufsz - offset < frame.infolen + 3) { + errno = EOVERFLOW; + + goto error; + } + + aprs->tx_buf[offset++] = ':'; + + memcpy(aprs->tx_buf + offset, frame.info, frame.infolen); + + offset += frame.infolen; + + aprs->tx_buf[offset++] = '\r'; + aprs->tx_buf[offset++] = '\n'; + + return write(aprs->fd, aprs->tx_buf, offset); + +error: + return -1; } patty_ax25_if_driver *patty_ax25_aprs_is_driver() {