Change in libosmocore[master]: Revert "add osmo_mobile_identity API"

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
Tue Jun 16 07:21:14 UTC 2020


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/18853 )


Change subject: Revert "add osmo_mobile_identity API"
......................................................................

Revert "add osmo_mobile_identity API"

This reverts commit d1ceca9d48eb3d8b212f386a1ebb35d8fc612297, as it
introduces regressions in both osmo-msc and osmo-nitb which have been
causing failing builds for several days now.

Change-Id: I4bd958d0cd2ab4b0c4725e6d114f4404d725fcf7
---
M include/osmocom/core/utils.h
M include/osmocom/gsm/gsm48.h
M src/gb/gprs_bssgp.c
M src/gb/gprs_bssgp_bss.c
M src/gsm/gsm0808.c
M src/gsm/gsm29118.c
M src/gsm/gsm48.c
M src/gsm/libosmogsm.map
M src/utils.c
M tests/gsm0408/gsm0408_test.c
M tests/gsm0408/gsm0408_test.ok
M tests/utils/utils_test.c
M tests/utils/utils_test.ok
13 files changed, 150 insertions(+), 1,165 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/53/18853/1

diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index 8619120..e637786 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -55,7 +55,6 @@
 uint8_t osmo_char2bcd(char c);
 
 int osmo_bcd2str(char *dst, size_t dst_size, const uint8_t *bcd, int start_nibble, int end_nibble, bool allow_hex);
-int osmo_str2bcd(uint8_t *dst, size_t dst_size, const char *digits, int start_nibble, int end_nibble, bool allow_hex);
 
 int osmo_hexparse(const char *str, uint8_t *b, int max_len);
 
diff --git a/include/osmocom/gsm/gsm48.h b/include/osmocom/gsm/gsm48.h
index 81f6028..7c68b1d 100644
--- a/include/osmocom/gsm/gsm48.h
+++ b/include/osmocom/gsm/gsm48.h
@@ -4,12 +4,10 @@
 
 #include <stdbool.h>
 
-#include <osmocom/core/defs.h>
 #include <osmocom/core/msgb.h>
 
 #include <osmocom/gsm/tlv.h>
 #include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/protocol/gsm_23_003.h>
 #include <osmocom/gsm/gsm48_ie.h>
 #include <osmocom/gsm/gsm23003.h>
 
@@ -50,55 +48,16 @@
 void gsm48_generate_lai2(struct gsm48_loc_area_id *lai48, const struct osmo_location_area_id *lai);
 
 #define GSM48_MID_MAX_SIZE	11
-int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi)
-	OSMO_DEPRECATED("Instead use: l = msgb_tl_put(msg, GSM48_IE_MOBILE_ID);"
-			" *l = osmo_mobile_identity_encode_msgb(...)");
-int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi)
-	OSMO_DEPRECATED("Instead use: l = msgb_tl_put(msg, GSM48_IE_MOBILE_ID);"
-			" *l = osmo_mobile_identity_encode_msgb(...)");
-uint8_t gsm48_generate_mid(uint8_t *buf, const char *id, uint8_t mi_type)
-	OSMO_DEPRECATED("Instead use: l = msgb_tl_put(msg, GSM48_IE_MOBILE_ID);"
-			" *l = osmo_mobile_identity_encode_msgb(...)");
+int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi);
+int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi);
+uint8_t gsm48_generate_mid(uint8_t *buf, const char *id, uint8_t mi_type);
 
+/* Convert Mobile Identity (10.5.1.4) to string */
+int gsm48_mi_to_string(char *string, int str_len, const uint8_t *mi, int mi_len);
 const char *gsm48_mi_type_name(uint8_t mi);
-/* Convert encoded Mobile Identity (10.5.1.4) to string */
-int gsm48_mi_to_string(char *string, int str_len, const uint8_t *mi, int mi_len)
-	OSMO_DEPRECATED("Instead use osmo_mobile_identity_decode()");
-const char *osmo_mi_name(const uint8_t *mi, uint8_t mi_len)
-	OSMO_DEPRECATED("Instead use osmo_mobile_identity_to_str_c()");
-char *osmo_mi_name_buf(char *buf, size_t buf_len, const uint8_t *mi, uint8_t mi_len)
-	OSMO_DEPRECATED("Instead use osmo_mobile_identity_to_str_buf()");
-char *osmo_mi_name_c(const void *ctx, const uint8_t *mi, uint8_t mi_len)
-	OSMO_DEPRECATED("Instead use osmo_mobile_identity_to_str_c()");
-
-/*! Decoded representation of a Mobile Identity (3GPP TS 24.008 10.5.1.4).
- * See osmo_mobile_identity_decode() and osmo_mobile_identity_from_l3(). */
-struct osmo_mobile_identity {
-	/*! A GSM_MI_TYPE_* constant (like GSM_MI_TYPE_IMSI). */
-	uint8_t type;
-	/*! Decoded Mobile Identity digits or TMSI value. IMSI, IMEI and IMEISV as digits like
-	 * "12345678", and TMSI is represented as raw uint32_t. */
-	union {
-		/*! type == GSM_MI_TYPE_IMSI. */
-		char imsi[GSM23003_IMSI_MAX_DIGITS + 1];
-		/*! type == GSM_MI_TYPE_IMEI. */
-		char imei[GSM23003_IMEI_NUM_DIGITS + 1];
-		/*! type == GSM_MI_TYPE_IMEISV. */
-		char imeisv[GSM23003_IMEISV_NUM_DIGITS + 1];
-		/*! TMSI / P-TMSI / M-TMSI integer value if type == GSM_MI_TYPE_TMSI. */
-		uint32_t tmsi;
-	};
-};
-
-int osmo_mobile_identity_to_str_buf(char *buf, size_t buflen, const struct osmo_mobile_identity *mi);
-char *osmo_mobile_identity_to_str_c(void *ctx, const struct osmo_mobile_identity *mi);
-int osmo_mobile_identity_cmp(const struct osmo_mobile_identity *a, const struct osmo_mobile_identity *b);
-int osmo_mobile_identity_decode(struct osmo_mobile_identity *mi, const uint8_t *mi_data, uint8_t mi_len,
-				bool allow_hex);
-int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct msgb *msg, bool allow_hex);
-int osmo_mobile_identity_encoded_len(const struct osmo_mobile_identity *mi, int *mi_digits);
-int osmo_mobile_identity_encode_buf(uint8_t *buf, size_t buflen, const struct osmo_mobile_identity *mi, bool allow_hex);
-int osmo_mobile_identity_encode_msgb(struct msgb *msg, const struct osmo_mobile_identity *mi, bool allow_hex);
+const char *osmo_mi_name(const uint8_t *mi, uint8_t mi_len);
+char *osmo_mi_name_buf(char *buf, size_t buf_len, const uint8_t *mi, uint8_t mi_len);
+char *osmo_mi_name_c(const void *ctx, const uint8_t *mi, uint8_t mi_len);
 
 /* Parse Routeing Area Identifier */
 void gsm48_parse_ra(struct gprs_ra_id *raid, const uint8_t *buf);
diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c
index 2784d0a..38794c2 100644
--- a/src/gb/gprs_bssgp.c
+++ b/src/gb/gprs_bssgp.c
@@ -1170,20 +1170,19 @@
 
 	/* IMSI */
 	if (dup->imsi && strlen(dup->imsi)) {
-		struct osmo_mobile_identity mi = { .type = GSM_MI_TYPE_IMSI, };
-		OSMO_STRLCPY_ARRAY(mi.imsi, dup->imsi);
-		msgb_tvl_put(msg, BSSGP_IE_IMSI, osmo_mobile_identity_encoded_len(&mi, NULL));
-		if (osmo_mobile_identity_encode_msgb(msg, &mi, false) <= 0) {
-			if (log_check_level(DBSSGP, LOGL_NOTICE)) {
-				char strbuf[64];
-				osmo_mobile_identity_to_str_buf(strbuf, sizeof(strbuf), &mi);
-				LOGP(DBSSGP, LOGL_ERROR,
-				     "NSEI=%u/BVCI=%u Cannot encode Mobile Identity %s\n",
-				     nsei, bvci, strbuf);
-			}
-			msgb_free(msg);
-			return -EINVAL;
-		}
+		uint8_t mi[GSM48_MID_MAX_SIZE];
+/* gsm48_generate_mid_from_imsi() is guaranteed to never return more than 11,
+ * but somehow gcc (8.2) is not smart enough to figure this out and claims that
+ * the memcpy in msgb_tvlv_put() below will cause and out-of-bounds access up to
+ * mi[131], which is wrong */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+		int imsi_len = gsm48_generate_mid_from_imsi(mi, dup->imsi);
+		OSMO_ASSERT(imsi_len <= GSM48_MID_MAX_SIZE);
+		if (imsi_len > 2)
+			msgb_tvlv_push(msg, BSSGP_IE_IMSI,
+				imsi_len-2, mi+2);
+#pragma GCC diagnostic pop
 	}
 
 	/* DRX parameters */
@@ -1228,8 +1227,12 @@
 	struct bssgp_normal_hdr *bgph =
 			(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
 	uint16_t drx_params = osmo_htons(pinfo->drx_params);
+	uint8_t mi[GSM48_MID_MAX_SIZE];
+	int imsi_len = gsm48_generate_mid_from_imsi(mi, pinfo->imsi);
 	struct gsm48_ra_id ra;
-	struct osmo_mobile_identity mi;
+
+	if (imsi_len < 2)
+		return -EINVAL;
 
 	msgb_nsei(msg) = nsei;
 	msgb_bvci(msg) = ns_bvci;
@@ -1238,23 +1241,16 @@
 		bgph->pdu_type = BSSGP_PDUT_PAGING_PS;
 	else
 		bgph->pdu_type = BSSGP_PDUT_PAGING_CS;
-
 	/* IMSI */
-	mi = (struct osmo_mobile_identity){ .type = GSM_MI_TYPE_IMSI, };
-	OSMO_STRLCPY_ARRAY(mi.imsi, pinfo->imsi);
-	msgb_tvl_put(msg, BSSGP_IE_IMSI, osmo_mobile_identity_encoded_len(&mi, NULL));
-	if (osmo_mobile_identity_encode_msgb(msg, &mi, false) <= 0) {
-		if (log_check_level(DBSSGP, LOGL_NOTICE)) {
-			char strbuf[64];
-			osmo_mobile_identity_to_str_buf(strbuf, sizeof(strbuf), &mi);
-			LOGP(DBSSGP, LOGL_ERROR,
-			     "NSEI=%u/BVCI=%u Cannot encode Mobile Identity %s\n",
-			     nsei, ns_bvci, strbuf);
-		}
-		msgb_free(msg);
-		return -EINVAL;
-	}
-
+/* gsm48_generate_mid_from_imsi() is guaranteed to never return more than 11,
+ * but somehow gcc (8.2) is not smart enough to figure this out and claims that
+ * the memcpy in msgb_tvlv_put() below will cause and out-of-bounds access up to
+ * mi[131], which is wrong */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+	OSMO_ASSERT(imsi_len <= GSM48_MID_MAX_SIZE);
+	msgb_tvlv_put(msg, BSSGP_IE_IMSI, imsi_len-2, mi+2);
+#pragma GCC diagnostic pop
 	/* DRX Parameters */
 	msgb_tvlv_put(msg, BSSGP_IE_DRX_PARAMS, 2,
 			(uint8_t *) &drx_params);
diff --git a/src/gb/gprs_bssgp_bss.c b/src/gb/gprs_bssgp_bss.c
index 9e9cefc..5c9d11c 100644
--- a/src/gb/gprs_bssgp_bss.c
+++ b/src/gb/gprs_bssgp_bss.c
@@ -178,17 +178,22 @@
 				const char *imsi)
 {
 	struct msgb *msg = common_tx_radio_status(bctx);
-	struct osmo_mobile_identity mi = { .type = GSM_MI_TYPE_IMSI, };
-	OSMO_STRLCPY_ARRAY(mi.imsi, imsi);
+	uint8_t mi[GSM48_MID_MAX_SIZE];
+	int imsi_len = gsm48_generate_mid_from_imsi(mi, imsi);
 
 	if (!msg)
 		return -ENOMEM;
-
-	msgb_tvl_put(msg, BSSGP_IE_IMSI, osmo_mobile_identity_encoded_len(&mi, NULL));
-	if (osmo_mobile_identity_encode_msgb(msg, &mi, false) <= 0) {
-		msgb_free(msg);
-		return -EINVAL;
-	}
+/* gsm48_generate_mid_from_imsi() is guaranteed to never return more than 11,
+ * but somehow gcc (8.2) is not smart enough to figure this out and claims that
+ * the memcpy in msgb_tvlv_put() below will cause and out-of-bounds access up to
+ * mi[131], which is wrong */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+	OSMO_ASSERT(imsi_len <= GSM48_MID_MAX_SIZE);
+	/* strip the MI type and length values (2 bytes) */
+	if (imsi_len > 2)
+		msgb_tvlv_put(msg, BSSGP_IE_IMSI, imsi_len-2, mi+2);
+#pragma GCC diagnostic pop
 	LOGPC(DBSSGP, LOGL_NOTICE, "IMSI=%s ", imsi);
 
 	return common_tx_radio_status2(msg, cause);
@@ -481,7 +486,6 @@
 	struct tlv_parsed tp;
 	uint8_t ra[6];
 	int rc, data_len;
-	struct osmo_mobile_identity mi;
 
 	memset(ra, 0, sizeof(ra));
 
@@ -506,11 +510,9 @@
 		goto err_mand_ie;
 	if (!pinfo->imsi)
 		pinfo->imsi = talloc_zero_size(pinfo, GSM_IMSI_LENGTH);
-	if (osmo_mobile_identity_decode(&mi, TLVP_VAL(&tp, BSSGP_IE_IMSI), TLVP_LEN(&tp, BSSGP_IE_IMSI), false))
-		goto err_mand_ie;
-	if (mi.type != GSM_MI_TYPE_IMSI)
-		goto err_mand_ie;
-	osmo_talloc_replace_string(pinfo, &pinfo->imsi, mi.imsi);
+	gsm48_mi_to_string(pinfo->imsi, GSM_IMSI_LENGTH,
+			   TLVP_VAL(&tp, BSSGP_IE_IMSI),
+			   TLVP_LEN(&tp, BSSGP_IE_IMSI));
 
 	/* DRX Parameters */
 	if (!TLVP_PRESENT(&tp, BSSGP_IE_DRX_PARAMS))
diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c
index 6560d4b..9fdf379 100644
--- a/src/gsm/gsm0808.c
+++ b/src/gsm/gsm0808.c
@@ -730,10 +730,9 @@
 				    const uint8_t *chan_needed)
 {
 	struct msgb *msg;
-	struct osmo_mobile_identity mi;
+	uint8_t mid_buf[GSM48_MI_SIZE + 2];
+	int mid_len;
 	uint32_t tmsi_sw;
-	uint8_t *l;
-	int rc;
 
 	/* Mandatory elements! */
 	OSMO_ASSERT(imsi);
@@ -751,15 +750,8 @@
 	msgb_v_put(msg, BSS_MAP_MSG_PAGING);
 
 	/* mandatory IMSI 3.2.2.6 */
-	mi = (struct osmo_mobile_identity){ .type = GSM_MI_TYPE_IMSI, };
-	OSMO_STRLCPY_ARRAY(mi.imsi, imsi);
-	l = msgb_tl_put(msg, GSM0808_IE_IMSI);
-	rc = osmo_mobile_identity_encode_msgb(msg, &mi, false);
-	if (rc <= 0) {
-		msgb_free(msg);
-		return NULL;
-	}
-	*l = rc;
+	mid_len = gsm48_generate_mid_from_imsi(mid_buf, imsi);
+	msgb_tlv_put(msg, GSM0808_IE_IMSI, mid_len - 2, mid_buf + 2);
 
 	/* TMSI 3.2.2.7 */
 	if (tmsi) {
@@ -975,17 +967,9 @@
 
 	/* IMSI 3.2.2.6 */
 	if (params->imsi) {
-		uint8_t *l;
-		int rc;
-		struct osmo_mobile_identity mi = { .type = GSM_MI_TYPE_IMSI, };
-		OSMO_STRLCPY_ARRAY(mi.imsi, params->imsi);
-		l = msgb_tl_put(msg, GSM0808_IE_IMSI);
-		rc = osmo_mobile_identity_encode_msgb(msg, &mi, false);
-		if (rc <= 0) {
-			msgb_free(msg);
-			return NULL;
-		}
-		*l = rc;
+		uint8_t mid_buf[GSM48_MI_SIZE + 2];
+		int mid_len = gsm48_generate_mid_from_imsi(mid_buf, params->imsi);
+		msgb_tlv_put(msg, GSM0808_IE_IMSI, mid_len - 2, mid_buf + 2);
 	}
 
 	if (params->aoip_transport_layer)
diff --git a/src/gsm/gsm29118.c b/src/gsm/gsm29118.c
index 5c72b4d..2c02b2f 100644
--- a/src/gsm/gsm29118.c
+++ b/src/gsm/gsm29118.c
@@ -219,14 +219,12 @@
 /* Encode IMSI from string representation and append to SGSaAP msg */
 static void msgb_sgsap_imsi_put(struct msgb *msg, const char *imsi)
 {
-	int rc;
-	struct osmo_mobile_identity mi = { .type = GSM_MI_TYPE_IMSI, };
-	uint8_t *l;
-	OSMO_STRLCPY_ARRAY(mi.imsi, imsi);
-	l = msgb_tl_put(msg, SGSAP_IE_IMSI);
-	rc = osmo_mobile_identity_encode_msgb(msg, &mi, false);
-	/* This function fails to do error handling, so in case of error, leave the len == 0. */
-	*l = rc > 0? rc : 0;
+	uint8_t buf[16];
+	uint8_t len;
+	/* encoding is just like TS 04.08 */
+	len = gsm48_generate_mid_from_imsi(buf, imsi);
+	/* skip first two bytes (tag+length) so we can use msgb_tlv_put */
+	msgb_tlv_put(msg, SGSAP_IE_IMSI, len - 2, buf + 2);
 }
 
 /* Encode LAI from struct representation and append to SGSaAP msg */
diff --git a/src/gsm/gsm48.c b/src/gsm/gsm48.c
index 11bd361..8d0998b 100644
--- a/src/gsm/gsm48.c
+++ b/src/gsm/gsm48.c
@@ -45,7 +45,6 @@
 #include <osmocom/gsm/protocol/gsm_04_80.h>
 #include <osmocom/gsm/protocol/gsm_08_58.h>
 #include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
-#include <osmocom/gsm/protocol/gsm_23_003.h>
 
 /*! \addtogroup gsm0408
  *  @{
@@ -459,500 +458,70 @@
 	return get_value_string(mi_type_names, mi);
 }
 
-/*! Deprecated, see osmo_mobile_identity instead.
- * Return a human readable representation of a Mobile Identity in caller-provided buffer.
+/*! Return a human readable representation of a Mobile Identity in caller-provided buffer.
  * \param[out] buf caller-provided output buffer
  * \param[in] buf_len size of buf in bytes
  * \param[in] mi  Mobile Identity buffer containing 3GPP TS 04.08 style MI type and data.
  * \param[in] mi_len  Length of mi.
  * \return buf
  */
-char *osmo_mi_name_buf(char *buf, size_t buf_len, const uint8_t *mi_data, uint8_t mi_len)
+char *osmo_mi_name_buf(char *buf, size_t buf_len, const uint8_t *mi, uint8_t mi_len)
 {
-	struct osmo_mobile_identity mi;
-	if (osmo_mobile_identity_decode(&mi, mi_data, mi_len, true)) {
+	uint8_t mi_type;
+	uint32_t tmsi;
+	char mi_string[GSM48_MI_SIZE];
+
+	mi_type = (mi && mi_len) ? (mi[0] & GSM_MI_TYPE_MASK) : GSM_MI_TYPE_NONE;
+
+	switch (mi_type) {
+	case GSM_MI_TYPE_TMSI:
+		/* Table 10.5.4.3, reverse generate_mid_from_tmsi */
+		if (mi_len == GSM48_TMSI_LEN && mi[0] == (0xf0 | GSM_MI_TYPE_TMSI)) {
+			tmsi = osmo_load32be(&mi[1]);
+			snprintf(buf, buf_len, "TMSI-0x%08" PRIX32, tmsi);
+		} else {
+			snprintf(buf, buf_len, "TMSI-invalid");
+		}
+		return buf;
+
+	case GSM_MI_TYPE_IMSI:
+	case GSM_MI_TYPE_IMEI:
+	case GSM_MI_TYPE_IMEISV:
+		osmo_bcd2str(mi_string, sizeof(mi_string), mi, 1, (mi_len * 2) - (mi[0] & GSM_MI_ODD ? 0 : 1), true);
+		snprintf(buf, buf_len, "%s-%s", gsm48_mi_type_name(mi_type), mi_string);
+		return buf;
+
+	default:
 		snprintf(buf, buf_len, "unknown");
 		return buf;
 	}
-	osmo_mobile_identity_to_str_buf(buf, buf_len, &mi);
-	return buf;
 }
 
-/*! Deprecated, see osmo_mobile_identity instead.
- * Return a human readable representation of a Mobile Identity in static buffer.
+/*! Return a human readable representation of a Mobile Identity in static buffer.
  * \param[in] mi  Mobile Identity buffer containing 3GPP TS 04.08 style MI type and data.
  * \param[in] mi_len  Length of mi.
  * \return A string like "IMSI-1234567", "TMSI-0x1234ABCD" or "unknown", "TMSI-invalid"...
  */
-const char *osmo_mi_name(const uint8_t *mi_data, uint8_t mi_len)
+const char *osmo_mi_name(const uint8_t *mi, uint8_t mi_len)
 {
 	static __thread char mi_name[10 + GSM48_MI_SIZE + 1];
-	struct osmo_mobile_identity mi;
-	if (osmo_mobile_identity_decode(&mi, mi_data, mi_len, true) == 0)
-		osmo_mobile_identity_to_str_buf(mi_name, sizeof(mi_name), &mi);
-	else
-		snprintf(mi_name, sizeof(mi_name), "unknown");
-	return mi_name;
+	return osmo_mi_name_buf(mi_name, sizeof(mi_name), mi, mi_len);
 }
 
-/*! Deprecated, see osmo_mobile_identity instead.
- * Return a human readable representation of a Mobile Identity in dynamically-allocated buffer.
+/*! Return a human readable representation of a Mobile Identity in dynamically-allocated buffer.
  * \param[in] ctx talloc context from which to allocate output buffer
  * \param[in] mi  Mobile Identity buffer containing 3GPP TS 04.08 style MI type and data.
  * \param[in] mi_len  Length of mi.
  * \return A string like "IMSI-1234567", "TMSI-0x1234ABCD" or "unknown", "TMSI-invalid" in a
  * 	   dynamically-allocated output buffer.
  */
-char *osmo_mi_name_c(const void *ctx, const uint8_t *mi_data, uint8_t mi_len)
+char *osmo_mi_name_c(const void *ctx, const uint8_t *mi, uint8_t mi_len)
 {
-	struct osmo_mobile_identity mi;
-	if (osmo_mobile_identity_decode(&mi, mi_data, mi_len, true))
-		return talloc_strdup((void*)ctx, "unknown");
-	return osmo_mobile_identity_to_str_c((void*)ctx, &mi);
-}
-
-/*! Extract Mobile Identity from encoded bytes (3GPP TS 24.008 10.5.1.4).
- *
- * On failure (negative return value), mi->type == GSM_MI_TYPE_NONE, mi->string[] is all-zero and mi->tmsi ==
- * GSM_RESERVED_TMSI.
- *
- * On success, mi->type reflects the decoded Mobile Identity type (GSM_MI_TYPE_IMSI, GSM_MI_TYPE_TMSI, GSM_MI_TYPE_IMEI
- * or GSM_MI_TYPE_IMEISV).
- *
- * On success, mi->string always contains a human readable representation of the Mobile Identity digits: IMSI, IMEI and
- * IMEISV as digits like "12345678", and TMSI as "0x" and 8 hexadecimal digits like "0x1234abcd".
- *
- * mi->tmsi contains the uint32_t TMSI value iff the extracted Mobile Identity was a TMSI, or GSM_RESERVED_TMSI
- * otherwise.
- *
- * \param[out] mi  Return buffer for decoded Mobile Identity.
- * \param[in] mi_data  The encoded Mobile Identity octets.
- * \param[in] mi_len  Number of octets in mi_data.
- * \param[in] allow_hex  If false, hexadecimal digits (>9) result in an error return value.
- * \returns 0 on success, negative on error: -EBADMSG = invalid length indication or invalid data,
- *          -EINVAL = unknown Mobile Identity type.
- */
-int osmo_mobile_identity_decode(struct osmo_mobile_identity *mi, const uint8_t *mi_data, uint8_t mi_len,
-				bool allow_hex)
-{
-	int rc;
-	int nibbles_len;
-	char *str;
-	size_t str_size;
-
-	if (!mi_data || mi_len < 1)
-		return -EBADMSG;
-
-	nibbles_len = (mi_len - 1) * 2 + ((mi_data[0] & GSM_MI_ODD) ? 1 : 0);
-
-	*mi = (struct osmo_mobile_identity){
-		.type = mi_data[0] & GSM_MI_TYPE_MASK,
-	};
-
-	/* First do length checks */
-	switch (mi->type) {
-	case GSM_MI_TYPE_TMSI:
-		mi->tmsi = GSM_RESERVED_TMSI;
-		if (nibbles_len != (GSM23003_TMSI_NUM_BYTES * 2)) {
-			rc = -EBADMSG;
-			goto return_error;
-		}
-		break;
-
-	case GSM_MI_TYPE_IMSI:
-		if (nibbles_len < GSM23003_IMSI_MIN_DIGITS || nibbles_len > GSM23003_IMSI_MAX_DIGITS) {
-			rc = -EBADMSG;
-			goto return_error;
-		}
-		str = mi->imsi;
-		str_size = sizeof(mi->imsi);
-		break;
-
-	case GSM_MI_TYPE_IMEI:
-		if (nibbles_len != GSM23003_IMEI_NUM_DIGITS && nibbles_len != GSM23003_IMEI_NUM_DIGITS_NO_CHK) {
-			rc = -EBADMSG;
-			goto return_error;
-		}
-		str = mi->imei;
-		str_size = sizeof(mi->imei);
-		break;
-
-	case GSM_MI_TYPE_IMEISV:
-		if (nibbles_len != GSM23003_IMEISV_NUM_DIGITS) {
-			rc = -EBADMSG;
-			goto return_error;
-		}
-		str = mi->imeisv;
-		str_size = sizeof(mi->imeisv);
-		break;
-
-	default:
-		rc = -EINVAL;
-		goto return_error;
-	}
-
-	/* Decode BCD digits */
-	switch (mi->type) {
-	case GSM_MI_TYPE_TMSI:
-		/* MI is a 32bit integer TMSI. Length has been checked above. */
-		if ((mi_data[0] & 0xf0) != 0xf0) {
-			/* A TMSI always has the first nibble == 0xf */
-			rc = -EBADMSG;
-			goto return_error;
-		}
-		mi->tmsi = osmo_load32be(&mi_data[1]);
-		return 0;
-
-	case GSM_MI_TYPE_IMSI:
-	case GSM_MI_TYPE_IMEI:
-	case GSM_MI_TYPE_IMEISV:
-		/* If the length is even, the last nibble (higher nibble of last octet) must be 0xf */
-		if (!(mi_data[0] & GSM_MI_ODD)
-		    && ((mi_data[mi_len - 1] & 0xf0) != 0xf0)) {
-			rc = -EBADMSG;
-			goto return_error;
-		}
-		rc = osmo_bcd2str(str, str_size, mi_data, 1, 1 + nibbles_len, allow_hex);
-		/* rc checked below */
-		break;
-
-	default:
-		/* Already handled above, but as future bug paranoia: */
-		rc = -EINVAL;
-		goto return_error;
-	}
-
-	/* check mi->str printing rc */
-	if (rc < 1 || rc >= str_size) {
-		rc = -EBADMSG;
-		goto return_error;
-	}
-	return 0;
-
-return_error:
-	*mi = (struct osmo_mobile_identity){
-		.type = GSM_MI_TYPE_NONE,
-	};
-	return rc;
-}
-
-/*! Return the number of encoded Mobile Identity octets, without actually encoding.
- * Useful to write tag-length header before encoding the MI.
- * \param[in] mi  Mobile Identity.
- * \param[out] mi_digits  If not NULL, store the number of nibbles of used MI data (i.e. strlen(mi->string) or 8 for a TMSI).
- * \return octets that osmo_mobile_identity_encode_msgb() will write for this mi.
- */
-int osmo_mobile_identity_encoded_len(const struct osmo_mobile_identity *mi, int *mi_digits)
-{
-	int mi_nibbles;
-	if (!mi)
-		return -EINVAL;
-	switch (mi->type) {
-	case GSM_MI_TYPE_TMSI:
-		mi_nibbles = GSM23003_TMSI_NUM_BYTES * 2;
-		break;
-	case GSM_MI_TYPE_IMSI:
-		mi_nibbles = strlen(mi->imsi);
-		if (mi_nibbles < GSM23003_IMSI_MIN_DIGITS
-		    || mi_nibbles > GSM23003_IMSI_MAX_DIGITS)
-			return -EINVAL;
-		break;
-	case GSM_MI_TYPE_IMEI:
-		mi_nibbles = strlen(mi->imei);
-		if (mi_nibbles < GSM23003_IMEI_NUM_DIGITS_NO_CHK
-		    || mi_nibbles > GSM23003_IMEI_NUM_DIGITS)
-			return -EINVAL;
-		break;
-	case GSM_MI_TYPE_IMEISV:
-		mi_nibbles = strlen(mi->imeisv);
-		if (mi_nibbles != GSM23003_IMEISV_NUM_DIGITS)
-			return -EINVAL;
-		break;
-	default:
-		return -ENOTSUP;
-	}
-
-	if (mi_digits)
-		*mi_digits = mi_nibbles;
-
-	/* one type nibble, plus the MI nibbles, plus a filler nibble to complete the last octet:
-	 * mi_octets = ceil((float)(mi_nibbles + 1) / 2)
-	 */
-	return (mi_nibbles + 2) / 2;
-}
-
-/*! Encode Mobile Identity from uint32_t (TMSI) or digits string (all others) (3GPP TS 24.008 10.5.1.4).
- *
- * \param[out] buf  Return buffer for encoded Mobile Identity.
- * \param[in] buflen  sizeof(buf).
- * \param[in] mi  Mobile identity to encode.
- * \param[in] allow_hex  If false, hexadecimal digits (>9) result in an error return value.
- * \returns Amount of bytes written to buf, or negative on error.
- */
-int osmo_mobile_identity_encode_buf(uint8_t *buf, size_t buflen, const struct osmo_mobile_identity *mi, bool allow_hex)
-{
-	int rc;
-	int nibbles_len;
-	int mi_octets;
-	const char *mi_str;
-
-	if (!buf || !buflen)
-		return -EIO;
-
-	mi_octets = osmo_mobile_identity_encoded_len(mi, &nibbles_len);
-	if (mi_octets < 0)
-		return mi_octets;
-	if (mi_octets > buflen)
-		return -ENOSPC;
-
-	buf[0] = (mi->type & GSM_MI_TYPE_MASK) | ((nibbles_len & 1) ? GSM_MI_ODD : 0);
-
-	switch (mi->type) {
-	case GSM_MI_TYPE_TMSI:
-		buf[0] |= 0xf0;
-		osmo_store32be(mi->tmsi, &buf[1]);
-		return mi_octets;
-
-	case GSM_MI_TYPE_IMSI:
-		mi_str = mi->imsi;
-		break;
-	case GSM_MI_TYPE_IMEI:
-		mi_str = mi->imei;
-		break;
-	case GSM_MI_TYPE_IMEISV:
-		mi_str = mi->imeisv;
-		break;
-	default:
-		return -ENOTSUP;
-	}
-	rc = osmo_str2bcd(buf, buflen, mi_str, 1, -1, allow_hex);
-	if (rc != mi_octets)
-		return -EINVAL;
-	return mi_octets;
-}
-
-/*! Encode Mobile Identity type and BCD digits, appended to a msgb.
- * Example to add a GSM48_IE_MOBILE_ID IEI with tag and length to a msgb:
- *
- *  struct osmo_mobile_identity mi = { .type = GSM_MI_TYPE_IMSI, .tmsi = random_tmsi, };
- *  uint8_t *l = msgb_tl_put(msg, GSM48_IE_MOBILE_ID);
- *  int rc = osmo_mobile_identity_encode_msgb(msg, &mi, false);
- *  if (rc < 0)
- *          goto error;
- *  *l = rc;
- *
- * Example to add a BSSGP_IE_IMSI with tag and variable-size length, where the
- * length needs to be known at the time of writing the IE tag-length header:
- *
- *  struct osmo_mobile_identity mi = { .type = GSM_MI_TYPE_IMSI, };
- *  OSMO_STRLCPY_ARRAY(mi.imsi, pinfo->imsi);
- *  msgb_tvl_put(msg, BSSGP_IE_IMSI, osmo_mobile_identity_encoded_len(&mi, NULL));
- *  if (osmo_mobile_identity_encode_msgb(msg, &mi, false) < 0)
- *          goto error;
- */
-int osmo_mobile_identity_encode_msgb(struct msgb *msg, const struct osmo_mobile_identity *mi, bool allow_hex)
-{
-	int rc = osmo_mobile_identity_encode_buf(msg->tail, msgb_tailroom(msg), mi, allow_hex);
-	if (rc < 0)
-		return rc;
-	msgb_put(msg, rc);
-	return rc;
-}
-
-/*! Extract Mobile Identity from a Complete Layer 3 message.
- *
- * Determine the Mobile Identity data and call osmo_mobile_identity_decode() to return a decoded struct
- * osmo_mobile_identity.
- *
- * \param[out] mi  Return buffer for decoded Mobile Identity.
- * \param[in] msg  The Complete Layer 3 message to extract from (LU, CM Service Req or Paging Resp).
- * \returns 0 on success, negative on error: return codes as defined in osmo_mobile_identity_decode(), or
- *          -ENOTSUP = not a Complete Layer 3 message,
- */
-int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct msgb *msg, bool allow_hex)
-{
-	const struct gsm48_hdr *gh;
-	int8_t pdisc = 0;
-	uint8_t mtype = 0;
-	const struct gsm48_loc_upd_req *lu;
-	const uint8_t *cm2_buf;
-	uint8_t cm2_len;
-	const uint8_t *mi_start;
-	const struct gsm48_pag_resp *paging_response;
-	const uint8_t *mi_data;
-	uint8_t mi_len;
-	const struct gsm48_imsi_detach_ind *idi;
-
-	*mi = (struct osmo_mobile_identity){
-		.type = GSM_MI_TYPE_NONE,
-		.tmsi = GSM_RESERVED_TMSI,
-	};
-
-	if (msgb_l3len(msg) < sizeof(*gh))
-		return -EBADMSG;
-
-	gh = msgb_l3(msg);
-	pdisc = gsm48_hdr_pdisc(gh);
-	mtype = gsm48_hdr_msg_type(gh);
-
-	switch (pdisc) {
-	case GSM48_PDISC_MM:
-
-		switch (mtype) {
-		case GSM48_MT_MM_LOC_UPD_REQUEST:
-			/* First make sure that lu-> can be dereferenced */
-			if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*lu))
-				return -EBADMSG;
-
-			/* Now we know there is enough msgb data to read a lu->mi_len, so also check that */
-			lu = (struct gsm48_loc_upd_req*)gh->data;
-			if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*lu) + lu->mi_len)
-				return -EBADMSG;
-			mi_data = lu->mi;
-			mi_len = lu->mi_len;
-			goto got_mi;
-
-		case GSM48_MT_MM_CM_SERV_REQ:
-		case GSM48_MT_MM_CM_REEST_REQ:
-			/* Unfortunately in Phase1 the Classmark2 length is variable, so we cannot
-			 * just use gsm48_service_request struct, and need to parse it manually. */
-			if (msgb_l3len(msg) < sizeof(*gh) + 2)
-				return -EBADMSG;
-
-			cm2_len = gh->data[1];
-			cm2_buf = gh->data + 2;
-			goto got_cm2;
-
-		case GSM48_MT_MM_IMSI_DETACH_IND:
-			if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*idi))
-				return -EBADMSG;
-			idi = (struct gsm48_imsi_detach_ind*) gh->data;
-			mi_data = idi->mi;
-			mi_len = idi->mi_len;
-			goto got_mi;
-
-		case GSM48_MT_MM_ID_RESP:
-			if (msgb_l3len(msg) < sizeof(*gh) + 2)
-				return -EBADMSG;
-			mi_data = gh->data+1;
-			mi_len = gh->data[0];
-			goto got_mi;
-
-		default:
-			break;
-		}
-		break;
-
-	case GSM48_PDISC_RR:
-
-		switch (mtype) {
-		case GSM48_MT_RR_PAG_RESP:
-			if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*paging_response))
-				return -EBADMSG;
-			paging_response = (struct gsm48_pag_resp*)gh->data;
-			cm2_len = paging_response->cm2_len;
-			cm2_buf = (uint8_t*)&paging_response->cm2;
-			goto got_cm2;
-
-		default:
-			break;
-		}
-		break;
-	}
-
-	return -ENOTSUP;
-
-got_cm2:
-	/* MI (Mobile Identity) LV follows the Classmark2 */
-
-	/* There must be at least a mi_len byte after the CM2 */
-	if (cm2_buf + cm2_len + 1 > msg->tail)
-		return -EBADMSG;
-
-	mi_start = cm2_buf + cm2_len;
-	mi_len = mi_start[0];
-	mi_data = mi_start + 1;
-
-got_mi:
-	/* mi_data points at the start of the Mobile Identity coding of mi_len bytes */
-	if (mi_data + mi_len > msg->tail)
-		return -EBADMSG;
-
-	return osmo_mobile_identity_decode(mi, mi_data, mi_len, allow_hex);
-}
-
-/*! Return a human readable representation of a struct osmo_mobile_identity.
- * Write a string like "IMSI-1234567", "TMSI-0x1234ABCD" or "NONE", "NULL".
- * \param[out] buf  String buffer to write to.
- * \param[in] buflen  sizeof(buf).
- * \param[in] mi  Decoded Mobile Identity data.
- * \return the strlen() of the string written when buflen is sufficiently large, like snprintf().
- */
-int osmo_mobile_identity_to_str_buf(char *buf, size_t buflen, const struct osmo_mobile_identity *mi)
-{
-	struct osmo_strbuf sb = { .buf = buf, .len = buflen };
-	if (!mi)
-		return snprintf(buf, buflen, "NULL");
-	OSMO_STRBUF_PRINTF(sb, "%s", gsm48_mi_type_name(mi->type));
-	switch (mi->type) {
-	case GSM_MI_TYPE_TMSI:
-		OSMO_STRBUF_PRINTF(sb, "-0x%08" PRIX32, mi->tmsi);
-		break;
-	case GSM_MI_TYPE_IMSI:
-		OSMO_STRBUF_PRINTF(sb, "-%s", mi->imsi);
-		break;
-	case GSM_MI_TYPE_IMEI:
-		OSMO_STRBUF_PRINTF(sb, "-%s", mi->imei);
-		break;
-	case GSM_MI_TYPE_IMEISV:
-		OSMO_STRBUF_PRINTF(sb, "-%s", mi->imeisv);
-		break;
-	default:
-		break;
-	}
-	return sb.chars_needed;
-}
-
-/*! Like osmo_mobile_identity_to_str_buf(), but return the string in a talloc buffer.
- * \param[in] ctx  Talloc context to allocate from.
- * \param[in] mi  Decoded Mobile Identity data.
- * \return a string like "IMSI-1234567", "TMSI-0x1234ABCD" or "NONE", "NULL".
- */
-char *osmo_mobile_identity_to_str_c(void *ctx, const struct osmo_mobile_identity *mi)
-{
-        OSMO_NAME_C_IMPL(ctx, 32, "ERROR", osmo_mobile_identity_to_str_buf, mi)
-}
-
-/*! Compare two osmo_mobile_identity structs, returning typical cmp() result.
- * \param[in] a  Left side osmo_mobile_identity.
- * \param[in] b  Right side osmo_mobile_identity.
- * \returns 0 if both are equal, -1 if a < b, 1 if a > b.
- */
-int osmo_mobile_identity_cmp(const struct osmo_mobile_identity *a, const struct osmo_mobile_identity *b)
-{
-	int cmp;
-	if (a == b)
-		return 0;
-	if (!a)
-		return -1;
-	if (!b)
-		return 1;
-	cmp = OSMO_CMP(a->type, b->type);
-	if (cmp)
-		return cmp;
-	switch (a->type) {
-	case GSM_MI_TYPE_TMSI:
-		return OSMO_CMP(a->tmsi, b->tmsi);
-	case GSM_MI_TYPE_IMSI:
-		return strncmp(a->imsi, b->imsi, sizeof(a->imsi));
-	case GSM_MI_TYPE_IMEI:
-		return strncmp(a->imei, b->imei, sizeof(a->imei));
-	case GSM_MI_TYPE_IMEISV:
-		return strncmp(a->imeisv, b->imeisv, sizeof(a->imeisv));
-	default:
-		/* No known type, but both have the same type. */
-		return 0;
-	}
+	size_t buf_len = 10 + GSM48_MI_SIZE + 1;
+	char *mi_name = talloc_size(ctx, buf_len);
+	if (!mi_name)
+		return NULL;
+	return osmo_mi_name_buf(mi_name, buf_len, mi, mi_len);
 }
 
 /*! Checks is particular message is cipherable in A/Gb mode according to
@@ -1107,76 +676,64 @@
 	}
 }
 
-static int legacy_compat_generate_mid(uint8_t *buf, const struct osmo_mobile_identity *mi)
-{
-	int rc;
-	buf[0] = GSM48_IE_MOBILE_ID;
-	rc = osmo_mobile_identity_encode_buf(buf + 2, GSM48_MID_MAX_SIZE - 2, mi, false);
-	if (rc <= 0)
-		return 0;
-	OSMO_ASSERT(rc <= 9);
-	buf[1] = rc;
-	return 2 + rc;
-}
-
-/*! Deprecated, see osmo_mobile_identity instead.
- * Generate TS 04.08 Mobile ID from TMSI
+/*! Generate TS 04.08 Mobile ID from TMSI
  *  \param[out] buf Caller-provided output buffer (7 bytes)
  *  \param[in] tmsi TMSI to be encoded
  *  \returns number of byes encoded (always 7) */
 int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi)
 {
-	struct osmo_mobile_identity mi = {
-		.type = GSM_MI_TYPE_TMSI,
-		.tmsi = tmsi,
-	};
-	return legacy_compat_generate_mid(buf, &mi);
+	uint32_t tmsi_be = osmo_htonl(tmsi);
+
+	buf[0] = GSM48_IE_MOBILE_ID;
+	buf[1] = GSM48_TMSI_LEN;
+	buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
+	memcpy(&buf[3], &tmsi_be, sizeof(tmsi_be));
+
+	return 7;
 }
 
-/*! Deprecated, see osmo_mobile_identity instead.
- * Generate TS 24.008 §10.5.1.4 Mobile ID of BCD type from ASCII string
+/*! Generate TS 24.008 §10.5.1.4 Mobile ID of BCD type from ASCII string
  *  \param[out] buf Caller-provided output buffer of at least GSM48_MID_MAX_SIZE bytes
  *  \param[in] id Identity to be encoded
  *  \param[in] mi_type Type of identity (e.g. GSM_MI_TYPE_IMSI, IMEI, IMEISV)
  *  \returns number of bytes used in \a buf */
 uint8_t gsm48_generate_mid(uint8_t *buf, const char *id, uint8_t mi_type)
 {
-	struct osmo_mobile_identity mi = { .type = mi_type };
-	switch (mi_type) {
-	case GSM_MI_TYPE_TMSI:
-		mi.tmsi = strtoul(id, NULL, 10);
-		break;
-	case GSM_MI_TYPE_IMSI:
-		OSMO_STRLCPY_ARRAY(mi.imsi, id);
-		break;
-	case GSM_MI_TYPE_IMEI:
-		OSMO_STRLCPY_ARRAY(mi.imei, id);
-		break;
-	case GSM_MI_TYPE_IMEISV:
-		OSMO_STRLCPY_ARRAY(mi.imeisv, id);
-		break;
-	default:
-		return 0;
+	uint8_t length = strnlen(id, 16), i, off = 0, odd = (length & 1) == 1;
+	/* maximum length == 16 (IMEISV) */
+
+	buf[0] = GSM48_IE_MOBILE_ID;
+	buf[2] = osmo_char2bcd(id[0]) << 4 | (mi_type & GSM_MI_TYPE_MASK) | (odd << 3);
+
+	/* if the length is even we will fill half of the last octet */
+	buf[1] = (length + (odd ? 1 : 2)) >> 1;
+	/* buf[1] maximum = 18/2 = 9 */
+	OSMO_ASSERT(buf[1] <= 9);
+
+	for (i = 1; i < buf[1]; ++i) {
+		uint8_t upper, lower = osmo_char2bcd(id[++off]);
+		if (!odd && off + 1 == length)
+			upper = 0x0f;
+		else
+			upper = osmo_char2bcd(id[++off]) & 0x0f;
+
+		buf[2 + i] = (upper << 4) | lower;
 	}
-	return legacy_compat_generate_mid(buf, &mi);
+
+	/* maximum return value: 2 + 9 = 11 */
+	return 2 + buf[1];
 }
 
-/*! Deprecated, see osmo_mobile_identity instead.
- * Generate TS 04.08 Mobile ID from IMSI
+/*! Generate TS 04.08 Mobile ID from IMSI
  *  \param[out] buf Caller-provided output buffer
  *  \param[in] imsi IMSI to be encoded
  *  \returns number of bytes used in \a buf */
 int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi)
 {
-	struct osmo_mobile_identity mi = {
-		.type = GSM_MI_TYPE_IMSI,
-	};
-	OSMO_STRLCPY_ARRAY(mi.imsi, imsi);
-	return legacy_compat_generate_mid(buf, &mi);
+	return gsm48_generate_mid(buf, imsi, GSM_MI_TYPE_IMSI);
 }
 
-/*! Deprecated, see osmo_mobile_identity instead.
- * Convert TS 04.08 Mobile Identity (10.5.1.4) to string.
+/*! Convert TS 04.08 Mobile Identity (10.5.1.4) to string.
  * This function does not validate the Mobile Identity digits, i.e. digits > 9 are returned as 'A'-'F'.
  *  \param[out] string Caller-provided buffer for output
  *  \param[in] str_len Length of \a string in bytes
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 742cec3..ac9aeb2 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -363,14 +363,6 @@
 gsm48_generate_mid_from_imsi;
 gsm48_generate_mid_from_tmsi;
 gsm48_mi_to_string;
-osmo_mobile_identity_to_str_buf;
-osmo_mobile_identity_to_str_c;
-osmo_mobile_identity_cmp;
-osmo_mobile_identity_decode;
-osmo_mobile_identity_decode_from_l3;
-osmo_mobile_identity_encoded_len;
-osmo_mobile_identity_encode_buf;
-osmo_mobile_identity_encode_msgb;
 gsm48_mm_att_tlvdef;
 gsm48_number_of_paging_subchannels;
 gsm48_parse_ra;
diff --git a/src/utils.c b/src/utils.c
index 3c4a8c9..18e105f 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -175,65 +175,6 @@
 	return OSMO_MAX(0, end_nibble - start_nibble);
 }
 
-/*! Convert string to BCD.
- * The given nibble offsets are interpreted in BCD order, i.e. nibble 0 is bcd[0] & 0x0f, nibble 1 is bcd[0] & 0xf0, nibble
- * 3 is bcd[1] & 0x0f, etc..
- *  \param[out] dst  Output BCD buffer.
- *  \param[in] dst_size  sizeof() the output string buffer.
- *  \param[in] digits  String containing decimal or hexadecimal digits in upper or lower case.
- *  \param[in] start_nibble  Offset to start from, in nibbles, typically 1 to skip the first (MI type) nibble.
- *  \param[in] end_nibble  Negative to write all digits found in str, followed by 0xf nibbles to fill any started octet.
- *                         If >= 0, stop before this offset in nibbles, e.g. to get default behavior, pass
- *                         start_nibble + strlen(str) + ((start_nibble + strlen(str)) & 1? 1 : 0) + 1.
- *  \param[in] allow_hex  If false, return error if there are hexadecimal digits (A-F). If true, write those to
- *                        BCD.
- *  \returns The buffer size in octets that is used to place all bcd digits (including the skipped nibbles
- *           from 'start_nibble' and rounded up to full octets); -EINVAL on invalid digits;
- *           -ENOMEM if dst is NULL, if dst_size is too small to contain all nibbles, or if start_nibble is negative.
- */
-int osmo_str2bcd(uint8_t *dst, size_t dst_size, const char *digits, int start_nibble, int end_nibble, bool allow_hex)
-{
-	const char *digit = digits;
-	int nibble_i;
-
-	if (!dst || !dst_size || start_nibble < 0)
-		return -ENOMEM;
-
-	if (end_nibble < 0) {
-		end_nibble = start_nibble + strlen(digits);
-		/* If the last octet is not complete, add another filler nibble */
-		if (end_nibble & 1)
-			end_nibble++;
-	}
-	if ((end_nibble / 2) > dst_size)
-		return -ENOMEM;
-
-	for (nibble_i = start_nibble; nibble_i < end_nibble; nibble_i++) {
-		uint8_t nibble = 0xf;
-		int octet = nibble_i >> 1;
-		if (*digit) {
-			char c = *digit;
-			digit++;
-			if (c >= '0' && c <= '9')
-				nibble = c - '0';
-			else if (allow_hex && c >= 'A' && c <= 'F')
-				nibble = 0xa + (c - 'A');
-			else if (allow_hex && c >= 'a' && c <= 'f')
-				nibble = 0xa + (c - 'a');
-			else
-				return -EINVAL;
-		}
-		nibble &= 0xf;
-		if ((nibble_i & 1))
-			dst[octet] = (nibble << 4) | (dst[octet] & 0x0f);
-		else
-			dst[octet] = (dst[octet] & 0xf0) | nibble;
-	}
-
-	/* floor(float(end_nibble) / 2) */
-	return end_nibble / 2;
-}
-
 /*! Parse a string containing hexadecimal digits
  *  \param[in] str string containing ASCII encoded hexadecimal digits
  *  \param[out] b output buffer
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index a86fe11..9617823 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -18,8 +18,6 @@
  *
  */
 
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -388,9 +386,8 @@
 	{
 		.mi_type = GSM_MI_TYPE_IMSI | GSM_MI_ODD,
 		.mi_str = "423423",
-		.expect_str = "",
-		.expect_rc = 1,
-		.mi_name = "unknown",
+		.mi_name = "IMSI-423423",
+		.expect_mi_tlv_hex = "1704413224f3",
 	},
 	{
 		.mi_type = GSM_MI_TYPE_IMSI,
@@ -474,21 +471,21 @@
 		.mi_type = GSM_MI_TYPE_NONE,
 		.mi_str = "123",
 		.mi_name = "unknown",
-		.expect_mi_tlv_hex = "",
+		.expect_mi_tlv_hex = "17021832", /* encoding invalid MI type */
 		.expect_str = "",
 	},
 	{
 		.mi_type = GSM_MI_TYPE_NONE,
 		.mi_str = "1234",
 		.mi_name = "unknown",
-		.expect_mi_tlv_hex = "",
+		.expect_mi_tlv_hex = "17031032f4", /* encoding invalid MI type */
 		.expect_str = "",
 	},
 	{
 		.mi_type = GSM_MI_ODD,
 		.mi_str = "1234",
 		.mi_name = "unknown",
-		.expect_mi_tlv_hex = "",
+		.expect_mi_tlv_hex = "17031032f4", /* encoding invalid MI type */
 		.expect_str = "",
 	},
 };
@@ -525,14 +522,9 @@
 			printf("     ERROR: expected '%s'\n", t->expect_mi_tlv_hex);
 		}
 
-		if (tlv_len) {
-			/* skip the GSM48_IE_MOBILE_ID tag and length */
-			mi_buf = tlv_buf + 2;
-			mi_len = tlv_len - 2;
-		} else {
-			mi_buf = NULL;
-			mi_len = 0;
-		}
+		/* skip the GSM48_IE_MOBILE_ID tag and length */
+		mi_buf = tlv_buf + 2;
+		mi_len = tlv_len - 2;
 
 		rc = gsm48_mi_to_string(str, str_size, mi_buf, mi_len);
 		printf("  -> MI-str=%s rc=%d\n", osmo_quote_str(str, -1), rc);
@@ -619,368 +611,6 @@
 	printf("\n");
 }
 
-struct msgb *msgb_from_hex(const char *label, uint16_t size, const char *hex)
-{
-	struct msgb *msg = msgb_alloc_headroom(size, 4, label);
-	OSMO_ASSERT(msg);
-	msg->l3h = msgb_put(msg, osmo_hexparse(hex, msg->data, msgb_tailroom(msg)));
-	return msg;
-}
-
-struct mobile_identity_tc {
-	const char *label;
-	const char *compl_l3_msg;
-	int expect_rc;
-	struct osmo_mobile_identity expect_mi;
-};
-
-/* Some Complete Layer 3 messages copied from real GSM network traces. */
-struct mobile_identity_tc mobile_identity_tests[] = {
-	{
-		.label = "LU with IMSI 901700000004620",
-		.compl_l3_msg = "050802008168000130" "089910070000006402",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "901700000004620",
-		},
-	},
-	{
-		.label = "LU with TMSI 0x0980ad8a",
-		.compl_l3_msg = "05084262f224002a50" "05f40980ad8a",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_TMSI,
-			.tmsi = 0x0980ad8a,
-		},
-	},
-	{
-		.label = "LU with invalid MI type",
-		.compl_l3_msg = "050802008168000130" "089d10070000006402",
-		.expect_rc = -EINVAL,
-	},
-	{
-		.label = "LU with truncated IMSI MI",
-		.compl_l3_msg = "050802008168000130" "0899100700000064",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "LU with too short IMSI MI (12345)",
-		.compl_l3_msg = "050802008168000130" "03193254",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "LU with just long enough IMSI MI 123456",
-		.compl_l3_msg = "050802008168000130" "04113254f6",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "123456",
-		},
-	},
-	{
-		.label = "LU with max length IMSI MI 123456789012345",
-		.compl_l3_msg = "050802008168000130" "081932547698103254",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "123456789012345",
-		},
-	},
-	{
-		.label = "LU with just too long IMSI MI 1234567890123456",
-		.compl_l3_msg = "050802008168000130" "091132547698103254f6",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "LU with truncated TMSI MI",
-		.compl_l3_msg = "05084262f224002a50" "05f40980ad",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "LU with odd length TMSI",
-		.compl_l3_msg = "05084262f224002a50" "05fc0980ad8a",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "LU with too long TMSI MI",
-		.compl_l3_msg = "05084262f224002a50" "06f40980ad23",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "LU with too short TMSI",
-		.compl_l3_msg = "05084262f224002a50" "04f480ad8a",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "CM Service Request with IMSI 123456",
-		.compl_l3_msg = "052401035058a6" "04113254f6",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "123456",
-		},
-	},
-	{
-		.label = "CM Service Request with TMSI 0x5a42e404",
-		.compl_l3_msg = "052401035058a6" "05f45a42e404",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_TMSI,
-			.tmsi = 0x5a42e404,
-		},
-	},
-	{
-		.label = "CM Service Request with shorter CM2, with IMSI 123456",
-		.compl_l3_msg = "052401025058" "04113254f6",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "123456",
-		},
-	},
-	{
-		.label = "CM Service Request with longer CM2, with IMSI 123456",
-		.compl_l3_msg = "052401055058a62342" "04113254f6",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "123456",
-		},
-	},
-	{
-		.label = "CM Service Request with shorter CM2, with TMSI 0x00000000",
-		.compl_l3_msg = "052401025058" "05f400000000",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_TMSI,
-			.tmsi = 0,
-		},
-	},
-	{
-		.label = "CM Service Request with invalid MI type",
-		.compl_l3_msg = "052401035058a6" "089d10070000006402",
-		.expect_rc = -EINVAL,
-	},
-	{
-		.label = "CM Service Request with truncated IMSI MI",
-		.compl_l3_msg = "052401035058a6" "0899100700000064",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "CM Service Request with truncated TMSI MI",
-		.compl_l3_msg = "0524010150" "05f40980ad",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "CM Service Request with odd length TMSI",
-		.compl_l3_msg = "052401045058a623" "05fc0980ad8a",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "CM Service Request with too long TMSI MI",
-		.compl_l3_msg = "052401035058a6" "06f40980ad23",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "CM Service Request with too short TMSI",
-		.compl_l3_msg = "052401035058a6" "04f480ad8a",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "CM Service Reestablish Request with TMSI 0x5a42e404",
-		.compl_l3_msg = "052801035058a6" "05f45a42e404",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_TMSI,
-			.tmsi = 0x5a42e404,
-		},
-	},
-	{
-		.label = "Paging Response with IMSI 1234567",
-		.compl_l3_msg = "06270003505886" "0419325476",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "1234567",
-		},
-	},
-	{
-		.label = "Paging Response with TMSI 0xb48883de",
-		.compl_l3_msg = "06270003505886" "05f4b48883de",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_TMSI,
-			.tmsi = 0xb48883de,
-		},
-	},
-	{
-		.label = "Paging Response with TMSI, with unused nibble not 0xf",
-		.compl_l3_msg = "06270003505886" "0504b48883de",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "Paging Response with too short IMEI (1234567)",
-		.compl_l3_msg = "06270003505886" "041a325476",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "Paging Response with IMEI 123456789012345",
-		.compl_l3_msg = "06270003505886" "081a32547698103254",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMEI,
-			.imei = "123456789012345",
-		},
-	},
-	{
-		.label = "Paging Response with IMEI 12345678901234 (no Luhn checksum)",
-		.compl_l3_msg = "06270003505886" "0812325476981032f4",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMEI,
-			.imei = "12345678901234",
-		},
-	},
-	{
-		.label = "Paging Response with IMEISV 1234567890123456",
-		.compl_l3_msg = "06270003505886" "091332547698103254f6",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMEISV,
-			.imeisv = "1234567890123456",
-		},
-	},
-	{
-		.label = "Paging Response with too short IMEISV 123456789012345",
-		.compl_l3_msg = "06270003505886" "081b32547698103254",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "Paging Response with too long IMEISV 12345678901234567",
-		.compl_l3_msg = "06270003505886" "091b3254769810325476",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "Paging Response with IMSI 123456789012345 and flipped ODD bit",
-		.compl_l3_msg = "06270003505886" "081132547698103254",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "IMSI-Detach with IMSI 901700000004620",
-		.compl_l3_msg = "050130" "089910070000006402",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "901700000004620",
-		},
-	},
-	{
-		.label = "IMSI-Detach with TMSI 0x0980ad8a",
-		.compl_l3_msg = "050130" "05f40980ad8a",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_TMSI,
-			.tmsi = 0x0980ad8a,
-		},
-	},
-	{
-		.label = "IMSI-Detach with invalid MI type",
-		.compl_l3_msg = "050130" "089d10070000006402",
-		.expect_rc = -EINVAL,
-	},
-	{
-		.label = "IMSI-Detach with truncated IMSI MI",
-		.compl_l3_msg = "050130" "0899100700000064",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "IMSI-Detach with too short IMSI MI (12345)",
-		.compl_l3_msg = "050130" "03193254",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "IMSI-Detach with just long enough IMSI MI 123456",
-		.compl_l3_msg = "050130" "04113254f6",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "123456",
-		},
-	},
-	{
-		.label = "IMSI-Detach with max length IMSI MI 123456789012345",
-		.compl_l3_msg = "050130" "081932547698103254",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "123456789012345",
-		},
-	},
-	{
-		.label = "IMSI-Detach with just too long IMSI MI 1234567890123456",
-		.compl_l3_msg = "050130" "091132547698103254f6",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "IMSI-Detach with truncated TMSI MI",
-		.compl_l3_msg = "050130" "05f40980ad",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "IMSI-Detach with odd length TMSI",
-		.compl_l3_msg = "050130" "05fc0980ad8a",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "IMSI-Detach with too long TMSI MI",
-		.compl_l3_msg = "050130" "06f40980ad23",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "IMSI-Detach with too short TMSI",
-		.compl_l3_msg = "050130" "04f480ad8a",
-		.expect_rc = -EBADMSG,
-	},
-	{
-		.label = "Identity Response with IMSI 901700000004620",
-		.compl_l3_msg = "0519" "089910070000006402",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMSI,
-			.imsi = "901700000004620",
-		},
-	},
-	{
-		.label = "Identity Response with IMEI 123456789012345",
-		.compl_l3_msg = "0519" "081a32547698103254",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMEI,
-			.imei = "123456789012345",
-		},
-	},
-	{
-		.label = "Identity Response with IMEISV 9876543210987654",
-		.compl_l3_msg = "0519" "099378563412907856f4",
-		.expect_mi = {
-			.type = GSM_MI_TYPE_IMEISV,
-			.imeisv = "9876543210987654",
-		},
-	},
-};
-
-void test_struct_mobile_identity()
-{
-	struct mobile_identity_tc *t;
-	printf("%s()\n", __func__);
-	for (t = mobile_identity_tests; (t - mobile_identity_tests) < ARRAY_SIZE(mobile_identity_tests); t++) {
-		struct osmo_mobile_identity mi;
-		struct msgb *msg;
-		int rc;
-		memset(&mi, 0xff, sizeof(mi));
-
-		msg = msgb_from_hex(t->label, 1024, t->compl_l3_msg);
-		rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false);
-		msgb_free(msg);
-
-		printf("%s: rc = %d", t->label, rc);
-		if (!rc) {
-			printf(", mi = %s", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
-		}
-
-		if (rc == t->expect_rc
-		    && ((rc != 0) || !osmo_mobile_identity_cmp(&mi, &t->expect_mi))) {
-			printf(" ok");
-		} else {
-			printf("  ERROR: Expected rc = %d", t->expect_rc);
-			if (!t->expect_rc)
-				printf(", mi = %s", osmo_mobile_identity_to_str_c(OTC_SELECT, &t->expect_mi));
-		}
-		printf("\n");
-	}
-	printf("\n");
-}
-
 static const struct bcd_number_test {
 	/* Human-readable test name */
 	const char *test_name;
@@ -1552,7 +1182,6 @@
 	test_mid_from_imsi();
 	test_mid_encode_decode();
 	test_mid_decode_zero_length();
-	test_struct_mobile_identity();
 	test_bcd_number_encode_decode();
 	test_ra_cap();
 	test_lai_encode_decode();
diff --git a/tests/gsm0408/gsm0408_test.ok b/tests/gsm0408/gsm0408_test.ok
index f8de54a..d343869 100644
--- a/tests/gsm0408/gsm0408_test.ok
+++ b/tests/gsm0408/gsm0408_test.ok
@@ -17,9 +17,9 @@
   -> MI-str="423423" rc=7
   -> MI-name="IMSI-423423"
 - unknown 0x9 423423
-  -> MI-TLV-hex=''
-  -> MI-str="" rc=1
-  -> MI-name="unknown"
+  -> MI-TLV-hex='1704413224f3'
+  -> MI-str="423423" rc=7
+  -> MI-name="IMSI-423423"
 - IMSI 4234235
   -> MI-TLV-hex='170449322453'
   -> MI-str="4234235" rc=8
@@ -65,15 +65,15 @@
   -> MI-str="3054" rc=9
   -> MI-name="TMSI-0x12345678"
 - NONE 123
-  -> MI-TLV-hex=''
+  -> MI-TLV-hex='17021832'
   -> MI-str="" rc=1
   -> MI-name="unknown"
 - NONE 1234
-  -> MI-TLV-hex=''
+  -> MI-TLV-hex='17031032f4'
   -> MI-str="" rc=1
   -> MI-name="unknown"
 - unknown 0x8 1234
-  -> MI-TLV-hex=''
+  -> MI-TLV-hex='17031032f4'
   -> MI-str="" rc=1
   -> MI-name="unknown"
 
@@ -139,57 +139,6 @@
     rc=1
     returned empty string
 
-test_struct_mobile_identity()
-LU with IMSI 901700000004620: rc = 0, mi = IMSI-901700000004620 ok
-LU with TMSI 0x0980ad8a: rc = 0, mi = TMSI-0x0980AD8A ok
-LU with invalid MI type: rc = -22 ok
-LU with truncated IMSI MI: rc = -74 ok
-LU with too short IMSI MI (12345): rc = -74 ok
-LU with just long enough IMSI MI 123456: rc = 0, mi = IMSI-123456 ok
-LU with max length IMSI MI 123456789012345: rc = 0, mi = IMSI-123456789012345 ok
-LU with just too long IMSI MI 1234567890123456: rc = -74 ok
-LU with truncated TMSI MI: rc = -74 ok
-LU with odd length TMSI: rc = -74 ok
-LU with too long TMSI MI: rc = -74 ok
-LU with too short TMSI: rc = -74 ok
-CM Service Request with IMSI 123456: rc = 0, mi = IMSI-123456 ok
-CM Service Request with TMSI 0x5a42e404: rc = 0, mi = TMSI-0x5A42E404 ok
-CM Service Request with shorter CM2, with IMSI 123456: rc = 0, mi = IMSI-123456 ok
-CM Service Request with longer CM2, with IMSI 123456: rc = 0, mi = IMSI-123456 ok
-CM Service Request with shorter CM2, with TMSI 0x00000000: rc = 0, mi = TMSI-0x00000000 ok
-CM Service Request with invalid MI type: rc = -22 ok
-CM Service Request with truncated IMSI MI: rc = -74 ok
-CM Service Request with truncated TMSI MI: rc = -74 ok
-CM Service Request with odd length TMSI: rc = -74 ok
-CM Service Request with too long TMSI MI: rc = -74 ok
-CM Service Request with too short TMSI: rc = -74 ok
-CM Service Reestablish Request with TMSI 0x5a42e404: rc = 0, mi = TMSI-0x5A42E404 ok
-Paging Response with IMSI 1234567: rc = 0, mi = IMSI-1234567 ok
-Paging Response with TMSI 0xb48883de: rc = 0, mi = TMSI-0xB48883DE ok
-Paging Response with TMSI, with unused nibble not 0xf: rc = -74 ok
-Paging Response with too short IMEI (1234567): rc = -74 ok
-Paging Response with IMEI 123456789012345: rc = 0, mi = IMEI-123456789012345 ok
-Paging Response with IMEI 12345678901234 (no Luhn checksum): rc = 0, mi = IMEI-12345678901234 ok
-Paging Response with IMEISV 1234567890123456: rc = 0, mi = IMEI-SV-1234567890123456 ok
-Paging Response with too short IMEISV 123456789012345: rc = -74 ok
-Paging Response with too long IMEISV 12345678901234567: rc = -74 ok
-Paging Response with IMSI 123456789012345 and flipped ODD bit: rc = -74 ok
-IMSI-Detach with IMSI 901700000004620: rc = 0, mi = IMSI-901700000004620 ok
-IMSI-Detach with TMSI 0x0980ad8a: rc = 0, mi = TMSI-0x0980AD8A ok
-IMSI-Detach with invalid MI type: rc = -22 ok
-IMSI-Detach with truncated IMSI MI: rc = -74 ok
-IMSI-Detach with too short IMSI MI (12345): rc = -74 ok
-IMSI-Detach with just long enough IMSI MI 123456: rc = 0, mi = IMSI-123456 ok
-IMSI-Detach with max length IMSI MI 123456789012345: rc = 0, mi = IMSI-123456789012345 ok
-IMSI-Detach with just too long IMSI MI 1234567890123456: rc = -74 ok
-IMSI-Detach with truncated TMSI MI: rc = -74 ok
-IMSI-Detach with odd length TMSI: rc = -74 ok
-IMSI-Detach with too long TMSI MI: rc = -74 ok
-IMSI-Detach with too short TMSI: rc = -74 ok
-Identity Response with IMSI 901700000004620: rc = 0, mi = IMSI-901700000004620 ok
-Identity Response with IMEI 123456789012345: rc = 0, mi = IMEI-123456789012345 ok
-Identity Response with IMEISV 9876543210987654: rc = 0, mi = IMEI-SV-9876543210987654 ok
-
 BSD number encoding / decoding test
 - Running test: regular 9-digit MSISDN
   - Encoding ASCII (buffer limit=0) '123456789'...
diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c
index e15cf5f..e87cb22 100644
--- a/tests/utils/utils_test.c
+++ b/tests/utils/utils_test.c
@@ -487,7 +487,6 @@
 {
 	int i;
 	uint8_t bcd[64];
-	uint8_t bcd2[64];
 	int rc;
 
 	printf("\nTesting bcd to string conversion\n");
@@ -512,12 +511,6 @@
 			printf("    ERROR: expected rc=%d\n", t->expect_rc);
 		if (strcmp(str, t->expect_str))
 			printf("    ERROR: expected result %s\n", osmo_quote_str(t->expect_str, -1));
-
-		memset(bcd2, 0xff, sizeof(bcd2));
-		rc = osmo_str2bcd(bcd2, sizeof(bcd2), str, t->start_nibble, -1, t->allow_hex);
-		printf("osmo_str2bcd(start_nibble=%d) -> rc=%d\n", t->start_nibble, rc);
-		if (rc > 0)
-			printf(" = %s\n", osmo_hexdump(bcd2, rc));
 	}
 
 	printf("- zero output buffer\n");
diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok
index cbab72a..baa708e 100644
--- a/tests/utils/utils_test.ok
+++ b/tests/utils/utils_test.ok
@@ -181,41 +181,27 @@
 - BCD-input='1a 32 54 76 98 f0' nibbles=[1..11[ str_size=64
   rc=10
   -> "1234567890"
-osmo_str2bcd(start_nibble=1) -> rc=6
- = 1f 32 54 76 98 f0 
 - BCD-input='1a 32 a4 cb 9d f0' nibbles=[1..11[ str_size=64
   rc=-22
   -> "1234ABCD90"
-osmo_str2bcd(start_nibble=1) -> rc=-22
 - BCD-input='1a 32 a4 cb 9d f0' nibbles=[1..11[ str_size=64
   rc=10
   -> "1234ABCD90"
-osmo_str2bcd(start_nibble=1) -> rc=6
- = 1f 32 a4 cb 9d f0 
 - BCD-input='1a 32 54 76 98 f0' nibbles=[1..12[ str_size=64
   rc=-22
   -> "1234567890F"
-osmo_str2bcd(start_nibble=1) -> rc=-22
 - BCD-input='1a 32 54 76 98 f0' nibbles=[1..12[ str_size=64
   rc=11
   -> "1234567890F"
-osmo_str2bcd(start_nibble=1) -> rc=6
- = 1f 32 54 76 98 f0 
 - BCD-input='1a 32 54 76 98 f0' nibbles=[0..12[ str_size=64
   rc=12
   -> "A1234567890F"
-osmo_str2bcd(start_nibble=0) -> rc=6
- = 1a 32 54 76 98 f0 
 - BCD-input='1a 32 54 76 98 f0' nibbles=[1..12[ str_size=5
   rc=11
   -> "1234"
-osmo_str2bcd(start_nibble=1) -> rc=3
- = 1f 32 f4 
 - BCD-input='' nibbles=[1..1[ str_size=64
   rc=0
   -> ""
-osmo_str2bcd(start_nibble=1) -> rc=1
- = ff 
 - zero output buffer
   bcd2str(NULL, ...) -> -12
   bcd2str(dst, 0, ...) -> -12

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

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I4bd958d0cd2ab4b0c4725e6d114f4404d725fcf7
Gerrit-Change-Number: 18853
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200616/3ed69fd0/attachment.htm>


More information about the gerrit-log mailing list