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/.
laforge gerrit-no-reply at lists.osmocom.orglaforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/22800 ) Change subject: gsm: Introduce API osmo_gsm48_rest_octets_si13_decode ...................................................................... gsm: Introduce API osmo_gsm48_rest_octets_si13_decode Related: SYS#5358 Change-Id: I74fb0a3afc1ac4aadbfc609b882d929401f790eb --- M include/osmocom/gsm/gsm48_rest_octets.h M src/gsm/gsm48_rest_octets.c M src/gsm/libosmogsm.map M tests/Makefile.am A tests/gsm48/rest_octets_test.c A tests/gsm48/rest_octets_test.ok M tests/testsuite.at 7 files changed, 249 insertions(+), 1 deletion(-) Approvals: laforge: Looks good to me, approved daniel: Looks good to me, approved fixeria: Looks good to me, but someone else must approve Jenkins Builder: Verified diff --git a/include/osmocom/gsm/gsm48_rest_octets.h b/include/osmocom/gsm/gsm48_rest_octets.h index 8f143be..f295824 100644 --- a/include/osmocom/gsm/gsm48_rest_octets.h +++ b/include/osmocom/gsm/gsm48_rest_octets.h @@ -120,7 +120,8 @@ uint8_t prio_acc_thr; }; -/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */ +/* Parse/Generate SI13 Rest Octests (Chapter 10.5.2.37b) */ +int osmo_gsm48_rest_octets_si13_decode(struct osmo_gsm48_si13_info *si13, const uint8_t *data); int osmo_gsm48_rest_octets_si13_encode(uint8_t *data, const struct osmo_gsm48_si13_info *si13); /* Parse SI3 Rest Octets */ diff --git a/src/gsm/gsm48_rest_octets.c b/src/gsm/gsm48_rest_octets.c index 1bab8e0..77fd349 100644 --- a/src/gsm/gsm48_rest_octets.c +++ b/src/gsm/gsm48_rest_octets.c @@ -749,6 +749,119 @@ return bv.data_len; } + +static unsigned int decode_t3192(unsigned int t3192) +{ + /* See also 3GPP TS 44.060 + Table 12.24.2: GPRS Cell Options information element details */ + static const unsigned int decode_t3192_tbl[8] = {500, 1000, 1500, 0, 80, 120, 160, 200}; + OSMO_ASSERT(t3192 <= 7); + return decode_t3192_tbl[t3192]; +} + +static unsigned int decode_drx_timer(unsigned int drx) +{ + static const unsigned int decode_drx_timer_tbl[8] = {0, 1, 2, 4, 8, 16, 32, 64}; + OSMO_ASSERT(drx <= 7); + return decode_drx_timer_tbl[drx]; +} + +static int decode_gprs_cell_opt(struct osmo_gprs_cell_options *gco, struct bitvec *bv) +{ + gco->nmo = bitvec_get_uint(bv, 2); + gco->t3168 = (bitvec_get_uint(bv, 3) + 1) * 500; + gco->t3192 = decode_t3192(bitvec_get_uint(bv, 3)); + gco->drx_timer_max = decode_drx_timer(bitvec_get_uint(bv, 3)); + + /* ACCESS_BURST_TYPE: */ + bitvec_get_uint(bv, 1); + /* CONTROL_ACK_TYPE: */ + gco->ctrl_ack_type_use_block = bitvec_get_uint(bv, 1); + gco->bs_cv_max = bitvec_get_uint(bv, 4); + + if (bitvec_get_uint(bv, 1)) { + bitvec_get_uint(bv, 3); /* DEC */ + bitvec_get_uint(bv, 3); /* INC */ + bitvec_get_uint(bv, 3); /* MAX */ + } + + if (bitvec_get_uint(bv, 1)) { + int ext_len = bitvec_get_uint(bv, 6); + if (ext_len < 0) + return ext_len; + unsigned int cur_bit = bv->cur_bit; + /* Extension Information */ + /* R99 extension: */ + gco->ext_info.egprs_supported = bitvec_get_uint(bv, 1); + if (gco->ext_info.egprs_supported) { + gco->ext_info.use_egprs_p_ch_req = !bitvec_get_uint(bv, 1); + gco->ext_info.bep_period = bitvec_get_uint(bv, 4); + } + gco->ext_info.pfc_supported = bitvec_get_uint(bv, 1); + gco->ext_info.dtm_supported = bitvec_get_uint(bv, 1); + gco->ext_info.bss_paging_coordination = bitvec_get_uint(bv, 1); + /* REL-4 extension: */ + gco->ext_info.ccn_active = bitvec_get_uint(bv, 1); + bitvec_get_uint(bv, 1); /* NW_EXT_UTBF */ + bv->cur_bit = cur_bit + ext_len + 1; + } + return 0; +} + +static void decode_gprs_pwr_ctrl_pars(struct osmo_gprs_power_ctrl_pars *pcp, struct bitvec *bv) +{ + pcp->alpha = bitvec_get_uint(bv, 4); + pcp->t_avg_w = bitvec_get_uint(bv,5); + pcp->t_avg_t = bitvec_get_uint(bv, 5); + pcp->pc_meas_chan = bitvec_get_uint(bv, 1); + pcp->n_avg_i = bitvec_get_uint(bv, 4); +} + +/*! Decode SI13 Rest Octests (04.08 Chapter 10.5.2.37b). + * \param[out] si13 decoded SI13 rest octets + * \param[in] encoded SI13 rest octets + * \returns parsed bits on success, negative on error */ +int osmo_gsm48_rest_octets_si13_decode(struct osmo_gsm48_si13_info *si13, const uint8_t *data) +{ + struct osmo_gprs_cell_options *co = &si13->cell_opts; + struct osmo_gprs_power_ctrl_pars *pcp = &si13->pwr_ctrl_pars; + struct bitvec bv; + int rc; + + memset(&bv, 0, sizeof(bv)); + bv.data = (uint8_t *) data; + bv.data_len = 20; + + memset(si13, 0, sizeof(*si13)); + + + if (bitvec_get_bit_high(&bv) == H) { + si13->bcch_change_mark = bitvec_get_uint(&bv, 3); + si13->si_change_field = bitvec_get_uint(&bv, 4); + if (bitvec_get_uint(&bv, 1)) { + si13->bcch_change_mark = bitvec_get_uint(&bv, 2); + /* FIXME: implement parsing GPRS Mobile Allocation IE */ + return -ENOTSUP; + } + if (bitvec_get_uint(&bv, 1)) { + /* PBCCH present in cell */ + /* FIXME: parse not implemented */ + return -ENOTSUP; + } else { + /* PBCCH not present in cell */ + si13->rac = bitvec_get_uint(&bv, 8); + si13->spgc_ccch_sup = bitvec_get_uint(&bv, 1); + si13->prio_acc_thr = bitvec_get_uint(&bv, 3); + si13->net_ctrl_ord = bitvec_get_uint(&bv, 2); + if ((rc = decode_gprs_cell_opt(co, &bv)) < 0) + return rc; + + decode_gprs_pwr_ctrl_pars(pcp, &bv); + } + } + return bv.cur_bit; +} + /* GPRS Mobile Allocation as per TS 04.60 Chapter 12.10a: < GPRS Mobile Allocation IE > ::= < HSN : bit (6) > diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index efa23e6..0ea0678 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -320,6 +320,7 @@ osmo_gsm48_rest_octets_si6_encode; osmo_gsm48_rest_octets_si3_encode; osmo_gsm48_rest_octets_si4_encode; +osmo_gsm48_rest_octets_si13_decode; osmo_gsm48_rest_octets_si13_encode; osmo_gsm48_rest_octets_si3_decode; osmo_gsm48_rest_octets_si4_decode; diff --git a/tests/Makefile.am b/tests/Makefile.am index 10306aa..158bc69 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,6 +42,7 @@ bsslap/bsslap_test \ bssmap_le/bssmap_le_test \ it_q/it_q_test \ + gsm48/rest_octets_test \ $(NULL) if ENABLE_MSGFILE @@ -139,6 +140,9 @@ gsm0408_gsm0408_test_SOURCES = gsm0408/gsm0408_test.c gsm0408_gsm0408_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la +gsm48_rest_octets_test_SOURCES = gsm48/rest_octets_test.c +gsm48_rest_octets_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la + gprs_gprs_test_SOURCES = gprs/gprs_test.c gprs_gprs_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la @@ -399,6 +403,7 @@ bsslap/bsslap_test.ok \ bssmap_le/bssmap_le_test.ok \ it_q/it_q_test.ok \ + gsm48/rest_octets_test.ok \ $(NULL) if ENABLE_LIBSCTP diff --git a/tests/gsm48/rest_octets_test.c b/tests/gsm48/rest_octets_test.c new file mode 100644 index 0000000..beff6e4 --- /dev/null +++ b/tests/gsm48/rest_octets_test.c @@ -0,0 +1,120 @@ +/* + * (C) 2021 by sysmocom - s.m.f.c. GmbH <info at sysmocom.de> + * Author: Pau Espin Pedrol <pespin at sysmocom.de> + * All Rights Reserved + * + * 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 <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/gsm/gsm48_rest_octets.h> + +struct si13_test { + const char *name; + const struct osmo_gsm48_si13_info si; + int enc_rc; + int dec_rc; + void (*post_dec_cb)(const struct si13_test *test, const struct osmo_gsm48_si13_info* dec); +}; + +void post_dec_cb_test_alpha(const struct si13_test *test, const struct osmo_gsm48_si13_info* dec) +{ + OSMO_ASSERT(test->si.pwr_ctrl_pars.alpha == dec->pwr_ctrl_pars.alpha); +} + +static const struct si13_test test_si13_arr[] = { + { + .name = "test alpha", + .si = { + .cell_opts = { + .nmo = GPRS_NMO_II, + .t3168 = 2000, + .t3192 = 1500, + .drx_timer_max = 3, + .bs_cv_max = 15, + .ctrl_ack_type_use_block = true, + .ext_info_present = 0, + .ext_info = { + .egprs_supported = 1, + .use_egprs_p_ch_req = 1, + .bep_period = 5, + .pfc_supported = 0, + .dtm_supported = 0, + .bss_paging_coordination = 0, + .ccn_active = true, + }, + }, + .pwr_ctrl_pars = { + .alpha = 5, + .t_avg_w = 16, + .t_avg_t = 16, + .pc_meas_chan = 0, + .n_avg_i = 8, + }, + .bcch_change_mark = 1, + .si_change_field = 0, + .rac = 0x03, + .spgc_ccch_sup = 0, + .net_ctrl_ord = 0, + .prio_acc_thr = 6, + }, + .enc_rc = 20, + .dec_rc = 71, + .post_dec_cb = post_dec_cb_test_alpha, + }, +}; + +static void test_si13() +{ + int i, rc; + uint8_t data[GSM_MACBLOCK_LEN]; + struct osmo_gsm48_si13_info si13; + + for (i = 0; i < ARRAY_SIZE(test_si13_arr); i++) { + memset(data, 0, sizeof(data)); + rc = osmo_gsm48_rest_octets_si13_encode(data, &test_si13_arr[i].si); + if (rc >= 0) { + printf("si13_encode (%d): %s\n", rc, osmo_hexdump(data, rc)); + } else { + printf("si13_encode failed (%d)\n", rc); + } + OSMO_ASSERT(rc == test_si13_arr[i].enc_rc); + if (rc <= 0) + continue; + memset(&si13, 0 , sizeof(si13)); + rc = osmo_gsm48_rest_octets_si13_decode(&si13, data); + if (rc >= 0) { + printf("si13_decode (%d)\n", rc); + } else { + printf("si13_decode failed (%d)\n", rc); + } + OSMO_ASSERT(rc == test_si13_arr[i].dec_rc); + if (test_si13_arr[i].post_dec_cb) { + test_si13_arr[i].post_dec_cb(&test_si13_arr[i], &si13); + } + } +} + +int main(int argc, char **argv) +{ + test_si13(); + + return EXIT_SUCCESS; +} diff --git a/tests/gsm48/rest_octets_test.ok b/tests/gsm48/rest_octets_test.ok new file mode 100644 index 0000000..54204f2 --- /dev/null +++ b/tests/gsm48/rest_octets_test.ok @@ -0,0 +1,2 @@ +si13_encode (20): 90 00 d8 5a 6f c9 e5 84 10 ab 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +si13_decode (71) diff --git a/tests/testsuite.at b/tests/testsuite.at index d715a3e..d2a10dd 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -156,6 +156,12 @@ AT_CHECK([$abs_top_builddir/tests/gsm0408/gsm0408_test], [0], [expout], [ignore]) AT_CLEANUP +AT_SETUP([gsm48_rest_octets]) +AT_KEYWORDS([gsm48_rest_octets]) +cat $abs_srcdir/gsm48/rest_octets_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/gsm48/rest_octets_test], [0], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([gprs]) AT_KEYWORDS([gprs]) cat $abs_srcdir/gprs/gprs_test.ok > expout -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/22800 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I74fb0a3afc1ac4aadbfc609b882d929401f790eb Gerrit-Change-Number: 22800 Gerrit-PatchSet: 4 Gerrit-Owner: pespin <pespin at sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: daniel <dwillmann at sysmocom.de> Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de> Gerrit-Reviewer: laforge <laforge at osmocom.org> Gerrit-Reviewer: osmith <osmith at sysmocom.de> Gerrit-MessageType: merged -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210218/f6d90e51/attachment.htm>