diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2020-05-26 02:45:23 +0200 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2020-06-12 16:35:26 +0200 |
commit | d1ceca9d48eb3d8b212f386a1ebb35d8fc612297 (patch) | |
tree | ed3b0558378654bf1699c98b766b78520dde2d97 /tests/utils | |
parent | 0b6a8c8446497da32970b8442c68eca796518b6d (diff) |
add osmo_mobile_identity API
Implement better API around 3GPP TS 24.008 Mobile Identity coding.
struct osmo_mobile_identity is a decoded representation of the raw Mobile
Identity, with a string representation as well as dedicated raw uint32_t TMSI.
The aim is to remove all uncertainty about decoded buffer sizes / data types.
I have patches ready for all osmo programs, completely replacing the Mobile
Identity coding with this new API. Hence deprecate the old MI API.
New API functions provide properly size-checking implementations of:
- decoding a raw MI from a bunch of MI octets;
- locating and decoding MI from a full 3GPP TS 24.008 Complete Layer 3 msgb;
- encoding to a buffer;
- encoding to the end of a msgb.
Other than the old gsm48_generate_mid(), omit a TLV tag and length from
encoding. Many callers manually stripped the tag and value after calling
gsm48_generate_mid(). The aim is to leave writing a TL to the caller entirely,
especially since some callers need to use a TvL, i.e. support a variable-size
length of 8 or 16 bit.
New validity checks so far not implemented anywhere else:
- stricter validation of number of digits of IMSI, IMEI, IMEI-SV MI.
- stricter on filler nibbles to be 0xf.
Rationale:
While implementing osmo-bsc's MSC pooling feature in osmo-bsc, this API will be
used to reduce the number of times a Mobile Identity is extracted from a raw
RSL message.
Extracting the Mobile Identity from messages has numerous duplicate
implementations across our code with various levels of specialization.
https://xkcd.com/927/
To name a few:
- libosmocore: gsm48_mi_to_string(), osmo_mi_name_buf()
- osmo-bsc: extract_sub()
- osmo-msc: mm_rx_loc_upd_req(), cm_serv_reuse_conn(), gsm48_rx_mm_serv_req(),
vlr_proc_acc_req()
We have existing functions to produce a human readable string from a Mobile
Identity, more or less awkward:
- gsm48_mi_to_string() decodes a TMSI as a decimal number. These days we use
hexadecimal TMSI everywhere.
- osmo_mi_name_buf() decodes the BCD digits from a raw MI every time, so we'd
need to pass around the raw message bytes. Also, osmo_mi_name_buf() has the
wrong signature, it should return a length like snprintf().
- osmo-bsc's extract_sub() first uses gsm48_mi_to_string() which encodes the
raw uint32_t TMSI to a string, and then calls strtoul() via
tmsi_from_string() to code those back to a raw uint32_t.
Each of the above implementations employ their own size overflow checks, each
invoke osmo_bcd2str() and implement their own TMSI osmo_load32be() handling.
Too much code dup, let's hope that each and every one is correct.
In osmo-bsc, I am now implementing MSC pooling, and need to extract NRI bits
from a TMSI Mobile Identity. Since none of the above functions are general
enough to be re-used, I found myself again copy-pasting Mobile Identity code:
locating the MI in a 24.008 message with proper size checks, decoding MI
octets.
This time I would like it to become a generally re-usable API.
Change-Id: Ic3f969e739654c1e8c387aedeeba5cce07fe2307
Diffstat (limited to 'tests/utils')
-rw-r--r-- | tests/utils/utils_test.c | 7 | ||||
-rw-r--r-- | tests/utils/utils_test.ok | 14 |
2 files changed, 21 insertions, 0 deletions
diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c index e87cb22f..e15cf5f6 100644 --- a/tests/utils/utils_test.c +++ b/tests/utils/utils_test.c @@ -487,6 +487,7 @@ static void bcd2str_test(void) { int i; uint8_t bcd[64]; + uint8_t bcd2[64]; int rc; printf("\nTesting bcd to string conversion\n"); @@ -511,6 +512,12 @@ static void bcd2str_test(void) 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 baa708ee..cbab72a9 100644 --- a/tests/utils/utils_test.ok +++ b/tests/utils/utils_test.ok @@ -181,27 +181,41 @@ Testing bcd to string conversion - 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 |