aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am364
-rw-r--r--tests/abis/abis_test.c53
-rw-r--r--tests/abis/abis_test.ok1
-rw-r--r--tests/auth/xor2g_test.c77
-rw-r--r--tests/auth/xor2g_test.ok6
-rw-r--r--tests/base64/base64_test.c55
-rw-r--r--tests/base64/base64_test.ok3
-rw-r--r--tests/bitgen/bitgen_test.c6
-rw-r--r--tests/bitvec/bitvec_test.c11
-rw-r--r--tests/bitvec/bitvec_test.ok32
-rw-r--r--tests/bsslap/bsslap_test.c103
-rw-r--r--tests/bsslap/bsslap_test.ok7
-rw-r--r--tests/bssmap_le/bssmap_le_test.c207
-rw-r--r--tests/bssmap_le/bssmap_le_test.ok12
-rw-r--r--tests/codec/codec_ecu_fr_test.c4
-rw-r--r--tests/coding/coding_test.c4
-rw-r--r--tests/conv/conv_gsm0503_test.ok32
-rw-r--r--tests/ctrl/ctrl_test.c13
-rw-r--r--tests/dtx/dtx_gsm0503_test.c168
-rw-r--r--tests/dtx/dtx_gsm0503_test.ok34
-rw-r--r--tests/fr/fr_test.c6
-rw-r--r--tests/fsm/fsm_dealloc_test.c8
-rw-r--r--tests/fsm/fsm_test.c82
-rw-r--r--tests/fsm/fsm_test.err28
-rw-r--r--tests/gad/gad_test.c143
-rw-r--r--tests/gad/gad_test.ok8
-rw-r--r--tests/gb/bssgp_fc_test.c4
-rw-r--r--tests/gb/gprs_bssgp_rim_test.c799
-rw-r--r--tests/gb/gprs_bssgp_rim_test.ok276
-rw-r--r--tests/gb/gprs_bssgp_test.c6
-rw-r--r--tests/gb/gprs_ns2_test.c670
-rw-r--r--tests/gb/gprs_ns2_test.ok51
-rw-r--r--tests/gb/gprs_ns2_vty.vty89
-rw-r--r--tests/gb/gprs_ns_test.c24
-rw-r--r--tests/gb/osmo-ns-dummy.cfg25
-rw-r--r--tests/gb/osmoappdesc.py27
-rw-r--r--tests/gsm0408/gsm0408_test.c283
-rw-r--r--tests/gsm0408/gsm0408_test.err3
-rw-r--r--tests/gsm0408/gsm0408_test.ok457
-rw-r--r--tests/gsm0502/gsm0502_test.c6
-rw-r--r--tests/gsm0808/gsm0808_test.c492
-rw-r--r--tests/gsm0808/gsm0808_test.ok805
-rw-r--r--tests/gsm23003/gsm23003_test.c18
-rw-r--r--tests/gsm23236/gsm23236_test.c16
-rw-r--r--tests/gsm29205/gsm29205_test.c6
-rw-r--r--tests/gsm44021/test_frame_csd.c93
-rw-r--r--tests/gsm44021/test_frame_csd.ok31
-rw-r--r--tests/gsm48/rest_octets_test.c116
-rw-r--r--tests/gsm48/rest_octets_test.ok2
-rw-r--r--tests/gsup/gsup_test.c3
-rw-r--r--tests/i460_mux/i460_mux_test.c3
-rw-r--r--tests/it_q/it_q_test.c120
-rw-r--r--tests/it_q/it_q_test.ok15
-rw-r--r--tests/iuup/iuup_test.c764
-rw-r--r--tests/iuup/iuup_test.ok61
-rw-r--r--tests/lapd/lapd_test.c14
-rw-r--r--tests/logging/logging_test.c20
-rw-r--r--tests/logging/logging_test.err2
-rw-r--r--tests/logging/logging_vty_test.c11
-rw-r--r--tests/logging/logging_vty_test.vty66
-rw-r--r--tests/loggingrb/loggingrb_test.c8
-rw-r--r--tests/msgb/msgb_test.c34
-rw-r--r--tests/msgfile/msgfile_test.c4
-rw-r--r--tests/oap/oap_client_test.c3
-rw-r--r--tests/oap/oap_test.c4
-rw-r--r--tests/osmo-auc-gen/osmo-auc-gen_test.ok30
-rw-r--r--tests/sercomm/sercomm_test.c4
-rw-r--r--tests/sim/sim_test.c4
-rw-r--r--tests/sms/sms_test.c59
-rw-r--r--tests/sms/sms_test.ok16
-rw-r--r--tests/smscb/cbsp_test.c108
-rw-r--r--tests/smscb/cbsp_test.ok2
-rw-r--r--tests/smscb/gsm0341_test.c14
-rw-r--r--tests/smscb/gsm0341_test.ok1
-rw-r--r--tests/smscb/smscb_test.c4
-rw-r--r--tests/sockaddr_str/sockaddr_str_test.c8
-rw-r--r--tests/socket/socket_sctp_test.c10
-rw-r--r--tests/socket/socket_test.c147
-rw-r--r--tests/socket/socket_test.ok10
-rw-r--r--tests/stats/stats_test.c416
-rw-r--r--tests/stats/stats_test.err163
-rw-r--r--tests/stats/stats_test.ok132
-rw-r--r--tests/stats/stats_vty_test.c88
-rw-r--r--tests/stats/stats_vty_test.vty217
-rw-r--r--tests/strrb/strrb_test.c4
-rw-r--r--tests/tdef/tdef_test.c25
-rw-r--r--tests/tdef/tdef_test.ok42
-rw-r--r--tests/tdef/tdef_vty_config_root_test.c (renamed from tests/tdef/tdef_vty_test_config_root.c)14
-rw-r--r--tests/tdef/tdef_vty_config_root_test.vty (renamed from tests/tdef/tdef_vty_test_config_root.vty)0
-rw-r--r--tests/tdef/tdef_vty_config_subnode_test.c (renamed from tests/tdef/tdef_vty_test_config_subnode.c)12
-rw-r--r--tests/tdef/tdef_vty_config_subnode_test.vty (renamed from tests/tdef/tdef_vty_test_config_subnode.vty)0
-rw-r--r--tests/tdef/tdef_vty_dynamic_test.c (renamed from tests/tdef/tdef_vty_test_dynamic.c)10
-rw-r--r--tests/tdef/tdef_vty_dynamic_test.vty (renamed from tests/tdef/tdef_vty_test_dynamic.vty)0
-rw-r--r--tests/testsuite.at120
-rw-r--r--tests/time_cc/time_cc_test.c768
-rw-r--r--tests/time_cc/time_cc_test.ok328
-rw-r--r--tests/timer/clk_override_test.c4
-rw-r--r--tests/timer/timer_test.c6
-rw-r--r--tests/tlv/tlv_test.c130
-rw-r--r--tests/tlv/tlv_test.ok7
-rw-r--r--tests/use_count/use_count_test.c8
-rw-r--r--tests/use_count/use_count_test.err10
-rw-r--r--tests/ussd/ussd_test.c4
-rw-r--r--tests/utils/utils_test.c712
-rw-r--r--tests/utils/utils_test.ok514
-rw-r--r--tests/v110/test_frame.c54
-rw-r--r--tests/v110/test_frame.ok20
-rw-r--r--tests/v110/test_ra1.c71
-rw-r--r--tests/v110/test_ra1.ok216
-rw-r--r--tests/vty/vty_test.c105
-rw-r--r--tests/vty/vty_test.err77
-rw-r--r--tests/vty/vty_test.ok48
-rw-r--r--tests/vty/vty_transcript_test.c158
-rw-r--r--tests/vty/vty_transcript_test.vty93
-rw-r--r--tests/write_queue/wqueue_test.c4
115 files changed, 10619 insertions, 1276 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7a0b4b1f..275cf5f1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,7 +1,7 @@
-AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir)
AM_CFLAGS = -Wall $(TALLOC_CFLAGS) $(PTHREAD_CFLAGS)
AM_LDFLAGS = -no-install
-LDADD = $(top_builddir)/src/libosmocore.la $(TALLOC_LIBS) $(PTHREAD_LIBS)
+LDADD = $(top_builddir)/src/core/libosmocore.la $(TALLOC_LIBS) $(PTHREAD_LIBS)
if ENABLE_SERCOM_STUB
noinst_LIBRARIES = libsercomstub.a
@@ -9,13 +9,13 @@ LDADD += $(top_builddir)/tests/libsercomstub.a
endif
check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \
- smscb/smscb_test bits/bitrev_test a5/a5_test \
+ bits/bitrev_test a5/a5_test \
conv/conv_test auth/milenage_test lapd/lapd_test \
gsm0808/gsm0808_test gsm0408/gsm0408_test \
gprs/gprs_test kasumi/kasumi_test gea/gea_test \
logging/logging_test codec/codec_test \
loggingrb/loggingrb_test strrb/strrb_test \
- comp128/comp128_test smscb/gsm0341_test \
+ comp128/comp128_test \
bitvec/bitvec_test msgb/msgb_test bits/bitcomp_test \
bits/bitfield_test \
tlv/tlv_test gsup/gsup_test oap/oap_test \
@@ -28,9 +28,9 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \
oap/oap_client_test gsm29205/gsm29205_test \
logging/logging_vty_test \
vty/vty_transcript_test \
- tdef/tdef_test tdef/tdef_vty_test_config_root \
- tdef/tdef_vty_test_config_subnode \
- tdef/tdef_vty_test_dynamic \
+ tdef/tdef_test tdef/tdef_vty_config_root_test \
+ tdef/tdef_vty_config_subnode_test \
+ tdef/tdef_vty_dynamic_test \
sockaddr_str/sockaddr_str_test \
use_count/use_count_test \
context/context_test \
@@ -38,6 +38,21 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \
dtx/dtx_gsm0503_test \
i460_mux/i460_mux_test \
bitgen/bitgen_test \
+ gad/gad_test \
+ bsslap/bsslap_test \
+ bssmap_le/bssmap_le_test \
+ it_q/it_q_test \
+ time_cc/time_cc_test \
+ gsm48/rest_octets_test \
+ base64/base64_test \
+ iuup/iuup_test \
+ smscb/smscb_test \
+ smscb/gsm0341_test \
+ smscb/cbsp_test \
+ auth/xor2g_test \
+ v110/test_frame \
+ v110/test_ra1 \
+ gsm44021/test_frame_csd \
$(NULL)
if ENABLE_MSGFILE
@@ -67,18 +82,25 @@ endif
if !EMBEDDED
check_PROGRAMS += \
stats/stats_test \
+ stats/stats_vty_test \
exec/exec_test
endif
if ENABLE_GB
-check_PROGRAMS += gb/bssgp_fc_test gb/gprs_bssgp_test gb/gprs_ns_test fr/fr_test
+check_PROGRAMS += gb/bssgp_fc_test gb/gprs_bssgp_test gb/gprs_bssgp_rim_test gb/gprs_ns_test gb/gprs_ns2_test fr/fr_test
endif
+base64_base64_test_SOURCES = base64/base64_test.c
+
utils_utils_test_SOURCES = utils/utils_test.c
utils_utils_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
stats_stats_test_SOURCES = stats/stats_test.c
stats_stats_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+stats_stats_test_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/core
+
+stats_stats_vty_test_SOURCES = stats/stats_vty_test.c
+stats_stats_vty_test_LDADD = $(LDADD) $(top_builddir)/src/vty/libosmovty.la
a5_a5_test_SOURCES = a5/a5_test.c
a5_a5_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libgsmint.la
@@ -92,6 +114,9 @@ comp128_comp128_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
auth_milenage_test_SOURCES = auth/milenage_test.c
auth_milenage_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+auth_xor2g_test_SOURCES = auth/xor2g_test.c
+auth_xor2g_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+
abis_abis_test_SOURCES = abis/abis_test.c
abis_abis_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
@@ -135,11 +160,14 @@ gsm29205_gsm29205_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
gsm0408_gsm0408_test_SOURCES = gsm0408/gsm0408_test.c
gsm0408_gsm0408_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+gsm48_rest_octets_test_SOURCES = gsm48/rest_octets_test.c
+gsm48_rest_octets_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+
gprs_gprs_test_SOURCES = gprs/gprs_test.c
gprs_gprs_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
lapd_lapd_test_SOURCES = lapd/lapd_test.c
-lapd_lapd_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+lapd_lapd_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la $(top_builddir)/src/isdn/libosmoisdn.la
msgb_msgb_test_SOURCES = msgb/msgb_test.c
@@ -151,6 +179,9 @@ smscb_smscb_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
smscb_gsm0341_test_SOURCES = smscb/gsm0341_test.c
smscb_gsm0341_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+smscb_cbsp_test_SOURCES = smscb/cbsp_test.c
+smscb_cbsp_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+
sms_sms_test_SOURCES = sms/sms_test.c
sms_sms_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
@@ -169,13 +200,25 @@ gb_bssgp_fc_test_LDADD = $(LDADD) $(top_builddir)/src/gb/libosmogb.la \
gb_gprs_bssgp_test_SOURCES = gb/gprs_bssgp_test.c
gb_gprs_bssgp_test_LDADD = $(LDADD) $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DLSYM) \
$(top_builddir)/src/vty/libosmovty.la \
- $(top_builddir)/src/gsm/libosmogsm.la
+ $(top_builddir)/src/gsm/libosmogsm.la \
+ $(top_builddir)/src/gb/libosmogb.la
+
+gb_gprs_bssgp_rim_test_SOURCES = gb/gprs_bssgp_rim_test.c
+gb_gprs_bssgp_rim_test_LDADD = $(LDADD) $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DLSYM) \
+ $(top_builddir)/src/gb/libosmogb.la
gb_gprs_ns_test_SOURCES = gb/gprs_ns_test.c
gb_gprs_ns_test_LDADD = $(LDADD) $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DLSYM) \
$(top_builddir)/src/vty/libosmovty.la \
$(top_builddir)/src/gsm/libosmogsm.la
+gb_gprs_ns2_test_SOURCES = gb/gprs_ns2_test.c
+gb_gprs_ns2_test_LDADD = $(LDADD) $(LIBRARY_DLSYM) \
+ $(top_builddir)/src/vty/libosmovty.la \
+ $(top_builddir)/src/gsm/libosmogsm.la \
+ $(top_builddir)/src/core/libosmocore.la \
+ $(top_builddir)/src/gb/libosmogb-test.la
+
logging_logging_test_SOURCES = logging/logging_test.c
logging_logging_vty_test_SOURCES = logging/logging_vty_test.c
@@ -254,14 +297,14 @@ gsm23236_gsm23236_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
tdef_tdef_test_SOURCES = tdef/tdef_test.c
tdef_tdef_test_LDADD = $(LDADD)
-tdef_tdef_vty_test_config_root_SOURCES = tdef/tdef_vty_test_config_root.c
-tdef_tdef_vty_test_config_root_LDADD = $(LDADD) $(top_builddir)/src/vty/libosmovty.la
+tdef_tdef_vty_config_root_test_SOURCES = tdef/tdef_vty_config_root_test.c
+tdef_tdef_vty_config_root_test_LDADD = $(LDADD) $(top_builddir)/src/vty/libosmovty.la
-tdef_tdef_vty_test_config_subnode_SOURCES = tdef/tdef_vty_test_config_subnode.c
-tdef_tdef_vty_test_config_subnode_LDADD = $(LDADD) $(top_builddir)/src/vty/libosmovty.la
+tdef_tdef_vty_config_subnode_test_SOURCES = tdef/tdef_vty_config_subnode_test.c
+tdef_tdef_vty_config_subnode_test_LDADD = $(LDADD) $(top_builddir)/src/vty/libosmovty.la
-tdef_tdef_vty_test_dynamic_SOURCES = tdef/tdef_vty_test_dynamic.c
-tdef_tdef_vty_test_dynamic_LDADD = $(LDADD) $(top_builddir)/src/vty/libosmovty.la
+tdef_tdef_vty_dynamic_test_SOURCES = tdef/tdef_vty_dynamic_test.c
+tdef_tdef_vty_dynamic_test_LDADD = $(LDADD) $(top_builddir)/src/vty/libosmovty.la
sockaddr_str_sockaddr_str_test_SOURCES = sockaddr_str/sockaddr_str_test.c
sockaddr_str_sockaddr_str_test_LDADD = $(LDADD)
@@ -276,11 +319,40 @@ exec_exec_test_SOURCES = exec/exec_test.c
exec_exec_test_LDADD = $(LDADD)
i460_mux_i460_mux_test_SOURCES = i460_mux/i460_mux_test.c
-i460_mux_i460_mux_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+i460_mux_i460_mux_test_LDADD = $(LDADD) $(top_builddir)/src/isdn/libosmoisdn.la
bitgen_bitgen_test_SOURCES = bitgen/bitgen_test.c
bitgen_bitgen_test_LDADD = $(LDADD)
+gad_gad_test_SOURCES = gad/gad_test.c
+gad_gad_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+
+bsslap_bsslap_test_SOURCES = bsslap/bsslap_test.c
+bsslap_bsslap_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+
+bssmap_le_bssmap_le_test_SOURCES = bssmap_le/bssmap_le_test.c
+bssmap_le_bssmap_le_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+
+it_q_it_q_test_SOURCES = it_q/it_q_test.c
+it_q_it_q_test_LDADD = $(LDADD)
+
+time_cc_time_cc_test_SOURCES = time_cc/time_cc_test.c
+time_cc_time_cc_test_LDADD = $(LDADD)
+
+iuup_iuup_test_SOURCES = iuup/iuup_test.c
+iuup_iuup_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
+
+v110_test_frame_SOURCES = v110/test_frame.c
+v110_test_frame_LDADD = $(LDADD) $(top_builddir)/src/isdn/libosmoisdn.la
+
+v110_test_ra1_SOURCES = v110/test_ra1.c
+v110_test_ra1_LDADD = $(LDADD) $(top_builddir)/src/isdn/libosmoisdn.la
+
+gsm44021_test_frame_csd_SOURCES = gsm44021/test_frame_csd.c
+gsm44021_test_frame_csd_LDADD = $(LDADD) $(top_builddir)/src/isdn/libosmoisdn.la \
+ $(top_builddir)/src/gsm/libosmogsm.la
+
+
# The `:;' works around a Bash 3.2 bug when the output is not writeable.
$(srcdir)/package.m4: $(top_srcdir)/configure.ac
:;{ \
@@ -301,12 +373,17 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
timer/timer_test.ok sms/sms_test.ok ussd/ussd_test.ok \
- smscb/smscb_test.ok bits/bitrev_test.ok a5/a5_test.ok \
+ bits/bitrev_test.ok a5/a5_test.ok \
conv/conv_test.ok auth/milenage_test.ok ctrl/ctrl_test.ok \
- lapd/lapd_test.ok gsm0408/gsm0408_test.ok \
+ auth/xor2g_test.ok \
+ lapd/lapd_test.ok \
+ gsm0408/gsm0408_test.ok gsm0408/gsm0408_test.err \
gsm0808/gsm0808_test.ok gb/bssgp_fc_tests.err \
gb/bssgp_fc_tests.ok gb/bssgp_fc_tests.sh \
gb/gprs_bssgp_test.ok gb/gprs_ns_test.ok gea/gea_test.ok \
+ gb/gprs_bssgp_rim_test.ok \
+ gb/gprs_ns2_vty.vty gb/osmoappdesc.py gb/osmo-ns-dummy.cfg \
+ gb/gprs_ns2_test.ok \
gprs/gprs_test.ok kasumi/kasumi_test.ok \
msgfile/msgfile_test.ok msgfile/msgconfig.cfg \
logging/logging_test.ok logging/logging_test.err \
@@ -315,7 +392,7 @@ 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 \
- vty/vty_test.ok \
+ vty/vty_test.ok vty/vty_test.err \
vty/fail_not_de-indented.cfg \
vty/fail_tabs_and_spaces.cfg \
vty/fail_too_much_indent.cfg \
@@ -330,7 +407,9 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
vty/ok_tabs.cfg \
vty/ok_deprecated_logging.cfg \
comp128/comp128_test.ok bits/bitfield_test.ok \
- utils/utils_test.ok utils/utils_test.err stats/stats_test.ok \
+ utils/utils_test.ok utils/utils_test.err \
+ stats/stats_test.ok stats/stats_test.err \
+ stats/stats_vty_test.vty \
bitvec/bitvec_test.ok msgb/msgb_test.ok bits/bitcomp_test.ok \
sim/sim_test.ok tlv/tlv_test.ok abis/abis_test.ok \
gsup/gsup_test.ok gsup/gsup_test.err \
@@ -350,9 +429,9 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
vty/vty_transcript_test.vty \
tdef/tdef_test.ok \
tdef/tdef_test_range_64bit.ok \
- tdef/tdef_vty_test_config_root.vty \
- tdef/tdef_vty_test_config_subnode.vty \
- tdef/tdef_vty_test_dynamic.vty \
+ tdef/tdef_vty_config_root_test.vty \
+ tdef/tdef_vty_config_subnode_test.vty \
+ tdef/tdef_vty_dynamic_test.vty \
sockaddr_str/sockaddr_str_test.ok \
use_count/use_count_test.ok use_count/use_count_test.err \
context/context_test.ok \
@@ -361,6 +440,20 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
exec/exec_test.ok exec/exec_test.err \
i460_mux/i460_mux_test.ok \
bitgen/bitgen_test.ok \
+ gad/gad_test.ok \
+ bsslap/bsslap_test.ok \
+ bssmap_le/bssmap_le_test.ok \
+ it_q/it_q_test.ok \
+ time_cc/time_cc_test.ok \
+ gsm48/rest_octets_test.ok \
+ base64/base64_test.ok \
+ iuup/iuup_test.ok \
+ smscb/smscb_test.ok \
+ smscb/gsm0341_test.ok \
+ smscb/cbsp_test.ok \
+ v110/test_frame.ok \
+ v110/test_ra1.ok \
+ gsm44021/test_frame_csd.ok \
$(NULL)
if ENABLE_LIBSCTP
@@ -377,6 +470,200 @@ noinst_HEADERS = conv/conv.h
TESTSUITE = $(srcdir)/testsuite
+update_exp: $(check_PROGRAMS)
+ a5/a5_test \
+ >$(srcdir)/a5/a5_test.ok
+ abis/abis_test \
+ >$(srcdir)/abis/abis_test.ok
+if ENABLE_CTRL
+ ctrl/ctrl_test \
+ >$(srcdir)/ctrl/ctrl_test.ok
+endif
+ kasumi/kasumi_test \
+ >$(srcdir)/kasumi/kasumi_test.ok
+ bits/bitrev_test \
+ >$(srcdir)/bits/bitrev_test.ok
+ bitvec/bitvec_test \
+ >$(srcdir)/bitvec/bitvec_test.ok
+ bits/bitcomp_test \
+ >$(srcdir)/bits/bitcomp_test.ok
+ bits/bitfield_test \
+ >$(srcdir)/bits/bitfield_test.ok
+ conv/conv_test \
+ >$(srcdir)/conv/conv_test.ok
+ conv/conv_gsm0503_test \
+ >$(srcdir)/conv/conv_gsm0503_test.ok
+ coding/coding_test \
+ >$(srcdir)/coding/coding_test.ok
+ msgb/msgb_test \
+ >$(srcdir)/msgb/msgb_test.ok
+ gea/gea_test \
+ >$(srcdir)/gea/gea_test.ok
+if ENABLE_MSGFILE
+ cp $(srcdir)/msgfile/msgconfig.cfg .
+ msgfile/msgfile_test \
+ >$(srcdir)/msgfile/msgfile_test.ok
+endif
+ sms/sms_test \
+ >$(srcdir)/sms/sms_test.ok
+ smscb/smscb_test \
+ >$(srcdir)/smscb/smscb_test.ok
+ smscb/gsm0341_test \
+ >$(srcdir)/smscb/gsm0341_test.ok
+ smscb/cbsp_test \
+ >$(srcdir)/smscb/cbsp_test.ok
+ ussd/ussd_test \
+ >$(srcdir)/ussd/ussd_test.ok
+ auth/milenage_test \
+ >$(srcdir)/auth/milenage_test.ok
+ comp128/comp128_test \
+ >$(srcdir)/comp128/comp128_test.ok
+ lapd/lapd_test \
+ >$(srcdir)/lapd/lapd_test.ok
+ gsm0502/gsm0502_test \
+ >$(srcdir)/gsm0502/gsm0502_test.ok
+ dtx/dtx_gsm0503_test \
+ >$(srcdir)/dtx/dtx_gsm0503_test.ok
+ gsm0808/gsm0808_test \
+ >$(srcdir)/gsm0808/gsm0808_test.ok
+ gsm29205/gsm29205_test \
+ >$(srcdir)/gsm29205/gsm29205_test.ok
+ gsm0408/gsm0408_test \
+ 2>$(srcdir)/gsm0408/gsm0408_test.err \
+ 1>$(srcdir)/gsm0408/gsm0408_test.ok
+ gsm48/rest_octets_test \
+ >$(srcdir)/gsm48/rest_octets_test.ok
+ gprs/gprs_test \
+ >$(srcdir)/gprs/gprs_test.ok
+ logging/logging_test \
+ >$(srcdir)/logging/logging_test.ok \
+ 2>$(srcdir)/logging/logging_test.err
+ codec/codec_test \
+ >$(srcdir)/codec/codec_test.ok
+ codec/codec_ecu_fr_test \
+ >$(srcdir)/codec/codec_ecu_fr_test.ok
+if ENABLE_GB
+ fr/fr_test \
+ >$(srcdir)/fr/fr_test.ok
+endif
+ loggingrb/loggingrb_test \
+ >$(srcdir)/loggingrb/logging_test.ok \
+ 2>$(srcdir)/loggingrb/logging_test.err
+ strrb/strrb_test \
+ >$(srcdir)/strrb/strrb_test.ok
+if ENABLE_VTY
+ cp $(srcdir)/vty/*.cfg .
+ vty/vty_test \
+ >$(srcdir)/vty/vty_test.ok \
+ 2>$(srcdir)/vty/vty_test.err
+endif
+if ENABLE_GB
+ gb/gprs_bssgp_test \
+ >$(srcdir)/gb/gprs_bssgp_test.ok
+ gb/gprs_bssgp_rim_test \
+ >$(srcdir)/gb/gprs_bssgp_rim_test.ok
+ gb/gprs_ns_test \
+ >$(srcdir)/gb/gprs_ns_test.ok
+ gb/gprs_ns2_test \
+ >$(srcdir)/gb/gprs_ns2_test.ok
+endif
+if ENABLE_UTILITIES
+ utils/utils_test \
+ >$(srcdir)/utils/utils_test.ok
+endif
+if !EMBEDDED
+ stats/stats_test \
+ >$(srcdir)/stats/stats_test.ok \
+ 2>$(srcdir)/stats/stats_test.err
+endif
+ write_queue/wqueue_test \
+ >$(srcdir)/write_queue/wqueue_test.ok
+if ENABLE_GB
+ $(srcdir)/gb/bssgp_fc_tests.sh gb \
+ >$(srcdir)/gb/bssgp_fc_tests.ok \
+ 2>$(srcdir)/gb/bssgp_fc_tests.err
+endif
+if ENABLE_PCSC
+ sim/sim_test \
+ >$(srcdir)/sim/sim_test.ok
+endif
+ timer/timer_test \
+ >$(srcdir)/timer/timer_test.ok
+ timer/clk_override_test \
+ >$(srcdir)/timer/clk_override_test.ok
+ tlv/tlv_test \
+ >$(srcdir)/tlv/tlv_test.ok
+ gsup/gsup_test \
+ >$(srcdir)/gsup/gsup_test.ok \
+ 2>$(srcdir)/gsup/gsup_test.err
+if ENABLE_CTRL
+ fsm/fsm_test \
+ >$(srcdir)/fsm/fsm_test.ok \
+ 2>$(srcdir)/fsm/fsm_test.err
+ fsm/fsm_dealloc_test \
+ 2>$(srcdir)/fsm/fsm_dealloc_test.err
+endif
+ oap/oap_test \
+ >$(srcdir)/oap/oap_test.ok
+ oap/oap_client_test \
+ >$(srcdir)/oap/oap_client_test.ok \
+ 2>$(srcdir)/oap/oap_client_test.err
+ socket/socket_test \
+ >$(srcdir)/socket/socket_test.ok \
+ 2>$(srcdir)/socket/socket_test.err
+ socket/socket_sctp_test \
+ >$(srcdir)/socket/socket_sctp_test.ok \
+ 2>$(srcdir)/socket/socket_sctp_test.err
+ $(srcdir)/osmo-auc-gen/osmo-auc-gen_test.sh ../utils/osmo-auc-gen \
+ >$(srcdir)/osmo-auc-gen/osmo-auc-gen_test.ok \
+ 2>$(srcdir)/osmo-auc-gen/osmo-auc-gen_test.err
+ endian/endian_test \
+ >$(srcdir)/endian/endian_test.ok
+ sercomm/sercomm_test \
+ >$(srcdir)/sercomm/sercomm_test.ok
+ prbs/prbs_test \
+ >$(srcdir)/prbs/prbs_test.ok
+ gsm23003/gsm23003_test \
+ >$(srcdir)/gsm23003/gsm23003_test.ok
+ gsm23236/gsm23236_test \
+ >$(srcdir)/gsm23236/gsm23236_test.ok
+ tdef/tdef_test \
+ >$(srcdir)/tdef/tdef_test.ok
+ sockaddr_str/sockaddr_str_test \
+ >$(srcdir)/sockaddr_str/sockaddr_str_test.ok
+ use_count/use_count_test \
+ >$(srcdir)/use_count/use_count_test.ok \
+ 2>$(srcdir)/use_count/use_count_test.err
+ context/context_test \
+ >$(srcdir)/context/context_test.ok
+if !EMBEDDED
+ exec/exec_test \
+ >$(srcdir)/exec/exec_test.ok \
+ 2>$(srcdir)/exec/exec_test.err
+endif
+ i460_mux/i460_mux_test \
+ >$(srcdir)/i460_mux/i460_mux_test.ok
+ bitgen/bitgen_test \
+ >$(srcdir)/bitgen/bitgen_test.ok
+ gad/gad_test \
+ >$(srcdir)/gad/gad_test.ok
+ bsslap/bsslap_test \
+ >$(srcdir)/bsslap/bsslap_test.ok
+ bssmap_le/bssmap_le_test \
+ >$(srcdir)/bssmap_le/bssmap_le_test.ok
+ it_q/it_q_test \
+ >$(srcdir)/it_q/it_q_test.ok
+ time_cc/time_cc_test \
+ >$(srcdir)/time_cc/time_cc_test.ok
+ iuup/iuup_test \
+ >$(srcdir)/iuup/iuup_test.ok
+ v110/test_frame \
+ >$(srcdir)/v110/test_frame.ok
+ v110/test_ra1 \
+ >$(srcdir)/v110/test_ra1.ok
+ gsm44021/test_frame_csd \
+ >$(srcdir)/gsm44021/test_frame_csd.ok
+
check-local: atconfig $(TESTSUITE)
[ -e /proc/cpuinfo ] && cat /proc/cpuinfo
$(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS)
@@ -414,6 +701,15 @@ endif
# pass -u to osmo_verify_transcript_vty.py by doing:
# make vty-test U=-u
+vty-test-ns2:
+ $(MAKE) -C $(top_builddir)/utils osmo-ns-dummy
+ osmo_verify_transcript_vty.py -v \
+ -p 42042 \
+ -r "$(top_builddir)/utils/osmo-ns-dummy -p 42042" \
+ $(U) $(srcdir)/gb/gprs_ns2*.vty
+ osmotestvty.py -p $(abs_top_srcdir)/tests/gb -w $(abs_top_builddir)/tests/gb -v
+ osmotestconfig.py -p $(abs_top_srcdir)/tests/gb -w $(abs_top_builddir)/tests/gb -v
+
vty-test-logging:
osmo_verify_transcript_vty.py -v \
-p 42042 \
@@ -429,22 +725,30 @@ vty-test-vty:
vty-test-tdef:
osmo_verify_transcript_vty.py -v \
-p 42042 \
- -r "$(top_builddir)/tests/tdef/tdef_vty_test_config_root" \
- $(U) $(srcdir)/tdef/tdef_vty_test_config_root.vty
+ -r "$(top_builddir)/tests/tdef/tdef_vty_config_root_test" \
+ $(U) $(srcdir)/tdef/tdef_vty_config_root_test.vty
osmo_verify_transcript_vty.py -v \
-p 42042 \
- -r "$(top_builddir)/tests/tdef/tdef_vty_test_config_subnode" \
- $(U) $(srcdir)/tdef/tdef_vty_test_config_subnode.vty
+ -r "$(top_builddir)/tests/tdef/tdef_vty_config_subnode_test" \
+ $(U) $(srcdir)/tdef/tdef_vty_config_subnode_test.vty
+ osmo_verify_transcript_vty.py -v \
+ -p 42042 \
+ -r "$(top_builddir)/tests/tdef/tdef_vty_dynamic_test" \
+ $(U) $(srcdir)/tdef/tdef_vty_dynamic_test.vty
+
+vty-test-stats:
osmo_verify_transcript_vty.py -v \
-p 42042 \
- -r "$(top_builddir)/tests/tdef/tdef_vty_test_dynamic" \
- $(U) $(srcdir)/tdef/tdef_vty_test_dynamic.vty
+ -r "$(top_builddir)/tests/stats/stats_vty_test" \
+ $(U) $(srcdir)/stats/*.vty
# don't run vty tests concurrently so that the ports don't conflict
vty-test:
$(MAKE) vty-test-logging
$(MAKE) vty-test-vty
$(MAKE) vty-test-tdef
+ $(MAKE) vty-test-ns2
+ $(MAKE) vty-test-stats
ctrl-test:
echo "No CTRL tests exist currently"
diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c
index ca6daed8..563363d3 100644
--- a/tests/abis/abis_test.c
+++ b/tests/abis/abis_test.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/core/application.h>
@@ -171,7 +167,7 @@ static inline void chk_descr(struct msgb *msg, const char *f_id, const char *f_v
}
}
-static void test_sw_descr()
+static void test_sw_descr(void)
{
const char *f_id = "TEST.L0L", *f_ver = "0.1.666~deadbeeffacefeed-dirty";
uint8_t chain[] = { 0x42, 0x12, 0x00, 0x03, 0x01, 0x02, 0x03, 0x13, 0x00, 0x03, 0x03, 0x04, 0x05, 0x42, 0x12,
@@ -197,6 +193,52 @@ static void test_sw_descr()
msgb_free(msg);
}
+/* Test decode IPAC_DLCX_IND obtained from SYS#5915 */
+static void test_dec_ipac_dlc_indx(void)
+{
+/* Radio Signalling Link (RSL)
+ 0111 111. = Message discriminator: ip.access Vendor Specific messages (63)
+ .... ...0 = T bit: Not considered transparent by BTS
+ .111 0110 = Message type: ip.access DLCX INDication (0x76)
+ Channel number IE
+ Element identifier: Channel Number (0x01)
+ 0000 1... = C-bits: Bm + ACCH (1)
+ .... .110 = Time slot number (TN): 6
+ Element identifier: Connection Identifier (0xf8)
+ ip.access Connection ID: 0
+ Element identifier: Connection Statistics (0xf6)
+ [1 byte length here, val = 28 (0x1c)]
+ Packets Sent: 1202
+ Octets Sent: 45052
+ Packets Received: 556
+ Octets Received: 24580
+ Packets Lost: 0
+ Inter-arrival Jitter: 0
+ Average Tx Delay: 0
+ Cause IE
+ Element identifier: Cause (0x1a)
+ Length: 1
+ 0... .... = Extension: No Extension
+ .000 .... = Class: Normal event (0)
+ .000 1111 = Cause Value: normal event, unspecified (15)
+*/
+ const uint8_t hex[] = {
+ 0x7e, 0x76, 0x01, 0x0e, 0xf8, 0x00, 0x00, 0xf6, 0x1c, 0x00, 0x00, 0x04, 0xb2, 0x00, 0x00, 0xaf,
+ 0xfc, 0x00, 0x00, 0x02, 0x2c, 0x00, 0x00, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x01, 0x0f
+ };
+ struct abis_rsl_dchan_hdr *dh = (struct abis_rsl_dchan_hdr *)&hex[0];
+
+ struct tlv_parsed tp;
+ int rc;
+
+ printf("Testing decoding IPAC_DLCX_IND\n");
+
+ rc = rsl_tlv_parse(&tp, dh->data, sizeof(hex) - sizeof(*dh));
+
+ OSMO_ASSERT(rc == 3);
+}
+
int main(int argc, char **argv)
{
void *ctx = talloc_named_const(NULL, 0, "abis_test");
@@ -206,6 +248,7 @@ int main(int argc, char **argv)
test_simple_sw_config();
test_simple_sw_short();
test_dual_sw_config();
+ test_dec_ipac_dlc_indx();
printf("OK.\n");
diff --git a/tests/abis/abis_test.ok b/tests/abis/abis_test.ok
index e6b626be..2ee647bb 100644
--- a/tests/abis/abis_test.ok
+++ b/tests/abis/abis_test.ok
@@ -38,4 +38,5 @@ len: 13
file_id: 09 07 05
file_ver: 06 07 08
test_dual_sw_config(): OK
+Testing decoding IPAC_DLCX_IND
OK.
diff --git a/tests/auth/xor2g_test.c b/tests/auth/xor2g_test.c
new file mode 100644
index 00000000..82ab25ac
--- /dev/null
+++ b/tests/auth/xor2g_test.c
@@ -0,0 +1,77 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include <osmocom/crypt/auth.h>
+#include <osmocom/core/utils.h>
+
+static void dump_auth_vec(struct osmo_auth_vector *vec)
+{
+ printf("RAND:\t%s\n", osmo_hexdump(vec->rand, sizeof(vec->rand)));
+
+ if (vec->auth_types & OSMO_AUTH_TYPE_UMTS) {
+ printf("AUTN:\t%s\n", osmo_hexdump(vec->autn, sizeof(vec->autn)));
+ printf("IK:\t%s\n", osmo_hexdump(vec->ik, sizeof(vec->ik)));
+ printf("CK:\t%s\n", osmo_hexdump(vec->ck, sizeof(vec->ck)));
+ printf("RES:\t%s\n", osmo_hexdump(vec->res, vec->res_len));
+ }
+
+ if (vec->auth_types & OSMO_AUTH_TYPE_GSM) {
+ printf("SRES:\t%s\n", osmo_hexdump(vec->sres, sizeof(vec->sres)));
+ /* According to 3GPP TS 55.205 Sec. 4 the GSM-MILENAGE output is limited to 64 bits.
+ According to 3GPP TS 33.102 Annex. B5 in UMTS security context Kc can be 128 bits.
+ Here we test the former, so make sure we only print interesting Kc bits. */
+ printf("Kc:\t%s\n", osmo_hexdump(vec->kc, OSMO_A5_MAX_KEY_LEN_BYTES/2));
+ }
+}
+
+static struct osmo_sub_auth_data test_aud = {
+ .type = OSMO_AUTH_TYPE_GSM,
+ .algo = OSMO_AUTH_ALG_XOR_2G,
+ .u.gsm = {
+ .ki = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ },
+};
+
+int main(int argc, char **argv)
+{
+ struct osmo_auth_vector _vec;
+ struct osmo_auth_vector *vec = &_vec;
+ uint8_t _rand[16];
+ int rc;
+
+#if 0
+ srand(time(NULL));
+ *(uint32_t *)&_rand[0] = rand();
+ *(uint32_t *)(&_rand[4]) = rand();
+ *(uint32_t *)(&_rand[8]) = rand();
+ *(uint32_t *)(&_rand[12]) = rand();
+#else
+ memset(_rand, 0, sizeof(_rand));
+#endif
+ memset(vec, 0, sizeof(*vec));
+
+ rc = osmo_auth_gen_vec(vec, &test_aud, _rand);
+ if (rc < 0) {
+ fprintf(stderr, "error generating auth vector\n");
+ exit(1);
+ }
+ dump_auth_vec(vec);
+
+ /* test once more with non-zero RAND to see it show in result */
+ for (int i = 0; i < sizeof(_rand); i++)
+ _rand[i] = i << 4;
+
+ rc = osmo_auth_gen_vec(vec, &test_aud, _rand);
+ if (rc < 0) {
+ fprintf(stderr, "error generating auth vector\n");
+ exit(1);
+ }
+ dump_auth_vec(vec);
+
+ exit(0);
+}
diff --git a/tests/auth/xor2g_test.ok b/tests/auth/xor2g_test.ok
new file mode 100644
index 00000000..58becf65
--- /dev/null
+++ b/tests/auth/xor2g_test.ok
@@ -0,0 +1,6 @@
+RAND: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+SRES: 00 01 02 03
+Kc: 04 05 06 07 08 09 0a 0b
+RAND: 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0
+SRES: 00 11 22 33
+Kc: 44 55 66 77 88 99 aa bb
diff --git a/tests/base64/base64_test.c b/tests/base64/base64_test.c
new file mode 100644
index 00000000..79ec212a
--- /dev/null
+++ b/tests/base64/base64_test.c
@@ -0,0 +1,55 @@
+#include <osmocom/core/base64.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static const unsigned char base64_test_dec[64] = {
+ 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
+ 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
+ 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
+ 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
+ 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
+ 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
+ 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
+ 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
+};
+
+static const unsigned char base64_test_enc[] =
+ "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
+ "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
+
+/*
+ * Checkup routine
+ */
+int main(int argc, char **argv)
+{
+ size_t len;
+ const unsigned char *src;
+ unsigned char buffer[128];
+
+ printf(" Base64 encoding test: ");
+
+ src = base64_test_dec;
+
+ if (osmo_base64_encode(buffer, sizeof(buffer), &len, src, 64) != 0 ||
+ memcmp(base64_test_enc, buffer, 88) != 0) {
+ printf("failed\n");
+
+ exit(1);
+ }
+
+ printf("passed\n Base64 decoding test: ");
+
+ src = base64_test_enc;
+
+ if (osmo_base64_decode(buffer, sizeof(buffer), &len, src, 88) != 0 ||
+ memcmp(base64_test_dec, buffer, 64) != 0) {
+ printf("failed\n");
+
+ exit(1);
+ }
+
+ printf("passed\n\n");
+
+ exit(0);
+}
diff --git a/tests/base64/base64_test.ok b/tests/base64/base64_test.ok
new file mode 100644
index 00000000..ff187d9c
--- /dev/null
+++ b/tests/base64/base64_test.ok
@@ -0,0 +1,3 @@
+ Base64 encoding test: passed
+ Base64 decoding test: passed
+
diff --git a/tests/bitgen/bitgen_test.c b/tests/bitgen/bitgen_test.c
index 8657bbef..bd472916 100644
--- a/tests/bitgen/bitgen_test.c
+++ b/tests/bitgen/bitgen_test.c
@@ -14,17 +14,17 @@
for (at_idx = 0; at_idx < len; at_idx++) { \
uint##SIZE##_t read_val = 0; \
memset(buf, 0, sizeof(buf)); \
- osmo_store##SIZE####BE_LE##_ext(val, &buf[at_idx], len); \
+ osmo_store##SIZE##BE_LE##_ext(val, &buf[at_idx], len); \
printf("osmo_store" #SIZE #BE_LE "_ext(0x%" PRIx##SIZE ", &buf[%d], %d) = %s\n", \
val, \
at_idx, len, osmo_hexdump(buf, sizeof(buf))); \
\
- read_val = osmo_load##SIZE####BE_LE##_ext(&buf[at_idx], len); \
+ read_val = osmo_load##SIZE##BE_LE##_ext(&buf[at_idx], len); \
printf("osmo_load" #SIZE #BE_LE "_ext(&buf[%d], %d) = 0x%" PRIx##SIZE "\n", \
at_idx, len, read_val); \
\
if (!strcmp(#BE_LE, "be")) { \
- read_val = osmo_load##SIZE####BE_LE##_ext_2(&buf[at_idx], len); \
+ read_val = osmo_load##SIZE##BE_LE##_ext_2(&buf[at_idx], len); \
printf("osmo_load" #SIZE #BE_LE "_ext_2(&buf[%d], %d) = 0x%" PRIx##SIZE "\n", \
at_idx, len, read_val); \
} \
diff --git a/tests/bitvec/bitvec_test.c b/tests/bitvec/bitvec_test.c
index b4764e68..29c3e33d 100644
--- a/tests/bitvec/bitvec_test.c
+++ b/tests/bitvec/bitvec_test.c
@@ -69,7 +69,7 @@ static inline void test_set(struct bitvec *bv, enum bit_value bit)
printf(" %s [%d]\n\n", lol, bv->cur_bit);
}
-static void test_byte_ops()
+static void test_byte_ops(void)
{
struct bitvec bv;
const uint8_t *in = (const uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
@@ -162,7 +162,7 @@ static inline void test_bitvec_rl_curbit(struct bitvec *bv, bool b, int max_bits
OSMO_ASSERT(num == result);
}
-static void test_array()
+static void test_array(void)
{
struct bitvec b;
uint8_t d[4096];
@@ -181,7 +181,7 @@ static void test_array()
test_array_item(17, &b, n, array, n * 3);
}
-static void test_used_bytes()
+static void test_used_bytes(void)
{
struct bitvec b;
uint8_t d[32];
@@ -204,7 +204,7 @@ static void test_used_bytes()
}
}
-static void test_tailroom()
+static void test_tailroom(void)
{
struct bitvec b;
uint8_t d[32];
@@ -237,7 +237,8 @@ static void test_bitvec_read_field(void)
#define _bitvec_read_field(idx, len) \
readIndex = idx; \
field = bitvec_read_field(&bv, &readIndex, len); \
- printf("bitvec_read_field(idx=%u, len=%u) => %" PRIx64 "\n", idx, len, field);
+ printf("bitvec_read_field(idx=%u, len=%u) => %" PRIx64 " (%s)\n", \
+ idx, len, field, errno == 0 ? "success" : "error");
_bitvec_read_field(0, 64);
_bitvec_read_field(0, 32);
diff --git a/tests/bitvec/bitvec_test.ok b/tests/bitvec/bitvec_test.ok
index b118502e..d87ac7e0 100644
--- a/tests/bitvec/bitvec_test.ok
+++ b/tests/bitvec/bitvec_test.ok
@@ -171,21 +171,21 @@ bitvec_runlength....
bitvec bytes used.
test bitvec_read_field():
-bitvec_read_field(idx=0, len=64) => deadbeeffeebdaed
-bitvec_read_field(idx=0, len=32) => deadbeef
-bitvec_read_field(idx=0, len=16) => dead
-bitvec_read_field(idx=0, len=8) => de
-bitvec_read_field(idx=0, len=0) => 0
-bitvec_read_field(idx=8, len=8) => ad
-bitvec_read_field(idx=8, len=4) => a
-bitvec_read_field(idx=8, len=0) => 0
-bitvec_read_field(idx=10, len=9) => 16d
-bitvec_read_field(idx=10, len=7) => 5b
-bitvec_read_field(idx=10, len=5) => 16
-bitvec_read_field(idx=10, len=3) => 5
-bitvec_read_field(idx=10, len=1) => 1
-bitvec_read_field(idx=512, len=16) => ffffffffffffffea
-bitvec_read_field(idx=0, len=65) => ffffffffffffffea
-bitvec_read_field(idx=64, len=16) => ffffffffffffffea
+bitvec_read_field(idx=0, len=64) => deadbeeffeebdaed (success)
+bitvec_read_field(idx=0, len=32) => deadbeef (success)
+bitvec_read_field(idx=0, len=16) => dead (success)
+bitvec_read_field(idx=0, len=8) => de (success)
+bitvec_read_field(idx=0, len=0) => 0 (success)
+bitvec_read_field(idx=8, len=8) => ad (success)
+bitvec_read_field(idx=8, len=4) => a (success)
+bitvec_read_field(idx=8, len=0) => 0 (success)
+bitvec_read_field(idx=10, len=9) => 16d (success)
+bitvec_read_field(idx=10, len=7) => 5b (success)
+bitvec_read_field(idx=10, len=5) => 16 (success)
+bitvec_read_field(idx=10, len=3) => 5 (success)
+bitvec_read_field(idx=10, len=1) => 1 (success)
+bitvec_read_field(idx=512, len=16) => 0 (error)
+bitvec_read_field(idx=0, len=65) => 0 (error)
+bitvec_read_field(idx=64, len=16) => 0 (error)
bitvec ok.
diff --git a/tests/bsslap/bsslap_test.c b/tests/bsslap/bsslap_test.c
new file mode 100644
index 00000000..fc5ce754
--- /dev/null
+++ b/tests/bsslap/bsslap_test.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/bsslap.h>
+
+struct bsslap_pdu bsslap_test_pdus[] = {
+ {
+ .msg_type = BSSLAP_MSGT_TA_REQUEST,
+ },
+ {
+ .msg_type = BSSLAP_MSGT_TA_RESPONSE,
+ .ta_response = {
+ .cell_id = 23,
+ .ta = 42,
+ },
+ },
+ {
+ .msg_type = BSSLAP_MSGT_REJECT,
+ .reject = BSSLAP_CAUSE_OTHER_RADIO_EVT_FAIL,
+ },
+ {
+ .msg_type = BSSLAP_MSGT_RESET,
+ .reset = {
+ .cell_id = 23,
+ .ta = 42,
+ .chan_desc = {
+ .chan_nr = 23,
+ .h0 = {
+ .tsc = 5,
+ .h = 1,
+ .arfcn_high = 2,
+ .arfcn_low = 3,
+ },
+ },
+ .cause = BSSLAP_CAUSE_INTRA_BSS_HO,
+ },
+ },
+ {
+ .msg_type = BSSLAP_MSGT_ABORT,
+ .abort = BSSLAP_CAUSE_LOSS_SIG_CONN_MS,
+ },
+ {
+ .msg_type = BSSLAP_MSGT_TA_LAYER3,
+ .ta_layer3 = {
+ .ta = 23,
+ },
+ },
+};
+
+void test_bsslap_enc_dec(void)
+{
+ struct bsslap_pdu *pdu;
+ printf("--- %s\n", __func__);
+
+ for (pdu = bsslap_test_pdus; (pdu - bsslap_test_pdus) < ARRAY_SIZE(bsslap_test_pdus); pdu++) {
+ struct msgb *msg = msgb_alloc(1024, __func__);
+ struct bsslap_pdu dec_pdu;
+ struct osmo_bsslap_err *err;
+ int rc;
+ void *loop_ctx = msg;
+ rc = osmo_bsslap_enc(msg, pdu);
+ if (rc <= 0) {
+ printf("[%td] %s: ERROR: failed to encode pdu\n", (pdu - bsslap_test_pdus),
+ osmo_bsslap_msgt_name(pdu->msg_type));
+ goto loop_end;
+ }
+ if (rc != msg->len) {
+ printf("[%td] %s: ERROR: osmo_bsslap_enc() returned length %d but msgb has %d bytes\n",
+ (pdu - bsslap_test_pdus), osmo_bsslap_msgt_name(pdu->msg_type),
+ rc, msg->len);
+ goto loop_end;
+ }
+
+ memset(&dec_pdu, 0xff, sizeof(dec_pdu));
+ rc = osmo_bsslap_dec(&dec_pdu, &err, loop_ctx, msg->data, msg->len);
+ if (rc) {
+ printf("[%td] %s: ERROR: failed to decode pdu: %s\n", (pdu - bsslap_test_pdus),
+ osmo_bsslap_msgt_name(pdu->msg_type), err->logmsg);
+ printf(" encoded data: %s\n", osmo_hexdump(msg->data, msg->len));
+ goto loop_end;
+ }
+
+ if (memcmp(pdu, &dec_pdu, sizeof(dec_pdu))) {
+ printf("[%td] %s: ERROR: decoded PDU != encoded PDU\n", (pdu - bsslap_test_pdus),
+ osmo_bsslap_msgt_name(pdu->msg_type));
+ printf(" original struct: %s\n", osmo_hexdump((void*)pdu, sizeof(*pdu)));
+ printf(" decoded struct: %s\n", osmo_hexdump((void*)&dec_pdu, sizeof(dec_pdu)));
+ goto loop_end;
+ }
+
+ printf("[%td] %s: ok\n", (pdu - bsslap_test_pdus), osmo_bsslap_msgt_name(pdu->msg_type));
+
+loop_end:
+ msgb_free(msg);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ test_bsslap_enc_dec();
+ return 0;
+}
diff --git a/tests/bsslap/bsslap_test.ok b/tests/bsslap/bsslap_test.ok
new file mode 100644
index 00000000..f3199e11
--- /dev/null
+++ b/tests/bsslap/bsslap_test.ok
@@ -0,0 +1,7 @@
+--- test_bsslap_enc_dec
+[0] TA Request: ok
+[1] TA Response: ok
+[2] Reject: ok
+[3] Reset: ok
+[4] Abort: ok
+[5] TA Layer3: ok
diff --git a/tests/bssmap_le/bssmap_le_test.c b/tests/bssmap_le/bssmap_le_test.c
new file mode 100644
index 00000000..a14c38a3
--- /dev/null
+++ b/tests/bssmap_le/bssmap_le_test.c
@@ -0,0 +1,207 @@
+#include <stdio.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/gsm/bssmap_le.h>
+
+struct bssmap_le_pdu bssmap_le_test_pdus[] = {
+ {
+ .msg_type = BSSMAP_LE_MSGT_RESET,
+ .reset = GSM0808_CAUSE_EQUIPMENT_FAILURE,
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_RESET_ACK,
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_PERFORM_LOC_REQ,
+ .perform_loc_req = {
+ .location_type = {
+ .location_information = BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC,
+ },
+
+ .cell_id = {
+ .id_discr = CELL_IDENT_LAC_AND_CI,
+ .id.lac_and_ci = {
+ .lac = 23,
+ .ci = 42,
+ },
+ },
+
+ .lcs_client_type_present = true,
+ .lcs_client_type = BSSMAP_LE_LCS_CTYPE_VALUE_ADDED_UNSPECIFIED,
+
+ .imsi = {
+ .type = GSM_MI_TYPE_IMSI,
+ .imsi = "1234567890",
+ },
+
+ .imei = {
+ .type = GSM_MI_TYPE_IMEI,
+ .imei = "123456789012345",
+ },
+
+ .apdu_present = true,
+ .apdu = {
+ .msg_type = BSSLAP_MSGT_TA_LAYER3,
+ .ta_layer3 = {
+ .ta = 23,
+ },
+ },
+ },
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_PERFORM_LOC_RESP,
+ .perform_loc_resp = {
+ .location_estimate_present = true,
+ .location_estimate = {
+ .ell_point_unc_circle = {
+ .h = { .type = GAD_TYPE_ELL_POINT_UNC_CIRCLE },
+ .lat = { 1, 2, 3 },
+ .lon = { 4, 5, 6 },
+ .unc = 123,
+ },
+ },
+ },
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_PERFORM_LOC_RESP,
+ .perform_loc_resp = {
+ .lcs_cause = {
+ .present = true,
+ .cause_val = LCS_CAUSE_REQUEST_ABORTED,
+ },
+ },
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_PERFORM_LOC_RESP,
+ .perform_loc_resp = {
+ .lcs_cause = {
+ .present = true,
+ .cause_val = LCS_CAUSE_POS_METH_FAILURE,
+ .diag_val_present = true,
+ .diag_val = 23,
+ },
+ },
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_PERFORM_LOC_ABORT,
+ .perform_loc_abort = {
+ .present = true,
+ .cause_val = LCS_CAUSE_REQUEST_ABORTED,
+ },
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_CONN_ORIENTED_INFO,
+ .conn_oriented_info = {
+ .apdu = {
+ .msg_type = BSSLAP_MSGT_TA_REQUEST,
+ },
+ },
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_CONN_ORIENTED_INFO,
+ .conn_oriented_info = {
+ .apdu = {
+ .msg_type = BSSLAP_MSGT_TA_RESPONSE,
+ .ta_response = {
+ .cell_id = 23,
+ .ta = 42,
+ },
+ },
+ },
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_CONN_ORIENTED_INFO,
+ .conn_oriented_info = {
+ .apdu = {
+ .msg_type = BSSLAP_MSGT_REJECT,
+ .reject = BSSLAP_CAUSE_CONGESTION,
+ },
+ },
+ },
+ {
+ .msg_type = BSSMAP_LE_MSGT_PERFORM_LOC_REQ,
+ .perform_loc_req = {
+ .location_type = {
+ .location_information = BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC,
+ },
+
+ .cell_id = {
+ .id_discr = CELL_IDENT_LAC_AND_CI,
+ .id.lac_and_ci = {
+ .lac = 23,
+ .ci = 42,
+ },
+ },
+
+ .lcs_client_type_present = true,
+ .lcs_client_type = BSSMAP_LE_LCS_CTYPE_EMERG_SVC_UNSPECIFIED,
+
+ .more_items = true,
+
+ .lcs_priority_present = true,
+ .lcs_priority = 0x00, /* highest */
+
+ .lcs_qos_present = true,
+ .lcs_qos = {
+ .ha_ind = 1,
+ .ha_val = 0x12,
+ },
+ },
+ },
+};
+
+void test_bssmap_le_enc_dec(void)
+{
+ struct bssmap_le_pdu *pdu;
+ printf("--- %s\n", __func__);
+
+ for (pdu = bssmap_le_test_pdus; (pdu - bssmap_le_test_pdus) < ARRAY_SIZE(bssmap_le_test_pdus); pdu++) {
+ struct msgb *msg;
+ struct bssap_le_pdu enc_pdu = {
+ .discr = BSSAP_LE_MSG_DISCR_BSSMAP_LE,
+ .bssmap_le = *pdu,
+ };
+ struct bssap_le_pdu dec_pdu;
+ struct osmo_bssap_le_err *err = NULL;
+ void *loop_ctx;
+ int rc;
+
+ msg = osmo_bssap_le_enc(&enc_pdu);
+ if (!msg) {
+ printf("[%td] %s: ERROR: failed to encode pdu\n", (pdu - bssmap_le_test_pdus),
+ osmo_bssmap_le_msgt_name(pdu->msg_type));
+ goto loop_end;
+ }
+ loop_ctx = msg;
+
+ memset(&dec_pdu, 0xff, sizeof(dec_pdu));
+ rc = osmo_bssap_le_dec(&dec_pdu, &err, loop_ctx, msg);
+ if (rc) {
+ printf("[%td] %s: ERROR: failed to decode pdu: %s\n", (pdu - bssmap_le_test_pdus),
+ osmo_bssmap_le_msgt_name(pdu->msg_type), err->logmsg);
+ printf(" encoded data: %s\n", osmo_hexdump(msg->data, msg->len));
+ goto loop_end;
+ }
+
+ if (memcmp(&enc_pdu, &dec_pdu, sizeof(dec_pdu))) {
+ printf("[%td] %s: ERROR: decoded PDU != encoded PDU\n", (pdu - bssmap_le_test_pdus),
+ osmo_bssmap_le_msgt_name(pdu->msg_type));
+ printf(" original struct: %s\n", osmo_hexdump((void*)&enc_pdu, sizeof(enc_pdu)));
+ printf(" decoded struct: %s\n", osmo_hexdump((void*)&dec_pdu, sizeof(dec_pdu)));
+ printf(" encoded data: %s\n", osmo_hexdump(msg->data, msg->len));
+ goto loop_end;
+ }
+
+ printf("[%td] %s: ok (encoded len = %d)\n", (pdu - bssmap_le_test_pdus),
+ osmo_bssmap_le_msgt_name(pdu->msg_type), msg->len);
+
+loop_end:
+ msgb_free(msg);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ test_bssmap_le_enc_dec();
+ return 0;
+}
diff --git a/tests/bssmap_le/bssmap_le_test.ok b/tests/bssmap_le/bssmap_le_test.ok
new file mode 100644
index 00000000..8cc77039
--- /dev/null
+++ b/tests/bssmap_le/bssmap_le_test.ok
@@ -0,0 +1,12 @@
+--- test_bssmap_le_enc_dec
+[0] RESET: ok (encoded len = 6)
+[1] RESET ACKNOWLEDGE: ok (encoded len = 3)
+[2] PERFORM LOCATION REQUEST: ok (encoded len = 41)
+[3] PERFORM LOCATION RESPONSE: ok (encoded len = 13)
+[4] PERFORM LOCATION RESPONSE: ok (encoded len = 6)
+[5] PERFORM LOCATION RESPONSE: ok (encoded len = 7)
+[6] PERFORM LOCATION ABORT: ok (encoded len = 6)
+[7] CONNECTION ORIENTED INFORMATON: ok (encoded len = 8)
+[8] CONNECTION ORIENTED INFORMATON: ok (encoded len = 13)
+[9] CONNECTION ORIENTED INFORMATON: ok (encoded len = 10)
+[10] PERFORM LOCATION REQUEST: ok (encoded len = 25)
diff --git a/tests/codec/codec_ecu_fr_test.c b/tests/codec/codec_ecu_fr_test.c
index 4040ce94..a9dae896 100644
--- a/tests/codec/codec_ecu_fr_test.c
+++ b/tests/codec/codec_ecu_fr_test.c
@@ -183,7 +183,7 @@ void test_fr_concealment_core(void)
}
/* Simulate a real life situation: voice frames with a few dropouts */
-void test_fr_concealment_realistic()
+void test_fr_concealment_realistic(void)
{
struct osmo_ecu_fr_state state;
uint8_t frame[GSM_FR_BYTES];
@@ -219,7 +219,7 @@ void test_fr_concealment_realistic()
}
/* Simulate a real life situation: voice frames with a few dropouts, using generic core */
-void test_fr_concealment_realistic_core()
+void test_fr_concealment_realistic_core(void)
{
struct osmo_ecu_state *state = osmo_ecu_init(NULL, OSMO_ECU_CODEC_FR);
uint8_t frame[GSM_FR_BYTES];
diff --git a/tests/coding/coding_test.c b/tests/coding/coding_test.c
index bdfe3002..5a6f6e06 100644
--- a/tests/coding/coding_test.c
+++ b/tests/coding/coding_test.c
@@ -13,10 +13,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
diff --git a/tests/conv/conv_gsm0503_test.ok b/tests/conv/conv_gsm0503_test.ok
index 764bd436..bfefcd0d 100644
--- a/tests/conv/conv_gsm0503_test.ok
+++ b/tests/conv/conv_gsm0503_test.ok
@@ -6,6 +6,38 @@
[..] Encoding / Decoding cycle : OK
[..] Encoding / Decoding cycle : OK
+[+] Testing: gsm0503_tch_f24
+[.] Input length : ret = 72 exp = 72 -> OK
+[.] Output length : ret = 456 exp = 456 -> OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
+[+] Testing: gsm0503_tch_f48
+[.] Input length : ret = 152 exp = 152 -> OK
+[.] Output length : ret = 468 exp = 468 -> OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
+[+] Testing: gsm0503_tch_f96
+[.] Input length : ret = 240 exp = 240 -> OK
+[.] Output length : ret = 456 exp = 456 -> OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
+[+] Testing: gsm0503_tch_f144
+[.] Input length : ret = 290 exp = 290 -> OK
+[.] Output length : ret = 456 exp = 456 -> OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
[+] Testing: gsm0503_rach
[.] Input length : ret = 14 exp = 14 -> OK
[.] Output length : ret = 36 exp = 36 -> OK
diff --git a/tests/ctrl/ctrl_test.c b/tests/ctrl/ctrl_test.c
index b46e9ac5..1d4d4d74 100644
--- a/tests/ctrl/ctrl_test.c
+++ b/tests/ctrl/ctrl_test.c
@@ -117,11 +117,14 @@ static void assert_test(struct ctrl_handle *ctrl, struct ctrl_connection *ccon,
} else {
struct msgb *sent_msg = msgb_dequeue(&ccon->write_queue.msg_queue);
OSMO_ASSERT(sent_msg);
- msgb_put_u8(sent_msg, 0);
- printf("replied: '%s'\n", osmo_escape_str((char*)msgb_l2(sent_msg), -1));
+ char *strbuf = talloc_size(sent_msg, msgb_l2len(sent_msg) + 1);
+ memcpy(strbuf, msgb_l2(sent_msg), msgb_l2len(sent_msg));
+ strbuf[msgb_l2len(sent_msg)] = '\0';
+
+ printf("replied: '%s'\n", osmo_escape_str(strbuf, -1));
OSMO_ASSERT(t->reply_str);
- OSMO_ASSERT(!strcmp(t->reply_str, (char*)msgb_l2(sent_msg)));
+ OSMO_ASSERT(!strcmp(t->reply_str, strbuf));
msgb_free(sent_msg);
}
osmo_wqueue_clear(&ccon->write_queue);
@@ -331,7 +334,7 @@ static const struct one_test test_messages_list[] = {
},
};
-static void test_messages()
+static void test_messages(void)
{
struct ctrl_handle *ctrl;
struct ctrl_connection *ccon;
@@ -387,7 +390,7 @@ static int verify_test_defer(struct ctrl_cmd *cmd, const char *value, void *data
return 0;
}
-static void test_deferred_cmd()
+static void test_deferred_cmd(void)
{
struct ctrl_handle *ctrl;
struct ctrl_connection *ccon;
diff --git a/tests/dtx/dtx_gsm0503_test.c b/tests/dtx/dtx_gsm0503_test.c
index f3003133..21d1751e 100644
--- a/tests/dtx/dtx_gsm0503_test.c
+++ b/tests/dtx/dtx_gsm0503_test.c
@@ -15,18 +15,18 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <osmocom/core/utils.h>
+#include <osmocom/coding/gsm0503_coding.h>
#include <osmocom/coding/gsm0503_amr_dtx.h>
+/* Length of payload bits in a Normal Burst */
+#define BURST_PLEN (57 * 2 + 2)
+
char sample_afs_sid_frame[] =
{
"111111110000000011001100101010100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001"
@@ -72,7 +72,7 @@ char sample_sid_update_inh_frame[] =
"xBxBxBxBxBxBxBxBxBxBxBxBxBxBxBxBx0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1"
};
-unsigned int string_to_ubit(ubit_t * ubits, char *string)
+unsigned int string_to_sbit(sbit_t *sbits, char *string)
{
unsigned int len;
unsigned int i;
@@ -80,7 +80,7 @@ unsigned int string_to_ubit(ubit_t * ubits, char *string)
len = strlen(string);
for (i = 0; i < len; i++) {
- ubits[i] = string[i] & 1;
+ sbits[i] = string[i] == '1' ? -127 : 127;
}
return len;
@@ -88,28 +88,161 @@ unsigned int string_to_ubit(ubit_t * ubits, char *string)
void test_gsm0503_detect_afs_dtx_frame(char *string)
{
- ubit_t ubits[512];
+ sbit_t sbits[512];
uint8_t dtx_frame_type;
int n_errors;
int n_bits_total;
+ int mode_id = -1;
- string_to_ubit(ubits, string);
- dtx_frame_type = gsm0503_detect_afs_dtx_frame(&n_errors, &n_bits_total, ubits);
- printf(" ==> %s, n_errors=%i, n_bits_total=%i\n", gsm0503_amr_dtx_frame_name(dtx_frame_type),
- n_errors, n_bits_total);
+ string_to_sbit(sbits, string);
+ dtx_frame_type = gsm0503_detect_afs_dtx_frame2(&n_errors, &n_bits_total, &mode_id, sbits);
+ printf(" ==> %s, n_errors=%d, n_bits_total=%d, mode_id=%d\n",
+ gsm0503_amr_dtx_frame_name(dtx_frame_type),
+ n_errors, n_bits_total, mode_id);
}
void test_gsm0503_detect_ahs_dtx_frame(char *string)
{
- ubit_t ubits[512];
+ sbit_t sbits[512];
uint8_t dtx_frame_type;
int n_errors;
int n_bits_total;
+ int mode_id = -1;
+
+ string_to_sbit(sbits, string);
+ dtx_frame_type = gsm0503_detect_ahs_dtx_frame2(&n_errors, &n_bits_total, &mode_id, sbits);
+ printf(" ==> %s, n_errors=%d, n_bits_total=%d, mode_id=%d\n",
+ gsm0503_amr_dtx_frame_name(dtx_frame_type),
+ n_errors, n_bits_total, mode_id);
+}
+
+static void test_gsm0503_tch_afhs_decode_dtx(const sbit_t *bursts, size_t offset,
+ enum gsm0503_amr_dtx_frames *amr_last_dtx,
+ bool full_rate, const char *test_desc)
+{
+ uint8_t tch_data[128]; /* just to be safe */
+ int n_errors = 0, n_bits_total = 0;
+ int rc;
+
+ printf("Running %s(at offset=%zu): testing %s\n", __func__, offset, test_desc);
+
+ /* Dummy (not really important) values */
+ uint8_t codec[4] = { 0, 1, 2, 3 };
+ int codecs = ARRAY_SIZE(codec);
+ uint8_t ul_cmr = 0;
+ uint8_t ul_ft = 0;
+
+ if (full_rate) {
+ rc = gsm0503_tch_afs_decode_dtx(&tch_data[0], &bursts[offset], false,
+ codec, codecs, &ul_ft, &ul_cmr,
+ &n_errors, &n_bits_total,
+ (uint8_t *)amr_last_dtx);
+ } else {
+ rc = gsm0503_tch_ahs_decode_dtx(&tch_data[0], &bursts[offset], false, false,
+ codec, codecs, &ul_ft, &ul_cmr,
+ &n_errors, &n_bits_total,
+ (uint8_t *)amr_last_dtx);
+ }
+ printf(" ==> gsm0503_tch_a%cs_decode_dtx() yields '%s' (rc=%d, BER %d/%d)\n",
+ full_rate ? 'f' : 'h', gsm0503_amr_dtx_frame_name(*amr_last_dtx),
+ rc, n_errors, n_bits_total);
+ if (rc > 0)
+ printf(" ====> tch_data[] = { %s }\n", osmo_hexdump_nospc(tch_data, rc));
+}
+
+static void test_gsm0503_tch_afhs_decode_dtx_sid_update(void)
+{
+ enum gsm0503_amr_dtx_frames amr_last_dtx = AMR_OTHER;
+ sbit_t bursts[BURST_PLEN * 12]; /* 12 bursts */
+ int rc;
+
+ /* 456 soft-bits containing an AFS_SID_UPDATE frame (captured on the air) */
+ const char *afs_sid_update = \
+ "94 81 83 76 7b 81 6b 7f 76 8c 81 81 81 86 71 7f 75 81 6d 7a 81 6b 7f 78 8a 87 70 75 8e"
+ "81 8d 7f 81 70 72 81 7f 85 86 7f 93 81 8a 74 7f 71 89 8a 75 7f 7f 78 8c 81 8b 7f 81 7f"
+ "7f 7f 70 8a 8b 7f 90 81 81 81 8a 77 7f 7f 70 81 70 71 86 8e 7f 81 7f 81 75 72 87 8c 76"
+ "7f 72 8e 81 81 81 81 92 7f 8c 81 92 7f 8c 89 7f 81 7f 8f 8b 77 76 86 8c 78 73 88 81 8b"
+ "81 7f 8c 85 77 7b 8d 81 81 81 8b 7f 81 7f 8e 81 8e 7f 8a 8a 7f 93 85 6b 7f 7f 72 81 6f"
+ "76 89 81 81 81 8a 73 7f 72 88 87 73 7f 73 81 7f 81 7f 92 87 73 78 81 6f 7f 71 81 76 77"
+ "6f 81 7f 81 71 7f 6e 81 75 77 83 81 81 90 7f 8b 88 76 76 8a 8d 76 74 81 7f 92 81 81 8b"
+ "78 72 81 77 76 81 6c 7c 8b 81 81 8d 7f 8b 81 8e 74 7f 7f 72 81 7f 81 74 7f 71 81 75 7f"
+ "8e 81 81 8c 72 79 85 8c 78 75 8c 8a 7f 90 81 8e 77 77 81 70 7f 7f 71 81 7f 81 7f 8e 89"
+ "7f 8f 81 8f 7f 8c 8d 7f 81 7f 81 6f 7f 71 8a 87 7f 81 6f 77 81 7f 8d 88 73 79 8a 8a 7f"
+ "7f 7f 7f 7f 76 8b 81 8c 77 7c 8a 81 91 7f 81 76 79 81 71 7f 7f 6f 84 8e 78 7f 7f 7f 74"
+ "88 86 7b 77 81 6f 7f 7f 7f 7f 7f 75 81 70 7f 76 89 81 81 81 8d 78 74 84 81 8e 7f 8d 8a"
+ "7f 79 8c 87 7f 81 7f 81 6f 7f 75 8d 8a 7f 81 7f 92 81 81 85 76 7f 6f 8c 88 6c 7f 73 91"
+ "81 8d 71 7f 7f 73 8d 88 7f 81 7f 91 86 6f 7f 73 8e 81 8d 79 78 81 72 74 8c 86 72 7f 77"
+ "6e 81 7f 81 77 76 81 72 74 81 6f 7f 6f 8d 81 91 7f 81 6d 7f 6d 81 6c 7f 6c 81 7f 81 7f"
+ "8c 8b 7f 8e 89 74 74 8c 81 81 81 81 81 92 7f 8e 8b 7f 93 81 8f 7f 90 81 8d 74 7b 8b 89";
- string_to_ubit(ubits, string);
- dtx_frame_type = gsm0503_detect_ahs_dtx_frame(&n_errors, &n_bits_total, ubits);
- printf(" ==> %s, n_errors=%i, n_bits_total=%i\n", gsm0503_amr_dtx_frame_name(dtx_frame_type),
- n_errors, n_bits_total);
+ memset(&bursts[0], 0, sizeof(bursts));
+ rc = osmo_hexparse(afs_sid_update, (uint8_t *)&bursts[BURST_PLEN * 4], BURST_PLEN * 8);
+ OSMO_ASSERT(rc == BURST_PLEN * 4);
+
+ /* Test detection of AFS_SID_UPDATE (marker) */
+ test_gsm0503_tch_afhs_decode_dtx(&bursts[0], BURST_PLEN * 0, &amr_last_dtx, true /* AFS */,
+ "detection of AFS_SID_UPDATE");
+
+ /* Test decoding of AFS_SID_UPDATE_CN (actual SID) */
+ test_gsm0503_tch_afhs_decode_dtx(&bursts[0], BURST_PLEN * 4, &amr_last_dtx, true /* AFS */,
+ "decoding of AFS_SID_UPDATE");
+
+ /* 456 soft-bits containing an AHS_SID_UPDATE frame (captured on the air) */
+ const char *ahs_sid_update = \
+ "81 67 7f 7f 7f 71 8f 88 6f 73 81 7e 81 6b 7f 7e 7d 6f 8f 8a 72 76 92 81 82 81 8f 6d 6f"
+ "81 7f 92 8c 7f 97 81 8e 6f 7f 7c 7f 6e 81 7e 81 6e 73 81 7f 93 8d 6f 7f 6c 81 6b 7f 72"
+ "7c 7c 7d 7f 6f 8f 81 94 7f 92 8d 6e 7d 7d 7f 6c 8b 8e 73 71 81 7f 92 90 7f 81 6e 6e 81"
+ "7f 94 8e 70 7f 6e 8c 8d 77 7f 6a 81 7f 81 70 6d 81 6c 71 8c 91 7f 90 8e 73 6e 81 6d 7f"
+ "81 8b 71 6e 81 7f 82 7c 81 7f 81 6d 73 81 6c 6d 81 6d 7f 6e 81 7e 81 6b 7f 7f 7f 6b 81"
+ "6e 6f 81 68 7f 71 91 81 82 81 8e 70 7f 7c 7d 7f 70 81 7f 91 8f 7f 81 6c 7f 71 81 6d 74"
+ "6f 8f 81 92 7f 82 7f 91 8b 7f 81 6b 7f 6d 81 6b 6f 81 6f 6e 90 81 81 92 7f 94 81 95 7f"
+ "96 81 96 70 7f 72 8f 81 95 7f 81 6f 70 81 7f 90 92 7f 81 6c 70 81 6b 7f 6f 8d 8d 7f 81"
+ "77 81 6a 7e 7e 73 92 8c 7f 81 6a 7f 6c 8e 8e 6e 7f 71 8e 8d 7e 81 6d 7f 6c 81 6d 6c 81"
+ "7f 94 81 92 7f 97 81 92 6e 7f 70 8c 8b 73 73 91 81 93 7f 81 70 72 81 7d 81 71 70 81 7f"
+ "7d 7f 6d 90 8d 73 76 92 81 92 6f 7d 7d 70 91 81 8f 73 75 8c 90 7f 94 81 91 70 7f 7d 7e"
+ "70 8d 8d 73 7f 7c 7e 6a 81 7e 81 6d 7f 6a 81 6f 7f 7f 71 8e 81 82 81 81 81 96 72 7e 7d"
+ "81 8d 7f 81 68 7f 7e 7c 7b 7f 6c 81 6a 7f 7f 71 8f 8d 7f 81 6c 72 8e 88 70 70 81 6d 70"
+ "8d 90 7f 81 7e 95 81 94 7f 92 8b 6e 7f 7f 70 8c 8c 73 75 91 81 91 6d 7d 7e 7b 7c 7d 71"
+ "6c 89 91 7f 81 7f 95 81 93 7f 95 90 7f 81 6d 70 81 6f 75 8c 8e 75 71 81 6e 70 8d 8d 7f"
+ "91 92 7f 81 7f 94 8d 70 71 81 6e 6d 81 6e 75 8e 81 93 70 7f 70 8f 8c 7f 81 6d 6f 81 6a";
+
+ memset(&bursts[0], 0, sizeof(bursts));
+ rc = osmo_hexparse(ahs_sid_update, (uint8_t *)&bursts[BURST_PLEN * 2], BURST_PLEN * 10);
+ OSMO_ASSERT(rc == BURST_PLEN * 4);
+
+ /* Test detection and decoding of AHS_SID_UPDATE */
+ test_gsm0503_tch_afhs_decode_dtx(&bursts[0], BURST_PLEN * 0, &amr_last_dtx, false /* AHS */,
+ "detection/decoding of AHS_SID_UPDATE");
+ test_gsm0503_tch_afhs_decode_dtx(&bursts[0], BURST_PLEN * 2, &amr_last_dtx, false /* AHS */,
+ "detection/decoding of AHS_SID_UPDATE");
+ test_gsm0503_tch_afhs_decode_dtx(&bursts[0], BURST_PLEN * 4, &amr_last_dtx, false /* AHS */,
+ "detection/decoding of AHS_SID_UPDATE");
+}
+
+static void test_gsm0503_tch_afhs_decode_dtx_facch(void)
+{
+ enum gsm0503_amr_dtx_frames amr_last_dtx;
+ sbit_t bursts[BURST_PLEN * 8]; /* 8 bursts */
+ unsigned int i;
+
+ /* Set stealing bits to provoke FACCH/[FH] detection */
+ for (i = 0; i < 8; i++) {
+ sbit_t *burst = &bursts[BURST_PLEN * i];
+ memset(&burst[0], 0, BURST_PLEN);
+ burst[i >> 2 ? 57 : 58] = -127;
+ }
+
+ amr_last_dtx = AFS_SID_UPDATE;
+ test_gsm0503_tch_afhs_decode_dtx(&bursts[0], BURST_PLEN * 0,
+ &amr_last_dtx, true /* AFS */,
+ "tagging of FACCH/F");
+ OSMO_ASSERT(amr_last_dtx == AMR_OTHER);
+
+ amr_last_dtx = AHS_SID_UPDATE;
+ test_gsm0503_tch_afhs_decode_dtx(&bursts[0], BURST_PLEN * 0,
+ &amr_last_dtx, false /* AHS */,
+ "tagging of FACCH/H");
+ OSMO_ASSERT(amr_last_dtx == AMR_OTHER);
}
int main(int argc, char **argv)
@@ -126,5 +259,8 @@ int main(int argc, char **argv)
test_gsm0503_detect_ahs_dtx_frame(sample_sid_first_inh_frame);
test_gsm0503_detect_ahs_dtx_frame(sample_sid_update_inh_frame);
+ test_gsm0503_tch_afhs_decode_dtx_sid_update();
+ test_gsm0503_tch_afhs_decode_dtx_facch();
+
return EXIT_SUCCESS;
}
diff --git a/tests/dtx/dtx_gsm0503_test.ok b/tests/dtx/dtx_gsm0503_test.ok
index 77a49360..477d4312 100644
--- a/tests/dtx/dtx_gsm0503_test.ok
+++ b/tests/dtx/dtx_gsm0503_test.ok
@@ -1,11 +1,27 @@
FR AMR DTX FRAMES:
- ==> AFS_SID_FIRST, n_errors=0, n_bits_total=212
- ==> AFS_SID_UPDATE (marker), n_errors=0, n_bits_total=212
- ==> AFS_ONSET, n_errors=0, n_bits_total=228
+ ==> AFS_SID_FIRST, n_errors=0, n_bits_total=212, mode_id=-1
+ ==> AFS_SID_UPDATE (marker), n_errors=0, n_bits_total=212, mode_id=-1
+ ==> AFS_ONSET, n_errors=0, n_bits_total=228, mode_id=0
HR AMR DTX FRAMES:
- ==> AHS_SID_UPDATE (marker), n_errors=0, n_bits_total=212
- ==> AHS_SID_FIRST_P1, n_errors=0, n_bits_total=212
- ==> AHS_SID_FIRST_P2, n_errors=0, n_bits_total=114
- ==> AHS_ONSET, n_errors=0, n_bits_total=114
- ==> AHS_SID_FIRST_INH, n_errors=0, n_bits_total=212
- ==> AHS_SID_UPDATE_INH, n_errors=0, n_bits_total=212
+ ==> AHS_SID_UPDATE (marker), n_errors=0, n_bits_total=212, mode_id=-1
+ ==> AHS_SID_FIRST_P1, n_errors=0, n_bits_total=212, mode_id=-1
+ ==> AHS_SID_FIRST_P2, n_errors=0, n_bits_total=114, mode_id=0
+ ==> AHS_ONSET, n_errors=0, n_bits_total=114, mode_id=0
+ ==> AHS_SID_FIRST_INH, n_errors=0, n_bits_total=212, mode_id=-1
+ ==> AHS_SID_UPDATE_INH, n_errors=0, n_bits_total=212, mode_id=-1
+Running test_gsm0503_tch_afhs_decode_dtx(at offset=0): testing detection of AFS_SID_UPDATE
+ ==> gsm0503_tch_afs_decode_dtx() yields 'AFS_SID_UPDATE (marker)' (rc=0, BER 0/212)
+Running test_gsm0503_tch_afhs_decode_dtx(at offset=464): testing decoding of AFS_SID_UPDATE
+ ==> gsm0503_tch_afs_decode_dtx() yields 'AFS_SID_UPDATE_CN (audio)' (rc=5, BER 0/212)
+ ====> tch_data[] = { 26e9b1d2b0 }
+Running test_gsm0503_tch_afhs_decode_dtx(at offset=0): testing detection/decoding of AHS_SID_UPDATE
+ ==> gsm0503_tch_ahs_decode_dtx() yields 'AMR_OTHER (audio)' (rc=-1, BER 109/212)
+Running test_gsm0503_tch_afhs_decode_dtx(at offset=232): testing detection/decoding of AHS_SID_UPDATE
+ ==> gsm0503_tch_ahs_decode_dtx() yields 'AHS_SID_UPDATE_CN (audio)' (rc=5, BER 0/424)
+ ====> tch_data[] = { 6003ccb270 }
+Running test_gsm0503_tch_afhs_decode_dtx(at offset=464): testing detection/decoding of AHS_SID_UPDATE
+ ==> gsm0503_tch_ahs_decode_dtx() yields 'AMR_OTHER (audio)' (rc=-1, BER 111/212)
+Running test_gsm0503_tch_afhs_decode_dtx(at offset=0): testing tagging of FACCH/F
+ ==> gsm0503_tch_afs_decode_dtx() yields 'AMR_OTHER (audio)' (rc=-1, BER 456/456)
+Running test_gsm0503_tch_afhs_decode_dtx(at offset=0): testing tagging of FACCH/H
+ ==> gsm0503_tch_ahs_decode_dtx() yields 'AMR_OTHER (audio)' (rc=-1, BER 456/456)
diff --git a/tests/fr/fr_test.c b/tests/fr/fr_test.c
index 4d472b55..cdcdb434 100644
--- a/tests/fr/fr_test.c
+++ b/tests/fr/fr_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#define _GNU_SOURCE
@@ -56,7 +52,7 @@ int socket(int domain, int type, int protocol)
return fd;
}
-void bssgp_prim_cb()
+void bssgp_prim_cb(void)
{
}
diff --git a/tests/fsm/fsm_dealloc_test.c b/tests/fsm/fsm_dealloc_test.c
index 48f80e57..246ba563 100644
--- a/tests/fsm/fsm_dealloc_test.c
+++ b/tests/fsm/fsm_dealloc_test.c
@@ -290,7 +290,7 @@ void obj_set_other(struct obj *a, struct obj *b)
obj_add_other(b, a);
}
-static struct scene *scene_alloc()
+static struct scene *scene_alloc(void)
{
struct scene *s = talloc_zero(ctx, struct scene);
s->use_count.talloc_object = s;
@@ -419,7 +419,7 @@ static void trigger_tests(void *loop_ctx)
}
}
-void test_osmo_fsm_term_safely()
+void test_osmo_fsm_term_safely(void)
{
fprintf(stderr, "\n\n%s()\n", __func__);
osmo_fsm_term_safely(true);
@@ -428,7 +428,7 @@ void test_osmo_fsm_term_safely()
fprintf(stderr, "\n\n%s() done\n", __func__);
}
-void test_osmo_fsm_set_dealloc_ctx()
+void test_osmo_fsm_set_dealloc_ctx(void)
{
fprintf(stderr, "\n\n%s()\n", __func__);
void *dealloc_ctx = talloc_named_const(ctx, 0, "fsm_dealloc");
@@ -443,7 +443,7 @@ int main(void)
ctx = talloc_named_const(NULL, 0, "main");
osmo_init_logging2(ctx, NULL);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
log_set_print_level(osmo_stderr_target, 1);
log_set_print_category(osmo_stderr_target, 1);
log_set_print_category_hex(osmo_stderr_target, 0);
diff --git a/tests/fsm/fsm_test.c b/tests/fsm/fsm_test.c
index fe48b2ba..960042c7 100644
--- a/tests/fsm/fsm_test.c
+++ b/tests/fsm/fsm_test.c
@@ -172,7 +172,7 @@ static struct osmo_fsm_inst *foo(void)
return fi;
}
-static void test_id_api()
+static void test_id_api(void)
{
struct osmo_fsm_inst *fi;
@@ -280,7 +280,7 @@ const struct timeval fake_time_start_time = { 123, 456 };
osmo_timers_update(); \
} while (0)
-void fake_time_start()
+void fake_time_start(void)
{
struct timespec *clock_override;
@@ -301,7 +301,7 @@ static int timer_cb(struct osmo_fsm_inst *fi)
return 0;
}
-static void test_state_chg_keep_timer()
+static void test_state_chg_keep_timer(void)
{
struct osmo_fsm_inst *fi;
@@ -349,7 +349,7 @@ static void test_state_chg_keep_timer()
fprintf(stderr, "--- %s() done\n", __func__);
}
-static void test_state_chg_T()
+static void test_state_chg_T(void)
{
struct osmo_fsm_inst *fi;
@@ -386,6 +386,74 @@ static void test_state_chg_T()
fprintf(stderr, "--- %s() done\n", __func__);
}
+/* Test setting a state timeout with second granularity */
+static void test_state_chg_Ts(void)
+{
+ struct osmo_fsm_inst *fi;
+
+ fprintf(stderr, "\n--- %s()\n", __func__);
+
+ fsm.timer_cb = &timer_cb;
+ timeout_fired = -1;
+ fake_time_start();
+
+ fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
+ OSMO_ASSERT(fi);
+
+ osmo_fsm_inst_state_chg(fi, ST_ONE, 8, 4242);
+ OSMO_ASSERT(timeout_fired == -1);
+
+ fake_time_passes(3, 0); /* +3s */
+ OSMO_ASSERT(timeout_fired == -1);
+
+ fake_time_passes(2, 500000); /* +2.5s */
+ OSMO_ASSERT(timeout_fired == -1);
+
+ fake_time_passes(2, 500000); /* +2.5s */
+ OSMO_ASSERT(timeout_fired == 4242);
+
+ osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
+
+ fprintf(stderr, "--- %s() done\n", __func__);
+}
+
+/* Test setting a state timeout with millisecond granularity */
+static void test_state_chg_Tms(void)
+{
+ struct osmo_fsm_inst *fi;
+
+ fprintf(stderr, "\n--- %s()\n", __func__);
+
+ fsm.timer_cb = &timer_cb;
+ timeout_fired = -1;
+ fake_time_start();
+
+ fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
+ OSMO_ASSERT(fi);
+
+ osmo_fsm_inst_state_chg_ms(fi, ST_ONE, 1337, 4242); /* 1s 337ms */
+ OSMO_ASSERT(timeout_fired == -1);
+
+ fake_time_passes(0, 500000); /* +500ms, 500ms total */
+ OSMO_ASSERT(timeout_fired == -1);
+
+ fake_time_passes(0, 250000); /* +250ms, 750ms total */
+ OSMO_ASSERT(timeout_fired == -1);
+
+ fake_time_passes(0, 350000); /* +350ms, 1s 100ms total */
+ OSMO_ASSERT(timeout_fired == -1);
+
+ fake_time_passes(0, 200000); /* +200ms, 1s 300ms total */
+ OSMO_ASSERT(timeout_fired == -1);
+
+ fake_time_passes(0, 37000); /* +37ms, 1s 337ms total */
+ OSMO_ASSERT(timeout_fired == 4242);
+
+ osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
+
+ fprintf(stderr, "--- %s() done\n", __func__);
+}
+
static const struct log_info_cat default_categories[] = {
[DMAIN] = {
.name = "DMAIN",
@@ -412,8 +480,10 @@ int main(int argc, char **argv)
log_init(&log_info, NULL);
stderr_target = log_target_create_stderr();
log_add_target(stderr_target);
- log_set_print_filename(stderr_target, 0);
+ log_set_print_filename2(stderr_target, LOG_FILENAME_NONE);
log_set_use_color(stderr_target, 0);
+ log_set_print_category(stderr_target, 0);
+ log_set_print_category_hex(stderr_target, 0);
g_ctrl = ctrl_handle_alloc(NULL, NULL, NULL);
g_ctx = NULL;
@@ -432,6 +502,8 @@ int main(int argc, char **argv)
test_id_api();
test_state_chg_keep_timer();
test_state_chg_T();
+ test_state_chg_Ts();
+ test_state_chg_Tms();
osmo_fsm_unregister(&fsm);
exit(0);
diff --git a/tests/fsm/fsm_test.err b/tests/fsm/fsm_test.err
index 4cc5ca40..51bf5da3 100644
--- a/tests/fsm/fsm_test.err
+++ b/tests/fsm/fsm_test.err
@@ -116,3 +116,31 @@ Test_FSM{TWO}: Terminating (cause = OSMO_FSM_TERM_REQUEST)
Test_FSM{TWO}: Freeing instance
Test_FSM{TWO}: Deallocated
--- test_state_chg_T() done
+
+--- test_state_chg_Ts()
+Total time passed: 0.000000 s
+Test_FSM{NULL}: Allocated
+Test_FSM{NULL}: State change to ONE (T4242, 8s)
+Total time passed: 3.000000 s
+Total time passed: 5.500000 s
+Total time passed: 8.000000 s
+Test_FSM{ONE}: Timeout of T4242
+Test_FSM{ONE}: Terminating (cause = OSMO_FSM_TERM_REQUEST)
+Test_FSM{ONE}: Freeing instance
+Test_FSM{ONE}: Deallocated
+--- test_state_chg_Ts() done
+
+--- test_state_chg_Tms()
+Total time passed: 0.000000 s
+Test_FSM{NULL}: Allocated
+Test_FSM{NULL}: State change to ONE (T4242, 1337ms)
+Total time passed: 0.500000 s
+Total time passed: 0.750000 s
+Total time passed: 1.100000 s
+Total time passed: 1.300000 s
+Total time passed: 1.337000 s
+Test_FSM{ONE}: Timeout of T4242
+Test_FSM{ONE}: Terminating (cause = OSMO_FSM_TERM_REQUEST)
+Test_FSM{ONE}: Freeing instance
+Test_FSM{ONE}: Deallocated
+--- test_state_chg_Tms() done
diff --git a/tests/gad/gad_test.c b/tests/gad/gad_test.c
new file mode 100644
index 00000000..19be6a61
--- /dev/null
+++ b/tests/gad/gad_test.c
@@ -0,0 +1,143 @@
+#include <stdio.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/gad.h>
+
+void test_gad_lat_lon_dec_enc_stability(void)
+{
+ uint32_t lat_enc;
+ uint32_t lon_enc;
+ printf("--- %s\n", __func__);
+ for (lat_enc = 0x0; lat_enc <= 0xffffff; lat_enc++) {
+ int32_t lat_dec = osmo_gad_dec_lat(lat_enc);
+ uint32_t enc2 = osmo_gad_enc_lat(lat_dec);
+ uint32_t want_enc = lat_enc;
+ /* "-0" == 0, because the highest bit is defined as a sign bit. */
+ if (lat_enc == 0x800000)
+ want_enc = 0;
+ if (enc2 != want_enc) {
+ printf("ERR: lat=%u --> %d --> %u\n", lat_enc, lat_dec, enc2);
+ printf("%d -> %u\n", lat_dec + 1, osmo_gad_enc_lat(lat_dec + 1));
+ OSMO_ASSERT(false);
+ }
+ }
+ printf("osmo_gad_dec_lat() -> osmo_gad_enc_lat() of %u values successful\n", lat_enc);
+ for (lon_enc = 0; lon_enc <= 0xffffff; lon_enc++) {
+ int32_t lon_dec = osmo_gad_dec_lon(lon_enc);
+ uint32_t enc2 = osmo_gad_enc_lon(lon_dec);
+ uint32_t want_enc = lon_enc;
+ if (enc2 != want_enc) {
+ printf("ERR: lon=%u 0x%x --> %d --> %u\n", lon_enc, lon_enc, lon_dec, enc2);
+ printf("%d -> %u\n", lon_dec + 1, osmo_gad_enc_lon(lon_dec + 1));
+ printf("%d -> %u\n", lon_dec - 1, osmo_gad_enc_lon(lon_dec - 1));
+ OSMO_ASSERT(false);
+ }
+ }
+ printf("osmo_gad_dec_lon() -> osmo_gad_enc_lon() of %u values successful\n", lon_enc);
+}
+
+struct osmo_gad gad_test_values[] = {
+ {
+ .type = GAD_TYPE_ELL_POINT_UNC_CIRCLE,
+ .ell_point_unc_circle = {
+ /* Values rounded to the nearest encodable value, for test result matching */
+ .lat = 23000006,
+ .lon = 42000002,
+ .unc = 442592,
+ },
+ },
+};
+
+void test_gad_enc_dec(void)
+{
+ int i;
+ printf("--- %s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(gad_test_values); i++) {
+ struct osmo_gad *t = &gad_test_values[i];
+ struct msgb *msg = msgb_alloc(1024, __func__);
+ union gad_raw raw_write;
+ union gad_raw raw_read;
+ struct osmo_gad dec_pdu;
+ int rc;
+ struct osmo_gad_err *err;
+ void *loop_ctx = msg;
+ rc = osmo_gad_enc(&raw_write, t);
+ if (rc <= 0) {
+ printf("[%d] %s: ERROR: osmo_gad_enc() failed\n", i, osmo_gad_type_name(t->type));
+ goto loop_end;
+ }
+ rc = osmo_gad_raw_write(msg, &raw_write);
+ if (rc <= 0) {
+ printf("[%d] %s: ERROR: osmo_gad_raw_write() failed\n", i, osmo_gad_type_name(t->type));
+ goto loop_end;
+ }
+ if (rc != msg->len) {
+ printf("[%d] %s: ERROR: osmo_gad_raw_write() returned length %d but msgb has %d bytes\n",
+ i, osmo_gad_type_name(t->type),
+ rc, msg->len);
+ goto loop_end;
+ }
+
+ memset(&raw_read, 0xff, sizeof(raw_read));
+ rc = osmo_gad_raw_read(&raw_read, &err, loop_ctx, msg->data, msg->len);
+ if (rc) {
+ printf("[%d] ERROR: osmo_gad_raw_read() failed: %s\n", i, err->logmsg);
+ printf(" encoded data: %s\n", osmo_hexdump(msg->data, msg->len));
+ goto loop_end;
+ }
+
+ memset(&dec_pdu, 0xff, sizeof(dec_pdu));
+ rc = osmo_gad_dec(&dec_pdu, &err, loop_ctx, &raw_read);
+ if (rc) {
+ printf("[%d] ERROR: failed to decode pdu: %s\n", i, err->logmsg);
+ printf(" encoded data: %s\n", osmo_hexdump(msg->data, msg->len));
+ goto loop_end;
+ }
+
+ if (memcmp(t, &dec_pdu, sizeof(dec_pdu))) {
+ char strbuf[128];
+ printf("[%d] %s: ERROR: decoded PDU != encoded PDU\n", i,
+ osmo_gad_type_name(t->type));
+ osmo_gad_to_str_buf(strbuf, sizeof(strbuf), t);
+ printf(" original struct: %s\n", strbuf);
+ osmo_gad_to_str_buf(strbuf, sizeof(strbuf), &dec_pdu);
+ printf(" decoded struct: %s\n", strbuf);
+ goto loop_end;
+ }
+
+ printf("[%d] %s: ok\n", i, osmo_gad_type_name(t->type));
+ printf(" encoded data: %s\n", msgb_hexdump(msg));
+
+loop_end:
+ msgb_free(msg);
+ }
+}
+
+void test_gad_to_str(void)
+{
+ int i;
+ printf("--- %s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(gad_test_values); i++) {
+ struct osmo_gad *t = &gad_test_values[i];
+ char buf[1024];
+ int rc;
+ rc = osmo_gad_to_str_buf(buf, sizeof(buf), t);
+
+ printf("[%d] ", i);
+ if (rc <= 0)
+ printf("%s: ERROR: osmo_gad_to_str_buf() failed\n", osmo_gad_type_name(t->type));
+ else
+ printf("%s\n", buf);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ test_gad_lat_lon_dec_enc_stability();
+ test_gad_enc_dec();
+ test_gad_to_str();
+ return 0;
+}
diff --git a/tests/gad/gad_test.ok b/tests/gad/gad_test.ok
new file mode 100644
index 00000000..ec5432a8
--- /dev/null
+++ b/tests/gad/gad_test.ok
@@ -0,0 +1,8 @@
+--- test_gad_lat_lon_dec_enc_stability
+osmo_gad_dec_lat() -> osmo_gad_enc_lat() of 16777216 values successful
+osmo_gad_dec_lon() -> osmo_gad_enc_lon() of 16777216 values successful
+--- test_gad_enc_dec
+[0] Ellipsoid-point-with-uncertainty-circle: ok
+ encoded data: 10 20 b6 0c 1d dd de 28
+--- test_gad_to_str
+[0] Ellipsoid-point-with-uncertainty-circle{lat=23.000006,lon=42.000002,unc=442.592m}
diff --git a/tests/gb/bssgp_fc_test.c b/tests/gb/bssgp_fc_test.c
index cc387771..63e8308a 100644
--- a/tests/gb/bssgp_fc_test.c
+++ b/tests/gb/bssgp_fc_test.c
@@ -148,7 +148,9 @@ int main(int argc, char **argv)
osmo_init_logging2(ctx, &info);
log_set_use_color(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category(osmo_stderr_target, 0);
+ log_set_print_category_hex(osmo_stderr_target, 0);
tall_msgb_ctx = msgb_talloc_ctx_init(ctx, 0);
diff --git a/tests/gb/gprs_bssgp_rim_test.c b/tests/gb/gprs_bssgp_rim_test.c
new file mode 100644
index 00000000..bb533f6d
--- /dev/null
+++ b/tests/gb/gprs_bssgp_rim_test.c
@@ -0,0 +1,799 @@
+/* Test routines for the BSSGP implementation in libosmogb
+ *
+ * (C) 2020 by sysmocom - s.f.m.c. GmbH
+ * Author: Philipp Maier <pmaier@sysmocom.de>
+ *
+ * Skeleton based on bssgp_fc_test.c
+ * (C) 2012 by Harald Welte <laforge@gnumonks.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#undef _GNU_SOURCE
+#define _GNU_SOURCE
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/gprs/gprs_bssgp.h>
+#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_bssgp_rim.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+void dump_rim_ri(struct bssgp_rim_routing_info *ri)
+{
+ switch (ri->discr) {
+ case BSSGP_RIM_ROUTING_INFO_GERAN:
+ printf("GERAN cell identifier\n");
+ printf(" * mcc: %u\n", ri->geran.raid.mcc);
+ printf(" mnc: %u\n", ri->geran.raid.mnc);
+ printf(" mnc 3 digits: %u\n", ri->geran.raid.mnc_3_digits);
+ printf(" lac: %u\n", ri->geran.raid.lac);
+ printf(" rac: %u\n", ri->geran.raid.rac);
+ printf(" * cell id: %04x\n", ri->geran.cid);
+ break;
+ case BSSGP_RIM_ROUTING_INFO_UTRAN:
+ printf("UTRAN RNC identifier\n");
+ printf(" * mcc: %u\n", ri->utran.raid.mcc);
+ printf(" mnc: %u\n", ri->utran.raid.mnc);
+ printf(" mnc 3 digits: %u\n", ri->utran.raid.mnc_3_digits);
+ printf(" lac: %u\n", ri->utran.raid.lac);
+ printf(" rac: %u\n", ri->utran.raid.rac);
+ printf(" * rnc id: %04x\n", ri->utran.rncid);
+ break;
+ case BSSGP_RIM_ROUTING_INFO_EUTRAN:
+ printf("EUTRAN eNB identifier\n");
+ printf(" * mcc: %u\n", ri->eutran.tai.mcc);
+ printf(" mnc: %u\n", ri->eutran.tai.mnc);
+ printf(" mnc 3 digits: %u\n", ri->eutran.tai.mnc_3_digits);
+ printf(" tac: %u\n", ri->eutran.tai.tac);
+ printf(" * global_enb_id: %s\n",
+ osmo_hexdump_nospc(ri->eutran.global_enb_id,
+ ri->eutran.global_enb_id_len));
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void test_bssgp_parse_rim_ri(void)
+{
+ int rc;
+ struct bssgp_rim_routing_info result;
+ uint8_t testvec_geran[] =
+ { 0x00, 0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };
+ uint8_t testvec_utran[] =
+ { 0x01, 0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };
+ uint8_t testvec_eutran[] =
+ { 0x02, 0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_parse_rim_ri(&result, testvec_geran,
+ sizeof(testvec_geran));
+ printf("rc=%d\n", rc);
+ dump_rim_ri(&result);
+ printf("\n");
+
+ rc = bssgp_parse_rim_ri(&result, testvec_utran,
+ sizeof(testvec_utran));
+ printf("rc=%d\n", rc);
+ dump_rim_ri(&result);
+ printf("\n");
+
+ rc = bssgp_parse_rim_ri(&result, testvec_eutran,
+ sizeof(testvec_eutran));
+ printf("rc=%d\n", rc);
+ dump_rim_ri(&result);
+ printf("\n");
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_create_rim_ri(void)
+{
+ int rc;
+ struct bssgp_rim_routing_info ri;
+ uint8_t result[15];
+
+ printf("----- %s START\n", __func__);
+ memset(&ri, 0, sizeof(ri));
+ memset(result, 0, sizeof(result));
+ ri.discr = BSSGP_RIM_ROUTING_INFO_GERAN;
+
+ ri.geran.raid.mcc = 262;
+ ri.geran.raid.mnc = 42;
+ ri.geran.raid.mnc_3_digits = false;
+ ri.geran.raid.lac = 13200;
+ ri.geran.raid.rac = 0;
+ ri.geran.cid = 0x51e1;
+ dump_rim_ri(&ri);
+ rc = bssgp_create_rim_ri(result, &ri);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n\n");
+
+ memset(&ri, 0, sizeof(ri));
+ memset(result, 0, sizeof(result));
+ ri.discr = BSSGP_RIM_ROUTING_INFO_UTRAN;
+ ri.utran.raid.mcc = 262;
+ ri.utran.raid.mnc = 42;
+ ri.utran.raid.mnc_3_digits = 0;
+ ri.utran.raid.lac = 13200;
+ ri.utran.raid.rac = 0;
+ ri.utran.rncid = 0x51e1;
+ dump_rim_ri(&ri);
+ rc = bssgp_create_rim_ri(result, &ri);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n\n");
+
+ memset(&ri, 0, sizeof(ri));
+ memset(result, 0, sizeof(result));
+ ri.discr = BSSGP_RIM_ROUTING_INFO_EUTRAN;
+ ri.eutran.tai.mcc = 262;
+ ri.eutran.tai.mnc = 42;
+ ri.eutran.tai.mnc_3_digits = 0;
+ ri.eutran.tai.tac = 13200;
+ ri.eutran.global_enb_id[0] = 0x00;
+ ri.eutran.global_enb_id[1] = 0x51;
+ ri.eutran.global_enb_id[2] = 0xe1;
+ ri.eutran.global_enb_id_len = 3;
+ dump_rim_ri(&ri);
+ rc = bssgp_create_rim_ri(result, &ri);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n\n");
+
+ printf("----- %s END\n", __func__);
+}
+
+void dump_bssgp_ran_inf_req_app_cont_nacc(struct bssgp_ran_inf_req_app_cont_nacc *app_cont)
+{
+ printf(" app_cont: bssgp_ran_inf_req_app_cont_nacc:\n");
+ printf(" reprt_cell.rai.lac.plmn.mcc = %u\n", app_cont->reprt_cell.rai.lac.plmn.mcc);
+ printf(" reprt_cell.rai.lac.plmn.mnc = %u\n", app_cont->reprt_cell.rai.lac.plmn.mnc);
+ printf(" reprt_cell.rai.lac.plmn.mnc_3_digits = %u\n", app_cont->reprt_cell.rai.lac.plmn.mnc_3_digits);
+ printf(" reprt_cell.rai.lac.lac = %u\n", app_cont->reprt_cell.rai.lac.lac);
+ printf(" reprt_cell.rai.rac = %u\n", app_cont->reprt_cell.rai.rac);
+ printf(" reprt_cell.cell_identity = %04x\n", app_cont->reprt_cell.cell_identity);
+}
+
+void dump_bssgp_ran_inf_req_rim_cont(struct bssgp_ran_inf_req_rim_cont *rim_cont)
+{
+ printf("bssgp_ran_inf_req_rim_cont:\n");
+ printf(" app_id = %02x\n", rim_cont->app_id);
+ printf(" seq_num = %08x\n", rim_cont->seq_num);
+ printf(" pdu_ind.ack_requested = %u\n", rim_cont->pdu_ind.ack_requested);
+ printf(" pdu_ind.pdu_type_ext = %u\n", rim_cont->pdu_ind.pdu_type_ext);
+ printf(" prot_ver = %u\n", rim_cont->prot_ver);
+ switch (rim_cont->app_id) {
+ case BSSGP_RAN_INF_APP_ID_NACC:
+ dump_bssgp_ran_inf_req_app_cont_nacc(&rim_cont->u.app_cont_nacc);
+ break;
+ case BSSGP_RAN_INF_APP_ID_SI3:
+ case BSSGP_RAN_INF_APP_ID_MBMS:
+ case BSSGP_RAN_INF_APP_ID_SON:
+ case BSSGP_RAN_INF_APP_ID_UTRA_SI:
+ printf(" app_cont: (not implemented yet)\n");
+ break;
+ default:
+ printf(" app_cont: (illegal application identifier)\n");
+ }
+ if (rim_cont->son_trans_app_id) {
+ printf(" son_trans_app_id: %s\n",
+ osmo_hexdump_nospc(rim_cont->son_trans_app_id, rim_cont->son_trans_app_id_len));
+ printf(" son_trans_app_id_len: %zu\n", rim_cont->son_trans_app_id_len);
+ }
+}
+
+static void test_bssgp_dec_ran_inf_req_rim_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_req_rim_cont rim_cont_dec;
+ uint8_t testvec[] =
+ { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x01, 0x4f, 0x81, 0x02, 0x55, 0x81, 0x01, 0x4d, 0x88,
+ 0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_dec_ran_inf_req_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));
+ printf("rc=%d, ", rc);
+ if (rc == 0)
+ dump_bssgp_ran_inf_req_rim_cont(&rim_cont_dec);
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_enc_ran_inf_req_rim_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_req_rim_cont rim_cont = { };
+ uint8_t result[256];
+ printf("----- %s START\n", __func__);
+
+ rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;
+ rim_cont.seq_num = 1;
+ rim_cont.pdu_ind.ack_requested = 0;
+ rim_cont.pdu_ind.pdu_type_ext = 1;
+ rim_cont.prot_ver = 1;
+ rim_cont.son_trans_app_id = NULL;
+ rim_cont.son_trans_app_id_len = 0;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mcc = 262;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mnc = 42;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mnc_3_digits = 0;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.lac = 13200;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.rac = 0;
+ rim_cont.u.app_cont_nacc.reprt_cell.cell_identity = 0x51e1;
+
+ dump_bssgp_ran_inf_req_rim_cont(&rim_cont);
+
+ rc = bssgp_enc_ran_inf_req_rim_cont(result, sizeof(result), &rim_cont);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n");
+ printf("----- %s END\n", __func__);
+}
+
+static void dump_bssgp_ran_inf_app_cont_nacc(struct bssgp_ran_inf_app_cont_nacc *app_cont)
+{
+ unsigned int i;
+ unsigned int silen;
+ printf(" app_cont: bssgp_ran_inf_app_cont_nacc:\n");
+ printf(" reprt_cell.rai.lac.plmn.mcc = %u\n", app_cont->reprt_cell.rai.lac.plmn.mcc);
+ printf(" reprt_cell.rai.lac.plmn.mnc = %u\n", app_cont->reprt_cell.rai.lac.plmn.mnc);
+ printf(" reprt_cell.rai.lac.plmn.mnc_3_digits = %u\n", app_cont->reprt_cell.rai.lac.plmn.mnc_3_digits);
+ printf(" reprt_cell.rai.lac.lac = %u\n", app_cont->reprt_cell.rai.lac.lac);
+ printf(" reprt_cell.rai.rac = %u\n", app_cont->reprt_cell.rai.rac);
+ printf(" reprt_cell.cell_identity = %04x\n", app_cont->reprt_cell.cell_identity);
+ printf(" type_psi = %u\n", app_cont->type_psi);
+ printf(" num_si = %u\n", app_cont->num_si);
+
+ if (app_cont->type_psi)
+ silen = 22;
+ else
+ silen = 21;
+
+ for (i = 0; i < app_cont->num_si; i++)
+ printf(" si[%u] = %s\n", i, osmo_hexdump_nospc(app_cont->si[i], silen));
+}
+
+static void dump_bssgp_app_err_cont_nacc(struct bssgp_app_err_cont_nacc *app_cont)
+{
+ printf(" app_err_cont: bssgp_app_err_cont_nacc:\n");
+ printf(" macc_cause = %02x\n", app_cont->nacc_cause);
+ if (app_cont->err_app_cont) {
+ printf(" err_app_cont: %s\n", osmo_hexdump_nospc(app_cont->err_app_cont, app_cont->err_app_cont_len));
+ printf(" err_app_cont_len: %zu\n", app_cont->err_app_cont_len);
+ }
+}
+
+static void dump_bssgp_ran_inf_rim_cont(struct bssgp_ran_inf_rim_cont *rim_cont)
+{
+ printf("bssgp_ran_inf_rim_cont:\n");
+ printf(" app_id = %02x\n", rim_cont->app_id);
+ printf(" seq_num = %08x\n", rim_cont->seq_num);
+ printf(" pdu_ind.ack_requested = %u\n", rim_cont->pdu_ind.ack_requested);
+ printf(" pdu_ind.pdu_type_ext = %u\n", rim_cont->pdu_ind.pdu_type_ext);
+ printf(" prot_ver = %u\n", rim_cont->prot_ver);
+ printf(" app_err = %u\n", rim_cont->app_err);
+ if (rim_cont->app_err) {
+ switch (rim_cont->app_id) {
+ case BSSGP_RAN_INF_APP_ID_NACC:
+ dump_bssgp_app_err_cont_nacc(&rim_cont->u.app_err_cont_nacc);
+ break;
+ case BSSGP_RAN_INF_APP_ID_SI3:
+ case BSSGP_RAN_INF_APP_ID_MBMS:
+ case BSSGP_RAN_INF_APP_ID_SON:
+ case BSSGP_RAN_INF_APP_ID_UTRA_SI:
+ printf(" app_err_cont: (not implemented yet)\n");
+ break;
+ default:
+ printf(" app_err_cont: (illegal application identifier)\n");
+ }
+ } else {
+ switch (rim_cont->app_id) {
+ case BSSGP_RAN_INF_APP_ID_NACC:
+ dump_bssgp_ran_inf_app_cont_nacc(&rim_cont->u.app_cont_nacc);
+ break;
+ case BSSGP_RAN_INF_APP_ID_SI3:
+ case BSSGP_RAN_INF_APP_ID_MBMS:
+ case BSSGP_RAN_INF_APP_ID_SON:
+ case BSSGP_RAN_INF_APP_ID_UTRA_SI:
+ printf(" app_cont: (not implemented yet)\n");
+ break;
+ default:
+ printf(" app_cont: (illegal application identifier)\n");
+ }
+ }
+ if (rim_cont->son_trans_app_id) {
+ printf(" son_trans_app_id: %s\n",
+ osmo_hexdump_nospc(rim_cont->son_trans_app_id, rim_cont->son_trans_app_id_len));
+ printf(" son_trans_app_id_len: %zu\n", rim_cont->son_trans_app_id_len);
+ }
+}
+
+static void test_bssgp_dec_ran_inf_rim_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_rim_cont rim_cont_dec;
+ uint8_t testvec[] =
+ { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x02, 0x4f, 0x81, 0x02, 0x55, 0x81, 0x01, 0x4e, 0xc8,
+ 0x62, 0xf2, 0x24, 0x33, 0x4f, 0x00, 0x51, 0xe0, 0x06, 0x19, 0x8f, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x2b, 0x1b, 0x75, 0x30, 0x00, 0xf1, 0x10,
+ 0x23, 0x6e,
+ 0xc9, 0x03, 0x3c, 0x27, 0x47, 0x40, 0x79, 0x00, 0x00, 0x3c, 0x0b, 0x2b, 0x2b, 0x00, 0x90, 0x00, 0x18,
+ 0x5a, 0x6f,
+ 0xc9, 0xe0, 0x84, 0x10, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b
+ };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_dec_ran_inf_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));
+ printf("rc=%d, ", rc);
+ if (rc == 0)
+ dump_bssgp_ran_inf_rim_cont(&rim_cont_dec);
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_dec_ran_inf_rim_cont_err_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_rim_cont rim_cont_dec;
+ uint8_t testvec[] =
+ { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x01, 0x4f, 0x81, 0x02, 0x55, 0x81, 0x01, 0x56, 0x86,
+ 0x01, 0xaa, 0xbb, 0xcc, 0xdd, 0xee };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_dec_ran_inf_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));
+ printf("rc=%d, ", rc);
+ if (rc == 0)
+ dump_bssgp_ran_inf_rim_cont(&rim_cont_dec);
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_enc_ran_inf_rim_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_rim_cont rim_cont = { };
+
+ uint8_t si1[] =
+ { 0x19, 0x8f, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x79, 0x00, 0x00, 0x2b
+ };
+ uint8_t si3[] =
+ { 0x1b, 0x75, 0x30, 0x00, 0xf1, 0x10, 0x23, 0x6e, 0xc9, 0x03, 0x3c, 0x27, 0x47, 0x40, 0x79, 0x00, 0x00,
+ 0x3c, 0x0b, 0x2b, 0x2b
+ };
+ uint8_t si13[] =
+ { 0x00, 0x90, 0x00, 0x18, 0x5a, 0x6f, 0xc9, 0xe0, 0x84, 0x10, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+ 0x2b, 0x2b, 0x2b, 0x2b
+ };
+
+ uint8_t result[256];
+ printf("----- %s START\n", __func__);
+
+ rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;
+ rim_cont.seq_num = 1;
+ rim_cont.pdu_ind.ack_requested = 0;
+ rim_cont.pdu_ind.pdu_type_ext = 1;
+ rim_cont.prot_ver = 1;
+ rim_cont.son_trans_app_id = NULL;
+ rim_cont.son_trans_app_id_len = 0;
+ rim_cont.app_err = false;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mcc = 262;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mnc = 42;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mnc_3_digits = 0;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.lac = 13135;
+ rim_cont.u.app_cont_nacc.reprt_cell.rai.rac = 0;
+ rim_cont.u.app_cont_nacc.reprt_cell.cell_identity = 0x51e0;
+ rim_cont.u.app_cont_nacc.type_psi = 0;
+ rim_cont.u.app_cont_nacc.num_si = 3;
+ rim_cont.u.app_cont_nacc.si[0] = si1;
+ rim_cont.u.app_cont_nacc.si[1] = si3;
+ rim_cont.u.app_cont_nacc.si[2] = si13;
+
+ dump_bssgp_ran_inf_rim_cont(&rim_cont);
+
+ rc = bssgp_enc_ran_inf_rim_cont(result, sizeof(result), &rim_cont);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n");
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_enc_ran_inf_rim_cont_err_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_rim_cont rim_cont = { };
+ uint8_t err_app_cont[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee };
+
+ uint8_t result[256];
+ printf("----- %s START\n", __func__);
+
+ rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;
+ rim_cont.seq_num = 1;
+ rim_cont.pdu_ind.ack_requested = 0;
+ rim_cont.pdu_ind.pdu_type_ext = 1;
+ rim_cont.prot_ver = 1;
+ rim_cont.son_trans_app_id = NULL;
+ rim_cont.son_trans_app_id_len = 0;
+ rim_cont.app_err = true;
+ rim_cont.u.app_err_cont_nacc.nacc_cause = BSSGP_NACC_CAUSE_SYNTAX_ERR;
+ rim_cont.u.app_err_cont_nacc.err_app_cont = err_app_cont;
+ rim_cont.u.app_err_cont_nacc.err_app_cont_len = sizeof(err_app_cont);
+ dump_bssgp_ran_inf_rim_cont(&rim_cont);
+
+ rc = bssgp_enc_ran_inf_rim_cont(result, sizeof(result), &rim_cont);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n");
+ printf("----- %s END\n", __func__);
+}
+
+static void dump_bssgp_ran_inf_ack_rim_cont(struct bssgp_ran_inf_ack_rim_cont *rim_cont)
+{
+ printf("bssgp_ran_inf_ack_rim_cont:\n");
+ printf(" app_id = %02x\n", rim_cont->app_id);
+ printf(" seq_num = %08x\n", rim_cont->seq_num);
+ printf(" prot_ver = %u\n", rim_cont->prot_ver);
+ if (rim_cont->son_trans_app_id) {
+ printf(" son_trans_app_id: %s\n",
+ osmo_hexdump_nospc(rim_cont->son_trans_app_id, rim_cont->son_trans_app_id_len));
+ printf(" son_trans_app_id_len: %zu\n", rim_cont->son_trans_app_id_len);
+ }
+}
+
+static void test_bssgp_dec_ran_inf_ack_rim_cont(void)
+{
+ int rc;
+ struct bssgp_ran_inf_ack_rim_cont rim_cont_dec;
+ uint8_t testvec[] = { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x01, 0x55, 0x81, 0x01 };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_dec_ran_inf_ack_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));
+ printf("rc=%d, ", rc);
+ if (rc == 0)
+ dump_bssgp_ran_inf_ack_rim_cont(&rim_cont_dec);
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_enc_ran_inf_ack_rim_cont(void)
+{
+ int rc;
+ struct bssgp_ran_inf_ack_rim_cont rim_cont = { };
+ uint8_t result[256];
+ printf("----- %s START\n", __func__);
+
+ rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;
+ rim_cont.seq_num = 1;
+ rim_cont.prot_ver = 1;
+ rim_cont.son_trans_app_id = NULL;
+ rim_cont.son_trans_app_id_len = 0;
+ dump_bssgp_ran_inf_ack_rim_cont(&rim_cont);
+
+ rc = bssgp_enc_ran_inf_ack_rim_cont(result, sizeof(result), &rim_cont);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n");
+ printf("----- %s END\n", __func__);
+}
+
+void dump_bssgp_ran_inf_err_rim_cont(struct bssgp_ran_inf_err_rim_cont *rim_cont)
+{
+ printf("bssgp_ran_inf_err_rim_cont:\n");
+ printf(" app_id = %02x\n", rim_cont->app_id);
+ printf(" cause = %02x\n", rim_cont->cause);
+ printf(" prot_ver = %u\n", rim_cont->prot_ver);
+ if (rim_cont->err_pdu) {
+ printf(" err_pdu: %s\n", osmo_hexdump_nospc(rim_cont->err_pdu, rim_cont->err_pdu_len));
+ printf(" err_pdu_len: %zu\n", rim_cont->err_pdu_len);
+ }
+ if (rim_cont->son_trans_app_id) {
+ printf(" son_trans_app_id: %s\n",
+ osmo_hexdump_nospc(rim_cont->son_trans_app_id, rim_cont->son_trans_app_id_len));
+ printf(" son_trans_app_id_len: %zu\n", rim_cont->son_trans_app_id_len);
+ }
+}
+
+static void test_bssgp_dec_ran_inf_err_rim_cont(void)
+{
+ int rc;
+ struct bssgp_ran_inf_err_rim_cont rim_cont_dec;
+ uint8_t testvec[] =
+ { 0x4b, 0x81, 0x17, 0x07, 0x81, 0x2b, 0x55, 0x81, 0x01, 0x15, 0x85, 0xaa, 0xbb, 0xcc, 0xdd, 0xee };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_dec_ran_inf_err_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));
+ printf("rc=%d, ", rc);
+ if (rc == 0)
+ dump_bssgp_ran_inf_err_rim_cont(&rim_cont_dec);
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_enc_ran_inf_err_rim_cont(void)
+{
+ int rc;
+ struct bssgp_ran_inf_err_rim_cont rim_cont = { };
+ uint8_t err_pdu[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee };
+ uint8_t result[256];
+ printf("----- %s START\n", __func__);
+
+ rim_cont.app_id = 23;
+ rim_cont.cause = 0x2b;
+ rim_cont.prot_ver = 1;
+ rim_cont.err_pdu = err_pdu;
+ rim_cont.err_pdu_len = sizeof(err_pdu);
+ rim_cont.son_trans_app_id = NULL;
+ rim_cont.son_trans_app_id_len = 0;
+ dump_bssgp_ran_inf_err_rim_cont(&rim_cont);
+
+ rc = bssgp_enc_ran_inf_err_rim_cont(result, sizeof(result), &rim_cont);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n");
+ printf("----- %s END\n", __func__);
+}
+
+void dump_bssgp_ran_inf_app_err_rim_cont(struct bssgp_ran_inf_app_err_rim_cont *rim_cont)
+{
+ printf("bssgp_ran_inf_app_err_rim_cont:\n");
+ printf(" app_id = %02x\n", rim_cont->app_id);
+ printf(" seq_num = %08x\n", rim_cont->seq_num);
+ printf(" pdu_ind.ack_requested = %u\n", rim_cont->pdu_ind.ack_requested);
+ printf(" pdu_ind.pdu_type_ext = %u\n", rim_cont->pdu_ind.pdu_type_ext);
+ printf(" prot_ver = %u\n", rim_cont->prot_ver);
+ switch (rim_cont->app_id) {
+ case BSSGP_RAN_INF_APP_ID_NACC:
+ dump_bssgp_app_err_cont_nacc(&rim_cont->u.app_err_cont_nacc);
+ break;
+ case BSSGP_RAN_INF_APP_ID_SI3:
+ case BSSGP_RAN_INF_APP_ID_MBMS:
+ case BSSGP_RAN_INF_APP_ID_SON:
+ case BSSGP_RAN_INF_APP_ID_UTRA_SI:
+ printf(" app_err_cont: (not implemented yet)\n");
+ break;
+ default:
+ printf(" app_err_cont: (illegal application identifier)\n");
+ }
+}
+
+static void test_bssgp_dec_ran_inf_app_err_rim_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_app_err_rim_cont rim_cont_dec;
+ uint8_t testvec[] =
+ { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x01, 0x4f, 0x81, 0x02, 0x55, 0x81, 0x01, 0x56, 0x85,
+ 0xaa, 0xbb, 0xcc, 0xdd, 0xee
+ };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_dec_ran_inf_app_err_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));
+ printf("rc=%d, ", rc);
+ if (rc == 0)
+ dump_bssgp_ran_inf_app_err_rim_cont(&rim_cont_dec);
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_enc_ran_inf_app_err_rim_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_app_err_rim_cont rim_cont = { };
+ uint8_t err_app_cont[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee };
+ uint8_t result[256];
+
+ printf("----- %s START\n", __func__);
+ rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;
+ rim_cont.seq_num = 1;
+ rim_cont.pdu_ind.ack_requested = 0;
+ rim_cont.pdu_ind.pdu_type_ext = 1;
+ rim_cont.prot_ver = 1;
+ rim_cont.u.app_err_cont_nacc.nacc_cause = BSSGP_NACC_CAUSE_SYNTAX_ERR;
+ rim_cont.u.app_err_cont_nacc.err_app_cont = err_app_cont;
+ rim_cont.u.app_err_cont_nacc.err_app_cont_len = sizeof(err_app_cont);
+ dump_bssgp_ran_inf_app_err_rim_cont(&rim_cont);
+
+ rc = bssgp_enc_ran_inf_app_err_rim_cont(result, sizeof(result), &rim_cont);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n");
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_dec_ran_inf_req_app_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_req_app_cont_nacc app_cont_dec;
+ uint8_t testvec[] = { 0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_dec_ran_inf_req_app_cont_nacc(&app_cont_dec, testvec, sizeof(testvec));
+ printf("rc=%d, ", rc);
+ if (rc == 0)
+ dump_bssgp_ran_inf_req_app_cont_nacc(&app_cont_dec);
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_enc_ran_inf_req_app_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_req_app_cont_nacc app_cont = { };
+ uint8_t result[256];
+ printf("----- %s START\n", __func__);
+
+ app_cont.reprt_cell.rai.lac.plmn.mcc = 262;
+ app_cont.reprt_cell.rai.lac.plmn.mnc = 42;
+ app_cont.reprt_cell.rai.lac.plmn.mnc_3_digits = 0;
+ app_cont.reprt_cell.rai.lac.lac = 13200;
+ app_cont.reprt_cell.rai.rac = 0;
+ app_cont.reprt_cell.cell_identity = 0x51e1;
+ dump_bssgp_ran_inf_req_app_cont_nacc(&app_cont);
+
+ rc = bssgp_enc_ran_inf_req_app_cont_nacc(result, sizeof(result), &app_cont);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n");
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_dec_ran_inf_app_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_app_cont_nacc app_cont_dec;
+ uint8_t testvec[] =
+ { 0x62, 0xf2, 0x24, 0x33, 0x4f, 0x00, 0x51, 0xe0, 0x06, 0x19, 0x8f, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x2b, 0x1b, 0x75, 0x30, 0x00, 0xf1, 0x10,
+ 0x23, 0x6e, 0xc9, 0x03, 0x3c, 0x27, 0x47, 0x40, 0x79, 0x00, 0x00, 0x3c, 0x0b, 0x2b, 0x2b, 0x00, 0x90, 0x00, 0x18,
+ 0x5a, 0x6f, 0xc9, 0xe0, 0x84, 0x10, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_dec_ran_inf_app_cont_nacc(&app_cont_dec, testvec, sizeof(testvec));
+ printf("rc=%d, ", rc);
+ if (rc == 0)
+ dump_bssgp_ran_inf_app_cont_nacc(&app_cont_dec);
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_enc_ran_inf_app_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_ran_inf_app_cont_nacc app_cont = { };
+
+ uint8_t si1[] =
+ { 0x19, 0x8f, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x79, 0x00, 0x00, 0x2b };
+ uint8_t si3[] =
+ { 0x1b, 0x75, 0x30, 0x00, 0xf1, 0x10, 0x23, 0x6e, 0xc9, 0x03, 0x3c, 0x27, 0x47, 0x40, 0x79, 0x00, 0x00,
+ 0x3c, 0x0b, 0x2b, 0x2b };
+ uint8_t si13[] =
+ { 0x00, 0x90, 0x00, 0x18, 0x5a, 0x6f, 0xc9, 0xe0, 0x84, 0x10, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
+ 0x2b, 0x2b, 0x2b, 0x2b };
+
+ uint8_t result[256];
+ printf("----- %s START\n", __func__);
+
+ app_cont.reprt_cell.rai.lac.plmn.mcc = 262;
+ app_cont.reprt_cell.rai.lac.plmn.mnc = 42;
+ app_cont.reprt_cell.rai.lac.plmn.mnc_3_digits = 0;
+ app_cont.reprt_cell.rai.lac.lac = 13135;
+ app_cont.reprt_cell.rai.rac = 0;
+ app_cont.reprt_cell.cell_identity = 0x51e1;
+ app_cont.type_psi = false;
+ app_cont.num_si = 3;
+ app_cont.si[0] = si1;
+ app_cont.si[1] = si3;
+ app_cont.si[2] = si13;
+ dump_bssgp_ran_inf_app_cont_nacc(&app_cont);
+
+ rc = bssgp_enc_ran_inf_app_cont_nacc(result, sizeof(result), &app_cont);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n");
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_dec_app_err_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_app_err_cont_nacc app_cont_dec;
+ uint8_t testvec[] = { 0x01, 0xaa, 0xbb, 0xcc, 0xdd, 0xee };
+
+ printf("----- %s START\n", __func__);
+
+ rc = bssgp_dec_app_err_cont_nacc(&app_cont_dec, testvec, sizeof(testvec));
+ printf("rc=%d, ", rc);
+ if (rc == 0)
+ dump_bssgp_app_err_cont_nacc(&app_cont_dec);
+
+ printf("----- %s END\n", __func__);
+}
+
+static void test_bssgp_enc_app_err_cont_nacc(void)
+{
+ int rc;
+ struct bssgp_app_err_cont_nacc app_cont = { };
+ uint8_t err_app_cont[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee };
+ uint8_t result[256];
+ printf("----- %s START\n", __func__);
+
+ app_cont.nacc_cause = BSSGP_NACC_CAUSE_SYNTAX_ERR;
+ app_cont.err_app_cont = err_app_cont;
+ app_cont.err_app_cont_len = sizeof(err_app_cont);
+ dump_bssgp_app_err_cont_nacc(&app_cont);
+
+ rc = bssgp_enc_app_err_cont_nacc(result, sizeof(result), &app_cont);
+ printf("rc=%d, ", rc);
+ if (rc > 0)
+ printf("result=%s", osmo_hexdump_nospc(result, rc));
+ printf("\n");
+ printf("----- %s END\n", __func__);
+}
+
+int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ printf("===== BSSGP RIM test START\n");
+
+ /* RIM routing information */
+ test_bssgp_parse_rim_ri();
+ test_bssgp_create_rim_ri();
+
+ /* RIM containers */
+ test_bssgp_dec_ran_inf_req_rim_cont_nacc();
+ test_bssgp_enc_ran_inf_req_rim_cont_nacc();
+ test_bssgp_dec_ran_inf_rim_cont_nacc();
+ test_bssgp_dec_ran_inf_rim_cont_err_nacc();
+ test_bssgp_enc_ran_inf_rim_cont_nacc();
+ test_bssgp_enc_ran_inf_rim_cont_err_nacc();
+ test_bssgp_dec_ran_inf_ack_rim_cont();
+ test_bssgp_enc_ran_inf_ack_rim_cont();
+ test_bssgp_dec_ran_inf_err_rim_cont();
+ test_bssgp_enc_ran_inf_err_rim_cont();
+ test_bssgp_dec_ran_inf_app_err_rim_cont_nacc();
+ test_bssgp_enc_ran_inf_app_err_rim_cont_nacc();
+
+ /* Application containers */
+ test_bssgp_dec_ran_inf_req_app_cont_nacc();
+ test_bssgp_enc_ran_inf_req_app_cont_nacc();
+ test_bssgp_dec_ran_inf_app_cont_nacc();
+ test_bssgp_enc_ran_inf_app_cont_nacc();
+ test_bssgp_dec_app_err_cont_nacc();
+ test_bssgp_enc_app_err_cont_nacc();
+
+ printf("===== BSSGP RIM test END\n\n");
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/tests/gb/gprs_bssgp_rim_test.ok b/tests/gb/gprs_bssgp_rim_test.ok
new file mode 100644
index 00000000..df5a41df
--- /dev/null
+++ b/tests/gb/gprs_bssgp_rim_test.ok
@@ -0,0 +1,276 @@
+===== BSSGP RIM test START
+----- test_bssgp_parse_rim_ri START
+rc=9
+GERAN cell identifier
+ * mcc: 262
+ mnc: 42
+ mnc 3 digits: 0
+ lac: 13200
+ rac: 0
+ * cell id: 51e1
+
+rc=9
+UTRAN RNC identifier
+ * mcc: 262
+ mnc: 42
+ mnc 3 digits: 0
+ lac: 13200
+ rac: 0
+ * rnc id: 51e1
+
+rc=9
+EUTRAN eNB identifier
+ * mcc: 262
+ mnc: 42
+ mnc 3 digits: 0
+ tac: 13200
+ * global_enb_id: 0051e1
+
+----- test_bssgp_parse_rim_ri END
+----- test_bssgp_create_rim_ri START
+GERAN cell identifier
+ * mcc: 262
+ mnc: 42
+ mnc 3 digits: 0
+ lac: 13200
+ rac: 0
+ * cell id: 51e1
+rc=9, result=0062f22433900051e1
+
+UTRAN RNC identifier
+ * mcc: 262
+ mnc: 42
+ mnc 3 digits: 0
+ lac: 13200
+ rac: 0
+ * rnc id: 51e1
+rc=9, result=0162f22433900051e1
+
+EUTRAN eNB identifier
+ * mcc: 262
+ mnc: 42
+ mnc 3 digits: 0
+ tac: 13200
+ * global_enb_id: 0051e1
+rc=9, result=0262f22433900051e1
+
+----- test_bssgp_create_rim_ri END
+----- test_bssgp_dec_ran_inf_req_rim_cont_nacc START
+rc=0, bssgp_ran_inf_req_rim_cont:
+ app_id = 01
+ seq_num = 00000001
+ pdu_ind.ack_requested = 0
+ pdu_ind.pdu_type_ext = 1
+ prot_ver = 1
+ app_cont: bssgp_ran_inf_req_app_cont_nacc:
+ reprt_cell.rai.lac.plmn.mcc = 262
+ reprt_cell.rai.lac.plmn.mnc = 42
+ reprt_cell.rai.lac.plmn.mnc_3_digits = 0
+ reprt_cell.rai.lac.lac = 13200
+ reprt_cell.rai.rac = 0
+ reprt_cell.cell_identity = 51e1
+----- test_bssgp_dec_ran_inf_req_rim_cont_nacc END
+----- test_bssgp_enc_ran_inf_req_rim_cont_nacc START
+bssgp_ran_inf_req_rim_cont:
+ app_id = 01
+ seq_num = 00000001
+ pdu_ind.ack_requested = 0
+ pdu_ind.pdu_type_ext = 1
+ prot_ver = 1
+ app_cont: bssgp_ran_inf_req_app_cont_nacc:
+ reprt_cell.rai.lac.plmn.mcc = 262
+ reprt_cell.rai.lac.plmn.mnc = 42
+ reprt_cell.rai.lac.plmn.mnc_3_digits = 0
+ reprt_cell.rai.lac.lac = 13200
+ reprt_cell.rai.rac = 0
+ reprt_cell.cell_identity = 51e1
+rc=25, result=4b81014c84000000014f81025581014d8862f22433900051e1
+----- test_bssgp_enc_ran_inf_req_rim_cont_nacc END
+----- test_bssgp_dec_ran_inf_rim_cont_nacc START
+rc=0, bssgp_ran_inf_rim_cont:
+ app_id = 01
+ seq_num = 00000002
+ pdu_ind.ack_requested = 0
+ pdu_ind.pdu_type_ext = 1
+ prot_ver = 1
+ app_err = 0
+ app_cont: bssgp_ran_inf_app_cont_nacc:
+ reprt_cell.rai.lac.plmn.mcc = 262
+ reprt_cell.rai.lac.plmn.mnc = 42
+ reprt_cell.rai.lac.plmn.mnc_3_digits = 0
+ reprt_cell.rai.lac.lac = 13135
+ reprt_cell.rai.rac = 0
+ reprt_cell.cell_identity = 51e0
+ type_psi = 0
+ num_si = 3
+ si[0] = 198fb100000000000000000000000000007900002b
+ si[1] = 1b753000f110236ec9033c2747407900003c0b2b2b
+ si[2] = 009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b
+----- test_bssgp_dec_ran_inf_rim_cont_nacc END
+----- test_bssgp_dec_ran_inf_rim_cont_err_nacc START
+rc=0, bssgp_ran_inf_rim_cont:
+ app_id = 01
+ seq_num = 00000001
+ pdu_ind.ack_requested = 0
+ pdu_ind.pdu_type_ext = 1
+ prot_ver = 1
+ app_err = 1
+ app_err_cont: bssgp_app_err_cont_nacc:
+ macc_cause = 01
+ err_app_cont: aabbccddee
+ err_app_cont_len: 5
+----- test_bssgp_dec_ran_inf_rim_cont_err_nacc END
+----- test_bssgp_enc_ran_inf_rim_cont_nacc START
+bssgp_ran_inf_rim_cont:
+ app_id = 01
+ seq_num = 00000001
+ pdu_ind.ack_requested = 0
+ pdu_ind.pdu_type_ext = 1
+ prot_ver = 1
+ app_err = 0
+ app_cont: bssgp_ran_inf_app_cont_nacc:
+ reprt_cell.rai.lac.plmn.mcc = 262
+ reprt_cell.rai.lac.plmn.mnc = 42
+ reprt_cell.rai.lac.plmn.mnc_3_digits = 0
+ reprt_cell.rai.lac.lac = 13135
+ reprt_cell.rai.rac = 0
+ reprt_cell.cell_identity = 51e0
+ type_psi = 0
+ num_si = 3
+ si[0] = 198fb100000000000000000000000000007900002b
+ si[1] = 1b753000f110236ec9033c2747407900003c0b2b2b
+ si[2] = 009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b
+rc=89, result=4b81014c84000000014f81025581014ec862f224334f0051e006198fb100000000000000000000000000007900002b1b753000f110236ec9033c2747407900003c0b2b2b009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b
+----- test_bssgp_enc_ran_inf_rim_cont_nacc END
+----- test_bssgp_enc_ran_inf_rim_cont_err_nacc START
+bssgp_ran_inf_rim_cont:
+ app_id = 01
+ seq_num = 00000001
+ pdu_ind.ack_requested = 0
+ pdu_ind.pdu_type_ext = 1
+ prot_ver = 1
+ app_err = 1
+ app_err_cont: bssgp_app_err_cont_nacc:
+ macc_cause = 01
+ err_app_cont: aabbccddee
+ err_app_cont_len: 5
+rc=23, result=4b81014c84000000014f8102558101568601aabbccddee
+----- test_bssgp_enc_ran_inf_rim_cont_err_nacc END
+----- test_bssgp_dec_ran_inf_ack_rim_cont START
+rc=0, bssgp_ran_inf_ack_rim_cont:
+ app_id = 01
+ seq_num = 00000001
+ prot_ver = 1
+----- test_bssgp_dec_ran_inf_ack_rim_cont END
+----- test_bssgp_enc_ran_inf_ack_rim_cont START
+bssgp_ran_inf_ack_rim_cont:
+ app_id = 01
+ seq_num = 00000001
+ prot_ver = 1
+rc=12, result=4b81014c8400000001558101
+----- test_bssgp_enc_ran_inf_ack_rim_cont END
+----- test_bssgp_dec_ran_inf_err_rim_cont START
+rc=0, bssgp_ran_inf_err_rim_cont:
+ app_id = 17
+ cause = 2b
+ prot_ver = 1
+ err_pdu: aabbccddee
+ err_pdu_len: 5
+----- test_bssgp_dec_ran_inf_err_rim_cont END
+----- test_bssgp_enc_ran_inf_err_rim_cont START
+bssgp_ran_inf_err_rim_cont:
+ app_id = 17
+ cause = 2b
+ prot_ver = 1
+ err_pdu: aabbccddee
+ err_pdu_len: 5
+rc=16, result=4b811707812b5581011585aabbccddee
+----- test_bssgp_enc_ran_inf_err_rim_cont END
+----- test_bssgp_dec_ran_inf_app_err_rim_cont_nacc START
+rc=0, bssgp_ran_inf_app_err_rim_cont:
+ app_id = 01
+ seq_num = 00000001
+ pdu_ind.ack_requested = 0
+ pdu_ind.pdu_type_ext = 1
+ prot_ver = 1
+ app_err_cont: bssgp_app_err_cont_nacc:
+ macc_cause = aa
+ err_app_cont: bbccddee
+ err_app_cont_len: 4
+----- test_bssgp_dec_ran_inf_app_err_rim_cont_nacc END
+----- test_bssgp_enc_ran_inf_app_err_rim_cont_nacc START
+bssgp_ran_inf_app_err_rim_cont:
+ app_id = 01
+ seq_num = 00000001
+ pdu_ind.ack_requested = 0
+ pdu_ind.pdu_type_ext = 1
+ prot_ver = 1
+ app_err_cont: bssgp_app_err_cont_nacc:
+ macc_cause = 01
+ err_app_cont: aabbccddee
+ err_app_cont_len: 5
+rc=23, result=4b81014c84000000014f8102558101568601aabbccddee
+----- test_bssgp_enc_ran_inf_app_err_rim_cont_nacc END
+----- test_bssgp_dec_ran_inf_req_app_cont_nacc START
+rc=0, app_cont: bssgp_ran_inf_req_app_cont_nacc:
+ reprt_cell.rai.lac.plmn.mcc = 262
+ reprt_cell.rai.lac.plmn.mnc = 42
+ reprt_cell.rai.lac.plmn.mnc_3_digits = 0
+ reprt_cell.rai.lac.lac = 13200
+ reprt_cell.rai.rac = 0
+ reprt_cell.cell_identity = 51e1
+----- test_bssgp_dec_ran_inf_req_app_cont_nacc END
+----- test_bssgp_enc_ran_inf_req_app_cont_nacc START
+ app_cont: bssgp_ran_inf_req_app_cont_nacc:
+ reprt_cell.rai.lac.plmn.mcc = 262
+ reprt_cell.rai.lac.plmn.mnc = 42
+ reprt_cell.rai.lac.plmn.mnc_3_digits = 0
+ reprt_cell.rai.lac.lac = 13200
+ reprt_cell.rai.rac = 0
+ reprt_cell.cell_identity = 51e1
+rc=8, result=62f22433900051e1
+----- test_bssgp_enc_ran_inf_req_app_cont_nacc END
+----- test_bssgp_dec_ran_inf_app_cont_nacc START
+rc=0, app_cont: bssgp_ran_inf_app_cont_nacc:
+ reprt_cell.rai.lac.plmn.mcc = 262
+ reprt_cell.rai.lac.plmn.mnc = 42
+ reprt_cell.rai.lac.plmn.mnc_3_digits = 0
+ reprt_cell.rai.lac.lac = 13135
+ reprt_cell.rai.rac = 0
+ reprt_cell.cell_identity = 51e0
+ type_psi = 0
+ num_si = 3
+ si[0] = 198fb100000000000000000000000000007900002b
+ si[1] = 1b753000f110236ec9033c2747407900003c0b2b2b
+ si[2] = 009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b
+----- test_bssgp_dec_ran_inf_app_cont_nacc END
+----- test_bssgp_enc_ran_inf_app_cont_nacc START
+ app_cont: bssgp_ran_inf_app_cont_nacc:
+ reprt_cell.rai.lac.plmn.mcc = 262
+ reprt_cell.rai.lac.plmn.mnc = 42
+ reprt_cell.rai.lac.plmn.mnc_3_digits = 0
+ reprt_cell.rai.lac.lac = 13135
+ reprt_cell.rai.rac = 0
+ reprt_cell.cell_identity = 51e1
+ type_psi = 0
+ num_si = 3
+ si[0] = 198fb100000000000000000000000000007900002b
+ si[1] = 1b753000f110236ec9033c2747407900003c0b2b2b
+ si[2] = 009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b
+rc=72, result=62f224334f0051e106198fb100000000000000000000000000007900002b1b753000f110236ec9033c2747407900003c0b2b2b009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b
+----- test_bssgp_enc_ran_inf_app_cont_nacc END
+----- test_bssgp_dec_app_err_cont_nacc START
+rc=0, app_err_cont: bssgp_app_err_cont_nacc:
+ macc_cause = 01
+ err_app_cont: aabbccddee
+ err_app_cont_len: 5
+----- test_bssgp_dec_app_err_cont_nacc END
+----- test_bssgp_enc_app_err_cont_nacc START
+ app_err_cont: bssgp_app_err_cont_nacc:
+ macc_cause = 01
+ err_app_cont: aabbccddee
+ err_app_cont_len: 5
+rc=6, result=01aabbccddee
+----- test_bssgp_enc_app_err_cont_nacc END
+===== BSSGP RIM test END
+
diff --git a/tests/gb/gprs_bssgp_test.c b/tests/gb/gprs_bssgp_test.c
index 52e986e8..775ae43b 100644
--- a/tests/gb/gprs_bssgp_test.c
+++ b/tests/gb/gprs_bssgp_test.c
@@ -173,7 +173,7 @@ static void test_bssgp_status(void)
printf("----- %s END\n", __func__);
}
-static void test_bssgp_bad_reset()
+static void test_bssgp_bad_reset(void)
{
struct msgb *msg;
uint16_t bvci_be = htons(2);
@@ -256,7 +256,7 @@ static void test_bssgp_flow_control_bvc(void)
printf("----- %s END\n", __func__);
}
-static void test_bssgp_msgb_copy()
+static void test_bssgp_msgb_copy(void)
{
struct msgb *msg, *msg2;
uint16_t bvci_be = htons(2);
@@ -298,7 +298,7 @@ int main(int argc, char **argv)
osmo_init_logging2(ctx, &info);
log_set_use_color(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
msgb_talloc_ctx_init(ctx, 0);
diff --git a/tests/gb/gprs_ns2_test.c b/tests/gb/gprs_ns2_test.c
new file mode 100644
index 00000000..0221a8d6
--- /dev/null
+++ b/tests/gb/gprs_ns2_test.c
@@ -0,0 +1,670 @@
+/* test routines for NS connection handling
+ * (C) 2020 sysmocom - s.f.m.c. GmbH
+ * Author: Alexander Couzens <lynxis@fe80.eu>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#undef _GNU_SOURCE
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include <getopt.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/write_queue.h>
+#include <osmocom/gprs/gprs_msgb.h>
+#include <osmocom/gprs/gprs_ns2.h>
+#include <osmocom/gprs/gprs_bssgp.h>
+
+#include "../../src/gb/gprs_ns2_internal.h"
+
+int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ return -1;
+}
+
+static struct log_info info = {};
+static struct osmo_wqueue *unitdata = NULL;
+static struct osmo_gprs_ns2_prim last_nse_recovery = {};
+static struct osmo_gprs_ns2_prim last_nse_mtu_change = {};
+
+static int ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_gprs_ns2_prim *nsp;
+ OSMO_ASSERT(oph->sap == SAP_NS);
+ nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph);
+ if (oph->msg) {
+ if (oph->primitive == GPRS_NS2_PRIM_UNIT_DATA) {
+ osmo_wqueue_enqueue(unitdata, oph->msg);
+ } else {
+ msgb_free(oph->msg);
+ }
+ }
+ if (oph->primitive == GPRS_NS2_PRIM_STATUS) {
+ if (nsp->u.status.cause == GPRS_NS2_AFF_CAUSE_RECOVERY) {
+ last_nse_recovery = *nsp;
+ } else if (nsp->u.status.cause == GPRS_NS2_AFF_CAUSE_MTU_CHANGE) {
+ last_nse_mtu_change = *nsp;
+ }
+ }
+ return 0;
+}
+
+static int gp_send_to_ns(struct gprs_ns2_inst *nsi, struct msgb *msg, uint16_t nsei, uint16_t bvci, uint32_t lsp)
+{
+ struct osmo_gprs_ns2_prim nsp = {};
+ nsp.nsei = nsei;
+ nsp.bvci = bvci;
+ nsp.u.unitdata.link_selector = lsp;
+ osmo_prim_init(&nsp.oph, SAP_NS, GPRS_NS2_PRIM_UNIT_DATA,
+ PRIM_OP_REQUEST, msg);
+ return gprs_ns2_recv_prim(nsi, &nsp.oph);
+}
+
+
+static struct msgb *get_pdu(struct gprs_ns2_vc_bind *bind, enum ns_pdu_type pdu_type)
+{
+ struct gprs_ns_hdr *nsh;
+ struct osmo_wqueue *queue = bind->priv;
+
+ while (!llist_empty(&queue->msg_queue)) {
+ struct msgb *msg = msgb_dequeue(&queue->msg_queue);
+ nsh = (struct gprs_ns_hdr *) msg->l2h;
+ if (nsh->pdu_type == pdu_type)
+ return msg;
+ msgb_free(msg);
+ }
+
+ return NULL;
+}
+
+static bool find_pdu(struct gprs_ns2_vc_bind *bind, enum ns_pdu_type pdu_type)
+{
+ struct msgb *msg;
+ msg = get_pdu(bind, pdu_type);
+ if (msg) {
+ msgb_free(msg);
+ return true;
+ }
+
+ return false;
+}
+
+static unsigned int count_pdus(struct gprs_ns2_vc_bind *bind)
+{
+ struct osmo_wqueue *queue = bind->priv;
+ return llist_count(&queue->msg_queue);
+}
+
+static void clear_pdus(struct gprs_ns2_vc_bind *bind)
+{
+ struct osmo_wqueue *queue = bind->priv;
+ osmo_wqueue_clear(queue);
+}
+
+struct gprs_ns2_vc_driver vc_driver_dummy = {
+ .name = "GB UDP dummy",
+ .free_bind = clear_pdus,
+};
+
+static int vc_sendmsg(struct gprs_ns2_vc *nsvc, struct msgb *msg)
+{
+ struct gprs_ns2_vc_bind *bind = nsvc->bind;
+ struct osmo_wqueue *queue = bind->priv;
+
+ osmo_wqueue_enqueue(queue, msg);
+ return 0;
+}
+
+static struct gprs_ns2_vc_bind *dummy_bind(struct gprs_ns2_inst *nsi, const char *name)
+{
+ struct gprs_ns2_vc_bind *bind = NULL;
+ OSMO_ASSERT(ns2_bind_alloc(nsi, name, &bind) == 0);
+ OSMO_ASSERT(bind);
+
+ bind->driver = &vc_driver_dummy;
+ bind->ll = GPRS_NS2_LL_UDP;
+ bind->transfer_capability = 42;
+ bind->send_vc = vc_sendmsg;
+ bind->priv = talloc_zero(bind, struct osmo_wqueue);
+ bind->mtu = 123;
+ struct osmo_wqueue *queue = bind->priv;
+
+ osmo_wqueue_init(queue, 100);
+
+ return bind;
+}
+
+static void free_loopback(struct gprs_ns2_vc_bind *bind) {}
+
+struct gprs_ns2_vc_driver vc_driver_loopback = {
+ .name = "loopback dummy",
+ .free_bind = free_loopback,
+};
+
+/* loopback the msg */
+static int loopback_sendmsg(struct gprs_ns2_vc *nsvc, struct msgb *msg)
+{
+ struct gprs_ns2_vc *target = nsvc->priv;
+ return ns2_recv_vc(target, msg);
+}
+
+/* create a loopback nsvc object which can be used with ns2_tx_* functions. it's not fully registered etc. */
+static struct gprs_ns2_vc *loopback_nsvc(struct gprs_ns2_vc_bind *bind, struct gprs_ns2_vc *target)
+{
+ struct gprs_ns2_vc *nsvc = talloc_zero(bind, struct gprs_ns2_vc);
+ memcpy(nsvc, target, sizeof(struct gprs_ns2_vc));
+ nsvc->bind = bind;
+ nsvc->priv = target;
+ return nsvc;
+}
+
+/* a loop back bind to use the tx_ functions from gprs_ns2_message.c */
+static struct gprs_ns2_vc_bind *loopback_bind(struct gprs_ns2_inst *nsi, const char *name)
+{
+ struct gprs_ns2_vc_bind *bind = NULL;
+ OSMO_ASSERT(ns2_bind_alloc(nsi, name, &bind) == 0)
+ OSMO_ASSERT(bind);
+ bind->driver = &vc_driver_loopback;
+ bind->ll = GPRS_NS2_LL_UDP;
+ bind->transfer_capability = 99;
+ bind->send_vc = loopback_sendmsg;
+ bind->mtu = 123;
+ return bind;
+}
+
+void test_nse_transfer_cap(void *ctx)
+{
+ struct gprs_ns2_inst *nsi;
+ struct gprs_ns2_vc_bind *bind[2];
+ struct gprs_ns2_nse *nse;
+ struct gprs_ns2_vc *nsvc[3];
+
+ /* create a UDP dummy bind[0] with transfer cap 42.
+ * create nse (nsei 1001)
+ * create 2x nsvc with the same bind.
+ * nsvc[0] or nsvc[1] is alive (or both) cap == 42
+ *
+ * create a second bind with transfer cap == 23
+ * create 3rd nsvc with bind[1]
+ * transfer cap should be 42 + 23
+ */
+
+ printf("--- Testing NSE transfer cap\n");
+
+ printf("---- Create NSE + Binds\n");
+ nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL);
+ bind[0] = dummy_bind(nsi, "transfercap1");
+ bind[1] = dummy_bind(nsi, "transfercap2");
+ bind[1]->transfer_capability = 23;
+ nse = gprs_ns2_create_nse(nsi, 1001, GPRS_NS2_LL_UDP, GPRS_NS2_DIALECT_STATIC_ALIVE);
+ OSMO_ASSERT(nse);
+
+ printf("---- Test with NSVC[0]\n");
+ nsvc[0] = ns2_vc_alloc(bind[0], nse, false, GPRS_NS2_VC_MODE_ALIVE, NULL);
+ OSMO_ASSERT(nsvc[0]);
+ OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 0);
+ nsvc[0]->fi->state = 3; /* HACK: 3 = GPRS_NS2_ST_UNBLOCKED */
+ ns2_nse_notify_unblocked(nsvc[0], true);
+ OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42);
+
+ printf("---- Test with NSVC[1]\n");
+ nsvc[1] = ns2_vc_alloc(bind[0], nse, false, GPRS_NS2_VC_MODE_ALIVE, NULL);
+ OSMO_ASSERT(nsvc[1]);
+ OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42);
+ nsvc[1]->fi->state = 3; /* HACK: 3 = GPRS_NS2_ST_UNBLOCKED */
+ ns2_nse_notify_unblocked(nsvc[1], true);
+ OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42);
+
+ printf("---- Test with NSVC[2]\n");
+ nsvc[2] = ns2_vc_alloc(bind[1], nse, false, GPRS_NS2_VC_MODE_ALIVE, NULL);
+ OSMO_ASSERT(nsvc[2]);
+ OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42);
+ nsvc[2]->fi->state = 3; /* HACK: 3 = GPRS_NS2_ST_UNBLOCKED */
+ ns2_nse_notify_unblocked(nsvc[2], true);
+ OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42 + 23);
+
+ printf("---- Test with NSVC[1] removed\n");
+ /* reset nsvc[1] to be unconfigured - shouldn't change anything */
+ nsvc[1]->fi->state = 0; /* HACK: 0 = GPRS_NS2_ST_UNCONFIGURED */
+ ns2_nse_notify_unblocked(nsvc[1], false);
+ OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42 + 23);
+
+ gprs_ns2_free(nsi);
+ printf("--- Finish NSE transfer cap\n");
+
+}
+
+/* setup NSE with 2x NSVCs.
+ * block 1x NSVC
+ * unblock 1x NSVC*/
+void test_block_unblock_nsvc(void *ctx)
+{
+ struct gprs_ns2_inst *nsi;
+ struct gprs_ns2_vc_bind *bind[2];
+ struct gprs_ns2_nse *nse;
+ struct gprs_ns2_vc *nsvc[2];
+ struct gprs_ns_hdr *nsh;
+ struct msgb *msg;
+ char idbuf[32];
+ int i;
+
+ printf("--- Testing NSE block unblock nsvc\n");
+ printf("---- Create NSE + Binds\n");
+ nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL);
+ bind[0] = dummy_bind(nsi, "bblock1");
+ bind[1] = dummy_bind(nsi, "bblock2");
+ nse = gprs_ns2_create_nse(nsi, 1001, GPRS_NS2_LL_UDP, GPRS_NS2_DIALECT_STATIC_RESETBLOCK);
+ OSMO_ASSERT(nse);
+
+ for (i=0; i<2; i++) {
+ printf("---- Create NSVC[i]\n");
+ snprintf(idbuf, sizeof(idbuf), "NSE%05u-dummy-%i", nse->nsei, i);
+ nsvc[i] = ns2_vc_alloc(bind[i], nse, false, GPRS_NS2_VC_MODE_BLOCKRESET, idbuf);
+ OSMO_ASSERT(nsvc[i]);
+ nsvc[i]->fi->state = 3; /* HACK: 3 = GPRS_NS2_ST_UNBLOCKED */
+ /* ensure the fi->state works correct */
+ OSMO_ASSERT(ns2_vc_is_unblocked(nsvc[i]));
+ ns2_nse_notify_unblocked(nsvc[i], true);
+ }
+
+ /* both nsvcs are unblocked and alive. Let's block it. */
+ OSMO_ASSERT(!find_pdu(bind[0], NS_PDUT_BLOCK));
+ clear_pdus(bind[0]);
+ ns2_vc_block(nsvc[0]);
+ OSMO_ASSERT(find_pdu(bind[0], NS_PDUT_BLOCK));
+ /* state == BLOCKED */
+ clear_pdus(bind[0]);
+
+ /* now unblocking it */
+ ns2_vc_unblock(nsvc[0]);
+ OSMO_ASSERT(find_pdu(bind[0], NS_PDUT_UNBLOCK));
+ clear_pdus(bind[0]);
+
+ msg = msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "test_unblock");
+ msg->l2h = msgb_put(msg, sizeof(*nsh));
+ nsh = (struct gprs_ns_hdr *) msg->l2h;
+ nsh->pdu_type = NS_PDUT_UNBLOCK_ACK;
+ ns2_recv_vc(nsvc[0], msg);
+
+ OSMO_ASSERT(ns2_vc_is_unblocked(nsvc[0]));
+ gprs_ns2_free(nsi);
+ printf("--- Finish NSE block unblock nsvc\n");
+}
+
+/* setup NSE with 2x NSVCs.
+ * block 1st NSVC
+ * block 2nd NSVC
+ * unblock 1st NSVC */
+void test_block_unblock_nsvc2(void *ctx)
+{
+ struct gprs_ns2_inst *nsi;
+ struct gprs_ns2_vc_bind *bind[2];
+ struct gprs_ns2_nse *nse;
+ struct gprs_ns2_vc *nsvc[2];
+ struct gprs_ns_hdr *nsh;
+ struct msgb *msg;
+ char idbuf[32];
+ int i;
+
+ printf("--- Testing NSE block unblock nsvc2\n");
+ printf("---- Create NSE + Binds\n");
+ nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL);
+ bind[0] = dummy_bind(nsi, "bblock1");
+ bind[1] = dummy_bind(nsi, "bblock2");
+ nse = gprs_ns2_create_nse(nsi, 1001, GPRS_NS2_LL_UDP, GPRS_NS2_DIALECT_STATIC_RESETBLOCK);
+ OSMO_ASSERT(nse);
+
+ for (i=0; i<2; i++) {
+ printf("---- Create NSVC[i]\n");
+ snprintf(idbuf, sizeof(idbuf), "NSE%05u-dummy-%i", nse->nsei, i);
+ nsvc[i] = ns2_vc_alloc(bind[i], nse, false, GPRS_NS2_VC_MODE_BLOCKRESET, idbuf);
+ OSMO_ASSERT(nsvc[i]);
+ nsvc[i]->fi->state = 3; /* HACK: 3 = GPRS_NS2_ST_UNBLOCKED */
+ /* ensure the fi->state works correct */
+ OSMO_ASSERT(ns2_vc_is_unblocked(nsvc[i]));
+ ns2_nse_notify_unblocked(nsvc[i], true);
+ }
+
+ OSMO_ASSERT(nse->alive);
+ /* both nsvcs are unblocked and alive. Let's block them. */
+ OSMO_ASSERT(!find_pdu(bind[0], NS_PDUT_BLOCK));
+ clear_pdus(bind[0]);
+ ns2_vc_block(nsvc[0]);
+ OSMO_ASSERT(find_pdu(bind[0], NS_PDUT_BLOCK));
+ clear_pdus(bind[0]);
+ OSMO_ASSERT(nse->alive);
+
+ OSMO_ASSERT(!find_pdu(bind[1], NS_PDUT_BLOCK));
+ clear_pdus(bind[1]);
+ ns2_vc_block(nsvc[1]);
+ OSMO_ASSERT(find_pdu(bind[1], NS_PDUT_BLOCK));
+ clear_pdus(bind[1]);
+ OSMO_ASSERT(!nse->alive);
+
+ /* now unblocking the 1st NSVC */
+ ns2_vc_unblock(nsvc[0]);
+ OSMO_ASSERT(find_pdu(bind[0], NS_PDUT_UNBLOCK));
+ clear_pdus(bind[0]);
+ msg = msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "test_unblock");
+ msg->l2h = msgb_put(msg, sizeof(*nsh));
+ nsh = (struct gprs_ns_hdr *) msg->l2h;
+ nsh->pdu_type = NS_PDUT_UNBLOCK_ACK;
+ ns2_recv_vc(nsvc[0], msg);
+ OSMO_ASSERT(nse->alive);
+
+ OSMO_ASSERT(ns2_vc_is_unblocked(nsvc[0]));
+ gprs_ns2_free(nsi);
+ printf("--- Finish NSE block unblock nsvc2\n");
+}
+
+static struct msgb *generate_unitdata(const char *msgname)
+{
+ struct gprs_ns_hdr *nsh;
+ struct msgb *msg = msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, msgname);
+ OSMO_ASSERT(msg);
+
+ msg->l2h = msgb_put(msg, sizeof(*nsh) + 6);
+ nsh = (struct gprs_ns_hdr *) msg->l2h;
+ nsh->pdu_type = NS_PDUT_UNITDATA;
+ nsh->data[0] = 0; /* sdu control */
+ nsh->data[1] = 0; /* msb bvci */
+ nsh->data[2] = 12; /* lsb bvci */
+ nsh->data[3] = 0xab; /* first data byte */
+ nsh->data[4] = 0xcd;
+ nsh->data[5] = 0xef;
+
+ return msg;
+}
+
+void test_unitdata(void *ctx)
+{
+ struct gprs_ns2_inst *nsi;
+ struct gprs_ns2_vc_bind *bind[2];
+ struct gprs_ns2_vc_bind *loopbind;
+ struct gprs_ns2_nse *nse;
+ struct gprs_ns2_vc *nsvc[2];
+ struct gprs_ns2_vc *loop[2];
+
+ struct msgb *msg, *other;
+ char idbuf[32];
+ int i;
+
+ printf("--- Testing unitdata test\n");
+ osmo_wqueue_clear(unitdata);
+ printf("---- Create NSE + Binds\n");
+ nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL);
+ bind[0] = dummy_bind(nsi, "bblock1");
+ bind[1] = dummy_bind(nsi, "bblock2");
+ loopbind = loopback_bind(nsi, "loopback");
+ nse = gprs_ns2_create_nse(nsi, 1004, GPRS_NS2_LL_UDP, GPRS_NS2_DIALECT_STATIC_RESETBLOCK);
+ OSMO_ASSERT(nse);
+
+ for (i=0; i<2; i++) {
+ printf("---- Create NSVC[%d]\n", i);
+ snprintf(idbuf, sizeof(idbuf), "NSE%05u-dummy-%i", nse->nsei, i);
+ nsvc[i] = ns2_vc_alloc(bind[i], nse, false, GPRS_NS2_VC_MODE_BLOCKRESET, idbuf);
+ loop[i] = loopback_nsvc(loopbind, nsvc[i]);
+ OSMO_ASSERT(nsvc[i]);
+ ns2_vc_fsm_start(nsvc[i]);
+ OSMO_ASSERT(!ns2_vc_is_unblocked(nsvc[i]));
+ ns2_tx_reset(loop[i], NS_CAUSE_OM_INTERVENTION);
+ ns2_tx_unblock(loop[i]);
+ OSMO_ASSERT(ns2_vc_is_unblocked(nsvc[i]));
+ }
+
+ /* both nsvcs are unblocked and alive */
+ printf("---- Send UNITDATA to NSVC[0]\n");
+ msg = generate_unitdata("test_unitdata");
+ ns2_recv_vc(nsvc[0], msg);
+ other = msgb_dequeue(&unitdata->msg_queue);
+ OSMO_ASSERT(msg == other);
+ other = msgb_dequeue(&unitdata->msg_queue);
+ OSMO_ASSERT(NULL == other);
+
+ printf("---- Send Block NSVC[0]\n");
+ ns2_vc_block(nsvc[0]);
+ ns2_tx_block_ack(loop[0], NULL);
+
+ /* try to receive a unitdata - this should be dropped & freed by NS */
+ printf("---- Try to receive over blocked NSVC[0]\n");
+ ns2_recv_vc(nsvc[0], msg);
+ other = msgb_dequeue(&unitdata->msg_queue);
+ OSMO_ASSERT(NULL == other);
+
+ /* nsvc[1] should be still good */
+ printf("---- Receive over NSVC[1]\n");
+ msg = generate_unitdata("test_unitdata2");
+ ns2_recv_vc(nsvc[1], msg);
+ other = msgb_dequeue(&unitdata->msg_queue);
+ OSMO_ASSERT(msg == other);
+ msgb_free(msg);
+
+ gprs_ns2_free(nsi);
+ printf("--- Finish unitdata test\n");
+}
+
+void test_unitdata_weights(void *ctx)
+{
+ struct gprs_ns2_inst *nsi;
+ struct gprs_ns2_vc_bind *bind[3];
+ struct gprs_ns2_vc_bind *loopbind;
+ struct gprs_ns2_nse *nse;
+ struct gprs_ns2_vc *nsvc[3];
+ struct gprs_ns2_vc *loop[3];
+
+ struct msgb *msg, *other;
+ char idbuf[32];
+ int i;
+
+ printf("--- Testing unitdata weight test\n");
+ osmo_wqueue_clear(unitdata);
+ printf("---- Create NSE + Binds\n");
+ nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL);
+ bind[0] = dummy_bind(nsi, "bblock1");
+ bind[1] = dummy_bind(nsi, "bblock2");
+ bind[2] = dummy_bind(nsi, "bblock3");
+ loopbind = loopback_bind(nsi, "loopback");
+ nse = gprs_ns2_create_nse(nsi, 1004, GPRS_NS2_LL_UDP, GPRS_NS2_DIALECT_STATIC_ALIVE);
+ OSMO_ASSERT(nse);
+
+ /* data weights are
+ * nsvc[0] = 1
+ * nsvc[1] = 2
+ * nsvc[2] = 3
+ */
+ for (i = 0; i < 3; i++) {
+ printf("---- Create NSVC[%d]\n", i);
+ snprintf(idbuf, sizeof(idbuf), "NSE%05u-dummy-%i", nse->nsei, i);
+ nsvc[i] = ns2_vc_alloc(bind[i], nse, false, GPRS_NS2_VC_MODE_ALIVE, idbuf);
+ loop[i] = loopback_nsvc(loopbind, nsvc[i]);
+ OSMO_ASSERT(nsvc[i]);
+ nsvc[i]->data_weight = i + 1;
+ ns2_vc_fsm_start(nsvc[i]);
+ OSMO_ASSERT(!ns2_vc_is_unblocked(nsvc[i]));
+ ns2_tx_alive_ack(loop[i]);
+ OSMO_ASSERT(ns2_vc_is_unblocked(nsvc[i]));
+ }
+
+ /* all nsvcs are alive */
+ printf("---- Send UNITDATA to all NSVCs\n");
+ for (i = 0; i < 3; i++) {
+ msg = generate_unitdata("test_unitdata_weight");
+ ns2_recv_vc(nsvc[i], msg);
+ other = msgb_dequeue(&unitdata->msg_queue);
+ OSMO_ASSERT(msg == other);
+ other = msgb_dequeue(&unitdata->msg_queue);
+ OSMO_ASSERT(NULL == other);
+ msgb_free(msg);
+ }
+
+ /* nsvc[1] should be still good */
+ printf("---- Send BSSGP data to the NSE to test unitdata over NSVC[1]\n");
+ for (i = 0; i < 3; i++)
+ clear_pdus(bind[i]);
+
+ for (i = 0; i < 12; i++) {
+ msg = generate_unitdata("test_unitdata_weight2");
+ gp_send_to_ns(nsi, msg, 1004, 1, i + 1);
+ }
+
+ for (i = 0; i < 3; i++)
+ fprintf(stderr, "count_pdus(bind[%d]) = %d\n", i, count_pdus(bind[i]));
+
+ for (i = 0; i < 3; i++) {
+ OSMO_ASSERT(count_pdus(bind[i]) == nsvc[i]->data_weight * 2);
+ }
+
+ gprs_ns2_free(nsi);
+ printf("--- Finish unitdata weight test\n");
+}
+
+void test_mtu(void *ctx)
+{
+ struct gprs_ns2_inst *nsi;
+ struct gprs_ns2_vc_bind *bind[2];
+ struct gprs_ns2_vc_bind *loopbind;
+ struct gprs_ns2_nse *nse;
+ struct gprs_ns2_vc *nsvc[2];
+ struct gprs_ns2_vc *loop[2];
+
+ struct msgb *msg, *other;
+ char idbuf[32];
+ int i;
+
+ printf("--- Testing mtu test\n");
+ osmo_wqueue_clear(unitdata);
+ printf("---- Create NSE + Binds\n");
+ nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL);
+ bind[0] = dummy_bind(nsi, "bblock1");
+ bind[1] = dummy_bind(nsi, "bblock2");
+ loopbind = loopback_bind(nsi, "loopback");
+ nse = gprs_ns2_create_nse(nsi, 1004, GPRS_NS2_LL_UDP, GPRS_NS2_DIALECT_STATIC_RESETBLOCK);
+ OSMO_ASSERT(nse);
+
+ for (i=0; i<2; i++) {
+ printf("---- Create NSVC[%d]\n", i);
+ snprintf(idbuf, sizeof(idbuf), "NSE%05u-dummy-%i", nse->nsei, i);
+ nsvc[i] = ns2_vc_alloc(bind[i], nse, false, GPRS_NS2_VC_MODE_BLOCKRESET, idbuf);
+ loop[i] = loopback_nsvc(loopbind, nsvc[i]);
+ OSMO_ASSERT(nsvc[i]);
+ ns2_vc_fsm_start(nsvc[i]);
+ OSMO_ASSERT(!ns2_vc_is_unblocked(nsvc[i]));
+ ns2_tx_reset(loop[i], NS_CAUSE_OM_INTERVENTION);
+ ns2_tx_unblock(loop[i]);
+ OSMO_ASSERT(ns2_vc_is_unblocked(nsvc[i]));
+ }
+
+ /* both nsvcs are unblocked and alive */
+ printf("---- Send a small UNITDATA to NSVC[0]\n");
+ msg = generate_unitdata("test_unitdata");
+ ns2_recv_vc(nsvc[0], msg);
+ other = msgb_dequeue(&unitdata->msg_queue);
+ OSMO_ASSERT(msg == other);
+ other = msgb_dequeue(&unitdata->msg_queue);
+ OSMO_ASSERT(NULL == other);
+ msgb_free(msg);
+
+ printf("---- Check if got mtu reported\n");
+ /* 1b NS PDU type, 1b NS SDU control, 2b BVCI */
+ OSMO_ASSERT(last_nse_recovery.u.status.mtu == 123 - 4);
+
+ bind[0]->mtu = 100;
+ ns2_nse_update_mtu(nse);
+ OSMO_ASSERT(last_nse_mtu_change.u.status.mtu == 100 - 4);
+
+ gprs_ns2_free(nsi);
+ printf("--- Finish unitdata test\n");
+}
+
+void test_unconfigured(void *ctx)
+{
+ struct gprs_ns2_inst *nsi;
+ struct gprs_ns2_vc_bind *bind[2];
+ struct gprs_ns2_vc_bind *loopbind;
+ struct gprs_ns2_nse *nse;
+ struct gprs_ns2_vc *nsvc[2];
+ struct gprs_ns2_vc *loop[2];
+
+ char idbuf[32];
+ int i;
+
+ printf("--- Testing force unconfigured\n");
+ osmo_wqueue_clear(unitdata);
+ printf("---- Create NSE + Binds\n");
+ nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL);
+ bind[0] = dummy_bind(nsi, "bblock1");
+ bind[1] = dummy_bind(nsi, "bblock2");
+ loopbind = loopback_bind(nsi, "loopback");
+ nse = gprs_ns2_create_nse(nsi, 1004, GPRS_NS2_LL_UDP, GPRS_NS2_DIALECT_STATIC_RESETBLOCK);
+ OSMO_ASSERT(nse);
+
+ for (i=0; i<2; i++) {
+ printf("---- Create NSVC[%d]\n", i);
+ snprintf(idbuf, sizeof(idbuf), "NSE%05u-dummy-%i", nse->nsei, i);
+ nsvc[i] = ns2_vc_alloc(bind[i], nse, false, GPRS_NS2_VC_MODE_BLOCKRESET, idbuf);
+ loop[i] = loopback_nsvc(loopbind, nsvc[i]);
+ OSMO_ASSERT(nsvc[i]);
+ ns2_vc_fsm_start(nsvc[i]);
+ OSMO_ASSERT(!ns2_vc_is_unblocked(nsvc[i]));
+ ns2_tx_reset(loop[i], NS_CAUSE_OM_INTERVENTION);
+ ns2_tx_unblock(loop[i]);
+ OSMO_ASSERT(ns2_vc_is_unblocked(nsvc[i]));
+ }
+
+ /* both nsvcs are unblocked and alive */
+ printf("---- Check if NSE is alive\n");
+ OSMO_ASSERT(nse->alive);
+
+ ns2_vc_force_unconfigured(nsvc[0]);
+ OSMO_ASSERT(nse->alive);
+
+ ns2_vc_force_unconfigured(nsvc[1]);
+ printf("---- Check if NSE is dead\n");
+ OSMO_ASSERT(!nse->alive);
+
+ gprs_ns2_free(nsi);
+ printf("--- Finish force unconfigured test\n");
+}
+
+int main(int argc, char **argv)
+{
+ void *ctx = talloc_named_const(NULL, 0, "gprs_ns2_test");
+ osmo_init_logging2(ctx, &info);
+ log_set_use_color(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category(osmo_stderr_target, 0);
+ log_set_print_category_hex(osmo_stderr_target, 0);
+ log_set_log_level(osmo_stderr_target, LOGL_INFO);
+ unitdata = talloc_zero(ctx, struct osmo_wqueue);
+ osmo_wqueue_init(unitdata, 100);
+ setlinebuf(stdout);
+
+ printf("===== NS2 protocol test START\n");
+ test_nse_transfer_cap(ctx);
+ test_block_unblock_nsvc(ctx);
+ test_block_unblock_nsvc2(ctx);
+ test_unitdata(ctx);
+ test_unitdata_weights(ctx);
+ test_unconfigured(ctx);
+ test_mtu(ctx);
+ printf("===== NS2 protocol test END\n\n");
+
+ talloc_free(ctx);
+ exit(EXIT_SUCCESS);
+}
diff --git a/tests/gb/gprs_ns2_test.ok b/tests/gb/gprs_ns2_test.ok
new file mode 100644
index 00000000..16e66bb8
--- /dev/null
+++ b/tests/gb/gprs_ns2_test.ok
@@ -0,0 +1,51 @@
+===== NS2 protocol test START
+--- Testing NSE transfer cap
+---- Create NSE + Binds
+---- Test with NSVC[0]
+---- Test with NSVC[1]
+---- Test with NSVC[2]
+---- Test with NSVC[1] removed
+--- Finish NSE transfer cap
+--- Testing NSE block unblock nsvc
+---- Create NSE + Binds
+---- Create NSVC[i]
+---- Create NSVC[i]
+--- Finish NSE block unblock nsvc
+--- Testing NSE block unblock nsvc2
+---- Create NSE + Binds
+---- Create NSVC[i]
+---- Create NSVC[i]
+--- Finish NSE block unblock nsvc2
+--- Testing unitdata test
+---- Create NSE + Binds
+---- Create NSVC[0]
+---- Create NSVC[1]
+---- Send UNITDATA to NSVC[0]
+---- Send Block NSVC[0]
+---- Try to receive over blocked NSVC[0]
+---- Receive over NSVC[1]
+--- Finish unitdata test
+--- Testing unitdata weight test
+---- Create NSE + Binds
+---- Create NSVC[0]
+---- Create NSVC[1]
+---- Create NSVC[2]
+---- Send UNITDATA to all NSVCs
+---- Send BSSGP data to the NSE to test unitdata over NSVC[1]
+--- Finish unitdata weight test
+--- Testing force unconfigured
+---- Create NSE + Binds
+---- Create NSVC[0]
+---- Create NSVC[1]
+---- Check if NSE is alive
+---- Check if NSE is dead
+--- Finish force unconfigured test
+--- Testing mtu test
+---- Create NSE + Binds
+---- Create NSVC[0]
+---- Create NSVC[1]
+---- Send a small UNITDATA to NSVC[0]
+---- Check if got mtu reported
+--- Finish unitdata test
+===== NS2 protocol test END
+
diff --git a/tests/gb/gprs_ns2_vty.vty b/tests/gb/gprs_ns2_vty.vty
new file mode 100644
index 00000000..8db5fb50
--- /dev/null
+++ b/tests/gb/gprs_ns2_vty.vty
@@ -0,0 +1,89 @@
+OsmoNSdummy> list
+...
+ show ns binds [stats]
+ show ns entities [stats]
+ show ns persistent
+ show ns (nsei|nsvc) <0-65535> [stats]
+...
+ logging filter nse nsei <0-65535>
+ logging filter nsvc nsvci <0-65535>
+...
+OsmoNSdummy> enable
+OsmoNSdummy# configure terminal
+OsmoNSdummy(config)# list
+...
+ ns
+...
+OsmoNSdummy(config)# ns
+OsmoNSdummy(config-ns)# list
+...
+ timer (tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov|tsns-size-retries|tsns-config-retries|tsns-procedures-retries) <0-65535>
+ nse <0-65535> [ip-sns-role-sgsn]
+ no nse <0-65535>
+ bind (fr|udp) ID
+ no bind ID
+...
+OsmoNSdummy(config-ns)# bind udp abc
+OsmoNSdummy(config-ns-bind)# fr eta0 frnet
+fr can be only used with frame relay bind
+OsmoNSdummy(config-ns-bind)# listen 127.0.0.14 42999
+OsmoNSdummy(config-ns-bind)# end
+OsmoNSdummy# show ns
+UDP bind: 127.0.0.14:42999 DSCP: 0 Priority: 0
+ IP-SNS signalling weight: 1 data weight: 1
+ 0 NS-VC:
+OsmoNSdummy# configure terminal
+OsmoNSdummy(config)# ns
+OsmoNSdummy(config-ns)# nse 1234
+OsmoNSdummy(config-ns-nse)# nsvc udp abc 127.0.0.15 9496
+OsmoNSdummy(config-ns-nse)# end
+OsmoNSdummy# show ns
+NSEI 01234: UDP, DEAD since 0d 0h 0m 0s
+ 1 NS-VC:
+ RECOVERING PERSIST sig_weight=1 data_weight=1 udp)[127.0.0.14]:42999<>[127.0.0.15]:9496 DEAD (cause: remote) since 0d 0h 0m 0s
+UDP bind: 127.0.0.14:42999 DSCP: 0 Priority: 0
+ IP-SNS signalling weight: 1 data weight: 1
+ 1 NS-VC:
+ RECOVERING PERSIST sig_weight=1 data_weight=1 udp)[127.0.0.14]:42999<>[127.0.0.15]:9496 DEAD (cause: remote) since 0d 0h 0m 0s
+OsmoNSdummy# configure terminal
+OsmoNSdummy(config)# ns
+OsmoNSdummy(config-ns)# nse 1234
+OsmoNSdummy(config-ns-nse)# nsvc udp abc 127.0.0.16 9496 signalling-weight 0 data-weight 9
+OsmoNSdummy(config-ns-nse)# nsvc udp abc 127.0.0.17 9496 signalling-weight 0 data-weight 0
+OsmoNSdummy(config-ns-nse)# end
+OsmoNSdummy# show ns
+NSEI 01234: UDP, DEAD since 0d 0h 0m 0s
+ 3 NS-VC:
+ RECOVERING PERSIST sig_weight=1 data_weight=1 udp)[127.0.0.14]:42999<>[127.0.0.15]:9496 DEAD (cause: remote) since 0d 0h 0m 0s
+ RECOVERING PERSIST sig_weight=0 data_weight=9 udp)[127.0.0.14]:42999<>[127.0.0.16]:9496 DEAD (cause: remote) since 0d 0h 0m 0s
+ RECOVERING PERSIST sig_weight=0 data_weight=0 udp)[127.0.0.14]:42999<>[127.0.0.17]:9496 DEAD (cause: remote) since 0d 0h 0m 0s
+UDP bind: 127.0.0.14:42999 DSCP: 0 Priority: 0
+ IP-SNS signalling weight: 1 data weight: 1
+ 3 NS-VC:
+ RECOVERING PERSIST sig_weight=1 data_weight=1 udp)[127.0.0.14]:42999<>[127.0.0.15]:9496 DEAD (cause: remote) since 0d 0h 0m 0s
+ RECOVERING PERSIST sig_weight=0 data_weight=9 udp)[127.0.0.14]:42999<>[127.0.0.16]:9496 DEAD (cause: remote) since 0d 0h 0m 0s
+ RECOVERING PERSIST sig_weight=0 data_weight=0 udp)[127.0.0.14]:42999<>[127.0.0.17]:9496 DEAD (cause: remote) since 0d 0h 0m 0s
+OsmoNSdummy# configure terminal
+OsmoNSdummy(config)# ns
+OsmoNSdummy(config-ns)# nse 1234
+OsmoNSdummy(config-ns-nse)# nsvc udp abc 127.0.0.16 9496 signalling-weight 2 data-weight 2
+Specified NSVC is already present in this NSE.
+OsmoNSdummy(config-ns-nse)# exit
+OsmoNSdummy(config-ns)# nse 1235
+OsmoNSdummy(config-ns-nse)# nsvc udp abc 127.0.0.16 9496 signalling-weight 2 data-weight 2
+Specified NSVC is already present in another NSE01234.
+OsmoNSdummy(config-ns-nse)# exit
+OsmoNSdummy(config-ns)# nse 2342
+OsmoNSdummy(config-ns-nse)# ip-sns-bind abc
+OsmoNSdummy(config-ns-nse)# ip-sns-bind abc
+Failed to add ip-sns-bind abc already present
+OsmoNSdummy(config-ns-nse)# ip-sns-bind abc2
+Can not find the given bind 'abc2'
+OsmoNSdummy(config-ns-nse)# ip-sns-remote 127.0.0.1 22222
+OsmoNSdummy(config-ns-nse)# ip-sns-remote 127.0.0.1 22222
+Specified SNS endpoint already part of the NSE.
+OsmoNSdummy(config-ns-nse)# exit
+OsmoNSdummy(config-ns)# no bind abc
+OsmoNSdummy(config-ns)# no bind abc77
+bind abc77 does not exist!
+OsmoNSdummy(config-ns)# exit
diff --git a/tests/gb/gprs_ns_test.c b/tests/gb/gprs_ns_test.c
index f70e4937..fc1ec605 100644
--- a/tests/gb/gprs_ns_test.c
+++ b/tests/gb/gprs_ns_test.c
@@ -262,7 +262,7 @@ static void dump_rate_ctr_group(FILE *stream, const char *prefix,
unsigned int i;
for (i = 0; i < ctrg->desc->num_ctr; i++) {
- struct rate_ctr *ctr = &ctrg->ctr[i];
+ struct rate_ctr *ctr = rate_ctr_group_get_ctr(ctrg, i);
if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, ':'))
fprintf(stream, " %s%s: %llu%s",
prefix, ctrg->desc->ctr_desc[i].description,
@@ -420,7 +420,7 @@ static int expire_nsvc_timer(struct gprs_nsvc *nsvc)
return rc;
}
-static void test_nsvc()
+static void test_nsvc(void)
{
struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
struct sockaddr_in peer[1] = {{0},};
@@ -459,7 +459,7 @@ static void test_nsvc()
alarm(0);
}
-static void test_ignored_messages()
+static void test_ignored_messages(void)
{
struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
struct sockaddr_in peer[1] = {{0},};
@@ -486,7 +486,7 @@ static void test_ignored_messages()
nsi = NULL;
}
-static void test_bss_port_changes()
+static void test_bss_port_changes(void)
{
struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
struct sockaddr_in peer[4] = {{0},};
@@ -540,7 +540,7 @@ static void test_bss_port_changes()
nsi = NULL;
}
-static void test_bss_reset_ack()
+static void test_bss_reset_ack(void)
{
struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
struct sockaddr_in peer[4] = {{0},};
@@ -687,7 +687,7 @@ static void test_bss_reset_ack()
}
-static void test_sgsn_reset()
+static void test_sgsn_reset(void)
{
struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
struct sockaddr_in sgsn_peer= {0};
@@ -765,7 +765,7 @@ static void test_sgsn_reset()
nsi = NULL;
}
-static void test_sgsn_reset_invalid_state()
+static void test_sgsn_reset_invalid_state(void)
{
struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
struct sockaddr_in sgsn_peer= {0};
@@ -833,7 +833,7 @@ static void test_sgsn_reset_invalid_state()
nsi = NULL;
}
-static void test_sgsn_output()
+static void test_sgsn_output(void)
{
struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
struct sockaddr_in sgsn_peer= {0};
@@ -904,11 +904,11 @@ int main(int argc, char **argv)
void *ctx = talloc_named_const(NULL, 0, "gprs_ns_test");
osmo_init_logging2(ctx, &info);
log_set_use_color(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
- osmo_signal_register_handler(SS_L_NS, &test_signal, NULL);
-
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_category(osmo_stderr_target, 0);
+ log_set_print_category_hex(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
log_set_log_level(osmo_stderr_target, LOGL_INFO);
+ osmo_signal_register_handler(SS_L_NS, &test_signal, NULL);
setlinebuf(stdout);
diff --git a/tests/gb/osmo-ns-dummy.cfg b/tests/gb/osmo-ns-dummy.cfg
new file mode 100644
index 00000000..72696189
--- /dev/null
+++ b/tests/gb/osmo-ns-dummy.cfg
@@ -0,0 +1,25 @@
+!
+! OsmoNSdummy (1.4.0.495-64db) configuration saved from vty
+!!
+ns
+ timer tns-block 3
+ timer tns-block-retries 3
+ timer tns-reset 3
+ timer tns-reset-retries 3
+ timer tns-test 30
+ timer tns-alive 3
+ timer tns-alive-retries 10
+ timer tsns-prov 3
+ timer tsns-size-retries 3
+ timer tsns-config-retries 3
+ bind udp local
+ listen 127.0.0.1 2158
+ accept-ipaccess
+ ip-sns signalling-weight 1 data-weight 1
+ nse 1236
+ nsvc ipa local 127.0.0.4 23000 nsvci 101
+ nse 1235
+ nsvc udp local 127.0.0.3 23000
+ nse 1234
+ ip-sns-bind local
+ ip-sns-remote 127.0.0.2 2158
diff --git a/tests/gb/osmoappdesc.py b/tests/gb/osmoappdesc.py
new file mode 100644
index 00000000..323b94ef
--- /dev/null
+++ b/tests/gb/osmoappdesc.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+
+# (C) 2021 by sysmocom - s.f.m.c. GmbH
+# Author: Alexander Couzens <lynxis@fe80.eu>
+# 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 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>
+
+app_configs = {
+ "osmo-ns-dummy": ["osmo-ns-dummy.cfg"],
+}
+
+apps = [(45999, "../../utils/osmo-ns-dummy -p 45999", "OsmoNSdummy", "osmo-ns-dummy")
+ ]
+
+vty_command = ["../../utils/osmo-ns-dummy", "-p", "45999", "-c", "osmo-ns-dummy.cfg"]
+
+vty_app = apps[0]
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index d2ae6f6c..4436d517 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -69,6 +65,18 @@ static const struct gsm_mncc_bearer_cap bcap_speech_all = {
},
};
+static const uint8_t speech_no3a_lv[] = { 0x01, 0xa0 };
+
+static const struct gsm_mncc_bearer_cap bcap_speech_no3a = {
+ .transfer = GSM48_BCAP_ITCAP_SPEECH,
+ .mode = GSM48_BCAP_TMOD_CIRCUIT,
+ .coding = GSM48_BCAP_CODING_GSM_STD,
+ .radio = GSM48_BCAP_RRQ_FR_ONLY,
+ .speech_ver = {
+ 0, -1,
+ },
+};
+
struct bcap_test {
const uint8_t *lv;
@@ -79,15 +87,17 @@ struct bcap_test {
static const struct bcap_test bcap_tests[] = {
{ csd_9600_v110_lv, &bcap_csd_9600_v110, "CSD 9600/V.110/transparent" },
{ speech_all_lv, &bcap_speech_all, "Speech, all codecs" },
+ { speech_no3a_lv, &bcap_speech_no3a, "Speech, without octet 3a" },
};
-static int test_bearer_cap()
+static int test_bearer_cap(void)
{
struct gsm_mncc_bearer_cap bc;
int i, rc;
for (i = 0; i < ARRAY_SIZE(bcap_tests); i++) {
struct msgb *msg = msgb_alloc(100, "test");
+ bool pass = false;
int lv_len;
memset(&bc, 0, sizeof(bc));
@@ -97,7 +107,7 @@ static int test_bearer_cap()
if (rc < 0) {
fprintf(stderr, "Error decoding %s\n",
bcap_tests[i].name);
- return rc;
+ goto verdict;
}
if (memcmp(&bc, bcap_tests[i].bc, sizeof(bc))) {
fprintf(stderr, "Incorrect decoded result of %s:\n",
@@ -106,7 +116,7 @@ static int test_bearer_cap()
osmo_hexdump((uint8_t *) bcap_tests[i].bc, sizeof(bc)));
fprintf(stderr, " is: %s\n",
osmo_hexdump((uint8_t *) &bc, sizeof(bc)));
- return -1;
+ goto verdict;
}
/* also test re-encode? */
@@ -114,7 +124,7 @@ static int test_bearer_cap()
if (rc < 0) {
fprintf(stderr, "Error encoding %s\n",
bcap_tests[i].name);
- return rc;
+ goto verdict;
}
lv_len = bcap_tests[i].lv[0]+1;
if (memcmp(msg->data, bcap_tests[i].lv, lv_len)) {
@@ -124,10 +134,14 @@ static int test_bearer_cap()
osmo_hexdump(bcap_tests[i].lv, lv_len));
fprintf(stderr, " is: %s\n",
osmo_hexdump(msg->data, msg->len));
- return -1;
+ goto verdict;
}
- printf("Test `%s' passed\n", bcap_tests[i].name);
+ /* all checks passed */
+ pass = true;
+
+verdict:
+ printf("Test `%s' %sed\n", bcap_tests[i].name, pass ? "pass" : "fail");
msgb_free(msg);
}
@@ -327,6 +341,203 @@ static void test_lai_encode_decode(void)
}
}
+static void dump_cm3(struct gsm48_classmark3 *cm3)
+{
+ printf("mult_band_supp=%02x\n", cm3->mult_band_supp);
+ printf("a5_bits=%02x\n", cm3->a5_bits);
+ printf("assoc_radio_cap_1=%02x\n", cm3->assoc_radio_cap_1);
+ printf("assoc_radio_cap_2=%02x\n", cm3->assoc_radio_cap_2);
+ printf("\n");
+ printf("r_support.present=%u\n", cm3->r_support.present);
+ printf("r_support.r_gsm_assoc_radio_cap=%02x\n",
+ cm3->r_support.r_gsm_assoc_radio_cap);
+ printf("\n");
+ printf("hscsd_mult_slot_cap.present=%u\n",
+ cm3->hscsd_mult_slot_cap.present);
+ printf("hscsd_mult_slot_cap.mslot_class=%02x\n",
+ cm3->hscsd_mult_slot_cap.mslot_class);
+ printf("\n");
+ printf("ucs2_treatment=%u\n", cm3->ucs2_treatment);
+ printf("extended_meas_cap=%u\n", cm3->extended_meas_cap);
+ printf("\n");
+ printf("ms_meas_cap.present=%u\n", cm3->ms_meas_cap.present);
+ printf("ms_meas_cap.sms_value=%02x\n", cm3->ms_meas_cap.sms_value);
+ printf("ms_meas_cap.sm_value=%02x\n", cm3->ms_meas_cap.sm_value);
+ printf("\n");
+ printf("ms_pos_method_cap.present=%u\n",
+ cm3->ms_pos_method_cap.present);
+ printf("ms_pos_method_cap.method=%02x\n",
+ cm3->ms_pos_method_cap.method);
+ printf("\n");
+ printf("ecsd_multislot_cap.present=%u\n",
+ cm3->ecsd_multislot_cap.present);
+ printf("ecsd_multislot_cap.mslot_class=%02x\n",
+ cm3->ecsd_multislot_cap.mslot_class);
+ printf("\n");
+ printf("psk8_struct.present=%u\n", cm3->psk8_struct.present);
+ printf("psk8_struct.mod_cap=%u\n", cm3->psk8_struct.mod_cap);
+ printf("psk8_struct.rf_pwr_cap_1.present=%u\n",
+ cm3->psk8_struct.rf_pwr_cap_1.present);
+ printf("psk8_struct.rf_pwr_cap_1.value=%02x\n",
+ cm3->psk8_struct.rf_pwr_cap_1.value);
+ printf("psk8_struct.rf_pwr_cap_2.present=%u\n",
+ cm3->psk8_struct.rf_pwr_cap_2.present);
+ printf("psk8_struct.rf_pwr_cap_2.value=%02x\n",
+ cm3->psk8_struct.rf_pwr_cap_2.value);
+ printf("\n");
+ printf("gsm_400_bands_supp.present=%u\n",
+ cm3->gsm_400_bands_supp.present);
+ printf("gsm_400_bands_supp.value=%02x\n",
+ cm3->gsm_400_bands_supp.value);
+ printf("gsm_400_bands_supp.assoc_radio_cap=%02x\n",
+ cm3->gsm_400_bands_supp.assoc_radio_cap);
+ printf("\n");
+ printf("gsm_850_assoc_radio_cap.present=%u\n",
+ cm3->gsm_850_assoc_radio_cap.present);
+ printf("gsm_850_assoc_radio_cap.value=%02x\n",
+ cm3->gsm_850_assoc_radio_cap.value);
+ printf("\n");
+ printf("gsm_1900_assoc_radio_cap.present=%u\n",
+ cm3->gsm_1900_assoc_radio_cap.present);
+ printf("gsm_1900_assoc_radio_cap.value=%02x\n",
+ cm3->gsm_1900_assoc_radio_cap.value);
+ printf("\n");
+ printf("umts_fdd_rat_cap=%u\n", cm3->umts_fdd_rat_cap);
+ printf("umts_tdd_rat_cap=%u\n", cm3->umts_tdd_rat_cap);
+ printf("cdma200_rat_cap=%u\n", cm3->cdma200_rat_cap);
+ printf("\n");
+ printf("dtm_gprs_multislot_cap.present=%u\n",
+ cm3->dtm_gprs_multislot_cap.present);
+ printf("dtm_gprs_multislot_cap.mslot_class=%02x\n",
+ cm3->dtm_gprs_multislot_cap.mslot_class);
+ printf("dtm_gprs_multislot_cap.single_slot_dtm=%u\n",
+ cm3->dtm_gprs_multislot_cap.single_slot_dtm);
+ printf("dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=%u\n",
+ cm3->dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present);
+ printf("dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=%02x\n",
+ cm3->dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class);
+ printf("\n");
+ printf("single_band_supp.present=%u\n", cm3->single_band_supp.present);
+ printf("single_band_supp.value=%u\n", cm3->single_band_supp.value);
+ printf("\n");
+ printf("gsm_750_assoc_radio_cap.present=%u\n",
+ cm3->gsm_750_assoc_radio_cap.present);
+ printf("gsm_750_assoc_radio_cap.value=%02x\n",
+ cm3->gsm_750_assoc_radio_cap.value);
+ printf("\n");
+ printf("umts_1_28_mcps_tdd_rat_cap=%u\n",
+ cm3->umts_1_28_mcps_tdd_rat_cap);
+ printf("geran_feature_package=%u\n", cm3->geran_feature_package);
+ printf("\n");
+ printf("extended_dtm_gprs_multislot_cap.present=%u\n",
+ cm3->extended_dtm_gprs_multislot_cap.present);
+ printf("extended_dtm_gprs_multislot_cap.mslot_class=%02x\n",
+ cm3->extended_dtm_gprs_multislot_cap.mslot_class);
+ printf
+ ("extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=%u\n",
+ cm3->extended_dtm_gprs_multislot_cap.
+ extended_dtm_egprs_multislot_cap.present);
+ printf
+ ("extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=%02x\n",
+ cm3->extended_dtm_gprs_multislot_cap.
+ extended_dtm_egprs_multislot_cap.mslot_class);
+ printf("\n");
+ printf("high_multislot_cap.present=%u\n",
+ cm3->high_multislot_cap.present);
+ printf("high_multislot_cap.value=%02x\n",
+ cm3->high_multislot_cap.value);
+ printf("\n");
+ printf("geran_feature_package_2=%u\n", cm3->geran_feature_package_2);
+ printf("gmsk_multislot_power_prof=%02x\n",
+ cm3->gmsk_multislot_power_prof);
+ printf("psk8_multislot_power_prof=%02x\n",
+ cm3->psk8_multislot_power_prof);
+ printf("\n");
+ printf("t_gsm_400_bands_supp.present=%u\n",
+ cm3->t_gsm_400_bands_supp.present);
+ printf("t_gsm_400_bands_supp.value=%02x\n",
+ cm3->t_gsm_400_bands_supp.value);
+ printf("t_gsm_400_bands_supp.assoc_radio_cap=%02x\n",
+ cm3->t_gsm_400_bands_supp.assoc_radio_cap);
+ printf("\n");
+ printf("dl_advanced_rx_perf=%02x\n", cm3->dl_advanced_rx_perf);
+ printf("dtm_enhancements_cap=%u\n", cm3->dtm_enhancements_cap);
+ printf("\n");
+ printf("dtm_gprs_high_multislot_cap.present=%u\n",
+ cm3->dtm_gprs_high_multislot_cap.present);
+ printf("dtm_gprs_high_multislot_cap.mslot_class=%02x\n",
+ cm3->dtm_gprs_high_multislot_cap.mslot_class);
+ printf("dtm_gprs_high_multislot_cap.offset_required=%u\n",
+ cm3->dtm_gprs_high_multislot_cap.offset_required);
+ printf
+ ("dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.present=%u\n",
+ cm3->dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.
+ present);
+ printf
+ ("dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.mslot_class=%02x\n",
+ cm3->dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.
+ mslot_class);
+ printf("\n");
+ printf("repeated_acch_capability=%u\n", cm3->repeated_acch_capability);
+ printf("\n");
+ printf("gsm_710_assoc_radio_cap.present=%u\n",
+ cm3->gsm_710_assoc_radio_cap.present);
+ printf("gsm_710_assoc_radio_cap.value=%02x\n",
+ cm3->gsm_710_assoc_radio_cap.value);
+ printf("\n");
+ printf("t_gsm_810_assoc_radio_cap.present=%u\n",
+ cm3->t_gsm_810_assoc_radio_cap.present);
+ printf("t_gsm_810_assoc_radio_cap.value=%02x\n",
+ cm3->t_gsm_810_assoc_radio_cap.value);
+ printf("\n");
+ printf("ciphering_mode_setting_cap=%u\n",
+ cm3->ciphering_mode_setting_cap);
+ printf("add_pos_cap=%u\n", cm3->add_pos_cap);
+ printf("e_utra_fdd_supp=%u\n", cm3->e_utra_fdd_supp);
+ printf("e_utra_tdd_supp=%u\n", cm3->e_utra_tdd_supp);
+ printf("e_utra_meas_rep_supp=%u\n", cm3->e_utra_meas_rep_supp);
+ printf("prio_resel_supp=%u\n", cm3->prio_resel_supp);
+ printf("utra_csg_cells_rep=%u\n", cm3->utra_csg_cells_rep);
+ printf("vamos_level=%02x\n", cm3->vamos_level);
+ printf("tighter_capability=%02x\n", cm3->tighter_capability);
+ printf("sel_ciph_dl_sacch=%u\n", cm3->sel_ciph_dl_sacch);
+ printf("cs_ps_srvcc_geran_utra=%02x\n", cm3->cs_ps_srvcc_geran_utra);
+ printf("cs_ps_srvcc_geran_eutra=%02x\n", cm3->cs_ps_srvcc_geran_eutra);
+ printf("geran_net_sharing=%u\n", cm3->geran_net_sharing);
+ printf("e_utra_wb_rsrq_meas_supp=%u\n", cm3->e_utra_wb_rsrq_meas_supp);
+ printf("er_band_support=%u\n", cm3->er_band_support);
+ printf("utra_mult_band_ind_supp=%u\n", cm3->utra_mult_band_ind_supp);
+ printf("e_utra_mult_band_ind_supp=%u\n",
+ cm3->e_utra_mult_band_ind_supp);
+ printf("extended_tsc_set_cap_supp=%u\n",
+ cm3->extended_tsc_set_cap_supp);
+ printf("extended_earfcn_val_range=%u\n",
+ cm3->extended_earfcn_val_range);
+}
+
+static void test_decode_classmark3(void)
+{
+ struct gsm48_classmark3 cm3;
+ const uint8_t cm3_1[] = { 0x60, 0x14, 0x04, 0x2f, 0x65, 0x00, 0x20, 0x03, 0x40, 0x4a };
+ const uint8_t cm3_2[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
+ const uint8_t cm3_3[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
+
+ printf("=====cm3_1=====\n");
+ gsm48_decode_classmark3(&cm3, cm3_1, sizeof(cm3_1));
+ dump_cm3(&cm3);
+ printf("\n");
+
+ printf("=====cm3_2=====\n");
+ gsm48_decode_classmark3(&cm3, cm3_2, sizeof(cm3_2));
+ dump_cm3(&cm3);
+ printf("\n");
+
+ printf("=====cm3_3=====\n");
+ gsm48_decode_classmark3(&cm3, cm3_3, sizeof(cm3_3));
+ dump_cm3(&cm3);
+ printf("\n");
+}
+
static void test_mid_from_tmsi(void)
{
static const uint8_t res[] = { 0x17, 0x05, 0xf4, 0xaa, 0xbb, 0xcc, 0xdd };
@@ -943,7 +1154,7 @@ struct mobile_identity_tc mobile_identity_tests[] = {
},
};
-void test_struct_mobile_identity()
+void test_struct_mobile_identity(void)
{
struct mobile_identity_tc *t;
printf("%s()\n", __func__);
@@ -957,7 +1168,7 @@ void test_struct_mobile_identity()
rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false);
msgb_free(msg);
- printf("%s: rc = %d", t->label, rc);
+ printf("%s: %s", t->label, rc ? "rc != 0" : "rc == 0");
if (!rc) {
printf(", mi = %s", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
}
@@ -966,7 +1177,7 @@ void test_struct_mobile_identity()
&& ((rc != 0) || !osmo_mobile_identity_cmp(&mi, &t->expect_mi))) {
printf(" ok");
} else {
- printf(" ERROR: Expected rc = %d", t->expect_rc);
+ printf(" ERROR: Got rc = %d, expected rc = %d", rc, t->expect_rc);
if (!t->expect_rc)
printf(", mi = %s", osmo_mobile_identity_to_str_c(OTC_SELECT, &t->expect_mi));
}
@@ -1105,7 +1316,7 @@ static const struct bcd_number_test {
},
};
-static void test_bcd_number_encode_decode()
+static void test_bcd_number_encode_decode(void)
{
const struct bcd_number_test *test;
uint8_t buf_enc[0xff] = { 0xff };
@@ -1339,7 +1550,7 @@ static void test_random_range_encoding(int range, int max_arfcn_num)
}
}
-static void test_range_encoding()
+static void test_range_encoding(void)
{
int *arfcns;
int arfcns_num = 0;
@@ -1400,7 +1611,7 @@ static int range512[] = {
__FILE__, __LINE__, (int) res, # cmp, (int) wanted); \
}
-static void test_arfcn_filter()
+static void test_arfcn_filter(void)
{
int arfcns[50], i, res, f0_included;
for (i = 0; i < ARRAY_SIZE(arfcns); ++i)
@@ -1433,7 +1644,7 @@ static void test_arfcn_filter()
VERIFY(arfcns[i], ==, ((i + 1) * 2) - 1);
}
-static void test_print_encoding()
+static void test_print_encoding(void)
{
int rc;
int w[17];
@@ -1458,7 +1669,7 @@ static void test_print_encoding()
printf("Range512: %s\n", osmo_hexdump(chan_list, ARRAY_SIZE(chan_list)));
}
-static void test_si_range_helpers()
+static void test_si_range_helpers(void)
{
int ws[(sizeof(freqs1)/sizeof(freqs1[0]))];
int i, f0 = 0xFFFFFF;
@@ -1497,7 +1708,7 @@ static void test_si_range_helpers()
VERIFY(f0, ==, 1);
}
-static void test_power_ctrl()
+static void test_power_ctrl(void)
{
int8_t rc8;
int rc;
@@ -1539,6 +1750,37 @@ static void test_power_ctrl()
VERIFY(rc, <, 0);
}
+static void test_rach_tx_integer_raw2val(void)
+{
+ unsigned int raw;
+ for (raw = 0; raw <= 0x0f; raw++) {
+ unsigned int val = rach_tx_integer_raw2val(raw);
+ printf("rach_tx_integer_raw2val(0x0%x): %u slots used to spread transmission\n",
+ raw, val);
+ }
+}
+
+static void test_gsm_gsmtime2fn(void)
+{
+ struct gsm_time gsm_time;
+ uint32_t fn;
+ uint32_t fn_recovered;
+
+ for (fn = 0; fn < 42432; fn++) {
+ gsm_time.t1 = (fn / 1326) % 32;
+ gsm_time.t2 = fn % 26;
+ gsm_time.t3 = fn % 51;
+
+ fn_recovered = gsm_gsmtime2fn(&gsm_time);
+
+ if (fn_recovered != fn) {
+ printf(" Wrong frame number computed! t1=%d, t2=%d, t3=%d ==> fn=%d, expected fn=%d\n",
+ gsm_time.t1, gsm_time.t2, gsm_time.t3, fn_recovered, fn);
+ OSMO_ASSERT(false);
+ }
+ }
+}
+
int main(int argc, char **argv)
{
test_bearer_cap();
@@ -1550,12 +1792,15 @@ int main(int argc, char **argv)
test_bcd_number_encode_decode();
test_ra_cap();
test_lai_encode_decode();
+ test_decode_classmark3();
test_si_range_helpers();
test_arfcn_filter();
test_print_encoding();
test_range_encoding();
test_power_ctrl();
+ test_rach_tx_integer_raw2val();
+ test_gsm_gsmtime2fn();
return EXIT_SUCCESS;
}
diff --git a/tests/gsm0408/gsm0408_test.err b/tests/gsm0408/gsm0408_test.err
new file mode 100644
index 00000000..8aeda3ed
--- /dev/null
+++ b/tests/gsm0408/gsm0408_test.err
@@ -0,0 +1,3 @@
+Incorrect encoded result of Speech, without octet 3a:
+ should: 01 a0
+ is: 02 20 80
diff --git a/tests/gsm0408/gsm0408_test.ok b/tests/gsm0408/gsm0408_test.ok
index 3e6ae1f4..dc48f84a 100644
--- a/tests/gsm0408/gsm0408_test.ok
+++ b/tests/gsm0408/gsm0408_test.ok
@@ -1,5 +1,6 @@
Test `CSD 9600/V.110/transparent' passed
Test `Speech, all codecs' passed
+Test `Speech, without octet 3a' failed
Simple TMSI encoding test....passed
Simple IMSI encoding test....passed: [10] 17 08 99 10 07 00 00 00 64 02
@@ -140,55 +141,55 @@ Decoding zero length Mobile Identities
returned empty string
test_struct_mobile_identity()
-LU with IMSI 901700000004620: rc = 0, mi = IMSI-901700000004620 ok
-LU with TMSI 0x0980ad8a: rc = 0, mi = TMSI-0x0980AD8A ok
-LU with invalid MI type: rc = -22 ok
-LU with truncated IMSI MI: rc = -74 ok
-LU with too short IMSI MI (12345): rc = -74 ok
-LU with just long enough IMSI MI 123456: rc = 0, mi = IMSI-123456 ok
-LU with max length IMSI MI 123456789012345: rc = 0, mi = IMSI-123456789012345 ok
-LU with just too long IMSI MI 1234567890123456: rc = -74 ok
-LU with truncated TMSI MI: rc = -74 ok
-LU with odd length TMSI: rc = -74 ok
-LU with too long TMSI MI: rc = -74 ok
-LU with too short TMSI: rc = -74 ok
-CM Service Request with IMSI 123456: rc = 0, mi = IMSI-123456 ok
-CM Service Request with TMSI 0x5a42e404: rc = 0, mi = TMSI-0x5A42E404 ok
-CM Service Request with shorter CM2, with IMSI 123456: rc = 0, mi = IMSI-123456 ok
-CM Service Request with longer CM2, with IMSI 123456: rc = 0, mi = IMSI-123456 ok
-CM Service Request with shorter CM2, with TMSI 0x00000000: rc = 0, mi = TMSI-0x00000000 ok
-CM Service Request with invalid MI type: rc = -22 ok
-CM Service Request with truncated IMSI MI: rc = -74 ok
-CM Service Request with truncated TMSI MI: rc = -74 ok
-CM Service Request with odd length TMSI: rc = -74 ok
-CM Service Request with too long TMSI MI: rc = -74 ok
-CM Service Request with too short TMSI: rc = -74 ok
-CM Service Reestablish Request with TMSI 0x5a42e404: rc = 0, mi = TMSI-0x5A42E404 ok
-Paging Response with IMSI 1234567: rc = 0, mi = IMSI-1234567 ok
-Paging Response with TMSI 0xb48883de: rc = 0, mi = TMSI-0xB48883DE ok
-Paging Response with TMSI, with unused nibble not 0xf: rc = -74 ok
-Paging Response with too short IMEI (1234567): rc = -74 ok
-Paging Response with IMEI 123456789012345: rc = 0, mi = IMEI-123456789012345 ok
-Paging Response with IMEI 12345678901234 (no Luhn checksum): rc = 0, mi = IMEI-12345678901234 ok
-Paging Response with IMEISV 1234567890123456: rc = 0, mi = IMEI-SV-1234567890123456 ok
-Paging Response with too short IMEISV 123456789012345: rc = -74 ok
-Paging Response with too long IMEISV 12345678901234567: rc = -74 ok
-Paging Response with IMSI 123456789012345 and flipped ODD bit: rc = -74 ok
-IMSI-Detach with IMSI 901700000004620: rc = 0, mi = IMSI-901700000004620 ok
-IMSI-Detach with TMSI 0x0980ad8a: rc = 0, mi = TMSI-0x0980AD8A ok
-IMSI-Detach with invalid MI type: rc = -22 ok
-IMSI-Detach with truncated IMSI MI: rc = -74 ok
-IMSI-Detach with too short IMSI MI (12345): rc = -74 ok
-IMSI-Detach with just long enough IMSI MI 123456: rc = 0, mi = IMSI-123456 ok
-IMSI-Detach with max length IMSI MI 123456789012345: rc = 0, mi = IMSI-123456789012345 ok
-IMSI-Detach with just too long IMSI MI 1234567890123456: rc = -74 ok
-IMSI-Detach with truncated TMSI MI: rc = -74 ok
-IMSI-Detach with odd length TMSI: rc = -74 ok
-IMSI-Detach with too long TMSI MI: rc = -74 ok
-IMSI-Detach with too short TMSI: rc = -74 ok
-Identity Response with IMSI 901700000004620: rc = 0, mi = IMSI-901700000004620 ok
-Identity Response with IMEI 123456789012345: rc = 0, mi = IMEI-123456789012345 ok
-Identity Response with IMEISV 9876543210987654: rc = 0, mi = IMEI-SV-9876543210987654 ok
+LU with IMSI 901700000004620: rc == 0, mi = IMSI-901700000004620 ok
+LU with TMSI 0x0980ad8a: rc == 0, mi = TMSI-0x0980AD8A ok
+LU with invalid MI type: rc != 0 ok
+LU with truncated IMSI MI: rc != 0 ok
+LU with too short IMSI MI (12345): rc != 0 ok
+LU with just long enough IMSI MI 123456: rc == 0, mi = IMSI-123456 ok
+LU with max length IMSI MI 123456789012345: rc == 0, mi = IMSI-123456789012345 ok
+LU with just too long IMSI MI 1234567890123456: rc != 0 ok
+LU with truncated TMSI MI: rc != 0 ok
+LU with odd length TMSI: rc != 0 ok
+LU with too long TMSI MI: rc != 0 ok
+LU with too short TMSI: rc != 0 ok
+CM Service Request with IMSI 123456: rc == 0, mi = IMSI-123456 ok
+CM Service Request with TMSI 0x5a42e404: rc == 0, mi = TMSI-0x5A42E404 ok
+CM Service Request with shorter CM2, with IMSI 123456: rc == 0, mi = IMSI-123456 ok
+CM Service Request with longer CM2, with IMSI 123456: rc == 0, mi = IMSI-123456 ok
+CM Service Request with shorter CM2, with TMSI 0x00000000: rc == 0, mi = TMSI-0x00000000 ok
+CM Service Request with invalid MI type: rc != 0 ok
+CM Service Request with truncated IMSI MI: rc != 0 ok
+CM Service Request with truncated TMSI MI: rc != 0 ok
+CM Service Request with odd length TMSI: rc != 0 ok
+CM Service Request with too long TMSI MI: rc != 0 ok
+CM Service Request with too short TMSI: rc != 0 ok
+CM Service Reestablish Request with TMSI 0x5a42e404: rc == 0, mi = TMSI-0x5A42E404 ok
+Paging Response with IMSI 1234567: rc == 0, mi = IMSI-1234567 ok
+Paging Response with TMSI 0xb48883de: rc == 0, mi = TMSI-0xB48883DE ok
+Paging Response with TMSI, with unused nibble not 0xf: rc != 0 ok
+Paging Response with too short IMEI (1234567): rc != 0 ok
+Paging Response with IMEI 123456789012345: rc == 0, mi = IMEI-123456789012345 ok
+Paging Response with IMEI 12345678901234 (no Luhn checksum): rc == 0, mi = IMEI-12345678901234 ok
+Paging Response with IMEISV 1234567890123456: rc == 0, mi = IMEI-SV-1234567890123456 ok
+Paging Response with too short IMEISV 123456789012345: rc != 0 ok
+Paging Response with too long IMEISV 12345678901234567: rc != 0 ok
+Paging Response with IMSI 123456789012345 and flipped ODD bit: rc != 0 ok
+IMSI-Detach with IMSI 901700000004620: rc == 0, mi = IMSI-901700000004620 ok
+IMSI-Detach with TMSI 0x0980ad8a: rc == 0, mi = TMSI-0x0980AD8A ok
+IMSI-Detach with invalid MI type: rc != 0 ok
+IMSI-Detach with truncated IMSI MI: rc != 0 ok
+IMSI-Detach with too short IMSI MI (12345): rc != 0 ok
+IMSI-Detach with just long enough IMSI MI 123456: rc == 0, mi = IMSI-123456 ok
+IMSI-Detach with max length IMSI MI 123456789012345: rc == 0, mi = IMSI-123456789012345 ok
+IMSI-Detach with just too long IMSI MI 1234567890123456: rc != 0 ok
+IMSI-Detach with truncated TMSI MI: rc != 0 ok
+IMSI-Detach with odd length TMSI: rc != 0 ok
+IMSI-Detach with too long TMSI MI: rc != 0 ok
+IMSI-Detach with too short TMSI: rc != 0 ok
+Identity Response with IMSI 901700000004620: rc == 0, mi = IMSI-901700000004620 ok
+Identity Response with IMEI 123456789012345: rc == 0, mi = IMEI-123456789012345 ok
+Identity Response with IMEISV 9876543210987654: rc == 0, mi = IMEI-SV-9876543210987654 ok
BSD number encoding / decoding test
- Running test: regular 9-digit MSISDN
@@ -385,6 +386,348 @@ RA test...passed
Encoded 21 63 54 00 17
gsm48_decode_lai2() gives 123-456-23 (3-digit MNC)
passed
+=====cm3_1=====
+mult_band_supp=06
+a5_bits=00
+assoc_radio_cap_1=04
+assoc_radio_cap_2=01
+
+r_support.present=0
+r_support.r_gsm_assoc_radio_cap=00
+
+hscsd_mult_slot_cap.present=0
+hscsd_mult_slot_cap.mslot_class=00
+
+ucs2_treatment=0
+extended_meas_cap=0
+
+ms_meas_cap.present=0
+ms_meas_cap.sms_value=00
+ms_meas_cap.sm_value=00
+
+ms_pos_method_cap.present=1
+ms_pos_method_cap.method=01
+
+ecsd_multislot_cap.present=0
+ecsd_multislot_cap.mslot_class=00
+
+psk8_struct.present=1
+psk8_struct.mod_cap=1
+psk8_struct.rf_pwr_cap_1.present=1
+psk8_struct.rf_pwr_cap_1.value=02
+psk8_struct.rf_pwr_cap_2.present=1
+psk8_struct.rf_pwr_cap_2.value=02
+
+gsm_400_bands_supp.present=0
+gsm_400_bands_supp.value=00
+gsm_400_bands_supp.assoc_radio_cap=00
+
+gsm_850_assoc_radio_cap.present=1
+gsm_850_assoc_radio_cap.value=04
+
+gsm_1900_assoc_radio_cap.present=0
+gsm_1900_assoc_radio_cap.value=00
+
+umts_fdd_rat_cap=0
+umts_tdd_rat_cap=0
+cdma200_rat_cap=0
+
+dtm_gprs_multislot_cap.present=0
+dtm_gprs_multislot_cap.mslot_class=00
+dtm_gprs_multislot_cap.single_slot_dtm=0
+dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=0
+dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=00
+
+single_band_supp.present=0
+single_band_supp.value=0
+
+gsm_750_assoc_radio_cap.present=0
+gsm_750_assoc_radio_cap.value=00
+
+umts_1_28_mcps_tdd_rat_cap=0
+geran_feature_package=1
+
+extended_dtm_gprs_multislot_cap.present=0
+extended_dtm_gprs_multislot_cap.mslot_class=00
+extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=0
+extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=00
+
+high_multislot_cap.present=0
+high_multislot_cap.value=00
+
+geran_feature_package_2=0
+gmsk_multislot_power_prof=00
+psk8_multislot_power_prof=00
+
+t_gsm_400_bands_supp.present=0
+t_gsm_400_bands_supp.value=00
+t_gsm_400_bands_supp.assoc_radio_cap=00
+
+dl_advanced_rx_perf=01
+dtm_enhancements_cap=1
+
+dtm_gprs_high_multislot_cap.present=0
+dtm_gprs_high_multislot_cap.mslot_class=00
+dtm_gprs_high_multislot_cap.offset_required=0
+dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.present=0
+dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.mslot_class=00
+
+repeated_acch_capability=1
+
+gsm_710_assoc_radio_cap.present=0
+gsm_710_assoc_radio_cap.value=00
+
+t_gsm_810_assoc_radio_cap.present=0
+t_gsm_810_assoc_radio_cap.value=00
+
+ciphering_mode_setting_cap=0
+add_pos_cap=0
+e_utra_fdd_supp=0
+e_utra_tdd_supp=0
+e_utra_meas_rep_supp=0
+prio_resel_supp=1
+utra_csg_cells_rep=0
+vamos_level=01
+tighter_capability=01
+sel_ciph_dl_sacch=0
+cs_ps_srvcc_geran_utra=00
+cs_ps_srvcc_geran_eutra=00
+geran_net_sharing=0
+e_utra_wb_rsrq_meas_supp=0
+er_band_support=0
+utra_mult_band_ind_supp=0
+e_utra_mult_band_ind_supp=0
+extended_tsc_set_cap_supp=0
+extended_earfcn_val_range=0
+
+=====cm3_2=====
+mult_band_supp=05
+a5_bits=05
+assoc_radio_cap_1=05
+assoc_radio_cap_2=05
+
+r_support.present=0
+r_support.r_gsm_assoc_radio_cap=00
+
+hscsd_mult_slot_cap.present=1
+hscsd_mult_slot_cap.mslot_class=0a
+
+ucs2_treatment=1
+extended_meas_cap=0
+
+ms_meas_cap.present=1
+ms_meas_cap.sms_value=05
+ms_meas_cap.sm_value=05
+
+ms_pos_method_cap.present=0
+ms_pos_method_cap.method=00
+
+ecsd_multislot_cap.present=1
+ecsd_multislot_cap.mslot_class=0a
+
+psk8_struct.present=1
+psk8_struct.mod_cap=0
+psk8_struct.rf_pwr_cap_1.present=1
+psk8_struct.rf_pwr_cap_1.value=01
+psk8_struct.rf_pwr_cap_2.present=0
+psk8_struct.rf_pwr_cap_2.value=00
+
+gsm_400_bands_supp.present=1
+gsm_400_bands_supp.value=01
+gsm_400_bands_supp.assoc_radio_cap=05
+
+gsm_850_assoc_radio_cap.present=0
+gsm_850_assoc_radio_cap.value=00
+
+gsm_1900_assoc_radio_cap.present=1
+gsm_1900_assoc_radio_cap.value=05
+
+umts_fdd_rat_cap=0
+umts_tdd_rat_cap=1
+cdma200_rat_cap=0
+
+dtm_gprs_multislot_cap.present=1
+dtm_gprs_multislot_cap.mslot_class=01
+dtm_gprs_multislot_cap.single_slot_dtm=0
+dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=1
+dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=01
+
+single_band_supp.present=0
+single_band_supp.value=0
+
+gsm_750_assoc_radio_cap.present=1
+gsm_750_assoc_radio_cap.value=05
+
+umts_1_28_mcps_tdd_rat_cap=0
+geran_feature_package=1
+
+extended_dtm_gprs_multislot_cap.present=0
+extended_dtm_gprs_multislot_cap.mslot_class=00
+extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=0
+extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=00
+
+high_multislot_cap.present=1
+high_multislot_cap.value=01
+
+geran_feature_package_2=1
+gmsk_multislot_power_prof=01
+psk8_multislot_power_prof=01
+
+t_gsm_400_bands_supp.present=0
+t_gsm_400_bands_supp.value=00
+t_gsm_400_bands_supp.assoc_radio_cap=00
+
+dl_advanced_rx_perf=01
+dtm_enhancements_cap=0
+
+dtm_gprs_high_multislot_cap.present=1
+dtm_gprs_high_multislot_cap.mslot_class=02
+dtm_gprs_high_multislot_cap.offset_required=1
+dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.present=0
+dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.mslot_class=00
+
+repeated_acch_capability=1
+
+gsm_710_assoc_radio_cap.present=0
+gsm_710_assoc_radio_cap.value=00
+
+t_gsm_810_assoc_radio_cap.present=1
+t_gsm_810_assoc_radio_cap.value=05
+
+ciphering_mode_setting_cap=0
+add_pos_cap=1
+e_utra_fdd_supp=0
+e_utra_tdd_supp=0
+e_utra_meas_rep_supp=0
+prio_resel_supp=0
+utra_csg_cells_rep=0
+vamos_level=00
+tighter_capability=00
+sel_ciph_dl_sacch=0
+cs_ps_srvcc_geran_utra=00
+cs_ps_srvcc_geran_eutra=00
+geran_net_sharing=0
+e_utra_wb_rsrq_meas_supp=0
+er_band_support=0
+utra_mult_band_ind_supp=0
+e_utra_mult_band_ind_supp=0
+extended_tsc_set_cap_supp=0
+extended_earfcn_val_range=0
+
+=====cm3_3=====
+mult_band_supp=02
+a5_bits=0a
+assoc_radio_cap_1=0a
+assoc_radio_cap_2=00
+
+r_support.present=1
+r_support.r_gsm_assoc_radio_cap=02
+
+hscsd_mult_slot_cap.present=1
+hscsd_mult_slot_cap.mslot_class=0a
+
+ucs2_treatment=1
+extended_meas_cap=0
+
+ms_meas_cap.present=1
+ms_meas_cap.sms_value=05
+ms_meas_cap.sm_value=05
+
+ms_pos_method_cap.present=0
+ms_pos_method_cap.method=00
+
+ecsd_multislot_cap.present=1
+ecsd_multislot_cap.mslot_class=0a
+
+psk8_struct.present=1
+psk8_struct.mod_cap=0
+psk8_struct.rf_pwr_cap_1.present=1
+psk8_struct.rf_pwr_cap_1.value=01
+psk8_struct.rf_pwr_cap_2.present=0
+psk8_struct.rf_pwr_cap_2.value=00
+
+gsm_400_bands_supp.present=1
+gsm_400_bands_supp.value=01
+gsm_400_bands_supp.assoc_radio_cap=05
+
+gsm_850_assoc_radio_cap.present=0
+gsm_850_assoc_radio_cap.value=00
+
+gsm_1900_assoc_radio_cap.present=1
+gsm_1900_assoc_radio_cap.value=05
+
+umts_fdd_rat_cap=0
+umts_tdd_rat_cap=1
+cdma200_rat_cap=0
+
+dtm_gprs_multislot_cap.present=1
+dtm_gprs_multislot_cap.mslot_class=01
+dtm_gprs_multislot_cap.single_slot_dtm=0
+dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=1
+dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=01
+
+single_band_supp.present=0
+single_band_supp.value=0
+
+gsm_750_assoc_radio_cap.present=1
+gsm_750_assoc_radio_cap.value=05
+
+umts_1_28_mcps_tdd_rat_cap=0
+geran_feature_package=1
+
+extended_dtm_gprs_multislot_cap.present=0
+extended_dtm_gprs_multislot_cap.mslot_class=00
+extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=0
+extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=00
+
+high_multislot_cap.present=1
+high_multislot_cap.value=01
+
+geran_feature_package_2=1
+gmsk_multislot_power_prof=01
+psk8_multislot_power_prof=01
+
+t_gsm_400_bands_supp.present=0
+t_gsm_400_bands_supp.value=00
+t_gsm_400_bands_supp.assoc_radio_cap=00
+
+dl_advanced_rx_perf=01
+dtm_enhancements_cap=0
+
+dtm_gprs_high_multislot_cap.present=1
+dtm_gprs_high_multislot_cap.mslot_class=02
+dtm_gprs_high_multislot_cap.offset_required=1
+dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.present=0
+dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.mslot_class=00
+
+repeated_acch_capability=1
+
+gsm_710_assoc_radio_cap.present=0
+gsm_710_assoc_radio_cap.value=00
+
+t_gsm_810_assoc_radio_cap.present=1
+t_gsm_810_assoc_radio_cap.value=04
+
+ciphering_mode_setting_cap=0
+add_pos_cap=0
+e_utra_fdd_supp=0
+e_utra_tdd_supp=0
+e_utra_meas_rep_supp=0
+prio_resel_supp=0
+utra_csg_cells_rep=0
+vamos_level=00
+tighter_capability=00
+sel_ciph_dl_sacch=0
+cs_ps_srvcc_geran_utra=00
+cs_ps_srvcc_geran_eutra=00
+geran_net_sharing=0
+e_utra_wb_rsrq_meas_supp=0
+er_band_support=0
+utra_mult_band_ind_supp=0
+e_utra_mult_band_ind_supp=0
+extended_tsc_set_cap_supp=0
+extended_earfcn_val_range=0
+
Element is: 2 => freqs[i] = 121
Element is: 2 => freqs[i] = 1
Element is: 0 => freqs[i] = 68
@@ -449,3 +792,19 @@ Random range test: range 127, max num ARFCNs 29
Random range test: range 255, max num ARFCNs 22
Random range test: range 511, max num ARFCNs 18
Random range test: range 1023, max num ARFCNs 16
+rach_tx_integer_raw2val(0x00): 3 slots used to spread transmission
+rach_tx_integer_raw2val(0x01): 4 slots used to spread transmission
+rach_tx_integer_raw2val(0x02): 5 slots used to spread transmission
+rach_tx_integer_raw2val(0x03): 6 slots used to spread transmission
+rach_tx_integer_raw2val(0x04): 7 slots used to spread transmission
+rach_tx_integer_raw2val(0x05): 8 slots used to spread transmission
+rach_tx_integer_raw2val(0x06): 9 slots used to spread transmission
+rach_tx_integer_raw2val(0x07): 10 slots used to spread transmission
+rach_tx_integer_raw2val(0x08): 11 slots used to spread transmission
+rach_tx_integer_raw2val(0x09): 12 slots used to spread transmission
+rach_tx_integer_raw2val(0x0a): 14 slots used to spread transmission
+rach_tx_integer_raw2val(0x0b): 16 slots used to spread transmission
+rach_tx_integer_raw2val(0x0c): 20 slots used to spread transmission
+rach_tx_integer_raw2val(0x0d): 25 slots used to spread transmission
+rach_tx_integer_raw2val(0x0e): 32 slots used to spread transmission
+rach_tx_integer_raw2val(0x0f): 50 slots used to spread transmission
diff --git a/tests/gsm0502/gsm0502_test.c b/tests/gsm0502/gsm0502_test.c
index a950c6c1..e9deaa9f 100644
--- a/tests/gsm0502/gsm0502_test.c
+++ b/tests/gsm0502/gsm0502_test.c
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <string.h>
@@ -90,7 +86,7 @@ uint32_t facch_h1_fn_samples[] = { 500728, 500771, 500797, 500841, 500875, 50091
502782, 502825, 502869, 502903, 502955, 502999
};
-static void test_gsm0502_fn_remap()
+static void test_gsm0502_fn_remap(void)
{
unsigned int i;
uint32_t fn_begin;
diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c
index dd2ffbe9..aa086a23 100644
--- a/tests/gsm0808/gsm0808_test.c
+++ b/tests/gsm0808/gsm0808_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/gsm/gsm0808.h>
@@ -115,7 +111,7 @@ static void test_create_layer3(void)
msgb_free(in_msg);
}
-static void test_create_layer3_aoip()
+static void test_create_layer3_aoip(void)
{
static const uint8_t res[] = {
0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
@@ -152,7 +148,7 @@ static void test_create_layer3_aoip()
msgb_free(in_msg);
}
-static void test_create_reset()
+static void test_create_reset(void)
{
static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 };
struct msgb *msg;
@@ -163,7 +159,7 @@ static void test_create_reset()
msgb_free(msg);
}
-static void test_create_reset_ack()
+static void test_create_reset_ack(void)
{
static const uint8_t res[] = { 0x00, 0x01, 0x31 };
struct msgb *msg;
@@ -175,7 +171,7 @@ static void test_create_reset_ack()
}
-static void test_create_clear_command()
+static void test_create_clear_command(void)
{
static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 };
struct msgb *msg;
@@ -186,7 +182,7 @@ static void test_create_clear_command()
msgb_free(msg);
}
-static void test_create_clear_command2()
+static void test_create_clear_command2(void)
{
static const uint8_t res[] = { 0x00, 0x04, 0x20, 0x04, 0x01, 0x23 };
struct msgb *msg;
@@ -197,7 +193,7 @@ static void test_create_clear_command2()
msgb_free(msg);
}
-static void test_create_clear_command2_csfb()
+static void test_create_clear_command2_csfb(void)
{
static const uint8_t res[] = { 0x00, 0x05, 0x20, 0x04, 0x01, 0x23, 0x8F };
struct msgb *msg;
@@ -208,7 +204,7 @@ static void test_create_clear_command2_csfb()
msgb_free(msg);
}
-static void test_create_clear_complete()
+static void test_create_clear_complete(void)
{
static const uint8_t res[] = { 0x00, 0x01, 0x21 };
struct msgb *msg;
@@ -219,7 +215,7 @@ static void test_create_clear_complete()
msgb_free(msg);
}
-static void test_create_cipher()
+static void test_create_cipher(void)
{
static const uint8_t res[] =
{ 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa,
@@ -259,7 +255,7 @@ static void test_create_cipher()
msgb_free(msg);
}
-static void test_create_cipher_complete()
+static void test_create_cipher_complete(void)
{
static const uint8_t res1[] = {
0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 };
@@ -316,7 +312,7 @@ static inline void parse_cipher_reject(struct msgb *msg, uint8_t exp)
rc, exp, OSMO_BIT_PRINT(exp), msgb_hexdump(msg));
}
-static void test_create_cipher_reject()
+static void test_create_cipher_reject(void)
{
static const uint8_t res[] = { 0x00, 0x04, 0x59, 0x04, 0x01, 0x23 };
enum gsm0808_cause cause = GSM0808_CAUSE_CCCH_OVERLOAD;
@@ -331,7 +327,7 @@ static void test_create_cipher_reject()
msgb_free(msg);
}
-static void test_create_cipher_reject_ext()
+static void test_create_cipher_reject_ext(void)
{
static const uint8_t res[] = { 0x00, 0x05, 0x59, 0x04, 0x02, 0xd0, 0xFA };
uint8_t cause = 0xFA;
@@ -346,7 +342,7 @@ static void test_create_cipher_reject_ext()
msgb_free(msg);
}
-static void test_create_cm_u()
+static void test_create_cm_u(void)
{
static const uint8_t res[] = {
0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 };
@@ -368,7 +364,7 @@ static void test_create_cm_u()
msgb_free(msg);
}
-static void test_create_sapi_reject()
+static void test_create_sapi_reject(void)
{
static const uint8_t res[] = { 0x00, 0x06, 0x25, 0x18, 0x03, 0x04, 0x01, 0x25 };
struct msgb *msg;
@@ -379,7 +375,7 @@ static void test_create_sapi_reject()
msgb_free(msg);
}
-static void test_dec_confusion()
+static void test_dec_confusion(void)
{
static const uint8_t hex[] =
{ 0x26, 0x04, 0x01, 0x52, 0x1f, 0x07, 0x00, 0xff, 0x00, 0x03, 0x25, 0x03, 0x25 };
@@ -428,7 +424,60 @@ static void test_dec_confusion()
osmo_hexdump(diag->msg, diag_len-2));
}
-static void test_create_ass()
+/* Test Perform Location Report SYS#5891 */
+static void test_dec_perform_location_report_sys5891(void)
+{
+/* Message Type Perform Location Request
+ Location Type
+ Element ID: 0x44
+ Length: 1
+ Location Information: current geographic location (0x00)
+ Cell Identifier/CI (25911)
+ Element ID: 0x05
+ Length: 8
+ 0000 .... = Spare bit(s): 0x00
+ .... 0000 = Cell identification discriminator: The whole Cell Global Identification, CGI, is used to identify the cells. (0)
+ Mobile Country Code (MCC): (removed))
+ Mobile Network Code (MNC): (removed))
+ Cell LAC: 0x001e (30)
+ Cell CI: 0x6537 (25911)
+ LCS Client Type
+ Element ID: 0x48
+ Length: 1
+ 0011 .... = Client Category: Emergency Services (0x03)
+ .... 0000 = Client Subtype: unspecified (0x00)
+ LCS Priority
+ Element ID: 0x43
+ Length: 1
+ Periodicity: highest (0)
+ LCS QoS
+ Element ID: 0x3e
+ Length: 4
+ 0000 00.. = Spare: 0x00
+ .... ..0. = Velocity Requested: do not report velocity (0x00)
+ .... ...0 = Vertical Coordinate Indicator: vertical coordinate not requested (0x00)
+ 1... .... = Horizontal Accuracy Indicator: horizontal accuracy is specified (0x01)
+ .001 0010 = Horizontal Accuracy: 0x12
+ 0... .... = Vertical Accuracy Indicator: vertical accuracy is not specified (0x00)
+ .000 0000 = Spare: 0x00
+ 00.. .... = Response Time Category: Response Time is not specified (0x00)
+*/
+ const uint8_t hex[] = {
+ 0x2b, 0x44, 0x01, 0x00, 0x05, 0x08, 0x00, 0xab, 0xbc, 0xcd, 0x00, 0x1e,
+ 0x65, 0x37, 0x48, 0x01, 0x30, 0x43, 0x01, 0x00, 0x3e, 0x04, 0x00, 0x92,
+ 0x00, 0x00
+ };
+
+ struct tlv_parsed tp;
+ int rc;
+
+ printf("Testing decoding Perform Location Report SYS#5891\n");
+
+ rc = tlv_parse(&tp, gsm0808_att_tlvdef(), hex+1, sizeof(hex)-1, 0, 0);
+ OSMO_ASSERT(rc == 5);
+}
+
+static void test_create_ass(void)
{
static const uint8_t res1[] =
{ 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00,
@@ -478,7 +527,7 @@ static void test_create_ass()
msgb_free(msg);
}
-static void test_create_ass2()
+static void test_create_ass2(void)
{
static const uint8_t res[] = {
BSSAP_MSG_BSS_MANAGEMENT,
@@ -499,7 +548,7 @@ static void test_create_ass2()
GSM0808_SCT_CSD | 0x90,
0xc0,
GSM0808_IE_CALL_ID,
- 0xce, 0xfa, 0xad, 0xde, /* CallID */
+ 0xce, 0xfa, 0xad, 0xde, /* CallID */
0x83, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, /* Kc */
GSM0808_IE_GLOBAL_CALL_REF, 0x0d, /* GCR, length */
0x03, 0x44, 0x44, 0x44, /* GCR, Net ID */
@@ -555,7 +604,7 @@ static void test_create_ass2()
msgb_free(msg);
}
-static void test_create_ass_compl()
+static void test_create_ass_compl(void)
{
static const uint8_t res1[] = {
0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c,
@@ -574,7 +623,7 @@ static void test_create_ass_compl()
msgb_free(msg);
}
-static void test_create_ass_compl_aoip()
+static void test_create_ass_compl_aoip(void)
{
struct sockaddr_storage ss;
struct sockaddr_in sin;
@@ -611,7 +660,7 @@ static void test_create_ass_compl_aoip()
msgb_free(msg);
}
-static void test_create_ass_fail()
+static void test_create_ass_fail(void)
{
static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 };
static const uint8_t res2[] = {
@@ -629,7 +678,7 @@ static void test_create_ass_fail()
msgb_free(msg);
}
-static void test_create_ass_fail_aoip()
+static void test_create_ass_fail_aoip(void)
{
static const uint8_t res1[] =
{ 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST,
@@ -655,7 +704,7 @@ static void test_create_ass_fail_aoip()
msgb_free(msg);
}
-static void test_create_clear_rqst()
+static void test_create_clear_rqst(void)
{
static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 };
struct msgb *msg;
@@ -666,7 +715,7 @@ static void test_create_clear_rqst()
msgb_free(msg);
}
-static void test_create_paging()
+static void test_create_paging(void)
{
static const uint8_t res[] =
{ 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00,
@@ -706,7 +755,7 @@ static void test_create_paging()
msgb_free(msg);
}
-static void test_create_dtap()
+static void test_create_dtap(void)
{
static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
struct msgb *msg, *l3;
@@ -723,7 +772,7 @@ static void test_create_dtap()
msgb_free(l3);
}
-static void test_prepend_dtap()
+static void test_prepend_dtap(void)
{
static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
struct msgb *in_msg;
@@ -740,7 +789,7 @@ static void test_prepend_dtap()
msgb_free(in_msg);
}
-static void test_enc_dec_lcls()
+static void test_enc_dec_lcls(void)
{
static const uint8_t res[] = {
GSM0808_IE_GLOBAL_CALL_REF,
@@ -818,7 +867,7 @@ static void test_enc_dec_lcls()
msgb_free(msg);
}
-static void test_enc_dec_aoip_trasp_addr_v4()
+static void test_enc_dec_aoip_trasp_addr_v4(void)
{
struct sockaddr_storage enc_addr;
struct sockaddr_storage dec_addr;
@@ -846,7 +895,7 @@ static void test_enc_dec_aoip_trasp_addr_v4()
msgb_free(msg);
}
-static void test_enc_dec_aoip_trasp_addr_v6()
+static void test_enc_dec_aoip_trasp_addr_v6(void)
{
struct sockaddr_storage enc_addr;
struct sockaddr_storage dec_addr;
@@ -875,7 +924,29 @@ static void test_enc_dec_aoip_trasp_addr_v6()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_speech_codec()
+static void test_enc_aoip_trasp_addr_msg_too_small(void)
+{
+ struct msgb *msg;
+ struct sockaddr_storage enc_addr;
+ struct sockaddr_in enc_addr_in;
+ uint8_t rc_enc;
+
+ memset(&enc_addr_in, 0, sizeof(enc_addr_in));
+ enc_addr_in.sin_family = AF_INET;
+ enc_addr_in.sin_port = htons(1234);
+ inet_aton("255.0.255.255", &enc_addr_in.sin_addr);
+
+ memset(&enc_addr, 0, sizeof(enc_addr));
+ memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in));
+
+ msg = msgb_alloc(7, "output buffer");
+ rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr);
+ OSMO_ASSERT(rc_enc == 0);
+
+ msgb_free(msg);
+}
+
+static void test_gsm0808_enc_dec_speech_codec(void)
{
struct gsm0808_speech_codec enc_sc = {
.pi = true,
@@ -888,7 +959,7 @@ static void test_gsm0808_enc_dec_speech_codec()
int rc_dec;
msg = msgb_alloc(1024, "output buffer");
- rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
+ rc_enc = gsm0808_enc_speech_codec2(msg, &enc_sc);
OSMO_ASSERT(rc_enc == 3);
rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
@@ -900,7 +971,7 @@ static void test_gsm0808_enc_dec_speech_codec()
}
-static void test_gsm0808_enc_dec_speech_codec_with_cfg()
+static void test_gsm0808_enc_dec_speech_codec_with_cfg(void)
{
struct gsm0808_speech_codec enc_sc = {
.pi = true,
@@ -914,7 +985,7 @@ static void test_gsm0808_enc_dec_speech_codec_with_cfg()
int rc_dec;
msg = msgb_alloc(1024, "output buffer");
- rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
+ rc_enc = gsm0808_enc_speech_codec2(msg, &enc_sc);
OSMO_ASSERT(rc_enc == 5);
rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
@@ -925,7 +996,7 @@ static void test_gsm0808_enc_dec_speech_codec_with_cfg()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg()
+static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg(void)
{
struct gsm0808_speech_codec enc_sc = {
.pi = true,
@@ -939,7 +1010,7 @@ static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg()
int rc_dec;
msg = msgb_alloc(1024, "output buffer");
- rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc);
+ rc_enc = gsm0808_enc_speech_codec2(msg, &enc_sc);
OSMO_ASSERT(rc_enc == 5);
rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2);
@@ -950,7 +1021,7 @@ static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_speech_codec_list()
+static void test_gsm0808_enc_dec_speech_codec_list(void)
{
struct gsm0808_speech_codec_list enc_scl = {
.codec = {
@@ -982,7 +1053,7 @@ static void test_gsm0808_enc_dec_speech_codec_list()
int rc_dec;
msg = msgb_alloc(1024, "output buffer");
- rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
+ rc_enc = gsm0808_enc_speech_codec_list2(msg, &enc_scl);
OSMO_ASSERT(rc_enc == 9);
rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
@@ -993,7 +1064,7 @@ static void test_gsm0808_enc_dec_speech_codec_list()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_empty_speech_codec_list()
+static void test_gsm0808_enc_dec_empty_speech_codec_list(void)
{
struct gsm0808_speech_codec_list enc_scl = {
.len = 0,
@@ -1004,7 +1075,7 @@ static void test_gsm0808_enc_dec_empty_speech_codec_list()
int rc_dec;
msg = msgb_alloc(1024, "output buffer");
- rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl);
+ rc_enc = gsm0808_enc_speech_codec_list2(msg, &enc_scl);
OSMO_ASSERT(rc_enc == 2);
rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2);
@@ -1015,7 +1086,89 @@ static void test_gsm0808_enc_dec_empty_speech_codec_list()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_channel_type()
+static void test_gsm0808_enc_dec_channel_type_data(void)
+{
+ struct gsm0808_channel_type enc_ct = {
+ .ch_indctr = GSM0808_CHAN_DATA,
+ .ch_rate_type = GSM0808_DATA_HALF_PREF,
+
+ .data_transparent = true,
+ .data_rate = GSM0808_DATA_RATE_TRANSP_4k8,
+ };
+ struct gsm0808_channel_type dec_ct = {};
+ struct msgb *msg;
+ uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE,
+ 0x03, 0x02, 0x0b, 0x11,
+ };
+ uint8_t rc_enc;
+ int rc_dec;
+
+ msg = msgb_alloc(1024, "output buffer");
+ rc_enc = gsm0808_enc_channel_type(msg, &enc_ct);
+ OSMO_ASSERT(rc_enc == 5);
+ if (memcmp(ct_enc_expected, msg->data, msg->len)) {
+ printf(" got: %s\n", osmo_hexdump(msg->data, msg->len));
+ printf("expect: %s\n", osmo_hexdump(ct_enc_expected, sizeof(ct_enc_expected)));
+ OSMO_ASSERT(false);
+ }
+
+ rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2);
+ OSMO_ASSERT(rc_dec == 3);
+ OSMO_ASSERT(dec_ct.ch_indctr == enc_ct.ch_indctr);
+ OSMO_ASSERT(dec_ct.ch_rate_type == enc_ct.ch_rate_type);
+ OSMO_ASSERT(dec_ct.data_transparent == enc_ct.data_transparent);
+ OSMO_ASSERT(dec_ct.data_rate == enc_ct.data_rate);
+ OSMO_ASSERT(dec_ct.data_rate_allowed_is_set == enc_ct.data_rate_allowed_is_set);
+ OSMO_ASSERT(dec_ct.data_asym_pref_is_set == enc_ct.data_asym_pref_is_set);
+
+ msgb_free(msg);
+}
+
+static void test_gsm0808_enc_dec_channel_type_data_asym_pref(void)
+{
+ struct gsm0808_channel_type enc_ct = {
+ .ch_indctr = GSM0808_CHAN_DATA,
+ .ch_rate_type = GSM0808_DATA_HALF_PREF,
+
+ .data_transparent = false,
+ .data_rate = GSM0808_DATA_RATE_NON_TRANSP_6k0,
+ .data_rate_allowed_is_set = true,
+ .data_rate_allowed = GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_6k0
+ | GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_12k0
+ | GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_14k5,
+ .data_asym_pref_is_set = true,
+ .data_asym_pref = GSM0808_CT_ASYM_PREF_UL,
+ };
+ struct gsm0808_channel_type dec_ct = {};
+ struct msgb *msg;
+ uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE,
+ 0x05, 0x02, 0x0b, 0xd1, 0x8b, 0x20,
+ };
+ uint8_t rc_enc;
+ int rc_dec;
+
+ msg = msgb_alloc(1024, "output buffer");
+ rc_enc = gsm0808_enc_channel_type(msg, &enc_ct);
+ OSMO_ASSERT(rc_enc == 7);
+ if (memcmp(ct_enc_expected, msg->data, msg->len)) {
+ printf(" got: %s\n", osmo_hexdump(msg->data, msg->len));
+ printf("expect: %s\n", osmo_hexdump(ct_enc_expected, sizeof(ct_enc_expected)));
+ OSMO_ASSERT(false);
+ }
+
+ rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2);
+ OSMO_ASSERT(rc_dec == 5);
+ OSMO_ASSERT(dec_ct.ch_indctr == enc_ct.ch_indctr);
+ OSMO_ASSERT(dec_ct.ch_rate_type == enc_ct.ch_rate_type);
+ OSMO_ASSERT(dec_ct.data_transparent == enc_ct.data_transparent);
+ OSMO_ASSERT(dec_ct.data_rate == enc_ct.data_rate);
+ OSMO_ASSERT(dec_ct.data_rate_allowed_is_set == enc_ct.data_rate_allowed_is_set);
+ OSMO_ASSERT(dec_ct.data_asym_pref_is_set == enc_ct.data_asym_pref_is_set);
+
+ msgb_free(msg);
+}
+
+static void test_gsm0808_enc_dec_channel_type_speech(void)
{
struct gsm0808_channel_type enc_ct = {
.ch_indctr = GSM0808_CHAN_SPEECH,
@@ -1046,7 +1199,65 @@ static void test_gsm0808_enc_dec_channel_type()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_encrypt_info()
+static void test_gsm0808_enc_dec_channel_type_sign(void)
+{
+ struct gsm0808_channel_type enc_ct = {
+ .ch_indctr = GSM0808_CHAN_SIGN,
+ .ch_rate_type = GSM0808_SIGN_FULL_PREF_NO_CHANGE,
+ };
+ struct gsm0808_channel_type dec_ct = {};
+ struct msgb *msg;
+ uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE,
+ 0x03, 0x03, 0x1a, 0x00
+ };
+ uint8_t rc_enc;
+ int rc_dec;
+
+ msg = msgb_alloc(1024, "output buffer");
+ rc_enc = gsm0808_enc_channel_type(msg, &enc_ct);
+ OSMO_ASSERT(rc_enc == 5);
+ OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0);
+
+ rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2);
+ OSMO_ASSERT(rc_dec == 2);
+ OSMO_ASSERT(enc_ct.ch_indctr == dec_ct.ch_indctr);
+ OSMO_ASSERT(enc_ct.ch_rate_type == dec_ct.ch_rate_type);
+
+ msgb_free(msg);
+}
+
+static void test_gsm0808_dec_channel_type_err(void)
+{
+ struct gsm0808_channel_type ct;
+ int rc;
+
+ /* Unknown channel indicator */
+ const uint8_t hex1[] = { 0x05, 0x0b, 0xa1, 0x25 };
+ rc = gsm0808_dec_channel_type(&ct, hex1, sizeof(hex1));
+ OSMO_ASSERT(rc == -ENOTSUP);
+
+ /* Data: ext in Octet 5 with transparent service */
+ const uint8_t hex2[] = { 0x02, 0x0b, 0x80, 0x00 };
+ rc = gsm0808_dec_channel_type(&ct, hex2, sizeof(hex2));
+ OSMO_ASSERT(rc == -EINVAL);
+
+ /* Data: ext in Octet 5, but too short */
+ const uint8_t hex3[] = { 0x02, 0x0b, 0xc0 };
+ rc = gsm0808_dec_channel_type(&ct, hex3, sizeof(hex3));
+ OSMO_ASSERT(rc == -EOVERFLOW);
+
+ /* Data: ext in Octet 5a, but too short */
+ const uint8_t hex4[] = { 0x02, 0x0b, 0xc0, 0x80 };
+ rc = gsm0808_dec_channel_type(&ct, hex4, sizeof(hex4));
+ OSMO_ASSERT(rc == -EOVERFLOW);
+
+ /* Speech: extension bit is set in last byte */
+ const uint8_t hex5[] = { 0x01, 0x0b, 0xa1, 0xa5 };
+ rc = gsm0808_dec_channel_type(&ct, hex5, sizeof(hex5));
+ OSMO_ASSERT(rc == -EOVERFLOW);
+}
+
+static void test_gsm0808_enc_dec_encrypt_info(void)
{
struct gsm0808_encrypt_info enc_ei = {
.perm_algo = { GSM0808_ALG_ID_A5_0, GSM0808_ALG_ID_A5_1 },
@@ -1076,7 +1287,20 @@ static void test_gsm0808_enc_dec_encrypt_info()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_list_lac()
+static void test_gsm0808_dec_cell_id_list_srvcc(void)
+{
+ /* taken from a pcap file of a real-world 3rd party MSC (SYS#5838) */
+ const uint8_t enc_cil[] = { 0x0b, 0x2, 0xf2, 0x10, 0x4e, 0x20, 0x15, 0xbe};
+ struct gsm0808_cell_id_list2 dec_cil;
+ int rc;
+
+ rc = gsm0808_dec_cell_id_list2(&dec_cil, enc_cil, sizeof(enc_cil));
+ OSMO_ASSERT(rc == sizeof(enc_cil));
+ OSMO_ASSERT(dec_cil.id_discr = CELL_IDENT_SAI);
+ OSMO_ASSERT(dec_cil.id_list_len = 1);
+}
+
+static void test_gsm0808_enc_dec_cell_id_list_lac(void)
{
struct gsm0808_cell_id_list2 enc_cil;
struct gsm0808_cell_id_list2 dec_cil;
@@ -1103,7 +1327,7 @@ static void test_gsm0808_enc_dec_cell_id_list_lac()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_list_single_lac()
+static void test_gsm0808_enc_dec_cell_id_list_single_lac(void)
{
struct gsm0808_cell_id_list2 enc_cil;
struct gsm0808_cell_id_list2 dec_cil;
@@ -1132,7 +1356,7 @@ static void test_gsm0808_enc_dec_cell_id_list_single_lac()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_list_multi_lac()
+static void test_gsm0808_enc_dec_cell_id_list_multi_lac(void)
{
struct gsm0808_cell_id_list2 enc_cil;
struct gsm0808_cell_id_list2 dec_cil;
@@ -1168,7 +1392,7 @@ static void test_gsm0808_enc_dec_cell_id_list_multi_lac()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_list_bss()
+static void test_gsm0808_enc_dec_cell_id_list_bss(void)
{
struct gsm0808_cell_id_list2 enc_cil;
struct gsm0808_cell_id_list2 dec_cil;
@@ -1191,7 +1415,7 @@ static void test_gsm0808_enc_dec_cell_id_list_bss()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac()
+static void test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac(void)
{
struct gsm0808_cell_id_list2 enc_cil;
struct gsm0808_cell_id_list2 dec_cil;
@@ -1247,7 +1471,7 @@ static void test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_list_multi_ci()
+static void test_gsm0808_enc_dec_cell_id_list_multi_ci(void)
{
struct gsm0808_cell_id_list2 enc_cil;
struct gsm0808_cell_id_list2 dec_cil;
@@ -1281,7 +1505,7 @@ static void test_gsm0808_enc_dec_cell_id_list_multi_ci()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci()
+static void test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci(void)
{
struct gsm0808_cell_id_list2 enc_cil;
struct gsm0808_cell_id_list2 dec_cil;
@@ -1322,7 +1546,7 @@ static void test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_list_multi_global()
+static void test_gsm0808_enc_dec_cell_id_list_multi_global(void)
{
struct gsm0808_cell_id_list2 enc_cil;
struct gsm0808_cell_id_list2 dec_cil;
@@ -1395,7 +1619,7 @@ static void print_cil(const struct gsm0808_cell_id_list2 *cil)
printf(" cell_id_list == %s\n", gsm0808_cell_id_list_name(cil));
}
-void test_cell_id_list_add() {
+void test_cell_id_list_add(void) {
size_t zu;
const struct gsm0808_cell_id_list2 cgi1 = {
@@ -1577,7 +1801,7 @@ void test_cell_id_list_add() {
printf("------- %s done\n", __func__);
}
-static void test_gsm0808_enc_dec_cell_id_lac()
+static void test_gsm0808_enc_dec_cell_id_lac(void)
{
struct gsm0808_cell_id enc_ci = {
.id_discr = CELL_IDENT_LAC,
@@ -1603,7 +1827,7 @@ static void test_gsm0808_enc_dec_cell_id_lac()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_bss()
+static void test_gsm0808_enc_dec_cell_id_bss(void)
{
struct gsm0808_cell_id enc_ci = {
.id_discr = CELL_IDENT_BSS,
@@ -1625,7 +1849,7 @@ static void test_gsm0808_enc_dec_cell_id_bss()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_no_cell()
+static void test_gsm0808_enc_dec_cell_id_no_cell(void)
{
struct gsm0808_cell_id enc_ci = {
.id_discr = CELL_IDENT_NO_CELL,
@@ -1647,7 +1871,7 @@ static void test_gsm0808_enc_dec_cell_id_no_cell()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_lai_and_lac()
+static void test_gsm0808_enc_dec_cell_id_lai_and_lac(void)
{
struct gsm0808_cell_id enc_ci = {
.id_discr = CELL_IDENT_LAI_AND_LAC,
@@ -1678,7 +1902,7 @@ static void test_gsm0808_enc_dec_cell_id_lai_and_lac()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_ci()
+static void test_gsm0808_enc_dec_cell_id_ci(void)
{
struct gsm0808_cell_id enc_ci = {
.id_discr = CELL_IDENT_CI,
@@ -1701,7 +1925,7 @@ static void test_gsm0808_enc_dec_cell_id_ci()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_lac_and_ci()
+static void test_gsm0808_enc_dec_cell_id_lac_and_ci(void)
{
struct gsm0808_cell_id enc_ci = {
.id_discr = CELL_IDENT_LAC_AND_CI,
@@ -1728,7 +1952,7 @@ static void test_gsm0808_enc_dec_cell_id_lac_and_ci()
msgb_free(msg);
}
-static void test_gsm0808_enc_dec_cell_id_global()
+static void test_gsm0808_enc_dec_cell_id_global(void)
{
struct gsm0808_cell_id enc_ci = {
.id_discr = CELL_IDENT_WHOLE_GLOBAL,
@@ -1760,29 +1984,123 @@ static void test_gsm0808_enc_dec_cell_id_global()
msgb_free(msg);
}
+static void test_gsm0808_enc_dec_cell_id_global_ps(void)
+{
+ struct gsm0808_cell_id enc_cgi = {
+ .id_discr = CELL_IDENT_WHOLE_GLOBAL,
+ .id.global = {
+ .lai = {
+ .plmn = { .mcc = 123, .mnc = 456 },
+ .lac = 0x2342
+ },
+ .cell_identity = 0x423,
+ }
+ };
+ struct gsm0808_cell_id enc_cgi_ps = {
+ .id_discr = CELL_IDENT_WHOLE_GLOBAL_PS,
+ .id.global_ps = {
+ .rai = {
+ .lac = {
+ .plmn = { .mcc = 123, .mnc = 456 },
+ .lac = 0x2342
+ },
+ .rac = 0xcc,
+ },
+ .cell_identity = 0x423,
+ }
+ };
+ struct msgb *msg_cgi, *msg_cgi_ps;
+ uint8_t rc_enc;
+
+ msg_cgi = msgb_alloc(1024, "output buffer (CGI)");
+ rc_enc = gsm0808_enc_cell_id(msg_cgi, &enc_cgi);
+ OSMO_ASSERT(rc_enc > 0);
+
+ msg_cgi_ps = msgb_alloc(1024, "output buffer (CGI-PS)");
+ rc_enc = gsm0808_enc_cell_id(msg_cgi_ps, &enc_cgi_ps);
+ OSMO_ASSERT(rc_enc > 0);
+
+ OSMO_ASSERT(msgb_eq(msg_cgi, msg_cgi_ps));
+
+ msgb_free(msg_cgi);
+ msgb_free(msg_cgi_ps);
+}
+
+static void print_s15_s0(uint16_t s15_s0, bool full_rate)
+{
+ int i;
+ printf(" S15-S0 = 0x%04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
+ OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
+ for (i = 0; i < 16; i++) {
+ uint8_t modes;
+ int m;
+ int space;
+
+ if (!(s15_s0 & (1 << i)))
+ continue;
+
+ space = 6;
+ if (i < 10)
+ space++;
+
+ printf(" S%d", i);
+
+ modes = gsm0808_amr_modes_from_cfg[full_rate ? 1 : 0][i];
+ if (!modes) {
+ printf(" (empty)\n");
+ continue;
+ }
+
+ for (m = 0; m < 8; m++) {
+ if (!(modes & (1 << m))) {
+ /* avoid whitespace at line ends -- accumulate whitespace width until there is
+ * non-whitespace to actually be printed.*/
+ space += 8;
+ continue;
+ }
+ printf("%*s", space, gsm0808_amr_mode_name(m));
+ space = 8;
+ }
+ printf("\n");
+ }
+}
+
+static void print_mr_cfg(const struct gsm48_multi_rate_conf *cfg)
+{
+ printf(" cfg.smod=%u spare=%u icmi=%u nscb=%u ver=%u\n",
+ cfg->smod, cfg->spare, cfg->icmi, cfg->nscb, cfg->ver);
+ printf(" ");
+#define PRINT_MODE_BIT(NAME) do { \
+ if (cfg->NAME) \
+ printf(" " #NAME "=1"); \
+ else \
+ printf(" -------"); \
+ } while (0)
+ PRINT_MODE_BIT(m4_75);
+ PRINT_MODE_BIT(m5_15);
+ PRINT_MODE_BIT(m5_90);
+ PRINT_MODE_BIT(m6_70);
+ PRINT_MODE_BIT(m7_40);
+ PRINT_MODE_BIT(m7_95);
+ PRINT_MODE_BIT(m10_2);
+ PRINT_MODE_BIT(m12_2);
+ printf("\n");
+}
+
static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(struct gsm48_multi_rate_conf *cfg)
{
uint16_t s15_s0;
printf("Input:\n");
- printf(" m4_75= %u smod= %u\n", cfg->m4_75, cfg->smod);
- printf(" m5_15= %u spare= %u\n", cfg->m5_15, cfg->spare);
- printf(" m5_90= %u icmi= %u\n", cfg->m5_90, cfg->icmi);
- printf(" m6_70= %u nscb= %u\n", cfg->m6_70, cfg->nscb);
- printf(" m7_40= %u ver= %u\n", cfg->m7_40, cfg->ver);
- printf(" m7_95= %u\n", cfg->m7_95);
- printf(" m10_2= %u\n", cfg->m10_2);
- printf(" m12_2= %u\n", cfg->m12_2);
+ print_mr_cfg(cfg);
s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, true);
printf("Result (fr):\n");
- printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
- OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
+ print_s15_s0(s15_s0, true);
s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, false);
printf("Result (hr):\n");
- printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
- OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
+ print_s15_s0(s15_s0, false);
printf("\n");
}
@@ -1974,7 +2292,7 @@ static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg(void)
cfg.m10_2 = 0;
cfg.m12_2 = 0;
test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(&cfg);
-
+
}
static void test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(uint16_t s15_s0)
@@ -1983,20 +2301,12 @@ static void test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(uint16_t s15_s0)
int rc;
printf("Input:\n");
- printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0,
- OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0));
+ print_s15_s0(s15_s0, true);
rc = gsm48_mr_cfg_from_gsm0808_sc_cfg(&cfg, s15_s0);
printf("Output:\n");
- printf(" m4_75= %u smod= %u\n", cfg.m4_75, cfg.smod);
- printf(" m5_15= %u spare= %u\n", cfg.m5_15, cfg.spare);
- printf(" m5_90= %u icmi= %u\n", cfg.m5_90, cfg.icmi);
- printf(" m6_70= %u nscb= %u\n", cfg.m6_70, cfg.nscb);
- printf(" m7_40= %u ver= %u\n", cfg.m7_40, cfg.ver);
- printf(" m7_95= %u\n", cfg.m7_95);
- printf(" m10_2= %u\n", cfg.m10_2);
- printf(" m12_2= %u\n", cfg.m12_2);
+ print_mr_cfg(&cfg);
if (rc != 0)
printf(" Result invalid!\n");
@@ -2004,7 +2314,7 @@ static void test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(uint16_t s15_s0)
printf("\n");
}
-void test_gsm48_mr_cfg_from_gsm0808_sc_cfg()
+void test_gsm48_mr_cfg_from_gsm0808_sc_cfg(void)
{
printf("Testing gsm48_mr_cfg_from_gsm0808_sc_cfg():\n");
@@ -2189,7 +2499,7 @@ static const struct test_cell_id_matching_data test_cell_id_matching_tests[] = {
{ .id = cgi_23_042_23_5, .match_id = cgi_23_99_23_5, .expect_match = false, .expect_exact_match = false },
};
-static void test_cell_id_matching()
+static void test_cell_id_matching(void)
{
int i;
bool ok = true;
@@ -2352,7 +2662,7 @@ static const struct gsm0808_cell_id test_gsm0808_cell_id_to_from_cgi_data[] = {
{ .id_discr = 423 },
};
-static void test_gsm0808_cell_id_to_from_cgi()
+static void test_gsm0808_cell_id_to_from_cgi(void)
{
int i;
int j;
@@ -2436,12 +2746,17 @@ int main(int argc, char **argv)
test_enc_dec_aoip_trasp_addr_v4();
test_enc_dec_aoip_trasp_addr_v6();
+ test_enc_aoip_trasp_addr_msg_too_small();
test_gsm0808_enc_dec_speech_codec();
test_gsm0808_enc_dec_speech_codec_ext_with_cfg();
test_gsm0808_enc_dec_speech_codec_with_cfg();
test_gsm0808_enc_dec_speech_codec_list();
test_gsm0808_enc_dec_empty_speech_codec_list();
- test_gsm0808_enc_dec_channel_type();
+ test_gsm0808_enc_dec_channel_type_data();
+ test_gsm0808_enc_dec_channel_type_data_asym_pref();
+ test_gsm0808_enc_dec_channel_type_speech();
+ test_gsm0808_enc_dec_channel_type_sign();
+ test_gsm0808_dec_channel_type_err();
test_gsm0808_enc_dec_encrypt_info();
test_gsm0808_enc_dec_cell_id_list_lac();
@@ -2452,6 +2767,7 @@ int main(int argc, char **argv)
test_gsm0808_enc_dec_cell_id_list_multi_ci();
test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci();
test_gsm0808_enc_dec_cell_id_list_multi_global();
+ test_gsm0808_dec_cell_id_list_srvcc();
test_cell_id_list_add();
@@ -2462,6 +2778,7 @@ int main(int argc, char **argv)
test_gsm0808_enc_dec_cell_id_ci();
test_gsm0808_enc_dec_cell_id_lac_and_ci();
test_gsm0808_enc_dec_cell_id_global();
+ test_gsm0808_enc_dec_cell_id_global_ps();
test_gsm0808_sc_cfg_from_gsm48_mr_cfg();
test_gsm48_mr_cfg_from_gsm0808_sc_cfg();
@@ -2472,6 +2789,7 @@ int main(int argc, char **argv)
test_gsm0808_cell_id_to_from_cgi();
test_dec_confusion();
+ test_dec_perform_location_report_sys5891();
printf("Done\n");
return EXIT_SUCCESS;
diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok
index eaae7a69..2329fcdc 100644
--- a/tests/gsm0808/gsm0808_test.ok
+++ b/tests/gsm0808/gsm0808_test.ok
@@ -87,549 +87,549 @@ test_gsm0808_enc_dec_cell_id_lac_and_ci: encoded: 05 05 01 04 23 02 35 (rc = 7)
test_gsm0808_enc_dec_cell_id_global: encoded: 05 08 00 21 63 54 23 42 04 23 (rc = 10)
Testing gsm0808_sc_cfg_from_gsm48_mr_cfg():
Input:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- ------- ------- -------
Result (fr):
- S15-S0 = 0000 = 0b0000000000000000
+ S15-S0 = 0x0000 = 0b0000000000000000
Result (hr):
- S15-S0 = 0000 = 0b0000000000000000
+ S15-S0 = 0x0000 = 0b0000000000000000
Input:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- ------- ------- ------- ------- ------- -------
Result (fr):
- S15-S0 = 5701 = 0b0101011100000001
+ S15-S0 = 0x5701 = 0b0101011100000001
+ S0 4.75
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0701 = 0b0000011100000001
+ S15-S0 = 0x0701 = 0b0000011100000001
+ S0 4.75
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
Input:
- m4_75= 0 smod= 0
- m5_15= 1 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- m5_15=1 ------- ------- ------- ------- ------- -------
Result (fr):
- S15-S0 = 0000 = 0b0000000000000000
+ S15-S0 = 0x0000 = 0b0000000000000000
Result (hr):
- S15-S0 = 0000 = 0b0000000000000000
+ S15-S0 = 0x0000 = 0b0000000000000000
Input:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- m5_90=1 ------- ------- ------- ------- -------
Result (fr):
- S15-S0 = 5704 = 0b0101011100000100
+ S15-S0 = 0x5704 = 0b0101011100000100
+ S2 5.90
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0704 = 0b0000011100000100
+ S15-S0 = 0x0704 = 0b0000011100000100
+ S2 5.90
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
Input:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 1 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- m6_70=1 ------- ------- ------- -------
Result (fr):
- S15-S0 = 1608 = 0b0001011000001000
+ S15-S0 = 0x1608 = 0b0001011000001000
+ S3 6.70
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
Result (hr):
- S15-S0 = 0608 = 0b0000011000001000
+ S15-S0 = 0x0608 = 0b0000011000001000
+ S3 6.70
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
Input:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- m7_40=1 ------- ------- -------
Result (fr):
- S15-S0 = 0410 = 0b0000010000010000
+ S15-S0 = 0x0410 = 0b0000010000010000
+ S4 7.40
+ S10 4.75 5.90 6.70 7.40
Result (hr):
- S15-S0 = 0410 = 0b0000010000010000
+ S15-S0 = 0x0410 = 0b0000010000010000
+ S4 7.40
+ S10 4.75 5.90 6.70 7.40
Input:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 1
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- m7_95=1 ------- -------
Result (fr):
- S15-S0 = 4020 = 0b0100000000100000
+ S15-S0 = 0x4020 = 0b0100000000100000
+ S5 7.95
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0020 = 0b0000000000100000
+ S15-S0 = 0x0020 = 0b0000000000100000
+ S5 7.95
Input:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 0
- m10_2= 1
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- ------- m10_2=1 -------
Result (fr):
- S15-S0 = 1040 = 0b0001000001000000
+ S15-S0 = 0x1040 = 0b0001000001000000
+ S6 10.2
+ S12 4.75 5.90 6.70 10.2
Result (hr):
- S15-S0 = 0000 = 0b0000000000000000
+ S15-S0 = 0x0000 = 0b0000000000000000
Input:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- ------- ------- m12_2=1
Result (fr):
- S15-S0 = 4080 = 0b0100000010000000
+ S15-S0 = 0x4080 = 0b0100000010000000
+ S7 12.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0000 = 0b0000000000000000
+ S15-S0 = 0x0000 = 0b0000000000000000
Input:
- m4_75= 1 smod= 0
- m5_15= 1 spare= 0
- m5_90= 1 icmi= 0
- m6_70= 1 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 m5_15=1 m5_90=1 m6_70=1 ------- ------- ------- -------
Result (fr):
- S15-S0 = 570d = 0b0101011100001101
+ S15-S0 = 0x570d = 0b0101011100001101
+ S0 4.75
+ S2 5.90
+ S3 6.70
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 070d = 0b0000011100001101
+ S15-S0 = 0x070d = 0b0000011100001101
+ S0 4.75
+ S2 5.90
+ S3 6.70
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
Input:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 0
- m7_95= 1
- m10_2= 1
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- m7_40=1 m7_95=1 m10_2=1 m12_2=1
Result (fr):
- S15-S0 = 54f0 = 0b0101010011110000
+ S15-S0 = 0x54f0 = 0b0101010011110000
+ S4 7.40
+ S5 7.95
+ S6 10.2
+ S7 12.2
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0430 = 0b0000010000110000
+ S15-S0 = 0x0430 = 0b0000010000110000
+ S4 7.40
+ S5 7.95
+ S10 4.75 5.90 6.70 7.40
Input:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 0
- m6_70= 1 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 0
- m10_2= 1
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- m5_90=1 m6_70=1 ------- ------- m10_2=1 m12_2=1
Result (fr):
- S15-S0 = 57cc = 0b0101011111001100
+ S15-S0 = 0x57cc = 0b0101011111001100
+ S2 5.90
+ S3 6.70
+ S6 10.2
+ S7 12.2
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 070c = 0b0000011100001100
+ S15-S0 = 0x070c = 0b0000011100001100
+ S2 5.90
+ S3 6.70
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
Input:
- m4_75= 1 smod= 0
- m5_15= 1 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 0
- m7_95= 1
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 m5_15=1 ------- ------- m7_40=1 m7_95=1 ------- -------
Result (fr):
- S15-S0 = 5731 = 0b0101011100110001
+ S15-S0 = 0x5731 = 0b0101011100110001
+ S0 4.75
+ S4 7.40
+ S5 7.95
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0731 = 0b0000011100110001
+ S15-S0 = 0x0731 = 0b0000011100110001
+ S0 4.75
+ S4 7.40
+ S5 7.95
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
Input:
- m4_75= 0 smod= 0
- m5_15= 1 spare= 0
- m5_90= 0 icmi= 0
- m6_70= 1 nscb= 0
- m7_40= 0 ver= 0
- m7_95= 1
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- m5_15=1 ------- m6_70=1 ------- m7_95=1 ------- m12_2=1
Result (fr):
- S15-S0 = 56a8 = 0b0101011010101000
+ S15-S0 = 0x56a8 = 0b0101011010101000
+ S3 6.70
+ S5 7.95
+ S7 12.2
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0628 = 0b0000011000101000
+ S15-S0 = 0x0628 = 0b0000011000101000
+ S3 6.70
+ S5 7.95
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
Input:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 0
- m7_95= 0
- m10_2= 1
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- m10_2=1 -------
Result (fr):
- S15-S0 = 5755 = 0b0101011101010101
+ S15-S0 = 0x5755 = 0b0101011101010101
+ S0 4.75
+ S2 5.90
+ S4 7.40
+ S6 10.2
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0717 = 0b0000011100010111
-
-Input:
- m4_75= 1 smod= 0
- m5_15= 1 spare= 0
- m5_90= 1 icmi= 0
- m6_70= 1 nscb= 0
- m7_40= 1 ver= 0
- m7_95= 1
- m10_2= 1
- m12_2= 1
+ S15-S0 = 0x0717 = 0b0000011100010111
+ S0 4.75
+ S1 4.75 5.90 7.40
+ S2 5.90
+ S4 7.40
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+
+Input:
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 m5_15=1 m5_90=1 m6_70=1 m7_40=1 m7_95=1 m10_2=1 m12_2=1
Result (fr):
- S15-S0 = 57ff = 0b0101011111111111
+ S15-S0 = 0x57ff = 0b0101011111111111
+ S0 4.75
+ S1 4.75 5.90 7.40 12.2
+ S2 5.90
+ S3 6.70
+ S4 7.40
+ S5 7.95
+ S6 10.2
+ S7 12.2
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 073f = 0b0000011100111111
-
-Input:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ S15-S0 = 0x073f = 0b0000011100111111
+ S0 4.75
+ S1 4.75 5.90 7.40
+ S2 5.90
+ S3 6.70
+ S4 7.40
+ S5 7.95
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+
+Input:
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Result (fr):
- S15-S0 = 5797 = 0b0101011110010111
+ S15-S0 = 0x5797 = 0b0101011110010111
+ S0 4.75
+ S1 4.75 5.90 7.40 12.2
+ S2 5.90
+ S4 7.40
+ S7 12.2
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0717 = 0b0000011100010111
-
-Input:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 0
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 0
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ S15-S0 = 0x0717 = 0b0000011100010111
+ S0 4.75
+ S1 4.75 5.90 7.40
+ S2 5.90
+ S4 7.40
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+
+Input:
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- -------
Result (fr):
- S15-S0 = 5715 = 0b0101011100010101
+ S15-S0 = 0x5715 = 0b0101011100010101
+ S0 4.75
+ S2 5.90
+ S4 7.40
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S12 4.75 5.90 6.70 10.2
+ S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0717 = 0b0000011100010111
+ S15-S0 = 0x0717 = 0b0000011100010111
+ S0 4.75
+ S1 4.75 5.90 7.40
+ S2 5.90
+ S4 7.40
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
Testing gsm48_mr_cfg_from_gsm0808_sc_cfg():
Input:
- S15-S0 = ff03 = 0b1111111100000011
+ S15-S0 = 0xff03 = 0b1111111100000011
+ S0 4.75
+ S1 4.75 5.90 7.40 12.2
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S11 (empty)
+ S12 4.75 5.90 6.70 10.2
+ S13 (empty)
+ S14 4.75 5.90 7.95 12.2
+ S15 (empty)
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Input:
- S15-S0 = 0000 = 0b0000000000000000
+ S15-S0 = 0x0000 = 0b0000000000000000
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- ------- ------- ------- ------- -------
Result invalid!
Input:
- S15-S0 = ff06 = 0b1111111100000110
+ S15-S0 = 0xff06 = 0b1111111100000110
+ S1 4.75 5.90 7.40 12.2
+ S2 5.90
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S11 (empty)
+ S12 4.75 5.90 6.70 10.2
+ S13 (empty)
+ S14 4.75 5.90 7.95 12.2
+ S15 (empty)
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Input:
- S15-S0 = 3e08 = 0b0011111000001000
+ S15-S0 = 0x3e08 = 0b0011111000001000
+ S3 6.70
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S11 (empty)
+ S12 4.75 5.90 6.70 10.2
+ S13 (empty)
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 1 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- m6_70=1 ------- ------- ------- -------
Input:
- S15-S0 = 0c12 = 0b0000110000010010
+ S15-S0 = 0x0c12 = 0b0000110000010010
+ S1 4.75 5.90 7.40 12.2
+ S4 7.40
+ S10 4.75 5.90 6.70 7.40
+ S11 (empty)
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Input:
- S15-S0 = c020 = 0b1100000000100000
+ S15-S0 = 0xc020 = 0b1100000000100000
+ S5 7.95
+ S14 4.75 5.90 7.95 12.2
+ S15 (empty)
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 1
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- ------- ------- m7_95=1 ------- -------
Input:
- S15-S0 = 3040 = 0b0011000001000000
+ S15-S0 = 0x3040 = 0b0011000001000000
+ S6 10.2
+ S12 4.75 5.90 6.70 10.2
+ S13 (empty)
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 1
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- ------- ------- ------- m10_2=1 -------
Input:
- S15-S0 = c082 = 0b1100000010000010
+ S15-S0 = 0xc082 = 0b1100000010000010
+ S1 4.75 5.90 7.40 12.2
+ S7 12.2
+ S14 4.75 5.90 7.95 12.2
+ S15 (empty)
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Input:
- S15-S0 = 0001 = 0b0000000000000001
+ S15-S0 = 0x0001 = 0b0000000000000001
+ S0 4.75
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- ------- ------- ------- ------- ------- -------
Input:
- S15-S0 = 0002 = 0b0000000000000010
+ S15-S0 = 0x0002 = 0b0000000000000010
+ S1 4.75 5.90 7.40 12.2
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Input:
- S15-S0 = 0004 = 0b0000000000000100
+ S15-S0 = 0x0004 = 0b0000000000000100
+ S2 5.90
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- m5_90=1 ------- ------- ------- ------- -------
Input:
- S15-S0 = 0008 = 0b0000000000001000
+ S15-S0 = 0x0008 = 0b0000000000001000
+ S3 6.70
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 1 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- m6_70=1 ------- ------- ------- -------
Input:
- S15-S0 = 0010 = 0b0000000000010000
+ S15-S0 = 0x0010 = 0b0000000000010000
+ S4 7.40
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- ------- m7_40=1 ------- ------- -------
Input:
- S15-S0 = 0020 = 0b0000000000100000
+ S15-S0 = 0x0020 = 0b0000000000100000
+ S5 7.95
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 1
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- ------- ------- m7_95=1 ------- -------
Input:
- S15-S0 = 0040 = 0b0000000001000000
+ S15-S0 = 0x0040 = 0b0000000001000000
+ S6 10.2
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 1
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- ------- ------- ------- m10_2=1 -------
Input:
- S15-S0 = 0080 = 0b0000000010000000
+ S15-S0 = 0x0080 = 0b0000000010000000
+ S7 12.2
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- ------- ------- ------- ------- m12_2=1
Input:
- S15-S0 = 0058 = 0b0000000001011000
+ S15-S0 = 0x0058 = 0b0000000001011000
+ S3 6.70
+ S4 7.40
+ S6 10.2
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 1 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 1
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- m6_70=1 m7_40=1 ------- m10_2=1 -------
Input:
- S15-S0 = 0021 = 0b0000000000100001
+ S15-S0 = 0x0021 = 0b0000000000100001
+ S0 4.75
+ S5 7.95
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 1
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- ------- ------- ------- m7_95=1 ------- -------
Input:
- S15-S0 = 0084 = 0b0000000010000100
+ S15-S0 = 0x0084 = 0b0000000010000100
+ S2 5.90
+ S7 12.2
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- m5_90=1 ------- ------- ------- ------- m12_2=1
Input:
- S15-S0 = 0086 = 0b0000000010000110
+ S15-S0 = 0x0086 = 0b0000000010000110
+ S1 4.75 5.90 7.40 12.2
+ S2 5.90
+ S7 12.2
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Input:
- S15-S0 = 000a = 0b0000000000001010
+ S15-S0 = 0x000a = 0b0000000000001010
+ S1 4.75 5.90 7.40 12.2
+ S3 6.70
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Result invalid!
Input:
- S15-S0 = 0079 = 0b0000000001111001
+ S15-S0 = 0x0079 = 0b0000000001111001
+ S0 4.75
+ S3 6.70
+ S4 7.40
+ S5 7.95
+ S6 10.2
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 1 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 1
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- ------- m6_70=1 m7_40=1 m7_95=1 ------- -------
Result invalid!
Input:
- S15-S0 = 0000 = 0b0000000000000000
+ S15-S0 = 0x0000 = 0b0000000000000000
Output:
- m4_75= 0 smod= 0
- m5_15= 0 spare= 0
- m5_90= 0 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 0 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 0
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ ------- ------- ------- ------- ------- ------- ------- -------
Result invalid!
Input:
- S15-S0 = ffff = 0b1111111111111111
+ S15-S0 = 0xffff = 0b1111111111111111
+ S0 4.75
+ S1 4.75 5.90 7.40 12.2
+ S2 5.90
+ S3 6.70
+ S4 7.40
+ S5 7.95
+ S6 10.2
+ S7 12.2
+ S8 4.75 5.90
+ S9 4.75 5.90 6.70
+ S10 4.75 5.90 6.70 7.40
+ S11 (empty)
+ S12 4.75 5.90 6.70 10.2
+ S13 (empty)
+ S14 4.75 5.90 7.95 12.2
+ S15 (empty)
Output:
- m4_75= 1 smod= 0
- m5_15= 0 spare= 0
- m5_90= 1 icmi= 1
- m6_70= 0 nscb= 0
- m7_40= 1 ver= 1
- m7_95= 0
- m10_2= 0
- m12_2= 1
+ cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Result invalid!
@@ -916,4 +916,5 @@ Testing decoding CONFUSION
Diagnostics error octet location 0 (Error location not determined)
Diagnostics error bit location 15 (Reserved value)
Diagnostics message that provoked the error: 00 03 25 03 25
+Testing decoding Perform Location Report SYS#5891
Done
diff --git a/tests/gsm23003/gsm23003_test.c b/tests/gsm23003/gsm23003_test.c
index eac5a115..77d3173e 100644
--- a/tests/gsm23003/gsm23003_test.c
+++ b/tests/gsm23003/gsm23003_test.c
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
@@ -58,7 +54,7 @@ static struct {
{ NULL, false },
};
-bool test_valid_imsi()
+bool test_valid_imsi(void)
{
int i;
bool pass = true;
@@ -101,7 +97,7 @@ static struct {
{ NULL, false },
};
-bool test_valid_msisdn()
+bool test_valid_msisdn(void)
{
int i;
bool pass = true;
@@ -142,7 +138,7 @@ static struct {
{ NULL, false, false },
};
-bool test_valid_imei()
+bool test_valid_imei(void)
{
int i;
bool pass = true;
@@ -189,7 +185,7 @@ static struct test_mnc_from_str test_mnc_from_strs[] = {
{ "023 ", { -EINVAL, 0, false } },
};
-static bool test_mnc_from_str()
+static bool test_mnc_from_str(void)
{
int i;
bool pass = true;
@@ -213,7 +209,7 @@ static bool test_mnc_from_str()
return pass;
}
-static bool test_gummei_name()
+static bool test_gummei_name(void)
{
static const struct osmo_gummei gummei = {
.plmn = { .mcc = 901, .mnc = 70 },
@@ -230,7 +226,7 @@ static bool test_gummei_name()
return pass;
}
-static bool test_domain_gen()
+static bool test_domain_gen(void)
{
static const struct osmo_gummei gummei = {
.plmn = { .mcc = 901, .mnc = 70 },
@@ -256,7 +252,7 @@ static bool test_domain_gen()
}
-static bool test_domain_parse()
+static bool test_domain_parse(void)
{
static const char *mme_dom_valid = "mmec01.mmegiA001.mme.epc.mnc070.mcc901.3gppnetwork.org";
static const char *home_dom_valid = "epc.mnc070.mcc901.3gppnetwork.org";
diff --git a/tests/gsm23236/gsm23236_test.c b/tests/gsm23236/gsm23236_test.c
index 14c5ce38..6cbdbeb2 100644
--- a/tests/gsm23236/gsm23236_test.c
+++ b/tests/gsm23236/gsm23236_test.c
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
@@ -142,7 +138,7 @@ struct nri_v_get_set_test nri_v_get_set_tests[] = {
},
};
-void test_nri_v_get_set()
+void test_nri_v_get_set(void)
{
struct nri_v_get_set_test *t;
@@ -226,7 +222,7 @@ struct nri_validate_tc nri_validate_tests[] = {
{ .nri = INT16_MAX, .nri_bitlen = 0, .expect_rc = 1 },
};
-void test_nri_validate()
+void test_nri_validate(void)
{
struct nri_validate_tc *t;
printf("\n%s()\n", __func__);
@@ -331,7 +327,7 @@ struct nri_range_validate_tc nri_range_validate_tests[] = {
};
-void test_nri_range_validate()
+void test_nri_range_validate(void)
{
struct nri_range_validate_tc *t;
printf("\n%s()\n", __func__);
@@ -361,7 +357,7 @@ void dump_list(const struct osmo_nri_ranges *nri_ranges)
printf("};\n");
}
-void test_nri_list()
+void test_nri_list(void)
{
struct osmo_nri_ranges *nri_ranges = osmo_nri_ranges_alloc(ctx);
printf("\n%s()\n", __func__);
@@ -549,7 +545,7 @@ void test_nri_list()
DEL(100, 1);
}
-void test_nri_limit_by_ranges()
+void test_nri_limit_by_ranges(void)
{
const uint8_t nri_bitlen = 8;
const int16_t expect_nri_vals[] = { 10, 20, 21, 30, 31, 32 };
@@ -598,7 +594,7 @@ void test_nri_limit_by_ranges()
}
}
-int main()
+int main(int argc, char **argv)
{
ctx = talloc_named_const(NULL, 0, "nri_test");
diff --git a/tests/gsm29205/gsm29205_test.c b/tests/gsm29205/gsm29205_test.c
index 44c3453c..6598f894 100644
--- a/tests/gsm29205/gsm29205_test.c
+++ b/tests/gsm29205/gsm29205_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/gsm/gsm29205.h>
@@ -32,7 +28,7 @@
#include <string.h>
#include <errno.h>
-static void test_gcr()
+static void test_gcr(void)
{
static const uint8_t res[] = {
0x03, /* .net_len */
diff --git a/tests/gsm44021/test_frame_csd.c b/tests/gsm44021/test_frame_csd.c
new file mode 100644
index 00000000..98efdacb
--- /dev/null
+++ b/tests/gsm44021/test_frame_csd.c
@@ -0,0 +1,93 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/isdn/v110.h>
+#include <osmocom/gsm/gsm44021.h>
+
+
+static void fill_v110_frame(struct osmo_v110_decoded_frame *fr)
+{
+ unsigned int i;
+
+ memset(fr, 0, sizeof(*fr));
+
+ /* we abuse the fact that ubit_t is 8bit so we can actually
+ * store integer values to clearly identify which bit ends up where */
+
+ /* D1..D48: 101..148 */
+ for (i = 0; i < ARRAY_SIZE(fr->d_bits); i++)
+ fr->d_bits[i] = 101 + i;
+ /* E1..E7: 201..207 */
+ for (i = 0; i < ARRAY_SIZE(fr->e_bits); i++)
+ fr->e_bits[i] = 201 + i;
+ /* S1..S9: 211..219 */
+ for (i = 0; i < ARRAY_SIZE(fr->s_bits); i++)
+ fr->s_bits[i] = 211 + i;
+ /* X1..X2: 221..222 */
+ for (i = 0; i < ARRAY_SIZE(fr->x_bits); i++)
+ fr->x_bits[i] = 221 + i;
+}
+
+
+static void test_frame_enc_12k_6k(void)
+{
+ struct osmo_v110_decoded_frame fr;
+ ubit_t bits[60];
+
+ printf("Testing Frame Encoding for 12k/6k radio interface rate\n");
+
+ fill_v110_frame(&fr);
+
+ /* run encoder and dump to stdout */
+ memset(bits, 0xff, sizeof(bits));
+ osmo_csd_12k_6k_encode_frame(bits, sizeof(bits), &fr);
+ osmo_csd_ubit_dump(stdout, bits, sizeof(bits));
+
+ /* run decoder on what we just encoded */
+ memset(&fr, 0, sizeof(fr));
+ osmo_csd_12k_6k_decode_frame(&fr, bits, sizeof(bits));
+
+ /* re-encode and dump again 'expout' will match it. */
+ memset(bits, 0xff, sizeof(bits));
+ osmo_csd_12k_6k_encode_frame(bits, sizeof(bits), &fr);
+ osmo_csd_ubit_dump(stdout, bits, sizeof(bits));
+}
+
+static void test_frame_enc_3k6(void)
+{
+ struct osmo_v110_decoded_frame fr;
+ ubit_t bits[36];
+
+ printf("Testing Frame Encoding for 3.6k radio interface rate\n");
+
+ fill_v110_frame(&fr);
+ /* different D-bit numbering for 3k6, see TS 44.021 Section 8.1.4 */
+ for (unsigned int i = 0; i < ARRAY_SIZE(fr.d_bits); i++)
+ fr.d_bits[i] = 101 + i/2;
+
+ /* run encoder and dump to stdout */
+ memset(bits, 0xff, sizeof(bits));
+ osmo_csd_3k6_encode_frame(bits, sizeof(bits), &fr);
+ osmo_csd_ubit_dump(stdout, bits, sizeof(bits));
+
+ /* run decoder on what we just encoded */
+ memset(&fr, 0, sizeof(fr));
+ osmo_csd_3k6_decode_frame(&fr, bits, sizeof(bits));
+
+ /* re-encode and dump again 'expout' will match it. */
+ memset(bits, 0xff, sizeof(bits));
+ osmo_csd_3k6_encode_frame(bits, sizeof(bits), &fr);
+ osmo_csd_ubit_dump(stdout, bits, sizeof(bits));
+}
+
+
+int main(int argc, char **argv)
+{
+ test_frame_enc_12k_6k();
+ printf("\n");
+ test_frame_enc_3k6();
+}
+
diff --git a/tests/gsm44021/test_frame_csd.ok b/tests/gsm44021/test_frame_csd.ok
new file mode 100644
index 00000000..1a5d3f25
--- /dev/null
+++ b/tests/gsm44021/test_frame_csd.ok
@@ -0,0 +1,31 @@
+Testing Frame Encoding for 12k/6k radio interface rate
+101 102 103 104 105 106 211
+107 108 109 110 111 112 221
+113 114 115 116 117 118 213
+119 120 121 122 123 124 214
+204 205 206 207 125 126 127
+128 129 130 216 131 132 133
+134 135 136 222 137 138 139
+140 141 142 218 143 144 145
+146 147 148 219
+101 102 103 104 105 106 211
+107 108 109 110 111 112 221
+113 114 115 116 117 118 213
+119 120 121 122 123 124 214
+204 205 206 207 125 126 127
+128 129 130 216 131 132 133
+134 135 136 222 137 138 139
+140 141 142 218 143 144 145
+146 147 148 219
+
+Testing Frame Encoding for 3.6k radio interface rate
+101 102 103 211 104 105 106 221
+107 108 109 213 110 111 112 214
+204 205 206 207 113 114 115 216
+116 117 118 222 119 120 121 218
+122 123 124 219
+101 102 103 211 104 105 106 221
+107 108 109 213 110 111 112 214
+204 205 206 207 113 114 115 216
+116 117 118 222 119 120 121 218
+122 123 124 219
diff --git a/tests/gsm48/rest_octets_test.c b/tests/gsm48/rest_octets_test.c
new file mode 100644
index 00000000..bf53212e
--- /dev/null
+++ b/tests/gsm48/rest_octets_test.c
@@ -0,0 +1,116 @@
+/*
+ * (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin@sysmocom.de>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/gsm48_rest_octets.h>
+
+struct si13_test {
+ const char *name;
+ const struct osmo_gsm48_si13_info si;
+ int enc_rc;
+ int dec_rc;
+ void (*post_dec_cb)(const struct si13_test *test, const struct osmo_gsm48_si13_info* dec);
+};
+
+void post_dec_cb_test_alpha(const struct si13_test *test, const struct osmo_gsm48_si13_info* dec)
+{
+ OSMO_ASSERT(test->si.pwr_ctrl_pars.alpha == dec->pwr_ctrl_pars.alpha);
+}
+
+static const struct si13_test test_si13_arr[] = {
+ {
+ .name = "test alpha",
+ .si = {
+ .cell_opts = {
+ .nmo = GPRS_NMO_II,
+ .t3168 = 2000,
+ .t3192 = 1500,
+ .drx_timer_max = 3,
+ .bs_cv_max = 15,
+ .ctrl_ack_type_use_block = true,
+ .ext_info_present = 0,
+ .ext_info = {
+ .egprs_supported = 1,
+ .use_egprs_p_ch_req = 1,
+ .bep_period = 5,
+ .pfc_supported = 0,
+ .dtm_supported = 0,
+ .bss_paging_coordination = 0,
+ .ccn_active = true,
+ },
+ },
+ .pwr_ctrl_pars = {
+ .alpha = 5,
+ .t_avg_w = 16,
+ .t_avg_t = 16,
+ .pc_meas_chan = 0,
+ .n_avg_i = 8,
+ },
+ .bcch_change_mark = 1,
+ .si_change_field = 0,
+ .rac = 0x03,
+ .spgc_ccch_sup = 0,
+ .net_ctrl_ord = 0,
+ .prio_acc_thr = 6,
+ },
+ .enc_rc = 20,
+ .dec_rc = 71,
+ .post_dec_cb = post_dec_cb_test_alpha,
+ },
+};
+
+static void test_si13(void)
+{
+ int i, rc;
+ uint8_t data[GSM_MACBLOCK_LEN];
+ struct osmo_gsm48_si13_info si13;
+
+ for (i = 0; i < ARRAY_SIZE(test_si13_arr); i++) {
+ memset(data, 0, sizeof(data));
+ rc = osmo_gsm48_rest_octets_si13_encode(data, &test_si13_arr[i].si);
+ if (rc >= 0) {
+ printf("si13_encode (%d): %s\n", rc, osmo_hexdump(data, rc));
+ } else {
+ printf("si13_encode failed (%d)\n", rc);
+ }
+ OSMO_ASSERT(rc == test_si13_arr[i].enc_rc);
+ if (rc <= 0)
+ continue;
+ memset(&si13, 0 , sizeof(si13));
+ rc = osmo_gsm48_rest_octets_si13_decode(&si13, data);
+ if (rc >= 0) {
+ printf("si13_decode (%d)\n", rc);
+ } else {
+ printf("si13_decode failed (%d)\n", rc);
+ }
+ OSMO_ASSERT(rc == test_si13_arr[i].dec_rc);
+ if (test_si13_arr[i].post_dec_cb) {
+ test_si13_arr[i].post_dec_cb(&test_si13_arr[i], &si13);
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ test_si13();
+
+ return EXIT_SUCCESS;
+}
diff --git a/tests/gsm48/rest_octets_test.ok b/tests/gsm48/rest_octets_test.ok
new file mode 100644
index 00000000..54204f24
--- /dev/null
+++ b/tests/gsm48/rest_octets_test.ok
@@ -0,0 +1,2 @@
+si13_encode (20): 90 00 d8 5a 6f c9 e5 84 10 ab 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
+si13_decode (71)
diff --git a/tests/gsup/gsup_test.c b/tests/gsup/gsup_test.c
index f34ac7a6..3d7ea401 100644
--- a/tests/gsup/gsup_test.c
+++ b/tests/gsup/gsup_test.c
@@ -749,9 +749,10 @@ int main(int argc, char **argv)
{
void *ctx = talloc_named_const(NULL, 0, "gsup_test");
osmo_init_logging2(ctx, &info);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
log_set_print_timestamp(osmo_stderr_target, 0);
log_set_use_color(osmo_stderr_target, 0);
+ log_set_print_category_hex(osmo_stderr_target, 0);
log_set_print_category(osmo_stderr_target, 1);
test_gsup_messages_dec_enc();
diff --git a/tests/i460_mux/i460_mux_test.c b/tests/i460_mux/i460_mux_test.c
index 9d5fcf78..1be35e7d 100644
--- a/tests/i460_mux/i460_mux_test.c
+++ b/tests/i460_mux/i460_mux_test.c
@@ -1,7 +1,7 @@
#include <osmocom/core/utils.h>
-#include <osmocom/gsm/i460_mux.h>
+#include <osmocom/isdn/i460_mux.h>
static void bits_cb(struct osmo_i460_subchan *schan, void *user_data,
const ubit_t *bits, unsigned int num_bits)
@@ -395,4 +395,5 @@ int main(int argc, char **argv)
test_16k_subchan();
test_8k_subchan();
test_unused_subchan();
+ return 0;
}
diff --git a/tests/it_q/it_q_test.c b/tests/it_q/it_q_test.c
new file mode 100644
index 00000000..28e32d89
--- /dev/null
+++ b/tests/it_q/it_q_test.c
@@ -0,0 +1,120 @@
+#include <stdio.h>
+#include <errno.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/it_q.h>
+
+struct it_q_test1 {
+ struct llist_head list;
+ int *foo;
+};
+
+struct it_q_test2 {
+ int foo;
+ struct llist_head list;
+};
+
+#define ENTER_TC printf("\n== Entering test case %s\n", __func__)
+
+static void tc_alloc(void)
+{
+ struct osmo_it_q *q1, *q2;
+
+ ENTER_TC;
+
+ printf("allocating q1\n");
+ q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 3, NULL, NULL);
+ OSMO_ASSERT(q1);
+
+ /* ensure that no duplicate allocation for the */
+ printf("attempting duplicate allocation of qa\n");
+ q2 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 3, NULL, NULL);
+ OSMO_ASSERT(!q2);
+
+ /* ensure that same name can be re-created after destroying old one */
+ osmo_it_q_destroy(q1);
+ printf("re-allocating q1\n");
+ q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", 3, NULL, NULL);
+ OSMO_ASSERT(q1);
+
+ osmo_it_q_destroy(q1);
+}
+
+static void tc_queue_length(void)
+{
+ struct osmo_it_q *q1;
+ unsigned int qlen = 3;
+ struct it_q_test1 *item;
+ int i, rc;
+
+ ENTER_TC;
+
+ printf("allocating q1\n");
+ q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", qlen, NULL, NULL);
+ OSMO_ASSERT(q1);
+
+ printf("adding queue entries up to the limit\n");
+ for (i = 0; i < qlen; i++) {
+ item = talloc_zero(OTC_GLOBAL, struct it_q_test1);
+ rc = osmo_it_q_enqueue(q1, item, list);
+ OSMO_ASSERT(rc == 0);
+ }
+ printf("attempting to add more than the limit\n");
+ item = talloc_zero(OTC_GLOBAL, struct it_q_test1);
+ rc = osmo_it_q_enqueue(q1, item, list);
+ OSMO_ASSERT(rc == -ENOSPC);
+
+ osmo_it_q_destroy(q1);
+}
+
+static int g_read_cb_count;
+
+static void q_read_cb(struct osmo_it_q *q, struct llist_head *item)
+{
+ struct it_q_test1 *it = container_of(item, struct it_q_test1, list);
+ *it->foo += 1;
+ talloc_free(item);
+}
+
+static void tc_eventfd(void)
+{
+ struct osmo_it_q *q1;
+ unsigned int qlen = 30;
+ struct it_q_test1 *item;
+ int i, rc;
+
+ ENTER_TC;
+
+ printf("allocating q1\n");
+ q1 = osmo_it_q_alloc(OTC_GLOBAL, "q1", qlen, q_read_cb, NULL);
+ OSMO_ASSERT(q1);
+ osmo_fd_register(&q1->event_ofd);
+
+ /* ensure read-cb isn't called unless we enqueue something */
+ osmo_select_main(1);
+ OSMO_ASSERT(g_read_cb_count == 0);
+
+ /* ensure read-cb is called for each enqueued msg once */
+ printf("adding %u queue entries up to the limit\n", qlen);
+ for (i = 0; i < qlen; i++) {
+ item = talloc_zero(OTC_GLOBAL, struct it_q_test1);
+ item->foo = &g_read_cb_count;
+ rc = osmo_it_q_enqueue(q1, item, list);
+ OSMO_ASSERT(rc == 0);
+ }
+
+ osmo_select_main(1);
+ printf("%u entries were dequeued\n", qlen);
+ OSMO_ASSERT(g_read_cb_count == qlen);
+
+ osmo_it_q_destroy(q1);
+}
+
+int main(int argc, char **argv)
+{
+ tc_alloc();
+ tc_queue_length();
+ tc_eventfd();
+ return 0;
+}
diff --git a/tests/it_q/it_q_test.ok b/tests/it_q/it_q_test.ok
new file mode 100644
index 00000000..7f102c61
--- /dev/null
+++ b/tests/it_q/it_q_test.ok
@@ -0,0 +1,15 @@
+
+== Entering test case tc_alloc
+allocating q1
+attempting duplicate allocation of qa
+re-allocating q1
+
+== Entering test case tc_queue_length
+allocating q1
+adding queue entries up to the limit
+attempting to add more than the limit
+
+== Entering test case tc_eventfd
+allocating q1
+adding 30 queue entries up to the limit
+30 entries were dequeued
diff --git a/tests/iuup/iuup_test.c b/tests/iuup/iuup_test.c
new file mode 100644
index 00000000..e40b9e77
--- /dev/null
+++ b/tests/iuup/iuup_test.c
@@ -0,0 +1,764 @@
+#include <stdint.h>
+#include <stdio.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/select.h>
+
+#include <osmocom/gsm/prim.h>
+#include <osmocom/gsm/iuup.h>
+
+static void *iuup_test_ctx;
+
+static struct osmo_iuup_rnl_config def_configure_req = {
+ .transparent = false,
+ .active = true,
+ .supported_versions_mask = 0x0001,
+ .num_rfci = 3,
+ .num_subflows = 3,
+ .IPTIs_present = true,
+ .rfci = {
+ {.used = 1, .id = 0, .IPTI = 1, .subflow_sizes = {81, 103, 60} },
+ {.used = 1, .id = 1, .IPTI = 7, .subflow_sizes = {39, 0, 0} },
+ {.used = 1, .id = 2, .IPTI = 1, .subflow_sizes = {0, 0, 0} },
+ },
+ /* .delivery_err_sdu = All set to 0 (YES) by default, */
+ .IPTIs_present = true,
+ .t_init = { .t_ms = IUUP_TIMER_INIT_T_DEFAULT, .n_max = IUUP_TIMER_INIT_N_DEFAULT },
+ .t_ta = { .t_ms = IUUP_TIMER_TA_T_DEFAULT, .n_max = IUUP_TIMER_TA_N_DEFAULT },
+ .t_rc = { .t_ms = IUUP_TIMER_RC_T_DEFAULT, .n_max = IUUP_TIMER_RC_N_DEFAULT },
+};
+
+/* Frame 33, "Initialization", OS#4744 3g_call_23112021.pcapng
+IuUP
+ 1110 .... = PDU Type: Control Procedure (14)
+ .... 00.. = Ack/Nack: Procedure (0)
+ .... ..00 = Frame Number: 0
+ 0000 .... = Mode Version: 0x0
+ .... 0000 = Procedure: Initialization (0)
+ 1101 11.. = Header CRC: 0x37 [correct]
+ .... ..11 1001 1001 = Payload CRC: 0x399
+ 000. .... = Spare: 0x0
+ ...1 .... = TI: IPTIs present in frame (1)
+ .... 011. = Subflows: 3
+ .... ...0 = Chain Indicator: this frame is the last frame for the procedure (0)
+ RFCI 0 Initialization
+ 0... .... = RFCI 0 LRI: Not last RFCI (0x0)
+ .0.. .... = RFCI 0 LI: one octet used (0x0)
+ ..00 0000 = RFCI 0: 0
+ RFCI 0 Flow 0 Len: 81
+ RFCI 0 Flow 1 Len: 103
+ RFCI 0 Flow 2 Len: 60
+ RFCI 1 Initialization
+ 0... .... = RFCI 1 LRI: Not last RFCI (0x0)
+ .0.. .... = RFCI 1 LI: one octet used (0x0)
+ ..00 0001 = RFCI 1: 1
+ RFCI 1 Flow 0 Len: 39
+ RFCI 1 Flow 1 Len: 0
+ RFCI 1 Flow 2 Len: 0
+ RFCI 2 Initialization
+ 1... .... = RFCI 2 LRI: Last RFCI in current frame (0x1)
+ .0.. .... = RFCI 2 LI: one octet used (0x0)
+ ..00 0010 = RFCI 2: 2
+ RFCI 2 Flow 0 Len: 0
+ RFCI 2 Flow 1 Len: 0
+ RFCI 2 Flow 2 Len: 0
+ IPTIs
+ 0001 .... = RFCI 0 IPTI: 0x1
+ .... 0111 = RFCI 1 IPTI: 0x7
+ 0001 .... = RFCI 2 IPTI: 0x1
+ Iu UP Mode Versions Supported: 0x0001
+ 0... .... .... .... = Version 16: not supported (0x0)
+ .0.. .... .... .... = Version 15: not supported (0x0)
+ ..0. .... .... .... = Version 14: not supported (0x0)
+ ...0 .... .... .... = Version 13: not supported (0x0)
+ .... 0... .... .... = Version 12: not supported (0x0)
+ .... .0.. .... .... = Version 11: not supported (0x0)
+ .... ..0. .... .... = Version 10: not supported (0x0)
+ .... ...0 .... .... = Version 9: not supported (0x0)
+ .... .... 0... .... = Version 8: not supported (0x0)
+ .... .... .0.. .... = Version 7: not supported (0x0)
+ .... .... ..0. .... = Version 6: not supported (0x0)
+ .... .... ...0 .... = Version 5: not supported (0x0)
+ .... .... .... 0... = Version 4: not supported (0x0)
+ .... .... .... .0.. = Version 3: not supported (0x0)
+ .... .... .... ..0. = Version 2: not supported (0x0)
+ .... .... .... ...1 = Version 1: supported (0x1)
+ 0000 .... = RFCI Data Pdu Type: PDU type 0 (0x0)
+*/
+static const uint8_t iuup_initialization[] = {
+ 0xe0, 0x00, 0xdf, 0x99, 0x16, 0x00, 0x51, 0x67, 0x3c, 0x01, 0x27, 0x00,
+ 0x00, 0x82, 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x01, 0x00
+};
+
+/* Frame 87, "Data RFCI=0 FN = 1", OS#4744 3g_call_23112021.pcapng
+IuUP
+ 0000 .... = PDU Type: Data with CRC (0)
+ .... 0001 = Frame Number: 1
+ 00.. .... = FQC: Frame Good (0)
+ ..00 0000 = RFCI: 0x00
+ 1110 00.. = Header CRC: 0x38 [correct]
+ .... ..11 1111 1111 = Payload CRC: 0x3ff
+ Payload Data: 08556d944c71a1a081e7ead204244480000ecd82b81118000097c4794e7740
+*/
+static const uint8_t iuup_data[] = {
+ 0x01, 0x00, 0xe3, 0xff, /*payload starts here: */ 0x08, 0x55, 0x6d, 0x94, 0x4c, 0x71, 0xa1, 0xa0,
+ 0x81, 0xe7, 0xea, 0xd2, 0x04, 0x24, 0x44, 0x80, 0x00, 0x0e, 0xcd, 0x82,
+ 0xb8, 0x11, 0x18, 0x00, 0x00, 0x97, 0xc4, 0x79, 0x4e, 0x77, 0x40
+};
+
+#define IUUP_MSGB_SIZE 4096
+
+static struct osmo_iuup_tnl_prim *itp_ctrl_nack_alloc(enum iuup_procedure proc_ind, enum iuup_error_cause error_cause, uint8_t fn)
+{
+ struct osmo_iuup_tnl_prim *tnp;
+ struct iuup_ctrl_nack *nack;
+ tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
+ tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(struct iuup_ctrl_nack));
+ nack = (struct iuup_ctrl_nack *) msgb_l2(tnp->oph.msg);
+ *nack = (struct iuup_ctrl_nack){
+ .hdr = {
+ .frame_nr = fn,
+ .ack_nack = IUUP_AN_NACK,
+ .pdu_type = IUUP_PDU_T_CONTROL,
+ .proc_ind = proc_ind,
+ .mode_version = 0,
+ .payload_crc_hi = 0,
+ .header_crc = 0,
+ .payload_crc_lo = 0,
+ },
+ .spare = 0,
+ .error_cause = error_cause,
+ };
+ nack->hdr.header_crc = osmo_iuup_compute_header_crc(msgb_l2(tnp->oph.msg), msgb_l2len(tnp->oph.msg));
+ return tnp;
+}
+
+static struct osmo_iuup_tnl_prim *itp_ctrl_ack_alloc(enum iuup_procedure proc_ind, uint8_t fn)
+{
+ struct osmo_iuup_tnl_prim *tnp;
+ struct iuup_ctrl_ack *ack;
+ tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
+ tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(struct iuup_ctrl_ack));
+ ack = (struct iuup_ctrl_ack *) msgb_l2(tnp->oph.msg);
+ *ack = (struct iuup_ctrl_ack){
+ .hdr = {
+ .frame_nr = fn,
+ .ack_nack = IUUP_AN_ACK,
+ .pdu_type = IUUP_PDU_T_CONTROL,
+ .proc_ind = proc_ind,
+ .mode_version = 0,
+ .payload_crc_hi = 0,
+ .header_crc = 0,
+ .payload_crc_lo = 0,
+ },
+ };
+ ack->hdr.header_crc = osmo_iuup_compute_header_crc(msgb_l2(tnp->oph.msg), msgb_l2len(tnp->oph.msg));
+ return tnp;
+}
+
+static void clock_override_set(long sec, long usec)
+{
+ osmo_gettimeofday_override_time.tv_sec = sec + usec / (1000*1000);
+ osmo_gettimeofday_override_time.tv_usec = usec % (1000*1000);
+ printf("sys={%lu.%06lu}, %s\n", osmo_gettimeofday_override_time.tv_sec,
+ osmo_gettimeofday_override_time.tv_usec, __func__);
+}
+
+void test_crc(void)
+{
+ int rc;
+
+ /* Frame 34, "Initialization ACK", OS#4744 3g_call_23112021.pcapng */
+ static const uint8_t iuup_initialization_ack[] = {
+ 0xe4, 0x00, 0xdf, 0x99, 0x16, 0x00, 0x51, 0x67, 0x3c, 0x01, 0x27, 0x00,
+ 0x00, 0x82, 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x01, 0x00
+ };
+
+ printf("=== start: %s ===\n", __func__);
+
+ rc = osmo_iuup_compute_header_crc(iuup_initialization, sizeof(iuup_initialization));
+ printf("iuup_initialization: Header CRC = 0x%02x\n", rc);
+ rc = osmo_iuup_compute_payload_crc(iuup_initialization, sizeof(iuup_initialization));
+ printf("iuup_initialization: Payload CRC = 0x%03x\n", rc);
+
+ rc = osmo_iuup_compute_header_crc(iuup_initialization_ack, sizeof(iuup_initialization_ack));
+ printf("iuup_initialization_ack: Header CRC = 0x%02x\n", rc);
+ rc = osmo_iuup_compute_payload_crc(iuup_initialization_ack, sizeof(iuup_initialization_ack));
+ printf("iuup_initialization_ack: Payload CRC = 0x%03x\n", rc);
+
+ printf("=== end: %s ===\n", __func__);
+}
+
+
+/****************************
+ * test_tinit_timeout_retrans
+ ****************************/
+static unsigned int _tinit_timeout_retrans_user_rx_prim = 0;
+static int _tinit_timeout_retrans_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_rnl_prim *irp = (struct osmo_iuup_rnl_prim *)oph;
+ printf("%s()\n", __func__);
+
+ OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_STATUS, PRIM_OP_INDICATION));
+
+ OSMO_ASSERT(irp->u.status.procedure == IUUP_PROC_ERR_EVENT);
+ OSMO_ASSERT(irp->u.status.u.error_event.cause == IUUP_ERR_CAUSE_INIT_FAILURE_NET_TMR);
+ OSMO_ASSERT(irp->u.status.u.error_event.distance == IUUP_ERR_DIST_LOCAL);
+ _tinit_timeout_retrans_user_rx_prim++;
+ msgb_free(oph->msg);
+ return 0;
+}
+static unsigned int _tinit_timeout_retrans_transport_rx_prim = 0;
+static int _tinit_timeout_retrans_transport_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_tnl_prim *itp = (struct osmo_iuup_tnl_prim *)oph;
+ struct msgb *msg = oph->msg;
+
+ printf("%s()\n", __func__);
+ OSMO_ASSERT(OSMO_PRIM_HDR(&itp->oph) == OSMO_PRIM(OSMO_IUUP_TNL_UNITDATA, PRIM_OP_REQUEST));
+ printf("Transport: DL len=%u: %s\n", msgb_l2len(msg),
+ osmo_hexdump((const unsigned char *) msgb_l2(msg), msgb_l2len(msg)));
+ _tinit_timeout_retrans_transport_rx_prim++;
+
+ msgb_free(msg);
+ return 0;
+}
+void test_tinit_timeout_retrans(void)
+{
+ struct osmo_iuup_instance *iui;
+ struct osmo_iuup_rnl_prim *rnp;
+ int rc, i;
+
+ iui = osmo_iuup_instance_alloc(iuup_test_ctx, __func__);
+ OSMO_ASSERT(iui);
+ osmo_iuup_instance_set_user_prim_cb(iui, _tinit_timeout_retrans_user_prim_cb, NULL);
+ osmo_iuup_instance_set_transport_prim_cb(iui, _tinit_timeout_retrans_transport_prim_cb, NULL);
+
+ clock_override_set(0, 0);
+
+ /* Tx CONFIG.req */
+ rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
+ rnp->u.config = def_configure_req;
+ OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
+ /* STATUS-INIT.req is transmitted automatically: */
+ OSMO_ASSERT(_tinit_timeout_retrans_transport_rx_prim == 1);
+
+ /* After one sec, INITIALIZATION msg is retransmitted */
+ for (i = 1; i < IUUP_TIMER_INIT_N_DEFAULT + 1; i++) {
+ clock_override_set(0, IUUP_TIMER_INIT_T_DEFAULT*1000 * i);
+ osmo_select_main(0);
+ OSMO_ASSERT(_tinit_timeout_retrans_transport_rx_prim == i + 1);
+ }
+ /* Last one should send an error event: */
+ OSMO_ASSERT(_tinit_timeout_retrans_user_rx_prim == 0);
+ clock_override_set(0, IUUP_TIMER_INIT_T_DEFAULT*1000 * i);
+ osmo_select_main(0);
+ OSMO_ASSERT(_tinit_timeout_retrans_transport_rx_prim == i);
+ OSMO_ASSERT(_tinit_timeout_retrans_user_rx_prim == 1);
+
+ /* Nothing else is received afterwards. osmo_select_main() will block forever. */
+ /*clock_override_set(i + 1, 0);
+ osmo_select_main(0);
+ OSMO_ASSERT(_tinit_timeout_retrans_transport_rx_prim == i);
+ OSMO_ASSERT(_tinit_timeout_retrans_user_rx_prim == 1);*/
+
+ osmo_iuup_instance_free(iui);
+}
+
+/****************************
+ * test_tinit_nack
+ ****************************/
+static unsigned int _init_nack_retrans_user_rx_prim = 0;
+static int _init_nack_retrans_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_rnl_prim *irp = (struct osmo_iuup_rnl_prim *)oph;
+
+ printf("%s()\n", __func__);
+
+ OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_STATUS, PRIM_OP_INDICATION));
+
+ OSMO_ASSERT(irp->u.status.procedure == IUUP_PROC_ERR_EVENT);
+ OSMO_ASSERT(irp->u.status.u.error_event.cause == IUUP_ERR_CAUSE_INIT_FAILURE_REP_NACK);
+ OSMO_ASSERT(irp->u.status.u.error_event.distance == IUUP_ERR_DIST_SECOND_FWD);
+ _init_nack_retrans_user_rx_prim++;
+ msgb_free(oph->msg);
+ return 0;
+}
+static int _init_nack_retrans_transport_rx_prim = 0;
+static int _init_nack_retrans_transport_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_tnl_prim *itp = (struct osmo_iuup_tnl_prim *)oph;
+ struct msgb *msg = oph->msg;
+
+ printf("%s()\n", __func__);
+ OSMO_ASSERT(OSMO_PRIM_HDR(&itp->oph) == OSMO_PRIM(OSMO_IUUP_TNL_UNITDATA, PRIM_OP_REQUEST));
+ printf("Transport: DL len=%u: %s\n", msgb_l2len(msg),
+ osmo_hexdump((const unsigned char *) msgb_l2(msg), msgb_l2len(msg)));
+ _init_nack_retrans_transport_rx_prim++;
+
+ msgb_free(msg);
+ return 0;
+}
+void test_init_nack_retrans(void)
+{
+ struct osmo_iuup_instance *iui;
+ struct osmo_iuup_rnl_prim *rnp;
+ struct osmo_iuup_tnl_prim *tnp;
+ int rc, i;
+
+ iui = osmo_iuup_instance_alloc(iuup_test_ctx, __func__);
+ OSMO_ASSERT(iui);
+ osmo_iuup_instance_set_user_prim_cb(iui, _init_nack_retrans_user_prim_cb, NULL);
+ osmo_iuup_instance_set_transport_prim_cb(iui, _init_nack_retrans_transport_prim_cb, NULL);
+
+ clock_override_set(0, 0);
+
+ /* Tx CONFIG.req */
+ rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
+ rnp->u.config = def_configure_req;
+ OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
+ /* STATUS-INIT.req is transmitted automatically: */
+ OSMO_ASSERT(_init_nack_retrans_transport_rx_prim == 1);
+
+ /* After one sec, INITIALIZATION msg is retransmitted */
+ for (i = 1; i < IUUP_TIMER_INIT_N_DEFAULT + 1; i++) {
+ /* Send NACK: */
+ tnp = itp_ctrl_nack_alloc(IUUP_PROC_INIT, IUUP_ERR_CAUSE_MODE_VERSION_NOT_SUPPORTED, 0);
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ /* A new INIT is retransmitted: */
+ OSMO_ASSERT(_init_nack_retrans_transport_rx_prim == i + 1);
+ }
+ /* Last one should send an error event: */
+ OSMO_ASSERT(_init_nack_retrans_user_rx_prim == 0);
+ tnp = itp_ctrl_nack_alloc(IUUP_PROC_INIT, IUUP_ERR_CAUSE_MODE_VERSION_NOT_SUPPORTED, 0);
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ OSMO_ASSERT(_init_nack_retrans_transport_rx_prim == i);
+ OSMO_ASSERT(_init_nack_retrans_user_rx_prim == 1);
+
+ /* Nothing else is received afterwards. osmo_select_main() will block forever. */
+
+ osmo_iuup_instance_free(iui);
+}
+
+
+/****************************
+ * test_init_ack
+ ****************************/
+static unsigned int _init_ack_user_rx_prim = 0;
+static int _init_ack_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_rnl_prim *irp = (struct osmo_iuup_rnl_prim *)oph;
+ struct msgb *msg = oph->msg;
+
+ printf("%s()\n", __func__);
+
+ OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_DATA, PRIM_OP_INDICATION));
+ printf("User: UL len=%u: %s\n", msgb_l3len(msg),
+ osmo_hexdump((const unsigned char *) msgb_l3(msg), msgb_l3len(msg)));
+
+ _init_ack_user_rx_prim++;
+ msgb_free(oph->msg);
+ return 0;
+}
+static int _init_ack_transport_rx_prim = 0;
+static int _init_ack_transport_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_tnl_prim *itp = (struct osmo_iuup_tnl_prim *)oph;
+ struct msgb *msg = oph->msg;
+
+ printf("%s()\n", __func__);
+ OSMO_ASSERT(OSMO_PRIM_HDR(&itp->oph) == OSMO_PRIM(OSMO_IUUP_TNL_UNITDATA, PRIM_OP_REQUEST));
+ printf("Transport: DL len=%u: %s\n", msgb_l2len(msg),
+ osmo_hexdump((const unsigned char *) msgb_l2(msg), msgb_l2len(msg)));
+ _init_ack_transport_rx_prim++;
+
+ msgb_free(msg);
+ return 0;
+}
+void test_init_ack(void)
+{
+ struct osmo_iuup_instance *iui;
+ struct osmo_iuup_rnl_prim *rnp;
+ struct osmo_iuup_tnl_prim *tnp;
+ struct iuup_pdutype0_hdr *hdr0;
+ int rc;
+
+ iui = osmo_iuup_instance_alloc(iuup_test_ctx, __func__);
+ OSMO_ASSERT(iui);
+ osmo_iuup_instance_set_user_prim_cb(iui, _init_ack_user_prim_cb, NULL);
+ osmo_iuup_instance_set_transport_prim_cb(iui, _init_ack_transport_prim_cb, NULL);
+
+ clock_override_set(0, 0);
+
+ /* Tx CONFIG.req */
+ rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
+ rnp->u.config = def_configure_req;
+ OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
+ /* STATUS-INIT.req is transmitted automatically: */
+ OSMO_ASSERT(_init_ack_transport_rx_prim == 1);
+
+ /* Send ACK: */
+ tnp = itp_ctrl_ack_alloc(IUUP_PROC_INIT, 0);
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ OSMO_ASSERT(_init_ack_transport_rx_prim == 1); /* Make sure there's no retrans */
+ OSMO_ASSERT(_init_ack_user_rx_prim == 0); /* Make sure there's no error event */
+
+ /* Send IuUP incoming data to the implementation: */
+ tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
+ tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(iuup_data));
+ hdr0 = (struct iuup_pdutype0_hdr *)msgb_l2(tnp->oph.msg);
+ memcpy(hdr0, iuup_data, sizeof(iuup_data));
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ /* We receive it in RNL: */
+ OSMO_ASSERT(_init_ack_user_rx_prim == 1);
+
+ /* Now in opposite direction, RNL->[IuuP]->TNL: */
+ rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_DATA, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
+ rnp->u.data.rfci = 0;
+ rnp->u.data.frame_nr = 1;
+ rnp->u.data.fqc = IUUP_FQC_FRAME_GOOD;
+ rnp->oph.msg->l3h = msgb_put(rnp->oph.msg, sizeof(iuup_data) - 4);
+ memcpy(rnp->oph.msg->l3h, iuup_data + 4, sizeof(iuup_data) - 4);
+ OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
+ OSMO_ASSERT(_init_ack_transport_rx_prim == 2); /* We receive data in TNL */
+
+ osmo_iuup_instance_free(iui);
+}
+
+/****************************
+ * test_passive_init
+ ****************************/
+static unsigned int _passive_init_user_rx_prim = 0;
+static int _passive_init_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_rnl_prim *irp = (struct osmo_iuup_rnl_prim *)oph;
+ struct msgb *msg = oph->msg;
+
+ printf("%s()\n", __func__);
+
+ switch (_passive_init_user_rx_prim) {
+ case 0:
+ OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_STATUS, PRIM_OP_INDICATION));
+ OSMO_ASSERT(irp->u.status.procedure == IUUP_PROC_INIT);
+ break;
+ case 1:
+ default:
+ OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_DATA, PRIM_OP_INDICATION));
+ printf("User: UL len=%u: %s\n", msgb_l3len(msg),
+ osmo_hexdump((const unsigned char *) msgb_l3(msg), msgb_l3len(msg)));
+ }
+
+ _passive_init_user_rx_prim++;
+ msgb_free(oph->msg);
+ return 0;
+}
+static int _passive_init_transport_rx_prim = 0;
+static int _passive_init_transport_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_tnl_prim *itp = (struct osmo_iuup_tnl_prim *)oph;
+ struct msgb *msg;
+
+ printf("%s()\n", __func__);
+ msg = oph->msg;
+ OSMO_ASSERT(OSMO_PRIM_HDR(&itp->oph) == OSMO_PRIM(OSMO_IUUP_TNL_UNITDATA, PRIM_OP_REQUEST));
+ printf("Transport: DL len=%u: %s\n", msgb_l2len(msg),
+ osmo_hexdump((const unsigned char *) msgb_l2(msg), msgb_l2len(msg)));
+ _passive_init_transport_rx_prim++;
+
+ msgb_free(msg);
+ return 0;
+}
+void test_passive_init(void)
+{
+ /* Here we check the passive INIT code path, aka receiving INIT and returning INIT_ACK/NACK */
+ struct osmo_iuup_instance *iui;
+ struct osmo_iuup_rnl_prim *rnp;
+ struct osmo_iuup_tnl_prim *tnp;
+ struct iuup_pdutype14_hdr *hdr14;
+ struct iuup_pdutype0_hdr *hdr0;
+ int rc;
+
+ iui = osmo_iuup_instance_alloc(iuup_test_ctx, __func__);
+ OSMO_ASSERT(iui);
+ osmo_iuup_instance_set_user_prim_cb(iui, _passive_init_user_prim_cb, NULL);
+ osmo_iuup_instance_set_transport_prim_cb(iui, _passive_init_transport_prim_cb, NULL);
+
+ clock_override_set(0, 0);
+
+ /* Tx CONFIG.req */
+ rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
+ rnp->u.config = def_configure_req;
+ rnp->u.config.active = false;
+ OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
+ /* STATUS-INIT.req is NOT transmitted automatically: */
+ OSMO_ASSERT(_passive_init_transport_rx_prim == 0);
+
+ /* Send Init: */
+ tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
+ tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(iuup_initialization));
+ hdr14 = (struct iuup_pdutype14_hdr *)msgb_l2(tnp->oph.msg);
+ memcpy(hdr14, iuup_initialization, sizeof(iuup_initialization));
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ OSMO_ASSERT(_passive_init_transport_rx_prim == 1); /* We receive an Init ACK */
+ OSMO_ASSERT(_passive_init_user_rx_prim == 1); /* We receive the Status-Init.ind */
+
+ /* Send IuUP incoming data to the implementation: */
+ tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
+ tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(iuup_data));
+ hdr0 = (struct iuup_pdutype0_hdr *)msgb_l2(tnp->oph.msg);
+ memcpy(hdr0, iuup_data, sizeof(iuup_data));
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ /* We receive it in RNL: */
+ OSMO_ASSERT(_passive_init_user_rx_prim == 2);
+
+ /* Now in opposite direction, RNL->[IuuP]->TNL: */
+ rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_DATA, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
+ rnp->u.data.rfci = 0;
+ rnp->u.data.frame_nr = 1;
+ rnp->u.data.fqc = IUUP_FQC_FRAME_GOOD;
+ rnp->oph.msg->l3h = msgb_put(rnp->oph.msg, sizeof(iuup_data) - 4);
+ memcpy(rnp->oph.msg->l3h, iuup_data + 4, sizeof(iuup_data) - 4);
+ OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
+ OSMO_ASSERT(_passive_init_transport_rx_prim == 2); /* We receive data in TNL */
+
+ osmo_iuup_instance_free(iui);
+}
+
+/****************************
+ * test_passive_init_retrans
+ ****************************/
+static unsigned int _passive_init_retrans_user_rx_prim = 0;
+static int _passive_init_retrans_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_rnl_prim *irp = (struct osmo_iuup_rnl_prim *)oph;
+ struct msgb *msg = oph->msg;
+
+ printf("%s()\n", __func__);
+
+ switch (_passive_init_retrans_user_rx_prim) {
+ case 0:
+ case 1:
+ OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_STATUS, PRIM_OP_INDICATION));
+ OSMO_ASSERT(irp->u.status.procedure == IUUP_PROC_INIT);
+ break;
+ case 2:
+ default:
+ OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_DATA, PRIM_OP_INDICATION));
+ printf("User: UL len=%u: %s\n", msgb_l3len(msg),
+ osmo_hexdump((const unsigned char *) msgb_l3(msg), msgb_l3len(msg)));
+ }
+
+ _passive_init_retrans_user_rx_prim++;
+ msgb_free(oph->msg);
+ return 0;
+}
+void test_passive_init_retrans(void)
+{
+ /* Here we check the passive INIT code path, aka receiving INIT and
+ * returning INIT_ACK/NACK. We emulate the peer not receiving the INIT
+ * ACK and hence retransmitting the INIT. The IuUP stack should then
+ * push the new INIT info up the stack and ACK it. */
+ struct osmo_iuup_instance *iui;
+ struct osmo_iuup_rnl_prim *rnp;
+ struct osmo_iuup_tnl_prim *tnp;
+ struct iuup_pdutype14_hdr *hdr14;
+ struct iuup_pdutype0_hdr *hdr0;
+ int rc;
+
+ /* reset global var, we reuse it together wth callback from test_passive_init(): */
+ _passive_init_transport_rx_prim = 0;
+
+ iui = osmo_iuup_instance_alloc(iuup_test_ctx, __func__);
+ OSMO_ASSERT(iui);
+ osmo_iuup_instance_set_user_prim_cb(iui, _passive_init_retrans_user_prim_cb, NULL);
+ osmo_iuup_instance_set_transport_prim_cb(iui, _passive_init_transport_prim_cb, NULL);
+
+ clock_override_set(0, 0);
+
+ /* Tx CONFIG.req */
+ rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
+ rnp->u.config = def_configure_req;
+ rnp->u.config.active = false;
+ OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
+ /* STATUS-INIT.req is NOT transmitted automatically: */
+ OSMO_ASSERT(_passive_init_transport_rx_prim == 0);
+
+ /* Send Init: */
+ tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
+ tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(iuup_initialization));
+ hdr14 = (struct iuup_pdutype14_hdr *)msgb_l2(tnp->oph.msg);
+ memcpy(hdr14, iuup_initialization, sizeof(iuup_initialization));
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ OSMO_ASSERT(_passive_init_transport_rx_prim == 1); /* We receive an Init ACK */
+ OSMO_ASSERT(_passive_init_retrans_user_rx_prim == 1); /* We receive the Status-Init.ind */
+
+ /* Send Init (retrans): */
+ tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
+ tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(iuup_initialization));
+ hdr14 = (struct iuup_pdutype14_hdr *)msgb_l2(tnp->oph.msg);
+ memcpy(hdr14, iuup_initialization, sizeof(iuup_initialization));
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ OSMO_ASSERT(_passive_init_transport_rx_prim == 2); /* We receive another Init ACK */
+ OSMO_ASSERT(_passive_init_retrans_user_rx_prim == 2); /* We receive another Status-Init.ind */
+
+ /* Send IuUP incoming data to the implementation: */
+ tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
+ tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(iuup_data));
+ hdr0 = (struct iuup_pdutype0_hdr *)msgb_l2(tnp->oph.msg);
+ memcpy(hdr0, iuup_data, sizeof(iuup_data));
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ /* We receive it in RNL: */
+ OSMO_ASSERT(_passive_init_retrans_user_rx_prim == 3);
+
+ /* Now in opposite direction, RNL->[IuuP]->TNL: */
+ rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_DATA, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
+ rnp->u.data.rfci = 0;
+ rnp->u.data.frame_nr = 1;
+ rnp->u.data.fqc = IUUP_FQC_FRAME_GOOD;
+ rnp->oph.msg->l3h = msgb_put(rnp->oph.msg, sizeof(iuup_data) - 4);
+ memcpy(rnp->oph.msg->l3h, iuup_data + 4, sizeof(iuup_data) - 4);
+ OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
+ OSMO_ASSERT(_passive_init_transport_rx_prim == 3); /* We receive data in TNL */
+
+ osmo_iuup_instance_free(iui);
+}
+
+static int _decode_passive_init_2_rfci_no_iptis_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_rnl_prim *irp = (struct osmo_iuup_rnl_prim *)oph;
+ printf("%s(): Initialization decoded fine!\n", __func__);
+ OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_STATUS, PRIM_OP_INDICATION));
+ OSMO_ASSERT(irp->u.status.procedure == IUUP_PROC_INIT);
+ OSMO_ASSERT(irp->u.status.u.initialization.num_rfci == 2);
+ OSMO_ASSERT(irp->u.status.u.initialization.num_subflows == 3);
+ OSMO_ASSERT(irp->u.status.u.initialization.data_pdu_type == 0);
+ OSMO_ASSERT(irp->u.status.u.initialization.IPTIs_present == false);
+ msgb_free(oph->msg);
+ return 0;
+}
+static int _decode_passive_init_2_rfci_no_iptis_transport_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_iuup_tnl_prim *itp = (struct osmo_iuup_tnl_prim *)oph;
+ struct msgb *msg;
+ struct iuup_pdutype14_hdr *hdr;
+
+ printf("%s()\n", __func__);
+ msg = oph->msg;
+ OSMO_ASSERT(OSMO_PRIM_HDR(&itp->oph) == OSMO_PRIM(OSMO_IUUP_TNL_UNITDATA, PRIM_OP_REQUEST));
+ printf("Transport: DL len=%u: %s\n", msgb_l2len(msg),
+ osmo_hexdump((const unsigned char *) msgb_l2(msg), msgb_l2len(msg)));
+ hdr = msgb_l2(msg);
+ OSMO_ASSERT(hdr->pdu_type == IUUP_PDU_T_CONTROL);
+ OSMO_ASSERT(hdr->ack_nack == IUUP_AN_ACK);
+ msgb_free(msg);
+ return 0;
+}
+void test_decode_passive_init_2_rfci_no_iptis(void)
+{
+ /* Here we check the passive INIT code path, aka receiving INIT and returning INIT_ACK/NACK */
+ struct osmo_iuup_instance *iui;
+ struct osmo_iuup_rnl_prim *rnp;
+ struct osmo_iuup_tnl_prim *tnp;
+ struct iuup_pdutype14_hdr *hdr14;
+ int rc;
+
+ /* Frame 46, "Initialization", SYS#5969 call4_Iu_Iuh.pcap
+ 1110 .... = PDU Type: Control Procedure (14)
+ .... 00.. = Ack/Nack: Procedure (0)
+ .... ..00 = Frame Number: 0
+ 0000 .... = Mode Version: 0x0
+ .... 0000 = Procedure: Initialization (0)
+ 1101 11.. = Header CRC: 0x37 [correct]
+ .... ..01 1011 0100 = Payload CRC: 0x1b4
+ 000. .... = Spare: 0x0
+ ...0 .... = TI: IPTIs not present (0)
+ .... 011. = Subflows: 3
+ .... ...0 = Chain Indicator: this frame is the last frame for the procedure (0)
+ RFCI 1 Initialization
+ 0... .... = RFCI 0 LRI: Not last RFCI (0x0)
+ .0.. .... = RFCI 0 LI: one octet used (0x0)
+ ..00 0001 = RFCI 0: 1
+ RFCI 0 Flow 0 Len: 81
+ RFCI 0 Flow 1 Len: 103
+ RFCI 0 Flow 2 Len: 60
+ RFCI 6 Initialization
+ 1... .... = RFCI 1 LRI: Last RFCI in current frame (0x1)
+ .0.. .... = RFCI 1 LI: one octet used (0x0)
+ ..00 0110 = RFCI 1: 6
+ RFCI 1 Flow 0 Len: 39
+ RFCI 1 Flow 1 Len: 0
+ RFCI 1 Flow 2 Len: 0
+ Iu UP Mode Versions Supported: 0x0001
+ 0... .... .... .... = Version 16: not supported (0x0)
+ .0.. .... .... .... = Version 15: not supported (0x0)
+ ..0. .... .... .... = Version 14: not supported (0x0)
+ ...0 .... .... .... = Version 13: not supported (0x0)
+ .... 0... .... .... = Version 12: not supported (0x0)
+ .... .0.. .... .... = Version 11: not supported (0x0)
+ .... ..0. .... .... = Version 10: not supported (0x0)
+ .... ...0 .... .... = Version 9: not supported (0x0)
+ .... .... 0... .... = Version 8: not supported (0x0)
+ .... .... .0.. .... = Version 7: not supported (0x0)
+ .... .... ..0. .... = Version 6: not supported (0x0)
+ .... .... ...0 .... = Version 5: not supported (0x0)
+ .... .... .... 0... = Version 4: not supported (0x0)
+ .... .... .... .0.. = Version 3: not supported (0x0)
+ .... .... .... ..0. = Version 2: not supported (0x0)
+ .... .... .... ...1 = Version 1: supported (0x1)
+ 0000 .... = RFCI Data Pdu Type: PDU type 0 (0x0)
+ */
+ const uint8_t iuup_init[] = {
+ 0xe0, 0x00, 0xdd, 0xb4, 0x06, 0x01, 0x51, 0x67, 0x3c, 0x86, 0x27,
+ 0x00, 0x00, 0x00, 0x01, 0x00
+ };
+
+ iui = osmo_iuup_instance_alloc(iuup_test_ctx, __func__);
+ OSMO_ASSERT(iui);
+ osmo_iuup_instance_set_user_prim_cb(iui, _decode_passive_init_2_rfci_no_iptis_user_prim_cb, NULL);
+ osmo_iuup_instance_set_transport_prim_cb(iui, _decode_passive_init_2_rfci_no_iptis_transport_prim_cb, NULL);
+
+ clock_override_set(0, 0);
+
+ /* Tx CONFIG.req */
+ rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
+ rnp->u.config = def_configure_req;
+ rnp->u.config.active = false;
+ OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
+
+ /* Send Init: */
+ tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
+ tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(iuup_init));
+ hdr14 = (struct iuup_pdutype14_hdr *)msgb_l2(tnp->oph.msg);
+ memcpy(hdr14, iuup_init, sizeof(iuup_init));
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+
+ osmo_iuup_instance_free(iui);
+}
+
+int main(int argc, char **argv)
+{
+ iuup_test_ctx = talloc_named_const(NULL, 0, "iuup_test");
+ osmo_init_logging2(iuup_test_ctx, NULL);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category(osmo_stderr_target, 1);
+ log_set_print_category_hex(osmo_stderr_target, 0);
+ log_set_use_color(osmo_stderr_target, 0);
+ log_set_category_filter(osmo_stderr_target, DLIUUP, 1, LOGL_DEBUG);
+ osmo_fsm_log_addr(false);
+
+ osmo_gettimeofday_override = true;
+
+ test_crc();
+ test_tinit_timeout_retrans();
+ test_init_nack_retrans();
+ test_init_ack();
+ test_passive_init();
+ test_passive_init_retrans();
+ test_decode_passive_init_2_rfci_no_iptis();
+
+ printf("OK.\n");
+}
diff --git a/tests/iuup/iuup_test.ok b/tests/iuup/iuup_test.ok
new file mode 100644
index 00000000..57baba9c
--- /dev/null
+++ b/tests/iuup/iuup_test.ok
@@ -0,0 +1,61 @@
+=== start: test_crc ===
+iuup_initialization: Header CRC = 0x37
+iuup_initialization: Payload CRC = 0x399
+iuup_initialization_ack: Header CRC = 0x09
+iuup_initialization_ack: Payload CRC = 0x399
+=== end: test_crc ===
+sys={0.000000}, clock_override_set
+_tinit_timeout_retrans_transport_prim_cb()
+Transport: DL len=22: e0 00 df 99 16 00 51 67 3c 01 27 00 00 82 00 00 00 17 10 00 01 00
+sys={1.000000}, clock_override_set
+_tinit_timeout_retrans_transport_prim_cb()
+Transport: DL len=22: e0 00 df 99 16 00 51 67 3c 01 27 00 00 82 00 00 00 17 10 00 01 00
+sys={2.000000}, clock_override_set
+_tinit_timeout_retrans_transport_prim_cb()
+Transport: DL len=22: e0 00 df 99 16 00 51 67 3c 01 27 00 00 82 00 00 00 17 10 00 01 00
+sys={3.000000}, clock_override_set
+_tinit_timeout_retrans_transport_prim_cb()
+Transport: DL len=22: e0 00 df 99 16 00 51 67 3c 01 27 00 00 82 00 00 00 17 10 00 01 00
+sys={4.000000}, clock_override_set
+_tinit_timeout_retrans_user_prim_cb()
+sys={0.000000}, clock_override_set
+_init_nack_retrans_transport_prim_cb()
+Transport: DL len=22: e0 00 df 99 16 00 51 67 3c 01 27 00 00 82 00 00 00 17 10 00 01 00
+_init_nack_retrans_transport_prim_cb()
+Transport: DL len=22: e0 00 df 99 16 00 51 67 3c 01 27 00 00 82 00 00 00 17 10 00 01 00
+_init_nack_retrans_transport_prim_cb()
+Transport: DL len=22: e0 00 df 99 16 00 51 67 3c 01 27 00 00 82 00 00 00 17 10 00 01 00
+_init_nack_retrans_transport_prim_cb()
+Transport: DL len=22: e0 00 df 99 16 00 51 67 3c 01 27 00 00 82 00 00 00 17 10 00 01 00
+_init_nack_retrans_user_prim_cb()
+sys={0.000000}, clock_override_set
+_init_ack_transport_prim_cb()
+Transport: DL len=22: e0 00 df 99 16 00 51 67 3c 01 27 00 00 82 00 00 00 17 10 00 01 00
+_init_ack_user_prim_cb()
+User: UL len=31: 08 55 6d 94 4c 71 a1 a0 81 e7 ea d2 04 24 44 80 00 0e cd 82 b8 11 18 00 00 97 c4 79 4e 77 40
+_init_ack_transport_prim_cb()
+Transport: DL len=35: 01 00 e3 ff 08 55 6d 94 4c 71 a1 a0 81 e7 ea d2 04 24 44 80 00 0e cd 82 b8 11 18 00 00 97 c4 79 4e 77 40
+sys={0.000000}, clock_override_set
+_passive_init_user_prim_cb()
+_passive_init_transport_prim_cb()
+Transport: DL len=4: e4 00 24 00
+_passive_init_user_prim_cb()
+User: UL len=31: 08 55 6d 94 4c 71 a1 a0 81 e7 ea d2 04 24 44 80 00 0e cd 82 b8 11 18 00 00 97 c4 79 4e 77 40
+_passive_init_transport_prim_cb()
+Transport: DL len=35: 01 00 e3 ff 08 55 6d 94 4c 71 a1 a0 81 e7 ea d2 04 24 44 80 00 0e cd 82 b8 11 18 00 00 97 c4 79 4e 77 40
+sys={0.000000}, clock_override_set
+_passive_init_retrans_user_prim_cb()
+_passive_init_transport_prim_cb()
+Transport: DL len=4: e4 00 24 00
+_passive_init_retrans_user_prim_cb()
+_passive_init_transport_prim_cb()
+Transport: DL len=4: e4 00 24 00
+_passive_init_retrans_user_prim_cb()
+User: UL len=31: 08 55 6d 94 4c 71 a1 a0 81 e7 ea d2 04 24 44 80 00 0e cd 82 b8 11 18 00 00 97 c4 79 4e 77 40
+_passive_init_transport_prim_cb()
+Transport: DL len=35: 01 00 e3 ff 08 55 6d 94 4c 71 a1 a0 81 e7 ea d2 04 24 44 80 00 0e cd 82 b8 11 18 00 00 97 c4 79 4e 77 40
+sys={0.000000}, clock_override_set
+_decode_passive_init_2_rfci_no_iptis_user_prim_cb(): Initialization decoded fine!
+_decode_passive_init_2_rfci_no_iptis_transport_prim_cb()
+Transport: DL len=4: e4 00 24 00
+OK.
diff --git a/tests/lapd/lapd_test.c b/tests/lapd/lapd_test.c
index 48851f47..739f9b7d 100644
--- a/tests/lapd/lapd_test.c
+++ b/tests/lapd/lapd_test.c
@@ -16,10 +16,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/core/application.h>
@@ -380,7 +376,7 @@ static int ms_to_bts_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *_ctx
return 0;
}
-static void test_lapdm_polling()
+static void test_lapdm_polling(void)
{
printf("I do some very simple LAPDm test.\n");
@@ -474,7 +470,7 @@ static void test_lapdm_polling()
lapdm_channel_exit(&ms_to_bts_channel);
}
-static void test_lapdm_contention_resolution()
+static void test_lapdm_contention_resolution(void)
{
printf("I test contention resultion by having two mobiles collide and "
"first mobile repeating SABM.\n");
@@ -527,7 +523,7 @@ static void test_lapdm_contention_resolution()
lapdm_channel_exit(&bts_to_ms_channel);
}
-static void test_lapdm_early_release()
+static void test_lapdm_early_release(void)
{
printf("I test RF channel release of an unestablished channel.\n");
@@ -607,7 +603,7 @@ static void lapdm_establish(const uint8_t *est_req, size_t est_req_size)
msgb_free(msg);
}
-static void test_lapdm_establishment()
+static void test_lapdm_establishment(void)
{
printf("I test RF channel establishment.\n");
printf("Testing SAPI3/SDCCH\n");
@@ -681,7 +677,7 @@ static void dump_queue(struct llist_head *head)
printf("\n");
}
-static void test_lapdm_desync()
+static void test_lapdm_desync(void)
{
printf("I test if desync problems exist in LAPDm\n");
diff --git a/tests/logging/logging_test.c b/tests/logging/logging_test.c
index b9cb57fb..3548b1dd 100644
--- a/tests/logging/logging_test.c
+++ b/tests/logging/logging_test.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/core/logging.h>
@@ -77,10 +73,16 @@ int main(int argc, char **argv)
stderr_target = log_target_create_stderr();
log_add_target(stderr_target);
log_set_all_filter(stderr_target, 1);
- log_set_print_filename(stderr_target, 0);
+ log_set_print_filename2(stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category_hex(stderr_target, 0);
log_set_print_category(stderr_target, 1);
log_set_use_color(stderr_target, 0);
+ if (argc > 1 && !strcmp(argv[1], "wqueue"))
+ log_target_file_switch_to_wqueue(stderr_target);
+ else
+ log_target_file_switch_to_stream(stderr_target);
+
log_parse_category_mask(stderr_target, "DRLL:DCC");
log_parse_category_mask(stderr_target, "DRLL");
@@ -128,5 +130,13 @@ int main(int argc, char **argv)
log_set_category_filter(stderr_target, DLGLOBAL, 1, LOGL_DEBUG);
DEBUGP(DLGLOBAL, "You should see this (DLGLOBAL on DEBUG)\n");
+ /* Test printing of the filename */
+ log_set_print_filename2(stderr_target, LOG_FILENAME_BASENAME);
+
+ log_set_print_filename_pos(stderr_target, LOG_FILENAME_POS_HEADER_END);
+ DEBUGP(DLGLOBAL, "A message with source info printed first\n");
+ log_set_print_filename_pos(stderr_target, LOG_FILENAME_POS_LINE_END);
+ DEBUGP(DLGLOBAL, "A message with source info printed last\n");
+
return 0;
}
diff --git a/tests/logging/logging_test.err b/tests/logging/logging_test.err
index 17b3cad0..01ab8782 100644
--- a/tests/logging/logging_test.err
+++ b/tests/logging/logging_test.err
@@ -7,3 +7,5 @@ DLGLOBAL You should see this on DLGLOBAL (c)
DLGLOBAL You should see this on DLGLOBAL (d)
DLGLOBAL You should see this on DLGLOBAL (e)
DLGLOBAL You should see this (DLGLOBAL on DEBUG)
+DLGLOBAL logging_test.c:137 A message with source info printed first
+DLGLOBAL A message with source info printed last (logging_test.c:139)
diff --git a/tests/logging/logging_vty_test.c b/tests/logging/logging_vty_test.c
index e7019f61..15f7fc2b 100644
--- a/tests/logging/logging_vty_test.c
+++ b/tests/logging/logging_vty_test.c
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#define _GNU_SOURCE
@@ -82,7 +78,7 @@ DEFUN(log_sweep, log_sweep_cmd,
return CMD_SUCCESS;
}
-static void vty_commands_init()
+static void vty_commands_init(void)
{
install_element_ve(&log_sweep_cmd);
}
@@ -125,7 +121,7 @@ const struct log_info log_info = {
.num_cat = ARRAY_SIZE(default_categories),
};
-static void print_help()
+static void print_help(void)
{
printf( "options:\n"
" -h --help this text\n"
@@ -254,6 +250,7 @@ int main(int argc, char **argv)
log_set_print_category_hex(osmo_stderr_target, 0);
log_set_print_level(osmo_stderr_target, 1);
log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_target_file_switch_to_wqueue(osmo_stderr_target);
if (cmdline_config.config_file) {
rc = vty_read_config_file(cmdline_config.config_file, NULL);
@@ -264,7 +261,7 @@ int main(int argc, char **argv)
}
}
- rc = telnet_init_dynif(root_ctx, NULL, vty_get_bind_addr(), 42042);
+ rc = telnet_init_default(root_ctx, NULL, 42042);
if (rc < 0)
return 2;
diff --git a/tests/logging/logging_vty_test.vty b/tests/logging/logging_vty_test.vty
index 5a5d7e65..2cff62c1 100644
--- a/tests/logging/logging_vty_test.vty
+++ b/tests/logging/logging_vty_test.vty
@@ -29,7 +29,7 @@ logging_vty_test(config)# no log stderr
logging_vty_test(config)# exit
logging_vty_test# logging level force-all notice
-Logging was not enabled.
+% Logging was not enabled.
logging_vty_test# logging enable
logging_vty_test# logging filter all 1
@@ -48,12 +48,13 @@ logging_vty_test# list
logging color (0|1)
logging timestamp (0|1)
logging print extended-timestamp (0|1)
+ logging print thread-id (0|1)
logging print category (0|1)
logging print category-hex (0|1)
logging print level (0|1)
logging print file (0|1|basename) [last]
logging set-log-mask MASK
- logging level (aa|bb|ccc|dddd|eee|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro|lns) (debug|info|notice|error|fatal)
+ logging level (aa|bb|ccc|dddd|eee|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro|lns|lbssgp|lnsdata|lnssignal|liuup|lpfcp|lcsn1) (debug|info|notice|error|fatal)
logging level set-all (debug|info|notice|error|fatal)
logging level force-all (debug|info|notice|error|fatal)
no logging level force-all
@@ -471,38 +472,44 @@ DEEE FATAL Log message for DEEE on level LOGL_FATAL
logging_vty_test# list
...
- logp (aa|bb|ccc|dddd|eee|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro|lns) (debug|info|notice|error|fatal) .LOGMESSAGE
+ logp (aa|bb|ccc|dddd|eee|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro|lns|lbssgp|lnsdata|lnssignal|liuup|lpfcp|lcsn1) (debug|info|notice|error|fatal) .LOGMESSAGE
...
logging_vty_test# logp?
logp Print a message on all log outputs; useful for placing markers in test logs
logging_vty_test# logp ?
- aa Antropomorphic Armadillos (AA)
- bb Bidirectional Breadspread (BB)
- ccc Chaos Communication Congress (CCC)
- dddd Dehydrated Dribbling Duck Dunkers (DDDD)
- eee Exhaustive Entropy Extraction (EEE)
- lglobal Library-internal global log family
- llapd LAPD in libosmogsm
- linp A-bis Intput Subsystem
- lmux A-bis B-Subchannel TRAU Frame Multiplex
- lmi A-bis Input Driver for Signalling
- lmib A-bis Input Driver for B-Channels (voice)
- lsms Layer3 Short Message Service (SMS)
- lctrl Control Interface
- lgtp GPRS GTP library
- lstats Statistics messages and logging
- lgsup Generic Subscriber Update Protocol
- loap Osmocom Authentication Protocol
- lss7 libosmo-sigtran Signalling System 7
- lsccp libosmo-sigtran SCCP Implementation
- lsua libosmo-sigtran SCCP User Adaptation
- lm3ua libosmo-sigtran MTP3 User Adaptation
- lmgcp libosmo-mgcp Media Gateway Control Protocol
- ljibuf libosmo-netif Jitter Buffer
- lrspro Remote SIM protocol
- lns GPRS NS layer
+ aa Antropomorphic Armadillos (AA)
+ bb Bidirectional Breadspread (BB)
+ ccc Chaos Communication Congress (CCC)
+ dddd Dehydrated Dribbling Duck Dunkers (DDDD)
+ eee Exhaustive Entropy Extraction (EEE)
+ lglobal Library-internal global log family
+ llapd LAPD in libosmogsm
+ linp A-bis Intput Subsystem
+ lmux A-bis B-Subchannel TRAU Frame Multiplex
+ lmi A-bis Input Driver for Signalling
+ lmib A-bis Input Driver for B-Channels (voice)
+ lsms Layer3 Short Message Service (SMS)
+ lctrl Control Interface
+ lgtp GPRS GTP library
+ lstats Statistics messages and logging
+ lgsup Generic Subscriber Update Protocol
+ loap Osmocom Authentication Protocol
+ lss7 libosmo-sigtran Signalling System 7
+ lsccp libosmo-sigtran SCCP Implementation
+ lsua libosmo-sigtran SCCP User Adaptation
+ lm3ua libosmo-sigtran MTP3 User Adaptation
+ lmgcp libosmo-mgcp Media Gateway Control Protocol
+ ljibuf libosmo-netif Jitter Buffer
+ lrspro Remote SIM protocol
+ lns GPRS NS layer
+ lbssgp GPRS BSSGP layer
+ lnsdata GPRS NS layer data PDU
+ lnssignal GPRS NS layer signal PDU
+ liuup Iu UP layer
+ lpfcp libosmo-pfcp Packet Forwarding Control Protocol
+ lcsn1 libosmo-csn1 Concrete Syntax Notation 1 codec
logging_vty_test# logp lglobal ?
debug Log debug messages and higher levels
@@ -522,3 +529,6 @@ DAA ERROR This is the log message
logging_vty_test# logp lglobal debug This log message is not echoed
logging_vty_test# logp lglobal notice This log message is echoed
DLGLOBAL NOTICE This log message is echoed
+
+logging_vty_test# logp lctrl notice This is a CTRL specific message
+DLCTRL NOTICE This is a CTRL specific message
diff --git a/tests/loggingrb/loggingrb_test.c b/tests/loggingrb/loggingrb_test.c
index 0b2ae5b5..fd11896a 100644
--- a/tests/loggingrb/loggingrb_test.c
+++ b/tests/loggingrb/loggingrb_test.c
@@ -14,10 +14,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/core/logging.h>
@@ -64,7 +60,9 @@ int main(int argc, char **argv)
ringbuf_target = log_target_create_rb(0x1000);
log_add_target(ringbuf_target);
log_set_all_filter(ringbuf_target, 1);
- log_set_print_filename(ringbuf_target, 0);
+ log_set_print_filename2(ringbuf_target, LOG_FILENAME_NONE);
+ log_set_print_category(ringbuf_target, 0);
+ log_set_print_category_hex(ringbuf_target, 0);
log_parse_category_mask(ringbuf_target, "DRLL:DCC");
log_parse_category_mask(ringbuf_target, "DRLL");
diff --git a/tests/msgb/msgb_test.c b/tests/msgb/msgb_test.c
index ffaa1557..7966103b 100644
--- a/tests/msgb/msgb_test.c
+++ b/tests/msgb/msgb_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdlib.h>
@@ -65,7 +61,7 @@ static int osmo_panic_try(volatile int *exception, int setjmp_result)
return *exception == 0;
}
-static void test_msgb_api()
+static void test_msgb_api(void)
{
struct msgb *msg = msgb_alloc_headroom(4096, 128, "data");
unsigned char *cptr = NULL;
@@ -121,7 +117,7 @@ static void test_msgb_api()
msgb_free(msg);
}
-static void test_msgb_api_errors()
+static void test_msgb_api_errors(void)
{
struct msgb *msg = msgb_alloc_headroom(4096, 128, "data");
volatile int e = 0;
@@ -142,7 +138,7 @@ static void test_msgb_api_errors()
osmo_set_panic_handler(NULL);
}
-static void test_msgb_copy()
+static void test_msgb_copy(void)
{
struct msgb *msg = msgb_alloc_headroom(4096, 128, "data");
struct msgb *msg2;
@@ -165,19 +161,31 @@ static void test_msgb_copy()
OSMO_ASSERT(msgb_l1len(msg) == msgb_l1len(msg2));
OSMO_ASSERT(msgb_l2len(msg) == msgb_l2len(msg2));
OSMO_ASSERT(msgb_l3len(msg) == msgb_l3len(msg2));
- OSMO_ASSERT(msg->tail - msg->l4h == msg2->tail - msg2->l4h);
+ OSMO_ASSERT(msgb_l4len(msg) == msgb_l4len(msg2));
+
+ if (!msgb_eq_data_print(msg2, msg->data, msgb_length(msg)))
+ printf("copy test failed!\n");
- for (i = 0; i < msgb_length(msg2); i++)
- OSMO_ASSERT(msg2->data[i] == (uint8_t)i);
+ if (!msgb_eq_l1_data_print(msg2, msgb_l1(msg), msgb_l1len(msg)))
+ printf("copy test failed at L1!\n");
+ if (!msgb_eq_l2_data_print(msg2, msgb_l2(msg), msgb_l2len(msg)))
+ printf("copy test failed at L2!\n");
+ if (!msgb_eq_l3_data_print(msg2, msgb_l3(msg), msgb_l3len(msg)))
+ printf("copy test failed at L3!\n");
+ if (!msgb_eq_l4_data_print(msg2, msgb_l4(msg), msgb_l4len(msg)))
+ printf("copy test failed at L4!\n");
printf("Src: %s\n", msgb_hexdump(msg));
- printf("Dst: %s\n", msgb_hexdump(msg));
+ printf("Dst: %s\n", msgb_hexdump(msg2));
+
+ OSMO_ASSERT(msgb_test_invariant(msg));
+ OSMO_ASSERT(msgb_test_invariant(msg2));
msgb_free(msg);
msgb_free(msg2);
}
-static void test_msgb_resize_area()
+static void test_msgb_resize_area(void)
{
struct msgb *msg = msgb_alloc_headroom(4096, 128, "data");
int rc;
@@ -277,7 +285,7 @@ static void test_msgb_resize_area()
osmo_set_panic_handler(NULL);
}
-static void test_msgb_printf()
+static void test_msgb_printf(void)
{
struct msgb *msg;
struct msgb *msg_ref;
diff --git a/tests/msgfile/msgfile_test.c b/tests/msgfile/msgfile_test.c
index 2684b6a4..3fe173d6 100644
--- a/tests/msgfile/msgfile_test.c
+++ b/tests/msgfile/msgfile_test.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/core/msgfile.h>
diff --git a/tests/oap/oap_client_test.c b/tests/oap/oap_client_test.c
index dadf2ee7..622912f9 100644
--- a/tests/oap/oap_client_test.c
+++ b/tests/oap/oap_client_test.c
@@ -260,7 +260,8 @@ int main(int argc, char **argv)
OSMO_ASSERT(osmo_stderr_target);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_timestamp(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category_hex(osmo_stderr_target, 0);
log_set_print_category(osmo_stderr_target, 1);
log_parse_category_mask(osmo_stderr_target, "DLOAP,1");
diff --git a/tests/oap/oap_test.c b/tests/oap/oap_test.c
index 32676ca3..bebd6031 100644
--- a/tests/oap/oap_test.c
+++ b/tests/oap/oap_test.c
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/core/application.h>
diff --git a/tests/osmo-auc-gen/osmo-auc-gen_test.ok b/tests/osmo-auc-gen/osmo-auc-gen_test.ok
index 2840783a..3c41f41b 100644
--- a/tests/osmo-auc-gen/osmo-auc-gen_test.ok
+++ b/tests/osmo-auc-gen/osmo-auc-gen_test.ok
@@ -9,6 +9,8 @@ AUTN: 790c5d80c47b0000716ce00883bc39e1
IK: 6cf555588bb61ab2ff23cd333c05ed09
CK: f0b29f50a7d873f30336473bdc35d04f
RES: f511d3a7f06e6a30
+IMS nonce: amEFB2XKoyyQNxNw5dbcLXkMXYDEewAAcWzgCIO8OeE=
+IMS res: 9RHTp/BuajA=
SRES: 057fb997
Kc: 60524000cc5e5407
SQN: 0
@@ -24,6 +26,8 @@ AUTN: 790c5d80c47a000058508ab3864e26a0
IK: 6cf555588bb61ab2ff23cd333c05ed09
CK: f0b29f50a7d873f30336473bdc35d04f
RES: f511d3a7f06e6a30
+IMS nonce: amEFB2XKoyyQNxNw5dbcLXkMXYDEegAAWFCKs4ZOJqA=
+IMS res: 9RHTp/BuajA=
SRES: 057fb997
Kc: 60524000cc5e5407
SQN: 1
@@ -39,6 +43,8 @@ AUTN: 790c5d80c46c0000e74d796ec095dbee
IK: 6cf555588bb61ab2ff23cd333c05ed09
CK: f0b29f50a7d873f30336473bdc35d04f
RES: f511d3a7f06e6a30
+IMS nonce: amEFB2XKoyyQNxNw5dbcLXkMXYDEbAAA5015bsCV2+4=
+IMS res: 9RHTp/BuajA=
SRES: 057fb997
Kc: 60524000cc5e5407
SQN: 23
@@ -54,6 +60,8 @@ AUTN: 434a46a71aeb0000fedc563f27a0916c
IK: d7213dd74860ccb8c14e54c0c4abc91c
CK: c350653d72f7a5bac3a27422e5186019
RES: 912cdfaadd7b0154
+IMS nonce: HcT5dDJczmEeVPUW3B/sVkNKRqca6wAA/txWPyegkWw=
+IMS res: kSzfqt17AVQ=
SRES: 4c57defe
Kc: 169d78081b24c007
SQN: 42
@@ -69,6 +77,8 @@ AUTN: bfbf3332c91e0000d6199cad31d15f26
IK: 191a93c4396113bff6939d4f98e169a6
CK: 9c38d9089265ed5ea164e190a65c200d
RES: fd40205be2c9c7b2
+IMS nonce: KkgWL/PtykrfC3teUn1sFr+/MzLJHgAA1hmcrTHRXyY=
+IMS res: /UAgW+LJx7I=
SRES: 1f89e7e9
Kc: d2d5361395b9b74a
SQN: 99
@@ -84,6 +94,8 @@ AUTN: afb993e4f4b8000069cdeebb4a4b5b58
IK: c348c2fe2f3e1fb37a7ae1638163bd98
CK: e740c156278705a14e1a99ba6d31334f
RES: 7c04e86a67967fcd
+IMS nonce: amEFB2XKoyyQNxNw5dbcLa+5k+T0uAAAac3uu0pLW1g=
+IMS res: fAToameWf80=
SRES: 1b9297a7
Kc: 10687b71e4eb94c5
SQN: 281474976710655
@@ -99,6 +111,8 @@ AUTN: 8704f5ba55d30000541dde77ea5b1d8c
IK: 27497388b6cb044648f396aa155b95ef
CK: f64735036e5871319c679f4742a75ea1
RES: e229c19e791f2e41
+IMS nonce: OfovTj1SPYYZpztPZcPhTYcE9bpV0wAAVB3ed+pbHYw=
+IMS res: 4inBnnkfLkE=
SRES: 9b36efdf
Kc: 059a4f668f6fbe39
SQN: 32
@@ -115,6 +129,8 @@ AUTN: 8704f5ba55d6000079267a4b347ad890
IK: 27497388b6cb044648f396aa155b95ef
CK: f64735036e5871319c679f4742a75ea1
RES: e229c19e791f2e41
+IMS nonce: OfovTj1SPYYZpztPZcPhTYcE9bpV1gAAeSZ6SzR62JA=
+IMS res: 4inBnnkfLkE=
SRES: 9b36efdf
Kc: 059a4f668f6fbe39
SQN: 37
@@ -131,6 +147,8 @@ AUTN: 8704f5ba55c40000129ddaa4f5016e25
IK: 27497388b6cb044648f396aa155b95ef
CK: f64735036e5871319c679f4742a75ea1
RES: e229c19e791f2e41
+IMS nonce: OfovTj1SPYYZpztPZcPhTYcE9bpVxAAAEp3apPUBbiU=
+IMS res: 4inBnnkfLkE=
SRES: 9b36efdf
Kc: 059a4f668f6fbe39
SQN: 55
@@ -147,6 +165,8 @@ AUTN: 8704f5ba55cc00009d169f5ff89f6087
IK: 27497388b6cb044648f396aa155b95ef
CK: f64735036e5871319c679f4742a75ea1
RES: e229c19e791f2e41
+IMS nonce: OfovTj1SPYYZpztPZcPhTYcE9bpVzAAAnRafX/ifYIc=
+IMS res: 4inBnnkfLkE=
SRES: 9b36efdf
Kc: 059a4f668f6fbe39
SQN: 63
@@ -163,6 +183,8 @@ AUTN: 8704f5ba55eb0000d7fc4f7f19cfc180
IK: 27497388b6cb044648f396aa155b95ef
CK: f64735036e5871319c679f4742a75ea1
RES: e229c19e791f2e41
+IMS nonce: OfovTj1SPYYZpztPZcPhTYcE9bpV6wAA1/xPfxnPwYA=
+IMS res: 4inBnnkfLkE=
SRES: 9b36efdf
Kc: 059a4f668f6fbe39
SQN: 24
@@ -179,6 +201,8 @@ AUTN: 8704f5ba55eb0000d7fc4f7f19cfc180
IK: 27497388b6cb044648f396aa155b95ef
CK: f64735036e5871319c679f4742a75ea1
RES: e229c19e791f2e41
+IMS nonce: OfovTj1SPYYZpztPZcPhTYcE9bpV6wAA1/xPfxnPwYA=
+IMS res: 4inBnnkfLkE=
SRES: 9b36efdf
Kc: 059a4f668f6fbe39
SQN: 24
@@ -195,6 +219,8 @@ AUTN: 8704f5ba55ea0000aab06de3fd6c01af
IK: 27497388b6cb044648f396aa155b95ef
CK: f64735036e5871319c679f4742a75ea1
RES: e229c19e791f2e41
+IMS nonce: OfovTj1SPYYZpztPZcPhTYcE9bpV6gAAqrBt4/1sAa8=
+IMS res: 4inBnnkfLkE=
SRES: 9b36efdf
Kc: 059a4f668f6fbe39
SQN: 25
@@ -211,6 +237,8 @@ AUTN: 8704f5ba54f30000cbba2fbba3c5e242
IK: 27497388b6cb044648f396aa155b95ef
CK: f64735036e5871319c679f4742a75ea1
RES: e229c19e791f2e41
+IMS nonce: OfovTj1SPYYZpztPZcPhTYcE9bpU8wAAy7ovu6PF4kI=
+IMS res: 4inBnnkfLkE=
SRES: 9b36efdf
Kc: 059a4f668f6fbe39
SQN: 256
@@ -227,6 +255,8 @@ AUTN: 8704f5ba54f200008f8e14579da5ecbb
IK: 27497388b6cb044648f396aa155b95ef
CK: f64735036e5871319c679f4742a75ea1
RES: e229c19e791f2e41
+IMS nonce: OfovTj1SPYYZpztPZcPhTYcE9bpU8gAAj44UV52l7Ls=
+IMS res: 4inBnnkfLkE=
SRES: 9b36efdf
Kc: 059a4f668f6fbe39
SQN: 257
diff --git a/tests/sercomm/sercomm_test.c b/tests/sercomm/sercomm_test.c
index 058c9eb4..9bffc0d8 100644
--- a/tests/sercomm/sercomm_test.c
+++ b/tests/sercomm/sercomm_test.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
diff --git a/tests/sim/sim_test.c b/tests/sim/sim_test.c
index 425ce11d..2e2eec58 100644
--- a/tests/sim/sim_test.c
+++ b/tests/sim/sim_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
diff --git a/tests/sms/sms_test.c b/tests/sms/sms_test.c
index 06153964..912c0829 100644
--- a/tests/sms/sms_test.c
+++ b/tests/sms/sms_test.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
@@ -219,7 +215,7 @@ static const struct test_case test_decode[] =
},
};
-static void test_octet_return()
+static void test_octet_return(void)
{
char out[256];
int oct, septets;
@@ -268,6 +264,54 @@ static void test_gen_oa(void)
printf("Result: len(%d) data(%s)\n", len, osmo_hexdump(oa, len));
}
+static void test_enc_large_msg(void)
+{
+ uint8_t enc_buf[2048 * 7 / 8];
+ char large_msg[2048 + 1];
+ int i, j, nsep, noct = 0;
+
+ printf("\nRunning %s\n", __func__);
+
+ /* Expected chunks (repeated) in the output buffer */
+ const uint8_t exp_chunk[] = { 0xc1, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x83 };
+
+ /* Length variants to be tested */
+ static const size_t nlen[] = { 2048, 1024, 555, 512, 260, 255, 250 };
+
+ memset(&large_msg[0], (int) 'A', sizeof(large_msg) - 1);
+
+ for (i = 0; i < ARRAY_SIZE(nlen); i++) {
+ /* Clear the output buffer first */
+ memset(&enc_buf[0], 0x00, sizeof(enc_buf));
+ /* Limit length of the input string */
+ large_msg[nlen[i]] = '\0';
+
+ /* How many octets we expect to be used? */
+ int noct_exp = nlen[i] * 7 / 8;
+ if (nlen[i] % 8 != 0)
+ noct_exp++;
+
+ /* Encode a sequence of 'A' repeated nlen[i] times */
+ nsep = gsm_7bit_encode_n(&enc_buf[0], sizeof(enc_buf), large_msg, &noct);
+ printf("gsm_7bit_encode_n(len=%zu) processed %d septets (expected %zu): %s\n",
+ nlen[i], nsep, nlen[i], nsep == nlen[i] ? "OK" : "FAIL");
+ printf("gsm_7bit_encode_n(len=%zu) used %d octets in the buffer (expected %d): %s\n",
+ nlen[i], noct, noct_exp, noct == noct_exp ? "OK" : "FAIL");
+
+ /* The encoding result is expected to consist of repeated chunks */
+ for (j = 0; j < noct_exp; j += sizeof(exp_chunk)) {
+ size_t len = OSMO_MIN(noct_exp - j, sizeof(exp_chunk));
+ if (nlen[i] % 8 != 0) /* skip incomplete octets */
+ len--;
+ if (memcmp(&enc_buf[j], exp_chunk, len) != 0) {
+ printf("\tUnexpected chunk at enc_buf[%d:%zu]: %s\n",
+ j, len, osmo_hexdump(&enc_buf[j], len));
+ break; /* No need to show them all */
+ }
+ }
+ }
+}
+
int main(int argc, char** argv)
{
printf("SMS testing\n");
@@ -336,7 +380,7 @@ int main(int argc, char** argv)
memcpy(tmp, septet_data, concatenated_part1_septet_length);
/* In our case: test_multiple_decode[0].ud_hdr_ind equals number of padding bits*/
- octet_length = gsm_septets2octets(coded, tmp, concatenated_part1_septet_length, test_multiple_encode[0].ud_hdr_ind);
+ octet_length = gsm_septet_pack(coded, tmp, concatenated_part1_septet_length, test_multiple_encode[0].ud_hdr_ind);
/* copy header */
memset(tmp, 0x42, sizeof(tmp));
@@ -354,7 +398,7 @@ int main(int argc, char** argv)
memcpy(tmp, septet_data + concatenated_part1_septet_length, concatenated_part2_septet_length);
/* In our case: test_multiple_decode[1].ud_hdr_ind equals number of padding bits*/
- octet_length = gsm_septets2octets(coded, tmp, concatenated_part2_septet_length, test_multiple_encode[1].ud_hdr_ind);
+ octet_length = gsm_septet_pack(coded, tmp, concatenated_part2_septet_length, test_multiple_encode[1].ud_hdr_ind);
/* copy header */
memset(tmp, 0x42, sizeof(tmp));
@@ -396,6 +440,7 @@ int main(int argc, char** argv)
test_octet_return();
test_gen_oa();
+ test_enc_large_msg();
printf("OK\n");
return 0;
diff --git a/tests/sms/sms_test.ok b/tests/sms/sms_test.ok
index a71567de..de1fce3a 100644
--- a/tests/sms/sms_test.ok
+++ b/tests/sms/sms_test.ok
@@ -18,4 +18,20 @@ Result: len(12) data(14 a1 21 43 65 87 09 21 43 65 87 19 )
Result: len(2) data(00 91 )
Result: len(9) data(0e d0 4f 78 d9 2d 9c 0e 01 )
Result: len(12) data(14 d0 4f 78 d9 2d 9c 0e c3 e2 31 19 )
+
+Running test_enc_large_msg
+gsm_7bit_encode_n(len=2048) processed 2048 septets (expected 2048): OK
+gsm_7bit_encode_n(len=2048) used 1792 octets in the buffer (expected 1792): OK
+gsm_7bit_encode_n(len=1024) processed 1024 septets (expected 1024): OK
+gsm_7bit_encode_n(len=1024) used 896 octets in the buffer (expected 896): OK
+gsm_7bit_encode_n(len=555) processed 555 septets (expected 555): OK
+gsm_7bit_encode_n(len=555) used 486 octets in the buffer (expected 486): OK
+gsm_7bit_encode_n(len=512) processed 512 septets (expected 512): OK
+gsm_7bit_encode_n(len=512) used 448 octets in the buffer (expected 448): OK
+gsm_7bit_encode_n(len=260) processed 260 septets (expected 260): OK
+gsm_7bit_encode_n(len=260) used 228 octets in the buffer (expected 228): OK
+gsm_7bit_encode_n(len=255) processed 255 septets (expected 255): OK
+gsm_7bit_encode_n(len=255) used 224 octets in the buffer (expected 224): OK
+gsm_7bit_encode_n(len=250) processed 250 septets (expected 250): OK
+gsm_7bit_encode_n(len=250) used 219 octets in the buffer (expected 219): OK
OK
diff --git a/tests/smscb/cbsp_test.c b/tests/smscb/cbsp_test.c
new file mode 100644
index 00000000..2dbdded7
--- /dev/null
+++ b/tests/smscb/cbsp_test.c
@@ -0,0 +1,108 @@
+/*
+ * (C) 2022 by sysmocom - s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Pau Espin Pedrol <pespin@sysmocom.de>
+ *
+ * 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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+
+#include <osmocom/gsm/protocol/gsm_48_049.h>
+#include <osmocom/gsm/cbsp.h>
+
+/*
+CBSP WRITE-REPLACE FAILURE
+ Message Type: WRITE-REPLACE FAILURE (3)
+ Message Length: 44
+ IE: Message Identifier: 0x0031
+ Information Element Identifier: Message Identifier (14)
+ Message Identifier: 0x0031
+ IE: New Serial Number: 0x4170
+ Information Element Identifier: New Serial Number (3)
+ New Serial Number: 0x4170
+ IE: Failure List: 2 items
+ Information Element Identifier: Failure List (9)
+ Information Element Length: 15
+ Failure List Item: MCC 901 International Mobile, shared code, MNC 70 Clementvale Baltic OÜ, LAC 0x0018, CI 0x0030: Cause Cell-identity-not-valid
+ Cell ID Discriminator: CGI (0)
+ Mobile Country Code (MCC): International Mobile, shared code (901)
+ Mobile Network Code (MNC): Clementvale Baltic OÜ (70)
+ Location Area Code (LAC): 0x0018
+ Cell Identifier (CI): 0x0030
+ Cause: Cell-identity-not-valid (0x03)
+ Failure List Item: LAC 02711, CI 0xc351: Cause LAI-or-LAC-not-valid
+ Cell ID Discriminator: LAC+CI (1)
+ Location Area Code (LAC): 0x2711
+ Cell Identifier (CI): 0xc351
+ Cause: LAI-or-LAC-not-valid (0x0f)
+ IE: Cell List (CGI): 2 items
+ Information Element Identifier: Cell List (4)
+ Information Element Length: 15
+ Cell ID Discriminator: CGI (0)
+ Cell List Item: MCC 901 International Mobile, shared code, MNC 70 Clementvale Baltic OÜ, LAC 0x0017, CI 0x002a
+ Mobile Country Code (MCC): International Mobile, shared code (901)
+ Mobile Network Code (MNC): Clementvale Baltic OÜ (70)
+ Location Area Code (LAC): 0x0017
+ Cell Identifier (CI): 0x002a
+ Cell List Item: MCC 901 International Mobile, shared code, MNC 70 Clementvale Baltic OÜ, LAC 0x0018, CI 0x002a
+ Mobile Country Code (MCC): International Mobile, shared code (901)
+ Mobile Network Code (MNC): Clementvale Baltic OÜ (70)
+ Location Area Code (LAC): 0x0018
+ Cell Identifier (CI): 0x002a
+ IE: Channel Indicator: basic channel
+ Information Element Identifier: Channel Indicator (18)
+ Channel Indicator: basic channel (0x00)
+*/
+static const char write_repl_fail_with_failure_list[] =
+ "0300002c0e003103417009000f0009f1070018003003012711c3510f04000f0009f1070017002a09f1070018002a1200";
+
+static struct msgb *msgb_from_hex(unsigned int size, const char *hex)
+{
+ struct msgb *msg = msgb_alloc(size, "test_cbsp");
+ OSMO_ASSERT(msg);
+ msg->l1h = msgb_put(msg, osmo_hexparse(hex, msg->data, msgb_tailroom(msg)));
+ msg->l2h = msg->l1h + sizeof(struct cbsp_header);
+ return msg;
+}
+
+static void test_decode(void)
+{
+ struct msgb *msg;
+ struct osmo_cbsp_decoded *cbsp_dec;
+
+ printf("=== %s start ===\n", __func__);
+
+ msg = msgb_from_hex(sizeof(write_repl_fail_with_failure_list),
+ write_repl_fail_with_failure_list);
+
+ cbsp_dec = osmo_cbsp_decode(NULL, msg);
+ OSMO_ASSERT(cbsp_dec);
+
+ talloc_free(cbsp_dec);
+ msgb_free(msg);
+
+ printf("=== %s end ===\n", __func__);
+}
+
+int main(int argc, char **argv)
+{
+ test_decode();
+
+ return EXIT_SUCCESS;
+}
diff --git a/tests/smscb/cbsp_test.ok b/tests/smscb/cbsp_test.ok
new file mode 100644
index 00000000..a837de57
--- /dev/null
+++ b/tests/smscb/cbsp_test.ok
@@ -0,0 +1,2 @@
+=== test_decode start ===
+=== test_decode end ===
diff --git a/tests/smscb/gsm0341_test.c b/tests/smscb/gsm0341_test.c
index c400f5c8..966a00fd 100644
--- a/tests/smscb/gsm0341_test.c
+++ b/tests/smscb/gsm0341_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <string.h>
@@ -29,7 +25,7 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/msgb.h>
-struct gsm341_ms_message *gen_msg_from_text(uint16_t msg_id, const char *text)
+struct gsm341_ms_message *gen_msg_from_text(uint16_t msg_id, uint8_t msg_code, const char *text)
{
struct gsm341_ms_message *cbmsg;
int text_len = strlen(text);
@@ -38,11 +34,11 @@ struct gsm341_ms_message *gen_msg_from_text(uint16_t msg_id, const char *text)
uint8_t payload[text_len];
int payload_octets;
- srand(time(NULL));
+ //srand(time(NULL));
gsm_7bit_encode_n(payload, sizeof(payload), text, &payload_octets);
//cbmsg = gsm0341_build_msg(NULL, 0, rand(), 0, msg_id, 0x0f, 1, 1, payload, payload_octets);
- cbmsg = gsm0341_build_msg(NULL, 0, rand(), 0, msg_id, 0x00, 1, 1, payload, payload_octets);
+ cbmsg = gsm0341_build_msg(NULL, 0, msg_code, 0, msg_id, 0x00, 1, 1, payload, payload_octets);
printf("%s\n", osmo_hexdump_nospc((uint8_t *)cbmsg, sizeof(*cbmsg)+payload_octets));
@@ -54,6 +50,7 @@ int main(int argc, char **argv)
uint16_t msg_id = GSM341_MSGID_ETWS_CMAS_MONTHLY_TEST;
char *text = "Mahlzeit!";
char tbuf[GSM341_MAX_CHARS+1];
+ struct gsm341_ms_message *cbmsg;
if (argc > 1)
msg_id = atoi(argv[1]);
@@ -67,7 +64,8 @@ int main(int argc, char **argv)
sizeof(tbuf)-strlen(text));
tbuf[GSM341_MAX_CHARS] = 0;
- gen_msg_from_text(msg_id, tbuf);
+ cbmsg = gen_msg_from_text(msg_id, 1, tbuf);
+ talloc_free(cbmsg);
return EXIT_SUCCESS;
}
diff --git a/tests/smscb/gsm0341_test.ok b/tests/smscb/gsm0341_test.ok
new file mode 100644
index 00000000..600797c3
--- /dev/null
+++ b/tests/smscb/gsm0341_test.ok
@@ -0,0 +1 @@
+0010111c0011cd309aad2fa7e9a146a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d168341a8d46a3d100
diff --git a/tests/smscb/smscb_test.c b/tests/smscb/smscb_test.c
index 5925f69b..3b6b74d3 100644
--- a/tests/smscb/smscb_test.c
+++ b/tests/smscb/smscb_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/gsm/protocol/gsm_03_41.h>
diff --git a/tests/sockaddr_str/sockaddr_str_test.c b/tests/sockaddr_str/sockaddr_str_test.c
index 64a61043..541c3a15 100644
--- a/tests/sockaddr_str/sockaddr_str_test.c
+++ b/tests/sockaddr_str/sockaddr_str_test.c
@@ -18,10 +18,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
@@ -94,7 +90,7 @@ void dump_oip(const struct osmo_sockaddr_str *oip)
printf("{ .af = %s, .ip = %s, .port = %u }\n", af_name(oip->af), osmo_quote_str(oip->ip, -1), oip->port);
}
-void sockaddr_str_test_conversions()
+void sockaddr_str_test_conversions(void)
{
int i;
char buf[1024];
@@ -239,7 +235,7 @@ void sockaddr_str_test_conversions()
}
-static void test_osmo_sockaddr_str_cmp()
+static void test_osmo_sockaddr_str_cmp(void)
{
int i;
printf("\n\n%s\n", __func__);
diff --git a/tests/socket/socket_sctp_test.c b/tests/socket/socket_sctp_test.c
index e70b8be5..e099be92 100644
--- a/tests/socket/socket_sctp_test.c
+++ b/tests/socket/socket_sctp_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
@@ -35,7 +31,7 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/bits.h>
-#include "../config.h"
+#include "config.h"
void *ctx = NULL;
@@ -222,7 +218,9 @@ int main(int argc, char *argv[])
ctx = talloc_named_const(NULL, 0, "socket_test_sctp");
osmo_init_logging2(ctx, &info);
log_set_use_color(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category(osmo_stderr_target, 0);
+ log_set_print_category_hex(osmo_stderr_target, 0);
#ifdef HAVE_LIBSCTP
test_sockinit2_multiaddr_simple();
test_sockinit2_multiaddr_several();
diff --git a/tests/socket/socket_test.c b/tests/socket/socket_test.c
index 671177fb..ddb69268 100644
--- a/tests/socket/socket_test.c
+++ b/tests/socket/socket_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
@@ -36,7 +32,7 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/bits.h>
-#include "../config.h"
+#include "config.h"
void *ctx = NULL;
@@ -154,7 +150,7 @@ static int test_sockinit2(void)
return 0;
}
-static int test_get_ip_and_port()
+static int test_get_ip_and_port(void)
{
int fd, rc;
char ip[INET6_ADDRSTRLEN] = { };
@@ -313,6 +309,139 @@ static int test_sockinit_osa(void)
return 0;
}
+static void test_osa_str(void)
+{
+ char buf[256];
+ const char *result;
+ struct osmo_sockaddr localhost4 = {};
+ struct osmo_sockaddr localhost6 = {};
+
+ localhost4.u.sin = (struct sockaddr_in){
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = inet_addr("127.0.0.1"),
+ .sin_port = htons(42),
+ };
+
+ localhost6.u.sin6 = (struct sockaddr_in6){
+ .sin6_family = AF_INET6,
+ .sin6_port = htons(42),
+ };
+ inet_pton(AF_INET6, "::1", &localhost6.u.sin6.sin6_addr);
+
+ /* test a too short str */
+ memset(&buf[0], 0, sizeof(buf));
+ result = osmo_sockaddr_to_str_buf(buf, 1, &localhost4);
+ printf("Checking osmo_sockaddr_to_str_buf to small IPv4\n");
+ OSMO_ASSERT(result == NULL);
+
+ memset(&buf[0], 0, sizeof(buf));
+ result = osmo_sockaddr_to_str_buf(buf, sizeof(buf), &localhost4);
+ printf("Checking osmo_sockaddr_to_str_buf IPv4\n");
+ OSMO_ASSERT(!strncmp("127.0.0.1:42", result, sizeof(buf)));
+
+ memset(&buf[0], 0, sizeof(buf));
+ result = osmo_sockaddr_to_str_buf(buf, 256, &localhost6);
+ printf("Checking osmo_sockaddr_to_str_buf IPv6\n");
+ OSMO_ASSERT(!strncmp("[::1]:42", result, sizeof(buf)));
+
+ memset(&buf[0], 0, sizeof(buf));
+ printf("Checking osmo_sockaddr_to_str_buf too short IPv6\n");
+ result = osmo_sockaddr_to_str_buf(buf, 8, &localhost6);
+ OSMO_ASSERT(result == NULL);
+ osmo_sockaddr_to_str_buf2(buf, 8, &localhost6);
+ OSMO_ASSERT(!strncmp("[::1]:4", buf, sizeof(buf)));
+
+ memset(&buf[0], 0, sizeof(buf));
+ result = osmo_sockaddr_to_str_buf(buf, 5, &localhost6);
+ printf("Checking osmo_sockaddr_to_str_buf too short IPv6\n");
+ OSMO_ASSERT(result == NULL);
+
+ localhost6.u.sin6.sin6_port = 0;
+ memset(&buf[0], 0, sizeof(buf));
+ result = osmo_sockaddr_to_str_buf(buf, 5, &localhost6);
+ printf("Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6\n");
+ OSMO_ASSERT(result == NULL);
+
+ inet_pton(AF_INET6, "::", &localhost6.u.sin6.sin6_addr);
+ memset(&buf[0], 0, sizeof(buf));
+ result = osmo_sockaddr_to_str_buf(buf, 5, &localhost6);
+ printf("Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6\n");
+ OSMO_ASSERT(!strncmp("[::]", result, sizeof(buf)));
+
+ inet_pton(AF_INET6, "2003:1234:5678:90ab:cdef:1234:4321:4321", &localhost6.u.sin6.sin6_addr);
+ memset(&buf[0], 0, sizeof(buf));
+ result = osmo_sockaddr_to_str_buf(buf, sizeof(buf), &localhost6);
+ printf("Checking osmo_sockaddr_to_str_buf long IPv6\n");
+ OSMO_ASSERT(!strncmp("[2003:1234:5678:90ab:cdef:1234:4321:4321]", result, sizeof(buf)));
+
+ localhost6.u.sin6.sin6_port = htons(23420);
+ memset(&buf[0], 0, sizeof(buf));
+ result = osmo_sockaddr_to_str_buf(buf, sizeof(buf), &localhost6);
+ printf("Checking osmo_sockaddr_to_str_buf long IPv6 port\n");
+ OSMO_ASSERT(!strncmp("[2003:1234:5678:90ab:cdef:1234:4321:4321]:23420", result, sizeof(buf)));
+
+ result = osmo_sockaddr_to_str(&localhost6);
+ printf("Checking osmo_sockaddr_to_str_buf long IPv6 port static buffer\n");
+ OSMO_ASSERT(!strncmp("[2003:1234:5678:90ab:cdef:1234:4321:4321]:23420", result, sizeof(buf)));
+}
+
+static void test_osa_netmask_prefixlen(void)
+{
+ struct osmo_sockaddr ipv4;
+ struct osmo_sockaddr ipv6;
+ int rc;
+
+ ipv4.u.sin = (struct sockaddr_in){
+ .sin_family = AF_INET,
+ };
+
+ ipv4.u.sin.sin_addr.s_addr = inet_addr("0.0.0.0");
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv4);
+ OSMO_ASSERT(rc == 0);
+
+ ipv4.u.sin.sin_addr.s_addr = inet_addr("255.0.0.0");
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv4);
+ OSMO_ASSERT(rc == 8);
+
+ ipv4.u.sin.sin_addr.s_addr = inet_addr("255.255.0.0");
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv4);
+ OSMO_ASSERT(rc == 16);
+
+ ipv4.u.sin.sin_addr.s_addr = inet_addr("255.255.255.0");
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv4);
+ OSMO_ASSERT(rc == 24);
+
+ ipv4.u.sin.sin_addr.s_addr = inet_addr("255.255.255.255");
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv4);
+ OSMO_ASSERT(rc == 32);
+
+ ipv4.u.sin.sin_addr.s_addr = inet_addr("0.255.0.0");
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv4);
+ /* FIXME: This shows the implementation is not that robust checking validity of input netmask: */
+ OSMO_ASSERT(rc == 8);
+
+ ipv6.u.sin6 = (struct sockaddr_in6){
+ .sin6_family = AF_INET6,
+ };
+
+ inet_pton(AF_INET6, "fe::", &ipv6.u.sin6.sin6_addr);
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv6);
+ OSMO_ASSERT(rc == 7);
+
+ inet_pton(AF_INET6, "ff::", &ipv6.u.sin6.sin6_addr);
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv6);
+ OSMO_ASSERT(rc == 8);
+
+ inet_pton(AF_INET6, "ff:ff::", &ipv6.u.sin6.sin6_addr);
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv6);
+ OSMO_ASSERT(rc == 16);
+
+ inet_pton(AF_INET6, "ff:ff::ff", &ipv6.u.sin6.sin6_addr);
+ rc = osmo_sockaddr_netmask_to_prefixlen(&ipv6);
+ /* FIXME: This shows the implementation is not that robust checking validity of input netmask: */
+ OSMO_ASSERT(rc == 24);
+}
+
const struct log_info_cat default_categories[] = {
};
@@ -326,12 +455,16 @@ int main(int argc, char *argv[])
ctx = talloc_named_const(NULL, 0, "socket_test");
osmo_init_logging2(ctx, &info);
log_set_use_color(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category(osmo_stderr_target, 0);
+ log_set_print_category_hex(osmo_stderr_target, 0);
test_sockinit();
test_sockinit2();
test_get_ip_and_port();
test_sockinit_osa();
+ test_osa_str();
+ test_osa_netmask_prefixlen();
return EXIT_SUCCESS;
}
diff --git a/tests/socket/socket_test.ok b/tests/socket/socket_test.ok
index 9a52d44e..236c0111 100644
--- a/tests/socket/socket_test.ok
+++ b/tests/socket/socket_test.ok
@@ -21,3 +21,13 @@ Checking osmo_sock_init_osa() for combined BIND + CONNECT on IPv6
Checking osmo_sock_init_osa() must fail on mixed IPv4 & IPv6
Checking osmo_sock_init_osa() must fail on mixed IPv6 & IPv4
Checking osmo_sock_init_osa() must fail on invalid osmo_sockaddr
+Checking osmo_sockaddr_to_str_buf to small IPv4
+Checking osmo_sockaddr_to_str_buf IPv4
+Checking osmo_sockaddr_to_str_buf IPv6
+Checking osmo_sockaddr_to_str_buf too short IPv6
+Checking osmo_sockaddr_to_str_buf too short IPv6
+Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6
+Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6
+Checking osmo_sockaddr_to_str_buf long IPv6
+Checking osmo_sockaddr_to_str_buf long IPv6 port
+Checking osmo_sockaddr_to_str_buf long IPv6 port static buffer
diff --git a/tests/stats/stats_test.c b/tests/stats/stats_test.c
index 71f710a9..2796100d 100644
--- a/tests/stats/stats_test.c
+++ b/tests/stats/stats_test.c
@@ -16,18 +16,17 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
+#include <osmocom/core/application.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/stat_item.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
+#include <stat_item_internal.h>
+
#include <stdio.h>
#include <inttypes.h>
@@ -87,11 +86,10 @@ static void stat_test(void)
struct osmo_stat_item_group *sgrp2;
const struct osmo_stat_item *sitem1, *sitem2;
- int rc;
int32_t value;
- int32_t rd_a = 0;
- int32_t rd_b = 0;
int i;
+ int64_t sum1;
+ int64_t sum2;
OSMO_ASSERT(statg != NULL);
@@ -109,144 +107,151 @@ static void stat_test(void)
sitem1 = osmo_stat_item_get_by_name(statg, "item.a");
OSMO_ASSERT(sitem1 != NULL);
- OSMO_ASSERT(sitem1 == statg->items[TEST_A_ITEM]);
+ OSMO_ASSERT(sitem1 == osmo_stat_item_group_get_item(statg, TEST_A_ITEM));
sitem2 = osmo_stat_item_get_by_name(statg, "item.b");
OSMO_ASSERT(sitem2 != NULL);
OSMO_ASSERT(sitem2 != sitem1);
- OSMO_ASSERT(sitem2 == statg->items[TEST_B_ITEM]);
+ OSMO_ASSERT(sitem2 == osmo_stat_item_group_get_item(statg, TEST_B_ITEM));
- value = osmo_stat_item_get_last(statg->items[TEST_A_ITEM]);
+ /* No value set yet, expecting default value from osmo_stat_item_desc definition above. */
+ value = osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM));
OSMO_ASSERT(value == -1);
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc == 0);
-
- osmo_stat_item_set(statg->items[TEST_A_ITEM], 1);
-
- value = osmo_stat_item_get_last(statg->items[TEST_A_ITEM]);
- OSMO_ASSERT(value == 1);
-
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
+ /* No value set yet, expecting new value in all fields */
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg, TEST_A_ITEM), 1);
+ sum1 = 1;
+ value = osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM));
OSMO_ASSERT(value == 1);
+ OSMO_ASSERT(sitem1->value.n == 1);
+ OSMO_ASSERT(sitem1->value.min == 1);
+ OSMO_ASSERT(sitem1->value.last == 1);
+ OSMO_ASSERT(sitem1->value.max == 1);
+ OSMO_ASSERT(sitem1->value.sum == 1);
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc == 0);
-
+ sum2 = 0;
for (i = 2; i <= 32; i++) {
- osmo_stat_item_set(statg->items[TEST_A_ITEM], i);
- osmo_stat_item_set(statg->items[TEST_B_ITEM], 1000 + i);
-
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == i);
-
- rc = osmo_stat_item_get_next(statg->items[TEST_B_ITEM], &rd_b, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 1000 + i);
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg, TEST_A_ITEM), i);
+ sum1 += i;
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg, TEST_B_ITEM), 1000 + i);
+ sum2 += 1000 + i;
}
+ OSMO_ASSERT(sitem1->value.n == 32);
+ OSMO_ASSERT(sitem1->value.min == 1);
+ OSMO_ASSERT(sitem1->value.last == 32);
+ OSMO_ASSERT(sitem1->value.max == 32);
+ OSMO_ASSERT(sitem1->value.sum == sum1);
+
+ OSMO_ASSERT(sitem2->value.n == 31);
+ OSMO_ASSERT(sitem2->value.min == 1002);
+ OSMO_ASSERT(sitem2->value.last == 1032);
+ OSMO_ASSERT(sitem2->value.max == 1032);
+ OSMO_ASSERT(sitem2->value.sum == sum2);
/* check if dec & inc is working */
- osmo_stat_item_set(statg->items[TEST_A_ITEM], 42);
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 42);
-
- osmo_stat_item_dec(statg->items[TEST_A_ITEM], 21);
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 21);
-
- osmo_stat_item_inc(statg->items[TEST_A_ITEM], 21);
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 42);
-
- /* Keep 2 in FIFO */
- osmo_stat_item_set(statg->items[TEST_A_ITEM], 33);
- osmo_stat_item_set(statg->items[TEST_B_ITEM], 1000 + 33);
-
- for (i = 34; i <= 64; i++) {
- osmo_stat_item_set(statg->items[TEST_A_ITEM], i);
- osmo_stat_item_set(statg->items[TEST_B_ITEM], 1000 + i);
-
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == i-1);
-
- rc = osmo_stat_item_get_next(statg->items[TEST_B_ITEM], &rd_b, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 1000 + i-1);
- }
-
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 64);
-
- rc = osmo_stat_item_get_next(statg->items[TEST_B_ITEM], &rd_b, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 1000 + 64);
-
- /* Overrun FIFOs */
- for (i = 65; i <= 96; i++) {
- osmo_stat_item_set(statg->items[TEST_A_ITEM], i);
- osmo_stat_item_set(statg->items[TEST_B_ITEM], 1000 + i);
- }
-
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 93);
-
- for (i = 94; i <= 96; i++) {
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == i);
- }
-
- rc = osmo_stat_item_get_next(statg->items[TEST_B_ITEM], &rd_b, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 1000 + 90);
-
- for (i = 91; i <= 96; i++) {
- rc = osmo_stat_item_get_next(statg->items[TEST_B_ITEM], &rd_b, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 1000 + i);
- }
-
- /* Test Discard (single item) */
- osmo_stat_item_set(statg->items[TEST_A_ITEM], 97);
- rc = osmo_stat_item_discard(statg->items[TEST_A_ITEM], &rd_a);
- OSMO_ASSERT(rc > 0);
-
- rc = osmo_stat_item_discard(statg->items[TEST_A_ITEM], &rd_a);
- OSMO_ASSERT(rc == 0);
-
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc == 0);
-
- osmo_stat_item_set(statg->items[TEST_A_ITEM], 98);
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc > 0);
- OSMO_ASSERT(value == 98);
-
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc == 0);
-
- /* Test Discard (all items) */
- osmo_stat_item_set(statg->items[TEST_A_ITEM], 99);
- osmo_stat_item_set(statg->items[TEST_A_ITEM], 100);
- osmo_stat_item_set(statg->items[TEST_A_ITEM], 101);
- osmo_stat_item_set(statg->items[TEST_B_ITEM], 99);
- osmo_stat_item_set(statg->items[TEST_B_ITEM], 100);
-
- rc = osmo_stat_item_discard_all(&rd_a);
- rc = osmo_stat_item_discard_all(&rd_b);
-
- rc = osmo_stat_item_get_next(statg->items[TEST_A_ITEM], &rd_a, &value);
- OSMO_ASSERT(rc == 0);
- rc = osmo_stat_item_get_next(statg->items[TEST_B_ITEM], &rd_b, &value);
- OSMO_ASSERT(rc == 0);
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg, TEST_A_ITEM), 42);
+ sum1 += 42;
+ OSMO_ASSERT(sitem1->value.n == 33);
+ OSMO_ASSERT(sitem1->value.min == 1);
+ OSMO_ASSERT(sitem1->value.last == 42);
+ OSMO_ASSERT(osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM)) == 42);
+ OSMO_ASSERT(sitem1->value.max == 42);
+ OSMO_ASSERT(sitem1->value.sum == sum1);
+
+ osmo_stat_item_dec(osmo_stat_item_group_get_item(statg, TEST_A_ITEM), 21);
+ sum1 += 42 - 21;
+ OSMO_ASSERT(sitem1->value.n == 34);
+ OSMO_ASSERT(sitem1->value.min == 1);
+ OSMO_ASSERT(sitem1->value.last == 21);
+ OSMO_ASSERT(osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM)) == 21);
+ OSMO_ASSERT(sitem1->value.max == 42);
+ OSMO_ASSERT(sitem1->value.sum == sum1);
+
+ osmo_stat_item_inc(osmo_stat_item_group_get_item(statg, TEST_A_ITEM), 21);
+ sum1 += 42;
+ OSMO_ASSERT(sitem1->value.n == 35);
+ OSMO_ASSERT(sitem1->value.min == 1);
+ OSMO_ASSERT(sitem1->value.last == 42);
+ OSMO_ASSERT(osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM)) == 42);
+ OSMO_ASSERT(sitem1->value.max == 42);
+ OSMO_ASSERT(sitem1->value.sum == sum1);
+
+ /* Test item flush, reporting period elapsing */
+ osmo_stat_item_flush(osmo_stat_item_group_get_item(statg, TEST_A_ITEM));
+ OSMO_ASSERT(sitem1->value.n == 0);
+ OSMO_ASSERT(sitem1->value.min == 42);
+ OSMO_ASSERT(sitem1->value.last == 42);
+ OSMO_ASSERT(osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM)) == 42);
+ OSMO_ASSERT(sitem1->value.max == 42);
+ OSMO_ASSERT(sitem1->value.sum == 0);
+
+ /* Still see the previous reporting period in reported.* */
+ OSMO_ASSERT(sitem1->reported.n == 35);
+ OSMO_ASSERT(sitem1->reported.min == 1);
+ OSMO_ASSERT(sitem1->reported.last == 42);
+ OSMO_ASSERT(sitem1->reported.max == 42);
+ OSMO_ASSERT(sitem1->reported.sum == sum1);
+
+ /* After a flush, the first item replaces the last, min and max */
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg, TEST_A_ITEM), 97);
+ OSMO_ASSERT(sitem1->value.n == 1);
+ OSMO_ASSERT(sitem1->value.min == 97);
+ OSMO_ASSERT(sitem1->value.last == 97);
+ OSMO_ASSERT(osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM)) == 97);
+ OSMO_ASSERT(sitem1->value.max == 97);
+ OSMO_ASSERT(sitem1->value.sum == 97);
+
+ /* ...and still see the previous reporting period in reported.* */
+ OSMO_ASSERT(sitem1->reported.n == 35);
+ OSMO_ASSERT(sitem1->reported.min == 1);
+ OSMO_ASSERT(sitem1->reported.last == 42);
+ OSMO_ASSERT(sitem1->reported.max == 42);
+ OSMO_ASSERT(sitem1->reported.sum == sum1);
+
+ /* If an entire reporting period elapses without a new value, the last seen value remains. */
+ osmo_stat_item_flush(osmo_stat_item_group_get_item(statg, TEST_A_ITEM));
+ osmo_stat_item_flush(osmo_stat_item_group_get_item(statg, TEST_A_ITEM));
+ OSMO_ASSERT(sitem1->value.n == 0);
+ OSMO_ASSERT(sitem1->value.min == 97);
+ OSMO_ASSERT(sitem1->value.last == 97);
+ OSMO_ASSERT(osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM)) == 97);
+ OSMO_ASSERT(sitem1->value.max == 97);
+ OSMO_ASSERT(sitem1->value.sum == 0);
+
+ /* now the previous reporting period got turned around */
+ OSMO_ASSERT(sitem1->reported.n == 0);
+ OSMO_ASSERT(sitem1->reported.min == 97);
+ OSMO_ASSERT(sitem1->reported.last == 97);
+ OSMO_ASSERT(sitem1->reported.max == 97);
+ OSMO_ASSERT(sitem1->reported.sum == 0);
+
+ /* Another empty reporting period, everything remained the same. */
+ osmo_stat_item_flush(osmo_stat_item_group_get_item(statg, TEST_A_ITEM));
+ OSMO_ASSERT(sitem1->value.n == 0);
+ OSMO_ASSERT(sitem1->value.min == 97);
+ OSMO_ASSERT(sitem1->value.last == 97);
+ OSMO_ASSERT(osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM)) == 97);
+ OSMO_ASSERT(sitem1->value.max == 97);
+ OSMO_ASSERT(sitem1->value.sum == 0);
+ OSMO_ASSERT(sitem1->reported.n == 0);
+ OSMO_ASSERT(sitem1->reported.min == 97);
+ OSMO_ASSERT(sitem1->reported.last == 97);
+ OSMO_ASSERT(sitem1->reported.max == 97);
+ OSMO_ASSERT(sitem1->reported.sum == 0);
+
+ /* Test Reset, place back to default value. The previously reported value remains the same. */
+ osmo_stat_item_reset(osmo_stat_item_group_get_item(statg, TEST_A_ITEM));
+ OSMO_ASSERT(sitem1->value.n == 0);
+ OSMO_ASSERT(sitem1->value.min == -1);
+ OSMO_ASSERT(sitem1->value.last == -1);
+ OSMO_ASSERT(osmo_stat_item_get_last(osmo_stat_item_group_get_item(statg, TEST_A_ITEM)) == -1);
+ OSMO_ASSERT(sitem1->value.max == -1);
+ OSMO_ASSERT(sitem1->value.sum == 0);
+ OSMO_ASSERT(sitem1->reported.n == 0);
+ OSMO_ASSERT(sitem1->reported.min == 97);
+ OSMO_ASSERT(sitem1->reported.last == 97);
+ OSMO_ASSERT(sitem1->reported.max == 97);
+ OSMO_ASSERT(sitem1->reported.sum == 0);
osmo_stat_item_group_free(statg);
@@ -258,7 +263,8 @@ static void stat_test(void)
/* define a special stats reporter for testing */
-static int send_count;
+static int sent_counter_vals;
+static int sent_stat_item_vals;
enum {
OSMO_STATS_REPORTER_TEST = OSMO_STATS_REPORTER_LOG + 1,
@@ -271,13 +277,13 @@ static int stats_reporter_test_send_counter(struct osmo_stats_reporter *srep,
{
const char *group_name = ctrg ? ctrg->desc->group_name_prefix : "";
- printf(" %s: counter p=%s g=%s i=%u n=%s v=%lld d=%lld\n",
+ fprintf(stderr, " %s: counter p=%s g=%s i=%u n=%s v=%lld d=%lld\n",
srep->name,
srep->name_prefix ? srep->name_prefix : "",
group_name, ctrg ? ctrg->idx : 0,
desc->name, (long long)value, (long long)delta);
- send_count += 1;
+ sent_counter_vals++;
return 0;
}
@@ -285,25 +291,25 @@ static int stats_reporter_test_send_item(struct osmo_stats_reporter *srep,
const struct osmo_stat_item_group *statg,
const struct osmo_stat_item_desc *desc, int64_t value)
{
- printf(" %s: item p=%s g=%s i=%u n=%s v=%"PRId64" u=%s\n",
+ fprintf(stderr, " %s: item p=%s g=%s i=%u n=%s v=%"PRId64" u=%s\n",
srep->name,
srep->name_prefix ? srep->name_prefix : "",
statg->desc->group_name_prefix, statg->idx,
desc->name, value, desc->unit ? desc->unit : "");
- send_count += 1;
+ sent_stat_item_vals++;
return 0;
}
static int stats_reporter_test_open(struct osmo_stats_reporter *srep)
{
- printf(" %s: open\n", srep->name);
+ fprintf(stderr, " %s: open\n", srep->name);
return 0;
}
static int stats_reporter_test_close(struct osmo_stats_reporter *srep)
{
- printf(" %s: close\n", srep->name);
+ fprintf(stderr, " %s: close\n", srep->name);
return 0;
}
@@ -322,8 +328,19 @@ static struct osmo_stats_reporter *stats_reporter_create_test(const char *name)
return srep;
}
+static void _do_report(int expect_counter_vals, int expect_stat_item_vals, int line)
+{
+ sent_counter_vals = 0;
+ sent_stat_item_vals = 0;
+ osmo_stats_report();
+ fprintf(stderr, "reported: %d counter vals, %d stat item vals\n", sent_counter_vals, sent_stat_item_vals);
+ OSMO_ASSERT(sent_counter_vals == expect_counter_vals);
+ OSMO_ASSERT(sent_stat_item_vals == expect_stat_item_vals);
+}
+
+#define do_report(A, B) _do_report(A, B, __LINE__)
-static void test_reporting()
+static void test_reporting(void)
{
struct osmo_stats_reporter *srep1, *srep2, *srep;
struct osmo_stat_item_group *statg1, *statg2;
@@ -332,7 +349,7 @@ static void test_reporting()
int rc;
- printf("Start test: %s\n", __func__);
+ fprintf(stderr, "Start test: %s\n", __func__);
/* Allocate counters and items */
statg1 = osmo_stat_item_group_alloc(stats_ctx, &statg_desc, 1);
@@ -374,112 +391,100 @@ static void test_reporting()
rc = osmo_stats_reporter_set_max_class(srep2, OSMO_STATS_CLASS_SUBSCRIBER);
OSMO_ASSERT(rc >= 0);
- printf("report (initial):\n");
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 20);
+ fprintf(stderr, "report (initial):\n");
+ do_report(12, 8);
- printf("report (srep1 global):\n");
+ fprintf(stderr, "report (srep1 global):\n");
/* force single flush */
osmo_stats_reporter_set_max_class(srep1, OSMO_STATS_CLASS_GLOBAL);
srep1->force_single_flush = 1;
srep2->force_single_flush = 1;
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 10);
+ do_report(6, 4);
- printf("report (srep1 peer):\n");
+ fprintf(stderr, "report (srep1 peer):\n");
/* force single flush */
osmo_stats_reporter_set_max_class(srep1, OSMO_STATS_CLASS_PEER);
srep1->force_single_flush = 1;
srep2->force_single_flush = 1;
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 14);
+ do_report(6, 8);
- printf("report (srep1 subscriber):\n");
+ fprintf(stderr, "report (srep1 subscriber):\n");
/* force single flush */
osmo_stats_reporter_set_max_class(srep1, OSMO_STATS_CLASS_SUBSCRIBER);
srep1->force_single_flush = 1;
srep2->force_single_flush = 1;
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 20);
+ do_report(12, 8);
- printf("report (srep2 disabled):\n");
+ fprintf(stderr, "report (srep2 disabled):\n");
/* force single flush */
srep1->force_single_flush = 1;
srep2->force_single_flush = 1;
rc = osmo_stats_reporter_disable(srep2);
OSMO_ASSERT(rc >= 0);
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 10);
+ do_report(6, 4);
- printf("report (srep2 enabled, no flush forced):\n");
+ fprintf(stderr, "report (srep2 enabled, no flush forced):\n");
rc = osmo_stats_reporter_enable(srep2);
OSMO_ASSERT(rc >= 0);
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 10);
+ do_report(6, 4);
- printf("report (should be empty):\n");
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 0);
+ fprintf(stderr, "report (should be empty):\n");
+ do_report(0, 0);
- printf("report (group 1, counter 1 update):\n");
- rate_ctr_inc(&ctrg1->ctr[TEST_A_CTR]);
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 2);
+ fprintf(stderr, "report (group 1, counter 1 update):\n");
+ rate_ctr_inc(rate_ctr_group_get_ctr(ctrg1, TEST_A_CTR));
+ do_report(2, 0);
- printf("report (group 1, item 1 update):\n");
- osmo_stat_item_set(statg1->items[TEST_A_ITEM], 10);
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 2);
+ fprintf(stderr, "report (group 1, item 1 update):\n");
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg1, TEST_A_ITEM), 10);
+ do_report(0, 2);
+
+ fprintf(stderr, "report (group 1, item 1 update twice, with same value):\n");
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg1, TEST_A_ITEM), 10);
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg1, TEST_A_ITEM), 10);
+ do_report(0, 0);
+
+ fprintf(stderr, "report (group 1, item 1 update twice, check max):\n");
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg1, TEST_A_ITEM), 20);
+ osmo_stat_item_set(osmo_stat_item_group_get_item(statg1, TEST_A_ITEM), 10);
+ do_report(0, 2);
+
+ fprintf(stderr, "report (group 1, item 1 no update, send last item (!= last max), OS#5215):\n");
+ do_report(0, 2);
+
+ fprintf(stderr, "report (group 1, item 1 no update, nothing to send):\n");
+ do_report(0, 0);
- printf("report (remove statg1, ctrg1):\n");
+ fprintf(stderr, "report (remove statg1, ctrg1):\n");
/* force single flush */
srep1->force_single_flush = 1;
srep2->force_single_flush = 1;
osmo_stat_item_group_free(statg1);
rate_ctr_group_free(ctrg1);
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 12);
+ do_report(8, 4);
- printf("report (remove srep1):\n");
+ fprintf(stderr, "report (remove srep1):\n");
/* force single flush */
srep1->force_single_flush = 1;
srep2->force_single_flush = 1;
osmo_stats_reporter_free(srep1);
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 6);
+ do_report(4, 2);
- printf("report (remove statg2):\n");
+ fprintf(stderr, "report (remove statg2):\n");
/* force single flush */
srep2->force_single_flush = 1;
osmo_stat_item_group_free(statg2);
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 4);
+ do_report(4, 0);
- printf("report (remove srep2):\n");
+ fprintf(stderr, "report (remove srep2):\n");
/* force single flush */
srep2->force_single_flush = 1;
osmo_stats_reporter_free(srep2);
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 0);
+ do_report(0, 0);
- printf("report (remove ctrg2, should be empty):\n");
+ fprintf(stderr, "report (remove ctrg2, should be empty):\n");
rate_ctr_group_free(ctrg2);
- send_count = 0;
- osmo_stats_report();
- OSMO_ASSERT(send_count == 0);
+ do_report(0, 0);
rate_ctr_group_free(ctrg3);
@@ -487,17 +492,24 @@ static void test_reporting()
OSMO_ASSERT(talloc_total_blocks(stats_ctx) == 1);
talloc_free(stats_ctx);
- printf("End test: %s\n", __func__);
+ fprintf(stderr, "End test: %s\n", __func__);
}
int main(int argc, char **argv)
{
- static const struct log_info log_info = {};
- log_init(&log_info, NULL);
+ void *ctx = talloc_named_const(NULL, 0, "main");
+ osmo_init_logging2(ctx, NULL);
+
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_level(osmo_stderr_target, 1);
+ log_set_print_category(osmo_stderr_target, 1);
+ log_set_print_category_hex(osmo_stderr_target, 0);
+ log_set_use_color(osmo_stderr_target, 0);
osmo_stat_item_init(NULL);
stat_test();
test_reporting();
+ talloc_free(ctx);
return 0;
}
diff --git a/tests/stats/stats_test.err b/tests/stats/stats_test.err
new file mode 100644
index 00000000..4acd35d0
--- /dev/null
+++ b/tests/stats/stats_test.err
@@ -0,0 +1,163 @@
+Start test: test_reporting
+DLGLOBAL ERROR counter group 'ctr-test:one' already exists for index 2, instead using index 3. This is a software bug that needs fixing.
+DLGLOBAL ERROR 'ctr-test.one_dot' is not a valid counter group identifier
+DLGLOBAL NOTICE counter group name mangled: 'ctr-test.one_dot' -> 'ctr-test:one_dot'
+DLGLOBAL NOTICE counter group name mangled: 'ctr.a' -> 'ctr:a'
+DLGLOBAL NOTICE counter group name mangled: 'ctr.b' -> 'ctr:b'
+ test1: open
+ test2: open
+report (initial):
+ test1: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test1: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test1: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
+ test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test1: item p= g=test.one i=1 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
+ test1: item p= g=test.one i=1 n=item.b v=-1 u=kb
+ test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
+reported: 12 counter vals, 8 stat item vals
+report (srep1 global):
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
+ test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
+reported: 6 counter vals, 4 stat item vals
+report (srep1 peer):
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
+ test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test1: item p= g=test.one i=1 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
+ test1: item p= g=test.one i=1 n=item.b v=-1 u=kb
+ test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
+reported: 6 counter vals, 8 stat item vals
+report (srep1 subscriber):
+ test1: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test1: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test1: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
+ test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test1: item p= g=test.one i=1 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
+ test1: item p= g=test.one i=1 n=item.b v=-1 u=kb
+ test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
+reported: 12 counter vals, 8 stat item vals
+report (srep2 disabled):
+ test2: close
+ test1: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test1: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test1: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
+ test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test1: item p= g=test.one i=1 n=item.a v=-1 u=ma
+ test1: item p= g=test.one i=1 n=item.b v=-1 u=kb
+reported: 6 counter vals, 4 stat item vals
+report (srep2 enabled, no flush forced):
+ test2: open
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
+ test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
+reported: 6 counter vals, 4 stat item vals
+report (should be empty):
+reported: 0 counter vals, 0 stat item vals
+report (group 1, counter 1 update):
+ test1: counter p= g=ctr-test:one i=1 n=ctr:a v=1 d=1
+ test2: counter p= g=ctr-test:one i=1 n=ctr:a v=1 d=1
+reported: 2 counter vals, 0 stat item vals
+report (group 1, item 1 update):
+ test1: item p= g=test.one i=1 n=item.a v=10 u=ma
+ test2: item p= g=test.one i=1 n=item.a v=10 u=ma
+reported: 0 counter vals, 2 stat item vals
+report (group 1, item 1 update twice, with same value):
+reported: 0 counter vals, 0 stat item vals
+report (group 1, item 1 update twice, check max):
+ test1: item p= g=test.one i=1 n=item.a v=20 u=ma
+ test2: item p= g=test.one i=1 n=item.a v=20 u=ma
+reported: 0 counter vals, 2 stat item vals
+report (group 1, item 1 no update, send last item (!= last max), OS#5215):
+ test1: item p= g=test.one i=1 n=item.a v=10 u=ma
+ test2: item p= g=test.one i=1 n=item.a v=10 u=ma
+reported: 0 counter vals, 2 stat item vals
+report (group 1, item 1 no update, nothing to send):
+reported: 0 counter vals, 0 stat item vals
+report (remove statg1, ctrg1):
+ test1: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test1: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test1: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
+ test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
+reported: 8 counter vals, 4 stat item vals
+report (remove srep1):
+ test1: close
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+ test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
+ test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
+reported: 4 counter vals, 2 stat item vals
+report (remove statg2):
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
+ test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
+reported: 4 counter vals, 0 stat item vals
+report (remove srep2):
+ test2: close
+reported: 0 counter vals, 0 stat item vals
+report (remove ctrg2, should be empty):
+reported: 0 counter vals, 0 stat item vals
+End test: test_reporting
diff --git a/tests/stats/stats_test.ok b/tests/stats/stats_test.ok
index 8628adb7..e69de29b 100644
--- a/tests/stats/stats_test.ok
+++ b/tests/stats/stats_test.ok
@@ -1,132 +0,0 @@
-Start test: test_reporting
- test1: open
- test2: open
-report (initial):
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
- test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
- test1: item p= g=test.one i=1 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
- test1: item p= g=test.one i=1 n=item.b v=-1 u=kb
-report (srep1 global):
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
- test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
-report (srep1 peer):
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
- test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
- test1: item p= g=test.one i=1 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
- test1: item p= g=test.one i=1 n=item.b v=-1 u=kb
-report (srep1 subscriber):
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
- test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
- test1: item p= g=test.one i=1 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
- test1: item p= g=test.one i=1 n=item.b v=-1 u=kb
-report (srep2 disabled):
- test2: close
- test1: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
- test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test1: item p= g=test.one i=1 n=item.a v=-1 u=ma
- test1: item p= g=test.one i=1 n=item.b v=-1 u=kb
-report (srep2 enabled, no flush forced):
- test2: open
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=1 n=ctr:b v=0 d=0
- test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test2: item p= g=test.one i=1 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=1 n=item.b v=-1 u=kb
-report (should be empty):
-report (group 1, counter 1 update):
- test2: counter p= g=ctr-test:one i=1 n=ctr:a v=1 d=1
- test1: counter p= g=ctr-test:one i=1 n=ctr:a v=1 d=1
-report (group 1, item 1 update):
- test2: item p= g=test.one i=1 n=item.a v=10 u=ma
- test1: item p= g=test.one i=1 n=item.a v=10 u=ma
-report (remove statg1, ctrg1):
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test1: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test1: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test1: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
- test1: item p= g=test.one i=2 n=item.b v=-1 u=kb
-report (remove srep1):
- test1: close
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
- test2: item p= g=test.one i=2 n=item.a v=-1 u=ma
- test2: item p= g=test.one i=2 n=item.b v=-1 u=kb
-report (remove statg2):
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one_dot i=3 n=ctr:b v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:a v=0 d=0
- test2: counter p= g=ctr-test:one i=2 n=ctr:b v=0 d=0
-report (remove srep2):
- test2: close
-report (remove ctrg2, should be empty):
-End test: test_reporting
diff --git a/tests/stats/stats_vty_test.c b/tests/stats/stats_vty_test.c
new file mode 100644
index 00000000..29cbf5ec
--- /dev/null
+++ b/tests/stats/stats_vty_test.c
@@ -0,0 +1,88 @@
+/*
+ * (C) 2021 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <signal.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/select.h>
+#include <osmocom/core/utils.h>
+
+#include <osmocom/vty/telnet_interface.h>
+#include <osmocom/vty/stats.h>
+#include <osmocom/vty/vty.h>
+
+static void *root_ctx = NULL;
+static int quit = 0;
+
+static void signal_handler(int signal)
+{
+ fprintf(stdout, "signal %u received\n", signal);
+
+ switch (signal) {
+ case SIGINT:
+ case SIGTERM:
+ quit++;
+ break;
+ }
+}
+
+static struct vty_app_info vty_info = {
+ .name = "stats_vty_test",
+};
+
+static const struct log_info_cat default_categories[] = { };
+
+const struct log_info log_info = {
+ .cat = default_categories,
+ .num_cat = ARRAY_SIZE(default_categories),
+};
+
+int main(int argc, char **argv)
+{
+ int rc;
+
+ root_ctx = talloc_named_const(NULL, 0, "stats_vty_test");
+
+ osmo_init_logging2(root_ctx, &log_info);
+
+ vty_info.tall_ctx = root_ctx;
+ vty_init(&vty_info);
+
+ osmo_stats_vty_add_cmds();
+
+ rc = telnet_init_default(root_ctx, NULL, 42042);
+ if (rc < 0)
+ return 2;
+
+ signal(SIGINT, &signal_handler);
+ signal(SIGTERM, &signal_handler);
+ osmo_init_ignore_signals();
+
+ while (!quit)
+ osmo_select_main(0);
+
+ talloc_free(tall_vty_ctx);
+ talloc_free(root_ctx);
+
+ return 0;
+}
diff --git a/tests/stats/stats_vty_test.vty b/tests/stats/stats_vty_test.vty
new file mode 100644
index 00000000..8732d50b
--- /dev/null
+++ b/tests/stats/stats_vty_test.vty
@@ -0,0 +1,217 @@
+stats_vty_test> en
+stats_vty_test# configure terminal
+stats_vty_test(config)# list
+...
+ stats reporter statsd [NAME]
+ no stats reporter statsd [NAME]
+ stats reporter log [NAME]
+ no stats reporter log [NAME]
+ stats interval <0-65535>
+ stats-tcp interval <0-65535>
+...
+
+stats_vty_test(config)# ### No reporters shall be configured by default
+stats_vty_test(config)# show running-config
+... !stats reporter
+
+
+stats_vty_test(config)# ### Create a statsd reporter
+stats_vty_test(config)# stats reporter statsd
+stats_vty_test(config-stats)# list
+...
+ local-ip ADDR
+ no local-ip
+ remote-ip ADDR
+ remote-port <1-65535>
+ mtu <100-65535>
+ no mtu
+ prefix PREFIX
+ no prefix
+ level (global|peer|subscriber)
+ enable
+ disable
+ flush-period <0-65535>
+...
+
+stats_vty_test(config-stats)# show running-config
+...
+stats interval 5
+stats reporter statsd
+ level global
+ no prefix
+ disable
+...
+
+stats_vty_test(config-stats)# level subscriber
+stats_vty_test(config-stats)# prefix statsd-prefix
+stats_vty_test(config-stats)# show running-config
+...
+stats reporter statsd
+ level subscriber
+ prefix statsd-prefix
+...
+
+stats_vty_test(config-stats)# remote-ip 192.168.1.200
+stats_vty_test(config-stats)# remote-port 6969
+stats_vty_test(config-stats)# show running-config
+...
+stats reporter statsd
+ remote-ip 192.168.1.200
+ remote-port 6969
+... !local-ip
+
+stats_vty_test(config-stats)# local-ip 192.168.1.100
+stats_vty_test(config-stats)# show running-config
+...
+stats reporter statsd
+ remote-ip 192.168.1.200
+ remote-port 6969
+ local-ip 192.168.1.100
+...
+
+stats_vty_test(config-stats)# no local-ip
+stats_vty_test(config-stats)# show running-config
+...
+stats reporter statsd
+... !local-ip
+
+stats_vty_test(config-stats)# mtu 1337
+stats_vty_test(config-stats)# show running-config
+...
+stats reporter statsd
+ remote-ip 192.168.1.200
+ remote-port 6969
+ mtu 1337
+...
+
+stats_vty_test(config-stats)# no mtu
+stats_vty_test(config-stats)# show running-config
+...
+stats reporter statsd
+... !mtu
+
+stats_vty_test(config-stats)# flush-period 43556
+stats_vty_test(config-stats)# show running-config
+...
+stats reporter statsd
+ remote-ip 192.168.1.200
+ remote-port 6969
+ level subscriber
+ prefix statsd-prefix
+ flush-period 43556
+...
+
+stats_vty_test(config-stats)# flush-period 0
+stats_vty_test(config-stats)# show running-config
+...
+stats reporter statsd
+... !flush-period
+
+stats_vty_test(config-stats)# enable
+stats_vty_test(config-stats)# exit
+stats_vty_test(config)# show running-config
+...
+stats reporter statsd
+ remote-ip 192.168.1.200
+ remote-port 6969
+ level subscriber
+ prefix statsd-prefix
+ enable
+...
+
+
+stats_vty_test(config)# ### Create a statsd reporter
+stats_vty_test(config)# stats reporter log
+stats_vty_test(config-stats)# level peer
+stats_vty_test(config-stats)# prefix log-prefix
+stats_vty_test(config-stats)# enable
+stats_vty_test(config-stats)# exit
+stats_vty_test(config)# show running-config
+...
+stats reporter statsd
+ remote-ip 192.168.1.200
+ remote-port 6969
+ level subscriber
+ prefix statsd-prefix
+ enable
+stats reporter log
+ level peer
+ prefix log-prefix
+ enable
+...
+
+
+stats_vty_test(config)# ### Create an additional statsd reporter
+stats_vty_test(config)# stats reporter statsd statsd-foo
+stats_vty_test(config-stats)# level global
+stats_vty_test(config-stats)# prefix statsd-one-prefix
+stats_vty_test(config-stats)# remote-ip 192.168.2.200
+stats_vty_test(config-stats)# remote-port 9696
+stats_vty_test(config-stats)# flush-period 1
+stats_vty_test(config-stats)# exit
+
+stats_vty_test(config)# ### Create an additional log reporter
+stats_vty_test(config)# stats reporter log log-bar
+stats_vty_test(config-stats)# level global
+stats_vty_test(config-stats)# prefix log-bar-prefix
+stats_vty_test(config-stats)# flush-period 2
+stats_vty_test(config-stats)# exit
+
+stats_vty_test(config)# ### Create an additional log reporter
+stats_vty_test(config)# stats reporter log log-zoo
+stats_vty_test(config-stats)# level global
+stats_vty_test(config-stats)# prefix log-zoo-prefix
+stats_vty_test(config-stats)# flush-period 3
+stats_vty_test(config-stats)# exit
+
+stats_vty_test(config)# ### We should have 5 reporters now
+stats_vty_test(config)# show running-config
+...
+stats reporter statsd
+ remote-ip 192.168.1.200
+ remote-port 6969
+ level subscriber
+ prefix statsd-prefix
+ enable
+stats reporter log
+ level peer
+ prefix log-prefix
+ enable
+stats reporter statsd statsd-foo
+ remote-ip 192.168.2.200
+ remote-port 9696
+ level global
+ prefix statsd-one-prefix
+ flush-period 1
+ disable
+stats reporter log log-bar
+ level global
+ prefix log-bar-prefix
+ flush-period 2
+ disable
+stats reporter log log-zoo
+ level global
+ prefix log-zoo-prefix
+ flush-period 3
+ disable
+...
+
+
+stats_vty_test(config)# ### Test removing reporters
+stats_vty_test(config)# no stats reporter statsd statsd-foo
+stats_vty_test(config)# no stats reporter log log-bar
+stats_vty_test(config)# no stats reporter log log-zoo
+stats_vty_test(config)# show running-config
+... !(foo|bar|zoo)
+
+stats_vty_test(config)# no stats reporter statsd statsd-foo
+% There is no such statsd reporter with name 'statsd-foo'
+stats_vty_test(config)# no stats reporter log log-zoo
+% There is no such log reporter with name 'log-zoo'
+
+
+stats_vty_test(config)# stats interval 1337
+stats_vty_test(config)# show running-config
+...
+stats interval 1337
+...
diff --git a/tests/strrb/strrb_test.c b/tests/strrb/strrb_test.c
index 4282d1aa..cdeaa346 100644
--- a/tests/strrb/strrb_test.c
+++ b/tests/strrb/strrb_test.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
diff --git a/tests/tdef/tdef_test.c b/tests/tdef/tdef_test.c
index 9c0808ea..a0fcc9a9 100644
--- a/tests/tdef/tdef_test.c
+++ b/tests/tdef/tdef_test.c
@@ -17,10 +17,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
@@ -38,7 +34,7 @@ static void *ctx = NULL;
static struct osmo_tdef tdefs[] = {
{ .T=1, .default_val=100, .desc="100s" },
{ .T=2, .default_val=100, .unit=OSMO_TDEF_MS, .desc="100ms" },
- { .T=3, .default_val=100, .unit=OSMO_TDEF_M, .desc="100m" },
+ { .T=3, .default_val=50, .unit=OSMO_TDEF_M, .desc="50m" },
{ .T=4, .default_val=100, .unit=OSMO_TDEF_CUSTOM, .desc="100 potatoes" },
{ .T=7, .default_val=50, .desc="Water Boiling Timeout", .min_val=20, .max_val=800 }, // default is .unit=OSMO_TDEF_S == 0
@@ -54,6 +50,7 @@ static struct osmo_tdef tdefs[] = {
{ .T=1006, .default_val=0, .unit=OSMO_TDEF_S, .desc="zero s" },
{ .T=1007, .default_val=0, .unit=OSMO_TDEF_M, .desc="zero m" },
{ .T=1008, .default_val=0, .unit=OSMO_TDEF_CUSTOM, .desc="zero" },
+ { .T=1009, .default_val=0, .unit=OSMO_TDEF_US, .desc="zero us" },
{ .T=0, .default_val=1, .unit=OSMO_TDEF_CUSTOM, .desc="zero" },
@@ -111,7 +108,7 @@ static void test_tdef_get(bool test_range)
for (i = 0; i < ARRAY_SIZE(tdefs)-1; i++) {
unsigned int T = tdefs[i].T;
print_tdef_info(T);
- for (as_unit = OSMO_TDEF_S; as_unit <= OSMO_TDEF_CUSTOM; as_unit++) {
+ for (as_unit = OSMO_TDEF_S; as_unit <= OSMO_TDEF_US; as_unit++) {
print_tdef_get_short(tdefs, T, as_unit);
}
}
@@ -122,13 +119,13 @@ static void test_tdef_get(bool test_range)
for (i = 0; i < ARRAY_SIZE(tdefs_range)-1; i++) {
unsigned int T = tdefs_range[i].T;
print_tdef_info(T);
- for (as_unit = OSMO_TDEF_S; as_unit <= OSMO_TDEF_CUSTOM; as_unit++) {
+ for (as_unit = OSMO_TDEF_S; as_unit <= OSMO_TDEF_US; as_unit++) {
print_tdef_get_short(tdefs_range, T, as_unit);
}
}
}
-static void test_tdef_get_nonexisting()
+static void test_tdef_get_nonexisting(void)
{
printf("\n%s()\n", __func__);
@@ -136,15 +133,17 @@ static void test_tdef_get_nonexisting()
print_tdef_get(tdefs, 5, OSMO_TDEF_MS);
print_tdef_get(tdefs, 5, OSMO_TDEF_M);
print_tdef_get(tdefs, 5, OSMO_TDEF_CUSTOM);
+ print_tdef_get(tdefs, 5, OSMO_TDEF_US);
}
-static void test_tdef_set_and_get()
+static void test_tdef_set_and_get(void)
{
struct osmo_tdef *t;
printf("\n%s()\n", __func__);
printf("setting 7 = 42\n");
t = osmo_tdef_get_entry(tdefs, 7);
+ OSMO_ASSERT(t != NULL);
OSMO_ASSERT(osmo_tdef_val_in_range(t, 42));
t->val = 42;
print_tdef_info(7);
@@ -152,6 +151,7 @@ static void test_tdef_set_and_get()
print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
+ print_tdef_get_short(tdefs, 7, OSMO_TDEF_US);
printf("setting 7 = 420\n");
OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 420, OSMO_TDEF_S) == 0);
@@ -160,6 +160,7 @@ static void test_tdef_set_and_get()
print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
+ print_tdef_get_short(tdefs, 7, OSMO_TDEF_US);
printf("setting 7 = 10 (ERANGE)\n");
OSMO_ASSERT(!osmo_tdef_val_in_range(t, 10));
@@ -169,6 +170,7 @@ static void test_tdef_set_and_get()
print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
+ print_tdef_get_short(tdefs, 7, OSMO_TDEF_US);
printf("setting 7 = 900 (ERANGE)\n");
OSMO_ASSERT(!osmo_tdef_val_in_range(t, 900));
@@ -178,6 +180,7 @@ static void test_tdef_set_and_get()
print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
+ print_tdef_get_short(tdefs, 7, OSMO_TDEF_US);
printf("setting 23 = 50 (EEXIST)\n");
OSMO_ASSERT(osmo_tdef_set(tdefs, 23, 50, OSMO_TDEF_S) == -EEXIST);
@@ -314,7 +317,7 @@ const struct timeval fake_time_start_time = { 123, 456 };
osmo_timers_update(); \
} while (0)
-void fake_time_start()
+void fake_time_start(void)
{
struct timespec *clock_override;
@@ -471,7 +474,7 @@ int main(int argc, char **argv)
ctx = talloc_named_const(NULL, 0, "tdef_test.c");
osmo_init_logging2(ctx, NULL);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
log_set_print_category(osmo_stderr_target, 1);
log_set_use_color(osmo_stderr_target, 0);
diff --git a/tests/tdef/tdef_test.ok b/tests/tdef/tdef_test.ok
index 3c4a0930..4c97dabb 100644
--- a/tests/tdef/tdef_test.ok
+++ b/tests/tdef/tdef_test.ok
@@ -5,92 +5,116 @@ osmo_tdef_get(1, s) = 100
osmo_tdef_get(1, ms) = 100000
osmo_tdef_get(1, m) = 2
osmo_tdef_get(1, custom-unit) = 100
+osmo_tdef_get(1, us) = 100000000
T2=100ms
osmo_tdef_get(2, s) = 1
osmo_tdef_get(2, ms) = 100
osmo_tdef_get(2, m) = 1
osmo_tdef_get(2, custom-unit) = 100
-T3=100m
-osmo_tdef_get(3, s) = 6000
-osmo_tdef_get(3, ms) = 6000000
-osmo_tdef_get(3, m) = 100
-osmo_tdef_get(3, custom-unit) = 100
+osmo_tdef_get(2, us) = 100000
+T3=50m
+osmo_tdef_get(3, s) = 3000
+osmo_tdef_get(3, ms) = 3000000
+osmo_tdef_get(3, m) = 50
+osmo_tdef_get(3, custom-unit) = 50
+osmo_tdef_get(3, us) = 3000000000
T4=100custom-unit
osmo_tdef_get(4, s) = 100
osmo_tdef_get(4, ms) = 100
osmo_tdef_get(4, m) = 100
osmo_tdef_get(4, custom-unit) = 100
+osmo_tdef_get(4, us) = 100
T7=50s
osmo_tdef_get(7, s) = 50
osmo_tdef_get(7, ms) = 50000
osmo_tdef_get(7, m) = 1
osmo_tdef_get(7, custom-unit) = 50
+osmo_tdef_get(7, us) = 50000000
T8=300s
osmo_tdef_get(8, s) = 300
osmo_tdef_get(8, ms) = 300000
osmo_tdef_get(8, m) = 5
osmo_tdef_get(8, custom-unit) = 300
+osmo_tdef_get(8, us) = 300000000
T9=5m
osmo_tdef_get(9, s) = 300
osmo_tdef_get(9, ms) = 300000
osmo_tdef_get(9, m) = 5
osmo_tdef_get(9, custom-unit) = 5
+osmo_tdef_get(9, us) = 300000000
T10=20m
osmo_tdef_get(10, s) = 1200
osmo_tdef_get(10, ms) = 1200000
osmo_tdef_get(10, m) = 20
osmo_tdef_get(10, custom-unit) = 20
+osmo_tdef_get(10, us) = 1200000000
T1000=2000ms
osmo_tdef_get(1000, s) = 2
osmo_tdef_get(1000, ms) = 2000
osmo_tdef_get(1000, m) = 1
osmo_tdef_get(1000, custom-unit) = 2000
+osmo_tdef_get(1000, us) = 2000000
T1001=60000ms
osmo_tdef_get(1001, s) = 60
osmo_tdef_get(1001, ms) = 60000
osmo_tdef_get(1001, m) = 1
osmo_tdef_get(1001, custom-unit) = 60000
+osmo_tdef_get(1001, us) = 60000000
T1004=1ms
osmo_tdef_get(1004, s) = 1
osmo_tdef_get(1004, ms) = 1
osmo_tdef_get(1004, m) = 1
osmo_tdef_get(1004, custom-unit) = 1
+osmo_tdef_get(1004, us) = 1000
T1005=0ms
osmo_tdef_get(1005, s) = 0
osmo_tdef_get(1005, ms) = 0
osmo_tdef_get(1005, m) = 0
osmo_tdef_get(1005, custom-unit) = 0
+osmo_tdef_get(1005, us) = 0
T1006=0s
osmo_tdef_get(1006, s) = 0
osmo_tdef_get(1006, ms) = 0
osmo_tdef_get(1006, m) = 0
osmo_tdef_get(1006, custom-unit) = 0
+osmo_tdef_get(1006, us) = 0
T1007=0m
osmo_tdef_get(1007, s) = 0
osmo_tdef_get(1007, ms) = 0
osmo_tdef_get(1007, m) = 0
osmo_tdef_get(1007, custom-unit) = 0
+osmo_tdef_get(1007, us) = 0
T1008=0custom-unit
osmo_tdef_get(1008, s) = 0
osmo_tdef_get(1008, ms) = 0
osmo_tdef_get(1008, m) = 0
osmo_tdef_get(1008, custom-unit) = 0
+osmo_tdef_get(1008, us) = 0
+T1009=0us
+osmo_tdef_get(1009, s) = 0
+osmo_tdef_get(1009, ms) = 0
+osmo_tdef_get(1009, m) = 0
+osmo_tdef_get(1009, custom-unit) = 0
+osmo_tdef_get(1009, us) = 0
T0=1custom-unit
osmo_tdef_get(0, s) = 1
osmo_tdef_get(0, ms) = 1
osmo_tdef_get(0, m) = 1
osmo_tdef_get(0, custom-unit) = 1
+osmo_tdef_get(0, us) = 1
T123=1s
osmo_tdef_get(123, s) = 1
osmo_tdef_get(123, ms) = 1000
osmo_tdef_get(123, m) = 1
osmo_tdef_get(123, custom-unit) = 1
+osmo_tdef_get(123, us) = 1000000
test_tdef_get_nonexisting()
osmo_tdef_get(tdefs, 5, s, 999) = 999
osmo_tdef_get(tdefs, 5, ms, 999) = 999
osmo_tdef_get(tdefs, 5, m, 999) = 999
osmo_tdef_get(tdefs, 5, custom-unit, 999) = 999
+osmo_tdef_get(tdefs, 5, us, 999) = 999
test_tdef_set_and_get()
setting 7 = 42
@@ -99,24 +123,28 @@ osmo_tdef_get(7, ms) = 42000
osmo_tdef_get(7, s) = 42
osmo_tdef_get(7, m) = 1
osmo_tdef_get(7, custom-unit) = 42
+osmo_tdef_get(7, us) = 42000000
setting 7 = 420
T7=420s(def=50)
osmo_tdef_get(7, ms) = 420000
osmo_tdef_get(7, s) = 420
osmo_tdef_get(7, m) = 7
osmo_tdef_get(7, custom-unit) = 420
+osmo_tdef_get(7, us) = 420000000
setting 7 = 10 (ERANGE)
T7=420s(def=50)
osmo_tdef_get(7, ms) = 420000
osmo_tdef_get(7, s) = 420
osmo_tdef_get(7, m) = 7
osmo_tdef_get(7, custom-unit) = 420
+osmo_tdef_get(7, us) = 420000000
setting 7 = 900 (ERANGE)
T7=420s(def=50)
osmo_tdef_get(7, ms) = 420000
osmo_tdef_get(7, s) = 420
osmo_tdef_get(7, m) = 7
osmo_tdef_get(7, custom-unit) = 420
+osmo_tdef_get(7, us) = 420000000
setting 23 = 50 (EEXIST)
resetting
T7=50s
@@ -126,7 +154,7 @@ test_tdef_state_timeout()
state=A T=0, no timeout
--> A (configured as T1 100 s) rc=0; state=A T=1, 100.000000 s remaining
--> B (configured as T2 100 ms) rc=0; state=B T=2, 1.000000 s remaining
- --> C (configured as T3 100 m) rc=0; state=C T=3, 6000.000000 s remaining
+ --> C (configured as T3 50 m) rc=0; state=C T=3, 3000.000000 s remaining
--> D (configured as T4 100 custom-unit) rc=0; state=D T=4, 100.000000 s remaining
--> G (configured as T7 50 s) rc=0; state=G T=7, 50.000000 s remaining
--> H (configured as T8 300 s) rc=0; state=H T=8, 300.000000 s remaining
@@ -155,5 +183,5 @@ state=A T=1, 76.954322 s remaining
- test disallowed transition:
--> Z (no timer configured for this state) rc=0; state=Z T=0, no timeout
--> B (configured as T2 100 ms) rc=-1; state=Z T=0, no timeout
- --> C (configured as T3 100 m) rc=-1; state=Z T=0, no timeout
+ --> C (configured as T3 50 m) rc=-1; state=Z T=0, no timeout
--> D (configured as T4 100 custom-unit) rc=-1; state=Z T=0, no timeout
diff --git a/tests/tdef/tdef_vty_test_config_root.c b/tests/tdef/tdef_vty_config_root_test.c
index 92113e87..8c46d958 100644
--- a/tests/tdef/tdef_vty_test_config_root.c
+++ b/tests/tdef/tdef_vty_config_root_test.c
@@ -17,10 +17,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
@@ -45,7 +41,7 @@
/* ------------------- HERE IS THE INTERESTING TDEF RELEVANT PART ------------------- */
/* This example keeps several separate timer groups and offers 'timer' VTY commands at the root of the config node. See
- * the tdef_vty_test_config_root.vty transcript test.
+ * the tdef_vty_config_root_test.vty transcript test.
*/
static struct osmo_tdef tdefs_test[] = {
@@ -102,7 +98,7 @@ enum tdef_vty_test_nodes {
/* This example puts 'timer' configuration commands directly at the root of the CONFIG_NODE.
* This TIMER_NODE is merely needed as a hook for the vty_write() command, but becomes an empty node in the VTY docs.
* It is possible to cheat around needing this if you choose to config_write_timer() in another root nodes' write cb.
- * Another example using a 'network' subnode is \ref tdef_vty_test_config_subnode.c */
+ * Another example using a 'network' subnode is \ref tdef_vty_config_subnode_test.c */
static struct cmd_node timer_node = {
TIMER_NODE,
"%s(config-timer)# ",
@@ -115,7 +111,7 @@ static int config_write_timer(struct vty *vty)
return CMD_SUCCESS;
}
-static void timer_init_vty()
+static void timer_init_vty(void)
{
/* Again, this is merely to get a vty write hook, see above. */
install_node(&timer_node, config_write_timer);
@@ -127,7 +123,7 @@ static void timer_init_vty()
void *root_ctx = NULL;
-static void print_help()
+static void print_help(void)
{
printf( "options:\n"
" -h --help this text\n"
@@ -264,7 +260,7 @@ int main(int argc, char **argv)
}
}
- rc = telnet_init_dynif(root_ctx, NULL, vty_get_bind_addr(), 42042);
+ rc = telnet_init_default(root_ctx, NULL, 42042);
if (rc < 0)
return 2;
diff --git a/tests/tdef/tdef_vty_test_config_root.vty b/tests/tdef/tdef_vty_config_root_test.vty
index 6a53b805..6a53b805 100644
--- a/tests/tdef/tdef_vty_test_config_root.vty
+++ b/tests/tdef/tdef_vty_config_root_test.vty
diff --git a/tests/tdef/tdef_vty_test_config_subnode.c b/tests/tdef/tdef_vty_config_subnode_test.c
index ce851f50..e3e165da 100644
--- a/tests/tdef/tdef_vty_test_config_subnode.c
+++ b/tests/tdef/tdef_vty_config_subnode_test.c
@@ -17,10 +17,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
@@ -46,7 +42,7 @@
/* This example keeps a single global timer group and offers a custom 'timer' VTY command in a 'network' subnode below
* the CONFIG_NODE.
- * the tdef_vty_test_config_subnode.vty transcript test.
+ * the tdef_vty_config_subnode_test.vty transcript test.
*/
static struct osmo_tdef global_tdefs[] = {
@@ -106,7 +102,7 @@ static int config_write_gsmnet(struct vty *vty)
return CMD_SUCCESS;
}
-static void gsmnet_init_vty()
+static void gsmnet_init_vty(void)
{
install_node(&gsmnet_node, config_write_gsmnet);
install_element(CONFIG_NODE, &cfg_net_cmd);
@@ -120,7 +116,7 @@ static void gsmnet_init_vty()
void *root_ctx = NULL;
-static void print_help()
+static void print_help(void)
{
printf( "options:\n"
" -h --help this text\n"
@@ -257,7 +253,7 @@ int main(int argc, char **argv)
}
}
- rc = telnet_init_dynif(root_ctx, NULL, vty_get_bind_addr(), 42042);
+ rc = telnet_init_default(root_ctx, NULL, 42042);
if (rc < 0)
return 2;
diff --git a/tests/tdef/tdef_vty_test_config_subnode.vty b/tests/tdef/tdef_vty_config_subnode_test.vty
index 2605f71d..2605f71d 100644
--- a/tests/tdef/tdef_vty_test_config_subnode.vty
+++ b/tests/tdef/tdef_vty_config_subnode_test.vty
diff --git a/tests/tdef/tdef_vty_test_dynamic.c b/tests/tdef/tdef_vty_dynamic_test.c
index 20dae535..b646c54e 100644
--- a/tests/tdef/tdef_vty_test_dynamic.c
+++ b/tests/tdef/tdef_vty_dynamic_test.c
@@ -17,10 +17,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
@@ -183,7 +179,7 @@ static int config_write_member(struct vty *vty)
return CMD_SUCCESS;
}
-static void member_init_vty()
+static void member_init_vty(void)
{
install_node(&member_node, config_write_member);
install_element(CONFIG_NODE, &cfg_member_cmd);
@@ -194,7 +190,7 @@ static void member_init_vty()
/* ------------------- THE REST is just boilerplate osmo main() ------------------- */
-static void print_help()
+static void print_help(void)
{
printf( "options:\n"
" -h --help this text\n"
@@ -331,7 +327,7 @@ int main(int argc, char **argv)
}
}
- rc = telnet_init_dynif(root_ctx, NULL, vty_get_bind_addr(), 42042);
+ rc = telnet_init_default(root_ctx, NULL, 42042);
if (rc < 0)
return 2;
diff --git a/tests/tdef/tdef_vty_test_dynamic.vty b/tests/tdef/tdef_vty_dynamic_test.vty
index 6aae746b..6aae746b 100644
--- a/tests/tdef/tdef_vty_test_dynamic.vty
+++ b/tests/tdef/tdef_vty_dynamic_test.vty
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 493c16f4..60aa74d3 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -36,7 +36,7 @@ AT_CLEANUP
AT_SETUP([bitvec])
AT_KEYWORDS([bitvec])
cat $abs_srcdir/bitvec/bitvec_test.ok > expout
-AT_CHECK([$abs_top_builddir/tests/bitvec/bitvec_test], [0], [expout], [ignore])
+AT_CHECK([$abs_top_builddir/tests/bitvec/bitvec_test], [0], [expout])
AT_CLEANUP
AT_SETUP([bitcomp])
@@ -102,6 +102,18 @@ cat $abs_srcdir/smscb/smscb_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/smscb/smscb_test], [0], [expout])
AT_CLEANUP
+AT_SETUP([smscb_gsm0341])
+AT_KEYWORDS([smscb_gsm0341])
+cat $abs_srcdir/smscb/gsm0341_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/smscb/gsm0341_test], [0], [expout])
+AT_CLEANUP
+
+AT_SETUP([smscb_cbsp])
+AT_KEYWORDS([smscb_cbsp])
+cat $abs_srcdir/smscb/cbsp_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/smscb/cbsp_test], [0], [expout])
+AT_CLEANUP
+
AT_SETUP([ussd])
AT_KEYWORDS([ussd])
cat $abs_srcdir/ussd/ussd_test.ok > expout
@@ -114,6 +126,12 @@ cat $abs_srcdir/auth/milenage_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/auth/milenage_test], [0], [expout], [ignore])
AT_CLEANUP
+AT_SETUP([auth_xor2g])
+AT_KEYWORDS([auth_xor2g])
+cat $abs_srcdir/auth/xor2g_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/auth/xor2g_test], [0], [expout], [ignore])
+AT_CLEANUP
+
AT_SETUP([comp128])
AT_KEYWORDS([comp128])
cat $abs_srcdir/comp128/comp128_test.ok > expout
@@ -153,7 +171,14 @@ AT_CLEANUP
AT_SETUP([gsm0408])
AT_KEYWORDS([gsm0408])
cat $abs_srcdir/gsm0408/gsm0408_test.ok > expout
-AT_CHECK([$abs_top_builddir/tests/gsm0408/gsm0408_test], [0], [expout], [ignore])
+cat $abs_srcdir/gsm0408/gsm0408_test.err > experr
+AT_CHECK([$abs_top_builddir/tests/gsm0408/gsm0408_test], [0], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([gsm48_rest_octets])
+AT_KEYWORDS([gsm48_rest_octets])
+cat $abs_srcdir/gsm48/rest_octets_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/gsm48/rest_octets_test], [0], [expout], [ignore])
AT_CLEANUP
AT_SETUP([gprs])
@@ -162,11 +187,18 @@ cat $abs_srcdir/gprs/gprs_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/gprs/gprs_test], [0], [expout], [ignore])
AT_CLEANUP
-AT_SETUP([logging])
-AT_KEYWORDS([logging])
+AT_SETUP([logging_stream])
+AT_KEYWORDS([logging_stream])
+cat $abs_srcdir/logging/logging_test.ok > expout
+cat $abs_srcdir/logging/logging_test.err > experr
+AT_CHECK([$abs_top_builddir/tests/logging/logging_test stream], [0], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([logging_wqueue])
+AT_KEYWORDS([logging_wqueue])
cat $abs_srcdir/logging/logging_test.ok > expout
cat $abs_srcdir/logging/logging_test.err > experr
-AT_CHECK([$abs_top_builddir/tests/logging/logging_test], [0], [expout], [experr])
+AT_CHECK([$abs_top_builddir/tests/logging/logging_test wqueue], [0], [expout], [experr])
AT_CLEANUP
AT_SETUP([codec])
@@ -204,8 +236,9 @@ AT_CLEANUP
AT_SETUP([vty])
AT_KEYWORDS([vty])
cat $abs_srcdir/vty/vty_test.ok > expout
+cat $abs_srcdir/vty/vty_test.err > experr
cp $abs_srcdir/vty/*.cfg .
-AT_CHECK([$abs_top_builddir/tests/vty/vty_test], [0], [expout], [ignore])
+AT_CHECK([$abs_top_builddir/tests/vty/vty_test], [0], [expout], [experr])
AT_CLEANUP
AT_SETUP([gprs-bssgp])
@@ -214,12 +247,24 @@ cat $abs_srcdir/gb/gprs_bssgp_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/gb/gprs_bssgp_test], [0], [expout], [ignore])
AT_CLEANUP
+AT_SETUP([gprs-bssgp-rim])
+AT_KEYWORDS([gprs-bssgp-rim])
+cat $abs_srcdir/gb/gprs_bssgp_rim_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/gb/gprs_bssgp_rim_test], [0], [expout], [ignore])
+AT_CLEANUP
+
AT_SETUP([gprs-ns])
AT_KEYWORDS([gprs-ns])
cat $abs_srcdir/gb/gprs_ns_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/gb/gprs_ns_test], [0], [expout], [ignore])
AT_CLEANUP
+AT_SETUP([gprs-ns2])
+AT_KEYWORDS([gprs-ns2])
+cat $abs_srcdir/gb/gprs_ns2_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/gb/gprs_ns2_test], [0], [expout], [ignore])
+AT_CLEANUP
+
AT_SETUP([utils])
AT_KEYWORDS([utils])
cat $abs_srcdir/utils/utils_test.ok > expout
@@ -230,7 +275,8 @@ AT_CLEANUP
AT_SETUP([stats])
AT_KEYWORDS([stats])
cat $abs_srcdir/stats/stats_test.ok > expout
-AT_CHECK([$abs_top_builddir/tests/stats/stats_test], [0], [expout], [ignore])
+cat $abs_srcdir/stats/stats_test.err > experr
+AT_CHECK([$abs_top_builddir/tests/stats/stats_test], [0], [expout], [experr])
AT_CLEANUP
AT_SETUP([write_queue])
@@ -402,3 +448,63 @@ AT_KEYWORDS([bitgen])
cat $abs_srcdir/bitgen/bitgen_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/bitgen/bitgen_test], [0], [expout], [ignore])
AT_CLEANUP
+
+AT_SETUP([gad])
+AT_KEYWORDS([gad])
+cat $abs_srcdir/gad/gad_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/gad/gad_test], [0], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([bsslap])
+AT_KEYWORDS([bsslap])
+cat $abs_srcdir/bsslap/bsslap_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/bsslap/bsslap_test], [0], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([bssmap_le])
+AT_KEYWORDS([bssmap_le])
+cat $abs_srcdir/bssmap_le/bssmap_le_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/bssmap_le/bssmap_le_test], [0], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([it_q])
+AT_KEYWORDS([it_q])
+cat $abs_srcdir/it_q/it_q_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/it_q/it_q_test], [0], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([base64])
+AT_KEYWORDS([base64])
+cat $abs_srcdir/base64/base64_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/base64/base64_test], [0], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([time_cc])
+AT_KEYWORDS([time_cc])
+cat $abs_srcdir/time_cc/time_cc_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/time_cc/time_cc_test], [0], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([iuup])
+AT_KEYWORDS([iuup])
+cat $abs_srcdir/iuup/iuup_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/iuup/iuup_test], [0], [expout], [ignore])
+AT_CLEANUP
+
+AT_SETUP([v110_test_frame])
+AT_KEYWORDS([v110_test_frame])
+cat $abs_srcdir/v110/test_frame.ok > expout
+AT_CHECK([$abs_top_builddir/tests/v110/test_frame], [], [expout],[])
+AT_CLEANUP
+
+AT_SETUP([v110_test_ra1])
+AT_KEYWORDS([v110_test_ra1])
+cat $abs_srcdir/v110/test_ra1.ok > expout
+AT_CHECK([$abs_top_builddir/tests/v110/test_ra1], [], [expout],[])
+AT_CLEANUP
+
+AT_SETUP([gsm44021_test_frame_csd])
+AT_KEYWORDS([gsm44021_test_frame_csd])
+cat $abs_srcdir/gsm44021/test_frame_csd.ok > expout
+AT_CHECK([$abs_top_builddir/tests/gsm44021/test_frame_csd], [], [expout],[])
+AT_CLEANUP
diff --git a/tests/time_cc/time_cc_test.c b/tests/time_cc/time_cc_test.c
new file mode 100644
index 00000000..e4a5aaf3
--- /dev/null
+++ b/tests/time_cc/time_cc_test.c
@@ -0,0 +1,768 @@
+/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <inttypes.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/select.h>
+#include <osmocom/core/tdef.h>
+#include <osmocom/core/time_cc.h>
+
+enum my_ctrs {
+ CTR_CEIL,
+ CTR_ROUND,
+ CTR_FLOOR,
+};
+
+const struct rate_ctr_desc my_ctr_desc[] = {
+ [CTR_CEIL] = {"ceil", "testing round_threshold_usec = 1"},
+ [CTR_ROUND] = {"round", "testing round_threshold_usec = 0 = gran_usec/2"},
+ [CTR_FLOOR] = {"floor", "testing round_threshold_usec = gran_usec"},
+};
+
+const struct rate_ctr_group_desc my_ctrg_desc = {
+ "time_cc_test",
+ "Counters for osmo_time_cc test",
+ 0,
+ ARRAY_SIZE(my_ctr_desc),
+ my_ctr_desc,
+};
+
+struct rate_ctr_group *my_ctrg;
+
+
+enum my_obj_timers {
+ T_GRAN = -23,
+ T_ROUND_THRESH = -24,
+ T_FORGET_SUM = -25,
+};
+
+struct osmo_tdef g_my_obj_tdefs[] = {
+ { .T = T_GRAN, .default_val = 0, .unit = OSMO_TDEF_MS, .desc = "flag_cc granularity, or zero for 1 second" },
+ { .T = T_ROUND_THRESH, .default_val = 0, .unit = OSMO_TDEF_MS,
+ .desc = "flag_cc rounding threshold, or zero for half a granularity" },
+ { .T = T_FORGET_SUM, .default_val = 0, .unit = OSMO_TDEF_MS,
+ .desc = "flag_cc inactivity forget period, or zero to not forget any timings" },
+ {}
+};
+
+
+struct my_obj {
+ struct osmo_time_cc flag_cc_ceil;
+ struct osmo_time_cc flag_cc_round;
+ struct osmo_time_cc flag_cc_floor;
+};
+
+void my_obj_init(struct my_obj *my_obj)
+{
+ osmo_time_cc_init(&my_obj->flag_cc_ceil);
+ my_obj->flag_cc_ceil.cfg = (struct osmo_time_cc_cfg){
+ .rate_ctr = rate_ctr_group_get_ctr(my_ctrg, CTR_CEIL),
+ .round_threshold_usec = 1,
+ .T_gran = T_GRAN,
+ .T_forget_sum = T_FORGET_SUM,
+ .T_defs = g_my_obj_tdefs,
+ };
+
+ osmo_time_cc_init(&my_obj->flag_cc_round);
+ my_obj->flag_cc_round.cfg = (struct osmo_time_cc_cfg){
+ .rate_ctr = rate_ctr_group_get_ctr(my_ctrg, CTR_ROUND),
+ .T_gran = T_GRAN,
+ .T_round_threshold = T_ROUND_THRESH,
+ .T_forget_sum = T_FORGET_SUM,
+ .T_defs = g_my_obj_tdefs,
+ };
+
+ osmo_time_cc_init(&my_obj->flag_cc_floor);
+ my_obj->flag_cc_floor.cfg = (struct osmo_time_cc_cfg){
+ .rate_ctr = rate_ctr_group_get_ctr(my_ctrg, CTR_FLOOR),
+ .round_threshold_usec = UINT64_MAX, /* always >= gran_usec */
+ .T_gran = T_GRAN,
+ .T_forget_sum = T_FORGET_SUM,
+ .T_defs = g_my_obj_tdefs,
+ };
+}
+
+void my_obj_event(struct my_obj *my_obj, bool flag)
+{
+ osmo_time_cc_set_flag(&my_obj->flag_cc_ceil, flag);
+ osmo_time_cc_set_flag(&my_obj->flag_cc_round, flag);
+ osmo_time_cc_set_flag(&my_obj->flag_cc_floor, flag);
+}
+
+void my_obj_destruct(struct my_obj *my_obj)
+{
+ osmo_time_cc_cleanup(&my_obj->flag_cc_ceil);
+ osmo_time_cc_cleanup(&my_obj->flag_cc_round);
+ osmo_time_cc_cleanup(&my_obj->flag_cc_floor);
+}
+
+static const struct log_info_cat log_categories[] = {
+};
+
+static const struct log_info log_info = {
+ .cat = log_categories,
+ .num_cat = ARRAY_SIZE(log_categories),
+};
+
+int main(int argc, char **argv)
+{
+ void *ctx = talloc_named_const(NULL, 0, "time_cc_test");
+ struct timespec *now;
+ struct my_obj my_obj = {0};
+
+ osmo_init_logging2(ctx, &log_info);
+
+ /* enable override for CLOCK_MONOTONIC */
+ osmo_clock_override_enable(CLOCK_MONOTONIC, true);
+ now = osmo_clock_override_gettimespec(CLOCK_MONOTONIC);
+ now->tv_sec = 23000;
+ now->tv_nsec = 0;
+
+ /* enable override for osmo_gettimeofday(), for osmo_timer_schedule() */
+ osmo_gettimeofday_override = true;
+ osmo_gettimeofday_override_time = (struct timeval){23000, 0};
+
+ my_ctrg = rate_ctr_group_alloc(ctx, &my_ctrg_desc, 0);
+
+#define CHECK_RATE_CTRS(exp_ceil, exp_round, exp_floor) do { \
+ printf("%d CHECK_RATE_CTRS(" #exp_ceil ", " #exp_round ", " #exp_floor ")", \
+ my_obj.flag_cc_round.flag_state); \
+ while (osmo_select_main_ctx(1) > 0); \
+ if (exp_ceil != my_obj.flag_cc_ceil.cfg.rate_ctr->current \
+ || exp_round != my_obj.flag_cc_round.cfg.rate_ctr->current \
+ || exp_floor != my_obj.flag_cc_floor.cfg.rate_ctr->current) \
+ printf("\n ERROR on line %d: ctr_ceil=%"PRIu64" ctr_round=%"PRIu64" ctr_floor=%"PRIu64"\n", \
+ __LINE__, \
+ my_obj.flag_cc_ceil.cfg.rate_ctr->current, \
+ my_obj.flag_cc_round.cfg.rate_ctr->current, \
+ my_obj.flag_cc_floor.cfg.rate_ctr->current); \
+ else \
+ printf(" ok\n"); \
+ } while (0)
+
+#define ADD_MILLISECS_NO_SELECT(ms) do { \
+ osmo_clock_override_add(CLOCK_MONOTONIC, ms / 1000, (uint64_t)(ms % 1000) * 1000000); \
+ osmo_gettimeofday_override_add(ms / 1000, (uint64_t)(ms % 1000) * 1000); \
+ printf("%d ADD_MILLISECS(" #ms ") --> %ld.%03ld", my_obj.flag_cc_round.flag_state, \
+ now->tv_sec, now->tv_nsec/1000000); \
+ printf("\n"); \
+ } while (0)
+
+#define ADD_MILLISECS(ms) do { \
+ ADD_MILLISECS_NO_SELECT(ms); \
+ while (osmo_select_main_ctx(1) > 0); \
+ } while (0)
+
+#define FLAG(VAL) do { \
+ printf(" flag: %s -> %s\n", my_obj.flag_cc_round.flag_state ? "TRUE" : "FALSE", VAL ? "TRUE" : "FALSE"); \
+ my_obj_event(&my_obj, VAL); \
+ } while (0)
+
+ /*
+ * sum ^
+ * | ________
+ * | /
+ * | /
+ * | /
+ * 3*gran --+--------------------------------------+
+ * | /:
+ * | / :
+ * | - - - - - - - - - - - - - - - - - / :
+ * | /. :
+ * | / . :
+ * 2*gran --+--------------------------------+ . :
+ * | /: . :
+ * | / : . :
+ * | - - - - - - - - - -_________/ : . :
+ * | / . : . :
+ * | / . : . :
+ * 1*gran --+-----------------+ . : . :
+ * | /: . : . :
+ * | / : . : . :
+ * | - - - - - - -/ : . : . :
+ * | /. : . : . :
+ * | ....-------' . : . : . :
+ * 0 +----------------------------------------------------------> elapsed time
+ * . : . : . :
+ * _ _ _______ ____________
+ * flag: __| |_| |____| . : |_______|. : . : |__________
+ * f t f t f t . : f t. : . : f
+ * round_threshold_usec : . : . : . :
+ * = 1 usec: 0 1 . :2 . :3 . :4 = "ceil()"
+ * = 0 == gran_usec/2: 0 1 : 2 : 3 : = "round()"
+ * = gran_usec: 0 1 2 3 = "floor()"
+ */
+
+ printf("\n----------- cumulating time, without forget_sum\n\n");
+
+ my_obj_init(&my_obj);
+ CHECK_RATE_CTRS(0, 0, 0);
+
+ ADD_MILLISECS(100);
+ CHECK_RATE_CTRS(0, 0, 0);
+
+ FLAG(true);
+ /* flag has just turned true the first time */
+ CHECK_RATE_CTRS(0, 0, 0);
+ ADD_MILLISECS(1);
+ /* flag has been true for 0.001s */
+ CHECK_RATE_CTRS(1, 0, 0);
+ ADD_MILLISECS(99);
+ /* flag has been true for 0.1s */
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(false);
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS(100);
+
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(true);
+ CHECK_RATE_CTRS(1, 0, 0);
+ ADD_MILLISECS(100);
+ /* flag has been true for 0.2s */
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(false);
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS(300);
+
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(true);
+ CHECK_RATE_CTRS(1, 0, 0);
+ ADD_MILLISECS(299);
+ /* flag has been true for 0.499s */
+ CHECK_RATE_CTRS(1, 0, 0);
+ ADD_MILLISECS(1);
+ /* flag has been true for 0.5s */
+ CHECK_RATE_CTRS(1, 1, 0);
+ ADD_MILLISECS(499);
+ /* flag has been true for 0.999s */
+ CHECK_RATE_CTRS(1, 1, 0);
+ ADD_MILLISECS(1);
+ /* flag has been true for 1.0s */
+ CHECK_RATE_CTRS(1, 1, 1);
+ ADD_MILLISECS(1);
+ /* flag has been true for 1.001s */
+ CHECK_RATE_CTRS(2, 1, 1);
+ ADD_MILLISECS(299);
+ /* flag has been true for 1.3s */
+ CHECK_RATE_CTRS(2, 1, 1);
+ FLAG(false);
+ CHECK_RATE_CTRS(2, 1, 1);
+
+ ADD_MILLISECS(400);
+
+ CHECK_RATE_CTRS(2, 1, 1);
+ FLAG(true);
+ CHECK_RATE_CTRS(2, 1, 1);
+ ADD_MILLISECS(199);
+ /* flag has been true for 1.499s */
+ CHECK_RATE_CTRS(2, 1, 1);
+ ADD_MILLISECS(2);
+ /* flag has been true for 1.501s */
+ CHECK_RATE_CTRS(2, 2, 1);
+ ADD_MILLISECS(498);
+ /* flag has been true for 1.999s */
+ CHECK_RATE_CTRS(2, 2, 1);
+ ADD_MILLISECS(2);
+ /* flag has been true for 2.001s */
+ CHECK_RATE_CTRS(3, 2, 2);
+ ADD_MILLISECS(500);
+ /* flag has been true for 2.501s */
+ CHECK_RATE_CTRS(3, 3, 2);
+ ADD_MILLISECS(498);
+ /* flag has been true for 2.999s */
+ CHECK_RATE_CTRS(3, 3, 2);
+ ADD_MILLISECS(3);
+ /* flag has been true for 3.003s */
+ CHECK_RATE_CTRS(4, 3, 3);
+ ADD_MILLISECS(200);
+ /* flag has been true for 3.203s */
+ CHECK_RATE_CTRS(4, 3, 3);
+ FLAG(false);
+ CHECK_RATE_CTRS(4, 3, 3);
+
+ ADD_MILLISECS(4321);
+ CHECK_RATE_CTRS(4, 3, 3);
+
+ FLAG(true);
+ CHECK_RATE_CTRS(4, 3, 3);
+ ADD_MILLISECS(5678);
+ CHECK_RATE_CTRS(9, 9, 8);
+ FLAG(false);
+ CHECK_RATE_CTRS(9, 9, 8);
+
+ my_obj_destruct(&my_obj);
+ rate_ctr_group_reset(my_ctrg);
+
+ printf("\n----------- test forget_sum_usec\n\n");
+ osmo_tdef_set(g_my_obj_tdefs, T_FORGET_SUM, 10, OSMO_TDEF_S);
+
+ now->tv_sec = 23000;
+ now->tv_nsec = 0;
+ osmo_gettimeofday_override_time = (struct timeval){23000, 0};
+
+ my_obj_init(&my_obj);
+
+ CHECK_RATE_CTRS(0, 0, 0);
+
+ FLAG(true);
+ /* flag has just turned true the first time */
+ CHECK_RATE_CTRS(0, 0, 0);
+ ADD_MILLISECS(100);
+ /* flag has been true for 0.1s */
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(false);
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS(1000);
+ /* 1 s of being false, forget_sum_usec has not yet occurred */
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS(8999);
+ /* 9.999 s of being false, forget_sum_usec has not yet occurred */
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS(1);
+ /* 10 s of being false, forget_sum_usec has occurred */
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ FLAG(true);
+ CHECK_RATE_CTRS(1, 0, 0);
+ ADD_MILLISECS(1);
+ /* Since previous sums were forgotton, ceil() triggers again */
+ CHECK_RATE_CTRS(2, 0, 0);
+ /* If the sum had not been forgotten, adding 400 ms to the initial 100 ms would have triggered round(). Verify
+ * that this does not occur, since now full 500 ms are required */
+ ADD_MILLISECS(399);
+ CHECK_RATE_CTRS(2, 0, 0);
+ /* Adding another 100 ms will trigger round() */
+ ADD_MILLISECS(99);
+ CHECK_RATE_CTRS(2, 0, 0);
+ ADD_MILLISECS(1);
+ CHECK_RATE_CTRS(2, 1, 0);
+ /* If the sum had not been forgotten, adding 900 ms to the initial 100 ms would have triggered floor(). Verify
+ * that this does not occur, since now full 1000 ms are required. We already added 500 ms above. */
+ ADD_MILLISECS(400);
+ CHECK_RATE_CTRS(2, 1, 0);
+ /* Adding another 100 ms will trigger floor() */
+ ADD_MILLISECS(99);
+ CHECK_RATE_CTRS(2, 1, 0);
+ ADD_MILLISECS(1);
+ CHECK_RATE_CTRS(2, 1, 1);
+
+ /* Test that durations of false below forget_sum_usec never trigger a forget */
+ ADD_MILLISECS(300);
+ CHECK_RATE_CTRS(3, 1, 1);
+ /* internal counter is now at 0.3s above the last reported rate counter */
+ FLAG(false);
+ ADD_MILLISECS(9999);
+ FLAG(true);
+ ADD_MILLISECS(25);
+ FLAG(false);
+ ADD_MILLISECS(9999);
+ FLAG(true);
+ ADD_MILLISECS(25);
+ FLAG(false);
+ ADD_MILLISECS(9999);
+ FLAG(true);
+ ADD_MILLISECS(25);
+ FLAG(false);
+ ADD_MILLISECS(9999);
+ FLAG(true);
+ ADD_MILLISECS(25);
+ /* internal counter is now at 0.4s above the last reported rate counter */
+ CHECK_RATE_CTRS(3, 1, 1);
+ ADD_MILLISECS(100);
+ CHECK_RATE_CTRS(3, 2, 1);
+ ADD_MILLISECS(500);
+ CHECK_RATE_CTRS(3, 2, 2);
+
+ /* Test that repeated osmo_time_cc_set_flag(false) does not cancel a forget_sum_usec */
+ ADD_MILLISECS(300);
+ /* internal counter is now at 0.3s above the last reported rate counter */
+ CHECK_RATE_CTRS(4, 2, 2);
+ FLAG(false);
+ ADD_MILLISECS(5000);
+ /* Repeat 'false', must not affect forget_sum_usec */
+ FLAG(false);
+ ADD_MILLISECS(5000);
+ CHECK_RATE_CTRS(4, 2, 2);
+ /* 10 s have passed, forget_sum_usec has occurred.
+ * Hence ceil() will trigger again right away: */
+ FLAG(true);
+ ADD_MILLISECS(1);
+ CHECK_RATE_CTRS(5, 2, 2);
+ /* Adding 200 ms to the initial 300 ms would have triggered round(), but no more after forget_sum_usec */
+ ADD_MILLISECS(199);
+ CHECK_RATE_CTRS(5, 2, 2);
+ /* Adding another 300 ms will trigger round() */
+ ADD_MILLISECS(299);
+ CHECK_RATE_CTRS(5, 2, 2);
+ ADD_MILLISECS(1);
+ CHECK_RATE_CTRS(5, 3, 2);
+ /* Adding 700 ms to the initial 300 ms would have triggered ceil(), but no more after forget_sum_usec */
+ ADD_MILLISECS(200);
+ CHECK_RATE_CTRS(5, 3, 2);
+ /* Adding another 300 ms will trigger ceil() */
+ ADD_MILLISECS(299);
+ CHECK_RATE_CTRS(5, 3, 2);
+ ADD_MILLISECS(1);
+ CHECK_RATE_CTRS(5, 3, 3);
+
+ my_obj_destruct(&my_obj);
+ rate_ctr_group_reset(my_ctrg);
+
+
+ /* Verify correctness when select() lags and runs timer callbacks too late */
+ printf("\n----------- cumulating time, without forget_sum, when timer cb are invoked late\n\n");
+ osmo_tdef_set(g_my_obj_tdefs, T_FORGET_SUM, 0, OSMO_TDEF_S);
+ now->tv_sec = 23000;
+ now->tv_nsec = 0;
+ osmo_gettimeofday_override_time = (struct timeval){23000, 0};
+
+ my_obj_init(&my_obj);
+ CHECK_RATE_CTRS(0, 0, 0);
+
+ ADD_MILLISECS_NO_SELECT(100);
+ CHECK_RATE_CTRS(0, 0, 0);
+
+ FLAG(true);
+ /* flag has just turned true the first time */
+ CHECK_RATE_CTRS(0, 0, 0);
+ ADD_MILLISECS_NO_SELECT(100);
+ /* flag has been true for 0.1s */
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(false);
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS_NO_SELECT(100);
+
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(true);
+ CHECK_RATE_CTRS(1, 0, 0);
+ ADD_MILLISECS_NO_SELECT(100);
+ /* flag has been true for 0.2s */
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(false);
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS_NO_SELECT(300);
+
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(true);
+ CHECK_RATE_CTRS(1, 0, 0);
+ ADD_MILLISECS_NO_SELECT(799);
+ /* flag has been true for 0.999s */
+ CHECK_RATE_CTRS(1, 1, 0);
+ ADD_MILLISECS_NO_SELECT(1);
+ /* flag has been true for 1.0s */
+ CHECK_RATE_CTRS(1, 1, 1);
+ ADD_MILLISECS_NO_SELECT(300);
+ /* flag has been true for 1.3s */
+ CHECK_RATE_CTRS(2, 1, 1);
+ FLAG(false);
+ CHECK_RATE_CTRS(2, 1, 1);
+
+ ADD_MILLISECS_NO_SELECT(400);
+
+ CHECK_RATE_CTRS(2, 1, 1);
+ FLAG(true);
+ CHECK_RATE_CTRS(2, 1, 1);
+ ADD_MILLISECS_NO_SELECT(699);
+ /* flag has been true for 1.999s */
+ CHECK_RATE_CTRS(2, 2, 1);
+ ADD_MILLISECS_NO_SELECT(1);
+ /* flag has been true for 2.0s */
+ CHECK_RATE_CTRS(2, 2, 2);
+ ADD_MILLISECS_NO_SELECT(1);
+ /* flag has been true for 2.001s */
+ CHECK_RATE_CTRS(3, 2, 2);
+ ADD_MILLISECS_NO_SELECT(499);
+ /* flag has been true for 2.5s */
+ CHECK_RATE_CTRS(3, 3, 2);
+ ADD_MILLISECS_NO_SELECT(499);
+ /* flag has been true for 2.999s */
+ CHECK_RATE_CTRS(3, 3, 2);
+ ADD_MILLISECS_NO_SELECT(1);
+ /* flag has been true for 3.0s */
+ CHECK_RATE_CTRS(3, 3, 3);
+ ADD_MILLISECS_NO_SELECT(200);
+ /* flag has been true for 3.2s */
+ CHECK_RATE_CTRS(4, 3, 3);
+ FLAG(false);
+ CHECK_RATE_CTRS(4, 3, 3);
+
+ ADD_MILLISECS_NO_SELECT(4321);
+ CHECK_RATE_CTRS(4, 3, 3);
+
+ FLAG(true);
+ CHECK_RATE_CTRS(4, 3, 3);
+ ADD_MILLISECS_NO_SELECT(5678);
+ CHECK_RATE_CTRS(9, 9, 8);
+ FLAG(false);
+ CHECK_RATE_CTRS(9, 9, 8);
+
+ my_obj_destruct(&my_obj);
+ rate_ctr_group_reset(my_ctrg);
+
+
+ printf("\n----------- test forget_sum, when timer cb are invoked late\n\n");
+ osmo_tdef_set(g_my_obj_tdefs, T_FORGET_SUM, 10, OSMO_TDEF_S);
+
+ now->tv_sec = 23000;
+ now->tv_nsec = 0;
+ osmo_gettimeofday_override_time = (struct timeval){23000, 0};
+
+ my_obj_init(&my_obj);
+
+ CHECK_RATE_CTRS(0, 0, 0);
+
+ FLAG(true);
+ /* flag has just turned true the first time */
+ CHECK_RATE_CTRS(0, 0, 0);
+ ADD_MILLISECS_NO_SELECT(100);
+ /* flag has been true for 0.1s */
+ CHECK_RATE_CTRS(1, 0, 0);
+ FLAG(false);
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS_NO_SELECT(1000);
+ /* 1 s of being false, forget_sum_usec has not yet occurred */
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS_NO_SELECT(8999);
+ /* 9.999 s of being false, forget_sum_usec has not yet occurred */
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ ADD_MILLISECS_NO_SELECT(1);
+ /* 10 s of being false, forget_sum_usec has occurred */
+ CHECK_RATE_CTRS(1, 0, 0);
+
+ FLAG(true);
+ CHECK_RATE_CTRS(1, 0, 0);
+ ADD_MILLISECS_NO_SELECT(1);
+ /* Since previous sums were forgotton, ceil() triggers again */
+ CHECK_RATE_CTRS(2, 0, 0);
+ /* If the sum had not been forgotten, adding 400 ms to the initial 100 ms would have triggered round(). Verify
+ * that this does not occur, since now full 500 ms are required */
+ ADD_MILLISECS_NO_SELECT(399);
+ CHECK_RATE_CTRS(2, 0, 0);
+ /* Adding another 100 ms will trigger round() */
+ ADD_MILLISECS_NO_SELECT(99);
+ CHECK_RATE_CTRS(2, 0, 0);
+ ADD_MILLISECS_NO_SELECT(1);
+ CHECK_RATE_CTRS(2, 1, 0);
+ /* If the sum had not been forgotten, adding 900 ms to the initial 100 ms would have triggered floor(). Verify
+ * that this does not occur, since now full 1000 ms are required. We already added 500 ms above. */
+ ADD_MILLISECS_NO_SELECT(400);
+ CHECK_RATE_CTRS(2, 1, 0);
+ /* Adding another 100 ms will trigger floor() */
+ ADD_MILLISECS_NO_SELECT(99);
+ CHECK_RATE_CTRS(2, 1, 0);
+ ADD_MILLISECS_NO_SELECT(1);
+ CHECK_RATE_CTRS(2, 1, 1);
+
+ /* Test that durations of false below forget_sum_usec never trigger a forget */
+ ADD_MILLISECS_NO_SELECT(300);
+ CHECK_RATE_CTRS(3, 1, 1);
+ /* internal counter is now at 0.3s above the last reported rate counter */
+ FLAG(false);
+ ADD_MILLISECS_NO_SELECT(9999);
+ FLAG(true);
+ ADD_MILLISECS_NO_SELECT(25);
+ FLAG(false);
+ ADD_MILLISECS_NO_SELECT(9999);
+ FLAG(true);
+ ADD_MILLISECS_NO_SELECT(25);
+ FLAG(false);
+ ADD_MILLISECS_NO_SELECT(9999);
+ FLAG(true);
+ ADD_MILLISECS_NO_SELECT(25);
+ FLAG(false);
+ ADD_MILLISECS_NO_SELECT(9999);
+ FLAG(true);
+ ADD_MILLISECS_NO_SELECT(25);
+ /* internal counter is now at 0.4s above the last reported rate counter */
+ CHECK_RATE_CTRS(3, 1, 1);
+ ADD_MILLISECS_NO_SELECT(100);
+ CHECK_RATE_CTRS(3, 2, 1);
+ ADD_MILLISECS_NO_SELECT(500);
+ CHECK_RATE_CTRS(3, 2, 2);
+
+ my_obj_destruct(&my_obj);
+ rate_ctr_group_reset(my_ctrg);
+
+
+#define SET_TDEFS(gran, round_thresh, forget_sum) do { \
+ osmo_tdef_set(g_my_obj_tdefs, T_GRAN, gran, OSMO_TDEF_MS); \
+ osmo_tdef_set(g_my_obj_tdefs, T_ROUND_THRESH, round_thresh, OSMO_TDEF_MS); \
+ osmo_tdef_set(g_my_obj_tdefs, T_FORGET_SUM, forget_sum, OSMO_TDEF_S); \
+ printf("T_defs: T_gran=%luusec T_round_threshold=%luusec T_forget_sum=%luusec\n", \
+ osmo_tdef_get(g_my_obj_tdefs, T_GRAN, OSMO_TDEF_US, -1), \
+ osmo_tdef_get(g_my_obj_tdefs, T_ROUND_THRESH, OSMO_TDEF_US, -1), \
+ osmo_tdef_get(g_my_obj_tdefs, T_FORGET_SUM, OSMO_TDEF_US, -1)); \
+ } while (0)
+
+ printf("\n----------- test T_defs\n\n");
+ now->tv_sec = 23000;
+ now->tv_nsec = 0;
+ osmo_gettimeofday_override_time = (struct timeval){23000, 0};
+
+ SET_TDEFS(100, 10, 0);
+
+ my_obj_init(&my_obj);
+ CHECK_RATE_CTRS(0, 0, 0);
+
+ ADD_MILLISECS(100);
+ CHECK_RATE_CTRS(0, 0, 0);
+
+ FLAG(true);
+ /* flag has just turned true the first time */
+ CHECK_RATE_CTRS(0, 0, 0);
+ ADD_MILLISECS(9);
+ /* flag has been true for 0.009s */
+ CHECK_RATE_CTRS(1, 0, 0);
+ ADD_MILLISECS(1);
+ /* flag has been true for 0.010s */
+ CHECK_RATE_CTRS(1, 1, 0);
+ ADD_MILLISECS(90);
+ /* flag has been true for 0.1s */
+ CHECK_RATE_CTRS(1, 1, 1);
+
+ SET_TDEFS(200, 190, 1);
+ /* gran is changed to 200ms, but still continues until the next scheduled event until the change is picked up.
+ * For ceil(), it is 1 ms ahead.
+ * For round(), it is 10 ms ahead.
+ * For floor(), it is at the next full (previous) gran 100 ms ahead.
+ * When T_defs change, all internal sums are reset to zero without reporting.
+ */
+ CHECK_RATE_CTRS(1, 1, 1);
+ ADD_MILLISECS(1);
+ /* 1ms elapsed: ceil() picks up the T_gran change, starts anew. */
+ /* elapsed: ceil 0 ms */
+ CHECK_RATE_CTRS(1, 1, 1);
+ ADD_MILLISECS(1);
+ /* elapsed: ceil 1 ms */
+ /* ceil() increments because flag has been true for more than 1 us after reset */
+ CHECK_RATE_CTRS(2, 1, 1);
+ ADD_MILLISECS(8);
+ /* 10 ms elapsed: round() picks up the T_gran change, starts anew */
+ /* elapsed: ceil 9 ms, round 0 ms */
+ CHECK_RATE_CTRS(2, 1, 1);
+ ADD_MILLISECS(90);
+ /* 100 ms elapsed: floor() picks up the T_gran change, starts anew */
+ /* elapsed: ceil 99 ms, round 90 ms, floor 0 ms */
+ CHECK_RATE_CTRS(2, 1, 1);
+ ADD_MILLISECS(99);
+ /* elapsed: ceil 198 ms, round 189 ms, floor 99 ms */
+ CHECK_RATE_CTRS(2, 1, 1);
+ ADD_MILLISECS(1);
+ /* elapsed: ceil 199 ms, round 190 ms, floor 100 ms */
+ CHECK_RATE_CTRS(2, 2, 1);
+ ADD_MILLISECS(1);
+ /* elapsed: ceil 200 ms, round 191 ms, floor 101 ms */
+ CHECK_RATE_CTRS(2, 2, 1);
+ ADD_MILLISECS(1);
+ /* elapsed: ceil 201 ms, round 192 ms, floor 102 ms */
+ CHECK_RATE_CTRS(3, 2, 1);
+ ADD_MILLISECS(98);
+ /* elapsed: ceil 299 ms, round 290 ms, floor 200 ms */
+ CHECK_RATE_CTRS(3, 2, 2);
+ ADD_MILLISECS(99);
+ /* elapsed: ceil 398 ms, round 389 ms, floor 299 ms */
+ CHECK_RATE_CTRS(3, 2, 2);
+ ADD_MILLISECS(1);
+ /* elapsed: ceil 399 ms, round 390 ms, floor 300 ms */
+ CHECK_RATE_CTRS(3, 3, 2);
+ ADD_MILLISECS(1);
+ /* elapsed: ceil 400 ms, round 391 ms, floor 301 ms */
+ CHECK_RATE_CTRS(3, 3, 2);
+ ADD_MILLISECS(1);
+ /* elapsed: ceil 401 ms, round 392 ms, floor 302 ms */
+ CHECK_RATE_CTRS(4, 3, 2);
+ ADD_MILLISECS(98);
+ /* elapsed: ceil 499 ms, round 490 ms, floor 400 ms */
+ CHECK_RATE_CTRS(4, 3, 3);
+
+
+ SET_TDEFS(100, 0, 0);
+ /* T_defs change, but they only get picked up upon the next event:
+ * For ceil(), it is 102 ms ahead.
+ * For round(), it is 100 ms ahead (thresh is still 190, currently at 90).
+ * For floor(), it is 200 ms ahead.
+ * When T_defs change, all internal sums are reset to zero without reporting.
+ */
+ CHECK_RATE_CTRS(4, 3, 3);
+ ADD_MILLISECS(100);
+ CHECK_RATE_CTRS(4, 3, 3);
+ /* round() picks up the new T_defs. Internal sum resets, nothing else happens yet.
+ * round() schedules the next event 50 ms ahead. */
+ ADD_MILLISECS(2);
+ CHECK_RATE_CTRS(4, 3, 3);
+ /* ceil() picks up the change, its next event is 1 ms ahead. */
+ ADD_MILLISECS(1);
+ /* ceil: 0.001
+ * round: 0.003
+ * floor: still 97 ms until it picks up the change */
+ CHECK_RATE_CTRS(5, 3, 3);
+ ADD_MILLISECS(46);
+ CHECK_RATE_CTRS(5, 3, 3);
+ ADD_MILLISECS(1);
+ /* round() has first counter trigger after T_defs change. */
+ CHECK_RATE_CTRS(5, 4, 3);
+ /* ceil: 0.048
+ * round: 0.050
+ * floor: still 50 ms until it picks up the change */
+ ADD_MILLISECS(50);
+ /* floor() picks up the change. nothing happens yet. */
+ /* ceil: 0.098
+ * round: 0.100
+ * floor: 0.0 */
+ ADD_MILLISECS(2);
+ /* ceil: 0.100
+ * round: 0.102
+ * floor: 0.002 */
+ CHECK_RATE_CTRS(5, 4, 3);
+ ADD_MILLISECS(1);
+ /* ceil: 0.101
+ * round: 0.103
+ * floor: 0.003 */
+ CHECK_RATE_CTRS(6, 4, 3);
+ ADD_MILLISECS(46);
+ /* ceil: 0.147
+ * round: 0.149
+ * floor: 0.049 */
+ CHECK_RATE_CTRS(6, 4, 3);
+ ADD_MILLISECS(1);
+ /* ceil: 0.148
+ * round: 0.150
+ * floor: 0.050 */
+ CHECK_RATE_CTRS(6, 5, 3);
+
+ my_obj_destruct(&my_obj);
+ rate_ctr_group_reset(my_ctrg);
+
+ return 0;
+}
diff --git a/tests/time_cc/time_cc_test.ok b/tests/time_cc/time_cc_test.ok
new file mode 100644
index 00000000..ccf84d95
--- /dev/null
+++ b/tests/time_cc/time_cc_test.ok
@@ -0,0 +1,328 @@
+
+----------- cumulating time, without forget_sum
+
+0 CHECK_RATE_CTRS(0, 0, 0) ok
+0 ADD_MILLISECS(100) --> 23000.100
+0 CHECK_RATE_CTRS(0, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(0, 0, 0) ok
+1 ADD_MILLISECS(1) --> 23000.101
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+1 ADD_MILLISECS(99) --> 23000.200
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(100) --> 23000.300
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+1 ADD_MILLISECS(100) --> 23000.400
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(300) --> 23000.700
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+1 ADD_MILLISECS(299) --> 23000.999
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+1 ADD_MILLISECS(1) --> 23001.000
+1 CHECK_RATE_CTRS(1, 1, 0) ok
+1 ADD_MILLISECS(499) --> 23001.499
+1 CHECK_RATE_CTRS(1, 1, 0) ok
+1 ADD_MILLISECS(1) --> 23001.500
+1 CHECK_RATE_CTRS(1, 1, 1) ok
+1 ADD_MILLISECS(1) --> 23001.501
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(299) --> 23001.800
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(2, 1, 1) ok
+0 ADD_MILLISECS(400) --> 23002.200
+0 CHECK_RATE_CTRS(2, 1, 1) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(199) --> 23002.399
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(2) --> 23002.401
+1 CHECK_RATE_CTRS(2, 2, 1) ok
+1 ADD_MILLISECS(498) --> 23002.899
+1 CHECK_RATE_CTRS(2, 2, 1) ok
+1 ADD_MILLISECS(2) --> 23002.901
+1 CHECK_RATE_CTRS(3, 2, 2) ok
+1 ADD_MILLISECS(500) --> 23003.401
+1 CHECK_RATE_CTRS(3, 3, 2) ok
+1 ADD_MILLISECS(498) --> 23003.899
+1 CHECK_RATE_CTRS(3, 3, 2) ok
+1 ADD_MILLISECS(3) --> 23003.902
+1 CHECK_RATE_CTRS(4, 3, 3) ok
+1 ADD_MILLISECS(200) --> 23004.102
+1 CHECK_RATE_CTRS(4, 3, 3) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(4, 3, 3) ok
+0 ADD_MILLISECS(4321) --> 23008.423
+0 CHECK_RATE_CTRS(4, 3, 3) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(4, 3, 3) ok
+1 ADD_MILLISECS(5678) --> 23014.101
+1 CHECK_RATE_CTRS(9, 9, 8) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(9, 9, 8) ok
+
+----------- test forget_sum_usec
+
+0 CHECK_RATE_CTRS(0, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(0, 0, 0) ok
+1 ADD_MILLISECS(100) --> 23000.100
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(1000) --> 23001.100
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(8999) --> 23010.099
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(1) --> 23010.100
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+1 ADD_MILLISECS(1) --> 23010.101
+1 CHECK_RATE_CTRS(2, 0, 0) ok
+1 ADD_MILLISECS(399) --> 23010.500
+1 CHECK_RATE_CTRS(2, 0, 0) ok
+1 ADD_MILLISECS(99) --> 23010.599
+1 CHECK_RATE_CTRS(2, 0, 0) ok
+1 ADD_MILLISECS(1) --> 23010.600
+1 CHECK_RATE_CTRS(2, 1, 0) ok
+1 ADD_MILLISECS(400) --> 23011.000
+1 CHECK_RATE_CTRS(2, 1, 0) ok
+1 ADD_MILLISECS(99) --> 23011.099
+1 CHECK_RATE_CTRS(2, 1, 0) ok
+1 ADD_MILLISECS(1) --> 23011.100
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(300) --> 23011.400
+1 CHECK_RATE_CTRS(3, 1, 1) ok
+ flag: TRUE -> FALSE
+0 ADD_MILLISECS(9999) --> 23021.399
+ flag: FALSE -> TRUE
+1 ADD_MILLISECS(25) --> 23021.424
+ flag: TRUE -> FALSE
+0 ADD_MILLISECS(9999) --> 23031.423
+ flag: FALSE -> TRUE
+1 ADD_MILLISECS(25) --> 23031.448
+ flag: TRUE -> FALSE
+0 ADD_MILLISECS(9999) --> 23041.447
+ flag: FALSE -> TRUE
+1 ADD_MILLISECS(25) --> 23041.472
+ flag: TRUE -> FALSE
+0 ADD_MILLISECS(9999) --> 23051.471
+ flag: FALSE -> TRUE
+1 ADD_MILLISECS(25) --> 23051.496
+1 CHECK_RATE_CTRS(3, 1, 1) ok
+1 ADD_MILLISECS(100) --> 23051.596
+1 CHECK_RATE_CTRS(3, 2, 1) ok
+1 ADD_MILLISECS(500) --> 23052.096
+1 CHECK_RATE_CTRS(3, 2, 2) ok
+1 ADD_MILLISECS(300) --> 23052.396
+1 CHECK_RATE_CTRS(4, 2, 2) ok
+ flag: TRUE -> FALSE
+0 ADD_MILLISECS(5000) --> 23057.396
+ flag: FALSE -> FALSE
+0 ADD_MILLISECS(5000) --> 23062.396
+0 CHECK_RATE_CTRS(4, 2, 2) ok
+ flag: FALSE -> TRUE
+1 ADD_MILLISECS(1) --> 23062.397
+1 CHECK_RATE_CTRS(5, 2, 2) ok
+1 ADD_MILLISECS(199) --> 23062.596
+1 CHECK_RATE_CTRS(5, 2, 2) ok
+1 ADD_MILLISECS(299) --> 23062.895
+1 CHECK_RATE_CTRS(5, 2, 2) ok
+1 ADD_MILLISECS(1) --> 23062.896
+1 CHECK_RATE_CTRS(5, 3, 2) ok
+1 ADD_MILLISECS(200) --> 23063.096
+1 CHECK_RATE_CTRS(5, 3, 2) ok
+1 ADD_MILLISECS(299) --> 23063.395
+1 CHECK_RATE_CTRS(5, 3, 2) ok
+1 ADD_MILLISECS(1) --> 23063.396
+1 CHECK_RATE_CTRS(5, 3, 3) ok
+
+----------- cumulating time, without forget_sum, when timer cb are invoked late
+
+0 CHECK_RATE_CTRS(0, 0, 0) ok
+0 ADD_MILLISECS(100) --> 23000.100
+0 CHECK_RATE_CTRS(0, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(0, 0, 0) ok
+1 ADD_MILLISECS(100) --> 23000.200
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(100) --> 23000.300
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+1 ADD_MILLISECS(100) --> 23000.400
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(300) --> 23000.700
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+1 ADD_MILLISECS(799) --> 23001.499
+1 CHECK_RATE_CTRS(1, 1, 0) ok
+1 ADD_MILLISECS(1) --> 23001.500
+1 CHECK_RATE_CTRS(1, 1, 1) ok
+1 ADD_MILLISECS(300) --> 23001.800
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(2, 1, 1) ok
+0 ADD_MILLISECS(400) --> 23002.200
+0 CHECK_RATE_CTRS(2, 1, 1) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(699) --> 23002.899
+1 CHECK_RATE_CTRS(2, 2, 1) ok
+1 ADD_MILLISECS(1) --> 23002.900
+1 CHECK_RATE_CTRS(2, 2, 2) ok
+1 ADD_MILLISECS(1) --> 23002.901
+1 CHECK_RATE_CTRS(3, 2, 2) ok
+1 ADD_MILLISECS(499) --> 23003.400
+1 CHECK_RATE_CTRS(3, 3, 2) ok
+1 ADD_MILLISECS(499) --> 23003.899
+1 CHECK_RATE_CTRS(3, 3, 2) ok
+1 ADD_MILLISECS(1) --> 23003.900
+1 CHECK_RATE_CTRS(3, 3, 3) ok
+1 ADD_MILLISECS(200) --> 23004.100
+1 CHECK_RATE_CTRS(4, 3, 3) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(4, 3, 3) ok
+0 ADD_MILLISECS(4321) --> 23008.421
+0 CHECK_RATE_CTRS(4, 3, 3) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(4, 3, 3) ok
+1 ADD_MILLISECS(5678) --> 23014.099
+1 CHECK_RATE_CTRS(9, 9, 8) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(9, 9, 8) ok
+
+----------- test forget_sum, when timer cb are invoked late
+
+0 CHECK_RATE_CTRS(0, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(0, 0, 0) ok
+1 ADD_MILLISECS(100) --> 23000.100
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: TRUE -> FALSE
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(1000) --> 23001.100
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(8999) --> 23010.099
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+0 ADD_MILLISECS(1) --> 23010.100
+0 CHECK_RATE_CTRS(1, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+1 ADD_MILLISECS(1) --> 23010.101
+1 CHECK_RATE_CTRS(2, 0, 0) ok
+1 ADD_MILLISECS(399) --> 23010.500
+1 CHECK_RATE_CTRS(2, 0, 0) ok
+1 ADD_MILLISECS(99) --> 23010.599
+1 CHECK_RATE_CTRS(2, 0, 0) ok
+1 ADD_MILLISECS(1) --> 23010.600
+1 CHECK_RATE_CTRS(2, 1, 0) ok
+1 ADD_MILLISECS(400) --> 23011.000
+1 CHECK_RATE_CTRS(2, 1, 0) ok
+1 ADD_MILLISECS(99) --> 23011.099
+1 CHECK_RATE_CTRS(2, 1, 0) ok
+1 ADD_MILLISECS(1) --> 23011.100
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(300) --> 23011.400
+1 CHECK_RATE_CTRS(3, 1, 1) ok
+ flag: TRUE -> FALSE
+0 ADD_MILLISECS(9999) --> 23021.399
+ flag: FALSE -> TRUE
+1 ADD_MILLISECS(25) --> 23021.424
+ flag: TRUE -> FALSE
+0 ADD_MILLISECS(9999) --> 23031.423
+ flag: FALSE -> TRUE
+1 ADD_MILLISECS(25) --> 23031.448
+ flag: TRUE -> FALSE
+0 ADD_MILLISECS(9999) --> 23041.447
+ flag: FALSE -> TRUE
+1 ADD_MILLISECS(25) --> 23041.472
+ flag: TRUE -> FALSE
+0 ADD_MILLISECS(9999) --> 23051.471
+ flag: FALSE -> TRUE
+1 ADD_MILLISECS(25) --> 23051.496
+1 CHECK_RATE_CTRS(3, 1, 1) ok
+1 ADD_MILLISECS(100) --> 23051.596
+1 CHECK_RATE_CTRS(3, 2, 1) ok
+1 ADD_MILLISECS(500) --> 23052.096
+1 CHECK_RATE_CTRS(3, 2, 2) ok
+
+----------- test T_defs
+
+T_defs: T_gran=100000usec T_round_threshold=10000usec T_forget_sum=0usec
+0 CHECK_RATE_CTRS(0, 0, 0) ok
+0 ADD_MILLISECS(100) --> 23000.100
+0 CHECK_RATE_CTRS(0, 0, 0) ok
+ flag: FALSE -> TRUE
+1 CHECK_RATE_CTRS(0, 0, 0) ok
+1 ADD_MILLISECS(9) --> 23000.109
+1 CHECK_RATE_CTRS(1, 0, 0) ok
+1 ADD_MILLISECS(1) --> 23000.110
+1 CHECK_RATE_CTRS(1, 1, 0) ok
+1 ADD_MILLISECS(90) --> 23000.200
+1 CHECK_RATE_CTRS(1, 1, 1) ok
+T_defs: T_gran=200000usec T_round_threshold=190000usec T_forget_sum=1000000usec
+1 CHECK_RATE_CTRS(1, 1, 1) ok
+1 ADD_MILLISECS(1) --> 23000.201
+1 CHECK_RATE_CTRS(1, 1, 1) ok
+1 ADD_MILLISECS(1) --> 23000.202
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(8) --> 23000.210
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(90) --> 23000.300
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(99) --> 23000.399
+1 CHECK_RATE_CTRS(2, 1, 1) ok
+1 ADD_MILLISECS(1) --> 23000.400
+1 CHECK_RATE_CTRS(2, 2, 1) ok
+1 ADD_MILLISECS(1) --> 23000.401
+1 CHECK_RATE_CTRS(2, 2, 1) ok
+1 ADD_MILLISECS(1) --> 23000.402
+1 CHECK_RATE_CTRS(3, 2, 1) ok
+1 ADD_MILLISECS(98) --> 23000.500
+1 CHECK_RATE_CTRS(3, 2, 2) ok
+1 ADD_MILLISECS(99) --> 23000.599
+1 CHECK_RATE_CTRS(3, 2, 2) ok
+1 ADD_MILLISECS(1) --> 23000.600
+1 CHECK_RATE_CTRS(3, 3, 2) ok
+1 ADD_MILLISECS(1) --> 23000.601
+1 CHECK_RATE_CTRS(3, 3, 2) ok
+1 ADD_MILLISECS(1) --> 23000.602
+1 CHECK_RATE_CTRS(4, 3, 2) ok
+1 ADD_MILLISECS(98) --> 23000.700
+1 CHECK_RATE_CTRS(4, 3, 3) ok
+T_defs: T_gran=100000usec T_round_threshold=0usec T_forget_sum=0usec
+1 CHECK_RATE_CTRS(4, 3, 3) ok
+1 ADD_MILLISECS(100) --> 23000.800
+1 CHECK_RATE_CTRS(4, 3, 3) ok
+1 ADD_MILLISECS(2) --> 23000.802
+1 CHECK_RATE_CTRS(4, 3, 3) ok
+1 ADD_MILLISECS(1) --> 23000.803
+1 CHECK_RATE_CTRS(5, 3, 3) ok
+1 ADD_MILLISECS(46) --> 23000.849
+1 CHECK_RATE_CTRS(5, 3, 3) ok
+1 ADD_MILLISECS(1) --> 23000.850
+1 CHECK_RATE_CTRS(5, 4, 3) ok
+1 ADD_MILLISECS(50) --> 23000.900
+1 ADD_MILLISECS(2) --> 23000.902
+1 CHECK_RATE_CTRS(5, 4, 3) ok
+1 ADD_MILLISECS(1) --> 23000.903
+1 CHECK_RATE_CTRS(6, 4, 3) ok
+1 ADD_MILLISECS(46) --> 23000.949
+1 CHECK_RATE_CTRS(6, 4, 3) ok
+1 ADD_MILLISECS(1) --> 23000.950
+1 CHECK_RATE_CTRS(6, 5, 3) ok
diff --git a/tests/timer/clk_override_test.c b/tests/timer/clk_override_test.c
index 308e8212..e67a6ed6 100644
--- a/tests/timer/clk_override_test.c
+++ b/tests/timer/clk_override_test.c
@@ -16,10 +16,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c
index d2b0204d..9c51ad94 100644
--- a/tests/timer/timer_test.c
+++ b/tests/timer/timer_test.c
@@ -16,10 +16,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
@@ -33,7 +29,7 @@
#include <osmocom/core/select.h>
#include <osmocom/core/linuxlist.h>
-#include "../config.h"
+#include "config.h"
static void main_timer_fired(void *data);
static void secondary_timer_fired(void *data);
diff --git a/tests/tlv/tlv_test.c b/tests/tlv/tlv_test.c
index 925d7628..f9137ad3 100644
--- a/tests/tlv/tlv_test.c
+++ b/tests/tlv/tlv_test.c
@@ -188,7 +188,7 @@ static void check_lv_shift_data_len(size_t data_len,
}
}
-static void test_tlv_shift_functions()
+static void test_tlv_shift_functions(void)
{
uint8_t test_data[1024];
uint8_t buf[1024];
@@ -250,7 +250,7 @@ static void test_tlv_shift_functions()
/* Most GSM related protocols clearly indicate that in case of duplicate
* IEs, only the first occurrence shall be used, while any further occurrences
* shall be ignored. See e.g. 3GPP TS 24.008 Section 8.6.3 */
-static void test_tlv_repeated_ie()
+static void test_tlv_repeated_ie(void)
{
uint8_t test_data[768];
int i, rc;
@@ -288,7 +288,7 @@ static void test_tlv_repeated_ie()
OSMO_ASSERT(dec3[2].lv[tag].val == &test_data[2 + 3 + 3]);
}
-static void test_tlv_encoder()
+static void test_tlv_encoder(void)
{
const uint8_t enc_ies[] = {
0x17, 0x14, 0x06, 0x2b, 0x12, 0x2b, 0x0b, 0x40, 0x2b, 0xb7, 0x05, 0xd0, 0x63, 0x82, 0x95, 0x03, 0x05, 0x40,
@@ -332,6 +332,128 @@ static void test_tlv_encoder()
msgb_free(msg);
}
+static void test_tlv_parser_bounds(void)
+{
+ struct tlv_definition tdef;
+ struct tlv_parsed dec;
+ uint8_t buf[32];
+
+ memset(&tdef, 0, sizeof(tdef));
+
+ printf("Testing TLV_TYPE_T decoder for out-of-bounds\n");
+ tdef.def[0x23].type = TLV_TYPE_T;
+ buf[0] = 0x23;
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == 1);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 0, 0, 0) == 0);
+
+ printf("Testing TLV_TYPE_TV decoder for out-of-bounds\n");
+ tdef.def[0x23].type = TLV_TYPE_TV;
+ buf[0] = 0x23;
+ buf[1] = 0x42;
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == 1);
+ OSMO_ASSERT(*TLVP_VAL(&dec, 0x23) == buf[1]);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+
+ printf("Testing TLV_TYPE_FIXED decoder for out-of-bounds\n");
+ tdef.def[0x23].type = TLV_TYPE_FIXED;
+ tdef.def[0x23].fixed_len = 2;
+ buf[0] = 0x23;
+ buf[1] = 0x42;
+ buf[2] = 0x55;
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == 1);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+
+ printf("Testing TLV_TYPE_TLV decoder for out-of-bounds\n");
+ tdef.def[0x23].type = TLV_TYPE_TLV;
+ buf[0] = 0x23;
+ buf[1] = 0x02;
+ buf[2] = 0x55;
+ buf[3] = 0xAA;
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 4, 0, 0) == 1);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == &buf[2]);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+
+ printf("Testing TLV_TYPE_vTvLV_GAN decoder for out-of-bounds\n");
+ tdef.def[0x23].type = TLV_TYPE_vTvLV_GAN;
+ buf[0] = 0x23;
+ buf[1] = 0x80;
+ buf[2] = 0x01;
+ buf[3] = 0xAA;
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 4, 0, 0) == 1);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == &buf[3]);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+
+ printf("Testing TLV_TYPE_TvLV decoder for out-of-bounds\n");
+ tdef.def[0x23].type = TLV_TYPE_TvLV;
+ buf[0] = 0x23;
+ buf[1] = 0x81;
+ buf[2] = 0xAA;
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == 1);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == &buf[2]);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+
+ printf("Testing TLV_TYPE_TL16V decoder for out-of-bounds\n");
+ tdef.def[0x23].type = TLV_TYPE_TL16V;
+ buf[0] = 0x23;
+ buf[1] = 0x00;
+ buf[2] = 0x01;
+ buf[3] = 0xAA;
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 4, 0, 0) == 1);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == &buf[3]);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+ OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
+ OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
+}
+
+static void test_tlv_lens(void)
+{
+ uint16_t buf_len;
+ uint8_t buf[512];
+ uint8_t val[512] = { 0 };
+ uint16_t x;
+
+
+ for (x = 0; x < 16; x++) {
+ buf_len = lv_put(buf, x, val) - buf;
+ OSMO_ASSERT(buf_len == LV_GROSS_LEN(x));
+ buf_len = tlv_put(buf, 0x23, x, val) - buf;
+ OSMO_ASSERT(buf_len == TLV_GROSS_LEN(x));
+ buf_len = tlv16_put(buf, 0x23, x, (uint16_t *) val) - buf;
+ OSMO_ASSERT(buf_len == TLV16_GROSS_LEN(x));
+ buf_len = tl16v_put(buf, 0x23, x, val) - buf;
+ OSMO_ASSERT(buf_len == TL16V_GROSS_LEN(x));
+ buf_len = t16lv_put(buf, 0x2342, x, val) - buf;
+ OSMO_ASSERT(buf_len == T16LV_GROSS_LEN(x));
+ buf_len = tvlv_put(buf, 0x23, x, val) - buf;
+ OSMO_ASSERT(buf_len == TVLV_GROSS_LEN(x));
+ }
+
+ for (x = 250; x < 300; x++) {
+ buf_len = tl16v_put(buf, 0x23, x, val) - buf;
+ OSMO_ASSERT(buf_len == TL16V_GROSS_LEN(x));
+ buf_len = tvlv_put(buf, 0x23, x, val) - buf;
+ OSMO_ASSERT(buf_len == TVLV_GROSS_LEN(x));
+ }
+}
+
int main(int argc, char **argv)
{
//osmo_init_logging2(ctx, &info);
@@ -339,6 +461,8 @@ int main(int argc, char **argv)
test_tlv_shift_functions();
test_tlv_repeated_ie();
test_tlv_encoder();
+ test_tlv_parser_bounds();
+ test_tlv_lens();
printf("Done.\n");
return EXIT_SUCCESS;
diff --git a/tests/tlv/tlv_test.ok b/tests/tlv/tlv_test.ok
index f3f0fd41..e24b889b 100644
--- a/tests/tlv/tlv_test.ok
+++ b/tests/tlv/tlv_test.ok
@@ -1,4 +1,11 @@
Test shift functions
Testing TLV encoder by decoding + re-encoding binary
Testing TLV encoder with IE ordering
+Testing TLV_TYPE_T decoder for out-of-bounds
+Testing TLV_TYPE_TV decoder for out-of-bounds
+Testing TLV_TYPE_FIXED decoder for out-of-bounds
+Testing TLV_TYPE_TLV decoder for out-of-bounds
+Testing TLV_TYPE_vTvLV_GAN decoder for out-of-bounds
+Testing TLV_TYPE_TvLV decoder for out-of-bounds
+Testing TLV_TYPE_TL16V decoder for out-of-bounds
Done.
diff --git a/tests/use_count/use_count_test.c b/tests/use_count/use_count_test.c
index 95af3082..b784aeb4 100644
--- a/tests/use_count/use_count_test.c
+++ b/tests/use_count/use_count_test.c
@@ -17,10 +17,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
@@ -196,7 +192,7 @@ static struct foo *foo_alloc(const char *name, size_t static_entries)
return foo;
}
-void print_foos()
+void print_foos(void)
{
int count = 0;
struct foo *foo;
@@ -208,7 +204,7 @@ void print_foos()
fprintf(stderr, "%d foos\n\n", count);
}
-static void test_use_count_fsm()
+static void test_use_count_fsm(void)
{
struct foo *a, *b, *c;
log("\n%s()\n", __func__);
diff --git a/tests/use_count/use_count_test.err b/tests/use_count/use_count_test.err
index 97e74a51..29ebfb73 100644
--- a/tests/use_count/use_count_test.err
+++ b/tests/use_count/use_count_test.err
@@ -11,9 +11,9 @@ c: 0 (-)
3 foos
A few gets and puts, logging source file information
-DFOO NOTICE foo(a){IN_USE}: a +1 barring: now used by 1 (barring) (use_count_test.c:223)
-DFOO NOTICE foo(b){IN_USE}: b +1 barring: now used by 1 (barring) (use_count_test.c:225)
-DFOO NOTICE foo(b){IN_USE}: b +1 fighting: now used by 2 (barring,fighting) (use_count_test.c:226)
+DFOO NOTICE foo(a){IN_USE}: a +1 barring: now used by 1 (barring) (use_count_test.c:219)
+DFOO NOTICE foo(b){IN_USE}: b +1 barring: now used by 1 (barring) (use_count_test.c:221)
+DFOO NOTICE foo(b){IN_USE}: b +1 fighting: now used by 2 (barring,fighting) (use_count_test.c:222)
all use counts:
a: 1 (barring)
@@ -22,7 +22,7 @@ c: 0 (-)
3 foos
Attempt to get more than one on limited 'barring' user:
-DFOO ERROR foo(b){IN_USE}: Attempt to get more than one barring (use_count_test.c:231)
+DFOO ERROR foo(b){IN_USE}: Attempt to get more than one barring (use_count_test.c:227)
osmo_use_count_get_put(b, barring, 1) returned error: -34 Numerical result out of range
all use counts:
@@ -32,7 +32,7 @@ c: 0 (-)
3 foos
Put away one user of b
-DFOO NOTICE foo(b){IN_USE}: b -1 barring: now used by 1 (fighting) (use_count_test.c:235)
+DFOO NOTICE foo(b){IN_USE}: b -1 barring: now used by 1 (fighting) (use_count_test.c:231)
all use counts:
a: 1 (barring)
diff --git a/tests/ussd/ussd_test.c b/tests/ussd/ussd_test.c
index 80250711..2b8321d3 100644
--- a/tests/ussd/ussd_test.c
+++ b/tests/ussd/ussd_test.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/core/application.h>
diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c
index 9ff023bf..0b7bfe44 100644
--- a/tests/utils/utils_test.c
+++ b/tests/utils/utils_test.c
@@ -14,10 +14,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <osmocom/gsm/ipa.h>
@@ -34,6 +30,7 @@
#include <arpa/inet.h>
#include <errno.h>
#include <limits.h>
+#include <inttypes.h>
static void hexdump_test(void)
{
@@ -345,7 +342,7 @@ static struct {
{ "DeafBeddedBabeAcceededFadedDecaff", 32, 32, false, false },
};
-bool test_is_hexstr()
+bool test_is_hexstr(void)
{
int i;
bool pass = true;
@@ -769,6 +766,65 @@ static void isqrt_test(void)
}
}
+static void mod_test_mod(int x, int y, int expected_result)
+{
+ int result;
+ result = x % y;
+ printf(" %d mod %d = %d = %d\n", x, y, result, expected_result);
+ OSMO_ASSERT(result == expected_result);
+}
+
+static void mod_test_mod_flr(int x, int y, int expected_result)
+{
+ int result;
+ result = OSMO_MOD_FLR(x, y);
+ printf(" %d mod_flr %d = %d = %d\n", x, y, result, expected_result);
+ OSMO_ASSERT(result == expected_result);
+}
+
+static void mod_test_mod_euc(int x, int y, int expected_result)
+{
+ int result;
+ result = OSMO_MOD_EUC(x, y);
+ printf(" %d mod_euc %d = %d = %d\n", x, y, result, expected_result);
+ OSMO_ASSERT(result == expected_result);
+}
+
+static void mod_test(void)
+{
+ /* See also: Daan Leijen, Division and Modulus for Computer
+ * Scientists, section 1.3 */
+
+ printf("\nTesting built in truncated modulo for comparison:\n");
+ mod_test_mod(8, 3, 2);
+ mod_test_mod(8, -3, 2);
+ mod_test_mod(-8, 3, -2);
+ mod_test_mod(-8, -3, -2);
+ mod_test_mod(1, 2, 1);
+ mod_test_mod(1, -2, 1);
+ mod_test_mod(-1, 2, -1);
+ mod_test_mod(-1, -2, -1);
+
+ printf("\nTesting OSMO_MOD_FLR():\n");
+ mod_test_mod_flr(8, 3, 2);
+ mod_test_mod_flr(8, -3, -1);
+ mod_test_mod_flr(-8, 3, 1);
+ mod_test_mod_flr(-8, -3, -2);
+ mod_test_mod_flr(1, 2, 1);
+ mod_test_mod_flr(1, -2, -1);
+ mod_test_mod_flr(-1, 2, 1);
+ mod_test_mod_flr(-1, -2, -1);
+
+ printf("\nTesting OSMO_MOD_EUC():\n");
+ mod_test_mod_euc(8, 3, 2);
+ mod_test_mod_euc(8, -3, 2);
+ mod_test_mod_euc(-8, 3, 1);
+ mod_test_mod_euc(-8, -3, 1);
+ mod_test_mod_euc(1, 2, 1);
+ mod_test_mod_euc(1, -2, 1);
+ mod_test_mod_euc(-1, 2, 1);
+ mod_test_mod_euc(-1, -2, 1);
+}
struct osmo_sockaddr_to_str_and_uint_test_case {
uint16_t port;
@@ -1026,7 +1082,7 @@ struct osmo_str_tolowupper_test_data osmo_str_tolowupper_tests[] = {
};
-static void osmo_str_tolowupper_test()
+static void osmo_str_tolowupper_test(void)
{
int i;
char buf[128];
@@ -1200,7 +1256,7 @@ int strbuf_cascade(char *buf, size_t buflen)
return sb.chars_needed;
}
-void strbuf_test()
+void strbuf_test(void)
{
char buf[256];
int rc;
@@ -1233,7 +1289,7 @@ void strbuf_test()
printf("(need %d chars, had size=63) %s\n", rc, buf);
}
-void strbuf_test_nolen()
+void strbuf_test_nolen(void)
{
char buf[20];
struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) };
@@ -1259,7 +1315,7 @@ static void startswith_test_str(const char *str, const char *startswith_str, boo
printf(" ERROR: EXPECTED %s\n", expect_rc ? "true" : "false");
}
-static void startswith_test()
+static void startswith_test(void)
{
printf("\n%s()\n", __func__);
startswith_test_str(NULL, NULL, true);
@@ -1304,7 +1360,7 @@ static char *foo_name_c_zero_null(void *ctx, const char *arg)
OSMO_NAME_C_IMPL(ctx, 0, NULL, foo_name_buf, arg)
}
-static void name_c_impl_test()
+static void name_c_impl_test(void)
{
char *test_strs[] = {
"test",
@@ -1443,6 +1499,637 @@ static void osmo_strnchr_test(void)
}
}
+struct float_str_to_int_test {
+ unsigned int precision;
+ const char *str;
+ int64_t expect_val;
+ int expect_err;
+};
+struct float_str_to_int_test float_str_to_int_tests[] = {
+ { 0, "0", 0 },
+ { 0, "1", 1 },
+ { 0, "12.345", 12 },
+ { 0, "+12.345", 12 },
+ { 0, "-12.345", -12 },
+ { 0, "0.345", 0 },
+ { 0, ".345", 0 },
+ { 0, "-0.345", 0 },
+ { 0, "-.345", 0 },
+ { 0, "12.", 12 },
+ { 0, "-180", -180 },
+ { 0, "180", 180 },
+ { 0, "360", 360 },
+ { 0, "123.4567890123", 123 },
+ { 0, "123.4567890123456789012345", 123 },
+ { 0, "9223372036854775807", 9223372036854775807LL },
+ { 0, "-9223372036854775807", -9223372036854775807LL },
+ { 0, "-9223372036854775808", .expect_err = -ERANGE },
+ { 0, "9223372036854775808", .expect_err = -ERANGE },
+ { 0, "-9223372036854775809", .expect_err = -ERANGE },
+ { 0, "100000000000000000000", .expect_err = -ERANGE },
+ { 0, "-100000000000000000000", .expect_err = -ERANGE },
+ { 0, "999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 0, "-999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 0, "1.2.3", .expect_err = -EINVAL },
+ { 0, "foo", .expect_err = -EINVAL },
+ { 0, "1.foo", .expect_err = -EINVAL },
+ { 0, "1.foo", .expect_err = -EINVAL },
+ { 0, "12.-345", .expect_err = -EINVAL },
+ { 0, "-12.-345", .expect_err = -EINVAL },
+ { 0, "12.+345", .expect_err = -EINVAL },
+ { 0, "+12.+345", .expect_err = -EINVAL },
+ { 0, "", .expect_err = -EINVAL },
+ { 0, NULL, .expect_err = -EINVAL },
+
+ { 1, "0", 0 },
+ { 1, "1", 10 },
+ { 1, "12.345", 123 },
+ { 1, "+12.345", 123 },
+ { 1, "-12.345", -123 },
+ { 1, "0.345", 3 },
+ { 1, ".345", 3 },
+ { 1, "-0.345", -3 },
+ { 1, "-.345", -3 },
+ { 1, "12.", 120 },
+ { 1, "-180", -1800 },
+ { 1, "180", 1800 },
+ { 1, "360", 3600 },
+ { 1, "123.4567890123", 1234 },
+ { 1, "123.4567890123456789012345", 1234 },
+ { 1, "922337203685477580.7", 9223372036854775807LL },
+ { 1, "-922337203685477580.7", -9223372036854775807LL },
+ { 1, "-922337203685477580.8", .expect_err = -ERANGE },
+ { 1, "922337203685477580.8", .expect_err = -ERANGE },
+ { 1, "-922337203685477580.9", .expect_err = -ERANGE },
+ { 1, "100000000000000000000", .expect_err = -ERANGE },
+ { 1, "-100000000000000000000", .expect_err = -ERANGE },
+ { 1, "999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 1, "-999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 1, "1.2.3", .expect_err = -EINVAL },
+ { 1, "foo", .expect_err = -EINVAL },
+ { 1, "1.foo", .expect_err = -EINVAL },
+ { 1, "1.foo", .expect_err = -EINVAL },
+ { 1, "12.-345", .expect_err = -EINVAL },
+ { 1, "-12.-345", .expect_err = -EINVAL },
+ { 1, "12.+345", .expect_err = -EINVAL },
+ { 1, "+12.+345", .expect_err = -EINVAL },
+ { 1, "", .expect_err = -EINVAL },
+ { 1, NULL, .expect_err = -EINVAL },
+
+ { 6, "0", 0 },
+ { 6, "1", 1000000 },
+ { 6, "12.345", 12345000 },
+ { 6, "+12.345", 12345000 },
+ { 6, "-12.345", -12345000 },
+ { 6, "0.345", 345000 },
+ { 6, ".345", 345000 },
+ { 6, "-0.345", -345000 },
+ { 6, "-.345", -345000 },
+ { 6, "12.", 12000000 },
+ { 6, "-180", -180000000 },
+ { 6, "180", 180000000 },
+ { 6, "360", 360000000 },
+ { 6, "123.4567890123", 123456789 },
+ { 6, "123.4567890123456789012345", 123456789 },
+ { 6, "9223372036854.775807", 9223372036854775807LL },
+ { 6, "-9223372036854.775807", -9223372036854775807LL },
+ { 6, "-9223372036854.775808", .expect_err = -ERANGE },
+ { 6, "9223372036854.775808", .expect_err = -ERANGE },
+ { 6, "-9223372036854.775809", .expect_err = -ERANGE },
+ { 6, "100000000000000000000", .expect_err = -ERANGE },
+ { 6, "-100000000000000000000", .expect_err = -ERANGE },
+ { 6, "999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 6, "-999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 6, "1.2.3", .expect_err = -EINVAL },
+ { 6, "foo", .expect_err = -EINVAL },
+ { 6, "1.foo", .expect_err = -EINVAL },
+ { 6, "1.foo", .expect_err = -EINVAL },
+ { 6, "12.-345", .expect_err = -EINVAL },
+ { 6, "-12.-345", .expect_err = -EINVAL },
+ { 6, "12.+345", .expect_err = -EINVAL },
+ { 6, "+12.+345", .expect_err = -EINVAL },
+ { 6, "", .expect_err = -EINVAL },
+ { 6, NULL, .expect_err = -EINVAL },
+
+ { 18, "0", 0 },
+ { 18, "1", 1000000000000000000LL },
+ { 18, "1.2345", 1234500000000000000LL },
+ { 18, "+1.2345", 1234500000000000000LL },
+ { 18, "-1.2345", -1234500000000000000LL },
+ { 18, "0.345", 345000000000000000LL },
+ { 18, ".345", 345000000000000000LL },
+ { 18, "-0.345", -345000000000000000LL },
+ { 18, "-.345", -345000000000000000LL },
+ { 18, "2.", 2000000000000000000LL },
+ { 18, "-8", -8000000000000000000LL },
+ { 18, "1.234567890123", 1234567890123000000LL },
+ { 18, "1.234567890123456789012345", 1234567890123456789LL },
+ { 18, "123.4567890123", .expect_err = -ERANGE },
+ { 18, "9.223372036854775807", 9223372036854775807LL },
+ { 18, "-9.223372036854775807", -9223372036854775807LL },
+ { 18, "-9.223372036854775808", .expect_err = -ERANGE },
+ { 18, "9.223372036854775808", .expect_err = -ERANGE },
+ { 18, "-9.223372036854775809", .expect_err = -ERANGE },
+ { 18, "100000000000000000000", .expect_err = -ERANGE },
+ { 18, "-100000000000000000000", .expect_err = -ERANGE },
+ { 18, "999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 18, "-999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 18, "1.2.3", .expect_err = -EINVAL },
+ { 18, "foo", .expect_err = -EINVAL },
+ { 18, "1.foo", .expect_err = -EINVAL },
+ { 18, "1.foo", .expect_err = -EINVAL },
+ { 18, "12.-345", .expect_err = -EINVAL },
+ { 18, "-12.-345", .expect_err = -EINVAL },
+ { 18, "12.+345", .expect_err = -EINVAL },
+ { 18, "+12.+345", .expect_err = -EINVAL },
+ { 18, "", .expect_err = -EINVAL },
+ { 18, NULL, .expect_err = -EINVAL },
+
+ { 19, "0", 0 },
+ { 19, ".1", 1000000000000000000LL },
+ { 19, ".12345", 1234500000000000000LL },
+ { 19, "+.12345", 1234500000000000000LL },
+ { 19, "-.12345", -1234500000000000000LL },
+ { 19, "0.0345", 345000000000000000LL },
+ { 19, ".0345", 345000000000000000LL },
+ { 19, "-0.0345", -345000000000000000LL },
+ { 19, "-.0345", -345000000000000000LL },
+ { 19, ".2", 2000000000000000000LL },
+ { 19, "-.8", -8000000000000000000LL },
+ { 19, ".1234567890123", 1234567890123000000LL },
+ { 19, ".1234567890123456789012345", 1234567890123456789LL },
+ { 19, "123.4567890123", .expect_err = -ERANGE },
+ { 19, ".9223372036854775807", 9223372036854775807LL },
+ { 19, "-.9223372036854775807", -9223372036854775807LL },
+ { 19, "-.9223372036854775808", .expect_err = -ERANGE },
+ { 19, ".9223372036854775808", .expect_err = -ERANGE },
+ { 19, "-.9223372036854775809", .expect_err = -ERANGE },
+ { 19, "100000000000000000000", .expect_err = -ERANGE },
+ { 19, "-100000000000000000000", .expect_err = -ERANGE },
+ { 19, "999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 19, "-999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 19, "1.2.3", .expect_err = -EINVAL },
+ { 19, "foo", .expect_err = -EINVAL },
+ { 19, "1.foo", .expect_err = -EINVAL },
+ { 19, "1.foo", .expect_err = -EINVAL },
+ { 19, "12.-345", .expect_err = -EINVAL },
+ { 19, "-12.-345", .expect_err = -EINVAL },
+ { 19, "12.+345", .expect_err = -EINVAL },
+ { 19, "+12.+345", .expect_err = -EINVAL },
+ { 19, "", .expect_err = -EINVAL },
+ { 19, NULL, .expect_err = -EINVAL },
+
+ { 20, "0", 0 },
+ { 20, ".01", 1000000000000000000LL },
+ { 20, ".012345", 1234500000000000000LL },
+ { 20, "+.012345", 1234500000000000000LL },
+ { 20, "-.012345", -1234500000000000000LL },
+ { 20, "0.00345", 345000000000000000LL },
+ { 20, ".00345", 345000000000000000LL },
+ { 20, "-0.00345", -345000000000000000LL },
+ { 20, "-.00345", -345000000000000000LL },
+ { 20, ".02", 2000000000000000000LL },
+ { 20, "-.08", -8000000000000000000LL },
+ { 20, ".01234567890123", 1234567890123000000LL },
+ { 20, ".01234567890123456789012345", 1234567890123456789LL },
+ { 20, "12.34567890123", .expect_err = -ERANGE },
+ { 20, ".09223372036854775807", 9223372036854775807LL },
+ { 20, "-.09223372036854775807", -9223372036854775807LL },
+ { 20, "-.09223372036854775808", .expect_err = -ERANGE },
+ { 20, ".09223372036854775808", .expect_err = -ERANGE },
+ { 20, "-.09223372036854775809", .expect_err = -ERANGE },
+ { 20, ".1", .expect_err = -ERANGE },
+ { 20, "-.1", .expect_err = -ERANGE },
+ { 20, "999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 20, "-999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 20, "1.2.3", .expect_err = -EINVAL },
+ { 20, "foo", .expect_err = -EINVAL },
+ { 20, "1.foo", .expect_err = -EINVAL },
+ { 20, "1.foo", .expect_err = -EINVAL },
+ { 20, "12.-345", .expect_err = -EINVAL },
+ { 20, "-12.-345", .expect_err = -EINVAL },
+ { 20, "12.+345", .expect_err = -EINVAL },
+ { 20, "+12.+345", .expect_err = -EINVAL },
+ { 20, "", .expect_err = -EINVAL },
+ { 20, NULL, .expect_err = -EINVAL },
+
+ { 25, "0", 0 },
+ { 25, ".0000001", 1000000000000000000LL },
+ { 25, ".00000012345", 1234500000000000000LL },
+ { 25, "+.00000012345", 1234500000000000000LL },
+ { 25, "-.00000012345", -1234500000000000000LL },
+ { 25, "0.0000000345", 345000000000000000LL },
+ { 25, ".0000000345", 345000000000000000LL },
+ { 25, "-0.0000000345", -345000000000000000LL },
+ { 25, "-.0000000345", -345000000000000000LL },
+ { 25, ".0000002", 2000000000000000000LL },
+ { 25, "-.0000008", -8000000000000000000LL },
+ { 25, ".0000001234567890123", 1234567890123000000LL },
+ { 25, ".0000001234567890123456789012345", 1234567890123456789LL },
+ { 25, ".0001234567890123", .expect_err = -ERANGE },
+ { 25, ".0000009223372036854775807", 9223372036854775807LL },
+ { 25, "-.0000009223372036854775807", -9223372036854775807LL },
+ { 25, "-.0000009223372036854775808", .expect_err = -ERANGE },
+ { 25, ".0000009223372036854775808", .expect_err = -ERANGE },
+ { 25, "-.0000009223372036854775809", .expect_err = -ERANGE },
+ { 25, ".000001", .expect_err = -ERANGE },
+ { 25, "-.000001", .expect_err = -ERANGE },
+ { 25, "999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 25, "-999999999999999999999999999.99", .expect_err = -ERANGE },
+ { 25, "1.2.3", .expect_err = -EINVAL },
+ { 25, "foo", .expect_err = -EINVAL },
+ { 25, "1.foo", .expect_err = -EINVAL },
+ { 25, "1.foo", .expect_err = -EINVAL },
+ { 25, "12.-345", .expect_err = -EINVAL },
+ { 25, "-12.-345", .expect_err = -EINVAL },
+ { 25, "12.+345", .expect_err = -EINVAL },
+ { 25, "+12.+345", .expect_err = -EINVAL },
+ { 25, "", .expect_err = -EINVAL },
+ { 25, NULL, .expect_err = -EINVAL },
+};
+const char *errno_str(int rc)
+{
+ switch (rc) {
+ case -EINVAL:
+ return "=-EINVAL";
+ case -ERANGE:
+ return "=-ERANGE";
+ case -E2BIG:
+ return "=-E2BIG";
+ case -EOVERFLOW:
+ return "=-EOVERFLOW";
+ default:
+ return "";
+ }
+}
+void test_float_str_to_int(void)
+{
+ const struct float_str_to_int_test *t;
+ printf("--- %s\n", __func__);
+ for (t = float_str_to_int_tests; (t - float_str_to_int_tests) < ARRAY_SIZE(float_str_to_int_tests); t++) {
+ int rc;
+ int64_t val;
+ rc = osmo_float_str_to_int(&val, t->str, t->precision);
+ printf("osmo_float_str_to_int(%s, %u) -> rc=%d%s val=%" PRId64 "\n",
+ osmo_quote_str(t->str, -1), t->precision, rc, errno_str(rc), val);
+
+ if (rc != t->expect_err)
+ printf(" ERROR: expected rc=%d%s\n", t->expect_err, errno_str(t->expect_err));
+ if (val != t->expect_val)
+ printf(" ERROR: expected val=%" PRId64 "\n", t->expect_val);
+ if (rc != t->expect_err||val != t->expect_val)
+ exit(0);
+ }
+}
+
+struct int_to_float_str_test {
+ unsigned int precision;
+ int64_t val;
+ const char *expect_str;
+};
+struct int_to_float_str_test int_to_float_str_tests[] = {
+ { 0, 0, "0" },
+ { 0, 1, "1" },
+ { 0, 1000000, "1000000" },
+ { 0, -1000000, "-1000000" },
+ { 0, 1000001, "1000001" },
+ { 0, -1000001, "-1000001" },
+ { 0, 1000100, "1000100" },
+ { 0, -1010000, "-1010000" },
+ { 0, 1100000, "1100000" },
+ { 0, 10000000, "10000000" },
+ { 0, -10000000, "-10000000" },
+ { 0, 100000000, "100000000" },
+ { 0, -100000000, "-100000000" },
+ { 0, 9223372036854775807, "9223372036854775807" },
+ { 0, -9223372036854775807, "-9223372036854775807" },
+ { 0, INT64_MIN, "-ERR" },
+
+ { 1, 0, "0" },
+ { 1, 1, "0.1" },
+ { 1, 1000000, "100000" },
+ { 1, -1000000, "-100000" },
+ { 1, 1000001, "100000.1" },
+ { 1, -1000001, "-100000.1" },
+ { 1, 1000100, "100010" },
+ { 1, -1010000, "-101000" },
+ { 1, 1100000, "110000" },
+ { 1, 10000000, "1000000" },
+ { 1, -10000000, "-1000000" },
+ { 1, 100000000, "10000000" },
+ { 1, -100000000, "-10000000" },
+ { 1, 9223372036854775807, "922337203685477580.7" },
+ { 1, -9223372036854775807, "-922337203685477580.7" },
+ { 1, INT64_MIN, "-ERR" },
+
+ { 3, 0, "0" },
+ { 3, 1, "0.001" },
+ { 3, 1000000, "1000" },
+ { 3, -1000000, "-1000" },
+ { 3, 1000001, "1000.001" },
+ { 3, -1000001, "-1000.001" },
+ { 3, 1000100, "1000.1" },
+ { 3, -1010000, "-1010" },
+ { 3, 1100000, "1100" },
+ { 3, 10000000, "10000" },
+ { 3, -10000000, "-10000" },
+ { 3, 100000000, "100000" },
+ { 3, -100000000, "-100000" },
+ { 3, 9223372036854775807, "9223372036854775.807" },
+ { 3, -9223372036854775807, "-9223372036854775.807" },
+ { 3, INT64_MIN, "-ERR" },
+
+ { 6, 0, "0" },
+ { 6, 1, "0.000001" },
+ { 6, 1000000, "1" },
+ { 6, -1000000, "-1" },
+ { 6, 1000001, "1.000001" },
+ { 6, -1000001, "-1.000001" },
+ { 6, 1000100, "1.0001" },
+ { 6, -1010000, "-1.01" },
+ { 6, 1100000, "1.1" },
+ { 6, 10000000, "10" },
+ { 6, -10000000, "-10" },
+ { 6, 100000000, "100" },
+ { 6, -100000000, "-100" },
+ { 6, 9223372036854775807, "9223372036854.775807" },
+ { 6, -9223372036854775807, "-9223372036854.775807" },
+ { 6, INT64_MIN, "-ERR" },
+
+ { 17, 0, "0" },
+ { 17, 1, "0.00000000000000001" },
+ { 17, 1000000, "0.00000000001" },
+ { 17, -1000000, "-0.00000000001" },
+ { 17, 1000001, "0.00000000001000001" },
+ { 17, -1000001, "-0.00000000001000001" },
+ { 17, 1000100, "0.000000000010001" },
+ { 17, -1010000, "-0.0000000000101" },
+ { 17, 1100000, "0.000000000011" },
+ { 17, 10000000, "0.0000000001" },
+ { 17, -10000000, "-0.0000000001" },
+ { 17, 100000000, "0.000000001" },
+ { 17, -100000000, "-0.000000001" },
+ { 17, 9223372036854775807, "92.23372036854775807" },
+ { 17, -9223372036854775807, "-92.23372036854775807" },
+ { 17, INT64_MIN, "-ERR" },
+
+ { 18, 0, "0" },
+ { 18, 1, "0.000000000000000001" },
+ { 18, 1000000, "0.000000000001" },
+ { 18, -1000000, "-0.000000000001" },
+ { 18, 1000001, "0.000000000001000001" },
+ { 18, -1000001, "-0.000000000001000001" },
+ { 18, 1000100, "0.0000000000010001" },
+ { 18, -1010000, "-0.00000000000101" },
+ { 18, 1100000, "0.0000000000011" },
+ { 18, 10000000, "0.00000000001" },
+ { 18, -10000000, "-0.00000000001" },
+ { 18, 100000000, "0.0000000001" },
+ { 18, -100000000, "-0.0000000001" },
+ { 18, 9223372036854775807, "9.223372036854775807" },
+ { 18, -9223372036854775807, "-9.223372036854775807" },
+ { 18, INT64_MIN, "-ERR" },
+
+ { 19, 0, "0" },
+ { 19, 1, "0.0000000000000000001" },
+ { 19, 1000000, "0.0000000000001" },
+ { 19, -1000000, "-0.0000000000001" },
+ { 19, 1000001, "0.0000000000001000001" },
+ { 19, -1000001, "-0.0000000000001000001" },
+ { 19, 1000100, "0.00000000000010001" },
+ { 19, -1010000, "-0.000000000000101" },
+ { 19, 1100000, "0.00000000000011" },
+ { 19, 10000000, "0.000000000001" },
+ { 19, -10000000, "-0.000000000001" },
+ { 19, 100000000, "0.00000000001" },
+ { 19, -100000000, "-0.00000000001" },
+ { 19, 9223372036854775807, "0.9223372036854775807" },
+ { 19, -9223372036854775807, "-0.9223372036854775807" },
+ { 19, INT64_MIN, "-ERR" },
+
+ { 23, 0, "0" },
+ { 23, 1, "0.00000000000000000000001" },
+ { 23, 1000000, "0.00000000000000001" },
+ { 23, -1000000, "-0.00000000000000001" },
+ { 23, 1000001, "0.00000000000000001000001" },
+ { 23, -1000001, "-0.00000000000000001000001" },
+ { 23, 1000100, "0.000000000000000010001" },
+ { 23, -1010000, "-0.0000000000000000101" },
+ { 23, 1100000, "0.000000000000000011" },
+ { 23, 10000000, "0.0000000000000001" },
+ { 23, -10000000, "-0.0000000000000001" },
+ { 23, 100000000, "0.000000000000001" },
+ { 23, -100000000, "-0.000000000000001" },
+ { 23, 9223372036854775807, "0.00009223372036854775807" },
+ { 23, -9223372036854775807, "-0.00009223372036854775807" },
+ { 23, INT64_MIN, "-ERR" },
+};
+void test_int_to_float_str(void)
+{
+ const struct int_to_float_str_test *t;
+ printf("--- %s\n", __func__);
+ for (t = int_to_float_str_tests;
+ (t - int_to_float_str_tests) < ARRAY_SIZE(int_to_float_str_tests);
+ t++) {
+ char buf[128];
+ int rc;
+ rc = osmo_int_to_float_str_buf(buf, sizeof(buf), t->val, t->precision);
+ printf("osmo_int_to_float_str_buf(%" PRId64 ", %u) -> rc=%d str=%s\n", t->val, t->precision, rc,
+ osmo_quote_str(buf, -1));
+
+ if (rc != strlen(buf))
+ printf(" ERROR: expected rc=%zu\n", strlen(buf));
+ if (strcmp(buf, t->expect_str))
+ printf(" ERROR: expected str=%s\n", osmo_quote_str(t->expect_str, -1));
+ if (rc != strlen(buf) || strcmp(buf, t->expect_str))
+ exit(0);
+ }
+}
+
+struct str_to_int_test {
+ const char *str;
+ int base;
+ int min_val;
+ int max_val;
+ int expect_rc;
+ int expect_val;
+};
+/* Avoid using INT_MAX and INT_MIN because that would produce different test output on different architectures */
+struct str_to_int_test str_to_int_tests[] = {
+ { NULL, 10, -1000, 1000, -EINVAL, 0 },
+ { "", 10, -1000, 1000, -EINVAL, 0 },
+ { " ", 10, -1000, 1000, -EINVAL, 0 },
+ { "-", 10, -1000, 1000, -EINVAL, 0 },
+ { "--", 10, -1000, 1000, -EINVAL, 0 },
+ { "+", 10, -1000, 1000, -EINVAL, 0 },
+ { "++", 10, -1000, 1000, -EINVAL, 0 },
+
+ { "0", 10, -1000, 1000, 0, 0 },
+ { "1", 10, -1000, 1000, 0, 1 },
+ { "+1", 10, -1000, 1000, 0, 1 },
+ { "-1", 10, -1000, 1000, 0, -1 },
+ { "1000", 10, -1000, 1000, 0, 1000 },
+ { "+1000", 10, -1000, 1000, 0, 1000 },
+ { "-1000", 10, -1000, 1000, 0, -1000 },
+ { "1001", 10, -1000, 1000, -ERANGE, 1001 },
+ { "+1001", 10, -1000, 1000, -ERANGE, 1001 },
+ { "-1001", 10, -1000, 1000, -ERANGE, -1001 },
+
+ { "0", 16, -1000, 1000, 0, 0 },
+ { "1", 16, -1000, 1000, 0, 1 },
+ { "0x1", 16, -1000, 1000, 0, 1 },
+ { "+1", 16, -1000, 1000, 0, 1 },
+ { "-1", 16, -1000, 1000, 0, -1 },
+ { "+0x1", 16, -1000, 1000, 0, 1 },
+ { "-0x1", 16, -1000, 1000, 0, -1 },
+ { "3e8", 16, -1000, 1000, 0, 1000 },
+ { "3E8", 16, -1000, 1000, 0, 1000 },
+ { "0x3e8", 16, -1000, 1000, 0, 1000 },
+ { "0x3E8", 16, -1000, 1000, 0, 1000 },
+ { "+3e8", 16, -1000, 1000, 0, 1000 },
+ { "+3E8", 16, -1000, 1000, 0, 1000 },
+ { "+0x3e8", 16, -1000, 1000, 0, 1000 },
+ { "+0x3E8", 16, -1000, 1000, 0, 1000 },
+ { "-3e8", 16, -1000, 1000, 0, -1000 },
+ { "-3E8", 16, -1000, 1000, 0, -1000 },
+ { "-0x3e8", 16, -1000, 1000, 0, -1000 },
+ { "-0x3E8", 16, -1000, 1000, 0, -1000 },
+ { "3e9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "3E9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "0x3e9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "0x3E9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "+3e9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "+3E9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "+0x3e9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "+0x3E9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "-3e9", 16, -1000, 1000, -ERANGE, -1001 },
+ { "-3E9", 16, -1000, 1000, -ERANGE, -1001 },
+ { "-0x3e9", 16, -1000, 1000, -ERANGE, -1001 },
+ { "-0x3E9", 16, -1000, 1000, -ERANGE, -1001 },
+
+ { "garble", 10, -1000, 1000, -EINVAL, 0 },
+ { "-garble", 10, -1000, 1000, -EINVAL, 0 },
+ { "0x123", 10, -1000, 1000, -E2BIG, 0 },
+ { "123potatoes", 10, -1000, 1000, -E2BIG, 123 },
+ { "123 potatoes", 10, -1000, 1000, -E2BIG, 123 },
+ { "123 ", 10, -1000, 1000, -E2BIG, 123 },
+ { "123.4", 10, -1000, 1000, -E2BIG, 123 },
+};
+void test_str_to_int(void)
+{
+ const struct str_to_int_test *t;
+ printf("--- %s\n", __func__);
+ for (t = str_to_int_tests; (t - str_to_int_tests) < ARRAY_SIZE(str_to_int_tests); t++) {
+ int rc;
+ int val;
+ rc = osmo_str_to_int(&val, t->str, t->base, t->min_val, t->max_val);
+ printf("osmo_str_to_int(%s, %d, %d, %d) -> rc=%d%s val=%d\n",
+ osmo_quote_str(t->str, -1), t->base, t->min_val, t->max_val, rc, errno_str(rc), val);
+
+ if (rc != t->expect_rc)
+ printf(" ERROR: expected rc=%d%s\n", t->expect_rc, errno_str(t->expect_rc));
+ if (val != t->expect_val)
+ printf(" ERROR: expected val=%d\n", t->expect_val);
+ }
+}
+
+struct str_to_int64_test {
+ const char *str;
+ int base;
+ int64_t min_val;
+ int64_t max_val;
+ int expect_rc;
+ int64_t expect_val;
+};
+struct str_to_int64_test str_to_int64_tests[] = {
+ { NULL, 10, -1000, 1000, -EINVAL, 0 },
+ { "", 10, -1000, 1000, -EINVAL, 0 },
+ { " ", 10, -1000, 1000, -EINVAL, 0 },
+ { "-", 10, -1000, 1000, -EINVAL, 0 },
+ { "--", 10, -1000, 1000, -EINVAL, 0 },
+ { "+", 10, -1000, 1000, -EINVAL, 0 },
+ { "++", 10, -1000, 1000, -EINVAL, 0 },
+
+ { "0", 10, -1000, 1000, 0, 0 },
+ { "1", 10, -1000, 1000, 0, 1 },
+ { "+1", 10, -1000, 1000, 0, 1 },
+ { "-1", 10, -1000, 1000, 0, -1 },
+ { "1000", 10, -1000, 1000, 0, 1000 },
+ { "+1000", 10, -1000, 1000, 0, 1000 },
+ { "-1000", 10, -1000, 1000, 0, -1000 },
+ { "1001", 10, -1000, 1000, -ERANGE, 1001 },
+ { "+1001", 10, -1000, 1000, -ERANGE, 1001 },
+ { "-1001", 10, -1000, 1000, -ERANGE, -1001 },
+
+ { "0", 16, -1000, 1000, 0, 0 },
+ { "1", 16, -1000, 1000, 0, 1 },
+ { "0x1", 16, -1000, 1000, 0, 1 },
+ { "+1", 16, -1000, 1000, 0, 1 },
+ { "-1", 16, -1000, 1000, 0, -1 },
+ { "+0x1", 16, -1000, 1000, 0, 1 },
+ { "-0x1", 16, -1000, 1000, 0, -1 },
+ { "3e8", 16, -1000, 1000, 0, 1000 },
+ { "3E8", 16, -1000, 1000, 0, 1000 },
+ { "0x3e8", 16, -1000, 1000, 0, 1000 },
+ { "0x3E8", 16, -1000, 1000, 0, 1000 },
+ { "+3e8", 16, -1000, 1000, 0, 1000 },
+ { "+3E8", 16, -1000, 1000, 0, 1000 },
+ { "+0x3e8", 16, -1000, 1000, 0, 1000 },
+ { "+0x3E8", 16, -1000, 1000, 0, 1000 },
+ { "-3e8", 16, -1000, 1000, 0, -1000 },
+ { "-3E8", 16, -1000, 1000, 0, -1000 },
+ { "-0x3e8", 16, -1000, 1000, 0, -1000 },
+ { "-0x3E8", 16, -1000, 1000, 0, -1000 },
+ { "3e9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "3E9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "0x3e9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "0x3E9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "+3e9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "+3E9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "+0x3e9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "+0x3E9", 16, -1000, 1000, -ERANGE, 1001 },
+ { "-3e9", 16, -1000, 1000, -ERANGE, -1001 },
+ { "-3E9", 16, -1000, 1000, -ERANGE, -1001 },
+ { "-0x3e9", 16, -1000, 1000, -ERANGE, -1001 },
+ { "-0x3E9", 16, -1000, 1000, -ERANGE, -1001 },
+
+ { "garble", 10, -1000, 1000, -EINVAL, 0 },
+ { "-garble", 10, -1000, 1000, -EINVAL, 0 },
+ { "0x123", 10, -1000, 1000, -E2BIG, 0 },
+ { "123potatoes", 10, -1000, 1000, -E2BIG, 123 },
+ { "123 potatoes", 10, -1000, 1000, -E2BIG, 123 },
+ { "123 ", 10, -1000, 1000, -E2BIG, 123 },
+ { "123.4", 10, -1000, 1000, -E2BIG, 123 },
+
+ { "-9223372036854775808", 10, INT64_MIN, INT64_MAX, 0, INT64_MIN },
+ { "9223372036854775807", 10, INT64_MIN, INT64_MAX, 0, INT64_MAX },
+
+ { "-9223372036854775809", 10, INT64_MIN, INT64_MAX, -EOVERFLOW, INT64_MIN },
+ { "9223372036854775808", 10, INT64_MIN, INT64_MAX, -EOVERFLOW, INT64_MAX },
+
+ { "-9223372036854775808", 10, -1000, 1000, -ERANGE, INT64_MIN },
+ { "9223372036854775807", 10, -1000, 1000, -ERANGE, INT64_MAX },
+ { "-9223372036854775809", 10, -1000, 1000, -EOVERFLOW, INT64_MIN },
+ { "9223372036854775808", 10, -1000, 1000, -EOVERFLOW, INT64_MAX },
+};
+void test_str_to_int64(void)
+{
+ const struct str_to_int64_test *t;
+ printf("--- %s\n", __func__);
+ for (t = str_to_int64_tests; (t - str_to_int64_tests) < ARRAY_SIZE(str_to_int64_tests); t++) {
+ int rc;
+ int64_t val;
+ rc = osmo_str_to_int64(&val, t->str, t->base, t->min_val, t->max_val);
+ printf("osmo_str_to_int64(%s, %d, %"PRId64", %"PRId64") -> rc=%d%s val=%"PRId64"\n",
+ osmo_quote_str(t->str, -1), t->base, t->min_val, t->max_val, rc, errno_str(rc), val);
+
+ if (rc != t->expect_rc)
+ printf(" ERROR: expected rc=%d%s\n", t->expect_rc, errno_str(t->expect_rc));
+ if (val != t->expect_val)
+ printf(" ERROR: expected val=%"PRId64"\n", t->expect_val);
+ }
+}
+
int main(int argc, char **argv)
{
static const struct log_info log_info = {};
@@ -1460,6 +2147,7 @@ int main(int argc, char **argv)
str_escape3_test();
str_quote3_test();
isqrt_test();
+ mod_test();
osmo_sockaddr_to_str_and_uint_test();
osmo_str_tolowupper_test();
strbuf_test();
@@ -1468,5 +2156,9 @@ int main(int argc, char **argv)
name_c_impl_test();
osmo_print_n_test();
osmo_strnchr_test();
+ test_float_str_to_int();
+ test_int_to_float_str();
+ test_str_to_int();
+ test_str_to_int64();
return 0;
}
diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok
index f1b07fa8..3f453e95 100644
--- a/tests/utils/utils_test.ok
+++ b/tests/utils/utils_test.ok
@@ -354,6 +354,36 @@ strcmp("NULL", osmo_quote_cstr_c(ctx, NULL, -1)) == 0
Testing integer square-root
+Testing built in truncated modulo for comparison:
+ 8 mod 3 = 2 = 2
+ 8 mod -3 = 2 = 2
+ -8 mod 3 = -2 = -2
+ -8 mod -3 = -2 = -2
+ 1 mod 2 = 1 = 1
+ 1 mod -2 = 1 = 1
+ -1 mod 2 = -1 = -1
+ -1 mod -2 = -1 = -1
+
+Testing OSMO_MOD_FLR():
+ 8 mod_flr 3 = 2 = 2
+ 8 mod_flr -3 = -1 = -1
+ -8 mod_flr 3 = 1 = 1
+ -8 mod_flr -3 = -2 = -2
+ 1 mod_flr 2 = 1 = 1
+ 1 mod_flr -2 = -1 = -1
+ -1 mod_flr 2 = 1 = 1
+ -1 mod_flr -2 = -1 = -1
+
+Testing OSMO_MOD_EUC():
+ 8 mod_euc 3 = 2 = 2
+ 8 mod_euc -3 = 2 = 2
+ -8 mod_euc 3 = 1 = 1
+ -8 mod_euc -3 = 1 = 1
+ 1 mod_euc 2 = 1 = 1
+ 1 mod_euc -2 = 1 = 1
+ -1 mod_euc 2 = 1 = 1
+ -1 mod_euc -2 = 1 = 1
+
osmo_sockaddr_to_str_and_uint_test
[0] [0.0.0.0]:0 addr_len=20 --> [0.0.0.0]:0 rc=7
[1] [255.255.255.255]:65535 addr_len=20 --> [255.255.255.255]:65535 rc=15
@@ -505,3 +535,487 @@ osmo_strnchr("foo=bar", 3, '=') -> -1
osmo_strnchr("foo=bar", 0, '=') -> -1
osmo_strnchr("foo", 9, '=') -> -1
osmo_strnchr("foo", 9, '\0') -> 3
+--- test_float_str_to_int
+osmo_float_str_to_int("0", 0) -> rc=0 val=0
+osmo_float_str_to_int("1", 0) -> rc=0 val=1
+osmo_float_str_to_int("12.345", 0) -> rc=0 val=12
+osmo_float_str_to_int("+12.345", 0) -> rc=0 val=12
+osmo_float_str_to_int("-12.345", 0) -> rc=0 val=-12
+osmo_float_str_to_int("0.345", 0) -> rc=0 val=0
+osmo_float_str_to_int(".345", 0) -> rc=0 val=0
+osmo_float_str_to_int("-0.345", 0) -> rc=0 val=0
+osmo_float_str_to_int("-.345", 0) -> rc=0 val=0
+osmo_float_str_to_int("12.", 0) -> rc=0 val=12
+osmo_float_str_to_int("-180", 0) -> rc=0 val=-180
+osmo_float_str_to_int("180", 0) -> rc=0 val=180
+osmo_float_str_to_int("360", 0) -> rc=0 val=360
+osmo_float_str_to_int("123.4567890123", 0) -> rc=0 val=123
+osmo_float_str_to_int("123.4567890123456789012345", 0) -> rc=0 val=123
+osmo_float_str_to_int("9223372036854775807", 0) -> rc=0 val=9223372036854775807
+osmo_float_str_to_int("-9223372036854775807", 0) -> rc=0 val=-9223372036854775807
+osmo_float_str_to_int("-9223372036854775808", 0) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("9223372036854775808", 0) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-9223372036854775809", 0) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("100000000000000000000", 0) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-100000000000000000000", 0) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("999999999999999999999999999.99", 0) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-999999999999999999999999999.99", 0) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("1.2.3", 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("foo", 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.-345", 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("-12.-345", 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.+345", 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("+12.+345", 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("", 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int(NULL, 0) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("0", 1) -> rc=0 val=0
+osmo_float_str_to_int("1", 1) -> rc=0 val=10
+osmo_float_str_to_int("12.345", 1) -> rc=0 val=123
+osmo_float_str_to_int("+12.345", 1) -> rc=0 val=123
+osmo_float_str_to_int("-12.345", 1) -> rc=0 val=-123
+osmo_float_str_to_int("0.345", 1) -> rc=0 val=3
+osmo_float_str_to_int(".345", 1) -> rc=0 val=3
+osmo_float_str_to_int("-0.345", 1) -> rc=0 val=-3
+osmo_float_str_to_int("-.345", 1) -> rc=0 val=-3
+osmo_float_str_to_int("12.", 1) -> rc=0 val=120
+osmo_float_str_to_int("-180", 1) -> rc=0 val=-1800
+osmo_float_str_to_int("180", 1) -> rc=0 val=1800
+osmo_float_str_to_int("360", 1) -> rc=0 val=3600
+osmo_float_str_to_int("123.4567890123", 1) -> rc=0 val=1234
+osmo_float_str_to_int("123.4567890123456789012345", 1) -> rc=0 val=1234
+osmo_float_str_to_int("922337203685477580.7", 1) -> rc=0 val=9223372036854775807
+osmo_float_str_to_int("-922337203685477580.7", 1) -> rc=0 val=-9223372036854775807
+osmo_float_str_to_int("-922337203685477580.8", 1) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("922337203685477580.8", 1) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-922337203685477580.9", 1) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("100000000000000000000", 1) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-100000000000000000000", 1) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("999999999999999999999999999.99", 1) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-999999999999999999999999999.99", 1) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("1.2.3", 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("foo", 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.-345", 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("-12.-345", 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.+345", 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("+12.+345", 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("", 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int(NULL, 1) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("0", 6) -> rc=0 val=0
+osmo_float_str_to_int("1", 6) -> rc=0 val=1000000
+osmo_float_str_to_int("12.345", 6) -> rc=0 val=12345000
+osmo_float_str_to_int("+12.345", 6) -> rc=0 val=12345000
+osmo_float_str_to_int("-12.345", 6) -> rc=0 val=-12345000
+osmo_float_str_to_int("0.345", 6) -> rc=0 val=345000
+osmo_float_str_to_int(".345", 6) -> rc=0 val=345000
+osmo_float_str_to_int("-0.345", 6) -> rc=0 val=-345000
+osmo_float_str_to_int("-.345", 6) -> rc=0 val=-345000
+osmo_float_str_to_int("12.", 6) -> rc=0 val=12000000
+osmo_float_str_to_int("-180", 6) -> rc=0 val=-180000000
+osmo_float_str_to_int("180", 6) -> rc=0 val=180000000
+osmo_float_str_to_int("360", 6) -> rc=0 val=360000000
+osmo_float_str_to_int("123.4567890123", 6) -> rc=0 val=123456789
+osmo_float_str_to_int("123.4567890123456789012345", 6) -> rc=0 val=123456789
+osmo_float_str_to_int("9223372036854.775807", 6) -> rc=0 val=9223372036854775807
+osmo_float_str_to_int("-9223372036854.775807", 6) -> rc=0 val=-9223372036854775807
+osmo_float_str_to_int("-9223372036854.775808", 6) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("9223372036854.775808", 6) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-9223372036854.775809", 6) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("100000000000000000000", 6) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-100000000000000000000", 6) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("999999999999999999999999999.99", 6) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-999999999999999999999999999.99", 6) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("1.2.3", 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("foo", 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.-345", 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("-12.-345", 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.+345", 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("+12.+345", 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("", 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int(NULL, 6) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("0", 18) -> rc=0 val=0
+osmo_float_str_to_int("1", 18) -> rc=0 val=1000000000000000000
+osmo_float_str_to_int("1.2345", 18) -> rc=0 val=1234500000000000000
+osmo_float_str_to_int("+1.2345", 18) -> rc=0 val=1234500000000000000
+osmo_float_str_to_int("-1.2345", 18) -> rc=0 val=-1234500000000000000
+osmo_float_str_to_int("0.345", 18) -> rc=0 val=345000000000000000
+osmo_float_str_to_int(".345", 18) -> rc=0 val=345000000000000000
+osmo_float_str_to_int("-0.345", 18) -> rc=0 val=-345000000000000000
+osmo_float_str_to_int("-.345", 18) -> rc=0 val=-345000000000000000
+osmo_float_str_to_int("2.", 18) -> rc=0 val=2000000000000000000
+osmo_float_str_to_int("-8", 18) -> rc=0 val=-8000000000000000000
+osmo_float_str_to_int("1.234567890123", 18) -> rc=0 val=1234567890123000000
+osmo_float_str_to_int("1.234567890123456789012345", 18) -> rc=0 val=1234567890123456789
+osmo_float_str_to_int("123.4567890123", 18) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("9.223372036854775807", 18) -> rc=0 val=9223372036854775807
+osmo_float_str_to_int("-9.223372036854775807", 18) -> rc=0 val=-9223372036854775807
+osmo_float_str_to_int("-9.223372036854775808", 18) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("9.223372036854775808", 18) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-9.223372036854775809", 18) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("100000000000000000000", 18) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-100000000000000000000", 18) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("999999999999999999999999999.99", 18) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-999999999999999999999999999.99", 18) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("1.2.3", 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("foo", 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.-345", 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("-12.-345", 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.+345", 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("+12.+345", 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("", 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int(NULL, 18) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("0", 19) -> rc=0 val=0
+osmo_float_str_to_int(".1", 19) -> rc=0 val=1000000000000000000
+osmo_float_str_to_int(".12345", 19) -> rc=0 val=1234500000000000000
+osmo_float_str_to_int("+.12345", 19) -> rc=0 val=1234500000000000000
+osmo_float_str_to_int("-.12345", 19) -> rc=0 val=-1234500000000000000
+osmo_float_str_to_int("0.0345", 19) -> rc=0 val=345000000000000000
+osmo_float_str_to_int(".0345", 19) -> rc=0 val=345000000000000000
+osmo_float_str_to_int("-0.0345", 19) -> rc=0 val=-345000000000000000
+osmo_float_str_to_int("-.0345", 19) -> rc=0 val=-345000000000000000
+osmo_float_str_to_int(".2", 19) -> rc=0 val=2000000000000000000
+osmo_float_str_to_int("-.8", 19) -> rc=0 val=-8000000000000000000
+osmo_float_str_to_int(".1234567890123", 19) -> rc=0 val=1234567890123000000
+osmo_float_str_to_int(".1234567890123456789012345", 19) -> rc=0 val=1234567890123456789
+osmo_float_str_to_int("123.4567890123", 19) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int(".9223372036854775807", 19) -> rc=0 val=9223372036854775807
+osmo_float_str_to_int("-.9223372036854775807", 19) -> rc=0 val=-9223372036854775807
+osmo_float_str_to_int("-.9223372036854775808", 19) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int(".9223372036854775808", 19) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-.9223372036854775809", 19) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("100000000000000000000", 19) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-100000000000000000000", 19) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("999999999999999999999999999.99", 19) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-999999999999999999999999999.99", 19) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("1.2.3", 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("foo", 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.-345", 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("-12.-345", 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.+345", 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("+12.+345", 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("", 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int(NULL, 19) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("0", 20) -> rc=0 val=0
+osmo_float_str_to_int(".01", 20) -> rc=0 val=1000000000000000000
+osmo_float_str_to_int(".012345", 20) -> rc=0 val=1234500000000000000
+osmo_float_str_to_int("+.012345", 20) -> rc=0 val=1234500000000000000
+osmo_float_str_to_int("-.012345", 20) -> rc=0 val=-1234500000000000000
+osmo_float_str_to_int("0.00345", 20) -> rc=0 val=345000000000000000
+osmo_float_str_to_int(".00345", 20) -> rc=0 val=345000000000000000
+osmo_float_str_to_int("-0.00345", 20) -> rc=0 val=-345000000000000000
+osmo_float_str_to_int("-.00345", 20) -> rc=0 val=-345000000000000000
+osmo_float_str_to_int(".02", 20) -> rc=0 val=2000000000000000000
+osmo_float_str_to_int("-.08", 20) -> rc=0 val=-8000000000000000000
+osmo_float_str_to_int(".01234567890123", 20) -> rc=0 val=1234567890123000000
+osmo_float_str_to_int(".01234567890123456789012345", 20) -> rc=0 val=1234567890123456789
+osmo_float_str_to_int("12.34567890123", 20) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int(".09223372036854775807", 20) -> rc=0 val=9223372036854775807
+osmo_float_str_to_int("-.09223372036854775807", 20) -> rc=0 val=-9223372036854775807
+osmo_float_str_to_int("-.09223372036854775808", 20) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int(".09223372036854775808", 20) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-.09223372036854775809", 20) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int(".1", 20) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-.1", 20) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("999999999999999999999999999.99", 20) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-999999999999999999999999999.99", 20) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("1.2.3", 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("foo", 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.-345", 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("-12.-345", 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.+345", 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("+12.+345", 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("", 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int(NULL, 20) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("0", 25) -> rc=0 val=0
+osmo_float_str_to_int(".0000001", 25) -> rc=0 val=1000000000000000000
+osmo_float_str_to_int(".00000012345", 25) -> rc=0 val=1234500000000000000
+osmo_float_str_to_int("+.00000012345", 25) -> rc=0 val=1234500000000000000
+osmo_float_str_to_int("-.00000012345", 25) -> rc=0 val=-1234500000000000000
+osmo_float_str_to_int("0.0000000345", 25) -> rc=0 val=345000000000000000
+osmo_float_str_to_int(".0000000345", 25) -> rc=0 val=345000000000000000
+osmo_float_str_to_int("-0.0000000345", 25) -> rc=0 val=-345000000000000000
+osmo_float_str_to_int("-.0000000345", 25) -> rc=0 val=-345000000000000000
+osmo_float_str_to_int(".0000002", 25) -> rc=0 val=2000000000000000000
+osmo_float_str_to_int("-.0000008", 25) -> rc=0 val=-8000000000000000000
+osmo_float_str_to_int(".0000001234567890123", 25) -> rc=0 val=1234567890123000000
+osmo_float_str_to_int(".0000001234567890123456789012345", 25) -> rc=0 val=1234567890123456789
+osmo_float_str_to_int(".0001234567890123", 25) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int(".0000009223372036854775807", 25) -> rc=0 val=9223372036854775807
+osmo_float_str_to_int("-.0000009223372036854775807", 25) -> rc=0 val=-9223372036854775807
+osmo_float_str_to_int("-.0000009223372036854775808", 25) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int(".0000009223372036854775808", 25) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-.0000009223372036854775809", 25) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int(".000001", 25) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-.000001", 25) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("999999999999999999999999999.99", 25) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("-999999999999999999999999999.99", 25) -> rc=-34=-ERANGE val=0
+osmo_float_str_to_int("1.2.3", 25) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("foo", 25) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 25) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("1.foo", 25) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.-345", 25) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("-12.-345", 25) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("12.+345", 25) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("+12.+345", 25) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int("", 25) -> rc=-22=-EINVAL val=0
+osmo_float_str_to_int(NULL, 25) -> rc=-22=-EINVAL val=0
+--- test_int_to_float_str
+osmo_int_to_float_str_buf(0, 0) -> rc=1 str="0"
+osmo_int_to_float_str_buf(1, 0) -> rc=1 str="1"
+osmo_int_to_float_str_buf(1000000, 0) -> rc=7 str="1000000"
+osmo_int_to_float_str_buf(-1000000, 0) -> rc=8 str="-1000000"
+osmo_int_to_float_str_buf(1000001, 0) -> rc=7 str="1000001"
+osmo_int_to_float_str_buf(-1000001, 0) -> rc=8 str="-1000001"
+osmo_int_to_float_str_buf(1000100, 0) -> rc=7 str="1000100"
+osmo_int_to_float_str_buf(-1010000, 0) -> rc=8 str="-1010000"
+osmo_int_to_float_str_buf(1100000, 0) -> rc=7 str="1100000"
+osmo_int_to_float_str_buf(10000000, 0) -> rc=8 str="10000000"
+osmo_int_to_float_str_buf(-10000000, 0) -> rc=9 str="-10000000"
+osmo_int_to_float_str_buf(100000000, 0) -> rc=9 str="100000000"
+osmo_int_to_float_str_buf(-100000000, 0) -> rc=10 str="-100000000"
+osmo_int_to_float_str_buf(9223372036854775807, 0) -> rc=19 str="9223372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775807, 0) -> rc=20 str="-9223372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775808, 0) -> rc=4 str="-ERR"
+osmo_int_to_float_str_buf(0, 1) -> rc=1 str="0"
+osmo_int_to_float_str_buf(1, 1) -> rc=3 str="0.1"
+osmo_int_to_float_str_buf(1000000, 1) -> rc=6 str="100000"
+osmo_int_to_float_str_buf(-1000000, 1) -> rc=7 str="-100000"
+osmo_int_to_float_str_buf(1000001, 1) -> rc=8 str="100000.1"
+osmo_int_to_float_str_buf(-1000001, 1) -> rc=9 str="-100000.1"
+osmo_int_to_float_str_buf(1000100, 1) -> rc=6 str="100010"
+osmo_int_to_float_str_buf(-1010000, 1) -> rc=7 str="-101000"
+osmo_int_to_float_str_buf(1100000, 1) -> rc=6 str="110000"
+osmo_int_to_float_str_buf(10000000, 1) -> rc=7 str="1000000"
+osmo_int_to_float_str_buf(-10000000, 1) -> rc=8 str="-1000000"
+osmo_int_to_float_str_buf(100000000, 1) -> rc=8 str="10000000"
+osmo_int_to_float_str_buf(-100000000, 1) -> rc=9 str="-10000000"
+osmo_int_to_float_str_buf(9223372036854775807, 1) -> rc=20 str="922337203685477580.7"
+osmo_int_to_float_str_buf(-9223372036854775807, 1) -> rc=21 str="-922337203685477580.7"
+osmo_int_to_float_str_buf(-9223372036854775808, 1) -> rc=4 str="-ERR"
+osmo_int_to_float_str_buf(0, 3) -> rc=1 str="0"
+osmo_int_to_float_str_buf(1, 3) -> rc=5 str="0.001"
+osmo_int_to_float_str_buf(1000000, 3) -> rc=4 str="1000"
+osmo_int_to_float_str_buf(-1000000, 3) -> rc=5 str="-1000"
+osmo_int_to_float_str_buf(1000001, 3) -> rc=8 str="1000.001"
+osmo_int_to_float_str_buf(-1000001, 3) -> rc=9 str="-1000.001"
+osmo_int_to_float_str_buf(1000100, 3) -> rc=6 str="1000.1"
+osmo_int_to_float_str_buf(-1010000, 3) -> rc=5 str="-1010"
+osmo_int_to_float_str_buf(1100000, 3) -> rc=4 str="1100"
+osmo_int_to_float_str_buf(10000000, 3) -> rc=5 str="10000"
+osmo_int_to_float_str_buf(-10000000, 3) -> rc=6 str="-10000"
+osmo_int_to_float_str_buf(100000000, 3) -> rc=6 str="100000"
+osmo_int_to_float_str_buf(-100000000, 3) -> rc=7 str="-100000"
+osmo_int_to_float_str_buf(9223372036854775807, 3) -> rc=20 str="9223372036854775.807"
+osmo_int_to_float_str_buf(-9223372036854775807, 3) -> rc=21 str="-9223372036854775.807"
+osmo_int_to_float_str_buf(-9223372036854775808, 3) -> rc=4 str="-ERR"
+osmo_int_to_float_str_buf(0, 6) -> rc=1 str="0"
+osmo_int_to_float_str_buf(1, 6) -> rc=8 str="0.000001"
+osmo_int_to_float_str_buf(1000000, 6) -> rc=1 str="1"
+osmo_int_to_float_str_buf(-1000000, 6) -> rc=2 str="-1"
+osmo_int_to_float_str_buf(1000001, 6) -> rc=8 str="1.000001"
+osmo_int_to_float_str_buf(-1000001, 6) -> rc=9 str="-1.000001"
+osmo_int_to_float_str_buf(1000100, 6) -> rc=6 str="1.0001"
+osmo_int_to_float_str_buf(-1010000, 6) -> rc=5 str="-1.01"
+osmo_int_to_float_str_buf(1100000, 6) -> rc=3 str="1.1"
+osmo_int_to_float_str_buf(10000000, 6) -> rc=2 str="10"
+osmo_int_to_float_str_buf(-10000000, 6) -> rc=3 str="-10"
+osmo_int_to_float_str_buf(100000000, 6) -> rc=3 str="100"
+osmo_int_to_float_str_buf(-100000000, 6) -> rc=4 str="-100"
+osmo_int_to_float_str_buf(9223372036854775807, 6) -> rc=20 str="9223372036854.775807"
+osmo_int_to_float_str_buf(-9223372036854775807, 6) -> rc=21 str="-9223372036854.775807"
+osmo_int_to_float_str_buf(-9223372036854775808, 6) -> rc=4 str="-ERR"
+osmo_int_to_float_str_buf(0, 17) -> rc=1 str="0"
+osmo_int_to_float_str_buf(1, 17) -> rc=19 str="0.00000000000000001"
+osmo_int_to_float_str_buf(1000000, 17) -> rc=13 str="0.00000000001"
+osmo_int_to_float_str_buf(-1000000, 17) -> rc=14 str="-0.00000000001"
+osmo_int_to_float_str_buf(1000001, 17) -> rc=19 str="0.00000000001000001"
+osmo_int_to_float_str_buf(-1000001, 17) -> rc=20 str="-0.00000000001000001"
+osmo_int_to_float_str_buf(1000100, 17) -> rc=17 str="0.000000000010001"
+osmo_int_to_float_str_buf(-1010000, 17) -> rc=16 str="-0.0000000000101"
+osmo_int_to_float_str_buf(1100000, 17) -> rc=14 str="0.000000000011"
+osmo_int_to_float_str_buf(10000000, 17) -> rc=12 str="0.0000000001"
+osmo_int_to_float_str_buf(-10000000, 17) -> rc=13 str="-0.0000000001"
+osmo_int_to_float_str_buf(100000000, 17) -> rc=11 str="0.000000001"
+osmo_int_to_float_str_buf(-100000000, 17) -> rc=12 str="-0.000000001"
+osmo_int_to_float_str_buf(9223372036854775807, 17) -> rc=20 str="92.23372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775807, 17) -> rc=21 str="-92.23372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775808, 17) -> rc=4 str="-ERR"
+osmo_int_to_float_str_buf(0, 18) -> rc=1 str="0"
+osmo_int_to_float_str_buf(1, 18) -> rc=20 str="0.000000000000000001"
+osmo_int_to_float_str_buf(1000000, 18) -> rc=14 str="0.000000000001"
+osmo_int_to_float_str_buf(-1000000, 18) -> rc=15 str="-0.000000000001"
+osmo_int_to_float_str_buf(1000001, 18) -> rc=20 str="0.000000000001000001"
+osmo_int_to_float_str_buf(-1000001, 18) -> rc=21 str="-0.000000000001000001"
+osmo_int_to_float_str_buf(1000100, 18) -> rc=18 str="0.0000000000010001"
+osmo_int_to_float_str_buf(-1010000, 18) -> rc=17 str="-0.00000000000101"
+osmo_int_to_float_str_buf(1100000, 18) -> rc=15 str="0.0000000000011"
+osmo_int_to_float_str_buf(10000000, 18) -> rc=13 str="0.00000000001"
+osmo_int_to_float_str_buf(-10000000, 18) -> rc=14 str="-0.00000000001"
+osmo_int_to_float_str_buf(100000000, 18) -> rc=12 str="0.0000000001"
+osmo_int_to_float_str_buf(-100000000, 18) -> rc=13 str="-0.0000000001"
+osmo_int_to_float_str_buf(9223372036854775807, 18) -> rc=20 str="9.223372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775807, 18) -> rc=21 str="-9.223372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775808, 18) -> rc=4 str="-ERR"
+osmo_int_to_float_str_buf(0, 19) -> rc=1 str="0"
+osmo_int_to_float_str_buf(1, 19) -> rc=21 str="0.0000000000000000001"
+osmo_int_to_float_str_buf(1000000, 19) -> rc=15 str="0.0000000000001"
+osmo_int_to_float_str_buf(-1000000, 19) -> rc=16 str="-0.0000000000001"
+osmo_int_to_float_str_buf(1000001, 19) -> rc=21 str="0.0000000000001000001"
+osmo_int_to_float_str_buf(-1000001, 19) -> rc=22 str="-0.0000000000001000001"
+osmo_int_to_float_str_buf(1000100, 19) -> rc=19 str="0.00000000000010001"
+osmo_int_to_float_str_buf(-1010000, 19) -> rc=18 str="-0.000000000000101"
+osmo_int_to_float_str_buf(1100000, 19) -> rc=16 str="0.00000000000011"
+osmo_int_to_float_str_buf(10000000, 19) -> rc=14 str="0.000000000001"
+osmo_int_to_float_str_buf(-10000000, 19) -> rc=15 str="-0.000000000001"
+osmo_int_to_float_str_buf(100000000, 19) -> rc=13 str="0.00000000001"
+osmo_int_to_float_str_buf(-100000000, 19) -> rc=14 str="-0.00000000001"
+osmo_int_to_float_str_buf(9223372036854775807, 19) -> rc=21 str="0.9223372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775807, 19) -> rc=22 str="-0.9223372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775808, 19) -> rc=4 str="-ERR"
+osmo_int_to_float_str_buf(0, 23) -> rc=1 str="0"
+osmo_int_to_float_str_buf(1, 23) -> rc=25 str="0.00000000000000000000001"
+osmo_int_to_float_str_buf(1000000, 23) -> rc=19 str="0.00000000000000001"
+osmo_int_to_float_str_buf(-1000000, 23) -> rc=20 str="-0.00000000000000001"
+osmo_int_to_float_str_buf(1000001, 23) -> rc=25 str="0.00000000000000001000001"
+osmo_int_to_float_str_buf(-1000001, 23) -> rc=26 str="-0.00000000000000001000001"
+osmo_int_to_float_str_buf(1000100, 23) -> rc=23 str="0.000000000000000010001"
+osmo_int_to_float_str_buf(-1010000, 23) -> rc=22 str="-0.0000000000000000101"
+osmo_int_to_float_str_buf(1100000, 23) -> rc=20 str="0.000000000000000011"
+osmo_int_to_float_str_buf(10000000, 23) -> rc=18 str="0.0000000000000001"
+osmo_int_to_float_str_buf(-10000000, 23) -> rc=19 str="-0.0000000000000001"
+osmo_int_to_float_str_buf(100000000, 23) -> rc=17 str="0.000000000000001"
+osmo_int_to_float_str_buf(-100000000, 23) -> rc=18 str="-0.000000000000001"
+osmo_int_to_float_str_buf(9223372036854775807, 23) -> rc=25 str="0.00009223372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775807, 23) -> rc=26 str="-0.00009223372036854775807"
+osmo_int_to_float_str_buf(-9223372036854775808, 23) -> rc=4 str="-ERR"
+--- test_str_to_int
+osmo_str_to_int(NULL, 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int("", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int(" ", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int("-", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int("--", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int("+", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int("++", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int("0", 10, -1000, 1000) -> rc=0 val=0
+osmo_str_to_int("1", 10, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int("+1", 10, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int("-1", 10, -1000, 1000) -> rc=0 val=-1
+osmo_str_to_int("1000", 10, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("+1000", 10, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("-1000", 10, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int("1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("+1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("-1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int("0", 16, -1000, 1000) -> rc=0 val=0
+osmo_str_to_int("1", 16, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int("0x1", 16, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int("+1", 16, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int("-1", 16, -1000, 1000) -> rc=0 val=-1
+osmo_str_to_int("+0x1", 16, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int("-0x1", 16, -1000, 1000) -> rc=0 val=-1
+osmo_str_to_int("3e8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("3E8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("0x3e8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("0x3E8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("+3e8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("+3E8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("+0x3e8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("+0x3E8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int("-3e8", 16, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int("-3E8", 16, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int("-0x3e8", 16, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int("-0x3E8", 16, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int("3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("+3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("+3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("+0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("+0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int("-3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int("-3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int("-0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int("-0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int("garble", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int("-garble", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int("0x123", 10, -1000, 1000) -> rc=-7=-E2BIG val=0
+osmo_str_to_int("123potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123
+osmo_str_to_int("123 potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123
+osmo_str_to_int("123 ", 10, -1000, 1000) -> rc=-7=-E2BIG val=123
+osmo_str_to_int("123.4", 10, -1000, 1000) -> rc=-7=-E2BIG val=123
+--- test_str_to_int64
+osmo_str_to_int64(NULL, 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int64("", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int64(" ", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int64("-", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int64("--", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int64("+", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int64("++", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int64("0", 10, -1000, 1000) -> rc=0 val=0
+osmo_str_to_int64("1", 10, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int64("+1", 10, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int64("-1", 10, -1000, 1000) -> rc=0 val=-1
+osmo_str_to_int64("1000", 10, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("+1000", 10, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("-1000", 10, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int64("1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("+1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("-1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int64("0", 16, -1000, 1000) -> rc=0 val=0
+osmo_str_to_int64("1", 16, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int64("0x1", 16, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int64("+1", 16, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int64("-1", 16, -1000, 1000) -> rc=0 val=-1
+osmo_str_to_int64("+0x1", 16, -1000, 1000) -> rc=0 val=1
+osmo_str_to_int64("-0x1", 16, -1000, 1000) -> rc=0 val=-1
+osmo_str_to_int64("3e8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("3E8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("0x3e8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("0x3E8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("+3e8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("+3E8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("+0x3e8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("+0x3E8", 16, -1000, 1000) -> rc=0 val=1000
+osmo_str_to_int64("-3e8", 16, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int64("-3E8", 16, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int64("-0x3e8", 16, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int64("-0x3E8", 16, -1000, 1000) -> rc=0 val=-1000
+osmo_str_to_int64("3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("+3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("+3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("+0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("+0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001
+osmo_str_to_int64("-3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int64("-3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int64("-0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int64("-0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001
+osmo_str_to_int64("garble", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int64("-garble", 10, -1000, 1000) -> rc=-22=-EINVAL val=0
+osmo_str_to_int64("0x123", 10, -1000, 1000) -> rc=-7=-E2BIG val=0
+osmo_str_to_int64("123potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123
+osmo_str_to_int64("123 potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123
+osmo_str_to_int64("123 ", 10, -1000, 1000) -> rc=-7=-E2BIG val=123
+osmo_str_to_int64("123.4", 10, -1000, 1000) -> rc=-7=-E2BIG val=123
+osmo_str_to_int64("-9223372036854775808", 10, -9223372036854775808, 9223372036854775807) -> rc=0 val=-9223372036854775808
+osmo_str_to_int64("9223372036854775807", 10, -9223372036854775808, 9223372036854775807) -> rc=0 val=9223372036854775807
+osmo_str_to_int64("-9223372036854775809", 10, -9223372036854775808, 9223372036854775807) -> rc=-75=-EOVERFLOW val=-9223372036854775808
+osmo_str_to_int64("9223372036854775808", 10, -9223372036854775808, 9223372036854775807) -> rc=-75=-EOVERFLOW val=9223372036854775807
+osmo_str_to_int64("-9223372036854775808", 10, -1000, 1000) -> rc=-34=-ERANGE val=-9223372036854775808
+osmo_str_to_int64("9223372036854775807", 10, -1000, 1000) -> rc=-34=-ERANGE val=9223372036854775807
+osmo_str_to_int64("-9223372036854775809", 10, -1000, 1000) -> rc=-75=-EOVERFLOW val=-9223372036854775808
+osmo_str_to_int64("9223372036854775808", 10, -1000, 1000) -> rc=-75=-EOVERFLOW val=9223372036854775807
diff --git a/tests/v110/test_frame.c b/tests/v110/test_frame.c
new file mode 100644
index 00000000..ebc617c0
--- /dev/null
+++ b/tests/v110/test_frame.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/isdn/v110.h>
+
+
+static void test_frame_enc(void)
+{
+ struct osmo_v110_decoded_frame fr;
+ ubit_t bits[80];
+ unsigned int i;
+
+ memset(&fr, 0, sizeof(fr));
+
+ /* we abuse the fact that ubit_t is 8bit so we can actually
+ * store integer values to clearly identify which bit ends up where */
+
+ /* D1..D48: 101..148 */
+ for (i = 0; i < ARRAY_SIZE(fr.d_bits); i++)
+ fr.d_bits[i] = 101 + i;
+ /* E1..E7: 201..207 */
+ for (i = 0; i < ARRAY_SIZE(fr.e_bits); i++)
+ fr.e_bits[i] = 201 + i;
+ /* S1..S9: 211..219 */
+ for (i = 0; i < ARRAY_SIZE(fr.s_bits); i++)
+ fr.s_bits[i] = 211 + i;
+ /* X1..X2: 221..222 */
+ for (i = 0; i < ARRAY_SIZE(fr.x_bits); i++)
+ fr.x_bits[i] = 221 + i;
+
+ /* run encoder and dump to stdout */
+ memset(bits, 0xff, sizeof(bits));
+ osmo_v110_encode_frame(bits, sizeof(bits), &fr);
+ osmo_v110_ubit_dump(stdout, bits, sizeof(bits));
+
+ /* run decoder on what we just encoded */
+ memset(&fr, 0, sizeof(fr));
+ osmo_v110_decode_frame(&fr, bits, sizeof(bits));
+
+ /* re-encode and dump again 'expout' will match it. */
+ memset(bits, 0xff, sizeof(bits));
+ osmo_v110_encode_frame(bits, sizeof(bits), &fr);
+ osmo_v110_ubit_dump(stdout, bits, sizeof(bits));
+}
+
+
+int main(int argc, char **argv)
+{
+ test_frame_enc();
+}
+
diff --git a/tests/v110/test_frame.ok b/tests/v110/test_frame.ok
new file mode 100644
index 00000000..ecefaa87
--- /dev/null
+++ b/tests/v110/test_frame.ok
@@ -0,0 +1,20 @@
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 211
+1 107 108 109 110 111 112 221
+1 113 114 115 116 117 118 213
+1 119 120 121 122 123 124 214
+1 201 202 203 204 205 206 207
+1 125 126 127 128 129 130 216
+1 131 132 133 134 135 136 222
+1 137 138 139 140 141 142 218
+1 143 144 145 146 147 148 219
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 211
+1 107 108 109 110 111 112 221
+1 113 114 115 116 117 118 213
+1 119 120 121 122 123 124 214
+1 201 202 203 204 205 206 207
+1 125 126 127 128 129 130 216
+1 131 132 133 134 135 136 222
+1 137 138 139 140 141 142 218
+1 143 144 145 146 147 148 219
diff --git a/tests/v110/test_ra1.c b/tests/v110/test_ra1.c
new file mode 100644
index 00000000..775ec4b7
--- /dev/null
+++ b/tests/v110/test_ra1.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/isdn/v110.h>
+
+
+static void test_ra1(enum osmo_v100_sync_ra1_rate rate)
+{
+ int user_rate = osmo_v110_sync_ra1_get_user_data_rate(rate);
+ int user_data_chunk_bits = osmo_v110_sync_ra1_get_user_data_chunk_bitlen(rate);
+ struct osmo_v110_decoded_frame fr;
+ ubit_t user_bits[48];
+ ubit_t bits[80];
+ unsigned int i;
+ int rc;
+
+ printf("\n======= User data rate %u\n", user_rate);
+
+ /* we abuse the fact that ubit_t is 8bit so we can actually
+ * store integer values to clearly identify which bit ends up where */
+ memset(user_bits, 0xFE, sizeof(user_bits));
+ for (i = 0; i < user_data_chunk_bits; i++)
+ user_bits[i] = 101 + i;
+
+ printf("user_bits: ");
+ for (i = 0; i < user_data_chunk_bits; i++)
+ printf("%03d ", user_bits[i]);
+ printf("\n");
+
+ /* generate the decoded v.110 frame */
+ memset(&fr, 0, sizeof(fr));
+ rc = osmo_v110_sync_ra1_user_to_ir(rate, &fr, user_bits, user_data_chunk_bits);
+ OSMO_ASSERT(rc == 0);
+
+ /* run encoder and dump to stdout */
+ memset(bits, 0xff, sizeof(bits));
+ osmo_v110_encode_frame(bits, sizeof(bits), &fr);
+ printf("dumping %u encoded bits in V.110 frame:\n", user_data_chunk_bits);
+ osmo_v110_ubit_dump(stdout, bits, sizeof(bits));
+
+ /* run decoder on what we just encoded */
+ memset(&fr, 0, sizeof(fr));
+ osmo_v110_decode_frame(&fr, bits, sizeof(bits));
+ printf("dumping re-decoded V.110 frame:\n");
+ printf("E-bits: %s\n", osmo_hexdump(fr.e_bits, sizeof(fr.e_bits)));
+ printf("S-bits: %s\n", osmo_hexdump(fr.s_bits, sizeof(fr.s_bits)));
+
+ /* re-encode and dump again 'expout' will match it. */
+ memset(user_bits, 0xff, sizeof(user_bits));
+ rc = osmo_v110_sync_ra1_ir_to_user(rate, user_bits, sizeof(user_bits), &fr);
+ if (rc != user_data_chunk_bits) {
+ fprintf(stderr, "ERROR: adapt_ir_to_user() returned %d, expected %u\n", rc,
+ user_data_chunk_bits);
+ exit(23);
+ }
+ fprintf(stdout, "re-decoded user bits: ");
+ for (i = 0; i < user_data_chunk_bits; i++)
+ printf("%03d ", user_bits[i]);
+ printf("\n");
+}
+
+
+int main(int argc, char **argv)
+{
+ for (int i = 0; i < _NUM_OSMO_V110_SYNC_RA1; i++)
+ test_ra1(i);
+}
+
diff --git a/tests/v110/test_ra1.ok b/tests/v110/test_ra1.ok
new file mode 100644
index 00000000..8a61fc3f
--- /dev/null
+++ b/tests/v110/test_ra1.ok
@@ -0,0 +1,216 @@
+
+======= User data rate 600
+user_bits: 101 102 103 104 105 106
+dumping 6 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 101 101 101 101 101 0
+1 101 101 102 102 102 102 0
+1 102 102 102 102 103 103 0
+1 103 103 103 103 103 103 0
+1 1 0 0 0 0 0 0
+1 104 104 104 104 104 104 0
+1 104 104 105 105 105 105 0
+1 105 105 105 105 106 106 0
+1 106 106 106 106 106 106 0
+dumping re-decoded V.110 frame:
+E-bits: 01 00 00 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106
+
+======= User data rate 1200
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112
+dumping 12 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 101 101 101 102 102 0
+1 102 102 103 103 103 103 0
+1 104 104 104 104 105 105 0
+1 105 105 106 106 106 106 0
+1 0 1 0 0 0 0 0
+1 107 107 107 107 108 108 0
+1 108 108 109 109 109 109 0
+1 110 110 110 110 111 111 0
+1 111 111 112 112 112 112 0
+dumping re-decoded V.110 frame:
+E-bits: 00 01 00 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112
+
+======= User data rate 2400
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
+dumping 24 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 101 102 102 103 103 0
+1 104 104 105 105 106 106 0
+1 107 107 108 108 109 109 0
+1 110 110 111 111 112 112 0
+1 1 1 0 0 0 0 0
+1 113 113 114 114 115 115 0
+1 116 116 117 117 118 118 0
+1 119 119 120 120 121 121 0
+1 122 122 123 123 124 124 0
+dumping re-decoded V.110 frame:
+E-bits: 01 01 00 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
+
+======= User data rate 4800
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
+dumping 48 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 0
+1 107 108 109 110 111 112 0
+1 113 114 115 116 117 118 0
+1 119 120 121 122 123 124 0
+1 0 1 1 0 0 0 0
+1 125 126 127 128 129 130 0
+1 131 132 133 134 135 136 0
+1 137 138 139 140 141 142 0
+1 143 144 145 146 147 148 0
+dumping re-decoded V.110 frame:
+E-bits: 00 01 01 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
+
+======= User data rate 7200
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
+dumping 36 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 0
+1 107 108 109 110 1 1 0
+1 111 112 1 1 113 114 0
+1 1 1 115 116 117 118 0
+1 1 0 1 0 0 0 0
+1 119 120 121 122 123 124 0
+1 125 126 127 128 1 1 0
+1 129 130 1 1 131 132 0
+1 1 1 133 134 135 136 0
+dumping re-decoded V.110 frame:
+E-bits: 01 00 01 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
+
+======= User data rate 9600
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
+dumping 48 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 0
+1 107 108 109 110 111 112 0
+1 113 114 115 116 117 118 0
+1 119 120 121 122 123 124 0
+1 0 1 1 0 0 0 0
+1 125 126 127 128 129 130 0
+1 131 132 133 134 135 136 0
+1 137 138 139 140 141 142 0
+1 143 144 145 146 147 148 0
+dumping re-decoded V.110 frame:
+E-bits: 00 01 01 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
+
+======= User data rate 12000
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
+dumping 30 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 0
+1 107 108 109 110 1 1 0
+1 111 112 1 1 113 114 0
+1 1 1 115 1 1 1 0
+1 0 0 1 0 0 0 0
+1 116 117 118 119 120 121 0
+1 122 123 124 125 1 1 0
+1 126 127 1 1 128 129 0
+1 1 1 130 1 1 1 0
+dumping re-decoded V.110 frame:
+E-bits: 00 00 01 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
+
+======= User data rate 14400
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
+dumping 36 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 0
+1 107 108 109 110 1 1 0
+1 111 112 1 1 113 114 0
+1 1 1 115 116 117 118 0
+1 1 0 1 0 0 0 0
+1 119 120 121 122 123 124 0
+1 125 126 127 128 1 1 0
+1 129 130 1 1 131 132 0
+1 1 1 133 134 135 136 0
+dumping re-decoded V.110 frame:
+E-bits: 01 00 01 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
+
+======= User data rate 19200
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
+dumping 48 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 0
+1 107 108 109 110 111 112 0
+1 113 114 115 116 117 118 0
+1 119 120 121 122 123 124 0
+1 0 1 1 0 0 0 0
+1 125 126 127 128 129 130 0
+1 131 132 133 134 135 136 0
+1 137 138 139 140 141 142 0
+1 143 144 145 146 147 148 0
+dumping re-decoded V.110 frame:
+E-bits: 00 01 01 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
+
+======= User data rate 24000
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
+dumping 30 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 0
+1 107 108 109 110 1 1 0
+1 111 112 1 1 113 114 0
+1 1 1 115 1 1 1 0
+1 0 0 1 0 0 0 0
+1 116 117 118 119 120 121 0
+1 122 123 124 125 1 1 0
+1 126 127 1 1 128 129 0
+1 1 1 130 1 1 1 0
+dumping re-decoded V.110 frame:
+E-bits: 00 00 01 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
+
+======= User data rate 28800
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
+dumping 36 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 0
+1 107 108 109 110 1 1 0
+1 111 112 1 1 113 114 0
+1 1 1 115 116 117 118 0
+1 1 0 1 0 0 0 0
+1 119 120 121 122 123 124 0
+1 125 126 127 128 1 1 0
+1 129 130 1 1 131 132 0
+1 1 1 133 134 135 136 0
+dumping re-decoded V.110 frame:
+E-bits: 01 00 01 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
+
+======= User data rate 38400
+user_bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
+dumping 48 encoded bits in V.110 frame:
+0 0 0 0 0 0 0 0
+1 101 102 103 104 105 106 0
+1 107 108 109 110 111 112 0
+1 113 114 115 116 117 118 0
+1 119 120 121 122 123 124 0
+1 0 1 1 0 0 0 0
+1 125 126 127 128 129 130 0
+1 131 132 133 134 135 136 0
+1 137 138 139 140 141 142 0
+1 143 144 145 146 147 148 0
+dumping re-decoded V.110 frame:
+E-bits: 00 01 01 00 00 00 00
+S-bits: 00 00 00 00 00 00 00 00 00
+re-decoded user bits: 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
diff --git a/tests/vty/vty_test.c b/tests/vty/vty_test.c
index b2d34ad8..01e323ed 100644
--- a/tests/vty/vty_test.c
+++ b/tests/vty/vty_test.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#include <stdio.h>
@@ -452,7 +448,35 @@ DEFUN(cfg_numeric_range, cfg_numeric_range_cmd,
return CMD_SUCCESS;
}
-void test_vty_add_cmds()
+DEFUN(cfg_range_base10, cfg_range_base10_cmd,
+ "range-base10 <0-999999>",
+ "testing decimal range\n"
+ "the decimal range\n")
+{
+ printf("Called: 'return-success'\n");
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_range_base16, cfg_range_base16_cmd,
+ "range-base16 <0x0-0x8888>",
+ "testing hexadecimal range\n"
+ "the hexadecimal range\n")
+{
+ printf("Called: 'return-success'\n");
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_range_baseboth, cfg_range_baseboth_cmd,
+ "range-baseboth (<0-999999>|<0x0-0x8888>)",
+ "testing both ranges\n"
+ "the decimal range\n"
+ "the hexadecimal range\n")
+{
+ printf("Called: 'return-success'\n");
+ return CMD_SUCCESS;
+}
+
+void test_vty_add_cmds(void)
{
install_element(CONFIG_NODE, &cfg_ret_warning_cmd);
install_element(CONFIG_NODE, &cfg_ret_success_cmd);
@@ -477,9 +501,13 @@ void test_vty_add_cmds()
install_element_ve(&cfg_ambiguous_str_2_cmd);
install_element_ve(&cfg_numeric_range_cmd);
+
+ install_element_ve(&cfg_range_base10_cmd);
+ install_element_ve(&cfg_range_base16_cmd);
+ install_element_ve(&cfg_range_baseboth_cmd);
}
-void test_is_cmd_ambiguous()
+void test_is_cmd_ambiguous(void)
{
struct vty *vty;
struct vty_test test;
@@ -498,7 +526,7 @@ void test_is_cmd_ambiguous()
destroy_test_vty(&test, vty);
}
-void test_numeric_range()
+void test_numeric_range(void)
{
struct vty *vty;
struct vty_test test;
@@ -513,11 +541,73 @@ void test_numeric_range()
destroy_test_vty(&test, vty);
}
+void test_ranges(void)
+{
+ struct vty *vty;
+ struct vty_test test;
+
+ printf("Going to test test_ranges()\n");
+ vty = create_test_vty(&test);
+
+ printf("test range-base10\n");
+ OSMO_ASSERT(do_vty_command(vty, "range-base10 0") == CMD_SUCCESS);
+ OSMO_ASSERT(do_vty_command(vty, "range-base10 40000") == CMD_SUCCESS);
+ OSMO_ASSERT(do_vty_command(vty, "range-base10 -400000") == CMD_ERR_NO_MATCH);
+ OSMO_ASSERT(do_vty_command(vty, "range-base10 0x0") == CMD_ERR_NO_MATCH);
+ OSMO_ASSERT(do_vty_command(vty, "range-base10 0x343") == CMD_ERR_NO_MATCH);
+ OSMO_ASSERT(do_vty_command(vty, "range-base10 -0x343") == CMD_ERR_NO_MATCH);
+
+ printf("test range-base16\n");
+ OSMO_ASSERT(do_vty_command(vty, "range-base16 0") == CMD_ERR_NO_MATCH);
+ OSMO_ASSERT(do_vty_command(vty, "range-base16 40000") == CMD_ERR_NO_MATCH);
+ OSMO_ASSERT(do_vty_command(vty, "range-base16 -400000") == CMD_ERR_NO_MATCH);
+ OSMO_ASSERT(do_vty_command(vty, "range-base16 0x0") == CMD_SUCCESS);
+ OSMO_ASSERT(do_vty_command(vty, "range-base16 0x343") == CMD_SUCCESS);
+ OSMO_ASSERT(do_vty_command(vty, "range-base16 -0x343") == CMD_ERR_NO_MATCH);
+
+ printf("test range-baseboth\n");
+ OSMO_ASSERT(do_vty_command(vty, "range-baseboth 0") == CMD_SUCCESS);
+ OSMO_ASSERT(do_vty_command(vty, "range-baseboth 40000") == CMD_SUCCESS);
+ OSMO_ASSERT(do_vty_command(vty, "range-baseboth -400000") == CMD_ERR_NO_MATCH);
+ OSMO_ASSERT(do_vty_command(vty, "range-baseboth 0x0") == CMD_SUCCESS);
+ OSMO_ASSERT(do_vty_command(vty, "range-baseboth 0x343") == CMD_SUCCESS);
+ OSMO_ASSERT(do_vty_command(vty, "range-baseboth -0x343") == CMD_ERR_NO_MATCH);
+
+ destroy_test_vty(&test, vty);
+}
+/* Application specific attributes */
+enum vty_test_attr {
+ VTY_TEST_ATTR_FOO = 0,
+ VTY_TEST_ATTR_BAR,
+ VTY_TEST_ATTR_ZOO,
+ VTY_TEST_ATTR_FOO_DUP,
+ VTY_TEST_ATTR_ZOO_DUP,
+ VTY_TEST_ATTR_UPPER,
+ VTY_TEST_ATTR_RAFC_DOT,
+ VTY_TEST_ATTR_RAFC_EXCL,
+ VTY_TEST_ATTR_RAFC_AT,
+};
+
int main(int argc, char **argv)
{
struct vty_app_info vty_info = {
.name = "VtyTest",
.version = 0,
+ .usr_attr_letters = {
+ [VTY_TEST_ATTR_FOO] = 'f',
+ [VTY_TEST_ATTR_BAR] = 'b',
+ [VTY_TEST_ATTR_ZOO] = 'z',
+
+ /* Duplicate detection check */
+ [VTY_TEST_ATTR_FOO_DUP] = 'f',
+ [VTY_TEST_ATTR_ZOO_DUP] = 'z',
+ /* Reserved for libraries */
+ [VTY_TEST_ATTR_UPPER] = 'X',
+ /* Reserved for global attribues */
+ [VTY_TEST_ATTR_RAFC_DOT] = '.',
+ [VTY_TEST_ATTR_RAFC_EXCL] = '!',
+ [VTY_TEST_ATTR_RAFC_AT] = '@',
+ },
};
const struct log_info_cat default_categories[] = {};
@@ -567,6 +657,7 @@ int main(int argc, char **argv)
test_is_cmd_ambiguous();
test_numeric_range();
+ test_ranges();
/* Leak check */
OSMO_ASSERT(talloc_total_blocks(stats_ctx) == 1);
diff --git a/tests/vty/vty_test.err b/tests/vty/vty_test.err
new file mode 100644
index 00000000..b021425d
--- /dev/null
+++ b/tests/vty/vty_test.err
@@ -0,0 +1,77 @@
+Found duplicate flag letter 'f' in application specific attributes (index 0 vs 3)! Please fix.
+Found duplicate flag letter 'z' in application specific attributes (index 2 vs 4)! Please fix.
+Attribute flag letter 'X' is reserved for libraries! Please fix.
+Attribute flag character '.' is reserved for globals! Please fix.
+Attribute flag character '!' is reserved for globals! Please fix.
+Attribute flag character '@' is reserved for globals! Please fix.
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 1
+Got VTY event: 3
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 1
+Got VTY event: 2
+Got VTY event: 3
+There is no such command.
+Error occurred during reading the below line:
+ level1 b
+
+Inconsistent indentation -- leading whitespace must match adjacent lines, and
+indentation must reflect child node levels. A mix of tabs and spaces is
+allowed, but their sequence must not change within a child block.
+Error occurred during reading the below line:
+ level1 b
+
+Inconsistent indentation -- leading whitespace must match adjacent lines, and
+indentation must reflect child node levels. A mix of tabs and spaces is
+allowed, but their sequence must not change within a child block.
+Error occurred during reading the below line:
+ child1 b
+
+Error occurred during reading the below line:
+return-warning
+
+% Ignoring deprecated 'logging level depr (debug|info|notice|error|fatal)'
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 1
+Got VTY event: 3
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 1
+Got VTY event: 3
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 2
+Got VTY event: 1
+Got VTY event: 3
diff --git a/tests/vty/vty_test.ok b/tests/vty/vty_test.ok
index 5f509f65..e97fbfc4 100644
--- a/tests/vty/vty_test.ok
+++ b/tests/vty/vty_test.ok
@@ -320,4 +320,52 @@ Called: 'return-success'
Returned: 0, Current node: 1 '%s> '
Going to execute 'numeric-range -400000'
Returned: 2, Current node: 1 '%s> '
+Going to test test_ranges()
+test range-base10
+Going to execute 'range-base10 0'
+Called: 'return-success'
+Returned: 0, Current node: 1 '%s> '
+Going to execute 'range-base10 40000'
+Called: 'return-success'
+Returned: 0, Current node: 1 '%s> '
+Going to execute 'range-base10 -400000'
+Returned: 2, Current node: 1 '%s> '
+Going to execute 'range-base10 0x0'
+Returned: 2, Current node: 1 '%s> '
+Going to execute 'range-base10 0x343'
+Returned: 2, Current node: 1 '%s> '
+Going to execute 'range-base10 -0x343'
+Returned: 2, Current node: 1 '%s> '
+test range-base16
+Going to execute 'range-base16 0'
+Returned: 2, Current node: 1 '%s> '
+Going to execute 'range-base16 40000'
+Returned: 2, Current node: 1 '%s> '
+Going to execute 'range-base16 -400000'
+Returned: 2, Current node: 1 '%s> '
+Going to execute 'range-base16 0x0'
+Called: 'return-success'
+Returned: 0, Current node: 1 '%s> '
+Going to execute 'range-base16 0x343'
+Called: 'return-success'
+Returned: 0, Current node: 1 '%s> '
+Going to execute 'range-base16 -0x343'
+Returned: 2, Current node: 1 '%s> '
+test range-baseboth
+Going to execute 'range-baseboth 0'
+Called: 'return-success'
+Returned: 0, Current node: 1 '%s> '
+Going to execute 'range-baseboth 40000'
+Called: 'return-success'
+Returned: 0, Current node: 1 '%s> '
+Going to execute 'range-baseboth -400000'
+Returned: 2, Current node: 1 '%s> '
+Going to execute 'range-baseboth 0x0'
+Called: 'return-success'
+Returned: 0, Current node: 1 '%s> '
+Going to execute 'range-baseboth 0x343'
+Called: 'return-success'
+Returned: 0, Current node: 1 '%s> '
+Going to execute 'range-baseboth -0x343'
+Returned: 2, Current node: 1 '%s> '
All tests passed
diff --git a/tests/vty/vty_transcript_test.c b/tests/vty/vty_transcript_test.c
index 6651097e..1754b67a 100644
--- a/tests/vty/vty_transcript_test.c
+++ b/tests/vty/vty_transcript_test.c
@@ -17,10 +17,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE
@@ -41,7 +37,7 @@
void *root_ctx = NULL;
-static void print_help()
+static void print_help(void)
{
printf( "options:\n"
" -h --help this text\n"
@@ -142,9 +138,34 @@ static void signal_handler(int signal)
}
}
+/* Application specific VTY attributes */
+enum {
+ TEST_ATTR_UNBELIEVABLE,
+ TEST_ATTR_MAGNIFICENT,
+ TEST_ATTR_WONDERFUL,
+ TEST_ATTR_UNUSED,
+};
+
static struct vty_app_info vty_info = {
.name = "vty_transcript_test",
.version = PACKAGE_VERSION,
+ .usr_attr_desc = {
+ /* Some random description strings, who cares... */
+ [TEST_ATTR_UNBELIEVABLE] = \
+ "Unbelievable: not able to be believed; unlikely to be true",
+ [TEST_ATTR_MAGNIFICENT] = \
+ "Magnificent: impressively beautiful, elaborate, or extravagant",
+ [TEST_ATTR_WONDERFUL] = \
+ "Wonderful: inspiring delight, pleasure, or admiration",
+ [TEST_ATTR_UNUSED] = \
+ "Intentionally unused attribute, ignore me",
+ },
+ .usr_attr_letters = {
+ [TEST_ATTR_UNBELIEVABLE] = 'u',
+ [TEST_ATTR_MAGNIFICENT] = 'm',
+ [TEST_ATTR_WONDERFUL] = 'w',
+ [TEST_ATTR_UNUSED] = 'n',
+ },
};
static const struct log_info_cat default_categories[] = {};
@@ -186,12 +207,135 @@ DEFUN(multi2, multi2_cmd,
return CMD_SUCCESS;
}
-static void init_vty_cmds()
+#define X(f) (1 << f)
+
+enum {
+ ATTR_TEST_NODE = _LAST_OSMOVTY_NODE + 1,
+};
+
+static struct cmd_node attr_test_node = {
+ ATTR_TEST_NODE,
+ "%s(config-attr-test)# ",
+ 1
+};
+
+DEFUN(cfg_attr_test, cfg_attr_test_cmd,
+ "attribute-test",
+ "Enter attribute test node\n")
+{
+ vty->index = NULL;
+ vty->node = ATTR_TEST_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUN_DEPRECATED(cfg_attr_deprecated,
+ cfg_attr_deprecated_cmd,
+ "foo-deprecated",
+ "This command is deprecated\n")
+{
+ return CMD_WARNING;
+}
+
+DEFUN_HIDDEN(cfg_attr_hidden,
+ cfg_attr_hidden_cmd,
+ "foo-hidden [expert-mode]",
+ "This command is hidden\n"
+ "But can be seen in the expert mode\n")
+{
+ return CMD_SUCCESS;
+}
+
+DEFUN_ATTR(cfg_attr_immediate, cfg_attr_immediate_cmd,
+ "foo-immediate",
+ "Applies immediately\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ return CMD_SUCCESS;
+}
+
+DEFUN_ATTR(cfg_attr_node_exit, cfg_attr_node_exit_cmd,
+ "foo-node-exit",
+ "Applies on node exit\n",
+ CMD_ATTR_NODE_EXIT)
+{
+ return CMD_SUCCESS;
+}
+
+DEFUN_USRATTR(cfg_app_attr_unbelievable,
+ cfg_app_attr_unbelievable_cmd,
+ X(TEST_ATTR_UNBELIEVABLE),
+ "app-unbelievable",
+ "Unbelievable help message\n")
+{
+ return CMD_SUCCESS;
+}
+
+DEFUN_USRATTR(cfg_app_attr_magnificent,
+ cfg_app_attr_magnificent_cmd,
+ X(TEST_ATTR_MAGNIFICENT),
+ "app-magnificent",
+ "Magnificent help message\n")
+{
+ return CMD_SUCCESS;
+}
+
+DEFUN_USRATTR(cfg_app_attr_wonderful,
+ cfg_app_attr_wonderful_cmd,
+ X(TEST_ATTR_WONDERFUL),
+ "app-wonderful",
+ "Wonderful help message\n")
+{
+ return CMD_SUCCESS;
+}
+
+DEFUN_USRATTR(cfg_app_attr_unbelievable_magnificent,
+ cfg_app_attr_unbelievable_magnificent_cmd,
+ X(TEST_ATTR_UNBELIEVABLE) | X(TEST_ATTR_MAGNIFICENT),
+ "app-unbelievable-magnificent",
+ "Unbelievable & magnificent help message\n")
+{
+ return CMD_SUCCESS;
+}
+
+DEFUN_USRATTR(cfg_app_attr_unbelievable_wonderful,
+ cfg_app_attr_unbelievable_wonderful_cmd,
+ X(TEST_ATTR_UNBELIEVABLE) | X(TEST_ATTR_WONDERFUL),
+ "app-unbelievable-wonderful",
+ "Unbelievable & wonderful help message\n")
+{
+ return CMD_SUCCESS;
+}
+
+DEFUN_ATTR_USRATTR(cfg_attr_hidden_app_attr_unbelievable,
+ cfg_attr_hidden_app_attr_unbelievable_cmd,
+ CMD_ATTR_HIDDEN, X(TEST_ATTR_UNBELIEVABLE),
+ "app-hidden-unbelievable",
+ "Hidden, but still unbelievable help message\n")
+{
+ return CMD_SUCCESS;
+}
+
+static void init_vty_cmds(void)
{
install_element_ve(&single0_cmd);
install_element_ve(&multi0_cmd);
install_element_ve(&multi1_cmd);
install_element_ve(&multi2_cmd);
+
+ install_element(CONFIG_NODE, &cfg_attr_test_cmd);
+ install_node(&attr_test_node, NULL);
+ install_element(ATTR_TEST_NODE, &cfg_attr_deprecated_cmd);
+ install_element(ATTR_TEST_NODE, &cfg_attr_hidden_cmd);
+ install_element(ATTR_TEST_NODE, &cfg_attr_immediate_cmd);
+ install_element(ATTR_TEST_NODE, &cfg_attr_node_exit_cmd);
+
+ install_element(ATTR_TEST_NODE, &cfg_app_attr_unbelievable_cmd);
+ install_element(ATTR_TEST_NODE, &cfg_app_attr_magnificent_cmd);
+ install_element(ATTR_TEST_NODE, &cfg_app_attr_wonderful_cmd);
+
+ install_element(ATTR_TEST_NODE, &cfg_app_attr_unbelievable_magnificent_cmd);
+ install_element(ATTR_TEST_NODE, &cfg_app_attr_unbelievable_wonderful_cmd);
+ install_element(ATTR_TEST_NODE, &cfg_attr_hidden_app_attr_unbelievable_cmd);
}
int main(int argc, char **argv)
@@ -217,7 +361,7 @@ int main(int argc, char **argv)
}
}
- rc = telnet_init_dynif(root_ctx, NULL, vty_get_bind_addr(), 42042);
+ rc = telnet_init_default(root_ctx, NULL, 42042);
if (rc < 0)
return 2;
diff --git a/tests/vty/vty_transcript_test.vty b/tests/vty/vty_transcript_test.vty
index db58830e..7b8241eb 100644
--- a/tests/vty/vty_transcript_test.vty
+++ b/tests/vty/vty_transcript_test.vty
@@ -84,3 +84,96 @@ ok argc=1 one
vty_transcript_test> single0
ok argc=0
+
+vty_transcript_test> show vty-attributes
+ Global attributes:
+ ^ This command is hidden (check expert mode)
+ ! This command applies immediately
+ @ This command applies on VTY node exit
+ Library specific attributes:
+ A This command applies on ASP restart
+ I This command applies on IPA link establishment
+ L This command applies on E1 line update
+ Application specific attributes:
+ u Unbelievable: not able to be believed; unlikely to be true
+ m Magnificent: impressively beautiful, elaborate, or extravagant
+ w Wonderful: inspiring delight, pleasure, or admiration
+ n Intentionally unused attribute, ignore me
+
+vty_transcript_test> en
+vty_transcript_test# configure terminal
+vty_transcript_test(config)# attribute-test
+
+vty_transcript_test(config-attr-test)# list
+... !foo-(hidden|deprecated)
+ foo-immediate
+ foo-node-exit
+ app-unbelievable
+ app-magnificent
+ app-wonderful
+ app-unbelievable-magnificent
+ app-unbelievable-wonderful
+... !app-hidden-*
+
+vty_transcript_test(config-attr-test)# list with-flags
+... !foo-(hidden|deprecated)
+ ! ... foo-immediate
+ @ ... foo-node-exit
+ . u.. app-unbelievable
+ . .m. app-magnificent
+ . ..w app-wonderful
+ . um. app-unbelievable-magnificent
+ . u.w app-unbelievable-wonderful
+... !app-hidden-*
+
+vty_transcript_test(config-attr-test)# foo-deprecated?
+% There is no matched command.
+vty_transcript_test(config-attr-test)# foo-hidden?
+% There is no matched command.
+vty_transcript_test(config-attr-test)# app-hidden-unbelievable?
+% There is no matched command.
+
+vty_transcript_test(config-attr-test)# end
+vty_transcript_test# disable
+
+vty_transcript_test> enable?
+ enable Turn on privileged mode command
+vty_transcript_test> enable ?
+ [expert-mode] Enable the expert mode (show hidden commands)
+
+vty_transcript_test> enable expert-mode
+vty_transcript_test# configure terminal
+vty_transcript_test(config)# attribute-test
+
+vty_transcript_test(config-attr-test)# list
+... !foo-deprected
+ foo-hidden [expert-mode]
+ foo-immediate
+ foo-node-exit
+ app-unbelievable
+ app-magnificent
+ app-wonderful
+ app-unbelievable-magnificent
+ app-unbelievable-wonderful
+ app-hidden-unbelievable
+
+vty_transcript_test(config-attr-test)# list with-flags
+... !foo-deprected
+ ^ ... foo-hidden [expert-mode]
+ ! ... foo-immediate
+ @ ... foo-node-exit
+ . u.. app-unbelievable
+ . .m. app-magnificent
+ . ..w app-wonderful
+ . um. app-unbelievable-magnificent
+ . u.w app-unbelievable-wonderful
+ ^ u.. app-hidden-unbelievable
+
+vty_transcript_test(config-attr-test)# foo-deprecated?
+% There is no matched command.
+vty_transcript_test(config-attr-test)# foo-hidden?
+ foo-hidden This command is hidden
+vty_transcript_test(config-attr-test)# foo-hidden ?
+ [expert-mode] But can be seen in the expert mode
+vty_transcript_test(config-attr-test)# app-hidden-unbelievable?
+ app-hidden-unbelievable Hidden, but still unbelievable help message
diff --git a/tests/write_queue/wqueue_test.c b/tests/write_queue/wqueue_test.c
index 827e4e84..3823ef5b 100644
--- a/tests/write_queue/wqueue_test.c
+++ b/tests/write_queue/wqueue_test.c
@@ -72,7 +72,9 @@ int main(int argc, char **argv)
log_init(&log_info, NULL);
stderr_target = log_target_create_stderr();
log_add_target(stderr_target);
- log_set_print_filename(stderr_target, 0);
+ log_set_print_filename2(stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category_hex(stderr_target, 0);
+ log_set_print_category(stderr_target, 0);
test_wqueue_limit();