Change in libosmocore[master]: gsm: Introduce API osmo_gsm48_rest_octets_si13_decode

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Thu Feb 18 00:54:33 UTC 2021


laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/22800 )

Change subject: gsm: Introduce API osmo_gsm48_rest_octets_si13_decode
......................................................................

gsm: Introduce API osmo_gsm48_rest_octets_si13_decode

Related: SYS#5358
Change-Id: I74fb0a3afc1ac4aadbfc609b882d929401f790eb
---
M include/osmocom/gsm/gsm48_rest_octets.h
M src/gsm/gsm48_rest_octets.c
M src/gsm/libosmogsm.map
M tests/Makefile.am
A tests/gsm48/rest_octets_test.c
A tests/gsm48/rest_octets_test.ok
M tests/testsuite.at
7 files changed, 249 insertions(+), 1 deletion(-)

Approvals:
  laforge: Looks good to me, approved
  daniel: Looks good to me, approved
  fixeria: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/include/osmocom/gsm/gsm48_rest_octets.h b/include/osmocom/gsm/gsm48_rest_octets.h
index 8f143be..f295824 100644
--- a/include/osmocom/gsm/gsm48_rest_octets.h
+++ b/include/osmocom/gsm/gsm48_rest_octets.h
@@ -120,7 +120,8 @@
 	uint8_t prio_acc_thr;
 };
 
-/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */
+/* Parse/Generate SI13 Rest Octests (Chapter 10.5.2.37b) */
+int osmo_gsm48_rest_octets_si13_decode(struct osmo_gsm48_si13_info *si13, const uint8_t *data);
 int osmo_gsm48_rest_octets_si13_encode(uint8_t *data, const struct osmo_gsm48_si13_info *si13);
 
 /* Parse SI3 Rest Octets */
diff --git a/src/gsm/gsm48_rest_octets.c b/src/gsm/gsm48_rest_octets.c
index 1bab8e0..77fd349 100644
--- a/src/gsm/gsm48_rest_octets.c
+++ b/src/gsm/gsm48_rest_octets.c
@@ -749,6 +749,119 @@
 	return bv.data_len;
 }
 
+
+static unsigned int decode_t3192(unsigned int t3192)
+{
+	/* See also 3GPP TS 44.060
+	   Table 12.24.2: GPRS Cell Options information element details */
+	static const unsigned int decode_t3192_tbl[8] = {500, 1000, 1500, 0, 80, 120, 160, 200};
+	OSMO_ASSERT(t3192 <= 7);
+	return decode_t3192_tbl[t3192];
+}
+
+static unsigned int decode_drx_timer(unsigned int drx)
+{
+	static const unsigned int decode_drx_timer_tbl[8] = {0, 1, 2, 4, 8, 16, 32, 64};
+	OSMO_ASSERT(drx <= 7);
+	return decode_drx_timer_tbl[drx];
+}
+
+static int decode_gprs_cell_opt(struct osmo_gprs_cell_options *gco, struct bitvec *bv)
+{
+	gco->nmo = bitvec_get_uint(bv, 2);
+	gco->t3168 = (bitvec_get_uint(bv, 3) + 1) * 500;
+	gco->t3192 = decode_t3192(bitvec_get_uint(bv, 3));
+	gco->drx_timer_max = decode_drx_timer(bitvec_get_uint(bv, 3));
+
+	/* ACCESS_BURST_TYPE: */
+	bitvec_get_uint(bv, 1);
+	/* CONTROL_ACK_TYPE: */
+	gco->ctrl_ack_type_use_block = bitvec_get_uint(bv, 1);
+	gco->bs_cv_max = bitvec_get_uint(bv, 4);
+
+	if (bitvec_get_uint(bv, 1)) {
+		bitvec_get_uint(bv, 3);	/* DEC */
+		bitvec_get_uint(bv, 3);	/* INC */
+		bitvec_get_uint(bv, 3);	/* MAX */
+	}
+
+	if (bitvec_get_uint(bv, 1)) {
+		int ext_len = bitvec_get_uint(bv, 6);
+		if (ext_len < 0)
+			return ext_len;
+		unsigned int cur_bit = bv->cur_bit;
+		/* Extension Information */
+		/* R99 extension: */
+		gco->ext_info.egprs_supported = bitvec_get_uint(bv, 1);
+		if (gco->ext_info.egprs_supported) {
+			gco->ext_info.use_egprs_p_ch_req = !bitvec_get_uint(bv, 1);
+			gco->ext_info.bep_period = bitvec_get_uint(bv, 4);
+		}
+		gco->ext_info.pfc_supported = bitvec_get_uint(bv, 1);
+		gco->ext_info.dtm_supported = bitvec_get_uint(bv, 1);
+		gco->ext_info.bss_paging_coordination = bitvec_get_uint(bv, 1);
+		/* REL-4 extension: */
+		gco->ext_info.ccn_active = bitvec_get_uint(bv, 1);
+		bitvec_get_uint(bv, 1); /* NW_EXT_UTBF */
+		bv->cur_bit = cur_bit + ext_len + 1;
+	}
+	return 0;
+}
+
+static void decode_gprs_pwr_ctrl_pars(struct osmo_gprs_power_ctrl_pars *pcp, struct bitvec *bv)
+{
+	pcp->alpha = bitvec_get_uint(bv, 4);
+	pcp->t_avg_w = bitvec_get_uint(bv,5);
+	pcp->t_avg_t = bitvec_get_uint(bv, 5);
+	pcp->pc_meas_chan = bitvec_get_uint(bv, 1);
+	pcp->n_avg_i = bitvec_get_uint(bv, 4);
+}
+
+/*! Decode SI13 Rest Octests (04.08 Chapter 10.5.2.37b).
+ *  \param[out] si13 decoded SI13 rest octets
+ *  \param[in] encoded SI13 rest octets
+ *  \returns parsed bits on success, negative on error */
+int osmo_gsm48_rest_octets_si13_decode(struct osmo_gsm48_si13_info *si13, const uint8_t *data)
+{
+	struct osmo_gprs_cell_options *co = &si13->cell_opts;
+	struct osmo_gprs_power_ctrl_pars *pcp = &si13->pwr_ctrl_pars;
+	struct bitvec bv;
+	int rc;
+
+	memset(&bv, 0, sizeof(bv));
+	bv.data = (uint8_t *) data;
+	bv.data_len = 20;
+
+	memset(si13, 0, sizeof(*si13));
+
+
+	if (bitvec_get_bit_high(&bv) == H) {
+		si13->bcch_change_mark = bitvec_get_uint(&bv, 3);
+		si13->si_change_field = bitvec_get_uint(&bv, 4);
+		if (bitvec_get_uint(&bv, 1)) {
+			si13->bcch_change_mark = bitvec_get_uint(&bv, 2);
+			/* FIXME: implement parsing GPRS Mobile Allocation IE */
+			return -ENOTSUP;
+		}
+		if (bitvec_get_uint(&bv, 1)) {
+			/* PBCCH present in cell */
+			/* FIXME: parse not implemented */
+			return -ENOTSUP;
+		} else {
+			/* PBCCH not present in cell */
+			si13->rac = bitvec_get_uint(&bv, 8);
+			si13->spgc_ccch_sup = bitvec_get_uint(&bv, 1);
+			si13->prio_acc_thr = bitvec_get_uint(&bv, 3);
+			si13->net_ctrl_ord = bitvec_get_uint(&bv, 2);
+			if ((rc = decode_gprs_cell_opt(co, &bv)) < 0)
+				return rc;
+
+			decode_gprs_pwr_ctrl_pars(pcp, &bv);
+		}
+	}
+	return bv.cur_bit;
+}
+
 /* GPRS Mobile Allocation as per TS 04.60 Chapter 12.10a:
    < GPRS Mobile Allocation IE > ::=
      < HSN : bit (6) >
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index efa23e6..0ea0678 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -320,6 +320,7 @@
 osmo_gsm48_rest_octets_si6_encode;
 osmo_gsm48_rest_octets_si3_encode;
 osmo_gsm48_rest_octets_si4_encode;
+osmo_gsm48_rest_octets_si13_decode;
 osmo_gsm48_rest_octets_si13_encode;
 osmo_gsm48_rest_octets_si3_decode;
 osmo_gsm48_rest_octets_si4_decode;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 10306aa..158bc69 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -42,6 +42,7 @@
 		 bsslap/bsslap_test					\
 		 bssmap_le/bssmap_le_test				\
 		 it_q/it_q_test						\
+		 gsm48/rest_octets_test					\
 		 $(NULL)
 
 if ENABLE_MSGFILE
@@ -139,6 +140,9 @@
 gsm0408_gsm0408_test_SOURCES = gsm0408/gsm0408_test.c
 gsm0408_gsm0408_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
 
+gsm48_rest_octets_test_SOURCES = gsm48/rest_octets_test.c
+gsm48_rest_octets_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+
 gprs_gprs_test_SOURCES = gprs/gprs_test.c
 gprs_gprs_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
 
@@ -399,6 +403,7 @@
 	     bsslap/bsslap_test.ok \
 	     bssmap_le/bssmap_le_test.ok \
 	     it_q/it_q_test.ok \
+	     gsm48/rest_octets_test.ok \
 	     $(NULL)
 
 if ENABLE_LIBSCTP
diff --git a/tests/gsm48/rest_octets_test.c b/tests/gsm48/rest_octets_test.c
new file mode 100644
index 0000000..beff6e4
--- /dev/null
+++ b/tests/gsm48/rest_octets_test.c
@@ -0,0 +1,120 @@
+/*
+ * (C) 2021 by sysmocom - s.m.f.c. GmbH <info at sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin at sysmocom.de>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/gsm48_rest_octets.h>
+
+struct si13_test {
+	const char *name;
+	const struct osmo_gsm48_si13_info si;
+	int enc_rc;
+	int dec_rc;
+	void (*post_dec_cb)(const struct si13_test *test, const struct osmo_gsm48_si13_info* dec);
+};
+
+void post_dec_cb_test_alpha(const struct si13_test *test, const struct osmo_gsm48_si13_info* dec)
+{
+	OSMO_ASSERT(test->si.pwr_ctrl_pars.alpha == dec->pwr_ctrl_pars.alpha);
+}
+
+static const struct si13_test test_si13_arr[] = {
+	{
+		.name = "test alpha",
+		.si = {
+			.cell_opts = {
+				.nmo 		= GPRS_NMO_II,
+				.t3168		= 2000,
+				.t3192		= 1500,
+				.drx_timer_max	= 3,
+				.bs_cv_max	= 15,
+				.ctrl_ack_type_use_block = true,
+				.ext_info_present = 0,
+				.ext_info = {
+					.egprs_supported = 1,
+					.use_egprs_p_ch_req = 1,
+					.bep_period = 5,
+					.pfc_supported = 0,
+					.dtm_supported = 0,
+					.bss_paging_coordination = 0,
+					.ccn_active = true,
+				},
+			},
+			.pwr_ctrl_pars = {
+				.alpha		= 5,
+				.t_avg_w	= 16,
+				.t_avg_t	= 16,
+				.pc_meas_chan	= 0,
+				.n_avg_i	= 8,
+			},
+			.bcch_change_mark	= 1,
+			.si_change_field	= 0,
+			.rac		= 0x03,
+			.spgc_ccch_sup 	= 0,
+			.net_ctrl_ord	= 0,
+			.prio_acc_thr	= 6,
+		},
+		.enc_rc = 20,
+		.dec_rc = 71,
+		.post_dec_cb = post_dec_cb_test_alpha,
+	},
+};
+
+static void test_si13()
+{
+	int i, rc;
+	uint8_t data[GSM_MACBLOCK_LEN];
+	struct osmo_gsm48_si13_info si13;
+
+	for (i = 0; i < ARRAY_SIZE(test_si13_arr); i++) {
+		memset(data, 0, sizeof(data));
+		rc = osmo_gsm48_rest_octets_si13_encode(data, &test_si13_arr[i].si);
+		if (rc >= 0) {
+			printf("si13_encode (%d): %s\n", rc, osmo_hexdump(data, rc));
+		} else {
+			printf("si13_encode failed (%d)\n", rc);
+		}
+		OSMO_ASSERT(rc == test_si13_arr[i].enc_rc);
+		if (rc <= 0)
+			continue;
+		memset(&si13, 0 , sizeof(si13));
+		rc = osmo_gsm48_rest_octets_si13_decode(&si13, data);
+		if (rc >= 0) {
+			printf("si13_decode (%d)\n", rc);
+		} else {
+			printf("si13_decode failed (%d)\n", rc);
+		}
+		OSMO_ASSERT(rc == test_si13_arr[i].dec_rc);
+		if (test_si13_arr[i].post_dec_cb) {
+			test_si13_arr[i].post_dec_cb(&test_si13_arr[i], &si13);
+		}
+	}
+}
+
+int main(int argc, char **argv)
+{
+	test_si13();
+
+	return EXIT_SUCCESS;
+}
diff --git a/tests/gsm48/rest_octets_test.ok b/tests/gsm48/rest_octets_test.ok
new file mode 100644
index 0000000..54204f2
--- /dev/null
+++ b/tests/gsm48/rest_octets_test.ok
@@ -0,0 +1,2 @@
+si13_encode (20): 90 00 d8 5a 6f c9 e5 84 10 ab 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 
+si13_decode (71)
diff --git a/tests/testsuite.at b/tests/testsuite.at
index d715a3e..d2a10dd 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -156,6 +156,12 @@
 AT_CHECK([$abs_top_builddir/tests/gsm0408/gsm0408_test], [0], [expout], [ignore])
 AT_CLEANUP
 
+AT_SETUP([gsm48_rest_octets])
+AT_KEYWORDS([gsm48_rest_octets])
+cat $abs_srcdir/gsm48/rest_octets_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/gsm48/rest_octets_test], [0], [expout], [ignore])
+AT_CLEANUP
+
 AT_SETUP([gprs])
 AT_KEYWORDS([gprs])
 cat $abs_srcdir/gprs/gprs_test.ok > expout

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

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I74fb0a3afc1ac4aadbfc609b882d929401f790eb
Gerrit-Change-Number: 22800
Gerrit-PatchSet: 4
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: osmith <osmith at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210218/f6d90e51/attachment.htm>


More information about the gerrit-log mailing list