diff options
| author | Harald Welte <laforge@gnumonks.org> | 2018-05-01 18:11:02 +0200 | 
|---|---|---|
| committer | Harald Welte <laforge@gnumonks.org> | 2018-05-08 18:53:38 +0000 | 
| commit | 1284c3e96170b1622106097e944e07354549bb2e (patch) | |
| tree | ef6e9485685241b2c6cab7e8f8c6293c443a1a19 /src | |
| parent | dda1d4511c7456b4ee58448dfa5979118d878d75 (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')
| -rw-r--r-- | src/gsm/lapdm.c | 45 | 
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; | 
