diff options
57 files changed, 2260 insertions, 122 deletions
@@ -70,7 +70,7 @@ Contributing Our coding standards are described at <https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards> -We us a gerrit based patch submission/review process for managing +We use a Gerrit based patch submission/review process for managing contributions. Please see <https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit> for more details diff --git a/TODO-RELEASE b/TODO-RELEASE index ce041627..8a1e0dc9 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -3,22 +3,9 @@ # In short: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info # LIBVERSION=c:r:a # If the library source code has changed at all since the last update, then increment revision: c:r + 1:a. -# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0. +# If any interfaces have been added, removed, or changed since the last update: c + 1:0:a. # If any interfaces have been added since the last public release: c:r:a + 1. # If any interfaces have been removed or changed since the last public release: c:r:0. #library what description / commit summary line -core ADD osmo_sock_multiaddr_{add,del}_local_addr() -core ADD osmo_sock_multiaddr_get_ip_and_port(), osmo_multiaddr_ip_and_port_snprintf(), osmo_sock_multiaddr_get_name_buf() -core ADD osmo_sock_sctp_get_peer_addr_info() -core ADD gsmtap_inst_fd2() core, DEPRECATE gsmtap_inst_fd() -core ADD osmo_sockaddr_str_from_osa() osmo_sockaddr_str_to_osa() -core behavior change osmo_tdef_fsm_inst_state_chg(): allow millisecond precision -core ABI change osmo_io_ops now contains a struct of structs, not union of structs -core ABI change osmo_iofd_set_ioops() now returns a value (error code) -isdn ABI change add states and flags for external T200 handling -isdn ADD initial implementation of the V.110 Terminal Adapter -gsm ABI change add T200 timer states to lapdm_datalink -gsm ABI change add UI queue to struct lapdm_datalink -gsm ADD gsup.h: struct osmo_gsup_pdp_info fields pdp_type_nr, pdp_type_org, deprecate pdp_type. -gsm ABI change gsup.h: Add field pdp_address in struct osmo_gsup_pdp_info shifts the struct, and in turn fields in struct osmo_gsup_message. -gsm ABI change gsup.h: Add field pco in struct osmo_gsup_message. Length of the struct osmo_gsup_message increase. +gb ADD add bssgp_parse_cell_id2/bssgp_create_cell_id2 +gsm ADD add osmo_rai_to_gprs/gprs_rai_to_osmo diff --git a/contrib/libosmocore.spec.in b/contrib/libosmocore.spec.in index 60ca3977..f16f7999 100644 --- a/contrib/libosmocore.spec.in +++ b/contrib/libosmocore.spec.in @@ -115,13 +115,13 @@ transcoding routines. This subpackage contains libraries and header files for developing applications that want to make use of libosmocoding. -%package -n libosmocore21 +%package -n libosmocore22 Summary: Osmocom core library # crc16.c has GPL2-only clauses, the rest (*.c) is GPL-2.0+ License: GPL-2.0-only AND GPL-2.0-or-later Group: System/Libraries -%description -n libosmocore21 +%description -n libosmocore22 libosmocore is a library with various utility functions shared between OpenBSC and OsmocomBB. @@ -130,7 +130,7 @@ Summary: Development files for the Osmocom core library # crc16.h has GPL2-only clauses, the rest (*.h) is GPL-2.0+ License: GPL-2.0-only AND GPL-2.0-or-later Group: Development/Libraries/C and C++ -Requires: libosmocore21 = %version +Requires: libosmocore22 = %version Requires: libtalloc-devel Requires: lksctp-tools-devel @@ -367,8 +367,8 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +) %postun -n libosmocodec4 -p /sbin/ldconfig %post -n libosmocoding0 -p /sbin/ldconfig %postun -n libosmocoding0 -p /sbin/ldconfig -%post -n libosmocore21 -p /sbin/ldconfig -%postun -n libosmocore21 -p /sbin/ldconfig +%post -n libosmocore22 -p /sbin/ldconfig +%postun -n libosmocore22 -p /sbin/ldconfig %post -n libosmoctrl0 -p /sbin/ldconfig %postun -n libosmoctrl0 -p /sbin/ldconfig %post -n libosmogb14 -p /sbin/ldconfig @@ -412,9 +412,9 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +) %_libdir/libosmocoding.so %_libdir/pkgconfig/libosmocoding.pc -%files -n libosmocore21 +%files -n libosmocore22 %defattr(-,root,root) -%_libdir/libosmocore.so.21* +%_libdir/libosmocore.so.22* %files -n libosmocore-devel %defattr(-,root,root) diff --git a/debian/changelog b/debian/changelog index c9184df0..f80c4e49 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,253 @@ +libosmocore (1.10.0) unstable; urgency=medium + + [ Mychaela N. Falconia ] + * gsm/protocol/gsm_04_11.h: add SMSC-address length limit definitions + * gsm0808: add knowledge of TW-TS-003 BSSMAP IE + * bts_features: add feature flags for TWTS001 and TWTS002 + * rsl: define RSL_IE_OSMO_RTP_EXTENSIONS + * include/osmocom/gsm: add rtp_extensions.h + * codec: make osmo_hr_check_sid() more efficient + + [ arehbein ] + * write_queue: Enable updating max_length field + * osmo_io: Clean up code + * gsmtap: Hide implementation of gsmtap_inst + * osmo_io_poll: Handle -EAGAIN in case of OSMO_FD_WRITE + * write_queue: Fix Doxygen comment + * gsmtap_util: Use Osmo IO instead of Osmo write queues + * gsmtap_util: Simplify sink + * gmstap_util: Fix sending out gsmtap messages + * ns2: Improve code consistency + + [ Manawyrm ] + * gsmtap.h: Add definitions for ISDN PPP sub-type + * gsm48_ie.c: add 3.1kHz audio bearer capability for CSD calls + * gsm48_ie.c: change bearer cap structure in outgoing CSD calls + * logging: ensure ANSI color escape is sent in same line/before newline + + [ Karsten Ohme ] + * APDU parsing support for GlobalPlatform GET RESPONSE + + [ Vadim Yanitskiy ] + * gsm: add gsm0502_fn_compare() for comparing TDMA FNs + * gsm: rename s/gsm0502_fn_compare/gsm0502_fncmp/ + * msgb: fix doxygen docs for msgb_pull_u{8,16,32): end -> front + * coding: gsm0503_tch_a[fh]s_encode(): improve cmr/ft checks + * coding: gsm0503_tch_a[fh]s_encode(): make *codec const + * tests/testsuite.at: remove copy-pasted 'touch experr' + * soft_uart: add osmo_soft_uart_free() + * soft_uart: add doxygen documentation + * soft_uart: split osmo_soft_uart_enable() + * soft_uart: make osmo_soft_uart_alloc() accept *cfg + * soft_uart: rework osmo_uart_rx_bit() to use flow state + * soft_uart: implement parity checking for the receiver + * soft_uart: implement the transmitter + * soft_uart: allow manually flushing the receive buffer + * soft_uart: add unit tests for the receiver and transmitter + * soft_uart: fix Rx buffer flushing logic in suart_rx_ch() + * soft_uart: fix handling of num_data_bits < 8 + * soft_uart: implement OSMO_SUART_PARITY_{MARK,SPACE} + * soft_uart: demonstrate a problem with osmo_soft_uart_tx_ubits() + * soft_uart: fix pulling a small number of Tx bits + * soft_uart: check n_bits against 0 in osmo_soft_uart_tx_ubits() + * soft_uart: fix spelling in doxygen docs + * soft_uart: add osmo_soft_uart_{get,set}_name() + * soft_uart: fix doxygen doc for osmo_soft_uart_tx_ubits() + * soft_uart: check Rx/Tx state once in osmo_soft_uart_{rx,tx}_ubits() + * soft_uart: cosmetic: do not use 'osmo_' prefix for static symbols + * soft_uart: improve doxygen documentation + * soft_uart: osmo_soft_uart_tx_ubits(): return number of bits pulled + * soft_uart: implement modem status lines and flow control + * coding: fix doxygen docs for gsm0503_pdtch[_egprs]_decode() + * coding: clarify the USF decoding for PDCH blocks + * coding: gsm0503_pdtch_decode(): implement USF decoding for CS1 + * tests/coding: fix -Wmaybe-uninitialized in test_pdtch() + * tests/it_q: add tc_enqueue/dequeue testcase + * core: fix wrong logic in _osmo_it_q_dequeue() + * tests/soft_uart: assert that osmo_soft_uart_rx_ubits() returns 0 + * tests/soft_uart: cosmetic: improve readability of the test output + * soft_uart: cosmetic: use consistent naming for the Rx buffer msgb + * logging: fix NULL pointer dereference in _output_buf() + * soft_uart: fix the Rx flushing logic, add a unit test + * soft_uart: demonstrate a problem with manual flush()ing + * soft_uart: demonstrate a problem with inefficient polling + * tests/lapd: fix wrong size passed in test_lapdm_contention_resolution() + * tests/gsm0808: fix assert()s in test_gsm0808_dec_cell_id_list_srvcc() + * tests/iuup: fix assert()s in test_decode_passive_init_2_rfci_no_iptis() + * tests/fsm: also test .onenter and .onleave callbacks + * tests: fix update-exp: soft_uart_test overwrites rlp_test.ok + * utils: fix OSMO_STRBUF_REMAIN to handle sb.pos == NULL correctly + * utils: improve readability of OSMO_STRBUF_CHAR_COUNT + * utils: fix -Wsign-compare in definition of OSMO_STRBUF_CHAR_COUNT + * utils: osmo_bcd2str(): fix applying non-zero offset to null pointer + * tests/utils: do not test strbuf_example2() with buf=NULL + * bitvec: bitvec_to_string_r(): drop unused variable + * tests/{gb,iuup}: also match stderr + * tests/tdef: also test OSMO_TDEF_US and negative T values + * tests/tdef: tune logging, also match stderr + * pseudotalloc: add talloc_memdup(), use it in talloc_strdup() + * gsm0808_utils: use osmo_strbuf API, drop APPEND_{THING,STR,CELL_ID_U} + * vty: suppress warnings about len being set but not used + * gsm48_ie: fix various issues in doxygen docs + * gsm: fix osmo_mobile_identity_decode(): init *mi on error + * core: osmo_tdef_fsm_inst_state_chg(): allow millisecond precision + * tests/tdef: improve test output (use OSMO_T_FMT[_ARGS]) + * fsm: fix OSMO_T_FMT_ARGS: add missing braces + * isdn: initial implementation of the V.110 TA + * isdn: add a lookup table with E1/E2/E3 bits from Table 5/V.110 + * tests/gsm0408: cosmetic: adjust coding style (make linter happy) + * tests/gsm0408: add two more samples to bcap_tests[] + * isdn/v110_ta: avoid redundant .status_update_cb() calls + * gsm: add more definitions from Table 10.5.112/3GPP TS 24.008 + * tests/iuup: fix duplicate assignment in def_configure_req + * tests/a5: fix bit-wise vs logical and in test_a5[34]() + * tests/sockaddr_str: fix dead code, print some errno values + * tests/sockaddr_str: rc_name(): also handle -EAFNOSUPPORT + * osmo-release.sh: make it a bit more user friendly + * tests/Makefile.am: do not add files to EXTRA_DIST conditionally + * utils/conv_codes_gsm.py: fix inconsistent formatting + * coding: fix a typo in docs for gsm0503_pdtch_decode() + * coding: improve readability in osmo_conv_decode_ber_punctured() + * coding: fix artificial bit errors for PDTCH CS2 and CS3 + * coding: fix wrong n_bits_total reported for PDTCH CS2 and CS3 + * core: fix missing '\n' in iofd_uring_connected_cb() + * tests: do not copy *.cfg files to the build directory + * tests: rename logging_test_gsmtap -> logging_gsmtap_test + * vty: fix memleak in host_config_set() + * {fsm,vty}: add a VTY command to generate FSM state graphs + * core: fix LOGPIO(): add missing space after 'iofd(...)' + * README.md: cosmetic: fix a typo + + [ Pau Espin Pedrol ] + * sockaddr_str.h Fix OSMO_SOCKADDR_STR_FMT_ARGS_NOT_NULL syntax error + * socket: Introduce APIs osmo_sock_multiaddr_{add,del}_local_addr() + * Fix typo in libosmocore.map + * socket.c: Fix compilation with --disable-libsctp + * tests/socket: Avoid keeping unneeded sockets open during next test cases + * socket: Reimplement osmo_sock_init2_multiaddr() + * socket: osmo_sock_init2_multiaddr2(): Apply params too if no OSMO_SOCK_F_BIND flag set + * socket: Introduce API osmo_sock_multiaddr_get_ip_and_port() + * socket: Introduce API osmo_sock_multiaddr_get_name_buf() + * socket: Fix uninitialized mem ptr free in osmo_sock_init2_multiaddr2() + * socket: Introduce API osmo_sock_sctp_get_peer_addr_info() + * socket: Introduce defines OSMO_SOCK_MULTIADDR_{PEER_STR,NAME}_MAXLEN + * ipa_ccm_tlv_to_unitdata(): free previous string if present before allocating new one + * cosmetic: gsup.h: fix whitespace formatting + * gsm_04_08_gprs.h: Introduce packed struct gsm48_pdp_address + * gsup: Fail decoding if len of PDP Type IE is less than 2 bytes + * gsup: Deprecate field pdp_type in favour of pdp_type_nr and pdp_type_org + * gsup: Convert PDP-Type IE to PDP-Address IE + * cosmetic: tests/gsup/gsup_test: Move send_e_send_end_signal_res to correct place + * socket: Support AF_UNIX in osmo_sock_get_name_buf() + * socket: Add remote PID and local FD to AF_UNIX sockname + * osmo_io: Add iofd param to segmentation_cb + + [ Daniel Willmann ] + * osmo_io: Init struct msghdr to zero + * osmo_io: Only allow reading/writing if the relevant callback is set + * logging_gsmtap: Temporarily disable logging when sending the logs + * osmo_io: Assert that iofd mode is correct when calling *_write_msgb + * Disable uring when building for embedded + * osmo_io: Factor out and use common send function from backend + * tests: Test gsmtap logging if write queue fills up + + [ Andreas Eversberg ] + * LAPDm: Correctly count expiry of T200 during estabishment/release + * ASCI: Add primitive to L1-SAP to switch uplink access detection on or off + * LAPD: Prepare lapd_send_i() for RTS support + * LAPD: Flush TX queue, if remote peer enters busy condition or rejects + * LAPD: Always update N(R) in pending TX frames if V(R) is incremented + * LAPD: Add support for RTS based polling and T200 + * LAPDm: Add support for RTS based polling + * LAPDm: Add an extra queue for UI frames + * LAPDm: Add a flag to enable suppression of subsequent REJ frame + * LAPD: Indicate sequence error after indicating received data + * coding: gsm0503_tch_{afs,ahs}_encode(): add ability to emit BFI + * Fix union abis_rsl_chan_nr and abis_rsl_link_id + * Add flag to enable RTS based polling + * Prevent poll() in select.c to timeout too early + * Make socket.c compile without libsctp support (--disable-libsctp) + * osmo_io: Move notify_connected function to backend + * osmo_io: Use poll/select to notify socket connection at osmo_io_uring.c + * osmo_io: Reject writing messages with length of 0 + * osmo_io_poll: Use -errno as result on read error + * osmo_io_uring: Cancel pending request, free msghdr on completion + * osmo_io_uring: Detach msghdr from iofd before calling iofd_handle_send_completion() + * osmo_io_poll: Declare local functions "static" + * osmo_io: Assign const name when stealing TX msg from iofd ctx + * osmo_io_uring: Check if osmo_fd_register fails at iofd_uring_notify_connected() + * osmo_io: do check_mode_callback_compat() only if ioops is set at osmo_iofd_setup() + * osmo_io_poll: Use -errno as result on write error + * Fix file descriptor that is passed to io_uring_register_eventfd() + * osmo_io_uring: Run check of tests/osmo_io with io_uring also + + [ Harald Welte ] + * core: Add software UART implementation + * add new osmo_sockaddr_from_str_and_uint() function + * io_uring: add some more source code comments/docs + * osmo_io: rename unsupported SCTP mode to OSMO_IO_FD_MODE_SCTP_RECVMSG_SEND + * osmo_io: Reject unknown/unsupported modes in osmo_iofd_setup() + * sim/class_tables: Prevent out-of-bounds access + * libosmosim: Support Microsoft smart card discovery process + * Add a GSM RLP decoder and encoder + * rlp: Add support for 576bit RLP frames + * osmo_io: Change struct osmo_io_ops to contain struct, not union + * osmo_io: sendmsg/recvmsg support + * osmo_io: Add osmo_io_get_ioops() function + * ctrl: Don't expose write_queue in ctrl_cmd_send() api + * cbsp: Add osmo_cbsp_segmentation_cb for message segmentation + * osmo_io: Guard osmo_iofd_register() with invalid file descriptor + * osmo_io: Log error message in case call-backs incompatible with mode + * osmo_io: Don't pretend to support backends without close_cb + * osmo_io: avoid OSMO_ASSERT one each API call + * osmo_io: Avoid implementing non-existant situations + * ctrl: re-introduce duplicate declaration of ctrl_cmd_send() + * io_uring: more verbose error messages if io_uring setup fails + * io_uring: check all operations in osmo_iofd_uring_init() + * osmo_io: Dont use __linux__ but !EMBEDDED + * osmo_io: Massive improvement of API documentation + * osmo_io: Make {write,sendto,sendmsg} completion callback optional + * Add funding link to github mirror + * libosmosim: class_tables: Resolve conflicting CLA=8x INS=F2 definitions + * libosmosim: class_tables: Fix GlobalPlatform CLA=8x INS=CA/CB GET DATA + * [cosmetic] libosmosim/class_tables: Add a quick reminder about the cases + + [ Alexander Couzens ] + * gsup: add message type for osmo-epdg CEAI interface + * gsup: fix error log message + * gsup.h: define newly added PCO IE + + [ Neels Hofmeyr ] + * util: add OSMO_STRBUF_REMAIN() + * util: add osmo_strbuf macros to manipulate the strbuf tail + * logging: fix nul octets in log output / use osmo_strbuf + * comment: gsm_04_08.h: add a spec hint + * sockaddr_str: add conversion to,from osmo_sockaddr + * fix update_exp: s/soft_uart.ok/soft_uart_test.ok + * add jhash.h, copied from linux/jhash.h + + [ Philipp Maier ] + * ecu: fix alignment of fr_ecu_state + + [ Eric ] + * logging: add log level cache + + [ Hoernchen ] + * Revert "logging: add log level cache" + * Revert "Revert "logging: add log level cache"" + + [ Matan Perelman ] + * ctrl: Add lchan node + + [ Oliver Smith ] + * osmo-release: don't default to REL=patch + * osmo-release: use script from PWD if available + * osmo-release: use colored output + * osmo-release: rework cleaning of TODO-RELEASE + * osmo-release: fix libversion updating comment + + -- Oliver Smith <osmith@sysmocom.de> Wed, 24 Jul 2024 10:19:45 +0200 + libosmocore (1.9.0) unstable; urgency=medium [ Oliver Smith ] diff --git a/debian/control b/debian/control index 5fb26cbc..ae8900fc 100644 --- a/debian/control +++ b/debian/control @@ -33,7 +33,7 @@ Architecture: any Multi-Arch: foreign Depends: libosmocodec4 (= ${binary:Version}), libosmocoding0 (= ${binary:Version}), - libosmocore21 (= ${binary:Version}), + libosmocore22 (= ${binary:Version}), libosmogb14 (= ${binary:Version}), libosmogsm20 (= ${binary:Version}), libosmoisdn0 (= ${binary:Version}), @@ -118,7 +118,7 @@ Description: Documentation for the osmo coding library . This package contains the documentation for the libosmocoding library. -Package: libosmocore21 +Package: libosmocore22 Section: libs Architecture: any Multi-Arch: same @@ -139,7 +139,7 @@ Package: libosmocore-doc Architecture: all Section: doc Depends: ${misc:Depends}, - libosmocore21, + libosmocore22, libjs-jquery, libosmocodec-doc, libosmocoding-doc, diff --git a/debian/libosmocore21.install b/debian/libosmocore22.install index b73331b9..b73331b9 100644 --- a/debian/libosmocore21.install +++ b/debian/libosmocore22.install diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h index c5981f89..7a23e7f0 100644 --- a/include/osmocom/codec/codec.h +++ b/include/osmocom/codec/codec.h @@ -100,6 +100,9 @@ bool osmo_efr_check_sid(const uint8_t *rtp_payload, size_t payload_len); enum osmo_gsm631_sid_class osmo_fr_sid_classify(const uint8_t *rtp_payload); enum osmo_gsm631_sid_class osmo_efr_sid_classify(const uint8_t *rtp_payload); +enum osmo_gsm631_sid_class osmo_hr_sid_classify(const uint8_t *rtp_payload, + bool bci_flag, + bool *bfi_from_bci); /*! Check if given FR codec frame is any kind of SID, valid or invalid * \param[in] rtp_payload Buffer with RTP payload diff --git a/include/osmocom/core/Makefile.am b/include/osmocom/core/Makefile.am index 7c29ca10..980f8134 100644 --- a/include/osmocom/core/Makefile.am +++ b/include/osmocom/core/Makefile.am @@ -27,6 +27,7 @@ osmocore_HEADERS = \ hashtable.h \ isdnhdlc.h \ it_q.h \ + jhash.h \ linuxlist.h \ linuxrbtree.h \ log2.h \ diff --git a/include/osmocom/core/jhash.h b/include/osmocom/core/jhash.h new file mode 100644 index 00000000..763fcd7d --- /dev/null +++ b/include/osmocom/core/jhash.h @@ -0,0 +1,171 @@ +#pragma once +#include <osmocom/core/bit32gen.h> + +/* Below is a partial copy of + * https://raw.githubusercontent.com/torvalds/linux/3eb3c33c1d87029a3832e205eebd59cfb56ba3a4/tools/include/linux/bitops.h + * with an osmo_ prefix applied to avoid any collisions. + */ +/* SPDX-License-Identifier: GPL-2.0 */ +/** + * rol32 - rotate a 32-bit value left + * @word: value to rotate + * @shift: bits to roll + */ +static inline uint32_t osmo_rol32(uint32_t word, unsigned int shift) +{ + return (word << shift) | (word >> ((-shift) & 31)); +} + +/* Below is a partial copy of + * https://raw.githubusercontent.com/torvalds/linux/22c033989c3eb9731ad0c497dfab4231b8e367d6/include/linux/unaligned/packed_struct.h + * with an osmo_ prefix applied to avoid any collisions. + */ +struct osmo_unaligned_cpu32 { + uint32_t x; +} __attribute__((__packed__)); + +static inline uint32_t osmo_get_unaligned_cpu32(const void *p) +{ + const struct osmo_unaligned_cpu32 *ptr = (const struct osmo_unaligned_cpu32 *)p; + return ptr->x; +} + +/* Below is a partial copy of + * https://raw.githubusercontent.com/torvalds/linux/79e3ea5aab48c83de9410e43b52895406847eca7/tools/include/linux/jhash.h + * with an osmo_ prefix applied to avoid any collisions. + */ +/* jhash.h: Jenkins hash support. + * + * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net) + * + * https://burtleburtle.net/bob/hash/ + * + * These are the credits from Bob's sources: + * + * lookup3.c, by Bob Jenkins, May 2006, Public Domain. + * + * These are functions for producing 32-bit hashes for hash table lookup. + * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() + * are externally useful functions. Routines to test the hash are included + * if SELF_TEST is defined. You can use this free for any purpose. It's in + * the public domain. It has no warranty. + * + * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) + * + * I've modified Bob's hash to be useful in the Linux kernel, and + * any bugs present are my fault. + * Jozsef + */ + +/* OSMO_JHASH_MIX -- mix 3 32-bit values reversibly. */ +#define OSMO_JHASH_MIX(a, b, c) \ +{ \ + a -= c; a ^= osmo_rol32(c, 4); c += b; \ + b -= a; b ^= osmo_rol32(a, 6); a += c; \ + c -= b; c ^= osmo_rol32(b, 8); b += a; \ + a -= c; a ^= osmo_rol32(c, 16); c += b; \ + b -= a; b ^= osmo_rol32(a, 19); a += c; \ + c -= b; c ^= osmo_rol32(b, 4); b += a; \ +} + +/* OSMO_JHASH_FINAL - final mixing of 3 32-bit values (a,b,c) into c */ +#define OSMO_JHASH_FINAL(a, b, c) \ +{ \ + c ^= b; c -= osmo_rol32(b, 14); \ + a ^= c; a -= osmo_rol32(c, 11); \ + b ^= a; b -= osmo_rol32(a, 25); \ + c ^= b; c -= osmo_rol32(b, 16); \ + a ^= c; a -= osmo_rol32(c, 4); \ + b ^= a; b -= osmo_rol32(a, 14); \ + c ^= b; c -= osmo_rol32(b, 24); \ +} + +/* An arbitrary initial parameter */ +#define JHASH_INITVAL 0xdeadbeef + +/* osmo_jhash - hash an arbitrary key + * @k: sequence of bytes as key + * @length: the length of the key + * @initval: the previous hash, or an arbitray value + * + * The generic version, hashes an arbitrary sequence of bytes. + * No alignment or length assumptions are made about the input key. + * + * Returns the hash value of the key. The result depends on endianness. + */ +static inline uint32_t osmo_jhash(const void *key, uint32_t length, uint32_t initval) +{ + uint32_t a, b, c; + const uint8_t *k = key; + + /* Set up the internal state */ + a = b = c = JHASH_INITVAL + length + initval; + + /* All but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) { + a += osmo_get_unaligned_cpu32(k); + b += osmo_get_unaligned_cpu32(k + 4); + c += osmo_get_unaligned_cpu32(k + 8); + OSMO_JHASH_MIX(a, b, c); + length -= 12; + k += 12; + } + /* Last block: affect all 32 bits of (c) */ + /* All the case statements fall through */ + switch (length) { + case 12: c += (uint32_t)k[11]<<24; + case 11: c += (uint32_t)k[10]<<16; + case 10: c += (uint32_t)k[9]<<8; + case 9: c += k[8]; + case 8: b += (uint32_t)k[7]<<24; + case 7: b += (uint32_t)k[6]<<16; + case 6: b += (uint32_t)k[5]<<8; + case 5: b += k[4]; + case 4: a += (uint32_t)k[3]<<24; + case 3: a += (uint32_t)k[2]<<16; + case 2: a += (uint32_t)k[1]<<8; + case 1: a += k[0]; + OSMO_JHASH_FINAL(a, b, c); + case 0: /* Nothing left to add */ + break; + } + + return c; +} + +/* osmo_jhash2 - hash an array of uint32_t's + * @k: the key which must be an array of uint32_t's + * @length: the number of uint32_t's in the key + * @initval: the previous hash, or an arbitray value + * + * Returns the hash value of the key. + */ +static inline uint32_t osmo_jhash2(const uint32_t *k, uint32_t length, uint32_t initval) +{ + uint32_t a, b, c; + + /* Set up the internal state */ + a = b = c = JHASH_INITVAL + (length<<2) + initval; + + /* Handle most of the key */ + while (length > 3) { + a += k[0]; + b += k[1]; + c += k[2]; + OSMO_JHASH_MIX(a, b, c); + length -= 3; + k += 3; + } + + /* Handle the last 3 uint32_t's: all the case statements fall through */ + switch (length) { + case 3: c += k[2]; + case 2: b += k[1]; + case 1: a += k[0]; + OSMO_JHASH_FINAL(a, b, c); + case 0: /* Nothing left to add */ + break; + } + + return c; +} diff --git a/include/osmocom/core/osmo_io.h b/include/osmocom/core/osmo_io.h index 6f4dfa8a..fa1f9c3c 100644 --- a/include/osmocom/core/osmo_io.h +++ b/include/osmocom/core/osmo_io.h @@ -55,7 +55,7 @@ * \param[in] args arguments to the format string */ #define LOGPIO(iofd, level, fmt, args...) \ - LOGP(DLIO, level, "iofd(%s)" fmt, iofd->name, ## args) + LOGP(DLIO, level, "iofd(%s) " fmt, iofd->name, ## args) struct osmo_io_fd; diff --git a/include/osmocom/gprs/gprs_bssgp.h b/include/osmocom/gprs/gprs_bssgp.h index 6c043327..dff7268c 100644 --- a/include/osmocom/gprs/gprs_bssgp.h +++ b/include/osmocom/gprs/gprs_bssgp.h @@ -182,6 +182,12 @@ uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf); int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid, uint16_t cid); +int bssgp_parse_cell_id2(struct osmo_routing_area_id *raid, uint16_t *cid, + const uint8_t *buf, size_t buf_len); +int bssgp_create_cell_id2(uint8_t *buf, size_t buf_len, + const struct osmo_routing_area_id *raid, + uint16_t cid); + /* Wrapper around TLV parser to parse BSSGP IEs */ static inline int bssgp_tlv_parse(struct tlv_parsed *tp, const uint8_t *buf, int len) { diff --git a/include/osmocom/gsm/Makefile.am b/include/osmocom/gsm/Makefile.am index 5678a51e..e42ffeca 100644 --- a/include/osmocom/gsm/Makefile.am +++ b/include/osmocom/gsm/Makefile.am @@ -50,6 +50,7 @@ osmogsm_HEADERS = \ oap_client.h \ rlp.h \ rsl.h \ + rtp_extensions.h \ rxlev_stat.h \ sysinfo.h \ tlv.h \ diff --git a/include/osmocom/gsm/bts_features.h b/include/osmocom/gsm/bts_features.h index cf1db4ac..8da08d83 100644 --- a/include/osmocom/gsm/bts_features.h +++ b/include/osmocom/gsm/bts_features.h @@ -36,6 +36,8 @@ enum osmo_bts_features { BTS_FEAT_OSMUX, /* Osmux (Osmocom RTP muxing) support */ BTS_FEAT_VBS, /* Voice Broadcast Service support, 3GPP TS 43.069 */ BTS_FEAT_VGCS, /* Voice Group Call Service support, 3GPP TS 44.068 */ + BTS_FEAT_TWTS001, /* TW-TS-001: enhanced RTP transport for FR & EFR */ + BTS_FEAT_TWTS002, /* TW-TS-002: enhanced RTP transport for HRv1 */ _NUM_BTS_FEAT }; diff --git a/include/osmocom/gsm/gsm48.h b/include/osmocom/gsm/gsm48.h index 00fb6f40..d36b85cb 100644 --- a/include/osmocom/gsm/gsm48.h +++ b/include/osmocom/gsm/gsm48.h @@ -42,6 +42,8 @@ const char *rr_cause_name(uint8_t cause); const char *osmo_rai_name(const struct gprs_ra_id *rai); char *osmo_rai_name_buf(char *buf, size_t buf_len, const struct gprs_ra_id *rai); char *osmo_rai_name_c(const void *ctx, const struct gprs_ra_id *rai); +void osmo_rai_to_gprs(struct gprs_ra_id *dest, const struct osmo_routing_area_id *src); +void gprs_rai_to_osmo(struct osmo_routing_area_id *dest, const struct gprs_ra_id *src); int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc, uint16_t *mnc, uint16_t *lac) diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index 1e211dc9..45396566 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -332,9 +332,10 @@ enum GSM0808_IE_CODING { GSM0808_IE_PS_REGISTERED_OPERATOR = 0x99, GSM0808_IE_CS_REGISTERED_OPERATOR = 0x9a, - /* Osmocom extensions: */ + /* Osmocom and Themyscira extensions: */ GSM0808_IE_OSMO_OSMUX_SUPPORT = 0xf0, GSM0808_IE_OSMO_OSMUX_CID = 0xf1, + GSM0808_IE_THEMWI_RTP_EXTENSIONS = 0xf2, }; /* 3GPP TS 48.008 3.2.3 Signalling Field Element Coding. diff --git a/include/osmocom/gsm/protocol/gsm_08_58.h b/include/osmocom/gsm/protocol/gsm_08_58.h index e8758df0..13e84bad 100644 --- a/include/osmocom/gsm/protocol/gsm_08_58.h +++ b/include/osmocom/gsm/protocol/gsm_08_58.h @@ -373,6 +373,7 @@ enum abis_rsl_ie { RSL_IE_OSMO_TRAINING_SEQUENCE = 0x61, RSL_IE_OSMO_TEMP_OVP_ACCH_CAP = 0x62, RSL_IE_OSMO_OSMUX_CID = 0x63, + RSL_IE_OSMO_RTP_EXTENSIONS = 0x64, /* ip.access */ RSL_IE_IPAC_SRTP_CONFIG = 0xe0, diff --git a/include/osmocom/gsm/rtp_extensions.h b/include/osmocom/gsm/rtp_extensions.h new file mode 100644 index 00000000..edea4316 --- /dev/null +++ b/include/osmocom/gsm/rtp_extensions.h @@ -0,0 +1,23 @@ +/* + * Themyscira Wireless Technical Specification TW-TS-003 defines a BSSMAP + * extension whereby a CN implementation and a BSS implementation can + * negotiate the use of non-3GPP-standard extensions to RTP user plane, + * extensions that modify RTP formats counter to the stipulations of + * 3GPP TS 48.103. There is also a private Osmocom-defined IE in Abis RSL + * that communicates the same RTP extensions from OsmoBSC to OsmoBTS. + * + * This header file defines the meaning of the bits in the first (and currently + * only) value octet of the TLV IE added to BSSMAP and RSL interfaces, + * namely, GSM0808_IE_THEMWI_RTP_EXTENSIONS and RSL_IE_OSMO_RTP_EXTENSIONS. + * It is based on this authoritative definition: + * + * https://www.freecalypso.org/specs/tw-ts-003-v010002.txt + * + * Section 5.3 in the above specification defines the assignment of + * individual bits in the single value octet. + */ + +#pragma once + +#define OSMO_RTP_EXT_TWTS001 0x01 +#define OSMO_RTP_EXT_TWTS002 0x02 diff --git a/osmo-release.mk b/osmo-release.mk index 01285b13..a28372c7 100644 --- a/osmo-release.mk +++ b/osmo-release.mk @@ -1,9 +1,2 @@ -ifndef REL - REL := patch -endif - release: -ifeq ($(origin REL), file) - @echo "No REL value specified, defaulting to 'patch' release" -endif - @osmo-release.sh $(VERSION) $(REL) + @PATH="$$PWD:$$PATH" osmo-release.sh $(VERSION) $(REL) diff --git a/osmo-release.sh b/osmo-release.sh index e947fe43..61adf579 100755 --- a/osmo-release.sh +++ b/osmo-release.sh @@ -3,8 +3,17 @@ VERSION=$1 REL=$2 if [ "z$REL" = "z" ]; then - echo "No REL value specified, defaulting to 'patch' release" - REL="patch" + echo "usage: make REL=patch|minor|major release" + echo + echo "optional environment variables:" + echo " DRY_RUN=1 run checks but make no modifications" + echo " ALLOW_NO_LIBVERSION_CHANGE=1 skip LIBVERSION in Makefile.am fchecks" + echo " ALLOW_NO_LIBVERSION_DEB_MATCH=1 skip LIBVERSION in debian packaging checks" + echo " ALLOW_NO_LIBVERSION_RPM_MATCH=1 skip LIBVERSION in rpm packaging checks" + echo + echo "See also:" + echo "https://osmocom.org/projects/cellular-infrastructure/wiki/Make_a_new_release" + exit 1 fi ALLOW_NO_LIBVERSION_CHANGE="${ALLOW_NO_LIBVERSION_CHANGE:-0}" @@ -13,6 +22,23 @@ ALLOW_NO_LIBVERSION_RPM_MATCH="${ALLOW_NO_LIBVERSION_RPM_MATCH:-0}" # Test stuff but don't modify stuff: DRY_RUN="${DRY_RUN:-0}" +RESET="\033[1;0m" +RED="\033[1;31m" +GREEN="\033[1;32m" +YELLOW="\033[1;33m" + +ok() { + echo "${GREEN}OK:${RESET} $@" +} + +warn() { + echo "${YELLOW}WARN:${RESET} $@" +} + +error() { + echo "${RED}ERROR:${RESET} $@" +} + libversion_to_lib_major() { libversion="$1" current="$(echo "$libversion" | cut -d ":" -f 1)" @@ -43,16 +69,16 @@ check_configureac_debctrl_deps_match() { if [ "z$debctrl_match_count" != "z0" ]; then #echo "Dependency <$dep, $ver> from configure.ac matched in debian/control! ($debctrl_match_count)" if [ "z$debctrl_match_count" != "z1" ]; then - echo "WARN: configure.ac <$dep, $ver> matches debian/control $debctrl_match_count times, manual check required!" + warn "configure.ac <$dep, $ver> matches debian/control $debctrl_match_count times, manual check required!" else # 1 match: parsed_match=$(echo "$debctrl_match" | tr -d "(" | tr -d ")" | tr -d "," | tr -d " " | tr -d "\t" | sed "s/>=/ /g") debctrl_dep=$(echo "$parsed_match" | cut -d " " -f 1 | sed "s/-dev//g") debctrl_ver=$(echo "$parsed_match" | cut -d " " -f 2) if [ "z$dep" != "z$debctrl_dep" ] || [ "z$ver" != "z$debctrl_ver" ]; then - echo "ERROR: configure.ac <$dep, $ver> does NOT match debian/control <$debctrl_dep, $debctrl_ver>!" + error "configure.ac <$dep, $ver> does NOT match debian/control <$debctrl_dep, $debctrl_ver>!" return_error=1 #else - # echo "OK: configure.ac <$dep, $ver> matches debian/control <$debctrl_dep, $debctrl_ver>" + # ok "configure.ac <$dep, $ver> matches debian/control <$debctrl_dep, $debctrl_ver>" fi fi fi @@ -64,10 +90,10 @@ check_configureac_debctrl_deps_match() { # catch and forward exit from pipe subshell "while read": if [ $? -ne 0 ]; then - echo "ERROR: exiting due to previous errors" + error "exiting due to previous errors" exit 1 fi - echo "OK: dependency specific versions in configure.ac and debian/control match" + ok "dependency specific versions in configure.ac and debian/control match" } # Make sure that depedency requirement versions match in configure.ac vs contrib/*.spec.in. @@ -88,16 +114,16 @@ check_configureac_rpmspecin_deps_match() { if [ "z$rpmspecin_match_count" != "z0" ]; then #echo "Dependency <$dep, $ver> from configure.ac matched in contrib/*.spec.in! ($rpmspecin_match_count)" if [ "z$rpmspecin_match_count" != "z1" ]; then - echo "WARN: configure.ac <$dep, $ver> matches contrib/*.spec.in $rpmspecin_match_count times, manual check required!" + warn "configure.ac <$dep, $ver> matches contrib/*.spec.in $rpmspecin_match_count times, manual check required!" else # 1 match: parsed_match=$(echo "$rpmspecin_match" | tr -d "(" | tr -d ")" | tr -d ":" | tr -d " " | tr -d "\t" | sed "s/BuildRequires//g" | sed "s/pkgconfig//g" |sed "s/>=/ /g") rpmspecin_dep=$(echo "$parsed_match" | cut -d " " -f 1) rpmspecin_ver=$(echo "$parsed_match" | cut -d " " -f 2) if [ "z$dep" != "z$rpmspecin_dep" ] || [ "z$ver" != "z$rpmspecin_ver" ]; then - echo "ERROR: configure.ac <$dep, $ver> does NOT match contrib/*.spec.in <$rpmspecin_dep, $rpmspecin_ver>!" + error "configure.ac <$dep, $ver> does NOT match contrib/*.spec.in <$rpmspecin_dep, $rpmspecin_ver>!" return_error=1 #else - # echo "OK: configure.ac <$dep, $ver> matches contrib/*.spec.in <$debctrl_dep, $debctrl_ver>" + # ok "configure.ac <$dep, $ver> matches contrib/*.spec.in <$debctrl_dep, $debctrl_ver>" fi fi fi @@ -109,10 +135,10 @@ check_configureac_rpmspecin_deps_match() { # catch and forward exit from pipe subshell "while read": if [ $? -ne 0 ]; then - echo "ERROR: exiting due to previous errors" + error "exiting due to previous errors" exit 1 fi - echo "OK: dependency specific versions in configure.ac and contrib/*.spec.in match" + ok "dependency specific versions in configure.ac and contrib/*.spec.in match" } # Make sure that patches under debian/patches/ apply: @@ -123,10 +149,10 @@ check_debian_patch_apply() { for patch in ${GIT_TOPDIR}/debian/patches/*.patch; do git apply --check $patch if [ $? -ne 0 ]; then - echo "ERROR: patch no longer applies! $patch" + error "patch no longer applies! $patch" exit 1 else - echo "OK: patch applies: $patch" + ok "patch applies: $patch" fi done } @@ -137,34 +163,34 @@ libversion_deb_match() { major="$(libversion_to_lib_major "$libversion")" file_matches="$(find "${GIT_TOPDIR}/debian" -name "lib*${major}.install" | wc -l)" if [ "z$file_matches" = "z0" ]; then - echo "ERROR: Found no matching debian/lib*$major.install file for LIBVERSION=$libversion" + error "Found no matching debian/lib*$major.install file for LIBVERSION=$libversion" exit 1 elif [ "z$file_matches" = "z1" ]; then - echo "OK: Found matching debian/lib*$major.install for LIBVERSION=$libversion" + ok "Found matching debian/lib*$major.install for LIBVERSION=$libversion" else - echo "WARN: Found $file_matches files matching debian/lib*$major.install for LIBVERSION=$libversion, manual check required!" + warn "Found $file_matches files matching debian/lib*$major.install for LIBVERSION=$libversion, manual check required!" fi control_matches="$(grep -e "Package" "${GIT_TOPDIR}/debian/control" | grep "lib" | grep "$major$" | wc -l)" if [ "z$control_matches" = "z0" ]; then - echo "ERROR: Found no matching Package lib*$major in debian/control for LIBVERSION=$libversion" + error "Found no matching Package lib*$major in debian/control for LIBVERSION=$libversion" exit 1 elif [ "z$control_matches" = "z1" ]; then - echo "OK: Found 'Package: lib*$major' in debian/control for LIBVERSION=$libversion" + ok "Found 'Package: lib*$major' in debian/control for LIBVERSION=$libversion" else - echo "WARN: Found $file_matches files matching 'Package: lib*$major' in debian/control for LIBVERSION=$libversion, manual check required!" + warn "Found $file_matches files matching 'Package: lib*$major' in debian/control for LIBVERSION=$libversion, manual check required!" fi dhstrip_lib_total="$(grep -e "dh_strip" "${GIT_TOPDIR}/debian/rules" | grep "\-plib" | wc -l)" dhstrip_lib_matches="$(grep -e "dh_strip" "${GIT_TOPDIR}/debian/rules" | grep "\-plib" | grep "$major" | wc -l)" if [ "z$dhstrip_lib_total" != "z0" ]; then if [ "z$dhstrip_lib_matches" = "z0" ] ; then - echo "ERROR: Found no matching 'dh_strip -plib*$major' line in debian/rules for LIBVERSION=$libversion" + error "Found no matching 'dh_strip -plib*$major' line in debian/rules for LIBVERSION=$libversion" exit 1 elif [ "z$dhstrip_lib_total" = "z1" ]; then - echo "OK: Found 'dh_strip -plib*$major' in debian/rules for LIBVERSION=$libversion" + ok "Found 'dh_strip -plib*$major' in debian/rules for LIBVERSION=$libversion" else - echo "WARN: Found $dhstrip_lib_matches/$dhstrip_lib_total dh_strip matches 'dh_strip -plib*$major' in debian/rules for LIBVERSION=$libversion, manual check required!" + warn "Found $dhstrip_lib_matches/$dhstrip_lib_total dh_strip matches 'dh_strip -plib*$major' in debian/rules for LIBVERSION=$libversion, manual check required!" fi fi done @@ -187,22 +213,22 @@ libversion_rpmspecin_match() { control_matches="$(grep -e "%files" "${GIT_TOPDIR}/contrib/"*.spec.in | grep "lib" | grep "$major$" | wc -l)" if [ "z$control_matches" = "z0" ]; then - echo "ERROR: Found no matching '%files -n lib*$major' in contrib/*.spec.in for LIBVERSION=$libversion" + error "Found no matching '%files -n lib*$major' in contrib/*.spec.in for LIBVERSION=$libversion" exit 1 elif [ "z$control_matches" = "z1" ]; then - echo "OK: Found '%files -n lib*$major' in contrib/*.spec.in for LIBVERSION=$libversion" + ok "Found '%files -n lib*$major' in contrib/*.spec.in for LIBVERSION=$libversion" else - echo "WARN: Found $file_matches files matching '%files -n lib*$major' in contrib/*.spec.in for LIBVERSION=$libversion, manual check required!" + warn "Found $file_matches files matching '%files -n lib*$major' in contrib/*.spec.in for LIBVERSION=$libversion, manual check required!" fi control_matches="$(grep -e "_libdir" "${GIT_TOPDIR}/contrib/"*.spec.in | grep "/lib" | grep "so.$major" | wc -l)" if [ "z$control_matches" = "z0" ]; then - echo "ERROR: Found no matching '%_libdir/lib*.so.$major*' in contrib/*.spec.in for LIBVERSION=$libversion" + error "Found no matching '%_libdir/lib*.so.$major*' in contrib/*.spec.in for LIBVERSION=$libversion" exit 1 elif [ "z$control_matches" = "z1" ]; then - echo "OK: Found '%_libdir/lib*.so.$major*' in contrib/*.spec.in for LIBVERSION=$libversion" + ok "Found '%_libdir/lib*.so.$major*' in contrib/*.spec.in for LIBVERSION=$libversion" else - echo "WARN: Found $file_matches files matching '%_libdir/lib*.so.$major*' in contrib/*.spec.in for LIBVERSION=$libversion, manual check required!" + warn "Found $file_matches files matching '%_libdir/lib*.so.$major*' in contrib/*.spec.in for LIBVERSION=$libversion, manual check required!" fi done # catch and forward exit from pipe subshell "while read": @@ -211,6 +237,20 @@ libversion_rpmspecin_match() { fi } +clean_todo_release() { + rm -f TODO-RELEASE + echo "# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install" >> TODO-RELEASE + echo "# according to https://osmocom.org/projects/cellular-infrastructure/wiki/Make_a_new_release" >> TODO-RELEASE + echo "# In short: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info" >> TODO-RELEASE + echo "# LIBVERSION=c:r:a" >> TODO-RELEASE + echo "# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a." >> TODO-RELEASE + echo "# If any interfaces have been added, removed, or changed since the last update: c + 1:0:a." >> TODO-RELEASE + echo "# If any interfaces have been added since the last public release: c:r:a + 1." >> TODO-RELEASE + echo "# If any interfaces have been removed or changed since the last public release: c:r:0." >> TODO-RELEASE + echo "#library what description / commit summary line" >> TODO-RELEASE + git add TODO-RELEASE +} + BUMPVER=`command -v bumpversion` if [ "z$BUMPVER" = "z" ]; then @@ -235,7 +275,7 @@ check_debian_patch_apply if [ "z$LIBVERS" != "z" ]; then if [ "z$MAKEMOD" = "z" ] && [ "z$ALLOW_NO_LIBVERSION_CHANGE" = "z0" ]; then - echo "ERROR: Before releasing, please modify some of the libversions:" + error "Before releasing, please modify some of the libversions:" for l in $LIBVERS; do echo " $l"; done echo "After making changes, add modified file(s) to the index using git-add." echo "You should NOT be doing this unless you've read and understood following article:" @@ -255,10 +295,9 @@ if [ "z$DRY_RUN" != "z0" ]; then fi set -e + if [ -f "TODO-RELEASE" ]; then - grep '#' TODO-RELEASE > TODO-RELEASE.clean || true - mv TODO-RELEASE.clean TODO-RELEASE - git add TODO-RELEASE + clean_todo_release fi # Add missing epoch (OS#5046) diff --git a/src/codec/Makefile.am b/src/codec/Makefile.am index bb01b9d3..17227b67 100644 --- a/src/codec/Makefile.am +++ b/src/codec/Makefile.am @@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=4:0:0 +LIBVERSION=4:1:0 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) AM_CFLAGS = -Wall $(TALLOC_CFLAGS) @@ -18,6 +18,7 @@ libosmocodec_la_SOURCES = \ gsm620.c \ gsm660.c \ gsm690.c \ + hr_sid_class.c \ ecu.c \ ecu_fr.c \ ecu_fr_old.c \ diff --git a/src/codec/gsm620.c b/src/codec/gsm620.c index ef1d3b9b..49ee7243 100644 --- a/src/codec/gsm620.c +++ b/src/codec/gsm620.c @@ -23,8 +23,6 @@ #include <stdbool.h> #include <string.h> -#include <osmocom/core/bitvec.h> -#include <osmocom/core/utils.h> #include <osmocom/codec/codec.h> /* GSM HR unvoiced (mode=0) frames - subjective importance bit ordering */ @@ -270,21 +268,32 @@ const uint16_t gsm620_voiced_bitorder[112] = { * \param[in] rtp_payload Buffer with RTP payload * \param[in] payload_len Length of payload * \returns true if code word is found, false otherwise + * + * Note that this function checks only for a perfect, error-free SID. + * Unlike GSM 06.31 for FR or GSM 06.81 for EFR, GSM 06.41 spec for HR + * does not prescribe exact bit counting rules, hence detection of + * partially corrupted SID frames in downstream network elements + * without out-of-band indication is not possible. */ bool osmo_hr_check_sid(const uint8_t *rtp_payload, size_t payload_len) { - struct bitvec bv = { - .data = (uint8_t *)rtp_payload, - .data_len = payload_len, - }; + static const uint8_t all_ff_bytes[9] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF}; - /* A SID frame is identified by a SID codeword consisting of 79 bits which are all 1, - * so we basically check if all bits in range r34..r112 (inclusive) are 1. */ - for (bv.cur_bit = 33; bv.cur_bit < bv.data_len * 8; bv.cur_bit++) - if (bitvec_get_bit_pos(&bv, bv.cur_bit) != ONE) - return false; + if (payload_len < GSM_HR_BYTES) + return false; - return true; + /* A SID frame is identified by a SID codeword consisting of 79 bits + * which are all 1, so we basically check if all bits in range + * r34..r112 (inclusive) are 1. However, given the position of + * these bits in the frame, the most efficient way to perform + * this check does not use any bit-level operations. */ + if ((rtp_payload[4] & 0x7F) != 0x7F) + return false; + if (memcmp(rtp_payload + 5, all_ff_bytes, 9) == 0) + return true; + else + return false; } /*! Reset the SID field of a potentially corrupted, but still valid GSM-HR diff --git a/src/codec/hr_sid_class.c b/src/codec/hr_sid_class.c new file mode 100644 index 00000000..6c5ba3d2 --- /dev/null +++ b/src/codec/hr_sid_class.c @@ -0,0 +1,176 @@ +/* + * This module implements osmo_hr_sid_classify() function - an independent + * reimplementation of the logic that was recommended (but not stipulated + * as normative) by ETSI for classifying received TCH/HS frames as + * valid SID, invalid SID or non-SID speech. + * + * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2024 - however, + * Mother Mychaela's contributions are NOT subject to copyright. + * No rights reserved, all rights relinquished. + * + * 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. + */ + +#include <stdint.h> +#include <stdbool.h> + +#include <osmocom/codec/codec.h> + +/* + * Input to the table: any 4-bit nibble. + * Output from the table: number of 1 bits in that nibble. + */ +static const uint8_t ones_in_nibble[16] = {0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4}; + +/* + * This helper function takes two byte arrays of equal length (data and mask), + * applies the mask to the data, then counts how many bits are set to 1 + * under the mask, and returns that number. + */ +static unsigned count_ones_under_mask(const uint8_t *data, const uint8_t *mask, + unsigned nbytes) +{ + unsigned n, accum; + uint8_t and; + + accum = 0; + for (n = 0; n < nbytes; n++) { + and = *data++ & *mask++; + accum += ones_in_nibble[and >> 4] + ones_in_nibble[and & 0xF]; + } + return accum; +} + +/* + * When a GSM-HR SID frame has been decoded correctly in voiced mode, + * the 79 bits of the SID field will be the last bits in the frame. + * In the packed format of TS 101 318, the bits of interest will be + * in the last 10 bytes. The following array is the mask to be applied. + */ +static const uint8_t sid_field_last10_mask[10] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +/* + * When a GSM-HR SID frame has been incorrectly decoded in unvoiced mode + * (both mode bits got flipped to 0 by channel errors), the 79 bits + * of the SID field will be badly misordered all over the frame. + * However, they can still be counted for the purpose of SID detection. + * The following array is the mask to be applied to the whole frame + * (14 bytes) to locate the misordered SID field. + */ +static const uint8_t sid_field_misordered[14] = { + 0x08, 0xEF, 0x1F, 0x3F, 0xF3, 0xFC, 0xA4, + 0xFF, 0xFA, 0x3F, 0xFF, 0x47, 0xFF, 0xEC +}; + +/* + * In the channel coding scheme on TCH/HS, the HR codec frame of 112 bits + * is divided into 95 class 1 bits and 17 class 2 bits. In the packed + * format of TS 101 318, all 17 class 2 bits will always be in the last + * 4 bytes; however, the specific bits will be different depending on + * whether the frame was decoded in voiced or unvoiced mode. + * The following two arrays are masks to be applied to the last 4 bytes. + */ +static const uint8_t class2_mask_voiced[4] = {0x7F, 0x80, 0x3F, 0xE0}; +static const uint8_t class2_mask_unvoiced[4] = {0x07, 0x07, 0xFF, 0xE0}; + +/* + * osmo_hr_sid_classify() - this function is an independent reimplementation + * of the logic that was recommended (but not stipulated as normative) by ETSI + * for classifying received TCH/HS frames as valid SID, invalid SID or non-SID + * speech. ETSI's original version is swSidDetection() function in reid.c + * in GSM 06.06 source; the present version implements exactly the same + * logic (same inputs will produce same output), but differs in the following + * ways: + * + * - The frame of channel-decoded 112 payload bits was passed in the form + * of an array of 18 codec parameters in ETSI's version; the present version + * uses the packed format of TS 101 318 instead. + * + * - The C code implementation was written anew by Mother Mychaela; no code + * in this file has been copied directly from GSM 06.06 code drop. + * + * This function is meant to be used only in the same network element + * that performs GSM 05.03 channel decoding (OsmoBTS, new implementations + * of GSM MS), _*NOT*_ in programs or network elements that receive + * HRv1 codec frames from other elements via RTP or Abis-E1 etc! + * + * The BCI logic recommended by ETSI and implemented in practice by at least + * one vendor whose implementation has been reverse-engineered (TI Calypso) + * is included in this function. To understand this logic, please refer + * to this wiki description: + * + * https://osmocom.org/projects/retro-gsm/wiki/HRv1_error_flags + */ +enum osmo_gsm631_sid_class osmo_hr_sid_classify(const uint8_t *rtp_payload, + bool bci_flag, + bool *bfi_from_bci) +{ + uint8_t mode_bits = rtp_payload[4] & 0x30; + unsigned sid_field_ones, class1_ones, class2_ones; + unsigned sid_field_zeros, class1_zeros; + unsigned invalid_sid_threshold; + enum osmo_gsm631_sid_class sidc; + + if (mode_bits != 0) { /* decoded as voiced */ + sid_field_ones = count_ones_under_mask(rtp_payload + 4, + sid_field_last10_mask, 10); + class2_ones = count_ones_under_mask(rtp_payload + 10, + class2_mask_voiced, 4); + } else { /* decoded as unvoiced */ + sid_field_ones = count_ones_under_mask(rtp_payload, + sid_field_misordered, 14); + class2_ones = count_ones_under_mask(rtp_payload + 10, + class2_mask_unvoiced, 4); + } + /* All class 2 bits are in SID field, hence class2_ones can never + * be greater than sid_field_ones. */ + class1_ones = sid_field_ones - class2_ones; + /* 79 is the total number of bits in the SID field */ + sid_field_zeros = 79 - sid_field_ones; + /* 62 is the total number of class 1 bits in TCH/HS frame */ + class1_zeros = 62 - class1_ones; + + /* frame classification logic recommended by ETSI */ + if (bci_flag) + invalid_sid_threshold = 16; + else + invalid_sid_threshold = 11; + + if (class1_zeros < 3) + sidc = OSMO_GSM631_SID_CLASS_VALID; + else if (sid_field_zeros < invalid_sid_threshold) + sidc = OSMO_GSM631_SID_CLASS_INVALID; + else + sidc = OSMO_GSM631_SID_CLASS_SPEECH; + + /* If the mode bits got corrupted and the frame was channel-decoded + * as unvoiced, it cannot be taken as valid SID because the bits + * that hold CN parameters have been misordered. Therefore, + * we have to turn it into invalid SID classification. + */ + if (mode_bits == 0 && sidc == OSMO_GSM631_SID_CLASS_VALID) + sidc = OSMO_GSM631_SID_CLASS_INVALID; + + /* ETSI's peculiar logic that "upgrades" BCI error flag to BFI + * (from lowest to highest error severity) when the decoded bit + * pattern matches a set criterion. We leave it up to applications + * whether they choose to apply this logic or not. If this logic + * is not wanted, pass NULL pointer as the last argument. + */ + if (bci_flag && bfi_from_bci && + sid_field_zeros >= 16 && sid_field_zeros <= 25) + *bfi_from_bci = true; + + return sidc; +} diff --git a/src/coding/Makefile.am b/src/coding/Makefile.am index 0cab66ff..c2a02d5b 100644 --- a/src/coding/Makefile.am +++ b/src/coding/Makefile.am @@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read Chapter 6 "Library interface versions" of the libtool # documentation before making any modification -LIBVERSION=3:0:3 +LIBVERSION=3:1:3 AM_CPPFLAGS = \ -I"$(top_srcdir)/include" \ diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 2efebd8d..96e64602 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=21:0:0 +LIBVERSION=22:0:0 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) AM_CFLAGS = -Wall $(TALLOC_CFLAGS) $(PTHREAD_CFLAGS) $(LIBSCTP_CFLAGS) $(LIBMNL_CFLAGS) $(URING_CFLAGS) diff --git a/src/core/socket.c b/src/core/socket.c index 80a9d0ec..90cf4cab 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -172,8 +172,8 @@ static int socket_helper(const struct addrinfo *rp, unsigned int flags) sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sfd == -1) { - LOGP(DLGLOBAL, LOGL_ERROR, - "unable to create socket: %s\n", strerror(errno)); + LOGP(DLGLOBAL, LOGL_ERROR, "unable to create socket(%d, %d, %d): %s\n", + rp->ai_family, rp->ai_socktype, rp->ai_protocol, strerror(errno)); return sfd; } @@ -278,6 +278,24 @@ static int osmo_sock_init_tail(int fd, uint16_t type, unsigned int flags) return 0; } +/*! Determine if the system supports AF_INET6 sockets at all. + * We call socket(AF_INET6) once and cache the result value. */ +static bool system_supports_inet6(void) +{ + static int cached_val = -1; + + if (cached_val < 0) { + int rc = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (rc < 0 && errno == EAFNOSUPPORT) { + cached_val = 0; + } else if (rc >= 0) { + cached_val = 1; + close(rc); + } + } + return cached_val == 1; +} + /*! Initialize a socket (including bind and/or connect) * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM @@ -343,26 +361,31 @@ int osmo_sock_init2(uint16_t family, uint16_t type, uint8_t proto, /* It must do a full run to ensure AF_UNSPEC does not fail. * In case first local valid entry is IPv4 and only remote valid entry * is IPv6 or vice versa */ - if (family == AF_UNSPEC) { + if (!system_supports_inet6()) { + /* if no AF_INET6 is supported, then the decision is easy...*/ + local_ipv4 = true; + remote_ipv4 = true; + family = AF_INET; + } else if (family == AF_UNSPEC) { for (rp = local; rp != NULL; rp = rp->ai_next) { switch (rp->ai_family) { - case AF_INET: - local_ipv4 = true; - break; - case AF_INET6: - local_ipv6 = true; - break; + case AF_INET: + local_ipv4 = true; + break; + case AF_INET6: + local_ipv6 = true; + break; } } for (rp = remote; rp != NULL; rp = rp->ai_next) { switch (rp->ai_family) { - case AF_INET: - remote_ipv4 = true; - break; - case AF_INET6: - remote_ipv6 = true; - break; + case AF_INET: + remote_ipv4 = true; + break; + case AF_INET6: + remote_ipv6 = true; + break; } } diff --git a/src/ctrl/Makefile.am b/src/ctrl/Makefile.am index f9e34333..9d3254c1 100644 --- a/src/ctrl/Makefile.am +++ b/src/ctrl/Makefile.am @@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=8:1:8 +LIBVERSION=9:0:9 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) AM_CFLAGS = -Wall $(TALLOC_CFLAGS) diff --git a/src/gb/Makefile.am b/src/gb/Makefile.am index 2f7ad5eb..0aa5b131 100644 --- a/src/gb/Makefile.am +++ b/src/gb/Makefile.am @@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=16:0:2 +LIBVERSION=16:1:2 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) AM_CFLAGS = -Wall -fno-strict-aliasing \ diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c index 7abef804..d436f0aa 100644 --- a/src/gb/gprs_bssgp.c +++ b/src/gb/gprs_bssgp.c @@ -354,6 +354,24 @@ uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf) return osmo_load16be(buf+6); } +/*! Parse the value of a BSSGP Cell identity (04.08 RAI + Cell Id) */ +int bssgp_parse_cell_id2(struct osmo_routing_area_id *raid, uint16_t *cid, + const uint8_t *buf, size_t buf_len) +{ + if (buf_len < 8) + return -EINVAL; + + /* 6 octets RAC */ + if (raid) + osmo_routing_area_id_decode(raid, buf, buf_len); + + /* 2 octets CID */ + if (cid) + *cid = osmo_load16be(buf + sizeof(struct gsm48_ra_id)); + + return 0; +} + int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid, uint16_t cid) { @@ -365,6 +383,23 @@ int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid, return 8; } +/*! Encode the 04.08 RAI, Cell Id into BSSGP Cell identity */ +int bssgp_create_cell_id2(uint8_t *buf, size_t buf_len, + const struct osmo_routing_area_id *raid, + const uint16_t cid) +{ + if (buf_len < 8) + return -ENOMEM; + + /* 6 octets RAC */ + osmo_routing_area_id_encode_buf(buf, buf_len, raid); + + /* 2 octets CID */ + osmo_store16be(cid, buf + sizeof(struct gsm48_ra_id)); + + return 8; +} + /* Chapter 8.4 BVC-Reset Procedure */ static int bssgp_rx_bvc_reset(struct msgb *msg, struct tlv_parsed *tp, uint16_t ns_bvci) diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map index e5a5c8fd..f1a6bd69 100644 --- a/src/gb/libosmogb.map +++ b/src/gb/libosmogb.map @@ -2,6 +2,7 @@ LIBOSMOGB_1.0 { global: bssgp_cause_str; bssgp_create_cell_id; +bssgp_create_cell_id2; bssgp_create_rim_ri; bssgp_dec_app_err_cont_nacc; bssgp_dec_ran_inf_ack_rim_cont; @@ -32,6 +33,7 @@ bssgp_msgb_tlli_put; bssgp_msgb_ra_put; bssgp_nacc_cause_strs; bssgp_parse_cell_id; +bssgp_parse_cell_id2; bssgp_parse_rim_pdu; bssgp_parse_rim_ri; bssgp_parse_rim_ra; diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index e6b687d2..8c70473e 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=20:0:0 +LIBVERSION=21:0:1 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include AM_CFLAGS = -Wall $(TALLOC_CFLAGS) diff --git a/src/gsm/bts_features.c b/src/gsm/bts_features.c index b6cd82ec..158937a9 100644 --- a/src/gsm/bts_features.c +++ b/src/gsm/bts_features.c @@ -47,6 +47,8 @@ const struct value_string osmo_bts_features_descs[] = { { BTS_FEAT_OSMUX, "Osmux (Osmocom RTP multiplexing)" }, { BTS_FEAT_VBS, "Voice Broadcast Service" }, { BTS_FEAT_VGCS, "Voice Group Call Service" }, + { BTS_FEAT_TWTS001, "TW-TS-001 RTP format" }, + { BTS_FEAT_TWTS002, "TW-TS-002 RTP format" }, { 0, NULL } }; @@ -88,6 +90,8 @@ const struct value_string osmo_bts_features_names[] = { { BTS_FEAT_OSMUX, "OSMUX" }, { BTS_FEAT_VBS, "VBS" }, { BTS_FEAT_VGCS, "VGCS" }, + { BTS_FEAT_TWTS001, "TWTS001" }, + { BTS_FEAT_TWTS002, "TWTS002" }, {} }; diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index 529dbdfe..85c2aef1 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -2310,9 +2310,10 @@ static const struct tlv_definition bss_att_tlvdef = { [GSM0808_IE_PS_REGISTERED_OPERATOR] = { TLV_TYPE_FIXED, 3 }, [GSM0808_IE_CS_REGISTERED_OPERATOR] = { TLV_TYPE_FIXED, 3 }, - /* Osmocom extensions */ + /* Osmocom and Themyscira extensions */ [GSM0808_IE_OSMO_OSMUX_SUPPORT] = { TLV_TYPE_T }, [GSM0808_IE_OSMO_OSMUX_CID] = { TLV_TYPE_TV }, + [GSM0808_IE_THEMWI_RTP_EXTENSIONS] = { TLV_TYPE_TLV }, }, }; diff --git a/src/gsm/gsm23236.c b/src/gsm/gsm23236.c index 4a83ec82..a80ecf46 100644 --- a/src/gsm/gsm23236.c +++ b/src/gsm/gsm23236.c @@ -487,7 +487,7 @@ static int osmo_nri_parse_range(struct osmo_nri_range *nri_range, const char *fi int osmo_nri_ranges_vty_add(const char **message, struct osmo_nri_range *added_range, struct osmo_nri_ranges *nri_ranges, int argc, const char **argv, uint8_t nri_bitlen) { - struct osmo_nri_range add_range; + struct osmo_nri_range add_range = {}; if (osmo_nri_parse_range(&add_range, argv[0], argc > 1 ? argv[1] : NULL)) { *message = "Error: cannot parse NRI range"; return -1; @@ -523,7 +523,7 @@ int osmo_nri_ranges_vty_add(const char **message, struct osmo_nri_range *added_r int osmo_nri_ranges_vty_del(const char **message, struct osmo_nri_range *removed_range, struct osmo_nri_ranges *nri_ranges, int argc, const char **argv) { - struct osmo_nri_range del_range; + struct osmo_nri_range del_range = {}; if (osmo_nri_parse_range(&del_range, argv[0], argc > 1 ? argv[1] : NULL)) { *message = "Error: cannot parse NRI range"; return -1; diff --git a/src/gsm/gsm48.c b/src/gsm/gsm48.c index 64b17658..1201595e 100644 --- a/src/gsm/gsm48.c +++ b/src/gsm/gsm48.c @@ -222,6 +222,34 @@ char *osmo_rai_name_c(const void *ctx, const struct gprs_ra_id *rai) return osmo_rai_name_buf(buf, 32, rai); } +/*! Convert osmo_routing_area_id (new) into gprs_ra_id (old) */ +void osmo_rai_to_gprs(struct gprs_ra_id *dest, const struct osmo_routing_area_id *src) +{ + OSMO_ASSERT(src); + OSMO_ASSERT(dest); + + dest->mcc = src->lac.plmn.mcc; + dest->mnc = src->lac.plmn.mnc; + dest->mnc_3_digits = src->lac.plmn.mnc_3_digits; + + dest->lac = src->lac.lac; + dest->rac = src->rac; +} + +/*! Convert gprs_ra_id (old) into osmo_routing_area_id (new) */ +void gprs_rai_to_osmo(struct osmo_routing_area_id *dest, const struct gprs_ra_id *src) +{ + OSMO_ASSERT(src); + OSMO_ASSERT(dest); + + dest->lac.plmn.mcc = src->mcc; + dest->lac.plmn.mnc = src->mnc; + dest->lac.plmn.mnc_3_digits = src->mnc_3_digits; + + dest->lac.lac = src->lac; + dest->rac = src->rac; +} + /* FIXME: convert to value_string */ static const char *cc_state_names[32] = { "NULL", diff --git a/src/gsm/iuup.c b/src/gsm/iuup.c index 16a6f5e0..49912131 100644 --- a/src/gsm/iuup.c +++ b/src/gsm/iuup.c @@ -1,5 +1,9 @@ /*! \file iu_up.c - * IuUP (Iu User Plane) according to 3GPP TS 25.415 */ + * IuUP (Iu User Plane) according to 3GPP TS 25.415 + * See also 3GPP TS 25.414 regarding data transport. + * See also 3GPP TS 29.414 and 3GPP TS 29.415 regarding Nb counterparts + * of the above specs. + */ /* * (C) 2017 by Harald Welte <laforge@gnumonks.org> * diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 2c4c621c..3bc8309c 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -487,6 +487,8 @@ osmo_rai_name_c; osmo_rai_name2; osmo_rai_name2_buf; osmo_rai_name2_c; +osmo_rai_to_gprs; +gprs_rai_to_osmo; osmo_cgi_cmp; osmo_cgi_name; osmo_cgi_name_buf; diff --git a/src/gsm/rsl.c b/src/gsm/rsl.c index fbba982a..c7d69a14 100644 --- a/src/gsm/rsl.c +++ b/src/gsm/rsl.c @@ -126,6 +126,7 @@ const struct tlv_definition rsl_att_tlvdef = { [RSL_IE_OSMO_TRAINING_SEQUENCE] = { TLV_TYPE_TLV }, [RSL_IE_OSMO_TEMP_OVP_ACCH_CAP] = { TLV_TYPE_TLV }, [RSL_IE_OSMO_OSMUX_CID] = { TLV_TYPE_TLV }, + [RSL_IE_OSMO_RTP_EXTENSIONS] = { TLV_TYPE_TLV }, [RSL_IE_IPAC_SRTP_CONFIG] = { TLV_TYPE_TLV }, [RSL_IE_IPAC_PROXY_UDP] = { TLV_TYPE_FIXED, 2 }, [RSL_IE_IPAC_BSCMPL_TOUT] = { TLV_TYPE_TV }, diff --git a/src/isdn/Makefile.am b/src/isdn/Makefile.am index 3e7f86eb..51455452 100644 --- a/src/isdn/Makefile.am +++ b/src/isdn/Makefile.am @@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=1:0:1 +LIBVERSION=2:0:2 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include AM_CFLAGS = -Wall $(TALLOC_CFLAGS) diff --git a/src/sim/Makefile.am b/src/sim/Makefile.am index 0f6be576..01c51757 100644 --- a/src/sim/Makefile.am +++ b/src/sim/Makefile.am @@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=3:2:1 +LIBVERSION=3:3:1 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) AM_CFLAGS = -fPIC -Wall $(TALLOC_CFLAGS) diff --git a/src/sim/class_tables.c b/src/sim/class_tables.c index 29c1e40e..7500fc5a 100644 --- a/src/sim/class_tables.c +++ b/src/sim/class_tables.c @@ -19,6 +19,14 @@ #include <osmocom/core/utils.h> #include <osmocom/sim/class_tables.h> +/* Quick reminder about the "cases" as per ISO7816-3 / ETSI TS 102 221 Section 7.3.1.1 + * + * Case 1: Command Length 0, Response Length 0 + * Case 2: Command Length 0, Response Length from P3 + * Case 3: Command Length P3, Response Length 0 + * Case 4: Command Length P3, followed by 61xx for response length + GET RESPONSE + */ + static const uint8_t iso7816_ins_tbl[256] = { [0xB0] = 2, /* READ BIN */ [0xD0] = 3, /* WRITE BIN */ @@ -178,6 +186,7 @@ static int gp_cla_ins_helper(const struct osim_cla_ins_case *cic, { uint8_t ins = hdr[1]; uint8_t p1 = hdr[2]; + uint8_t p3 = hdr[4]; switch (ins) { case 0xE2: /* STORE DATA */ @@ -187,6 +196,26 @@ static int gp_cla_ins_helper(const struct osim_cla_ins_case *cic, default: return 3; } + break; + case 0xF2: + /* in their infinite wisdom, GlobalPlatform re-defined the CLA 8x / INS F2 command, so one can + * take a guess if it's GlobalPlatform or ETSI. Lucikly, the P1 coding of ETSI [so far] + * states all the four upper bits must be 0, while GP always has one of those bits set */ + if (p1 & 0xF0) + return 4; /* GlobalPlatform v2.2 11.4.2 */ + else + return 2; /* ETSI TS 102 221 V16.2.0 11.1.2 */ + break; + case 0xCA: + case 0xCB: + /* in their infinite wisdom, GlobalPlatform made GET DATA a command that can be either APDU + * case 2 or case 4. As the specify Le must be 0x00, we can conclude that P3 == 0x00 must be + * Le, while P3 != 0x00 must be Lc and hence case 4 */ + if (p3 == 0x00) + return 2; + else + return 4; + break; } return 0; } @@ -215,9 +244,9 @@ static const uint8_t uicc_ins_tbl_80[256] = { static const uint8_t gp_ins_tbl_8ce[256] = { [0xE4] = 4, /* DELETE */ [0xE2] = 0x80, /* STORE DATA */ - [0xCA] = 4, /* GET DATA */ - [0xCB] = 4, /* GET DATA */ - [0xF2] = 4, /* GET STATUS */ + [0xCA] = 0x80, /* GET DATA */ + [0xCB] = 0x80, /* GET DATA */ + [0xF2] = 0x80, /* GET STATUS */ [0xE6] = 4, /* INSTALL */ [0xE8] = 4, /* LOAD */ [0xD8] = 4, /* PUT KEY */ @@ -246,6 +275,12 @@ static const struct osim_cla_ins_case uicc_ins_case[] = { .helper = uicc046_cla_ins_helper, .ins_tbl = uicc_ins_tbl_046, }, { + /* must be before uicc_ins_tbl_8ce below with same CLA+mask */ + .cla = 0x80, + .cla_mask = 0xF0, + .helper = gp_cla_ins_helper, + .ins_tbl = gp_ins_tbl_8ce, + }, { .cla = 0x80, .cla_mask = 0xF0, .ins_tbl = uicc_ins_tbl_8ce, @@ -258,11 +293,6 @@ static const struct osim_cla_ins_case uicc_ins_case[] = { .cla_mask = 0xF0, .ins_tbl = uicc_ins_tbl_8ce, }, { - .cla = 0x80, - .cla_mask = 0xF0, - .helper = gp_cla_ins_helper, - .ins_tbl = gp_ins_tbl_8ce, - }, { .cla = 0xC0, .cla_mask = 0xF0, .helper = gp_cla_ins_helper, @@ -308,6 +338,12 @@ static const struct osim_cla_ins_case uicc_sim_ins_case[] = { .helper = uicc046_cla_ins_helper, .ins_tbl = uicc_ins_tbl_046, }, { + /* must be before uicc_ins_tbl_8ce below with same CLA+mask */ + .cla = 0x80, + .cla_mask = 0xF0, + .helper = gp_cla_ins_helper, + .ins_tbl = gp_ins_tbl_8ce, + }, { .cla = 0x80, .cla_mask = 0xF0, .ins_tbl = uicc_ins_tbl_8ce, diff --git a/src/vty/Makefile.am b/src/vty/Makefile.am index c314a141..4a4f16ba 100644 --- a/src/vty/Makefile.am +++ b/src/vty/Makefile.am @@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=13:0:0 +LIBVERSION=13:1:0 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) AM_CFLAGS = -Wall $(TALLOC_CFLAGS) $(PTHREAD_CFLAGS) diff --git a/src/vty/fsm_vty.c b/src/vty/fsm_vty.c index da6038fa..19c35daa 100644 --- a/src/vty/fsm_vty.c +++ b/src/vty/fsm_vty.c @@ -158,6 +158,44 @@ DEFUN(show_fsm, show_fsm_cmd, return CMD_SUCCESS; } +DEFUN(show_fsm_state_graph, show_fsm_state_graph_cmd, + "show fsm-state-graph NAME", + SHOW_STR "Generate a state transition graph (using DOT language)\n" + "FSM name\n") +{ + const struct osmo_fsm *fsm; + + fsm = osmo_fsm_find_by_name(argv[0]); + if (!fsm) { + vty_out(vty, "Error: FSM with name '%s' doesn't exist!%s", + argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + vty_out(vty, "digraph \"%s\" {%s", fsm->name, VTY_NEWLINE); + + for (unsigned int i = 0; i < fsm->num_states; i++) { + const struct osmo_fsm_state *st = &fsm->states[i]; + + vty_out(vty, "\t\"%s\"; # out_state_mask=0x%08x%s", + st->name, st->out_state_mask, VTY_NEWLINE); + + for (unsigned int j = 0; j < sizeof(st->out_state_mask) * 8; j++) { + if (~st->out_state_mask & (1 << j)) + continue; + vty_out(vty, "\t\"%s\" -> \"%s\";%s", + st->name, osmo_fsm_state_name(fsm, j), + VTY_NEWLINE); + } + + vty_out(vty, "%s", VTY_NEWLINE); + } + + vty_out(vty, "}%s", VTY_NEWLINE); + + return CMD_SUCCESS; +} + DEFUN(show_fsm_insts, show_fsm_insts_cmd, "show fsm-instances all", SH_FSMI_STR @@ -214,6 +252,7 @@ void osmo_fsm_vty_add_cmds(void) install_lib_element_ve(&show_fsm_cmd); install_lib_element_ve(&show_fsms_cmd); + install_lib_element_ve(&show_fsm_state_graph_cmd); install_lib_element_ve(&show_fsm_inst_cmd); install_lib_element_ve(&show_fsm_insts_cmd); osmo_fsm_vty_cmds_installed = true; diff --git a/tests/Makefile.am b/tests/Makefile.am index 3b4325ee..48242c35 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,7 +26,9 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_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 \ + codec/codec_ecu_fr_test codec/codec_efr_sid_test \ + codec/codec_fr_sid_test codec/codec_hr_sid_test \ + timer/clk_override_test \ oap/oap_client_test gsm29205/gsm29205_test \ logging/logging_vty_test \ vty/vty_transcript_test \ @@ -59,6 +61,7 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \ osmo_io/osmo_io_test \ soft_uart/soft_uart_test \ rlp/rlp_test \ + jhash/jhash_test \ $(NULL) if ENABLE_MSGFILE @@ -264,6 +267,15 @@ codec_codec_test_LDADD = $(top_builddir)/src/codec/libosmocodec.la $(LDADD) codec_codec_ecu_fr_test_SOURCES = codec/codec_ecu_fr_test.c codec_codec_ecu_fr_test_LDADD = $(top_builddir)/src/codec/libosmocodec.la $(LDADD) +codec_codec_efr_sid_test_SOURCES = codec/codec_efr_sid_test.c +codec_codec_efr_sid_test_LDADD = $(top_builddir)/src/codec/libosmocodec.la $(LDADD) + +codec_codec_fr_sid_test_SOURCES = codec/codec_fr_sid_test.c +codec_codec_fr_sid_test_LDADD = $(top_builddir)/src/codec/libosmocodec.la $(LDADD) + +codec_codec_hr_sid_test_SOURCES = codec/codec_hr_sid_test.c +codec_codec_hr_sid_test_LDADD = $(top_builddir)/src/codec/libosmocodec.la $(LDADD) + loggingrb_loggingrb_test_SOURCES = loggingrb/loggingrb_test.c loggingrb_loggingrb_test_LDADD = $(LDADD) @@ -391,6 +403,7 @@ soft_uart_soft_uart_test_SOURCES = soft_uart/soft_uart_test.c rlp_rlp_test_SOURCES = rlp/rlp_test.c rlp_rlp_test_LDADD = $(top_builddir)/src/gsm/libosmogsm.la $(LDADD) +jhash_jhash_test_SOURCES = jhash/jhash_test.c # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac @@ -436,6 +449,9 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ loggingrb/logging_test.err strrb/strrb_test.ok \ codec/codec_test.ok \ codec/codec_ecu_fr_test.ok \ + codec/codec_efr_sid_test.ok codec/codec_efr_sid_test.in \ + codec/codec_fr_sid_test.ok codec/codec_fr_sid_test.in \ + codec/codec_hr_sid_test.ok codec/codec_hr_sid_test.in \ vty/vty_test.ok vty/vty_test.err \ vty/fail_not_de-indented.cfg \ vty/fail_tabs_and_spaces.cfg \ @@ -505,6 +521,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ soft_uart/soft_uart_test.ok \ rlp/rlp_test.ok \ socket/socket_sctp_test.ok socket/socket_sctp_test.err \ + jhash/jhash_test.ok \ $(NULL) if ENABLE_LIBSCTP @@ -595,6 +612,12 @@ endif >$(srcdir)/codec/codec_test.ok codec/codec_ecu_fr_test \ >$(srcdir)/codec/codec_ecu_fr_test.ok + codec/codec_efr_sid_test $(srcdir)/codec/codec_efr_sid_test.in \ + >$(srcdir)/codec/codec_efr_sid_test.ok + codec/codec_fr_sid_test $(srcdir)/codec/codec_fr_sid_test.in \ + >$(srcdir)/codec/codec_fr_sid_test.ok + codec/codec_hr_sid_test $(srcdir)/codec/codec_hr_sid_test.in \ + >$(srcdir)/codec/codec_hr_sid_test.ok if ENABLE_GB fr/fr_test \ >$(srcdir)/fr/fr_test.ok @@ -727,10 +750,11 @@ endif >$(srcdir)/osmo_io/osmo_io_test.ok \ 2>$(srcdir)/osmo_io/osmo_io_test.err soft_uart/soft_uart_test \ - >$(srcdir)/soft_uart/soft_uart.ok + >$(srcdir)/soft_uart/soft_uart_test.ok rlp/rlp_test \ - >$(srcdir)/rlp/rlp_test.ok \ - $(NULL) + >$(srcdir)/rlp/rlp_test.ok + jhash/jhash_test \ + >$(srcdir)/jhash/jhash_test.ok check-local: atconfig $(TESTSUITE) diff --git a/tests/codec/codec_efr_sid_test.c b/tests/codec/codec_efr_sid_test.c new file mode 100644 index 00000000..08cc94b5 --- /dev/null +++ b/tests/codec/codec_efr_sid_test.c @@ -0,0 +1,97 @@ +/* + * This program is a test for osmo_efr_sid_classify(). It reads a set of + * EFR codec frames in hex format (TS 101 318 RTP format represented in hex, + * each frame as its own hex line) and feeds each test frame to + * osmo_efr_sid_classify(). It then prints the output next to each input. + * + * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2024 - however, + * Mother Mychaela's contributions are NOT subject to copyright. + * No rights reserved, all rights relinquished. + * + * 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. + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include <osmocom/core/utils.h> +#include <osmocom/codec/codec.h> + +static void process_record(const char *hex_str) +{ + uint8_t frame_bytes[GSM_EFR_BYTES]; + enum osmo_gsm631_sid_class sidc; + + osmo_hexparse(hex_str, frame_bytes, GSM_EFR_BYTES); + sidc = osmo_efr_sid_classify(frame_bytes); + printf("%s ==> %d\n", hex_str, (int) sidc); +} + +static void process_line(char *linebuf, const char *infname, int lineno) +{ + char *cp = linebuf, *hex_str; + int ndig; + + while (isspace(*cp)) + cp++; + if (*cp == '\0' || *cp == '#') + return; + /* expect string of 62 hex digits */ + hex_str = cp; + for (ndig = 0; ndig < GSM_EFR_BYTES * 2; ndig++) { + if (!isxdigit(*cp)) + goto inv; + cp++; + } + if (*cp) { + if (!isspace(*cp)) + goto inv; + *cp++ = '\0'; + } + /* must be end of non-comment line */ + while (isspace(*cp)) + cp++; + if (*cp != '\0' && *cp != '#') + goto inv; + + process_record(hex_str); + return; + +inv: fprintf(stderr, "%s line %d: invalid syntax\n", infname, lineno); + exit(1); +} + +int main(int argc, char **argv) +{ + const char *infname; + FILE *inf; + char linebuf[128]; + int lineno; + + if (argc != 2) { + fprintf(stderr, "usage: %s input-file\n", argv[0]); + exit(1); + } + infname = argv[1]; + inf = fopen(infname, "r"); + if (!inf) { + perror(infname); + exit(1); + } + for (lineno = 1; fgets(linebuf, sizeof(linebuf), inf); lineno++) + process_line(linebuf, infname, lineno); + fclose(inf); + exit(0); +} diff --git a/tests/codec/codec_efr_sid_test.in b/tests/codec/codec_efr_sid_test.in new file mode 100644 index 00000000..af95b5b2 --- /dev/null +++ b/tests/codec/codec_efr_sid_test.in @@ -0,0 +1,183 @@ +# This file is input for the EFR SID classifier test program. +# It has been generated here: +# +# https://www.freecalypso.org/hg/vband-misc/file/tip/efr-sid +# +# Unit-test-desc file in the above directory contains +# a detailed description. + +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5802FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5804FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B58067FFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806BFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806DFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806EFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806F7FFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FBFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FDFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FEFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FF7FF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFBFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFDFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFEFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFF7F80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFBF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFDF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFEF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFF780001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFB80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFD80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFE80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF00001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E1BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E2BFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E33FFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E39FFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3AFFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3B7FFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BBFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BDFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BEFFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BF7FFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFBFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFDFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFEFFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFF7FE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFBFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFDFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFEFE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFF7E0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFBE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFDE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFEE0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFF60000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFA0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFC0000800FFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800BFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800DFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800EFFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800F7FFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FBFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FDFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FEFFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FF7FFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFBFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFDFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFEFFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFF7FF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFBFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFDFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFEFF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFF7F000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFBF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFDF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFEF000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFF7000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFB000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFD000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFE000040FFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF0000407FFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040BFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040DFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040EFFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040F7FCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FBFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FDFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FEFCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FF7CFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFBCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFDCFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFECFFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFF4FFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFF8FFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFC7FC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCBFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCDFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCEFC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCF7C00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFBC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFDC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFEC00010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFF400010 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFF800010 +C286DD29B5802FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFFC00010 +C286DD29B5804FFFFF80001E3BFFFFE0000800BFFFFF000040FFFCFFC00010 +C286DD29B58067FFFF80001E3BFFFFE0000800DFFFFF000040FFFCFFC00010 +C286DD29B5806BFFFF80001E3BFFFFE0000800EFFFFF000040FFFCFFC00010 +C286DD29B5806DFFFF80001E3BFFFFE0000800F7FFFF000040FFFCFFC00010 +C286DD29B5806EFFFF80001E3BFFFFE0000800FBFFFF000040FFFCFFC00010 +C286DD29B5806F7FFF80001E3BFFFFE0000800FDFFFF000040FFFCFFC00010 +C286DD29B5806FBFFF80001E3BFFFFE0000800FEFFFF000040FFFCFFC00010 +C286DD29B5806FDFFF80001E3BFFFFE0000800FF7FFF000040FFFCFFC00010 +C286DD29B5806FEFFF80001E3BFFFFE0000800FFBFFF000040FFFCFFC00010 +C286DD29B5806FF7FF80001E3BFFFFE0000800FFDFFF000040FFFCFFC00010 +C286DD29B5806FFBFF80001E3BFFFFE0000800FFEFFF000040FFFCFFC00010 +C286DD29B5806FFDFF80001E3BFFFFE0000800FFF7FF000040FFFCFFC00010 +C286DD29B5806FFEFF80001E3BFFFFE0000800FFFBFF000040FFFCFFC00010 +C286DD29B5806FFF7F80001E3BFFFFE0000800FFFDFF000040FFFCFFC00010 +C286DD29B5806FFFBF80001E3BFFFFE0000800FFFEFF000040FFFCFFC00010 +C286DD29B5806FFFDF80001E3BFFFFE0000800FFFF7F000040FFFCFFC00010 +C286DD29B5806FFFEF80001E3BFFFFE0000800FFFFBF000040FFFCFFC00010 +C286DD29B5806FFFF780001E3BFFFFE0000800FFFFDF000040FFFCFFC00010 +C286DD29B5806FFFFB80001E3BFFFFE0000800FFFFEF000040FFFCFFC00010 +C286DD29B5806FFFFD80001E3BFFFFE0000800FFFFF7000040FFFCFFC00010 +C286DD29B5806FFFFE80001E3BFFFFE0000800FFFFFB000040FFFCFFC00010 +C286DD29B5806FFFFF00001E3BFFFFE0000800FFFFFD000040FFFCFFC00010 +C286DD29B5806FFFFF80001E1BFFFFE0000800FFFFFE000040FFFCFFC00010 +C286DD29B5806FFFFF80001E2BFFFFE0000800FFFFFF0000407FFCFFC00010 +C286DD29B5806FFFFF80001E33FFFFE0000800FFFFFF000040BFFCFFC00010 +C286DD29B5806FFFFF80001E39FFFFE0000800FFFFFF000040DFFCFFC00010 +C286DD29B5806FFFFF80001E3AFFFFE0000800FFFFFF000040EFFCFFC00010 +C286DD29B5806FFFFF80001E3B7FFFE0000800FFFFFF000040F7FCFFC00010 +C286DD29B5806FFFFF80001E3BBFFFE0000800FFFFFF000040FBFCFFC00010 +C286DD29B5806FFFFF80001E3BDFFFE0000800FFFFFF000040FDFCFFC00010 +C286DD29B5806FFFFF80001E3BEFFFE0000800FFFFFF000040FEFCFFC00010 +C286DD29B5806FFFFF80001E3BF7FFE0000800FFFFFF000040FF7CFFC00010 +C286DD29B5806FFFFF80001E3BFBFFE0000800FFFFFF000040FFBCFFC00010 +C286DD29B5806FFFFF80001E3BFDFFE0000800FFFFFF000040FFDCFFC00010 +C286DD29B5806FFFFF80001E3BFEFFE0000800FFFFFF000040FFECFFC00010 +C286DD29B5806FFFFF80001E3BFF7FE0000800FFFFFF000040FFF4FFC00010 +C286DD29B5806FFFFF80001E3BFFBFE0000800FFFFFF000040FFF8FFC00010 +C286DD29B5806FFFFF80001E3BFFDFE0000800FFFFFF000040FFFC7FC00010 +C286DD29B5806FFFFF80001E3BFFEFE0000800FFFFFF000040FFFCBFC00010 +C286DD29B5806FFFFF80001E3BFFF7E0000800FFFFFF000040FFFCDFC00010 +C286DD29B5806FFFFF80001E3BFFFBE0000800FFFFFF000040FFFCEFC00010 +C286DD29B5806FFFFF80001E3BFFFDE0000800FFFFFF000040FFFCF7C00010 +C286DD29B5806FFFFF80001E3BFFFEE0000800FFFFFF000040FFFCFBC00010 +C286DD29B5806FFFFF80001E3BFFFF60000800FFFFFF000040FFFCFDC00010 +C286DD29B5806FFFFF80001E3BFFFFA0000800FFFFFF000040FFFCFEC00010 +C286DD29B5806FFFFF80001E3BFFFFC0000800FFFFFF000040FFFCFF400010 +C286DD29B5806FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFF800010 +C286DD29B5802F7DF780001E2BDF7DE0000800BEFBEF000040BEF8FFC00010 +C286DD29B5804FBEFB80001E33EFBEE0000800DF7DF7000040DF7C7FC00010 +C286DD29B58067DF7D80001E39F7DF60000800EFBEFB000040EFBCBFC00010 +C286DD29B5806BEFBE80001E3AFBEFA0000800F7DF7D000040F7DCDFC00010 +C286DD29B5806DF7DF00001E3B7DF7C0000800FBEFBE000040FBECEFC00010 +C286DD29B5806EFBEF80001E1BBEFBE00008007DF7DF0000407DF4F7C00010 +C286DD29B5806F7DF780001E2BDF7DE0000800BEFBEF000040BEF8FBC00010 +C286DD29B5806FBEFB80001E33EFBEE0000800DF7DF7000040DF7C7DC00010 +C286DD29B5806FDF7D80001E39F7DF60000800EFBEFB000040EFBCBEC00010 +C286DD29B5806FEFBE80001E3AFBEFA0000800F7DF7D000040F7DCDF400010 +C286DD29B5806FF7DF00001E3B7DF7C0000800FBEFBE000040FBECEF800010 +C286DD29B5802EF7BD80001E33DEF7A0000800EF7BDE000040F7FCFFC00010 +C286DD29B5804F7BDE80001E39EF7BC0000800F7BDEF0000407BFCFFC00010 +C286DD29B58067BDEF00001E3AF7BDE00008007BDEF7000040BDFCFFC00010 +C286DD29B5806BDEF780001E1B7BDEE0000800BDEF7B000040DEFCFFC00010 +C286DD29B5806DEF7B80001E2BBDEF60000800DEF7BD000040EF7CFFC00010 +C286DD29B5806EF7BD80001E33DEF7A0000800EF7BDE000040F7BCFFC00010 +C286DD29B5806F7BDE80001E39EF7BC0000800F7BDEF0000407BDCFFC00010 +C286DD29B5806FBDEF00001E3AF7BDE00008007BDEF7000040BDECFFC00010 +C286DD29B5806FDEF780001E1B7BDEE0000800BDEF7B000040DEF4FFC00010 +C286DD29B5806FEF7B80001E2BBDEF60000800DEF7BD000040EF78FFC00010 +C286DD29B5806FF7BD80001E33DEF7A0000800EF7BDE000040F7BC7FC00010 +C286DD29B5806FFBDE80001E39EF7BC0000800F7BDEF0000407BDCBFC00010 +C286DD29B5806FFDEF00001E3AF7BDE00008007BDEF7000040BDECDFC00010 +C286DD29B5806FFEF780001E1B7BDEE0000800BDEF7B000040DEF4EFC00010 +C286DD29B5806FFF7B80001E2BBDEF60000800DEF7BD000040EF78F7C00010 +C286DD29B5806FFFBD80001E33DEF7A0000800EF7BDE000040F7BC7BC00010 +C286DD29B5806FFFDE80001E39EF7BC0000800F7BDEF0000407BDCBDC00010 +C286DD29B5806FFFEF00001E3AF7BDE00008007BDEF7000040BDECDEC00010 +C286DD29B5806FFFF780001E1B7BDEE0000800BDEF7B000040DEF4EF400010 +C286DD29B5806FFFFB80001E2BBDEF60000800DEF7BD000040EF78F7800010 diff --git a/tests/codec/codec_efr_sid_test.ok b/tests/codec/codec_efr_sid_test.ok new file mode 100644 index 00000000..6b94cf4e --- /dev/null +++ b/tests/codec/codec_efr_sid_test.ok @@ -0,0 +1,175 @@ +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5802FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5804FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B58067FFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806BFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806DFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806EFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806F7FFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FBFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FDFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FEFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FF7FF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFBFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFDFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFEFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFF7F80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFBF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFDF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFEF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFF780001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFB80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFD80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFE80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF00001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E1BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E2BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E33FFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E39FFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3AFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3B7FFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BBFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BDFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BEFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BF7FFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFBFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFDFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFEFFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFF7FE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFBFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFDFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFEFE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFF7E0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFBE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFDE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFEE0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFF60000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFA0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFC0000800FFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800BFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800DFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800EFFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800F7FFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FBFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FDFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FEFFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FF7FFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFBFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFDFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFEFFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFF7FF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFBFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFDFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFEFF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFF7F000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFBF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFDF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFEF000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFF7000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFB000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFD000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFE000040FFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF0000407FFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040BFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040DFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040EFFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040F7FCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FBFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FDFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FEFCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FF7CFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFBCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFDCFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFECFFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFF4FFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFF8FFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFC7FC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCBFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCDFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCEFC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCF7C00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFBC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFDC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFEC00010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFF400010 ==> 2 +C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFF800010 ==> 2 +C286DD29B5802FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFFC00010 ==> 1 +C286DD29B5804FFFFF80001E3BFFFFE0000800BFFFFF000040FFFCFFC00010 ==> 1 +C286DD29B58067FFFF80001E3BFFFFE0000800DFFFFF000040FFFCFFC00010 ==> 1 +C286DD29B5806BFFFF80001E3BFFFFE0000800EFFFFF000040FFFCFFC00010 ==> 1 +C286DD29B5806DFFFF80001E3BFFFFE0000800F7FFFF000040FFFCFFC00010 ==> 1 +C286DD29B5806EFFFF80001E3BFFFFE0000800FBFFFF000040FFFCFFC00010 ==> 1 +C286DD29B5806F7FFF80001E3BFFFFE0000800FDFFFF000040FFFCFFC00010 ==> 1 +C286DD29B5806FBFFF80001E3BFFFFE0000800FEFFFF000040FFFCFFC00010 ==> 1 +C286DD29B5806FDFFF80001E3BFFFFE0000800FF7FFF000040FFFCFFC00010 ==> 1 +C286DD29B5806FEFFF80001E3BFFFFE0000800FFBFFF000040FFFCFFC00010 ==> 1 +C286DD29B5806FF7FF80001E3BFFFFE0000800FFDFFF000040FFFCFFC00010 ==> 1 +C286DD29B5806FFBFF80001E3BFFFFE0000800FFEFFF000040FFFCFFC00010 ==> 1 +C286DD29B5806FFDFF80001E3BFFFFE0000800FFF7FF000040FFFCFFC00010 ==> 1 +C286DD29B5806FFEFF80001E3BFFFFE0000800FFFBFF000040FFFCFFC00010 ==> 1 +C286DD29B5806FFF7F80001E3BFFFFE0000800FFFDFF000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFBF80001E3BFFFFE0000800FFFEFF000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFDF80001E3BFFFFE0000800FFFF7F000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFEF80001E3BFFFFE0000800FFFFBF000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFF780001E3BFFFFE0000800FFFFDF000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFFB80001E3BFFFFE0000800FFFFEF000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFFD80001E3BFFFFE0000800FFFFF7000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFFE80001E3BFFFFE0000800FFFFFB000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFFF00001E3BFFFFE0000800FFFFFD000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E1BFFFFE0000800FFFFFE000040FFFCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E2BFFFFE0000800FFFFFF0000407FFCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E33FFFFE0000800FFFFFF000040BFFCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E39FFFFE0000800FFFFFF000040DFFCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3AFFFFE0000800FFFFFF000040EFFCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3B7FFFE0000800FFFFFF000040F7FCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BBFFFE0000800FFFFFF000040FBFCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BDFFFE0000800FFFFFF000040FDFCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BEFFFE0000800FFFFFF000040FEFCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BF7FFE0000800FFFFFF000040FF7CFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFBFFE0000800FFFFFF000040FFBCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFDFFE0000800FFFFFF000040FFDCFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFEFFE0000800FFFFFF000040FFECFFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFF7FE0000800FFFFFF000040FFF4FFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFBFE0000800FFFFFF000040FFF8FFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFDFE0000800FFFFFF000040FFFC7FC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFEFE0000800FFFFFF000040FFFCBFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFF7E0000800FFFFFF000040FFFCDFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFFBE0000800FFFFFF000040FFFCEFC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFFDE0000800FFFFFF000040FFFCF7C00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFFEE0000800FFFFFF000040FFFCFBC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFFF60000800FFFFFF000040FFFCFDC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFFFA0000800FFFFFF000040FFFCFEC00010 ==> 1 +C286DD29B5806FFFFF80001E3BFFFFC0000800FFFFFF000040FFFCFF400010 ==> 1 +C286DD29B5806FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFF800010 ==> 1 +C286DD29B5802F7DF780001E2BDF7DE0000800BEFBEF000040BEF8FFC00010 ==> 1 +C286DD29B5804FBEFB80001E33EFBEE0000800DF7DF7000040DF7C7FC00010 ==> 1 +C286DD29B58067DF7D80001E39F7DF60000800EFBEFB000040EFBCBFC00010 ==> 1 +C286DD29B5806BEFBE80001E3AFBEFA0000800F7DF7D000040F7DCDFC00010 ==> 1 +C286DD29B5806DF7DF00001E3B7DF7C0000800FBEFBE000040FBECEFC00010 ==> 1 +C286DD29B5806EFBEF80001E1BBEFBE00008007DF7DF0000407DF4F7C00010 ==> 1 +C286DD29B5806F7DF780001E2BDF7DE0000800BEFBEF000040BEF8FBC00010 ==> 1 +C286DD29B5806FBEFB80001E33EFBEE0000800DF7DF7000040DF7C7DC00010 ==> 1 +C286DD29B5806FDF7D80001E39F7DF60000800EFBEFB000040EFBCBEC00010 ==> 1 +C286DD29B5806FEFBE80001E3AFBEFA0000800F7DF7D000040F7DCDF400010 ==> 1 +C286DD29B5806FF7DF00001E3B7DF7C0000800FBEFBE000040FBECEF800010 ==> 1 +C286DD29B5802EF7BD80001E33DEF7A0000800EF7BDE000040F7FCFFC00010 ==> 0 +C286DD29B5804F7BDE80001E39EF7BC0000800F7BDEF0000407BFCFFC00010 ==> 0 +C286DD29B58067BDEF00001E3AF7BDE00008007BDEF7000040BDFCFFC00010 ==> 0 +C286DD29B5806BDEF780001E1B7BDEE0000800BDEF7B000040DEFCFFC00010 ==> 0 +C286DD29B5806DEF7B80001E2BBDEF60000800DEF7BD000040EF7CFFC00010 ==> 0 +C286DD29B5806EF7BD80001E33DEF7A0000800EF7BDE000040F7BCFFC00010 ==> 0 +C286DD29B5806F7BDE80001E39EF7BC0000800F7BDEF0000407BDCFFC00010 ==> 0 +C286DD29B5806FBDEF00001E3AF7BDE00008007BDEF7000040BDECFFC00010 ==> 0 +C286DD29B5806FDEF780001E1B7BDEE0000800BDEF7B000040DEF4FFC00010 ==> 0 +C286DD29B5806FEF7B80001E2BBDEF60000800DEF7BD000040EF78FFC00010 ==> 0 +C286DD29B5806FF7BD80001E33DEF7A0000800EF7BDE000040F7BC7FC00010 ==> 0 +C286DD29B5806FFBDE80001E39EF7BC0000800F7BDEF0000407BDCBFC00010 ==> 0 +C286DD29B5806FFDEF00001E3AF7BDE00008007BDEF7000040BDECDFC00010 ==> 0 +C286DD29B5806FFEF780001E1B7BDEE0000800BDEF7B000040DEF4EFC00010 ==> 0 +C286DD29B5806FFF7B80001E2BBDEF60000800DEF7BD000040EF78F7C00010 ==> 0 +C286DD29B5806FFFBD80001E33DEF7A0000800EF7BDE000040F7BC7BC00010 ==> 0 +C286DD29B5806FFFDE80001E39EF7BC0000800F7BDEF0000407BDCBDC00010 ==> 0 +C286DD29B5806FFFEF00001E3AF7BDE00008007BDEF7000040BDECDEC00010 ==> 0 +C286DD29B5806FFFF780001E1B7BDEE0000800BDEF7B000040DEF4EF400010 ==> 0 +C286DD29B5806FFFFB80001E2BBDEF60000800DEF7BD000040EF78F7800010 ==> 0 diff --git a/tests/codec/codec_fr_sid_test.c b/tests/codec/codec_fr_sid_test.c new file mode 100644 index 00000000..25c1b3f3 --- /dev/null +++ b/tests/codec/codec_fr_sid_test.c @@ -0,0 +1,97 @@ +/* + * This program is a test for osmo_fr_sid_classify(). It reads a set of + * FRv1 codec frames in hex format (TS 101 318 RTP format represented in hex, + * each frame as its own hex line) and feeds each test frame to + * osmo_fr_sid_classify(). It then prints the output next to each input. + * + * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2024 - however, + * Mother Mychaela's contributions are NOT subject to copyright. + * No rights reserved, all rights relinquished. + * + * 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. + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include <osmocom/core/utils.h> +#include <osmocom/codec/codec.h> + +static void process_record(const char *hex_str) +{ + uint8_t frame_bytes[GSM_FR_BYTES]; + enum osmo_gsm631_sid_class sidc; + + osmo_hexparse(hex_str, frame_bytes, GSM_FR_BYTES); + sidc = osmo_fr_sid_classify(frame_bytes); + printf("%s ==> %d\n", hex_str, (int) sidc); +} + +static void process_line(char *linebuf, const char *infname, int lineno) +{ + char *cp = linebuf, *hex_str; + int ndig; + + while (isspace(*cp)) + cp++; + if (*cp == '\0' || *cp == '#') + return; + /* expect string of 66 hex digits */ + hex_str = cp; + for (ndig = 0; ndig < GSM_FR_BYTES * 2; ndig++) { + if (!isxdigit(*cp)) + goto inv; + cp++; + } + if (*cp) { + if (!isspace(*cp)) + goto inv; + *cp++ = '\0'; + } + /* must be end of non-comment line */ + while (isspace(*cp)) + cp++; + if (*cp != '\0' && *cp != '#') + goto inv; + + process_record(hex_str); + return; + +inv: fprintf(stderr, "%s line %d: invalid syntax\n", infname, lineno); + exit(1); +} + +int main(int argc, char **argv) +{ + const char *infname; + FILE *inf; + char linebuf[128]; + int lineno; + + if (argc != 2) { + fprintf(stderr, "usage: %s input-file\n", argv[0]); + exit(1); + } + infname = argv[1]; + inf = fopen(infname, "r"); + if (!inf) { + perror(infname); + exit(1); + } + for (lineno = 1; fgets(linebuf, sizeof(linebuf), inf); lineno++) + process_line(linebuf, infname, lineno); + fclose(inf); + exit(0); +} diff --git a/tests/codec/codec_fr_sid_test.in b/tests/codec/codec_fr_sid_test.in new file mode 100644 index 00000000..d5930e25 --- /dev/null +++ b/tests/codec/codec_fr_sid_test.in @@ -0,0 +1,184 @@ +# This file is input for the FRv1 SID classifier test program. +# It has been generated here: +# +# https://www.freecalypso.org/hg/vband-misc/file/tip/fr-sid +# +# It is based on the same principle as the EFR version: +# +# https://www.freecalypso.org/hg/vband-misc/file/tip/efr-sid/Unit-test-desc + +DAE6DB659B00010000000000000100000000000001000000000000010000000000 +DAE6DB659B00014000000000000100000000000001000000000000010000000000 +DAE6DB659B00012000000000000100000000000001000000000000010000000000 +DAE6DB659B00010800000000000100000000000001000000000000010000000000 +DAE6DB659B00010400000000000100000000000001000000000000010000000000 +DAE6DB659B00010100000000000100000000000001000000000000010000000000 +DAE6DB659B00010080000000000100000000000001000000000000010000000000 +DAE6DB659B00010020000000000100000000000001000000000000010000000000 +DAE6DB659B00010010000000000100000000000001000000000000010000000000 +DAE6DB659B00010004000000000100000000000001000000000000010000000000 +DAE6DB659B00010002000000000100000000000001000000000000010000000000 +DAE6DB659B00010000800000000100000000000001000000000000010000000000 +DAE6DB659B00010000400000000100000000000001000000000000010000000000 +DAE6DB659B00010000100000000100000000000001000000000000010000000000 +DAE6DB659B00010000080000000100000000000001000000000000010000000000 +DAE6DB659B00010000020000000100000000000001000000000000010000000000 +DAE6DB659B00010000010000000100000000000001000000000000010000000000 +DAE6DB659B00010000004000000100000000000001000000000000010000000000 +DAE6DB659B00010000002000000100000000000001000000000000010000000000 +DAE6DB659B00010000000800000100000000000001000000000000010000000000 +DAE6DB659B00010000000400000100000000000001000000000000010000000000 +DAE6DB659B00010000000100000100000000000001000000000000010000000000 +DAE6DB659B00010000000080000100000000000001000000000000010000000000 +DAE6DB659B00010000000020000100000000000001000000000000010000000000 +DAE6DB659B00010000000010000100000000000001000000000000010000000000 +DAE6DB659B00010000000004000100000000000001000000000000010000000000 +DAE6DB659B00010000000002000100000000000001000000000000010000000000 +DAE6DB659B00010000000000000140000000000001000000000000010000000000 +DAE6DB659B00010000000000000120000000000001000000000000010000000000 +DAE6DB659B00010000000000000108000000000001000000000000010000000000 +DAE6DB659B00010000000000000104000000000001000000000000010000000000 +DAE6DB659B00010000000000000101000000000001000000000000010000000000 +DAE6DB659B00010000000000000100800000000001000000000000010000000000 +DAE6DB659B00010000000000000100200000000001000000000000010000000000 +DAE6DB659B00010000000000000100100000000001000000000000010000000000 +DAE6DB659B00010000000000000100040000000001000000000000010000000000 +DAE6DB659B00010000000000000100020000000001000000000000010000000000 +DAE6DB659B00010000000000000100008000000001000000000000010000000000 +DAE6DB659B00010000000000000100004000000001000000000000010000000000 +DAE6DB659B00010000000000000100001000000001000000000000010000000000 +DAE6DB659B00010000000000000100000800000001000000000000010000000000 +DAE6DB659B00010000000000000100000200000001000000000000010000000000 +DAE6DB659B00010000000000000100000100000001000000000000010000000000 +DAE6DB659B00010000000000000100000040000001000000000000010000000000 +DAE6DB659B00010000000000000100000020000001000000000000010000000000 +DAE6DB659B00010000000000000100000008000001000000000000010000000000 +DAE6DB659B00010000000000000100000004000001000000000000010000000000 +DAE6DB659B00010000000000000100000001000001000000000000010000000000 +DAE6DB659B00010000000000000100000000800001000000000000010000000000 +DAE6DB659B00010000000000000100000000200001000000000000010000000000 +DAE6DB659B00010000000000000100000000100001000000000000010000000000 +DAE6DB659B00010000000000000100000000040001000000000000010000000000 +DAE6DB659B00010000000000000100000000020001000000000000010000000000 +DAE6DB659B00010000000000000100000000000001400000000000010000000000 +DAE6DB659B00010000000000000100000000000001200000000000010000000000 +DAE6DB659B00010000000000000100000000000001080000000000010000000000 +DAE6DB659B00010000000000000100000000000001040000000000010000000000 +DAE6DB659B00010000000000000100000000000001010000000000010000000000 +DAE6DB659B00010000000000000100000000000001008000000000010000000000 +DAE6DB659B00010000000000000100000000000001002000000000010000000000 +DAE6DB659B00010000000000000100000000000001001000000000010000000000 +DAE6DB659B00010000000000000100000000000001000400000000010000000000 +DAE6DB659B00010000000000000100000000000001000200000000010000000000 +DAE6DB659B00010000000000000100000000000001000080000000010000000000 +DAE6DB659B00010000000000000100000000000001000040000000010000000000 +DAE6DB659B00010000000000000100000000000001000010000000010000000000 +DAE6DB659B00010000000000000100000000000001000008000000010000000000 +DAE6DB659B00010000000000000100000000000001000002000000010000000000 +DAE6DB659B00010000000000000100000000000001000001000000010000000000 +DAE6DB659B00010000000000000100000000000001000000400000010000000000 +DAE6DB659B00010000000000000100000000000001000000200000010000000000 +DAE6DB659B00010000000000000100000000000001000000080000010000000000 +DAE6DB659B00010000000000000100000000000001000000040000010000000000 +DAE6DB659B00010000000000000100000000000001000000010000010000000000 +DAE6DB659B00010000000000000100000000000001000000008000010000000000 +DAE6DB659B00010000000000000100000000000001000000002000010000000000 +DAE6DB659B00010000000000000100000000000001000000001000010000000000 +DAE6DB659B00010000000000000100000000000001000000000400010000000000 +DAE6DB659B00010000000000000100000000000001000000000200010000000000 +DAE6DB659B00010000000000000100000000000001000000000000014000000000 +DAE6DB659B00010000000000000100000000000001000000000000012000000000 +DAE6DB659B00010000000000000100000000000001000000000000010800000000 +DAE6DB659B00010000000000000100000000000001000000000000010400000000 +DAE6DB659B00010000000000000100000000000001000000000000010100000000 +DAE6DB659B00010000000000000100000000000001000000000000010080000000 +DAE6DB659B00010000000000000100000000000001000000000000010020000000 +DAE6DB659B00010000000000000100000000000001000000000000010010000000 +DAE6DB659B00010000000000000100000000000001000000000000010004000000 +DAE6DB659B00010000000000000100000000000001000000000000010000800000 +DAE6DB659B00010000000000000100000000000001000000000000010000100000 +DAE6DB659B00010000000000000100000000000001000000000000010000020000 +DAE6DB659B00010000000000000100000000000001000000000000010000004000 +DAE6DB659B00010000000000000100000000000001000000000000010000000800 +DAE6DB659B00010000000000000100000000000001000000000000010000000100 +DAE6DB659B00010000000000000100000000000001000000000000010000000020 +DAE6DB659B00010000000000000100000000000001000000000000010000000004 +DAE6DB659B00014000000000000100000000800001000000000000010000000000 +DAE6DB659B00012000000000000100000000200001000000000000010000000000 +DAE6DB659B00010800000000000100000000100001000000000000010000000000 +DAE6DB659B00010400000000000100000000040001000000000000010000000000 +DAE6DB659B00010100000000000100000000020001000000000000010000000000 +DAE6DB659B00010080000000000100000000000001400000000000010000000000 +DAE6DB659B00010020000000000100000000000001200000000000010000000000 +DAE6DB659B00010010000000000100000000000001080000000000010000000000 +DAE6DB659B00010004000000000100000000000001040000000000010000000000 +DAE6DB659B00010002000000000100000000000001010000000000010000000000 +DAE6DB659B00010000800000000100000000000001008000000000010000000000 +DAE6DB659B00010000400000000100000000000001002000000000010000000000 +DAE6DB659B00010000100000000100000000000001001000000000010000000000 +DAE6DB659B00010000080000000100000000000001000400000000010000000000 +DAE6DB659B00010000020000000100000000000001000200000000010000000000 +DAE6DB659B00010000010000000100000000000001000080000000010000000000 +DAE6DB659B00010000004000000100000000000001000040000000010000000000 +DAE6DB659B00010000002000000100000000000001000010000000010000000000 +DAE6DB659B00010000000800000100000000000001000008000000010000000000 +DAE6DB659B00010000000400000100000000000001000002000000010000000000 +DAE6DB659B00010000000100000100000000000001000001000000010000000000 +DAE6DB659B00010000000080000100000000000001000000400000010000000000 +DAE6DB659B00010000000020000100000000000001000000200000010000000000 +DAE6DB659B00010000000010000100000000000001000000080000010000000000 +DAE6DB659B00010000000004000100000000000001000000040000010000000000 +DAE6DB659B00010000000002000100000000000001000000010000010000000000 +DAE6DB659B00010000000000000140000000000001000000008000010000000000 +DAE6DB659B00010000000000000120000000000001000000002000010000000000 +DAE6DB659B00010000000000000108000000000001000000001000010000000000 +DAE6DB659B00010000000000000104000000000001000000000400010000000000 +DAE6DB659B00010000000000000101000000000001000000000200010000000000 +DAE6DB659B00010000000000000100800000000001000000000000014000000000 +DAE6DB659B00010000000000000100200000000001000000000000012000000000 +DAE6DB659B00010000000000000100100000000001000000000000010800000000 +DAE6DB659B00010000000000000100040000000001000000000000010400000000 +DAE6DB659B00010000000000000100020000000001000000000000010100000000 +DAE6DB659B00010000000000000100008000000001000000000000010080000000 +DAE6DB659B00010000000000000100004000000001000000000000010020000000 +DAE6DB659B00010000000000000100001000000001000000000000010010000000 +DAE6DB659B00010000000000000100000800000001000000000000010004000000 +DAE6DB659B00010000000000000100000200000001000000000000010000800000 +DAE6DB659B00010000000000000100000100000001000000000000010000100000 +DAE6DB659B00010000000000000100000040000001000000000000010000020000 +DAE6DB659B00010000000000000100000020000001000000000000010000004000 +DAE6DB659B00010000000000000100000008000001000000000000010000000800 +DAE6DB659B00010000000000000100000004000001000000000000010000000100 +DAE6DB659B00010000000000000100000001000001000000000000010000000020 +DAE6DB659B00010000000000000100000000800001000000000000010000000004 +DAE6DB659B00014020100804000101008040200001080402010000014020000000 +DAE6DB659B00012010080402000100804020100001040201008000012010000000 +DAE6DB659B00010804020100000140201008040001010080402000010804000000 +DAE6DB659B00010402010080000120100804020001008040201000010400800000 +DAE6DB659B00010100804020000108040201000001402010080400010100100000 +DAE6DB659B00010080402010000104020100800001201008040200010080020000 +DAE6DB659B00010020100804000101008040200001080402010000014020004000 +DAE6DB659B00010010080402000100804020100001040201008000012010000800 +DAE6DB659B00010004020100000140201008040001010080402000010804000100 +DAE6DB659B00010002010080000120100804020001008040201000010400800020 +DAE6DB659B00010000804020000108040201000001402010080400010100100004 +DAE6DB659B00014080810102000101020204040001040408081000010000000000 +DAE6DB659B00012020404080000140808101020001010202040400010000000000 +DAE6DB659B00010810102020000120204040800001408081010200010000000000 +DAE6DB659B00010404080810000108101020200001202040408000014000000000 +DAE6DB659B00010102020404000104040808100001081010202000012000000000 +DAE6DB659B00010080810102000101020204040001040408081000010800000000 +DAE6DB659B00010020404080000140808101020001010202040400010400000000 +DAE6DB659B00010010102020000120204040800001408081010200010100000000 +DAE6DB659B00010004080810000108101020200001202040408000014080000000 +DAE6DB659B00010002020404000104040808100001081010202000012020000000 +DAE6DB659B00010000810102000101020204040001040408081000010810000000 +DAE6DB659B00010000404080000140808101020001010202040400010404000000 +DAE6DB659B00010000102020000120204040800001408081010200010100800000 +DAE6DB659B00010000080810000108101020200001202040408000014080100000 +DAE6DB659B00010000020404000104040808100001081010202000012020020000 +DAE6DB659B00010000010102000101020204040001040408081000010810004000 +DAE6DB659B00010000004080000140808101020001010202040400010404000800 +DAE6DB659B00010000002020000120204040800001408081010200010100800100 +DAE6DB659B00010000000810000108101020200001202040408000014080100020 +DAE6DB659B00010000000404000104040808100001081010202000012020020004 diff --git a/tests/codec/codec_fr_sid_test.ok b/tests/codec/codec_fr_sid_test.ok new file mode 100644 index 00000000..8dcaa345 --- /dev/null +++ b/tests/codec/codec_fr_sid_test.ok @@ -0,0 +1,175 @@ +DAE6DB659B00010000000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00014000000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00012000000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010800000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010400000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010100000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010080000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010020000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010010000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010004000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010002000000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000800000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000400000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000100000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000080000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000020000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000010000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000004000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000002000000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000800000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000400000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000100000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000080000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000020000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000010000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000004000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000002000100000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000140000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000120000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000108000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000104000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000101000000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100800000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100200000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100100000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100040000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100020000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100008000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100004000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100001000000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000800000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000200000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000100000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000040000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000020000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000008000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000004000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000001000001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000800001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000200001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000100001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000040001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000020001000000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001400000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001200000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001080000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001040000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001010000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001008000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001002000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001001000000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000400000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000200000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000080000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000040000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000010000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000008000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000002000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000001000000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000400000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000200000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000080000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000040000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000010000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000008000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000002000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000001000010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000400010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000200010000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000014000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000012000000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010800000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010400000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010100000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010080000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010020000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010010000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010004000000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010000800000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010000100000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010000020000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010000004000 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010000000800 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010000000100 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010000000020 ==> 2 +DAE6DB659B00010000000000000100000000000001000000000000010000000004 ==> 2 +DAE6DB659B00014000000000000100000000800001000000000000010000000000 ==> 1 +DAE6DB659B00012000000000000100000000200001000000000000010000000000 ==> 1 +DAE6DB659B00010800000000000100000000100001000000000000010000000000 ==> 1 +DAE6DB659B00010400000000000100000000040001000000000000010000000000 ==> 1 +DAE6DB659B00010100000000000100000000020001000000000000010000000000 ==> 1 +DAE6DB659B00010080000000000100000000000001400000000000010000000000 ==> 1 +DAE6DB659B00010020000000000100000000000001200000000000010000000000 ==> 1 +DAE6DB659B00010010000000000100000000000001080000000000010000000000 ==> 1 +DAE6DB659B00010004000000000100000000000001040000000000010000000000 ==> 1 +DAE6DB659B00010002000000000100000000000001010000000000010000000000 ==> 1 +DAE6DB659B00010000800000000100000000000001008000000000010000000000 ==> 1 +DAE6DB659B00010000400000000100000000000001002000000000010000000000 ==> 1 +DAE6DB659B00010000100000000100000000000001001000000000010000000000 ==> 1 +DAE6DB659B00010000080000000100000000000001000400000000010000000000 ==> 1 +DAE6DB659B00010000020000000100000000000001000200000000010000000000 ==> 1 +DAE6DB659B00010000010000000100000000000001000080000000010000000000 ==> 1 +DAE6DB659B00010000004000000100000000000001000040000000010000000000 ==> 1 +DAE6DB659B00010000002000000100000000000001000010000000010000000000 ==> 1 +DAE6DB659B00010000000800000100000000000001000008000000010000000000 ==> 1 +DAE6DB659B00010000000400000100000000000001000002000000010000000000 ==> 1 +DAE6DB659B00010000000100000100000000000001000001000000010000000000 ==> 1 +DAE6DB659B00010000000080000100000000000001000000400000010000000000 ==> 1 +DAE6DB659B00010000000020000100000000000001000000200000010000000000 ==> 1 +DAE6DB659B00010000000010000100000000000001000000080000010000000000 ==> 1 +DAE6DB659B00010000000004000100000000000001000000040000010000000000 ==> 1 +DAE6DB659B00010000000002000100000000000001000000010000010000000000 ==> 1 +DAE6DB659B00010000000000000140000000000001000000008000010000000000 ==> 1 +DAE6DB659B00010000000000000120000000000001000000002000010000000000 ==> 1 +DAE6DB659B00010000000000000108000000000001000000001000010000000000 ==> 1 +DAE6DB659B00010000000000000104000000000001000000000400010000000000 ==> 1 +DAE6DB659B00010000000000000101000000000001000000000200010000000000 ==> 1 +DAE6DB659B00010000000000000100800000000001000000000000014000000000 ==> 1 +DAE6DB659B00010000000000000100200000000001000000000000012000000000 ==> 1 +DAE6DB659B00010000000000000100100000000001000000000000010800000000 ==> 1 +DAE6DB659B00010000000000000100040000000001000000000000010400000000 ==> 1 +DAE6DB659B00010000000000000100020000000001000000000000010100000000 ==> 1 +DAE6DB659B00010000000000000100008000000001000000000000010080000000 ==> 1 +DAE6DB659B00010000000000000100004000000001000000000000010020000000 ==> 1 +DAE6DB659B00010000000000000100001000000001000000000000010010000000 ==> 1 +DAE6DB659B00010000000000000100000800000001000000000000010004000000 ==> 1 +DAE6DB659B00010000000000000100000200000001000000000000010000800000 ==> 1 +DAE6DB659B00010000000000000100000100000001000000000000010000100000 ==> 1 +DAE6DB659B00010000000000000100000040000001000000000000010000020000 ==> 1 +DAE6DB659B00010000000000000100000020000001000000000000010000004000 ==> 1 +DAE6DB659B00010000000000000100000008000001000000000000010000000800 ==> 1 +DAE6DB659B00010000000000000100000004000001000000000000010000000100 ==> 1 +DAE6DB659B00010000000000000100000001000001000000000000010000000020 ==> 1 +DAE6DB659B00010000000000000100000000800001000000000000010000000004 ==> 1 +DAE6DB659B00014020100804000101008040200001080402010000014020000000 ==> 1 +DAE6DB659B00012010080402000100804020100001040201008000012010000000 ==> 1 +DAE6DB659B00010804020100000140201008040001010080402000010804000000 ==> 1 +DAE6DB659B00010402010080000120100804020001008040201000010400800000 ==> 1 +DAE6DB659B00010100804020000108040201000001402010080400010100100000 ==> 1 +DAE6DB659B00010080402010000104020100800001201008040200010080020000 ==> 1 +DAE6DB659B00010020100804000101008040200001080402010000014020004000 ==> 1 +DAE6DB659B00010010080402000100804020100001040201008000012010000800 ==> 1 +DAE6DB659B00010004020100000140201008040001010080402000010804000100 ==> 1 +DAE6DB659B00010002010080000120100804020001008040201000010400800020 ==> 1 +DAE6DB659B00010000804020000108040201000001402010080400010100100004 ==> 1 +DAE6DB659B00014080810102000101020204040001040408081000010000000000 ==> 0 +DAE6DB659B00012020404080000140808101020001010202040400010000000000 ==> 0 +DAE6DB659B00010810102020000120204040800001408081010200010000000000 ==> 0 +DAE6DB659B00010404080810000108101020200001202040408000014000000000 ==> 0 +DAE6DB659B00010102020404000104040808100001081010202000012000000000 ==> 0 +DAE6DB659B00010080810102000101020204040001040408081000010800000000 ==> 0 +DAE6DB659B00010020404080000140808101020001010202040400010400000000 ==> 0 +DAE6DB659B00010010102020000120204040800001408081010200010100000000 ==> 0 +DAE6DB659B00010004080810000108101020200001202040408000014080000000 ==> 0 +DAE6DB659B00010002020404000104040808100001081010202000012020000000 ==> 0 +DAE6DB659B00010000810102000101020204040001040408081000010810000000 ==> 0 +DAE6DB659B00010000404080000140808101020001010202040400010404000000 ==> 0 +DAE6DB659B00010000102020000120204040800001408081010200010100800000 ==> 0 +DAE6DB659B00010000080810000108101020200001202040408000014080100000 ==> 0 +DAE6DB659B00010000020404000104040808100001081010202000012020020000 ==> 0 +DAE6DB659B00010000010102000101020204040001040408081000010810004000 ==> 0 +DAE6DB659B00010000004080000140808101020001010202040400010404000800 ==> 0 +DAE6DB659B00010000002020000120204040800001408081010200010100800100 ==> 0 +DAE6DB659B00010000000810000108101020200001202040408000014080100020 ==> 0 +DAE6DB659B00010000000404000104040808100001081010202000012020020004 ==> 0 diff --git a/tests/codec/codec_hr_sid_test.c b/tests/codec/codec_hr_sid_test.c new file mode 100644 index 00000000..ed4aa9bc --- /dev/null +++ b/tests/codec/codec_hr_sid_test.c @@ -0,0 +1,144 @@ +/* + * This program is a test for osmo_hr_sid_classify(). It reads a set of + * TCH/HS Rx bit patterns in TI DSP format (originally captured from a + * Calypso MS under conditions of induced radio errors), converts each + * bit pattern to TS 101 318 format (using same bit reordering function + * as libosmocoding gsm0503 implementation), and feeds each test line + * to osmo_hr_sid_classify(). It then prints the output next to each input. + * + * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2024 - however, + * Mother Mychaela's contributions are NOT subject to copyright. + * No rights reserved, all rights relinquished. + * + * 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. + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include <osmocom/core/bits.h> +#include <osmocom/core/utils.h> +#include <osmocom/codec/codec.h> + +#define HR_CODEC_BITS (GSM_HR_BYTES * 8) +#define HR_BYTES_TIDSP (GSM_HR_BYTES + 1) + +/* re-arrange according to TS 05.03 Table 3a (receiver) */ +/* function copied from src/coding/gsm0503_coding.c */ +static void tch_hr_d_to_b(ubit_t *b_bits, const ubit_t *d_bits) +{ + int i; + + const uint16_t *map; + + if (!d_bits[93] && !d_bits[94]) + map = gsm620_unvoiced_bitorder; + else + map = gsm620_voiced_bitorder; + + for (i = 0; i < 112; i++) + b_bits[map[i]] = d_bits[i]; +} + +static void process_record(const char *hex_str, bool bci_flag) +{ + uint8_t dsp_rx_bytes[HR_BYTES_TIDSP]; + ubit_t bits_transmission_order[HR_BYTES_TIDSP * 8]; + ubit_t bits_codec_order[HR_CODEC_BITS]; + uint8_t hr_bytes_ts101318[GSM_HR_BYTES]; + bool bfi_flag = false; + enum osmo_gsm631_sid_class sidc; + + osmo_hexparse(hex_str, dsp_rx_bytes, HR_BYTES_TIDSP); + osmo_pbit2ubit(bits_transmission_order, dsp_rx_bytes, + HR_BYTES_TIDSP * 8); + /* TI DSP format has a gap of 4 bits between class 1 and class 2 + * portions - get rid of it. 95 is the number of class 1 bits, + * 17 is the number of class 2 bits. */ + memmove(bits_transmission_order + 95, + bits_transmission_order + 95 + 4, 17); + tch_hr_d_to_b(bits_codec_order, bits_transmission_order); + osmo_ubit2pbit(hr_bytes_ts101318, bits_codec_order, HR_CODEC_BITS); + + sidc = osmo_hr_sid_classify(hr_bytes_ts101318, bci_flag, &bfi_flag); + printf("%s %d ==> %d %d\n", hex_str, (int) bci_flag, + (int) sidc, (int) bfi_flag); +} + +static void process_line(char *linebuf, const char *infname, int lineno) +{ + char *cp = linebuf, *hex_str; + int ndig; + bool bci_flag; + + while (isspace(*cp)) + cp++; + if (*cp == '\0' || *cp == '#') + return; + /* expect string of 30 hex digits */ + hex_str = cp; + for (ndig = 0; ndig < HR_BYTES_TIDSP * 2; ndig++) { + if (!isxdigit(*cp)) + goto inv; + cp++; + } + if (!isspace(*cp)) + goto inv; + *cp++ = '\0'; + while (isspace(*cp)) + cp++; + /* 0 or 1 must follow, giving BCI flag */ + if (*cp == '0') + bci_flag = false; + else if (*cp == '1') + bci_flag = true; + else + goto inv; + cp++; + /* must be end of non-comment line */ + while (isspace(*cp)) + cp++; + if (*cp != '\0' && *cp != '#') + goto inv; + + process_record(hex_str, bci_flag); + return; + +inv: fprintf(stderr, "%s line %d: invalid syntax\n", infname, lineno); + exit(1); +} + +int main(int argc, char **argv) +{ + const char *infname; + FILE *inf; + char linebuf[128]; + int lineno; + + if (argc != 2) { + fprintf(stderr, "usage: %s input-file\n", argv[0]); + exit(1); + } + infname = argv[1]; + inf = fopen(infname, "r"); + if (!inf) { + perror(infname); + exit(1); + } + for (lineno = 1; fgets(linebuf, sizeof(linebuf), inf); lineno++) + process_line(linebuf, infname, lineno); + fclose(inf); + exit(0); +} diff --git a/tests/codec/codec_hr_sid_test.in b/tests/codec/codec_hr_sid_test.in new file mode 100644 index 00000000..e8ad9662 --- /dev/null +++ b/tests/codec/codec_hr_sid_test.in @@ -0,0 +1,61 @@ +# This file is input for the HR SID classifier test program. All TCH/HS +# Rx bit strings contained in this file have been taken from hr-test1.dl +# or hr-test2.dl, attached to this wiki page: +# +# https://osmocom.org/projects/retro-gsm/wiki/HRv1_error_flags +# +# Each Rx bit string (15 hex bytes) is from TI DSP; the 0 or 1 that follows +# is the BCI flag to be fed to the SID classifier. The original DSP status +# word is noted in the comments; running the unit test program will show +# whether or not our SID classification agrees with that produced by +# TI Calypso DSP. + +# perfect, error-free SID: hr-test2.dl line 171, C010 +FFFFFFFFFFFFFFFFFFFFFFFE1FFFF0 0 + +# mode bits cleared to 0, all other bits still 1s +FFFFFFFFFFFFFFFFFFFFFFF81FFFF0 0 + +# selected error lines +FFFFFFFFFFFFFFFFFFFFFFFE0FFF70 0 # hr-test2.dl line 4226, C010 +FFFFFFFFFFFFFFFFFFFFFFFE13FFF0 1 # hr-test2.dl line 4256, C012 +FFFFFFFFFFFFFFFFFFFFFFFE17FFF0 1 # hr-test2.dl line 4258, C012 +FFFD01FFFFFFFFFFFFFFFFFE0FFFF0 1 # hr-test2.dl line 4598, C00A +FFFFFFFFFFFCC296452940FE1FFEF0 1 # hr-test2.dl line 5141, C00F +FFFFFFFFFFFCC296452940FE1FFEF0 0 # same bits without BCI +FF6E76F40C276FFFFFFFFFFE0FFFF0 1 # hr-test2.dl line 5173, C003 +FF6E76F40C276FFFFFFFFFFE0FFFF0 0 # same bits without BCI +FFFFFFFFFDFFFFFFFFFFFFFE0FFFF0 1 # hr-test2.dl line 5206, C012 +FFFFFFFFFDFFFFFFFFFFFFFE0FFFF0 0 # same bits without BCI +FFFFFFFFFFD0DFFFFFFFFFFE07FEF0 1 # hr-test2.dl line 5261, C00A +FFFFFFFFFFD0DFFFFFFFFFFE07FEF0 0 # same bits without BCI +FFFFFFFFFFFF41EAC9676FFE1F7DF0 1 # hr-test2.dl line 5738, C00F +FFFFFFFFFFFF41EAC9676FFE1F7DF0 0 # same bits without BCI + +FFFFFFFFFFFF847D5B9DBFFE1937B0 1 # hr-test2.dl line 6175, C00F +FFFFFFFFFFFF847D5B9DBFFE1937B0 0 # same bits without BCI +FFFFFFFFFFFFFFFFFFFFFFD01FFEB0 1 # hr-test2.dl line 6188, C017 +FFFFFFFFFFFFFFFFFFFFFFD01FFEB0 0 # same bits without BCI +FDBD7D552CB25FFFFFFFFFFE1DFBB0 1 # hr-test2.dl line 6191, C002 +FDBD7D552CB25FFFFFFFFFFE1DFBB0 0 # same bits without BCI +FFD2F0A52B8FFFFFFFFEDE600FFDF0 1 # hr-test2.dl line 6195, C007 +FFD2F0A52B8FFFFFFFFEDE600FFDF0 0 # same bits without BCI +FFFFFFFFCC7FFFFFFFF4EE601C31D0 1 # hr-test2.dl line 6318, C007 +FFFFFFFFCC7FFFFFFFF4EE601C31D0 0 # same bits without BCI +FFFFFFFFFFFFFFFFFFFFA5901BEFD0 1 # hr-test2.dl line 6545, C00F +FFFFFFFFFFFFFFFFFFFFA5901BEFD0 0 # same bits without BCI +FFFFFFFFEA97FFFFFFE765901FFFB0 1 # hr-test2.dl line 6973, C00F +FFFFFFFFEA97FFFFFFE765901FFFB0 0 # same bits without BCI + +FFFFFFFFF8C8A5E29DA0DFFE07FFF0 1 # hr-test2.dl line 7158, C00F +FFFFFFFFF8C8A5E29DA0DFFE07FFF0 0 # same bits without BCI +FFFD01853B7206E63FFFFFFE1FBFD0 1 # hr-test2.dl line 7175, C003 +FFFD01853B7206E63FFFFFFE1FBFD0 0 # same bits without BCI +E6ACC7FFFF40FFFFFFFFFFFE1FF770 1 # hr-test2.dl line 7195, C00B +E6ACC7FFFF40FFFFFFFFFFFE1FF770 0 # same bits without BCI + +# hr-test1.dl, PRBS without major errors +55A5404BFAED58A3BE33A978092A40 0 # hr-test1.dl line 1051, C000 +CFE44B516ED5D1F54E4615AA101260 0 # hr-test1.dl line 2710, C000 +D7881D40AA0F68106195DCD41568C0 0 # hr-test1.dl line 4306, C000 +D4CFB4961F8F9F11313454560690E0 1 # hr-test1.dl line 4631, C002 diff --git a/tests/codec/codec_hr_sid_test.ok b/tests/codec/codec_hr_sid_test.ok new file mode 100644 index 00000000..3ea1fedf --- /dev/null +++ b/tests/codec/codec_hr_sid_test.ok @@ -0,0 +1,40 @@ +FFFFFFFFFFFFFFFFFFFFFFFE1FFFF0 0 ==> 2 0 +FFFFFFFFFFFFFFFFFFFFFFF81FFFF0 0 ==> 1 0 +FFFFFFFFFFFFFFFFFFFFFFFE0FFF70 0 ==> 2 0 +FFFFFFFFFFFFFFFFFFFFFFFE13FFF0 1 ==> 2 0 +FFFFFFFFFFFFFFFFFFFFFFFE17FFF0 1 ==> 2 0 +FFFD01FFFFFFFFFFFFFFFFFE0FFFF0 1 ==> 1 0 +FFFFFFFFFFFCC296452940FE1FFEF0 1 ==> 1 0 +FFFFFFFFFFFCC296452940FE1FFEF0 0 ==> 0 0 +FF6E76F40C276FFFFFFFFFFE0FFFF0 1 ==> 0 1 +FF6E76F40C276FFFFFFFFFFE0FFFF0 0 ==> 0 0 +FFFFFFFFFDFFFFFFFFFFFFFE0FFFF0 1 ==> 2 0 +FFFFFFFFFDFFFFFFFFFFFFFE0FFFF0 0 ==> 2 0 +FFFFFFFFFFD0DFFFFFFFFFFE07FEF0 1 ==> 1 0 +FFFFFFFFFFD0DFFFFFFFFFFE07FEF0 0 ==> 1 0 +FFFFFFFFFFFF41EAC9676FFE1F7DF0 1 ==> 1 0 +FFFFFFFFFFFF41EAC9676FFE1F7DF0 0 ==> 0 0 +FFFFFFFFFFFF847D5B9DBFFE1937B0 1 ==> 1 0 +FFFFFFFFFFFF847D5B9DBFFE1937B0 0 ==> 0 0 +FFFFFFFFFFFFFFFFFFFFFFD01FFEB0 1 ==> 1 0 +FFFFFFFFFFFFFFFFFFFFFFD01FFEB0 0 ==> 1 0 +FDBD7D552CB25FFFFFFFFFFE1DFBB0 1 ==> 0 1 +FDBD7D552CB25FFFFFFFFFFE1DFBB0 0 ==> 0 0 +FFD2F0A52B8FFFFFFFFEDE600FFDF0 1 ==> 0 1 +FFD2F0A52B8FFFFFFFFEDE600FFDF0 0 ==> 0 0 +FFFFFFFFCC7FFFFFFFF4EE601C31D0 1 ==> 0 1 +FFFFFFFFCC7FFFFFFFF4EE601C31D0 0 ==> 0 0 +FFFFFFFFFFFFFFFFFFFFA5901BEFD0 1 ==> 1 0 +FFFFFFFFFFFFFFFFFFFFA5901BEFD0 0 ==> 1 0 +FFFFFFFFEA97FFFFFFE765901FFFB0 1 ==> 1 0 +FFFFFFFFEA97FFFFFFE765901FFFB0 0 ==> 0 0 +FFFFFFFFF8C8A5E29DA0DFFE07FFF0 1 ==> 1 0 +FFFFFFFFF8C8A5E29DA0DFFE07FFF0 0 ==> 0 0 +FFFD01853B7206E63FFFFFFE1FBFD0 1 ==> 0 1 +FFFD01853B7206E63FFFFFFE1FBFD0 0 ==> 0 0 +E6ACC7FFFF40FFFFFFFFFFFE1FF770 1 ==> 1 0 +E6ACC7FFFF40FFFFFFFFFFFE1FF770 0 ==> 0 0 +55A5404BFAED58A3BE33A978092A40 0 ==> 0 0 +CFE44B516ED5D1F54E4615AA101260 0 ==> 0 0 +D7881D40AA0F68106195DCD41568C0 0 ==> 0 0 +D4CFB4961F8F9F11313454560690E0 1 ==> 0 0 diff --git a/tests/jhash/jhash_test.c b/tests/jhash/jhash_test.c new file mode 100644 index 00000000..e2c8c71e --- /dev/null +++ b/tests/jhash/jhash_test.c @@ -0,0 +1,56 @@ +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/hashtable.h> +#include <osmocom/core/jhash.h> + +struct item { + const char blob[32]; + struct hlist_node node; +}; + +struct item items[] = { + { "blob one", }, + { "blob two and five are the same", }, + { "third blob", }, + { "fourth blob", }, + { "blob two and five are the same", }, +}; + +uint32_t item_hash(const struct item *item) +{ + return osmo_jhash(item->blob, strlen(item->blob), 0); +} + +int main(void) +{ + int i; + struct item *item; + + DECLARE_HASHTABLE(haystack, 5); + hash_init(haystack); + + printf("add:\n"); + for (i = 0; i < ARRAY_SIZE(items); i++) { + uint32_t hash; + item = &items[i]; + hash_add(haystack, &item->node, hash = item_hash(item)); + printf("- adding items[%d]#%x = %s\n", i, hash, item->blob); + } + + printf("list:\n"); + hash_for_each (haystack, i, item, node) + printf("- %s [%d]\n", item->blob, (int)(item - items)); + + printf("find:\n"); + for (i = 0; i < ARRAY_SIZE(items); i++) { + uint32_t hash; + struct item *needle = &items[i]; + hash = item_hash(needle); + printf("- looking up items[%d]#%x = %s\n", i, hash, needle->blob); + hash_for_each_possible (haystack, item, node, hash) + printf(" - %s items[%d]\n", + (item == needle) ? "found" : "not", + (int)(item - items)); + } + + return 0; +} diff --git a/tests/jhash/jhash_test.ok b/tests/jhash/jhash_test.ok new file mode 100644 index 00000000..e28ccc46 --- /dev/null +++ b/tests/jhash/jhash_test.ok @@ -0,0 +1,25 @@ +add: +- adding items[0]#b286bb61 = blob one +- adding items[1]#ad4eb7b = blob two and five are the same +- adding items[2]#6b8eae61 = third blob +- adding items[3]#24a546dc = fourth blob +- adding items[4]#ad4eb7b = blob two and five are the same +list: +- blob two and five are the same [4] +- blob two and five are the same [1] +- blob one [0] +- fourth blob [3] +- third blob [2] +find: +- looking up items[0]#b286bb61 = blob one + - found items[0] +- looking up items[1]#ad4eb7b = blob two and five are the same + - not items[4] + - found items[1] +- looking up items[2]#6b8eae61 = third blob + - found items[2] +- looking up items[3]#24a546dc = fourth blob + - found items[3] +- looking up items[4]#ad4eb7b = blob two and five are the same + - found items[4] + - not items[1] diff --git a/tests/sim/sim_test.c b/tests/sim/sim_test.c index 2e2eec58..ab5d2be3 100644 --- a/tests/sim/sim_test.c +++ b/tests/sim/sim_test.c @@ -27,6 +27,10 @@ const uint8_t uicc_tprof[] = { 0x80, 0x10, 0x00, 0x00, 0x02, 0x01, 0x02 }; const uint8_t uicc_tprof_wrong_class[] = { 0x00, 0x10, 0x00, 0x00, 0x02, 0x01, 0x02 }; const uint8_t uicc_read[] = { 0x00, 0xB0, 0x00, 0x00, 0x10 }; const uint8_t uicc_upd[] = { 0x00, 0xD6, 0x00, 0x00, 0x02, 0x01, 0x02 }; +const uint8_t uicc_get_status[] = { 0x80, 0xf2, 0x00, 0x02, 0x10 }; +const uint8_t euicc_m2m_get_status[] = { 0x81, 0xf2, 0x40, 0x02, 0x02, 0x4f, 0x00 }; +const uint8_t gp_get_data2[] = { 0x81, 0xCA, 0x00, 0x5A, 0x00 }; +const uint8_t gp_get_data4[] = { 0x81, 0xCA, 0x00, 0x5A, 0x12 }; #define APDU_CASE_ASSERT(x, y) \ do { \ @@ -45,6 +49,10 @@ static void test_cla_ins_tbl(void) APDU_CASE_ASSERT(uicc_tprof_wrong_class, 0); APDU_CASE_ASSERT(uicc_read, 2); APDU_CASE_ASSERT(uicc_upd, 3); + APDU_CASE_ASSERT(uicc_get_status, 2); + APDU_CASE_ASSERT(euicc_m2m_get_status, 4); + APDU_CASE_ASSERT(gp_get_data2, 2); + APDU_CASE_ASSERT(gp_get_data4, 4); } int main(int argc, char **argv) diff --git a/tests/sim/sim_test.ok b/tests/sim/sim_test.ok index 7d3f986d..3abfb718 100644 --- a/tests/sim/sim_test.ok +++ b/tests/sim/sim_test.ok @@ -4,3 +4,7 @@ Testing uicc_tprof Testing uicc_tprof_wrong_class Testing uicc_read Testing uicc_upd +Testing uicc_get_status +Testing euicc_m2m_get_status +Testing gp_get_data2 +Testing gp_get_data4 diff --git a/tests/testsuite.at b/tests/testsuite.at index e721b937..f22ca5a5 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -218,6 +218,24 @@ cat $abs_srcdir/codec/codec_ecu_fr_test.ok > expout AT_CHECK([$abs_top_builddir/tests/codec/codec_ecu_fr_test], [0], [expout], [ignore]) AT_CLEANUP +AT_SETUP([codec_efr_sid]) +AT_KEYWORDS([codec_efr_sid]) +cat $abs_srcdir/codec/codec_efr_sid_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/codec/codec_efr_sid_test $abs_srcdir/codec/codec_efr_sid_test.in], [0], [expout], [ignore]) +AT_CLEANUP + +AT_SETUP([codec_fr_sid]) +AT_KEYWORDS([codec_fr_sid]) +cat $abs_srcdir/codec/codec_fr_sid_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/codec/codec_fr_sid_test $abs_srcdir/codec/codec_fr_sid_test.in], [0], [expout], [ignore]) +AT_CLEANUP + +AT_SETUP([codec_hr_sid]) +AT_KEYWORDS([codec_hr_sid]) +cat $abs_srcdir/codec/codec_hr_sid_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/codec/codec_hr_sid_test $abs_srcdir/codec/codec_hr_sid_test.in], [0], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([fr]) AT_KEYWORDS([fr]) cat $abs_srcdir/fr/fr_test.ok > expout @@ -547,3 +565,9 @@ AT_KEYWORDS([rlp]) cat $abs_srcdir/rlp/rlp_test.ok > expout AT_CHECK([$abs_top_builddir/tests/rlp/rlp_test], [0], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([jhash]) +AT_KEYWORDS([jhash]) +cat $abs_srcdir/jhash/jhash_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/jhash/jhash_test], [0], [expout], [ignore]) +AT_CLEANUP |