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 gerrit-no-reply at lists.osmocom.orgneels has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/18506 ) Change subject: add TMSI and NRI utility functions for MSC pooling ...................................................................... add TMSI and NRI utility functions for MSC pooling These utilities will be used by osmo-bsc to determine the Network Resource Indicator seen in the TMSI, and by osmo-msc to compose a TMSI with a specific NRI, for osmo-bsc's load balancing between several MSCs. Related: OS#3682 Change-Id: Icb57a2dd9323c7ea11b34003eccc7e68a0247bf5 --- M include/Makefile.am A include/osmocom/gsm/gsm23236.h M src/gsm/Makefile.am A src/gsm/gsm23236.c M src/gsm/libosmogsm.map M tests/Makefile.am A tests/gsm23236/gsm23236_test.c A tests/gsm23236/gsm23236_test.ok M tests/testsuite.at 9 files changed, 306 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/06/18506/1 diff --git a/include/Makefile.am b/include/Makefile.am index 572c880..841e911 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -95,6 +95,7 @@ osmocom/gsm/gsm29205.h \ osmocom/gsm/gsm0808_utils.h \ osmocom/gsm/gsm23003.h \ + osmocom/gsm/gsm23236.h \ osmocom/gsm/gsm29118.h \ osmocom/gsm/gsm48.h \ osmocom/gsm/gsm48_arfcn_range_encode.h \ diff --git a/include/osmocom/gsm/gsm23236.h b/include/osmocom/gsm/gsm23236.h new file mode 100644 index 0000000..8cc58e0 --- /dev/null +++ b/include/osmocom/gsm/gsm23236.h @@ -0,0 +1,10 @@ +/*! \file gsm23236.h */ + +#pragma once + +#include <stdint.h> + +#define OSMO_TMSI_UNASSIGNED 0xffffffff + +int16_t osmo_tmsi_nri_get(uint32_t tmsi, uint8_t nri_bitlen); +uint32_t osmo_tmsi_nri_set(uint32_t tmsi, uint8_t nri_bitcount, uint16_t v); diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 6935eab..23d8324 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -31,7 +31,7 @@ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ gsup.c gsup_sms.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \ - gsm23003.c mncc.c bts_features.c oap_client.c \ + gsm23003.c gsm23236.c mncc.c bts_features.c oap_client.c \ gsm29118.c gsm48_rest_octets.c cbsp.c gsm48049.c libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = $(top_builddir)/src/libosmocore.la diff --git a/src/gsm/gsm23236.c b/src/gsm/gsm23236.c new file mode 100644 index 0000000..02060a6 --- /dev/null +++ b/src/gsm/gsm23236.c @@ -0,0 +1,63 @@ +/*! \file gsm23236.c + * Utility function implementations related to 3GPP TS 23.236 */ +/* + * (C) 2020 sysmocom - s.f.m.c. GmbH <info at sysmocom.de> + * Author: Neels Hofmeyr <nhofmeyr at sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <osmocom/gsm/gsm23236.h> + +/*! Retrieve the Network Resource Indicator bits from a TMSI or p-TMSI. + * Useful for MSC pooling as described by 3GPP TS 23.236. + * \param[in] tmsi TMSI value containing NRI bits. + * \param[in] nri_bitlen Length of the NRI value in number of bits, 1 <= nri_bitlen <= 10. + * \return the nri_v (NRI value) read from tmsi, or -1 if nri_bitlen is not in the range [1..10]. + */ +int16_t osmo_tmsi_nri_get(uint32_t tmsi, uint8_t nri_bitlen) +{ + /* According to 3GPP TS 23.236, the most significant bit of the NRI is always bit 23. + * (So this is not a temporary placeholder 23 we sometimes like to use, it is an actually specified 23!) */ + uint8_t lowest_bit; + if (nri_bitlen < 1 || nri_bitlen > 10) + return -1; + lowest_bit = 23 - (nri_bitlen - 1); + return (tmsi >> lowest_bit) & (0xfff >> (12 - nri_bitlen)); +} + +/*! Write Network Resource Indicator bits into a TMSI or p-TMSI. + * Return a TMSI or p-TMSI with the NRI bits overwritten by the given NRI value. + * Useful for MSC pooling as described by 3GPP TS 23.236. + * \param[in] tmsi A base TMSI or p-TMSI to replace the NRI value in. + * \param[in] nri_bitlen Length of the NRI value in number of bits, 1 <= nri_bitlen <= 10. + * \param[in] nri_v The NRI value to place in the tmsi. + * \return the original TMSI or p-TMSI with NRI bits replaced, or OSMO_TMSI_UNASSIGNED if nri_bitlen is not in the + * range [1..10]. + */ +uint32_t osmo_tmsi_nri_set(uint32_t tmsi, uint8_t nri_bitlen, uint16_t nri_v) +{ + uint8_t lowest_bit; + uint32_t v_mask; + if (nri_bitlen < 1 || nri_bitlen > 10) + return OSMO_TMSI_UNASSIGNED; + lowest_bit = 23 - (nri_bitlen - 1); + v_mask = (0xfff >> (12 - nri_bitlen)) << lowest_bit; + return (tmsi & ~v_mask) | ((((uint32_t)nri_v) << lowest_bit) & v_mask); +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 70b3916..98cdac5 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -667,5 +667,8 @@ osmo_cbsp_recv_buffered; osmo_cbsp_errstr; +osmo_tmsi_nri_get; +osmo_tmsi_nri_set; + local: *; }; diff --git a/tests/Makefile.am b/tests/Makefile.am index 0d0327a..87bea8d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -23,6 +23,7 @@ coding/coding_test conv/conv_gsm0503_test \ abis/abis_test endian/endian_test sercomm/sercomm_test \ prbs/prbs_test gsm23003/gsm23003_test \ + gsm23236/gsm23236_test \ codec/codec_ecu_fr_test timer/clk_override_test \ oap/oap_client_test gsm29205/gsm29205_test \ logging/logging_vty_test \ @@ -245,6 +246,9 @@ gsm23003_gsm23003_test_SOURCES = gsm23003/gsm23003_test.c gsm23003_gsm23003_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la +gsm23236_gsm23236_test_SOURCES = gsm23236/gsm23236_test.c +gsm23236_gsm23236_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la + tdef_tdef_test_SOURCES = tdef/tdef_test.c tdef_tdef_test_LDADD = $(LDADD) @@ -332,6 +336,7 @@ conv/conv_gsm0503_test.ok endian/endian_test.ok \ sercomm/sercomm_test.ok prbs/prbs_test.ok \ gsm29205/gsm29205_test.ok gsm23003/gsm23003_test.ok \ + gsm23236/gsm23236_test.ok \ timer/clk_override_test.ok \ oap/oap_client_test.ok oap/oap_client_test.err \ vty/vty_transcript_test.vty \ diff --git a/tests/gsm23236/gsm23236_test.c b/tests/gsm23236/gsm23236_test.c new file mode 100644 index 0000000..d6f6286 --- /dev/null +++ b/tests/gsm23236/gsm23236_test.c @@ -0,0 +1,163 @@ +/* + * (C) 2020 by sysmocom s.f.m.c. GmbH <info at sysmocom.de> + * Author: Neels Hofmeyr <nhofmeyr at sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <stdio.h> +#include <errno.h> +#include <strings.h> +#include <string.h> + +#include <osmocom/gsm/gsm23236.h> +#include <osmocom/core/utils.h> + +void bitdump(uint8_t count, uint32_t val) +{ + uint32_t bit; + for (bit = ((uint32_t)1) << (count - 1); bit; bit >>= 1) + printf("%c", (val & bit)? '1' : '0'); +} + +struct nri_get_set_test { + uint32_t tmsi; + uint8_t nri_bitlen; + int16_t expect_get_nri; + int16_t set_nri_v; + uint32_t expect_tmsi; +}; + +struct nri_get_set_test nri_get_set_tests[] = { + { + .tmsi = 0, + .nri_bitlen = 10, + .expect_get_nri = 0, + .set_nri_v = 0, + .expect_tmsi = 0, + }, + { + .tmsi = 0, + .nri_bitlen = 10, + .expect_get_nri = 0, + .set_nri_v = 0x7fff, + .expect_tmsi = 0x00ffc000 + }, + { + .tmsi = 0xffffffff, + .nri_bitlen = 10, + .expect_get_nri = 0x3ff, + .set_nri_v = 0, + .expect_tmsi = 0xff003fff + }, + { + .tmsi = 0xffffffff, + .nri_bitlen = 10, + .expect_get_nri = 0x3ff, + .set_nri_v = 0x7fff, + .expect_tmsi = 0xffffffff + }, + { + .tmsi = 0, + .nri_bitlen = 5, + .expect_get_nri = 0, + .set_nri_v = 0, + .expect_tmsi = 0, + }, + { + .tmsi = 0, + .nri_bitlen = 5, + .expect_get_nri = 0, + .set_nri_v = 0x7fff, + .expect_tmsi = 0x00f80000 + }, + { + .tmsi = 0xffffffff, + .nri_bitlen = 5, + .expect_get_nri = 0x1f, + .set_nri_v = 0, + .expect_tmsi = 0xff07ffff + }, + { + .tmsi = 0xffffffff, + .nri_bitlen = 5, + .expect_get_nri = 0x1f, + .set_nri_v = 0x7fff, + .expect_tmsi = 0xffffffff + }, + { + .tmsi = 0x01234567, + .nri_bitlen = 8, + .expect_get_nri = 0x23, + .set_nri_v = 0x42, + .expect_tmsi = 0x01424567 + }, +}; + +bool test_nri_get_set() +{ + struct nri_get_set_test *t; + bool ok = true; + + for (t = nri_get_set_tests; t < &nri_get_set_tests[ARRAY_SIZE(nri_get_set_tests)]; t++) { + int16_t nri_v; + uint32_t tmsi2; + + printf("........|NRI->..................\n"); + bitdump(32, t->tmsi); + printf(" tmsi nri_bitlen=%u\n", t->nri_bitlen); + + nri_v = osmo_tmsi_nri_get(t->tmsi, t->nri_bitlen); + printf(" "); + bitdump(t->nri_bitlen, nri_v); + printf(" = 0x%x", nri_v); + if (nri_v == t->expect_get_nri) { + printf(" ok\n"); + } else { + printf(" ERROR: expected %x\n", t->expect_get_nri); + ok = false; + } + + tmsi2 = osmo_tmsi_nri_set(t->tmsi, t->nri_bitlen, t->set_nri_v); + printf("osmo_tmsi_nri_set(0x%08x, %u, 0x%x) = 0x%08x\n", t->tmsi, t->nri_bitlen, t->set_nri_v, tmsi2); + printf(" "); + bitdump(t->nri_bitlen, t->set_nri_v); + printf("\n"); + bitdump(32, tmsi2); + if (tmsi2 == t->expect_tmsi) { + printf(" ok\n"); + } else { + printf(" ERROR: expected 0x%08x\n", t->expect_tmsi); + ok = false; + } + } + + return ok; +} + +int main(int argc, char **argv) +{ + bool pass = true; + + pass = pass && test_nri_get_set(); + + OSMO_ASSERT(pass); + + return EXIT_SUCCESS; +} diff --git a/tests/gsm23236/gsm23236_test.ok b/tests/gsm23236/gsm23236_test.ok new file mode 100644 index 0000000..3fb6ce1 --- /dev/null +++ b/tests/gsm23236/gsm23236_test.ok @@ -0,0 +1,54 @@ +........|NRI->.................. +00000000000000000000000000000000 tmsi nri_bitlen=10 + 0000000000 = 0x0 ok +osmo_tmsi_nri_set(0x00000000, 10, 0x0) = 0x00000000 + 0000000000 +00000000000000000000000000000000 ok +........|NRI->.................. +00000000000000000000000000000000 tmsi nri_bitlen=10 + 0000000000 = 0x0 ok +osmo_tmsi_nri_set(0x00000000, 10, 0x7fff) = 0x00ffc000 + 1111111111 +00000000111111111100000000000000 ok +........|NRI->.................. +11111111111111111111111111111111 tmsi nri_bitlen=10 + 1111111111 = 0x3ff ok +osmo_tmsi_nri_set(0xffffffff, 10, 0x0) = 0xff003fff + 0000000000 +11111111000000000011111111111111 ok +........|NRI->.................. +11111111111111111111111111111111 tmsi nri_bitlen=10 + 1111111111 = 0x3ff ok +osmo_tmsi_nri_set(0xffffffff, 10, 0x7fff) = 0xffffffff + 1111111111 +11111111111111111111111111111111 ok +........|NRI->.................. +00000000000000000000000000000000 tmsi nri_bitlen=5 + 00000 = 0x0 ok +osmo_tmsi_nri_set(0x00000000, 5, 0x0) = 0x00000000 + 00000 +00000000000000000000000000000000 ok +........|NRI->.................. +00000000000000000000000000000000 tmsi nri_bitlen=5 + 00000 = 0x0 ok +osmo_tmsi_nri_set(0x00000000, 5, 0x7fff) = 0x00f80000 + 11111 +00000000111110000000000000000000 ok +........|NRI->.................. +11111111111111111111111111111111 tmsi nri_bitlen=5 + 11111 = 0x1f ok +osmo_tmsi_nri_set(0xffffffff, 5, 0x0) = 0xff07ffff + 00000 +11111111000001111111111111111111 ok +........|NRI->.................. +11111111111111111111111111111111 tmsi nri_bitlen=5 + 11111 = 0x1f ok +osmo_tmsi_nri_set(0xffffffff, 5, 0x7fff) = 0xffffffff + 11111 +11111111111111111111111111111111 ok +........|NRI->.................. +00000001001000110100010101100111 tmsi nri_bitlen=8 + 00100011 = 0x23 ok +osmo_tmsi_nri_set(0x01234567, 8, 0x42) = 0x01424567 + 01000010 +00000001010000100100010101100111 ok diff --git a/tests/testsuite.at b/tests/testsuite.at index bab5730..c580578 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -344,6 +344,12 @@ AT_CHECK([$abs_top_builddir/tests/gsm23003/gsm23003_test], [0], [expout], [ignore]) AT_CLEANUP +AT_SETUP([gsm23236]) +AT_KEYWORDS([gsm23236]) +cat $abs_srcdir/gsm23236/gsm23236_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/gsm23236/gsm23236_test], [0], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([tdef]) AT_KEYWORDS([tdef]) cat $abs_srcdir/tdef/tdef_test.ok > expout -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/18506 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: Icb57a2dd9323c7ea11b34003eccc7e68a0247bf5 Gerrit-Change-Number: 18506 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr at sysmocom.de> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200526/d1bf0bcb/attachment.htm>