aboutsummaryrefslogtreecommitdiffstats
path: root/src/isdn/lapd_core.c
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2023-11-09 12:03:04 +0100
committerlaforge <laforge@osmocom.org>2023-11-15 21:28:22 +0000
commit913a783ff2a29e1803d6acfac89096431937cd16 (patch)
tree998cdd82851f8ad423184aee318c1f99e22171fa /src/isdn/lapd_core.c
parentcc63aae03077f382fd674e18a51884524f055082 (diff)
LAPD: Flush TX queue, if remote peer enters busy condition or rejects
In case of a busy condition or a reject (sequence error) from the remove peer, the messages in the TX queue are obsolete and will be flushed. Related: OS#4074 Change-Id: Iaaf9aaabb958ef889e252ddd0026ff82cfac981f
Diffstat (limited to 'src/isdn/lapd_core.c')
-rw-r--r--src/isdn/lapd_core.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/isdn/lapd_core.c b/src/isdn/lapd_core.c
index be45a955..e352189a 100644
--- a/src/isdn/lapd_core.c
+++ b/src/isdn/lapd_core.c
@@ -169,12 +169,17 @@ static void lapd_dl_flush_hist(struct lapd_datalink *dl)
}
}
-static void lapd_dl_flush_tx(struct lapd_datalink *dl)
+static void lapd_dl_flush_tx_queue(struct lapd_datalink *dl)
{
struct msgb *msg;
while ((msg = msgb_dequeue(&dl->tx_queue)))
msgb_free(msg);
+}
+
+static void lapd_dl_flush_tx(struct lapd_datalink *dl)
+{
+ lapd_dl_flush_tx_queue(dl);
lapd_dl_flush_hist(dl);
}
@@ -1376,6 +1381,10 @@ static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
/* 5.5.5 */
/* Set peer receiver busy condition */
dl->peer_busy = 1;
+ /* Flush pending messages in TX queue. */
+ lapd_dl_flush_tx_queue(dl);
+ /* stop Timer T200 */
+ lapd_stop_t200(dl);
if (lctx->p_f) {
if (lctx->cr == dl->cr.rem2loc.cmd) {
@@ -1416,6 +1425,8 @@ static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
dl->peer_busy = 0;
/* V(S) and V(A) to the N(R) in the REJ frame */
dl->v_send = dl->v_ack = lctx->n_recv;
+ /* Flush pending messages in TX queue. */
+ lapd_dl_flush_tx_queue(dl);
/* stop Timer T200 */
lapd_stop_t200(dl);
/* 5.5.3.2 */
@@ -1452,6 +1463,8 @@ static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
dl->peer_busy = 0;
/* V(S) and V(A) to the N(R) in the REJ frame */
dl->v_send = dl->v_ack = lctx->n_recv;
+ /* Flush pending messages in TX queue. */
+ lapd_dl_flush_tx_queue(dl);
/* stop Timer T200 */
lapd_stop_t200(dl);
/* 5.5.7 Clear timer recovery condition */
@@ -1461,6 +1474,8 @@ static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
dl->peer_busy = 0;
/* V(S) and V(A) to the N(R) in the REJ frame */
dl->v_send = dl->v_ack = lctx->n_recv;
+ /* Flush pending messages in TX queue. */
+ lapd_dl_flush_tx_queue(dl);
/* 5.5.3.2 */
if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
if (!dl->own_busy && !dl->seq_err_cond) {