Change in libosmocore[master]: gsm0408/gsm0408_test.c: introduce BCD number encoding / decoding test

Harald Welte gerrit-no-reply at lists.osmocom.org
Tue May 28 06:33:14 UTC 2019


Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/14184 )

Change subject: gsm0408/gsm0408_test.c: introduce BCD number encoding / decoding test
......................................................................

gsm0408/gsm0408_test.c: introduce BCD number encoding / decoding test

So far, both gsm48_encode_bcd_number() and gsm48_decode_bcd_number2()
did not have any unit test coverage. Let's fill this gap by testing
the following scenarios:

  - encoding / decoding of a regular 9-digit MSISDN;
  - encoding / decoding of a MSISDN with optional LHV;
  - encoding / decoding of a long 15-digit MSISDN;
  - encoding / decoding of a MSISDN to a buffer:
    - with exactly matching size,
    - with lower size (truncation);
  - decoding LV buffer with incorrect length,
  - encoding / decoding an empty input buffer.

As it turns out, gsm48_decode_bcd_number2() does not properly
handle encoded LV if the output buffer size is equal to the
original MSISDN length + 1 (\0-terminator): one digit is lost.

For example, decoding of 15-digit long MSISDN to a buffer of size
16 (15 digits + 1 for \0) would give us only 14 digits. This is
reflected in the unit test output:

  Decoding HEX (buffer limit=16) '0821436587092143f5'...
    Expected: (rc=0) '123456789012345'
      Actual: (rc=0) '12345678901234'

Moreover, if the output buffer is shorter than decoded number,
gsm48_decode_bcd_number2() silently truncates it and returns 0,
while its description states, that the rc should reflect this.

To be fixed in the follow-up patches.

Change-Id: I4b2c330cf8ffe4427c0bee7d5f3b74be56ecd85d
Related: OS#4025
---
M tests/gsm0408/gsm0408_test.c
M tests/gsm0408/gsm0408_test.ok
2 files changed, 224 insertions(+), 0 deletions(-)

Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved
  Pau Espin Pedrol: Looks good to me, but someone else must approve



diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index 2d60b84..3ccbf4d 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -610,6 +610,181 @@
 	printf("\n");
 }
 
+static const struct bcd_number_test {
+	/* Human-readable test name */
+	const char *test_name;
+
+	/* To be encoded number in ASCII */
+	const char *enc_ascii;
+	/* Expected encoding result in HEX */
+	const char *enc_hex;
+	/* Optional header length (LHV) */
+	uint8_t enc_h_len;
+	/* Expected return code */
+	int enc_rc;
+
+	/* To be decoded buffer in HEX */
+	const char *dec_hex;
+	/* Expected decoding result in ASCII */
+	const char *dec_ascii;
+	/* Optional header length (LHV) */
+	uint8_t dec_h_len;
+	/* Expected return code */
+	int dec_rc;
+
+	/* Encoding buffer limit (0 means unlimited) */
+	size_t enc_buf_lim;
+	/* Decoding buffer limit (0 means unlimited) */
+	size_t dec_buf_lim;
+} bcd_number_test_set[] = {
+	{
+		.test_name = "regular 9-digit MSISDN",
+
+		/* Encoding test */
+		.enc_ascii = "123456789",
+		.enc_hex   = "0521436587f9",
+		.enc_rc    = 6,
+
+		/* Decoding test */
+		.dec_hex   = "0521436587f9",
+		.dec_ascii = "123456789",
+	},
+	{
+		.test_name = "regular 6-digit MSISDN with optional header (LHV)",
+
+		/* Encoding test */
+		.enc_ascii = "123456",
+		.enc_hex   = "0700000000214365",
+		.enc_h_len = 4, /* LHV */
+		.enc_rc    = 4 + 4,
+
+		/* Decoding test */
+		.dec_hex   = "07deadbeef214365",
+		.dec_ascii = "123456",
+		.dec_h_len = 4, /* LHV */
+	},
+	{
+		.test_name = "long 15-digit (maximum) MSISDN",
+
+		/* Encoding test */
+		.enc_ascii = "123456789012345",
+		.enc_hex   = "0821436587092143f5",
+		.enc_rc    = 9,
+
+		/* Decoding test */
+		.dec_hex   = "0821436587092143f5",
+		.dec_ascii = "123456789012345",
+	},
+	{
+		.test_name = "long 15-digit (maximum) MSISDN, limited buffer",
+
+		/* Encoding test */
+		.enc_ascii = "123456789012345",
+		.enc_hex   = "0821436587092143f5",
+		.enc_rc    = 9,
+
+		/* Decoding test */
+		.dec_hex   = "0821436587092143f5",
+		.dec_ascii = "123456789012345",
+
+		/* Buffer length limitations */
+		.dec_buf_lim = 15 + 1,
+		.enc_buf_lim = 9,
+	},
+	{
+		.test_name = "to be truncated 20-digit MSISDN",
+
+		/* Encoding test (not enough room in buffer) */
+		.enc_ascii = "12345678901234567890",
+		.enc_hex   = "", /* nothing */
+		.enc_rc    = -EIO,
+
+		/* Decoding test (one 5 digits do not fit) */
+		.dec_hex   = "0a21436587092143658709",
+		.dec_ascii = "123456789012345",
+		.dec_rc    = 0,
+
+		/* Buffer length limitations */
+		.dec_buf_lim = 15 + 1, /* 5 digits less */
+		.enc_buf_lim = 9,
+	},
+	{
+		.test_name = "LV incorrect length",
+		.dec_hex   = "05214365", /* should be 0x03 */
+		.dec_ascii = "(none)",
+		.dec_rc    = -EIO,
+	},
+	{
+		.test_name = "empty input buffer",
+
+		/* Encoding test */
+		.enc_ascii = "",
+		.enc_hex   = "00",
+		.enc_rc    = 1,
+
+		/* Decoding test */
+		.dec_hex   = "",
+		.dec_ascii = "(none)",
+		.dec_rc = -EIO,
+	},
+};
+
+static void test_bcd_number_encode_decode()
+{
+	const struct bcd_number_test *test;
+	uint8_t buf_enc[0xff] = { 0 };
+	char buf_dec[0xff] = { 0 };
+	size_t buf_len, i;
+	int rc;
+
+	printf("BSD number encoding / decoding test\n");
+
+	for (i = 0; i < ARRAY_SIZE(bcd_number_test_set); i++) {
+		test = &bcd_number_test_set[i];
+		printf("- Running test: %s\n", test->test_name);
+
+		if (test->enc_ascii) {
+			if (test->enc_buf_lim)
+				buf_len = test->enc_buf_lim;
+			else
+				buf_len = sizeof(buf_enc);
+
+			printf("  - Encoding ASCII (buffer limit=%zu) '%s'...\n",
+			       test->enc_buf_lim, test->enc_ascii);
+
+			rc = gsm48_encode_bcd_number(buf_enc, buf_len,
+				test->enc_h_len, test->enc_ascii);
+			printf("    - Expected: (rc=%d) '%s'\n",
+			       test->enc_rc, test->enc_hex);
+			printf("    -   Actual: (rc=%d) '%s'\n",
+			       rc, osmo_hexdump_nospc(buf_enc, rc >= 0 ? rc : 0));
+		}
+
+		if (test->dec_hex) {
+			/* Parse a HEX string */
+			rc = osmo_hexparse(test->dec_hex, buf_enc, sizeof(buf_enc));
+			OSMO_ASSERT(rc >= 0);
+
+			if (test->dec_buf_lim)
+				buf_len = test->dec_buf_lim;
+			else
+				buf_len = sizeof(buf_dec);
+
+			printf("  - Decoding HEX (buffer limit=%zu) '%s'...\n",
+			       test->dec_buf_lim, test->dec_hex);
+
+			rc = gsm48_decode_bcd_number2(buf_dec, buf_len,
+				buf_enc, rc, test->dec_h_len);
+			printf("    - Expected: (rc=%d) '%s'\n",
+			       test->dec_rc, test->dec_ascii);
+			printf("    -   Actual: (rc=%d) '%s'\n",
+			       rc, rc == 0 ? buf_dec : "(none)");
+		}
+	}
+
+	printf("\n");
+}
+
 struct {
 	int range;
 	int arfcns_num;
@@ -949,6 +1124,7 @@
 	test_mid_from_imsi();
 	test_mid_encode_decode();
 	test_mid_decode_zero_length();
+	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 0bd101d..2441b2b 100644
--- a/tests/gsm0408/gsm0408_test.ok
+++ b/tests/gsm0408/gsm0408_test.ok
@@ -139,6 +139,54 @@
     rc=1
     returned empty string
 
+BSD number encoding / decoding test
+- Running test: regular 9-digit MSISDN
+  - Encoding ASCII (buffer limit=0) '123456789'...
+    - Expected: (rc=6) '0521436587f9'
+    -   Actual: (rc=6) '0521436587f9'
+  - Decoding HEX (buffer limit=0) '0521436587f9'...
+    - Expected: (rc=0) '123456789'
+    -   Actual: (rc=0) '123456789'
+- Running test: regular 6-digit MSISDN with optional header (LHV)
+  - Encoding ASCII (buffer limit=0) '123456'...
+    - Expected: (rc=8) '0700000000214365'
+    -   Actual: (rc=8) '0721436587214365'
+  - Decoding HEX (buffer limit=0) '07deadbeef214365'...
+    - Expected: (rc=0) '123456'
+    -   Actual: (rc=0) '123456'
+- Running test: long 15-digit (maximum) MSISDN
+  - Encoding ASCII (buffer limit=0) '123456789012345'...
+    - Expected: (rc=9) '0821436587092143f5'
+    -   Actual: (rc=9) '0821436587092143f5'
+  - Decoding HEX (buffer limit=0) '0821436587092143f5'...
+    - Expected: (rc=0) '123456789012345'
+    -   Actual: (rc=0) '123456789012345'
+- Running test: long 15-digit (maximum) MSISDN, limited buffer
+  - Encoding ASCII (buffer limit=9) '123456789012345'...
+    - Expected: (rc=9) '0821436587092143f5'
+    -   Actual: (rc=9) '0821436587092143f5'
+  - Decoding HEX (buffer limit=16) '0821436587092143f5'...
+    - Expected: (rc=0) '123456789012345'
+    -   Actual: (rc=0) '12345678901234'
+- Running test: to be truncated 20-digit MSISDN
+  - Encoding ASCII (buffer limit=9) '12345678901234567890'...
+    - Expected: (rc=-5) ''
+    -   Actual: (rc=-5) ''
+  - Decoding HEX (buffer limit=16) '0a21436587092143658709'...
+    - Expected: (rc=0) '123456789012345'
+    -   Actual: (rc=0) '12345678901234'
+- Running test: LV incorrect length
+  - Decoding HEX (buffer limit=0) '05214365'...
+    - Expected: (rc=-5) '(none)'
+    -   Actual: (rc=-5) '(none)'
+- Running test: empty input buffer
+  - Encoding ASCII (buffer limit=0) ''...
+    - Expected: (rc=1) '00'
+    -   Actual: (rc=1) '00'
+  - Decoding HEX (buffer limit=0) ''...
+    - Expected: (rc=-5) '(none)'
+    -   Actual: (rc=-5) '(none)'
+
 Constructed RA:
 077-121-666-5
 MCC+MNC in BCD: 70 17 21 

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

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I4b2c330cf8ffe4427c0bee7d5f3b74be56ecd85d
Gerrit-Change-Number: 14184
Gerrit-PatchSet: 6
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder (1000002)
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Pau Espin Pedrol <pespin at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190528/fc8c5191/attachment.html>


More information about the gerrit-log mailing list