Make patty_ax25_sock_resend() send with V(R)
Changes: * Make TX slots only large enough to hold the info field of an I frame; do not save header information * Fix issue wherein patty_ax25_sock_resend() would resend the N(R) value of an I frame as it was originally sent, even if this is incorrect for a given situation * Make control_i() in src/sock.c accept a V(S) sequence argument, as this can sometimes be independent of the socket current V(S) value * Declare control field functions as inline in src/sock.c
This commit is contained in:
parent
3db8c9cef3
commit
f41ce994f4
1 changed files with 70 additions and 64 deletions
134
src/sock.c
134
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) {
|
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) {
|
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)));
|
((uint8_t *)sock->tx_slots + (i * tx_slot_size(sock)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *tx_slot_buf(patty_ax25_sock *sock, int seq) {
|
static inline void tx_slot_save(patty_ax25_sock *sock, void *buf, size_t len) {
|
||||||
return (uint8_t *)tx_slot(sock, seq) + sizeof(struct slot);
|
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) {
|
static int init_bufs(patty_ax25_sock *sock) {
|
||||||
|
@ -638,6 +643,52 @@ error_invalid_type:
|
||||||
return -1;
|
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,
|
static ssize_t frame_send(patty_ax25_sock *sock,
|
||||||
enum patty_ax25_frame_cr cr,
|
enum patty_ax25_frame_cr cr,
|
||||||
uint16_t control,
|
uint16_t control,
|
||||||
|
@ -647,8 +698,7 @@ static ssize_t frame_send(patty_ax25_sock *sock,
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
ssize_t encoded;
|
ssize_t encoded;
|
||||||
|
|
||||||
uint8_t *buf = PATTY_AX25_FRAME_CONTROL_I(control)?
|
uint8_t *buf = sock->tx_buf;
|
||||||
tx_slot_buf(sock, sock->vs): sock->tx_buf;
|
|
||||||
|
|
||||||
if (sock->iface == NULL) {
|
if (sock->iface == NULL) {
|
||||||
errno = ENETDOWN;
|
errno = ENETDOWN;
|
||||||
|
@ -686,13 +736,6 @@ static ssize_t frame_send(patty_ax25_sock *sock,
|
||||||
memcpy(buf + offset, info, infolen);
|
memcpy(buf + offset, info, infolen);
|
||||||
|
|
||||||
offset += 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);
|
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) {
|
ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, int seq) {
|
||||||
struct slot *slot = tx_slot(sock, 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) {
|
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;
|
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,
|
ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock,
|
||||||
enum patty_ax25_frame_cr cr,
|
enum patty_ax25_frame_cr cr,
|
||||||
int pf) {
|
int pf) {
|
||||||
|
@ -968,8 +970,7 @@ static ssize_t write_segmented(patty_ax25_sock *sock,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (segments--) {
|
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);
|
uint8_t header = (uint8_t)(segments & 0xff);
|
||||||
|
|
||||||
size_t copylen = segments == 0?
|
size_t copylen = segments == 0?
|
||||||
|
@ -979,7 +980,7 @@ static ssize_t write_segmented(patty_ax25_sock *sock,
|
||||||
size_t o = 0;
|
size_t o = 0;
|
||||||
|
|
||||||
uint16_t control = sock->type == PATTY_AX25_SOCK_STREAM?
|
uint16_t control = sock->type == PATTY_AX25_SOCK_STREAM?
|
||||||
control_i(sock, 0):
|
control_i(sock, sock->vs, 0):
|
||||||
control_ui(0);
|
control_ui(0);
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
|
@ -994,6 +995,8 @@ static ssize_t write_segmented(patty_ax25_sock *sock,
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tx_slot_save(sock, buf + i, copylen);
|
||||||
|
|
||||||
memcpy(dest + o, (uint8_t *)buf + i, copylen);
|
memcpy(dest + o, (uint8_t *)buf + i, copylen);
|
||||||
|
|
||||||
i += copylen;
|
i += copylen;
|
||||||
|
@ -1030,14 +1033,16 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sock->type) {
|
switch (sock->type) {
|
||||||
case PATTY_AX25_SOCK_STREAM:
|
case PATTY_AX25_SOCK_STREAM:{
|
||||||
if (len > sock->n_maxlen_tx) {
|
if (len > sock->n_maxlen_tx) {
|
||||||
return write_segmented(sock, buf, len);
|
return write_segmented(sock, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tx_slot_save(sock, buf, len);
|
||||||
|
|
||||||
if (frame_send(sock,
|
if (frame_send(sock,
|
||||||
PATTY_AX25_FRAME_COMMAND,
|
PATTY_AX25_FRAME_COMMAND,
|
||||||
control_i(sock, 0),
|
control_i(sock, sock->vs, 0),
|
||||||
sock->proto,
|
sock->proto,
|
||||||
buf,
|
buf,
|
||||||
len) < 0) {
|
len) < 0) {
|
||||||
|
@ -1047,6 +1052,7 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock,
|
||||||
patty_ax25_sock_vs_incr(sock);
|
patty_ax25_sock_vs_incr(sock);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case PATTY_AX25_SOCK_DGRAM:
|
case PATTY_AX25_SOCK_DGRAM:
|
||||||
if (len > sock->n_maxlen_tx) {
|
if (len > sock->n_maxlen_tx) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue