Change in libosmocore[master]: add osmo_bsc2str()

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

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Wed Dec 5 23:41:51 UTC 2018


Neels Hofmeyr has uploaded this change for review. ( https://gerrit.osmocom.org/12153


Change subject: add osmo_bsc2str()
......................................................................

add osmo_bsc2str()

Add a standalone bcd-to-string conversion function with generic parameters.
Add a regression test in utils_test.c.

So far there is no single universal implementation that converts a BCD to a
string. I could only find gsm48_mi_to_string(), which also interprets
surrounding bytes, MI type and TMSI as non-BCD value.

The idea is to use this function from gsm48_mi_to_string() and similar
implementations in subsequent commits.

Root cause: in osmo-msc, I want to have an alternative MI-to-string function
for composing an FSM name, which needs the BCD part of gsm48_mi_to_string() but
not the TMSI part.

Change-Id: I86b09d37ceef33331c1a56046a5443127d6c6be0
---
M include/osmocom/core/utils.h
M src/utils.c
M tests/utils/utils_test.c
M tests/utils/utils_test.ok
4 files changed, 131 insertions(+), 0 deletions(-)



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

diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index 0b54c88..34e6a4a 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -49,6 +49,8 @@
 /* only works for numbers in ascci */
 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);
+
 int osmo_hexparse(const char *str, uint8_t *b, int max_len);
 
 char *osmo_ubit_dump(const uint8_t *bits, unsigned int len);
diff --git a/src/utils.c b/src/utils.c
index e6adcf8..a86b0fb 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -129,6 +129,38 @@
 		return 0;
 }
 
+/*! Convert BCD to string.
+ * The given nibble offsets are interpreted in BCD order, i.e. nibble 0 is bcd[0] & 0xf, nibble 1 is bcd[0] >> 4, nibble
+ * 3 is bcd[1] & 0xf, etc..
+ *  \param[out] dst  Output string buffer, is always nul terminated when dst_size > 0.
+ *  \param[in] dst_size  sizeof() the output string buffer.
+ *  \param[in] bcd  Binary coded data buffer.
+ *  \param[in] start_nibble  Offset to start from, in nibbles, typically 1 to skip the first nibble.
+ *  \param[in] end_nibble  Offset to stop before, in nibbles, e.g. sizeof(bcd) - (bcd[0] & GSM_MI_ODD? 0:1).
+ *  \returns The strlen that would be written if the output buffer is large enough, excluding nul byte (like
+ *           snprintf()).
+ */
+int osmo_bcd2str(char *dst, size_t dst_size, const uint8_t bcd[], int start_nibble, int end_nibble)
+{
+	char *dst_end = dst + dst_size - 1;
+	int nibble_i;
+
+	for (nibble_i = start_nibble; nibble_i < end_nibble && dst < dst_end; nibble_i++, dst++) {
+		uint8_t nibble = bcd[nibble_i >> 1];
+		if ((nibble_i & 1))
+			nibble >>= 4;
+		nibble &= 0xf;
+
+		*dst = osmo_bcd2char(nibble);
+	}
+
+	/* Always terminate, but guard against zero dst_size */
+	if (dst <= dst_end)
+		*dst = '\0';
+
+	return OSMO_MAX(0, end_nibble - start_nibble);
+}
+
 /*! Parse a string containing hexadecimal digits
  *  \param[in] str string containing ASCII encoded hexadecimal digits
  *  \param[out] b output buffer
diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c
index 2bb1f9c..f8ff105 100644
--- a/tests/utils/utils_test.c
+++ b/tests/utils/utils_test.c
@@ -383,6 +383,85 @@
 	}
 }
 
+struct bcd2str_test {
+	const char *bcd_hex;
+	int start_nibble;
+	int end_nibble;
+	size_t str_size;
+	const char *expect_str;
+	int expect_rc;
+};
+
+static const struct bcd2str_test bcd2str_tests[] = {
+	{
+		.bcd_hex = "1a 32 54 76 98 f0",
+		.start_nibble = 1,
+		.end_nibble = 11,
+		.expect_str = "1234567890",
+		.expect_rc = 10,
+	},
+	{
+		.bcd_hex = "1a 32 54 76 98 f0",
+		.start_nibble = 1,
+		.end_nibble = 12,
+		.expect_str = "1234567890F",
+		.expect_rc = 11,
+	},
+	{
+		.bcd_hex = "1a 32 54 76 98 f0",
+		.start_nibble = 0,
+		.end_nibble = 12,
+		.expect_str = "A1234567890F",
+		.expect_rc = 12,
+	},
+	{
+		.bcd_hex = "1a 32 54 76 98 f0",
+		.start_nibble = 1,
+		.end_nibble = 12,
+		.str_size = 5,
+		.expect_str = "1234",
+		.expect_rc = 11,
+	},
+	{
+		.bcd_hex = "",
+		.start_nibble = 1,
+		.end_nibble = 1,
+		.expect_str = "",
+		.expect_rc = 0,
+	},
+};
+
+static void bcd2str_test(void)
+{
+	int i;
+
+	printf("\nTesting bcd to string conversion\n");
+
+	for (i = 0; i < ARRAY_SIZE(bcd2str_tests); i++) {
+		const struct bcd2str_test *t = &bcd2str_tests[i];
+		uint8_t bcd[64];
+		char str[64] = {};
+		size_t str_size = t->str_size ? : sizeof(str);
+		int rc;
+
+		osmo_hexparse(t->bcd_hex, bcd, sizeof(bcd));
+
+		printf("- BCD-input='%s' nibbles=[%d..%d[ str_size=%zu\n", t->bcd_hex,
+		       t->start_nibble, t->end_nibble, str_size);
+		rc = osmo_bcd2str(str, str_size, bcd, t->start_nibble, t->end_nibble);
+
+		printf("  rc=%d\n", rc);
+
+		OSMO_ASSERT(str[str_size-1] == '\0');
+		printf("  -> %s\n", osmo_quote_str(str, -1));
+
+		if (rc != t->expect_rc)
+			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));
+	}
+}
+
 static void str_escape_test(void)
 {
 	int i;
@@ -810,6 +889,7 @@
 	test_ipa_ccm_id_resp_parsing();
 	test_is_hexstr();
 	bcd_test();
+	bcd2str_test();
 	str_escape_test();
 	str_quote_test();
 	isqrt_test();
diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok
index 3ea8ec6..69cc690 100644
--- a/tests/utils/utils_test.ok
+++ b/tests/utils/utils_test.ok
@@ -80,6 +80,23 @@
 	val=0xe, expected=E, found=E
 	val=0xf, expected=F, found=F
 
+Testing bcd to string conversion
+- BCD-input='1a 32 54 76 98 f0' nibbles=[1..11[ str_size=64
+  rc=10
+  -> "1234567890"
+- BCD-input='1a 32 54 76 98 f0' nibbles=[1..12[ str_size=64
+  rc=11
+  -> "1234567890F"
+- BCD-input='1a 32 54 76 98 f0' nibbles=[0..12[ str_size=64
+  rc=12
+  -> "A1234567890F"
+- BCD-input='1a 32 54 76 98 f0' nibbles=[1..12[ str_size=5
+  rc=11
+  -> "1234"
+- BCD-input='' nibbles=[1..1[ str_size=64
+  rc=0
+  -> ""
+
 Testing string escaping
 - all chars from 0 to 255 in batches of 16:
 "\0\1\2\3\4\5\6\a\b\t\n\v\f\r\14\15"

-- 
To view, visit https://gerrit.osmocom.org/12153
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: I86b09d37ceef33331c1a56046a5443127d6c6be0
Gerrit-Change-Number: 12153
Gerrit-PatchSet: 1
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20181205/48e20bce/attachment.htm>


More information about the gerrit-log mailing list