From 55405fb40b080b303dcbb380ecb2d738dc8f6206 Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Wed, 26 Mar 2014 13:45:17 +0100 Subject: lapdm: Make lapdm_datalink_for_sapi public This API allows you to get the lapdm_datalink for a SAPI. It's needed in the lapdm_test, so make it public. --- src/gsm/lapdm.c | 6 +++--- src/gsm/libosmogsm.map | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/gsm') diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c index 41f4be71..4edae633 100644 --- a/src/gsm/lapdm.c +++ b/src/gsm/lapdm.c @@ -181,7 +181,7 @@ void lapdm_channel_exit(struct lapdm_channel *lc) lapdm_entity_exit(&lc->lapdm_dcch); } -static struct lapdm_datalink *datalink_for_sapi(struct lapdm_entity *le, uint8_t sapi) +struct lapdm_datalink *lapdm_datalink_for_sapi(struct lapdm_entity *le, uint8_t sapi) { switch (sapi) { case LAPDm_SAPI_NORMAL: @@ -543,7 +543,7 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, } } - mctx.dl = datalink_for_sapi(le, sapi); + mctx.dl = lapdm_datalink_for_sapi(le, sapi); /* G.2.1 No action on frames containing an unallocated SAPI. */ if (!mctx.dl) { LOGP(DLLAPD, LOGL_NOTICE, "Received frame for unsupported " @@ -1071,7 +1071,7 @@ static int rslms_rx_rll(struct msgb *msg, struct lapdm_channel *lc) /* G.2.1 No action shall be taken on frames containing an unallocated * SAPI. */ - dl = datalink_for_sapi(le, sapi); + dl = lapdm_datalink_for_sapi(le, sapi); if (!dl) { LOGP(DLLAPD, LOGL_ERROR, "No instance for SAPI %d!\n", sapi); msgb_free(msg); diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 9d15d668..3c5025df 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -172,6 +172,7 @@ lapdm_channel_set_flags; lapdm_channel_set_l1; lapdm_channel_set_l3; lapdm_channel_set_mode; +lapdm_datalink_for_sapi; lapdm_entity_exit; lapdm_entity_init; lapdm_entity_reset; -- cgit v1.2.3 From 3dc4e16786d1e5723e76ad7c70ad54134957f9e5 Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Thu, 20 Mar 2014 19:24:48 +0100 Subject: gsm/lapdm: Prevent LAPD tx_queue from filling up in polling mode If LAPDm receives an I-Frame while there already is an I-Frame in the tx_queue the code generates an additional RR (to acknowledge the received I-Frame). Instead, N(R) of the I-Frame in the tx_queue should be updated to ACK the data. --- src/gsm/lapd_core.c | 6 ++++++ src/gsm/lapdm.c | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) (limited to 'src/gsm') diff --git a/src/gsm/lapd_core.c b/src/gsm/lapd_core.c index ef1d22a7..8c5fe9c6 100644 --- a/src/gsm/lapd_core.c +++ b/src/gsm/lapd_core.c @@ -1607,6 +1607,12 @@ 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(lctx, __LINE__); + + /* 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) { LOGP(DLLAPD, LOGL_INFO, "we are not busy and " "have no pending data, send RR\n"); diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c index 4edae633..698f8502 100644 --- a/src/gsm/lapdm.c +++ b/src/gsm/lapdm.c @@ -114,6 +114,7 @@ enum lapdm_format { static int lapdm_send_ph_data_req(struct lapd_msg_ctx *lctx, struct msgb *msg); static int send_rslms_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx); +static int update_pending_frames(struct lapd_msg_ctx *lctx); static void lapdm_dl_init(struct lapdm_datalink *dl, struct lapdm_entity *entity, int t200) @@ -124,6 +125,7 @@ static void lapdm_dl_init(struct lapdm_datalink *dl, dl->dl.reestablish = 0; /* GSM uses no reestablish */ dl->dl.send_ph_data_req = lapdm_send_ph_data_req; dl->dl.send_dlsap = send_rslms_dlsap; + dl->dl.update_pending_frames = update_pending_frames; dl->dl.n200_est_rel = N200_EST_REL; dl->dl.n200 = N200; dl->dl.t203_sec = 0; dl->dl.t203_usec = 0; @@ -488,6 +490,25 @@ static int lapdm_send_ph_data_req(struct lapd_msg_ctx *lctx, struct msgb *msg) 23); } +static int update_pending_frames(struct lapd_msg_ctx *lctx) +{ + struct lapd_datalink *dl = lctx->dl; + struct msgb *msg; + int rc = -1; + + llist_for_each_entry(msg, &dl->tx_queue, list) { + if (LAPDm_CTRL_is_I(msg->l2h[1])) { + msg->l2h[1] = LAPDm_CTRL_I(dl->v_recv, LAPDm_CTRL_I_Ns(msg->l2h[1]), + LAPDm_CTRL_PF_BIT(msg->l2h[1])); + rc = 0; + } else if (LAPDm_CTRL_is_S(msg->l2h[1])) { + LOGP(DLLAPD, LOGL_ERROR, "Supervisory frame in queue, this shouldn't happen\n"); + } + } + + return rc; +} + /* input into layer2 (from layer 1) */ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, uint8_t chan_nr, uint8_t link_id) -- cgit v1.2.3