Change in libosmocore[master]: (WIP) libosmogsm: introduce message definition and verification helpers

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/.

Vadim Yanitskiy gerrit-no-reply at lists.osmocom.org
Wed Sep 26 22:55:56 UTC 2018


Vadim Yanitskiy has uploaded this change for review. ( https://gerrit.osmocom.org/11105


Change subject: (WIP) libosmogsm: introduce message definition and verification helpers
......................................................................

(WIP) libosmogsm: introduce message definition and verification helpers

Change-Id: Idef83b0c53b17503a64d7ab7422184ca4b60be57
---
M include/Makefile.am
A include/osmocom/gsm/tlv_msg_def.h
M src/gsm/Makefile.am
A src/gsm/tlv_msg_def.c
M tests/Makefile.am
M tests/testsuite.at
A tests/tlv/tlv_msg_def_test.c
A tests/tlv/tlv_msg_def_test.ok
8 files changed, 323 insertions(+), 2 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/05/11105/1

diff --git a/include/Makefile.am b/include/Makefile.am
index 19695d1..ec56054 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -121,6 +121,7 @@
                        osmocom/gsm/rxlev_stat.h \
                        osmocom/gsm/sysinfo.h \
                        osmocom/gsm/tlv.h \
+                       osmocom/gsm/tlv_msg_def.h \
 		       osmocom/sim/class_tables.h \
 		       osmocom/sim/sim.h
 
diff --git a/include/osmocom/gsm/tlv_msg_def.h b/include/osmocom/gsm/tlv_msg_def.h
new file mode 100644
index 0000000..b0c108e
--- /dev/null
+++ b/include/osmocom/gsm/tlv_msg_def.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <stdint.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/gsm/tlv.h>
+
+/*! \addtogroup tlv
+ *  @{
+ * \file tlv_msg_def.h */
+
+/*! Marks IE as optional / conditional */
+#define TLV_IE_FLAG_OPTIONAL		(1 << 0)
+/*! Marks IE as exclusive (i.e. this IE shall not repeat within a message) */
+#define TLV_IE_FLAG_EXCLUSIVE		(1 << 1)
+/*! Marks IE as complex (i.e. this IE may contain TLV-based payload itself) */
+#define TLV_IE_FLAG_COMPLEX		(1 << 2)
+
+/*! Definition of a single IE (Information Element) */
+struct tlv_ie_def {
+	/*! Unique IE identifier */
+	uint8_t iei;
+	/*! TLV type (e.g. T, TV, TvLV) */
+	struct tlv_def tlv_def;
+	/*! Meta info (see \ref TLV_IE_FLAG_*) */
+	uint8_t flags;
+};
+
+/*! Definition of a message group */
+struct tlv_msg_group_def {
+	/*! Human-readable name of a message group definition */
+	const char *name;
+	/*! The \ref value-string list of all possible message types */
+	const struct value_string *msg_names;
+	/*! The \ref value-string list of all possible IEs */
+	const struct value_string *iei_names;
+	/*! List of expected (mandatory and optional) IEs */
+	const struct tlv_ie_def *ie_defs[256];
+};
+
+/*! @} */
diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am
index 29299a6..25a7d5c 100644
--- a/src/gsm/Makefile.am
+++ b/src/gsm/Makefile.am
@@ -30,7 +30,8 @@
 			milenage/aes-internal.c milenage/aes-internal-enc.c \
 			milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \
 			gsup.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \
-			gsm23003.c mncc.c bts_features.c oap_client.c
+			gsm23003.c mncc.c bts_features.c oap_client.c \
+			tlv_msg_def.c
 libgsmint_la_LDFLAGS = -no-undefined
 libgsmint_la_LIBADD = $(top_builddir)/src/libosmocore.la
 
diff --git a/src/gsm/tlv_msg_def.c b/src/gsm/tlv_msg_def.c
new file mode 100644
index 0000000..1eae99c
--- /dev/null
+++ b/src/gsm/tlv_msg_def.c
@@ -0,0 +1,50 @@
+/*! \file tlv_msg_def.c
+ * Message definition and verification helpers */
+/*
+ * (C) 2018 by Vadim Yanitskiy <axilirator at gmail.com>
+ *
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdint.h>
+#include <errno.h>
+
+#include <osmocom/core/utils.h>
+
+#include <osmocom/gsm/tlv_msg_def.h>
+#include <osmocom/gsm/tlv.h>
+
+/*! \addtogroup tlv
+ *  @{
+ *  Osmocom message definition and verification helpers
+ *
+ *  In almost all of the TLV based protocols we deal with (OML, RSL,
+ *  BSSAP, RR/CC/MM/...) the specification of the individual messages
+ *  always includes a statement on which IEs are mandatory, which are
+ *  conditional, and which are optional.
+ *
+ *  This module provides the message definition helpers, which can be
+ *  used to implicitly describe and verify the structure of TLV-based
+ *  messages.
+ *
+ * \file tlv_msg_def.c */
+
+
+
+/*! @} */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 18d4bb4..201b2d4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -26,6 +26,7 @@
 		 codec/codec_ecu_fr_test timer/clk_override_test	\
 		 oap/oap_client_test					\
 		 logging/logging_vty_test				\
+		 tlv/tlv_msg_def_test					\
 		 $(NULL)
 
 if ENABLE_MSGFILE
@@ -179,6 +180,9 @@
 tlv_tlv_test_SOURCES = tlv/tlv_test.c
 tlv_tlv_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
 
+tlv_tlv_msg_def_test_SOURCES = tlv/tlv_msg_def_test.c
+tlv_tlv_msg_def_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+
 gsup_gsup_test_SOURCES = gsup/gsup_test.c
 gsup_gsup_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
 
@@ -274,7 +278,8 @@
 	     sercomm/sercomm_test.ok prbs/prbs_test.ok			\
 	     gsm23003/gsm23003_test.ok                                 \
 	     timer/clk_override_test.ok					\
-	     oap/oap_client_test.ok oap/oap_client_test.err
+	     oap/oap_client_test.ok oap/oap_client_test.err		\
+	     tlv/tlv_msg_def_test.ok
 
 DISTCLEANFILES = atconfig atlocal conv/gsm0503_test_vectors.c
 BUILT_SOURCES = conv/gsm0503_test_vectors.c
diff --git a/tests/testsuite.at b/tests/testsuite.at
index a1cf98a..1a5b96a 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -253,6 +253,12 @@
 AT_CHECK([$abs_top_builddir/tests/tlv/tlv_test], [0], [expout], [ignore])
 AT_CLEANUP
 
+AT_SETUP([tlv_msg_def])
+AT_KEYWORDS([tlv_msg_def])
+cat $abs_srcdir/tlv/tlv_msg_def_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/tlv/tlv_msg_def_test], [0], [expout], [ignore])
+AT_CLEANUP
+
 AT_SETUP([gsup])
 AT_KEYWORDS([gsup])
 cat $abs_srcdir/gsup/gsup_test.ok > expout
diff --git a/tests/tlv/tlv_msg_def_test.c b/tests/tlv/tlv_msg_def_test.c
new file mode 100644
index 0000000..f16d1cd
--- /dev/null
+++ b/tests/tlv/tlv_msg_def_test.c
@@ -0,0 +1,216 @@
+#include <stdint.h>
+#include <stdio.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/gsm/tlv_msg_def.h>
+
+#define TEST_MSG_ITEM(msg)		msg, sizeof(msg)
+#define MSGT_IES_ITEM(msgt, ies)	[msgt] = (ies)
+#define TEST_MSGT_GEN(type, sub_type)	((type << 2) | sub_type)
+
+/* Inspired by 3GPP TS 29.002, chapter 12 */
+enum test_msg_type {
+	TEST_MSGT_MAP_SRI_FOR_SM_REQ	= TEST_MSGT_GEN(0x01, 1),
+	TEST_MSGT_MAP_SRI_FOR_SM_RES	= TEST_MSGT_GEN(0x01, 2),
+	TEST_MSGT_MAP_SRI_FOR_SM_ERR	= TEST_MSGT_GEN(0x01, 3),
+};
+static const struct value_string test_msgt_names[] = {
+	OSMO_VALUE_STRING(TEST_MSGT_MAP_SRI_FOR_SM_REQ),
+	OSMO_VALUE_STRING(TEST_MSGT_MAP_SRI_FOR_SM_RES),
+	OSMO_VALUE_STRING(TEST_MSGT_MAP_SRI_FOR_SM_ERR),
+	{ 0, NULL }
+};
+
+enum test_msg_ies {
+	TEST_MSG_SMSC_ADDR_IE	= 0x01,
+	TEST_MSG_NODE_ADDR_IE	= 0x02,
+	TEST_MSG_SM_RP_RPI_IE	= 0x03,
+	TEST_MSG_MSISDN_IE	= 0x04,
+	TEST_MSG_IMSI_IE	= 0x05,
+	TEST_MSG_CAUSE_IE	= 0x06,
+};
+static const struct value_string test_msg_iei_names[] = {
+	OSMO_VALUE_STRING(TEST_MSG_SMSC_ADDR_IE),
+	OSMO_VALUE_STRING(TEST_MSG_NODE_ADDR_IE),
+	OSMO_VALUE_STRING(TEST_MSG_SM_RP_RPI_IE),
+	OSMO_VALUE_STRING(TEST_MSG_MSISDN_IE),
+	OSMO_VALUE_STRING(TEST_MSG_IMSI_IE),
+	OSMO_VALUE_STRING(TEST_MSG_CAUSE_IE),
+	{ 0, NULL }
+};
+
+/* IE definitions */
+static const struct tlv_ie_def map_sriForSM_req_ies[] = {
+	{
+		.iei = TEST_MSG_MSISDN_IE,
+		.tlv_def = { TLV_TYPE_TLV },
+		.flags = TLV_IE_FLAG_EXCLUSIVE,
+	},
+	{
+		.iei = TEST_MSG_SM_RP_RPI_IE,
+		.tlv_def = { TLV_TYPE_TV },
+		.flags = TLV_IE_FLAG_EXCLUSIVE,
+	},
+	{
+		.iei = TEST_MSG_SMSC_ADDR_IE,
+		.tlv_def = { TLV_TYPE_TLV },
+		.flags = TLV_IE_FLAG_EXCLUSIVE,
+	},
+	{
+		.iei = TEST_MSG_IMSI_IE,
+		.tlv_def = { TLV_TYPE_TLV },
+		.flags = (TLV_IE_FLAG_EXCLUSIVE | TLV_IE_FLAG_OPTIONAL),
+	},
+};
+
+static const struct tlv_ie_def map_sriForSM_res_ies[] = {
+	{
+		.iei = TEST_MSG_IMSI_IE,
+		.tlv_def = { TLV_TYPE_TLV },
+		.flags = TLV_IE_FLAG_EXCLUSIVE,
+	},
+	{
+		.iei = TEST_MSG_NODE_ADDR_IE,
+		.tlv_def = { TLV_TYPE_TLV },
+		.flags = TLV_IE_FLAG_EXCLUSIVE,
+	},
+};
+
+static const struct tlv_ie_def map_sriForSM_err_ies[] = {
+	{
+		.iei = TEST_MSG_CAUSE_IE,
+		.tlv_def = { TLV_TYPE_TLV },
+	},
+};
+
+/* "SRI-FOR-SM" message group (REQ, RES, ERR) definition */
+static const struct tlv_msg_group_def map_sriForSM_def = {
+	.name = "MAP-MO-ForwardSM",
+	.msg_names = test_msgt_names,
+	.iei_names = test_msg_iei_names,
+
+	/* IEs according to section 12.1 */
+	.ie_defs = {
+		MSGT_IES_ITEM(TEST_MSGT_MAP_SRI_FOR_SM_REQ,
+			map_sriForSM_req_ies),
+		MSGT_IES_ITEM(TEST_MSGT_MAP_SRI_FOR_SM_RES,
+			map_sriForSM_res_ies),
+		MSGT_IES_ITEM(TEST_MSGT_MAP_SRI_FOR_SM_ERR,
+			map_sriForSM_err_ies),
+	},
+};
+
+/* A valid test set of hand-crafted messages */
+static const uint8_t map_sriForSM_enc_req_valid[] = {
+	TEST_MSGT_MAP_SRI_FOR_SM_REQ,
+	TEST_MSG_MSISDN_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x65, 0x75, 0x03, 0x28, 0x25,
+	TEST_MSG_SMSC_ADDR_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x75, 0x89, 0x00, 0x00, 0x10,
+	TEST_MSG_SM_RP_RPI_IE, 0x00, /* TV, M */
+};
+static const uint8_t map_sriForSM_enc_res_valid[] = {
+	TEST_MSGT_MAP_SRI_FOR_SM_RES,
+	TEST_MSG_IMSI_IE, 0x08, /* TLV, M */
+		0x46, 0x00, 0x44, 0x31, 0x60, 0x13, 0x03, 0xf5,
+	TEST_MSG_NODE_ADDR_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x75, 0x15, 0x08, 0x00, 0x40,
+};
+static const uint8_t map_sriForSM_enc_err_valid[] = {
+	TEST_MSGT_MAP_SRI_FOR_SM_ERR,
+	TEST_MSG_CAUSE_IE, 0x04, /* TLV, M */
+		0xde, 0xad, 0xbe, 0xef,
+};
+
+/* Unknown and optional IEs */
+static const uint8_t map_sriForSM_enc_req_valid_optional[] = {
+	TEST_MSGT_MAP_SRI_FOR_SM_REQ,
+	TEST_MSG_MSISDN_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x65, 0x75, 0x03, 0x28, 0x25,
+	TEST_MSG_IMSI_IE, 0x08, /* TLV, O (optional) */
+		0x46, 0x00, 0x44, 0x31, 0x60, 0x13, 0x03, 0xf5,
+	TEST_MSG_SMSC_ADDR_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x75, 0x89, 0x00, 0x00, 0x10,
+	TEST_MSG_SM_RP_RPI_IE, 0x00, /* TV, M */
+};
+static const uint8_t map_sriForSM_enc_res_valid_unknown[] = {
+	TEST_MSGT_MAP_SRI_FOR_SM_RES,
+	0x99, 0x03, /* Unknown IE (considered as TLV) */
+		0xff, 0xff, 0xff,
+	TEST_MSG_IMSI_IE, 0x08, /* TLV, M */
+		0x46, 0x00, 0x44, 0x31, 0x60, 0x13, 0x03, 0xf5,
+	TEST_MSG_NODE_ADDR_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x75, 0x15, 0x08, 0x00, 0x40,
+};
+
+/* Missing mandatory IE(s) */
+static const uint8_t map_sriForSM_enc_req_invalid_miss[] = {
+	TEST_MSGT_MAP_SRI_FOR_SM_REQ,
+	TEST_MSG_MSISDN_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x65, 0x75, 0x03, 0x28, 0x25,
+	TEST_MSG_SMSC_ADDR_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x75, 0x89, 0x00, 0x00, 0x10,
+};
+static const uint8_t map_sriForSM_enc_res_invalid_miss[] = {
+	TEST_MSGT_MAP_SRI_FOR_SM_RES,
+	TEST_MSG_NODE_ADDR_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x75, 0x15, 0x08, 0x00, 0x40,
+};
+
+/* TLV vs TV mismatch */
+static const uint8_t map_sriForSM_enc_req_invalid_tv_vs_tlv[] = {
+	TEST_MSGT_MAP_SRI_FOR_SM_REQ,
+	TEST_MSG_MSISDN_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x65, 0x75, 0x03, 0x28, 0x25,
+	TEST_MSG_SMSC_ADDR_IE, 0x07, /* TLV, M */
+		0x91, 0x52, 0x75, 0x89, 0x00, 0x00, 0x10,
+	TEST_MSG_SM_RP_RPI_IE, 0x04, /* TLV, M (incorrect) */
+		0xde, 0xad, 0xbe, 0xef,
+};
+
+/* Complete test set of hand-crafted messages */
+static const struct test_msg_def {
+	const char *name;
+	const uint8_t *data;
+	size_t data_len;
+} map_sriForSM_enc_test_set[] = {
+	{
+		"MAP-SRI-FOR-SM Request (valid, mandatory IEs only)",
+		TEST_MSG_ITEM(map_sriForSM_enc_req_valid),
+	},
+	{
+		"MAP-SRI-FOR-SM Response (valid, mandatory IEs only)",
+		TEST_MSG_ITEM(map_sriForSM_enc_res_valid),
+	},
+	{
+		"MAP-SRI-FOR-SM Error (valid, mandatory IEs only)",
+		TEST_MSG_ITEM(map_sriForSM_enc_err_valid),
+	},
+	{
+		"MAP-SRI-FOR-SM Request (valid, optional IEs)",
+		TEST_MSG_ITEM(map_sriForSM_enc_req_valid_optional),
+	},
+	{
+		"MAP-SRI-FOR-SM Response (valid, unknown IEs)",
+		TEST_MSG_ITEM(map_sriForSM_enc_res_valid_unknown),
+	},
+	{
+		"MAP-SRI-FOR-SM Request (invalid, missing mandatory IEs)",
+		TEST_MSG_ITEM(map_sriForSM_enc_req_invalid_miss),
+	},
+	{
+		"MAP-SRI-FOR-SM Response (invalid, missing mandatory IEs)",
+		TEST_MSG_ITEM(map_sriForSM_enc_res_invalid_miss),
+	},
+	{
+		/* FIXME: how it supposed to be detected??? decoding failure? */
+		"MAP-SRI-FOR-SM Request (invalid, TV vs TLV mismatch)",
+		TEST_MSG_ITEM(map_sriForSM_enc_req_invalid_tv_vs_tlv),
+	},
+};
+
+int main(int argc, char **argv)
+{
+	printf("Done.\n");
+	return 0;
+}
diff --git a/tests/tlv/tlv_msg_def_test.ok b/tests/tlv/tlv_msg_def_test.ok
new file mode 100644
index 0000000..619c561
--- /dev/null
+++ b/tests/tlv/tlv_msg_def_test.ok
@@ -0,0 +1 @@
+Done.

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

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Idef83b0c53b17503a64d7ab7422184ca4b60be57
Gerrit-Change-Number: 11105
Gerrit-PatchSet: 1
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180926/7834757e/attachment.htm>


More information about the gerrit-log mailing list