Change in ...libosmocore[master]: lapdm: Allow user to specify T200 values; Use correct N200 values

Harald Welte gerrit-no-reply at lists.osmocom.org
Sun Jun 2 19:38:28 UTC 2019


Harald Welte has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/14339


Change subject: lapdm: Allow user to specify T200 values; Use correct N200 values
......................................................................

lapdm: Allow user to specify T200 values; Use correct N200 values

TS 04.06 specifies a N200 re-transmission counter that depends on the
channel type, which we didn't care about at all so far.  Let's have the
caller tell us the channel type so we can internally look up the correct
N200 value for it.

At the same time, permit the user to specify T200 re-transmission timer
values for each SAPI on both DCCH and ACCH, which is required at least
in the BTS as per GSM TS 12.21.  Also, extend the timer resolution of
the API from seconds to milli-seconds, which is more applicable as
particularly on the FACCH the recommended values are in the 200ms range.

Change-Id: I90fdc4dd4720d4e02213197c894eb0a55a39158c
Related: OS#3906
Related: OS#2294
---
M include/osmocom/gsm/lapdm.h
M src/gsm/lapdm.c
M src/gsm/libosmogsm.map
3 files changed, 75 insertions(+), 12 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/39/14339/1

diff --git a/include/osmocom/gsm/lapdm.h b/include/osmocom/gsm/lapdm.h
index e01d065..fc51ae5 100644
--- a/include/osmocom/gsm/lapdm.h
+++ b/include/osmocom/gsm/lapdm.h
@@ -81,9 +81,14 @@
 struct lapdm_datalink *lapdm_datalink_for_sapi(struct lapdm_entity *le, uint8_t sapi);
 
 /* initialize a LAPDm entity */
-void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode, int t200);
-void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode);
-
+void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode, int t200)
+	OSMO_DEPRECATED("Use lapdm_entity_init2() instead");
+void lapdm_entity_init2(struct lapdm_entity *le, enum lapdm_mode mode,
+			const int *t200_ms, int n200);
+void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode)
+	OSMO_DEPRECATED("Use lapdm_channel_init2() instead");
+void lapdm_channel_init2(struct lapdm_channel *lc, enum lapdm_mode mode,
+			 const int *t200_ms_dcch, const int *t200_ms_acch, enum gsm_chan_t chan_t);
 /* deinitialize a LAPDm entity */
 void lapdm_entity_exit(struct lapdm_entity *le);
 void lapdm_channel_exit(struct lapdm_channel *lc);
diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c
index f1651d6..8fddb65 100644
--- a/src/gsm/lapdm.c
+++ b/src/gsm/lapdm.c
@@ -132,7 +132,7 @@
 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)
+			  struct lapdm_entity *entity, int t200_ms, uint32_t n200)
 {
 	memset(dl, 0, sizeof(*dl));
 	dl->entity = entity;
@@ -142,38 +142,94 @@
 	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.n200 = n200;
 	dl->dl.t203_sec = 0; dl->dl.t203_usec = 0;
-	dl->dl.t200_sec = t200; dl->dl.t200_usec = 0;
+	dl->dl.t200_sec = t200_ms / 1000; dl->dl.t200_usec = (t200_ms % 1000) * 1000;
 }
 
 /*! initialize a LAPDm entity and all datalinks inside
  *  \param[in] le LAPDm entity
  *  \param[in] mode \ref lapdm_mode (BTS/MS)
+ *  \param[in] t200 T200 re-transmission timer for all SAPIs in seconds
+ *
+ *  Don't use this function; It doesn't support different T200 values per API
+ *  and doesn't permit the caller to specify the N200 counter, both of which
+ *  are required by GSM specs and supported by lapdm_entity_init2().
  */
 void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode, int t200)
 {
+	/* convert from single full-second value to per-SAPI milli-second value */
+	int t200_ms_sapi_arr[_NR_DL_SAPI];
+	for (int i = 0; i < ARRAY_SIZE(t200_ms_sapi_arr); i++)
+		t200_ms_sapi_arr[i] = t200 * 1000;
+
+	return lapdm_entity_init2(le, mode, t200_ms_sapi_arr, N200);
+}
+
+/*! initialize a LAPDm entity and all datalinks inside
+ *  \param[in] le LAPDm entity
+ *  \param[in] mode \ref lapdm_mode (BTS/MS)
+ *  \param[in] t200_ms per-SAPI array of T200 re-transmission timer in milli-seconds
+ *  \param[in] n200 N200 re-transmisison count
+ */
+void lapdm_entity_init2(struct lapdm_entity *le, enum lapdm_mode mode,
+			const int *t200_ms, int n200)
+{
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(le->datalink); i++)
-		lapdm_dl_init(&le->datalink[i], le, t200);
+		lapdm_dl_init(&le->datalink[i], le, t200_ms[i], n200);
 
 	lapdm_entity_set_mode(le, mode);
 }
 
+static int get_n200_dcch(enum gsm_chan_t chan_t)
+{
+	switch (chan_t) {
+	case GSM_LCHAN_SDCCH:
+		return N200_TR_SDCCH;
+	case GSM_LCHAN_TCH_F:
+		return N200_TR_FACCH_FR;
+	case GSM_LCHAN_TCH_H:
+		return N200_TR_FACCH_HR;
+	default:
+		return -1;
+	}
+}
+
 /*! initialize a LAPDm channel and all its channels
  *  \param[in] lc \ref lapdm_channel to be initialized
  *  \param[in] mode \ref lapdm_mode (BTS/MS)
  *
- * This really is a convenience wrapper around calling \ref
- * lapdm_entity_init twice.
+ *  Don't use this function; It doesn't support different T200 values per API
+ *  and doesn't set the correct N200 counter, both of which
+ *  are required by GSM specs and supported by lapdm_channel_init2().
  */
 void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode)
 {
-	lapdm_entity_init(&lc->lapdm_acch, mode, 2);
+	/* emulate old backwards-compatible behavior with 1s/2s */
+	const int t200_ms_dcch[_NR_DL_SAPI] = { 1000, 1000 };
+	const int t200_ms_acch[_NR_DL_SAPI] = { 2000, 2000 };
+
+	lapdm_channel_init2(lc, mode, t200_ms_dcch, t200_ms_acch, GSM_LCHAN_SDCCH);
+}
+
+/*! initialize a LAPDm channel and all its channels
+ *  \param[in] lc \ref lapdm_channel to be initialized
+ *  \param[in] mode \ref lapdm_mode (BTS/MS)
+ *  \param[in] t200_ms_dcch per-SAPI array of T200 in milli-seconds for DCCH
+ *  \param[in] t200_ms_acch per-SAPI array of T200 in milli-seconds for SACCH
+ *  \param[in] chan_t GSM channel type (to correctly set N200)
+ */
+void lapdm_channel_init2(struct lapdm_channel *lc, enum lapdm_mode mode,
+			 const int *t200_ms_dcch, const int *t200_ms_acch, enum gsm_chan_t chan_t)
+{
+	int n200_dcch = get_n200_dcch(chan_t);
+
+	lapdm_entity_init2(&lc->lapdm_acch, mode, t200_ms_acch, N200_TR_SACCH);
 	lc->lapdm_acch.lapdm_ch = lc;
-	/* FIXME: this depends on chan type */
-	lapdm_entity_init(&lc->lapdm_dcch, mode, 1);
+
+	lapdm_entity_init2(&lc->lapdm_dcch, mode, t200_ms_dcch, n200_dcch);
 	lc->lapdm_dcch.lapdm_ch = lc;
 }
 
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index d49401d..646aec2 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -456,6 +456,7 @@
 
 lapdm_channel_exit;
 lapdm_channel_init;
+lapdm_channel_init2;
 lapdm_channel_reset;
 lapdm_channel_set_flags;
 lapdm_channel_set_l1;
@@ -464,6 +465,7 @@
 lapdm_datalink_for_sapi;
 lapdm_entity_exit;
 lapdm_entity_init;
+lapdm_entity_init2;
 lapdm_entity_reset;
 lapdm_entity_set_flags;
 lapdm_entity_set_mode;

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/14339
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I90fdc4dd4720d4e02213197c894eb0a55a39158c
Gerrit-Change-Number: 14339
Gerrit-PatchSet: 1
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190602/7ea777fd/attachment.html>


More information about the gerrit-log mailing list