Implement patty_ax25_aprs_is_send()
Implement patty_ax25_aprs_is_send() to be able to encode any outbound UI frames in TNC2 format, and to send them to a remote APRS-IS server Other changes: * Remove unimplemented patty_ax25_aprs_is_printf() declaration * Remove unimplemented patty_ax25_aprs_is_readline() declaration
This commit is contained in:
parent
34e5629bc9
commit
70d112eb91
2 changed files with 112 additions and 62 deletions
|
@ -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);
|
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);
|
int patty_ax25_aprs_is_fd(patty_ax25_aprs_is *aprs);
|
||||||
|
|
||||||
ssize_t patty_ax25_aprs_is_pending(patty_ax25_aprs_is *aprs);
|
ssize_t patty_ax25_aprs_is_pending(patty_ax25_aprs_is *aprs);
|
||||||
|
|
168
src/aprs_is.c
168
src/aprs_is.c
|
@ -41,51 +41,39 @@ struct _patty_ax25_aprs_is {
|
||||||
encoded;
|
encoded;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t send_line(patty_ax25_aprs_is *aprs, char *buf, size_t len) {
|
static ssize_t aprs_is_vprintf(patty_ax25_aprs_is *aprs,
|
||||||
if (len > PATTY_AX25_APRS_IS_PACKET_MAX - 2) {
|
const char *fmt,
|
||||||
len = PATTY_AX25_APRS_IS_PACKET_MAX - 2;
|
va_list args) {
|
||||||
}
|
int len;
|
||||||
|
|
||||||
buf[len] = '\r';
|
if ((len = vsnprintf(aprs->tx_buf,
|
||||||
buf[len+1] = '\n';
|
PATTY_AX25_APRS_IS_PACKET_MAX,
|
||||||
|
fmt,
|
||||||
return write(aprs->fd, buf, len+2);
|
args)) < 0) {
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
goto error_vsnprintf;
|
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:
|
error_vsnprintf:
|
||||||
return -1;
|
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_list args;
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
||||||
if (send_va(aprs, fmt, args) < 0) {
|
if ((len = aprs_is_vprintf(aprs, fmt, args)) < 0) {
|
||||||
goto error_send_va;
|
goto error_aprs_is_vprintf;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
return 0;
|
return len;
|
||||||
|
|
||||||
error_send_va:
|
error_aprs_is_vprintf:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,20 +101,20 @@ static int aprs_is_connect(patty_ax25_aprs_is *aprs,
|
||||||
|
|
||||||
freeaddrinfo(ai0);
|
freeaddrinfo(ai0);
|
||||||
|
|
||||||
if (send_fmt(aprs,
|
if (aprs_is_printf(aprs,
|
||||||
"user %s pass %s vers %s %s filter %s",
|
"user %s pass %s vers %s %s filter %s\r\n",
|
||||||
info->user,
|
info->user,
|
||||||
info->pass,
|
info->pass,
|
||||||
info->appname,
|
info->appname,
|
||||||
info->version,
|
info->version,
|
||||||
info->filter) < 0) {
|
info->filter) < 0) {
|
||||||
goto error_send_fmt;
|
goto error_aprs_is_printf;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_send_fmt:
|
error_aprs_is_printf:
|
||||||
close(aprs->fd);
|
close(aprs->fd);
|
||||||
|
|
||||||
error_getaddrinfo:
|
error_getaddrinfo:
|
||||||
|
@ -322,29 +310,97 @@ ssize_t patty_ax25_aprs_is_flush(patty_ax25_aprs_is *aprs) {
|
||||||
return ret;
|
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,
|
ssize_t patty_ax25_aprs_is_send(patty_ax25_aprs_is *aprs,
|
||||||
const void *buf,
|
const void *buf,
|
||||||
size_t len) {
|
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; i<frame.hops; i++) {
|
||||||
|
if (patty_ax25_ntop(&frame.repeaters[i],
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
patty_ax25_if_driver *patty_ax25_aprs_is_driver() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue