aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2023-11-09 12:09:21 +0100
committerlaforge <laforge@osmocom.org>2023-11-15 21:28:22 +0000
commit1bb0b99552d3eecd5e20e58a228b92e2275de8aa (patch)
tree23c9a88409956ce8c13ed2c1db95ab29942d25db /src
parent913a783ff2a29e1803d6acfac89096431937cd16 (diff)
LAPD: Always update N(R) in pending TX frames if V(R) is incremented
The outcome of the update function is still used to indicate if an RR frame must be sent or not. Only if there is no I frame in the TX queue, RR frame must be sent. Related: OS#4074 Change-Id: I71676c709878105bfd18b9370fecc61b92796a6f
Diffstat (limited to 'src')
-rw-r--r--src/gsm/lapdm.c3
-rw-r--r--src/isdn/lapd_core.c16
2 files changed, 11 insertions, 8 deletions
diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c
index 86dc242c..43f5662d 100644
--- a/src/gsm/lapdm.c
+++ b/src/gsm/lapdm.c
@@ -658,7 +658,8 @@ static int update_pending_frames(struct lapd_msg_ctx *lctx)
LAPDm_CTRL_PF_BIT(msg->l2h[1]));
rc = 0;
} else if (LAPDm_CTRL_is_S(msg->l2h[1])) {
- LOGDL(dl, LOGL_ERROR, "Supervisory frame in queue, this shouldn't happen\n");
+ msg->l2h[1] = LAPDm_CTRL_S(dl->v_recv, LAPDm_CTRL_S_BITS(msg->l2h[1]),
+ LAPDm_CTRL_PF_BIT(msg->l2h[1]));
}
}
diff --git a/src/isdn/lapd_core.c b/src/isdn/lapd_core.c
index e352189a..57a02252 100644
--- a/src/isdn/lapd_core.c
+++ b/src/isdn/lapd_core.c
@@ -1525,6 +1525,7 @@ static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
uint8_t ns = lctx->n_send;
int length = lctx->length;
int rc;
+ bool i_frame_in_queue = false;
LOGDL(dl, LOGL_INFO, "I received in state %s on SAPI(%u)\n",
lapd_state_name(dl->state), lctx->sapi);
@@ -1615,6 +1616,13 @@ static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
dl->v_recv = inc_mod(dl->v_recv, dl->v_range);
LOGDL(dl, LOGL_INFO, "incrementing V(R) to %u\n", dl->v_recv);
+ /* Update all pending frames in the queue to the new V(R) state. */
+ if (dl->update_pending_frames) {
+ rc = dl->update_pending_frames(lctx);
+ if (!rc)
+ i_frame_in_queue = true;
+ }
+
/* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
lapd_acknowledge(lctx); /* V(A) is also set here */
@@ -1680,13 +1688,7 @@ static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
if (!dl->own_busy) {
/* NOTE: V(R) is already set above */
rc = lapd_send_i(dl, __LINE__, false);
-
- /* if update_pending_iframe returns 0 it updated
- * the lapd header of an iframe in the tx queue */
- if (rc && dl->update_pending_frames)
- rc = dl->update_pending_frames(lctx);
-
- if (rc) {
+ if (rc && !i_frame_in_queue) {
LOGDL(dl, LOGL_INFO, "we are not busy and have no pending data, "
"send RR\n");
/* Send RR with F=0 */