summaryrefslogtreecommitdiffstats
path: root/src/gsm/lapdm.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2018-05-01 18:11:02 +0200
committerHarald Welte <laforge@gnumonks.org>2018-05-08 18:53:38 +0000
commit1284c3e96170b1622106097e944e07354549bb2e (patch)
treeef6e9485685241b2c6cab7e8f8c6293c443a1a19 /src/gsm/lapdm.c
parentdda1d4511c7456b4ee58448dfa5979118d878d75 (diff)
lapdm: Implement SABM related constraints
* MO SAPI0 establishment *must always* have L3 payload for contention resolution * SAPI3 establishment *must never* use contention resolution * MT establish must never use contention resolution Change-Id: I8c2c103cdc7f9a45d7b2080c572f559fc3db58e4 Closes: OS#2370
Diffstat (limited to 'src/gsm/lapdm.c')
-rw-r--r--src/gsm/lapdm.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c
index ae21ccdf..1e81bff7 100644
--- a/src/gsm/lapdm.c
+++ b/src/gsm/lapdm.c
@@ -48,6 +48,8 @@
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/protocol/gsm_08_58.h>
+#define LAPD_U_SABM 0x7
+
/* TS 04.06 Figure 4 / Section 3.2 */
#define LAPDm_LPD_NORMAL 0
#define LAPDm_LPD_SMSCB 1
@@ -537,6 +539,42 @@ static int update_pending_frames(struct lapd_msg_ctx *lctx)
return rc;
}
+/* determine if receiving a given LAPDm message is not permitted */
+static int lapdm_rx_not_permitted(const struct lapdm_entity *le,
+ const struct lapd_msg_ctx *lctx)
+{
+ /* we currently only implement SABM related checks here */
+ if (lctx->format != LAPD_FORM_U || lctx->s_u != LAPD_U_SABM)
+ return 0;
+
+ if (le->mode == LAPDM_MODE_BTS) {
+ if (le == &le->lapdm_ch->lapdm_acch) {
+ /* no contention resolution on SACCH */
+ if (lctx->length > 0)
+ return RLL_CAUSE_SABM_INFO_NOTALL;
+ } else {
+ switch (lctx->sapi) {
+ case 0:
+ /* SAPI0 must use contention resolution, i.e. L3 payload must exist */
+ if (lctx->length == 0)
+ return RLL_CAUSE_UFRM_INC_PARAM;
+ break;
+ case 3:
+ /* SAPI3 doesn't support contention resolution */
+ if (lctx->length > 0)
+ return RLL_CAUSE_SABM_INFO_NOTALL;
+ break;
+ }
+ }
+ } else if (le->mode == LAPDM_MODE_MS) {
+ /* contention resolution (L3 present) is only sent by MS, but
+ * never received by it */
+ if (lctx->length > 0)
+ return RLL_CAUSE_SABM_INFO_NOTALL;
+ }
+ return 0;
+}
+
/* 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)
@@ -674,6 +712,13 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le,
}
/* store context for messages from lapd */
memcpy(&mctx.dl->mctx, &mctx, sizeof(mctx.dl->mctx));
+ rc =lapdm_rx_not_permitted(le, &lctx);
+ if (rc > 0) {
+ LOGP(DLLAPD, LOGL_NOTICE, "received message not permitted");
+ msgb_free(msg);
+ rsl_rll_error(rc, &mctx);
+ return -EINVAL;
+ }
/* send to LAPD */
rc = lapd_ph_data_ind(msg, &lctx);
break;