Implement SOCK_DGRAM
Implement PATTY_AX25_SOCK_DGRAM type sockets as a means of exchanging UI frames between stations without requiring calling code to encode and decode UI frames explicitly
This commit is contained in:
parent
1d03b2883a
commit
4899aa4796
5 changed files with 89 additions and 45 deletions
|
@ -59,8 +59,7 @@ enum patty_ax25_frame_type {
|
||||||
PATTY_AX25_FRAME_FRMR = 0x87,
|
PATTY_AX25_FRAME_FRMR = 0x87,
|
||||||
PATTY_AX25_FRAME_UI = 0x03,
|
PATTY_AX25_FRAME_UI = 0x03,
|
||||||
PATTY_AX25_FRAME_XID = 0xaf,
|
PATTY_AX25_FRAME_XID = 0xaf,
|
||||||
PATTY_AX25_FRAME_TEST = 0xe3,
|
PATTY_AX25_FRAME_TEST = 0xe3
|
||||||
PATTY_AX25_FRAME_UNKNOWN = 0xff
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _patty_ax25_frame {
|
typedef struct _patty_ax25_frame {
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
enum patty_ax25_sock_type {
|
enum patty_ax25_sock_type {
|
||||||
PATTY_AX25_SOCK_STREAM,
|
PATTY_AX25_SOCK_STREAM,
|
||||||
|
PATTY_AX25_SOCK_DGRAM,
|
||||||
PATTY_AX25_SOCK_RAW
|
PATTY_AX25_SOCK_RAW
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ ssize_t patty_ax25_frame_decode_control(patty_ax25_frame *frame,
|
||||||
frame->nr = 0;
|
frame->nr = 0;
|
||||||
frame->ns = 0;
|
frame->ns = 0;
|
||||||
frame->pf = 0;
|
frame->pf = 0;
|
||||||
frame->type = PATTY_AX25_FRAME_UNKNOWN;
|
frame->type = 0xff;
|
||||||
frame->proto = PATTY_AX25_PROTO_UNKNOWN;
|
frame->proto = PATTY_AX25_PROTO_UNKNOWN;
|
||||||
frame->info = NULL;
|
frame->info = NULL;
|
||||||
frame->infolen = 0;
|
frame->infolen = 0;
|
||||||
|
|
42
src/server.c
42
src/server.c
|
@ -842,8 +842,6 @@ static int server_connect(patty_ax25_server *server,
|
||||||
*/
|
*/
|
||||||
memcpy(&sock->remote, &request.peer, sizeof(request.peer));
|
memcpy(&sock->remote, &request.peer, sizeof(request.peer));
|
||||||
|
|
||||||
sock->state = PATTY_AX25_SOCK_PENDING_CONNECT;
|
|
||||||
|
|
||||||
if (sock_save_remote(server, sock) < 0) {
|
if (sock_save_remote(server, sock) < 0) {
|
||||||
goto error_sock_save_remote;
|
goto error_sock_save_remote;
|
||||||
}
|
}
|
||||||
|
@ -852,21 +850,34 @@ static int server_connect(patty_ax25_server *server,
|
||||||
goto error_client_save_by_sock;
|
goto error_client_save_by_sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (sock->type) {
|
||||||
|
case PATTY_AX25_SOCK_DGRAM:
|
||||||
|
sock->state = PATTY_AX25_SOCK_ESTABLISHED;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PATTY_AX25_SOCK_STREAM:
|
||||||
|
sock->state = PATTY_AX25_SOCK_PENDING_CONNECT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send an XID frame, to attempt to negotiate AX.25 v2.2 and its default
|
* Send an XID frame, to attempt to negotiate AX.25 v2.2 and its
|
||||||
* parameters.
|
* default parameters.
|
||||||
*/
|
*/
|
||||||
if (patty_ax25_sock_send_xid(sock, PATTY_AX25_FRAME_COMMAND) < 0) {
|
if (patty_ax25_sock_send_xid(sock, PATTY_AX25_FRAME_COMMAND) < 0) {
|
||||||
return respond_connect(client, -1, errno);
|
return respond_connect(client, -1, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we will wait for a DM, FRMR or XID response, which
|
* At this point, we will wait for a DM, FRMR or XID response, which
|
||||||
* will help us determine what version of AX.25 to apply for this socket,
|
* will help us determine what version of AX.25 to apply for this
|
||||||
* or whether the peer is not accepting connections.
|
* socket, or whether the peer is not accepting connections.
|
||||||
*/
|
*/
|
||||||
|
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_client_save_by_sock:
|
error_client_save_by_sock:
|
||||||
|
@ -1396,6 +1407,17 @@ error_write:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int handle_ui(patty_ax25_server *server,
|
||||||
|
patty_ax25_if *iface,
|
||||||
|
patty_ax25_sock *sock,
|
||||||
|
patty_ax25_frame *frame) {
|
||||||
|
if (sock == NULL || sock->type != PATTY_AX25_SOCK_DGRAM) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return write(sock->fd, frame->info, frame->infolen);
|
||||||
|
}
|
||||||
|
|
||||||
static int handle_disc(patty_ax25_server *server,
|
static int handle_disc(patty_ax25_server *server,
|
||||||
patty_ax25_if *iface,
|
patty_ax25_if *iface,
|
||||||
patty_ax25_sock *sock,
|
patty_ax25_sock *sock,
|
||||||
|
@ -1690,6 +1712,7 @@ static int handle_frame(patty_ax25_server *server,
|
||||||
|
|
||||||
switch (frame.type) {
|
switch (frame.type) {
|
||||||
case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame);
|
case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame);
|
||||||
|
case PATTY_AX25_FRAME_UI: return handle_ui(server, iface, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_RR: return handle_rr(server, sock, &frame);
|
case PATTY_AX25_FRAME_RR: return handle_rr(server, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_RNR: return handle_rnr(server, sock, &frame);
|
case PATTY_AX25_FRAME_RNR: return handle_rnr(server, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_REJ: return handle_rej(server, sock, &frame);
|
case PATTY_AX25_FRAME_REJ: return handle_rej(server, sock, &frame);
|
||||||
|
@ -1702,9 +1725,6 @@ static int handle_frame(patty_ax25_server *server,
|
||||||
case PATTY_AX25_FRAME_DM: return handle_dm(server, iface, sock, &frame);
|
case PATTY_AX25_FRAME_DM: return handle_dm(server, iface, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_DISC: return handle_disc(server, iface, sock, &frame);
|
case PATTY_AX25_FRAME_DISC: return handle_disc(server, iface, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_FRMR: return handle_frmr(server, iface, sock, &frame);
|
case PATTY_AX25_FRAME_FRMR: return handle_frmr(server, iface, sock, &frame);
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
60
src/sock.c
60
src/sock.c
|
@ -111,26 +111,28 @@ error_realloc_tx_buf:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static patty_ax25_sock *init_raw(patty_ax25_sock *sock) {
|
static patty_ax25_sock *init_dgram(patty_ax25_sock *sock,
|
||||||
if (bind_pty(sock) < 0) {
|
enum patty_ax25_proto proto) {
|
||||||
goto error_bind_pty;
|
sock->proto = proto;
|
||||||
}
|
sock->type = PATTY_AX25_SOCK_DGRAM;
|
||||||
|
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static patty_ax25_sock *init_raw(patty_ax25_sock *sock) {
|
||||||
if ((sock->raw = patty_kiss_tnc_new_fd(sock->fd)) == NULL) {
|
if ((sock->raw = patty_kiss_tnc_new_fd(sock->fd)) == NULL) {
|
||||||
goto error_kiss_tnc_new_fd;
|
goto error_kiss_tnc_new_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock->proto = PATTY_AX25_PROTO_NONE;
|
sock->proto = PATTY_AX25_PROTO_NONE;
|
||||||
sock->type = PATTY_AX25_SOCK_RAW;
|
sock->type = PATTY_AX25_SOCK_RAW;
|
||||||
|
sock->state = PATTY_AX25_SOCK_ESTABLISHED;
|
||||||
|
|
||||||
return sock;
|
return sock;
|
||||||
|
|
||||||
error_kiss_tnc_new_fd:
|
error_kiss_tnc_new_fd:
|
||||||
(void)close(sock->fd);
|
(void)close(sock->fd);
|
||||||
|
|
||||||
error_bind_pty:
|
|
||||||
free(sock);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,11 +146,20 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto,
|
||||||
|
|
||||||
memset(sock, '\0', sizeof(*sock));
|
memset(sock, '\0', sizeof(*sock));
|
||||||
|
|
||||||
if (type == PATTY_AX25_SOCK_RAW) {
|
if (bind_pty(sock) < 0) {
|
||||||
return init_raw(sock);
|
goto error_bind_pty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case PATTY_AX25_SOCK_DGRAM:
|
||||||
|
return init_dgram(sock, proto);
|
||||||
|
|
||||||
|
case PATTY_AX25_SOCK_RAW:
|
||||||
|
return init_raw(sock);
|
||||||
|
|
||||||
|
case PATTY_AX25_SOCK_STREAM:
|
||||||
patty_ax25_sock_init(sock);
|
patty_ax25_sock_init(sock);
|
||||||
|
}
|
||||||
|
|
||||||
sock->proto = proto;
|
sock->proto = proto;
|
||||||
sock->type = type;
|
sock->type = type;
|
||||||
|
@ -160,18 +171,14 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto,
|
||||||
goto error_init_bufs;
|
goto error_init_bufs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind_pty(sock) < 0) {
|
|
||||||
goto error_bind_pty;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sock;
|
return sock;
|
||||||
|
|
||||||
error_bind_pty:
|
|
||||||
error_init_bufs:
|
error_init_bufs:
|
||||||
if (sock->tx_slots) free(sock->tx_slots);
|
if (sock->tx_slots) free(sock->tx_slots);
|
||||||
if (sock->rx_buf) free(sock->rx_buf);
|
if (sock->rx_buf) free(sock->rx_buf);
|
||||||
if (sock->tx_buf) free(sock->tx_buf);
|
if (sock->tx_buf) free(sock->tx_buf);
|
||||||
|
|
||||||
|
error_bind_pty:
|
||||||
free(sock);
|
free(sock);
|
||||||
|
|
||||||
error_malloc_sock:
|
error_malloc_sock:
|
||||||
|
@ -577,6 +584,10 @@ static uint16_t control_i(patty_ax25_sock *sock, int flag) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t control_ui(int flag) {
|
||||||
|
return PATTY_AX25_FRAME_UI | (flag << 4);
|
||||||
|
}
|
||||||
|
|
||||||
static uint16_t control_s(patty_ax25_sock *sock,
|
static uint16_t control_s(patty_ax25_sock *sock,
|
||||||
enum patty_ax25_frame_type type,
|
enum patty_ax25_frame_type type,
|
||||||
int flag) {
|
int flag) {
|
||||||
|
@ -719,16 +730,14 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock,
|
||||||
size_t len) {
|
size_t len) {
|
||||||
uint16_t control;
|
uint16_t control;
|
||||||
|
|
||||||
if (sock->type == PATTY_AX25_SOCK_RAW) {
|
|
||||||
return patty_ax25_if_send(sock->iface, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sock->mode == PATTY_AX25_SOCK_DM) {
|
if (sock->mode == PATTY_AX25_SOCK_DM) {
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
|
|
||||||
goto error_invalid_mode;
|
goto error_invalid_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (sock->type) {
|
||||||
|
case PATTY_AX25_SOCK_STREAM:
|
||||||
control = control_i(sock, 0);
|
control = control_i(sock, 0);
|
||||||
|
|
||||||
if (frame_send(sock, PATTY_AX25_FRAME_COMMAND, control, buf, len) < 0) {
|
if (frame_send(sock, PATTY_AX25_FRAME_COMMAND, control, buf, len) < 0) {
|
||||||
|
@ -737,6 +746,21 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock,
|
||||||
|
|
||||||
patty_ax25_sock_vs_incr(sock);
|
patty_ax25_sock_vs_incr(sock);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PATTY_AX25_SOCK_DGRAM:
|
||||||
|
control = control_ui(0);
|
||||||
|
|
||||||
|
if (frame_send(sock, PATTY_AX25_FRAME_COMMAND, control, buf, len) < 0) {
|
||||||
|
goto error_frame_send;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PATTY_AX25_SOCK_RAW:
|
||||||
|
return patty_ax25_if_send(sock->iface, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
error_frame_send:
|
error_frame_send:
|
||||||
|
|
Loading…
Add table
Reference in a new issue