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_UI = 0x03,
|
||||
PATTY_AX25_FRAME_XID = 0xaf,
|
||||
PATTY_AX25_FRAME_TEST = 0xe3,
|
||||
PATTY_AX25_FRAME_UNKNOWN = 0xff
|
||||
PATTY_AX25_FRAME_TEST = 0xe3
|
||||
};
|
||||
|
||||
typedef struct _patty_ax25_frame {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
enum patty_ax25_sock_type {
|
||||
PATTY_AX25_SOCK_STREAM,
|
||||
PATTY_AX25_SOCK_DGRAM,
|
||||
PATTY_AX25_SOCK_RAW
|
||||
};
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ ssize_t patty_ax25_frame_decode_control(patty_ax25_frame *frame,
|
|||
frame->nr = 0;
|
||||
frame->ns = 0;
|
||||
frame->pf = 0;
|
||||
frame->type = PATTY_AX25_FRAME_UNKNOWN;
|
||||
frame->type = 0xff;
|
||||
frame->proto = PATTY_AX25_PROTO_UNKNOWN;
|
||||
frame->info = NULL;
|
||||
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));
|
||||
|
||||
sock->state = PATTY_AX25_SOCK_PENDING_CONNECT;
|
||||
|
||||
if (sock_save_remote(server, sock) < 0) {
|
||||
goto error_sock_save_remote;
|
||||
}
|
||||
|
@ -852,21 +850,34 @@ static int server_connect(patty_ax25_server *server,
|
|||
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
|
||||
* parameters.
|
||||
* Send an XID frame, to attempt to negotiate AX.25 v2.2 and its
|
||||
* default parameters.
|
||||
*/
|
||||
if (patty_ax25_sock_send_xid(sock, PATTY_AX25_FRAME_COMMAND) < 0) {
|
||||
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
|
||||
* will help us determine what version of AX.25 to apply for this socket,
|
||||
* or whether the peer is not accepting connections.
|
||||
* will help us determine what version of AX.25 to apply for this
|
||||
* socket, or whether the peer is not accepting connections.
|
||||
*/
|
||||
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_client_save_by_sock:
|
||||
|
@ -1396,6 +1407,17 @@ error_write:
|
|||
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,
|
||||
patty_ax25_if *iface,
|
||||
patty_ax25_sock *sock,
|
||||
|
@ -1690,6 +1712,7 @@ static int handle_frame(patty_ax25_server *server,
|
|||
|
||||
switch (frame.type) {
|
||||
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_RNR: return handle_rnr(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_DISC: return handle_disc(server, iface, sock, &frame);
|
||||
case PATTY_AX25_FRAME_FRMR: return handle_frmr(server, iface, sock, &frame);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
58
src/sock.c
58
src/sock.c
|
@ -111,26 +111,28 @@ error_realloc_tx_buf:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static patty_ax25_sock *init_raw(patty_ax25_sock *sock) {
|
||||
if (bind_pty(sock) < 0) {
|
||||
goto error_bind_pty;
|
||||
static patty_ax25_sock *init_dgram(patty_ax25_sock *sock,
|
||||
enum patty_ax25_proto proto) {
|
||||
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) {
|
||||
goto error_kiss_tnc_new_fd;
|
||||
}
|
||||
|
||||
sock->proto = PATTY_AX25_PROTO_NONE;
|
||||
sock->type = PATTY_AX25_SOCK_RAW;
|
||||
sock->state = PATTY_AX25_SOCK_ESTABLISHED;
|
||||
|
||||
return sock;
|
||||
|
||||
error_kiss_tnc_new_fd:
|
||||
(void)close(sock->fd);
|
||||
|
||||
error_bind_pty:
|
||||
free(sock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -144,11 +146,20 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto,
|
|||
|
||||
memset(sock, '\0', sizeof(*sock));
|
||||
|
||||
if (type == PATTY_AX25_SOCK_RAW) {
|
||||
return init_raw(sock);
|
||||
if (bind_pty(sock) < 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
sock->proto = proto;
|
||||
sock->type = type;
|
||||
|
@ -160,18 +171,14 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto,
|
|||
goto error_init_bufs;
|
||||
}
|
||||
|
||||
if (bind_pty(sock) < 0) {
|
||||
goto error_bind_pty;
|
||||
}
|
||||
|
||||
return sock;
|
||||
|
||||
error_bind_pty:
|
||||
error_init_bufs:
|
||||
if (sock->tx_slots) free(sock->tx_slots);
|
||||
if (sock->rx_buf) free(sock->rx_buf);
|
||||
if (sock->tx_buf) free(sock->tx_buf);
|
||||
|
||||
error_bind_pty:
|
||||
free(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,
|
||||
enum patty_ax25_frame_type type,
|
||||
int flag) {
|
||||
|
@ -719,16 +730,14 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock,
|
|||
size_t len) {
|
||||
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) {
|
||||
errno = EBADF;
|
||||
|
||||
goto error_invalid_mode;
|
||||
}
|
||||
|
||||
switch (sock->type) {
|
||||
case PATTY_AX25_SOCK_STREAM:
|
||||
control = control_i(sock, 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);
|
||||
|
||||
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;
|
||||
|
||||
error_frame_send:
|
||||
|
|
Loading…
Add table
Reference in a new issue