diff --git a/src/sock.c b/src/sock.c index 9970a4b..820d27b 100644 --- a/src/sock.c +++ b/src/sock.c @@ -61,7 +61,7 @@ static inline size_t tx_slots(patty_ax25_sock *sock) { } static inline size_t tx_slot_size(patty_ax25_sock *sock) { - return sizeof(struct slot) + PATTY_AX25_FRAME_OVERHEAD + sock->n_maxlen_tx; + return sizeof(struct slot) + sock->n_maxlen_tx; } static inline size_t tx_slots_size(patty_ax25_sock *sock) { @@ -79,8 +79,13 @@ static inline struct slot *tx_slot(patty_ax25_sock *sock, int seq) { ((uint8_t *)sock->tx_slots + (i * tx_slot_size(sock))); } -static inline void *tx_slot_buf(patty_ax25_sock *sock, int seq) { - return (uint8_t *)tx_slot(sock, seq) + sizeof(struct slot); +static inline void tx_slot_save(patty_ax25_sock *sock, void *buf, size_t len) { + struct slot *slot = tx_slot(sock, sock->vs); + + slot->len = len; + slot->ack = 0; + + memcpy(slot + 1, buf, len); } static int init_bufs(patty_ax25_sock *sock) { @@ -638,6 +643,52 @@ error_invalid_type: return -1; } +static inline uint16_t control_i(patty_ax25_sock *sock, int ns, int flag) { + switch (sock->mode) { + case PATTY_AX25_SOCK_SABM: + return ((sock->vr & 0x07) << 5) + | (( ns & 0x07) << 1) + | (flag << 4); + + case PATTY_AX25_SOCK_SABME: + return ((sock->vr & 0x7f) << 9) + | (( ns & 0x7f) << 1) + | (flag << 8); + + default: + return 0; + } +} + +static inline uint16_t control_ui(int flag) { + return PATTY_AX25_FRAME_UI | (flag << 4); +} + +static inline uint16_t control_s(patty_ax25_sock *sock, + enum patty_ax25_frame_type type, + int flag) { + switch (sock->mode) { + case PATTY_AX25_SOCK_SABM: + return ((sock->vr & 0x07) << 5) + | (type & 0x0f) + | (flag << 4); + + case PATTY_AX25_SOCK_SABME: + return ((sock->vr & 0x7f) << 9) + | (type & 0x0f) + | (flag << 8); + + default: + return 0; + } +} + +static inline uint16_t control_u(enum patty_ax25_frame_type type, + int pf) { + return (type & PATTY_AX25_FRAME_U_MASK) + | (pf << 4); +} + static ssize_t frame_send(patty_ax25_sock *sock, enum patty_ax25_frame_cr cr, uint16_t control, @@ -647,8 +698,7 @@ static ssize_t frame_send(patty_ax25_sock *sock, size_t offset = 0; ssize_t encoded; - uint8_t *buf = PATTY_AX25_FRAME_CONTROL_I(control)? - tx_slot_buf(sock, sock->vs): sock->tx_buf; + uint8_t *buf = sock->tx_buf; if (sock->iface == NULL) { errno = ENETDOWN; @@ -686,13 +736,6 @@ static ssize_t frame_send(patty_ax25_sock *sock, memcpy(buf + offset, info, infolen); offset += infolen; - - if (PATTY_AX25_FRAME_CONTROL_I(control)) { - struct slot *slot = tx_slot(sock, sock->vs); - - slot->len = offset; - slot->ack = 0; - } } return patty_ax25_if_send(sock->iface, buf, offset); @@ -707,7 +750,12 @@ error_noif: ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, int seq) { struct slot *slot = tx_slot(sock, seq); - return slot->len > 0? patty_ax25_if_send(sock->iface, slot + 1, slot->len): 0; + return slot->len > 0? frame_send(sock, + PATTY_AX25_FRAME_COMMAND, + control_i(sock, seq, 0), + sock->proto, + slot + 1, + slot->len): 0; } ssize_t patty_ax25_sock_resend_pending(patty_ax25_sock *sock) { @@ -772,52 +820,6 @@ int patty_ax25_sock_ack_pending(patty_ax25_sock *sock) { return ret; } -static uint16_t control_i(patty_ax25_sock *sock, int flag) { - switch (sock->mode) { - case PATTY_AX25_SOCK_SABM: - return ((sock->vr & 0x07) << 5) - | ((sock->vs & 0x07) << 1) - | (flag << 4); - - case PATTY_AX25_SOCK_SABME: - return ((sock->vr & 0x7f) << 9) - | ((sock->vs & 0x7f) << 1) - | (flag << 8); - - default: - return 0; - } -} - -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) { - switch (sock->mode) { - case PATTY_AX25_SOCK_SABM: - return ((sock->vr & 0x07) << 5) - | (type & 0x0f) - | (flag << 4); - - case PATTY_AX25_SOCK_SABME: - return ((sock->vr & 0x7f) << 9) - | (type & 0x0f) - | (flag << 8); - - default: - return 0; - } -} - -static uint16_t control_u(enum patty_ax25_frame_type type, - int pf) { - return (type & PATTY_AX25_FRAME_U_MASK) - | (pf << 4); -} - ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock, enum patty_ax25_frame_cr cr, int pf) { @@ -968,8 +970,7 @@ static ssize_t write_segmented(patty_ax25_sock *sock, } while (segments--) { - uint8_t *dest = (uint8_t *)sock->tx_buf; - + uint8_t *dest = (uint8_t *)sock->tx_buf; uint8_t header = (uint8_t)(segments & 0xff); size_t copylen = segments == 0? @@ -979,7 +980,7 @@ static ssize_t write_segmented(patty_ax25_sock *sock, size_t o = 0; uint16_t control = sock->type == PATTY_AX25_SOCK_STREAM? - control_i(sock, 0): + control_i(sock, sock->vs, 0): control_ui(0); if (first) { @@ -994,6 +995,8 @@ static ssize_t write_segmented(patty_ax25_sock *sock, first = 0; } + tx_slot_save(sock, buf + i, copylen); + memcpy(dest + o, (uint8_t *)buf + i, copylen); i += copylen; @@ -1030,14 +1033,16 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, } switch (sock->type) { - case PATTY_AX25_SOCK_STREAM: + case PATTY_AX25_SOCK_STREAM:{ if (len > sock->n_maxlen_tx) { return write_segmented(sock, buf, len); } + tx_slot_save(sock, buf, len); + if (frame_send(sock, PATTY_AX25_FRAME_COMMAND, - control_i(sock, 0), + control_i(sock, sock->vs, 0), sock->proto, buf, len) < 0) { @@ -1047,6 +1052,7 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, patty_ax25_sock_vs_incr(sock); break; + } case PATTY_AX25_SOCK_DGRAM: if (len > sock->n_maxlen_tx) {