From aa0683d9f8290515fb9c6681727beeba39a72c1e Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Sat, 25 May 2019 23:14:00 +0700 Subject: 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 --- tests/gsm0408/gsm0408_test.c | 176 ++++++++++++++++++++++++++++++++++++++++++ tests/gsm0408/gsm0408_test.ok | 48 ++++++++++++ 2 files changed, 224 insertions(+) diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c index 2d60b845..3ccbf4dd 100644 --- a/tests/gsm0408/gsm0408_test.c +++ b/tests/gsm0408/gsm0408_test.c @@ -610,6 +610,181 @@ static void test_mid_decode_zero_length(void) 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 @@ int main(int argc, char **argv) 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 0bd101de..2441b2b4 100644 --- a/tests/gsm0408/gsm0408_test.ok +++ b/tests/gsm0408/gsm0408_test.ok @@ -139,6 +139,54 @@ Decoding zero length Mobile Identities 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 -- cgit v1.2.3