From 7b656884cfadfd8c56355e8a6c690721827b5b30 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Sun, 9 Jul 2017 22:09:18 +0200 Subject: split off osmo-bsc: remove files, apply build Change-Id: I64d84c52f6e38e98144eb9be8f0ab82e0e1f6cca --- configure.ac | 18 +- include/openbsc/Makefile.am | 42 +- include/openbsc/a_iface.h | 76 - include/openbsc/a_iface_bssap.h | 41 - include/openbsc/bsc_api.h | 1 + include/openbsc/common_cs.h | 7 + include/openbsc/db.h | 59 - include/openbsc/gb_proxy.h | 288 - include/openbsc/gprs_gb_parse.h | 59 - include/openbsc/gprs_gmm.h | 35 - include/openbsc/gprs_llc.h | 284 - include/openbsc/gprs_llc_xid.h | 57 - include/openbsc/gprs_sgsn.h | 478 -- include/openbsc/gprs_sndcp.h | 79 - include/openbsc/gprs_sndcp_comp.h | 82 - include/openbsc/gprs_sndcp_dcomp.h | 53 - include/openbsc/gprs_sndcp_pcomp.h | 46 - include/openbsc/gprs_sndcp_xid.h | 218 - include/openbsc/gprs_subscriber.h | 31 - include/openbsc/gprs_utils.h | 44 - include/openbsc/gsm_04_08.h | 85 - include/openbsc/gsm_04_08_utils.h | 32 + include/openbsc/gsm_04_11.h | 53 - include/openbsc/gsm_data.h | 1 + include/openbsc/gsm_data_shared.h | 1 + include/openbsc/gsup_client.h | 63 - include/openbsc/gtphub.h | 523 -- include/openbsc/iucs.h | 7 - include/openbsc/iucs_ranap.h | 7 - include/openbsc/oap_client.h | 82 - include/openbsc/rest_octets.h | 3 +- include/openbsc/slhc.h | 187 - include/openbsc/transaction.h | 1 - include/openbsc/v42bis.h | 147 - include/openbsc/v42bis_private.h | 126 - include/openbsc/vlr.h | 422 -- osmoappdesc.py | 15 +- src/Makefile.am | 4 - src/gprs/.gitignore | 2 - src/gprs/Makefile.am | 133 - src/gprs/crc24.c | 67 - src/gprs/gb_proxy.c | 1438 ---- src/gprs/gb_proxy_main.c | 317 - src/gprs/gb_proxy_patch.c | 459 -- src/gprs/gb_proxy_peer.c | 222 - src/gprs/gb_proxy_tlli.c | 723 -- src/gprs/gb_proxy_vty.c | 853 --- src/gprs/gprs_gb_parse.c | 636 -- src/gprs/gprs_gmm.c | 2937 --------- src/gprs/gprs_llc.c | 1132 ---- src/gprs/gprs_llc_parse.c | 251 - src/gprs/gprs_llc_vty.c | 116 - src/gprs/gprs_llc_xid.c | 281 - src/gprs/gprs_sgsn.c | 933 --- src/gprs/gprs_sndcp.c | 1258 ---- src/gprs/gprs_sndcp_comp.c | 323 - src/gprs/gprs_sndcp_dcomp.c | 358 - src/gprs/gprs_sndcp_pcomp.c | 282 - src/gprs/gprs_sndcp_vty.c | 71 - src/gprs/gprs_sndcp_xid.c | 1822 ------ src/gprs/gprs_subscriber.c | 937 --- src/gprs/gprs_utils.c | 246 - src/gprs/gtphub.c | 2937 --------- src/gprs/gtphub_ares.c | 220 - src/gprs/gtphub_main.c | 359 - src/gprs/gtphub_sock.c | 60 - src/gprs/gtphub_vty.c | 613 -- src/gprs/osmo_sgsn.cfg | 23 - src/gprs/sgsn_ares.c | 173 - src/gprs/sgsn_auth.c | 312 - src/gprs/sgsn_cdr.c | 259 - src/gprs/sgsn_ctrl.c | 69 - src/gprs/sgsn_libgtp.c | 885 --- src/gprs/sgsn_main.c | 476 -- src/gprs/sgsn_vty.c | 1329 ---- src/gprs/slhc.c | 813 --- src/gprs/v42bis.c | 767 --- src/libbsc/abis_rsl.c | 3 +- src/libbsc/bsc_api.c | 3 +- src/libbsc/bsc_init.c | 1 - src/libbsc/bsc_vty.c | 28 +- src/libbsc/chan_alloc.c | 1 + src/libbsc/gsm_04_08_utils.c | 2 +- src/libbsc/handover_logic.c | 6 +- src/libbsc/net_init.c | 1 + src/libbsc/paging.c | 1 - src/libbsc/system_information.c | 4 +- src/libcommon-cs/common_cs.c | 3 +- src/libcommon/Makefile.am | 18 - src/libcommon/gsm_data.c | 1 + src/libcommon/gsm_subscriber_base.c | 27 - src/libcommon/gsup_client.c | 347 - src/libcommon/gsup_test_client.c | 298 - src/libfilter/bsc_msg_filter.c | 2 + src/libmsc/Makefile.am | 75 - src/libmsc/a_iface.c | 591 -- src/libmsc/a_iface_bssap.c | 716 -- src/libmsc/auth.c | 42 - src/libmsc/ctrl_commands.c | 88 - src/libmsc/db.c | 1007 --- src/libmsc/gsm_04_08.c | 3493 ---------- src/libmsc/gsm_04_11.c | 1189 ---- src/libmsc/gsm_04_80.c | 155 - src/libmsc/gsm_subscriber.c | 190 - src/libmsc/iu_dummy.c | 93 - src/libmsc/iucs.c | 189 - src/libmsc/iucs_ranap.c | 104 - src/libmsc/meas_feed.c | 168 - src/libmsc/meas_feed.h | 12 - src/libmsc/mncc.c | 107 - src/libmsc/mncc_builtin.c | 383 -- src/libmsc/mncc_sock.c | 317 - src/libmsc/msc_ifaces.c | 423 -- src/libmsc/msc_vty.c | 162 - src/libmsc/osmo_msc.c | 387 -- src/libmsc/rrlp.c | 104 - src/libmsc/silent_call.c | 165 - src/libmsc/smpp_openbsc.c | 794 --- src/libmsc/smpp_smsc.c | 1037 --- src/libmsc/smpp_smsc.h | 167 - src/libmsc/smpp_utils.c | 62 - src/libmsc/smpp_vty.c | 612 -- src/libmsc/sms_queue.c | 578 -- src/libmsc/subscr_conn.c | 359 - src/libmsc/transaction.c | 221 - src/libmsc/ussd.c | 103 - src/libmsc/vty_interface_layer3.c | 979 --- src/libvlr/Makefile.am | 19 - src/libvlr/vlr.c | 1112 ---- src/libvlr/vlr_access_req_fsm.c | 795 --- src/libvlr/vlr_access_req_fsm.h | 17 - src/libvlr/vlr_auth_fsm.c | 605 -- src/libvlr/vlr_auth_fsm.h | 52 - src/libvlr/vlr_core.h | 21 - src/libvlr/vlr_lu_fsm.c | 1449 ----- src/libvlr/vlr_lu_fsm.h | 18 - src/osmo-bsc/Makefile.am | 1 - src/osmo-bsc/osmo_bsc_api.c | 3 + src/osmo-bsc/osmo_bsc_bssap.c | 16 +- src/osmo-bsc/osmo_bsc_filter.c | 2 + src/osmo-bsc/osmo_bsc_main.c | 2 +- src/osmo-bsc_nat/bsc_nat_rewrite.c | 2 + src/osmo-bsc_nat/bsc_nat_vty.c | 2 +- src/osmo-bsc_nat/bsc_ussd.c | 2 + src/osmo-msc/Makefile.am | 58 - src/osmo-msc/msc_main.c | 589 -- tests/Makefile.am | 29 - tests/channel/Makefile.am | 1 - tests/channel/channel_test.c | 1 - tests/db/Makefile.am | 47 - tests/db/db_test.c | 286 - tests/db/db_test.err | 3 - tests/db/db_test.ok | 4 - tests/db/hlr.sqlite3 | Bin 29696 -> 0 bytes tests/gbproxy/Makefile.am | 54 - tests/gbproxy/gbproxy_test.c | 4971 -------------- tests/gbproxy/gbproxy_test.ok | 7244 --------------------- tests/gprs/Makefile.am | 10 - tests/gprs/gprs_test.c | 140 - tests/gprs/gprs_test.ok | 17 - tests/gsm0408/gsm0408_test.c | 7 +- tests/gtphub/Makefile.am | 44 - tests/gtphub/gtphub_test.c | 1786 ----- tests/gtphub/gtphub_test.ok | 42 - tests/msc_vlr/Makefile.am | 168 - tests/msc_vlr/msc_vlr_test_gsm_authen.c | 924 --- tests/msc_vlr/msc_vlr_test_gsm_authen.err | 1997 ------ tests/msc_vlr/msc_vlr_test_gsm_authen.ok | 1 - tests/msc_vlr/msc_vlr_test_gsm_ciph.c | 845 --- tests/msc_vlr/msc_vlr_test_gsm_ciph.err | 1679 ----- tests/msc_vlr/msc_vlr_test_gsm_ciph.ok | 1 - tests/msc_vlr/msc_vlr_test_hlr_reject.c | 447 -- tests/msc_vlr/msc_vlr_test_hlr_reject.err | 1165 ---- tests/msc_vlr/msc_vlr_test_hlr_reject.ok | 1 - tests/msc_vlr/msc_vlr_test_hlr_timeout.c | 118 - tests/msc_vlr/msc_vlr_test_hlr_timeout.err | 189 - tests/msc_vlr/msc_vlr_test_hlr_timeout.ok | 1 - tests/msc_vlr/msc_vlr_test_ms_timeout.c | 189 - tests/msc_vlr/msc_vlr_test_ms_timeout.err | 342 - tests/msc_vlr/msc_vlr_test_ms_timeout.ok | 1 - tests/msc_vlr/msc_vlr_test_no_authen.c | 908 --- tests/msc_vlr/msc_vlr_test_no_authen.err | 2119 ------ tests/msc_vlr/msc_vlr_test_no_authen.ok | 1 - tests/msc_vlr/msc_vlr_test_reject_concurrency.c | 397 -- tests/msc_vlr/msc_vlr_test_reject_concurrency.err | 1817 ------ tests/msc_vlr/msc_vlr_test_reject_concurrency.ok | 1 - tests/msc_vlr/msc_vlr_test_rest.c | 201 - tests/msc_vlr/msc_vlr_test_rest.err | 493 -- tests/msc_vlr/msc_vlr_test_rest.ok | 1 - tests/msc_vlr/msc_vlr_test_umts_authen.c | 581 -- tests/msc_vlr/msc_vlr_test_umts_authen.err | 1381 ---- tests/msc_vlr/msc_vlr_test_umts_authen.ok | 1 - tests/msc_vlr/msc_vlr_tests.c | 805 --- tests/msc_vlr/msc_vlr_tests.h | 186 - tests/nanobts_omlattr/Makefile.am | 1 - tests/nanobts_omlattr/nanobts_omlattr_test.c | 1 - tests/oap/Makefile.am | 36 - tests/oap/oap_client_test.c | 270 - tests/oap/oap_client_test.err | 35 - tests/oap/oap_client_test.ok | 2 - tests/sgsn/Makefile.am | 81 - tests/sgsn/sgsn_test.c | 2487 ------- tests/sgsn/sgsn_test.ok | 45 - tests/slhc/Makefile.am | 15 - tests/slhc/slhc_test.c | 272 - tests/slhc/slhc_test.ok | 154 - tests/smpp/Makefile.am | 40 - tests/smpp/smpp_test.c | 73 - tests/smpp/smpp_test.err | 2 - tests/smpp/smpp_test.ok | 1 - tests/smpp_test_runner.py | 137 - tests/sms_queue/Makefile.am | 57 - tests/sms_queue/sms_queue_test.c | 215 - tests/sms_queue/sms_queue_test.err | 0 tests/sms_queue/sms_queue_test.ok | 98 - tests/sndcp_xid/Makefile.am | 21 - tests/sndcp_xid/sndcp_xid_test.c | 284 - tests/sndcp_xid/sndcp_xid_test.ok | 11 - tests/testsuite.at | 156 - tests/v42bis/Makefile.am | 15 - tests/v42bis/v42bis_test.c | 435 -- tests/v42bis/v42bis_test.ok | 648 -- tests/vty_test_runner.py | 392 -- tests/xid/Makefile.am | 39 - tests/xid/xid_test.c | 164 - tests/xid/xid_test.ok | 12 - 226 files changed, 100 insertions(+), 87177 deletions(-) delete mode 100644 include/openbsc/a_iface.h delete mode 100644 include/openbsc/a_iface_bssap.h delete mode 100644 include/openbsc/db.h delete mode 100644 include/openbsc/gb_proxy.h delete mode 100644 include/openbsc/gprs_gb_parse.h delete mode 100644 include/openbsc/gprs_gmm.h delete mode 100644 include/openbsc/gprs_llc.h delete mode 100644 include/openbsc/gprs_llc_xid.h delete mode 100644 include/openbsc/gprs_sgsn.h delete mode 100644 include/openbsc/gprs_sndcp.h delete mode 100644 include/openbsc/gprs_sndcp_comp.h delete mode 100644 include/openbsc/gprs_sndcp_dcomp.h delete mode 100644 include/openbsc/gprs_sndcp_pcomp.h delete mode 100644 include/openbsc/gprs_sndcp_xid.h delete mode 100644 include/openbsc/gprs_subscriber.h delete mode 100644 include/openbsc/gprs_utils.h delete mode 100644 include/openbsc/gsm_04_08.h create mode 100644 include/openbsc/gsm_04_08_utils.h delete mode 100644 include/openbsc/gsm_04_11.h delete mode 100644 include/openbsc/gsup_client.h delete mode 100644 include/openbsc/gtphub.h delete mode 100644 include/openbsc/iucs.h delete mode 100644 include/openbsc/iucs_ranap.h delete mode 100644 include/openbsc/oap_client.h delete mode 100644 include/openbsc/slhc.h delete mode 100644 include/openbsc/v42bis.h delete mode 100644 include/openbsc/v42bis_private.h delete mode 100644 include/openbsc/vlr.h delete mode 100644 src/gprs/.gitignore delete mode 100644 src/gprs/Makefile.am delete mode 100644 src/gprs/crc24.c delete mode 100644 src/gprs/gb_proxy.c delete mode 100644 src/gprs/gb_proxy_main.c delete mode 100644 src/gprs/gb_proxy_patch.c delete mode 100644 src/gprs/gb_proxy_peer.c delete mode 100644 src/gprs/gb_proxy_tlli.c delete mode 100644 src/gprs/gb_proxy_vty.c delete mode 100644 src/gprs/gprs_gb_parse.c delete mode 100644 src/gprs/gprs_gmm.c delete mode 100644 src/gprs/gprs_llc.c delete mode 100644 src/gprs/gprs_llc_parse.c delete mode 100644 src/gprs/gprs_llc_vty.c delete mode 100644 src/gprs/gprs_llc_xid.c delete mode 100644 src/gprs/gprs_sgsn.c delete mode 100644 src/gprs/gprs_sndcp.c delete mode 100644 src/gprs/gprs_sndcp_comp.c delete mode 100644 src/gprs/gprs_sndcp_dcomp.c delete mode 100644 src/gprs/gprs_sndcp_pcomp.c delete mode 100644 src/gprs/gprs_sndcp_vty.c delete mode 100644 src/gprs/gprs_sndcp_xid.c delete mode 100644 src/gprs/gprs_subscriber.c delete mode 100644 src/gprs/gprs_utils.c delete mode 100644 src/gprs/gtphub.c delete mode 100644 src/gprs/gtphub_ares.c delete mode 100644 src/gprs/gtphub_main.c delete mode 100644 src/gprs/gtphub_sock.c delete mode 100644 src/gprs/gtphub_vty.c delete mode 100644 src/gprs/osmo_sgsn.cfg delete mode 100644 src/gprs/sgsn_ares.c delete mode 100644 src/gprs/sgsn_auth.c delete mode 100644 src/gprs/sgsn_cdr.c delete mode 100644 src/gprs/sgsn_ctrl.c delete mode 100644 src/gprs/sgsn_libgtp.c delete mode 100644 src/gprs/sgsn_main.c delete mode 100644 src/gprs/sgsn_vty.c delete mode 100644 src/gprs/slhc.c delete mode 100644 src/gprs/v42bis.c delete mode 100644 src/libcommon/gsup_client.c delete mode 100644 src/libcommon/gsup_test_client.c delete mode 100644 src/libmsc/Makefile.am delete mode 100644 src/libmsc/a_iface.c delete mode 100644 src/libmsc/a_iface_bssap.c delete mode 100644 src/libmsc/auth.c delete mode 100644 src/libmsc/ctrl_commands.c delete mode 100644 src/libmsc/db.c delete mode 100644 src/libmsc/gsm_04_08.c delete mode 100644 src/libmsc/gsm_04_11.c delete mode 100644 src/libmsc/gsm_04_80.c delete mode 100644 src/libmsc/gsm_subscriber.c delete mode 100644 src/libmsc/iu_dummy.c delete mode 100644 src/libmsc/iucs.c delete mode 100644 src/libmsc/iucs_ranap.c delete mode 100644 src/libmsc/meas_feed.c delete mode 100644 src/libmsc/meas_feed.h delete mode 100644 src/libmsc/mncc.c delete mode 100644 src/libmsc/mncc_builtin.c delete mode 100644 src/libmsc/mncc_sock.c delete mode 100644 src/libmsc/msc_ifaces.c delete mode 100644 src/libmsc/msc_vty.c delete mode 100644 src/libmsc/osmo_msc.c delete mode 100644 src/libmsc/rrlp.c delete mode 100644 src/libmsc/silent_call.c delete mode 100644 src/libmsc/smpp_openbsc.c delete mode 100644 src/libmsc/smpp_smsc.c delete mode 100644 src/libmsc/smpp_smsc.h delete mode 100644 src/libmsc/smpp_utils.c delete mode 100644 src/libmsc/smpp_vty.c delete mode 100644 src/libmsc/sms_queue.c delete mode 100644 src/libmsc/subscr_conn.c delete mode 100644 src/libmsc/transaction.c delete mode 100644 src/libmsc/ussd.c delete mode 100644 src/libmsc/vty_interface_layer3.c delete mode 100644 src/libvlr/Makefile.am delete mode 100644 src/libvlr/vlr.c delete mode 100644 src/libvlr/vlr_access_req_fsm.c delete mode 100644 src/libvlr/vlr_access_req_fsm.h delete mode 100644 src/libvlr/vlr_auth_fsm.c delete mode 100644 src/libvlr/vlr_auth_fsm.h delete mode 100644 src/libvlr/vlr_core.h delete mode 100644 src/libvlr/vlr_lu_fsm.c delete mode 100644 src/libvlr/vlr_lu_fsm.h delete mode 100644 src/osmo-msc/Makefile.am delete mode 100644 src/osmo-msc/msc_main.c delete mode 100644 tests/db/Makefile.am delete mode 100644 tests/db/db_test.c delete mode 100644 tests/db/db_test.err delete mode 100644 tests/db/db_test.ok delete mode 100644 tests/db/hlr.sqlite3 delete mode 100644 tests/gbproxy/Makefile.am delete mode 100644 tests/gbproxy/gbproxy_test.c delete mode 100644 tests/gbproxy/gbproxy_test.ok delete mode 100644 tests/gprs/Makefile.am delete mode 100644 tests/gprs/gprs_test.c delete mode 100644 tests/gprs/gprs_test.ok delete mode 100644 tests/gtphub/Makefile.am delete mode 100644 tests/gtphub/gtphub_test.c delete mode 100644 tests/gtphub/gtphub_test.ok delete mode 100644 tests/msc_vlr/Makefile.am delete mode 100644 tests/msc_vlr/msc_vlr_test_gsm_authen.c delete mode 100644 tests/msc_vlr/msc_vlr_test_gsm_authen.err delete mode 100644 tests/msc_vlr/msc_vlr_test_gsm_authen.ok delete mode 100644 tests/msc_vlr/msc_vlr_test_gsm_ciph.c delete mode 100644 tests/msc_vlr/msc_vlr_test_gsm_ciph.err delete mode 100644 tests/msc_vlr/msc_vlr_test_gsm_ciph.ok delete mode 100644 tests/msc_vlr/msc_vlr_test_hlr_reject.c delete mode 100644 tests/msc_vlr/msc_vlr_test_hlr_reject.err delete mode 100644 tests/msc_vlr/msc_vlr_test_hlr_reject.ok delete mode 100644 tests/msc_vlr/msc_vlr_test_hlr_timeout.c delete mode 100644 tests/msc_vlr/msc_vlr_test_hlr_timeout.err delete mode 100644 tests/msc_vlr/msc_vlr_test_hlr_timeout.ok delete mode 100644 tests/msc_vlr/msc_vlr_test_ms_timeout.c delete mode 100644 tests/msc_vlr/msc_vlr_test_ms_timeout.err delete mode 100644 tests/msc_vlr/msc_vlr_test_ms_timeout.ok delete mode 100644 tests/msc_vlr/msc_vlr_test_no_authen.c delete mode 100644 tests/msc_vlr/msc_vlr_test_no_authen.err delete mode 100644 tests/msc_vlr/msc_vlr_test_no_authen.ok delete mode 100644 tests/msc_vlr/msc_vlr_test_reject_concurrency.c delete mode 100644 tests/msc_vlr/msc_vlr_test_reject_concurrency.err delete mode 100644 tests/msc_vlr/msc_vlr_test_reject_concurrency.ok delete mode 100644 tests/msc_vlr/msc_vlr_test_rest.c delete mode 100644 tests/msc_vlr/msc_vlr_test_rest.err delete mode 100644 tests/msc_vlr/msc_vlr_test_rest.ok delete mode 100644 tests/msc_vlr/msc_vlr_test_umts_authen.c delete mode 100644 tests/msc_vlr/msc_vlr_test_umts_authen.err delete mode 100644 tests/msc_vlr/msc_vlr_test_umts_authen.ok delete mode 100644 tests/msc_vlr/msc_vlr_tests.c delete mode 100644 tests/msc_vlr/msc_vlr_tests.h delete mode 100644 tests/oap/Makefile.am delete mode 100644 tests/oap/oap_client_test.c delete mode 100644 tests/oap/oap_client_test.err delete mode 100644 tests/oap/oap_client_test.ok delete mode 100644 tests/sgsn/Makefile.am delete mode 100644 tests/sgsn/sgsn_test.c delete mode 100644 tests/sgsn/sgsn_test.ok delete mode 100644 tests/slhc/Makefile.am delete mode 100644 tests/slhc/slhc_test.c delete mode 100644 tests/slhc/slhc_test.ok delete mode 100644 tests/smpp/Makefile.am delete mode 100644 tests/smpp/smpp_test.c delete mode 100644 tests/smpp/smpp_test.err delete mode 100644 tests/smpp/smpp_test.ok delete mode 100644 tests/smpp_test_runner.py delete mode 100644 tests/sms_queue/Makefile.am delete mode 100644 tests/sms_queue/sms_queue_test.c delete mode 100644 tests/sms_queue/sms_queue_test.err delete mode 100644 tests/sms_queue/sms_queue_test.ok delete mode 100644 tests/sndcp_xid/Makefile.am delete mode 100644 tests/sndcp_xid/sndcp_xid_test.c delete mode 100644 tests/sndcp_xid/sndcp_xid_test.ok delete mode 100644 tests/v42bis/Makefile.am delete mode 100644 tests/v42bis/v42bis_test.c delete mode 100644 tests/v42bis/v42bis_test.ok delete mode 100644 tests/xid/Makefile.am delete mode 100644 tests/xid/xid_test.c delete mode 100644 tests/xid/xid_test.ok diff --git a/configure.ac b/configure.ac index e97198528..cc07f7a01 100644 --- a/configure.ac +++ b/configure.ac @@ -209,7 +209,7 @@ AC_ARG_ENABLE([external_tests], [Include the VTY/CTRL tests in make check [default=no]]), [enable_ext_tests="$enableval"],[enable_ext_tests="no"]) if test "x$enable_ext_tests" = "xyes" ; then - AM_PATH_PYTHON +AM_PATH_PYTHON AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes) if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then AC_MSG_ERROR([Please install git://osmocom.org/python/osmo-python-tests to run the VTY/CTRL tests.]) @@ -229,17 +229,13 @@ AC_OUTPUT( src/Makefile src/libtrau/Makefile src/libbsc/Makefile - src/libmsc/Makefile - src/libvlr/Makefile src/libcommon/Makefile src/libfilter/Makefile src/libcommon-cs/Makefile - src/osmo-msc/Makefile src/osmo-bsc/Makefile src/osmo-bsc_nat/Makefile src/ipaccess/Makefile src/utils/Makefile - src/gprs/Makefile tests/Makefile tests/atlocal tests/gsm0408/Makefile @@ -247,22 +243,10 @@ AC_OUTPUT( tests/bsc/Makefile tests/bsc-nat/Makefile tests/bsc-nat-trie/Makefile - tests/gprs/Makefile - tests/gbproxy/Makefile tests/abis/Makefile - tests/smpp/Makefile tests/trau/Makefile - tests/sgsn/Makefile tests/subscr/Makefile - tests/oap/Makefile - tests/gtphub/Makefile - tests/xid/Makefile - tests/sndcp_xid/Makefile - tests/slhc/Makefile - tests/v42bis/Makefile tests/nanobts_omlattr/Makefile - tests/sms_queue/Makefile - tests/msc_vlr/Makefile doc/Makefile doc/examples/Makefile contrib/Makefile diff --git a/include/openbsc/Makefile.am b/include/openbsc/Makefile.am index c1cb6a3fb..3b8dbdf12 100644 --- a/include/openbsc/Makefile.am +++ b/include/openbsc/Makefile.am @@ -1,9 +1,8 @@ noinst_HEADERS = \ + a_reset.h \ abis_nm.h \ abis_om2000.h \ abis_rsl.h \ - a_iface.h \ - a_iface_bssap.h \ arfcn_range_encode.h \ auth.h \ bsc_msc.h \ @@ -21,37 +20,16 @@ noinst_HEADERS = \ common_cs.h \ crc24.h \ ctrl.h \ - db.h \ debug.h \ e1_config.h \ - gb_proxy.h \ - gprs_gb_parse.h \ - gprs_gmm.h \ - gprs_llc.h \ - gprs_llc_xid.h \ - gprs_sgsn.h \ - gprs_sndcp.h \ - gprs_sndcp_comp.h \ - gprs_sndcp_dcomp.h \ - gprs_sndcp_pcomp.h \ - gprs_sndcp_xid.h \ - gprs_subscriber.h \ - gprs_utils.h \ - gsm_04_08.h \ - gsm_04_11.h \ - gsm_04_14.h \ + gsm_04_08_utils.h \ gsm_04_80.h \ gsm_data.h \ gsm_data_shared.h \ gsm_subscriber.h \ - gsup_client.h \ - gtphub.h \ handover.h \ handover_decision.h \ ipaccess.h \ - iucs.h \ - iucs_ranap.h \ - iu_dummy.h \ meas_feed.h \ meas_rep.h \ misdn.h \ @@ -60,11 +38,9 @@ noinst_HEADERS = \ msc_ifaces.h \ nat_rewrite_trie.h \ network_listen.h \ - oap_client.h \ openbscdefines.h \ osmo_bsc.h \ osmo_bsc_grace.h \ - a_reset.h \ osmo_bsc_rf.h \ osmo_msc.h \ osmo_bsc_sigtran.h \ @@ -80,8 +56,6 @@ noinst_HEADERS = \ sgsn.h \ signal.h \ silent_call.h \ - slhc.h \ - smpp.h \ sms_queue.h \ socket.h \ system_information.h \ @@ -89,18 +63,6 @@ noinst_HEADERS = \ trau_mux.h \ trau_upqueue.h \ ussd.h \ - vlr.h \ vty.h \ - v42bis.h \ - v42bis_private.h \ - $(NULL) - -openbsc_HEADERS = \ bsc_api.h \ - gsm_04_08.h \ - meas_rep.h \ $(NULL) - -# DO NOT add a newline and '$(NULL)' to this line. That would add a trailing -# space to the directory installed: $prefix/include/'openbsc ' -openbscdir = $(includedir)/openbsc diff --git a/include/openbsc/a_iface.h b/include/openbsc/a_iface.h deleted file mode 100644 index 149f1c71e..000000000 --- a/include/openbsc/a_iface.h +++ /dev/null @@ -1,76 +0,0 @@ -/* (C) 2017 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - * - */ - -#pragma once - -#include - -/* A struct to keep a context information about the BSCs we are associated with */ -struct bsc_context { - struct llist_head list; - - /* Holds a copy of the sccp address of the BSC, - * this address will become known as soon as - * a remote BSC tries to make a connection or - * sends a RESET request via UNIDATA */ - struct osmo_sccp_addr bsc_addr; - - /* Holds a copy of the our local MSC address, - * this will be the sccp-address that is associated - * with the A interface */ - struct osmo_sccp_addr msc_addr; - - /* A pointer to the reset handler FSM, the - * state machine is allocated when the BSC - * is registerd. */ - struct a_reset_ctx *reset; - - /* A pointer to the sccp_user that is associated - * with the A interface. We need this information - * to send the resets and to send paging requests */ - struct osmo_sccp_user *sccp_user; -}; - -/* Initalize A interface connection between to MSC and BSC */ -int a_init(struct osmo_sccp_instance *sccp, struct gsm_network *network); - -/* Send DTAP message via A-interface */ -int a_iface_tx_dtap(struct msgb *msg); - -/* Send Cipher mode command via A-interface */ -int a_iface_tx_cipher_mode(const struct gsm_subscriber_connection *conn, - int cipher, const const uint8_t *key, int len, int include_imeisv); - -/* Page a subscriber via A-interface */ -int a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac); - -/* Send assignment request via A-interface */ -int a_iface_tx_assignment(const struct gsm_trans *trans); - -/* Send clear command via A-interface */ -int a_iface_tx_clear_cmd(struct gsm_subscriber_connection *conn); - -/* Clear all subscriber connections on a specified BSC - * (Helper function for a_iface_bssap.c) */ -void a_clear_all(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *bsc_addr); - -/* Delete info of a closed connection from the active connection list - * (Helper function for a_iface_bssap.c) */ -void a_delete_bsc_con(uint32_t conn_id); diff --git a/include/openbsc/a_iface_bssap.h b/include/openbsc/a_iface_bssap.h deleted file mode 100644 index 237c618fd..000000000 --- a/include/openbsc/a_iface_bssap.h +++ /dev/null @@ -1,41 +0,0 @@ -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - * - */ - -#pragma once - -/* Note: The structs and functions presented in this header file are intended - * to be used only by a_iface.c. */ - -/* A structure to hold tha most basic information about a sigtran connection - * we use this struct internally here to pass connection data around */ -struct a_conn_info { - struct osmo_sccp_addr *msc_addr; - struct osmo_sccp_addr *bsc_addr; - uint32_t conn_id; - struct gsm_network *network; - struct a_reset_ctx *reset; -}; - -/* Receive incoming connection less data messages via sccp */ -void sccp_rx_udt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg); - -/* Receive incoming connection oriented data messages via sccp */ -int sccp_rx_dt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg); - diff --git a/include/openbsc/bsc_api.h b/include/openbsc/bsc_api.h index 40068d6ef..6ee05629f 100644 --- a/include/openbsc/bsc_api.h +++ b/include/openbsc/bsc_api.h @@ -55,4 +55,5 @@ int gsm0808_page(struct gsm_bts *bts, unsigned int page_group, unsigned int mi_len, uint8_t *mi, int chan_type); int gsm0808_clear(struct gsm_subscriber_connection *conn); +int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id); #endif diff --git a/include/openbsc/common_cs.h b/include/openbsc/common_cs.h index 6dc956f80..09a4b0224 100644 --- a/include/openbsc/common_cs.h +++ b/include/openbsc/common_cs.h @@ -1,6 +1,7 @@ #pragma once #include +#include struct msgb; struct gsm_network; @@ -25,3 +26,9 @@ struct gsm_network *gsm_network_init(void *ctx, int common_cs_vty_init(struct gsm_network *network, int (* config_write_net )(struct vty *)); struct gsm_network *gsmnet_from_vty(struct vty *v); + +struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value); +int gsm48_extract_mi(uint8_t *classmark2_lv, int length, char *mi_string, uint8_t *mi_type); +int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length, + char *mi_string, uint8_t *mi_type); +struct msgb *gsm48_create_loc_upd_rej(uint8_t cause); diff --git a/include/openbsc/db.h b/include/openbsc/db.h deleted file mode 100644 index 988c9bd6e..000000000 --- a/include/openbsc/db.h +++ /dev/null @@ -1,59 +0,0 @@ -/* (C) 2008 by Jan Luebbe - * (C) 2009 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#ifndef _DB_H -#define _DB_H - -#include - -#include "gsm_subscriber.h" - -struct gsm_equipment; -struct gsm_network; -struct gsm_auth_info; -struct gsm_auth_tuple; -struct gsm_sms; - -/* one time initialisation */ -int db_init(const char *name); -int db_prepare(void); -int db_fini(void); - -/* SMS store-and-forward */ -int db_sms_store(struct gsm_sms *sms); -struct gsm_sms *db_sms_get(struct gsm_network *net, unsigned long long id); -struct gsm_sms *db_sms_get_next_unsent(struct gsm_network *net, - unsigned long long min_sms_id, - unsigned int max_failed); -struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net, - const char *last_msisdn, - unsigned int max_failed); -struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub, - unsigned int max_failed); -int db_sms_mark_delivered(struct gsm_sms *sms); -int db_sms_inc_deliver_attempts(struct gsm_sms *sms); -int db_sms_delete_by_msisdn(const char *msisdn); - -/* Statistics counter storage */ -struct osmo_counter; -int db_store_counter(struct osmo_counter *ctr); -struct rate_ctr_group; -int db_store_rate_ctr_group(struct rate_ctr_group *ctrg); - -#endif /* _DB_H */ diff --git a/include/openbsc/gb_proxy.h b/include/openbsc/gb_proxy.h deleted file mode 100644 index e10894fc3..000000000 --- a/include/openbsc/gb_proxy.h +++ /dev/null @@ -1,288 +0,0 @@ -#ifndef _GB_PROXY_H -#define _GB_PROXY_H - - -#include - -#include -#include - -#include -#include - -#define GBPROXY_INIT_VU_GEN_TX 256 - -struct rate_ctr_group; -struct gprs_gb_parse_context; -struct tlv_parsed; - -enum gbproxy_global_ctr { - GBPROX_GLOB_CTR_INV_BVCI, - GBPROX_GLOB_CTR_INV_LAI, - GBPROX_GLOB_CTR_INV_RAI, - GBPROX_GLOB_CTR_INV_NSEI, - GBPROX_GLOB_CTR_PROTO_ERR_BSS, - GBPROX_GLOB_CTR_PROTO_ERR_SGSN, - GBPROX_GLOB_CTR_NOT_SUPPORTED_BSS, - GBPROX_GLOB_CTR_NOT_SUPPORTED_SGSN, - GBPROX_GLOB_CTR_RESTART_RESET_SGSN, - GBPROX_GLOB_CTR_TX_ERR_SGSN, - GBPROX_GLOB_CTR_OTHER_ERR, - GBPROX_GLOB_CTR_PATCH_PEER_ERR, -}; - -enum gbproxy_peer_ctr { - GBPROX_PEER_CTR_BLOCKED, - GBPROX_PEER_CTR_UNBLOCKED, - GBPROX_PEER_CTR_DROPPED, - GBPROX_PEER_CTR_INV_NSEI, - GBPROX_PEER_CTR_TX_ERR, - GBPROX_PEER_CTR_RAID_PATCHED_BSS, - GBPROX_PEER_CTR_RAID_PATCHED_SGSN, - GBPROX_PEER_CTR_APN_PATCHED, - GBPROX_PEER_CTR_TLLI_PATCHED_BSS, - GBPROX_PEER_CTR_TLLI_PATCHED_SGSN, - GBPROX_PEER_CTR_PTMSI_PATCHED_BSS, - GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN, - GBPROX_PEER_CTR_PATCH_CRYPT_ERR, - GBPROX_PEER_CTR_PATCH_ERR, - GBPROX_PEER_CTR_ATTACH_REQS, - GBPROX_PEER_CTR_ATTACH_REJS, - GBPROX_PEER_CTR_ATTACH_ACKS, - GBPROX_PEER_CTR_ATTACH_COMPLS, - GBPROX_PEER_CTR_RA_UPD_REQS, - GBPROX_PEER_CTR_RA_UPD_REJS, - GBPROX_PEER_CTR_RA_UPD_ACKS, - GBPROX_PEER_CTR_RA_UPD_COMPLS, - GBPROX_PEER_CTR_GMM_STATUS_BSS, - GBPROX_PEER_CTR_GMM_STATUS_SGSN, - GBPROX_PEER_CTR_DETACH_REQS, - GBPROX_PEER_CTR_DETACH_ACKS, - GBPROX_PEER_CTR_PDP_ACT_REQS, - GBPROX_PEER_CTR_PDP_ACT_REJS, - GBPROX_PEER_CTR_PDP_ACT_ACKS, - GBPROX_PEER_CTR_PDP_DEACT_REQS, - GBPROX_PEER_CTR_PDP_DEACT_ACKS, - GBPROX_PEER_CTR_TLLI_UNKNOWN, - GBPROX_PEER_CTR_TLLI_CACHE_SIZE, - GBPROX_PEER_CTR_LAST, -}; - -enum gbproxy_keep_mode { - GBPROX_KEEP_NEVER, - GBPROX_KEEP_REATTACH, - GBPROX_KEEP_IDENTIFIED, - GBPROX_KEEP_ALWAYS, -}; - -enum gbproxy_match_id { - GBPROX_MATCH_PATCHING, - GBPROX_MATCH_ROUTING, - GBPROX_MATCH_LAST -}; - -struct gbproxy_match { - int enable; - char *re_str; - regex_t re_comp; -}; - -struct gbproxy_config { - /* parsed from config file */ - uint16_t nsip_sgsn_nsei; - - /* misc */ - struct gprs_ns_inst *nsi; - - /* Linked list of all Gb peers (except SGSN) */ - struct llist_head bts_peers; - - /* Counter */ - struct rate_ctr_group *ctrg; - - /* force mcc/mnc */ - int core_mnc; - int core_mcc; - uint8_t* core_apn; - size_t core_apn_size; - int tlli_max_age; - int tlli_max_len; - - /* Experimental config */ - int patch_ptmsi; - int acquire_imsi; - int route_to_sgsn2; - uint16_t nsip_sgsn2_nsei; - enum gbproxy_keep_mode keep_link_infos; - - /* IMSI checking/matching */ - struct gbproxy_match matches[GBPROX_MATCH_LAST]; -}; - -struct gbproxy_patch_state { - int local_mnc; - int local_mcc; - - /* List of TLLIs for which patching is enabled */ - struct llist_head logical_links; - int logical_link_count; -}; - -struct gbproxy_peer { - struct llist_head list; - - /* point back to the config */ - struct gbproxy_config *cfg; - - /* NSEI of the peer entity */ - uint16_t nsei; - - /* BVCI used for Point-to-Point to this peer */ - uint16_t bvci; - int blocked; - - /* Routeing Area that this peer is part of (raw 04.08 encoding) */ - uint8_t ra[6]; - - /* Counter */ - struct rate_ctr_group *ctrg; - - struct gbproxy_patch_state patch_state; -}; - -struct gbproxy_tlli_state { - uint32_t current; - uint32_t assigned; - int bss_validated; - int net_validated; - - uint32_t ptmsi; -}; - -struct gbproxy_link_info { - struct llist_head list; - - struct gbproxy_tlli_state tlli; - struct gbproxy_tlli_state sgsn_tlli; - uint32_t sgsn_nsei; - - time_t timestamp; - uint8_t *imsi; - size_t imsi_len; - - int imsi_acq_pending; - struct llist_head stored_msgs; - unsigned vu_gen_tx_bss; - - int is_deregistered; - - int is_matching[GBPROX_MATCH_LAST]; -}; - - -/* gb_proxy_vty .c */ - -int gbproxy_vty_init(void); -int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg); - - -/* gb_proxy.c */ -int gbproxy_init_config(struct gbproxy_config *cfg); - -/* Main input function for Gb proxy */ -int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei, uint16_t ns_bvci, uint16_t nsvci); - -int gbprox_signal(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data); - -/* Reset all persistent NS-VC's */ -int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi); - -void gbprox_reset(struct gbproxy_config *cfg); - -/* TLLI info handling */ -void gbproxy_delete_link_infos(struct gbproxy_peer *peer); -struct gbproxy_link_info *gbproxy_update_link_state_ul( - struct gbproxy_peer *peer, time_t now, - struct gprs_gb_parse_context *parse_ctx); -struct gbproxy_link_info *gbproxy_update_link_state_dl( - struct gbproxy_peer *peer, time_t now, - struct gprs_gb_parse_context *parse_ctx); -int gbproxy_update_link_state_after( - struct gbproxy_peer *peer, struct gbproxy_link_info *link_info, - time_t now, struct gprs_gb_parse_context *parse_ctx); -int gbproxy_remove_stale_link_infos(struct gbproxy_peer *peer, time_t now); -void gbproxy_delete_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info); -void gbproxy_link_info_discard_messages(struct gbproxy_link_info *link_info); - -void gbproxy_attach_link_info(struct gbproxy_peer *peer, time_t now, - struct gbproxy_link_info *link_info); -void gbproxy_update_link_info(struct gbproxy_link_info *link_info, - const uint8_t *imsi, size_t imsi_len); -void gbproxy_detach_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info); -struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_peer *peer); - -struct gbproxy_link_info *gbproxy_link_info_by_tlli( - struct gbproxy_peer *peer, uint32_t tlli); -struct gbproxy_link_info *gbproxy_link_info_by_imsi( - struct gbproxy_peer *peer, const uint8_t *imsi, size_t imsi_len); -struct gbproxy_link_info *gbproxy_link_info_by_any_sgsn_tlli( - struct gbproxy_peer *peer, uint32_t tlli); -struct gbproxy_link_info *gbproxy_link_info_by_sgsn_tlli( - struct gbproxy_peer *peer, - uint32_t tlli, uint32_t sgsn_nsei); -struct gbproxy_link_info *gbproxy_link_info_by_ptmsi( - struct gbproxy_peer *peer, - uint32_t ptmsi); - -int gbproxy_imsi_matches( - struct gbproxy_config *cfg, - enum gbproxy_match_id match_id, - struct gbproxy_link_info *link_info); -uint32_t gbproxy_map_tlli( - uint32_t other_tlli, struct gbproxy_link_info *link_info, int to_bss); - -/* needed by gb_proxy_tlli.h */ -uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer, uint32_t sgsn_ptmsi); -uint32_t gbproxy_make_sgsn_tlli( - struct gbproxy_peer *peer, struct gbproxy_link_info *link_info, - uint32_t bss_tlli); -void gbproxy_reset_link(struct gbproxy_link_info *link_info); -int gbproxy_check_imsi( - struct gbproxy_match *match, const uint8_t *imsi, size_t imsi_len); - -/* Message patching */ -void gbproxy_patch_bssgp( - struct msgb *msg, uint8_t *bssgp, size_t bssgp_len, - struct gbproxy_peer *peer, struct gbproxy_link_info *link_info, - int *len_change, struct gprs_gb_parse_context *parse_ctx); - -int gbproxy_patch_llc( - struct msgb *msg, uint8_t *llc, size_t llc_len, - struct gbproxy_peer *peer, struct gbproxy_link_info *link_info, - int *len_change, struct gprs_gb_parse_context *parse_ctx); - -int gbproxy_set_patch_filter( - struct gbproxy_match *match, const char *filter, const char **err_msg); -void gbproxy_clear_patch_filter(struct gbproxy_match *match); - -/* Peer handling */ -struct gbproxy_peer *gbproxy_peer_by_bvci( - struct gbproxy_config *cfg, uint16_t bvci); -struct gbproxy_peer *gbproxy_peer_by_nsei( - struct gbproxy_config *cfg, uint16_t nsei); -struct gbproxy_peer *gbproxy_peer_by_rai( - struct gbproxy_config *cfg, const uint8_t *ra); -struct gbproxy_peer *gbproxy_peer_by_lai( - struct gbproxy_config *cfg, const uint8_t *la); -struct gbproxy_peer *gbproxy_peer_by_lac( - struct gbproxy_config *cfg, const uint8_t *la); -struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv( - struct gbproxy_config *cfg, struct tlv_parsed *tp); -struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci); -void gbproxy_peer_free(struct gbproxy_peer *peer); -int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci); - -#endif diff --git a/include/openbsc/gprs_gb_parse.h b/include/openbsc/gprs_gb_parse.h deleted file mode 100644 index 246839286..000000000 --- a/include/openbsc/gprs_gb_parse.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include - -#include - -struct gprs_gb_parse_context { - /* Pointer to protocol specific parts */ - struct gsm48_hdr *g48_hdr; - struct bssgp_normal_hdr *bgp_hdr; - struct bssgp_ud_hdr *bud_hdr; - uint8_t *bssgp_data; - size_t bssgp_data_len; - uint8_t *llc; - size_t llc_len; - - /* Extracted information */ - struct gprs_llc_hdr_parsed llc_hdr_parsed; - struct tlv_parsed bssgp_tp; - int to_bss; - uint8_t *tlli_enc; - uint8_t *old_tlli_enc; - uint8_t *imsi; - size_t imsi_len; - uint8_t *apn_ie; - size_t apn_ie_len; - uint8_t *ptmsi_enc; - uint8_t *new_ptmsi_enc; - uint8_t *raid_enc; - uint8_t *old_raid_enc; - uint8_t *bssgp_raid_enc; - uint8_t *bssgp_ptmsi_enc; - - /* General info */ - const char *llc_msg_name; - int invalidate_tlli; - int await_reattach; - int need_decryption; - uint32_t tlli; - int pdu_type; - int old_raid_is_foreign; - int peer_nsei; -}; - -int gprs_gb_parse_dtap(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx); - -int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len, - struct gprs_gb_parse_context *parse_ctx); - -int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len, - struct gprs_gb_parse_context *parse_ctx); - -const char *gprs_gb_message_name(const struct gprs_gb_parse_context *parse_ctx, - const char *default_msg_name); - -void gprs_gb_log_parse_context(int log_level, - struct gprs_gb_parse_context *parse_ctx, - const char *default_msg_name); diff --git a/include/openbsc/gprs_gmm.h b/include/openbsc/gprs_gmm.h deleted file mode 100644 index c38e49f0d..000000000 --- a/include/openbsc/gprs_gmm.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _GPRS_GMM_H -#define _GPRS_GMM_H - -#include -#include - -#include - -int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause); -int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid, - uint8_t cause, uint8_t pco_len, uint8_t *pco_v); -int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp); -int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp); - -int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, - bool drop_cipherable); -int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, - uint16_t *sai); -int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx); -int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg, - struct gprs_llc_llme *llme); -void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx); -void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx, int gmm_cause); -void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx, int gmm_cause); -void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *mmctx); - -int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli); -int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli, - uint8_t suspend_ref); - -time_t gprs_max_time_to_idle(void); - -int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp); - -#endif /* _GPRS_GMM_H */ diff --git a/include/openbsc/gprs_llc.h b/include/openbsc/gprs_llc.h deleted file mode 100644 index 8bc226781..000000000 --- a/include/openbsc/gprs_llc.h +++ /dev/null @@ -1,284 +0,0 @@ -#ifndef _GPRS_LLC_H -#define _GPRS_LLC_H - -#include -#include -#include -#include - -/* Section 4.7 LLC Layer Structure */ -enum gprs_llc_sapi { - GPRS_SAPI_GMM = 1, - GPRS_SAPI_TOM2 = 2, - GPRS_SAPI_SNDCP3 = 3, - GPRS_SAPI_SNDCP5 = 5, - GPRS_SAPI_SMS = 7, - GPRS_SAPI_TOM8 = 8, - GPRS_SAPI_SNDCP9 = 9, - GPRS_SAPI_SNDCP11 = 11, -}; - -/* Section 6.4 Commands and Responses */ -enum gprs_llc_u_cmd { - GPRS_LLC_U_DM_RESP = 0x01, - GPRS_LLC_U_DISC_CMD = 0x04, - GPRS_LLC_U_UA_RESP = 0x06, - GPRS_LLC_U_SABM_CMD = 0x07, - GPRS_LLC_U_FRMR_RESP = 0x08, - GPRS_LLC_U_XID = 0x0b, - GPRS_LLC_U_NULL_CMD = 0x00, -}; - -/* Section 6.4.1.6 / Table 6 */ -enum gprs_llc_xid_type { - GPRS_LLC_XID_T_VERSION = 0, - GPRS_LLC_XID_T_IOV_UI = 1, - GPRS_LLC_XID_T_IOV_I = 2, - GPRS_LLC_XID_T_T200 = 3, - GPRS_LLC_XID_T_N200 = 4, - GPRS_LLC_XID_T_N201_U = 5, - GPRS_LLC_XID_T_N201_I = 6, - GPRS_LLC_XID_T_mD = 7, - GPRS_LLC_XID_T_mU = 8, - GPRS_LLC_XID_T_kD = 9, - GPRS_LLC_XID_T_kU = 10, - GPRS_LLC_XID_T_L3_PAR = 11, - GPRS_LLC_XID_T_RESET = 12, -}; - -extern const struct value_string gprs_llc_xid_type_names[]; - -/* TS 04.64 Section 7.1.2 Table 7: LLC layer primitives (GMM/SNDCP/SMS/TOM) */ -/* TS 04.65 Section 5.1.2 Table 2: Service primitives used by SNDCP */ -enum gprs_llc_primitive { - /* GMM <-> LLME */ - LLGMM_ASSIGN_REQ, /* GMM tells us new TLLI: TLLI old, TLLI new, Kc, CiphAlg */ - LLGMM_RESET_REQ, /* GMM tells us to perform XID negotiation: TLLI */ - LLGMM_RESET_CNF, /* LLC informs GMM that XID has completed: TLLI */ - LLGMM_SUSPEND_REQ, /* GMM tells us MS has suspended: TLLI, Page */ - LLGMM_RESUME_REQ, /* GMM tells us MS has resumed: TLLI */ - LLGMM_PAGE_IND, /* LLC asks GMM to page MS: TLLI */ - LLGMM_IOV_REQ, /* GMM tells us to perform XID: TLLI */ - LLGMM_STATUS_IND, /* LLC informs GMM about error: TLLI, Cause */ - /* LLE <-> (GMM/SNDCP/SMS/TOM) */ - LL_RESET_IND, /* TLLI */ - LL_ESTABLISH_REQ, /* TLLI, XID Req */ - LL_ESTABLISH_IND, /* TLLI, XID Req, N201-I, N201-U */ - LL_ESTABLISH_RESP, /* TLLI, XID Negotiated */ - LL_ESTABLISH_CONF, /* TLLI, XID Neg, N201-i, N201-U */ - LL_RELEASE_REQ, /* TLLI, Local */ - LL_RELEASE_IND, /* TLLI, Cause */ - LL_RELEASE_CONF, /* TLLI */ - LL_XID_REQ, /* TLLI, XID Requested */ - LL_XID_IND, /* TLLI, XID Req, N201-I, N201-U */ - LL_XID_RESP, /* TLLI, XID Negotiated */ - LL_XID_CONF, /* TLLI, XID Neg, N201-I, N201-U */ - LL_DATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */ - LL_DATA_IND, /* TLLI, SN-PDU */ - LL_DATA_CONF, /* TLLI, Ref */ - LL_UNITDATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */ - LL_UNITDATA_IND, /* TLLI, SN-PDU */ - LL_STATUS_IND, /* TLLI, Cause */ -}; - -/* Section 4.5.2 Logical Link States + Annex C.2 */ -enum gprs_llc_lle_state { - GPRS_LLES_UNASSIGNED = 1, /* No TLLI yet */ - GPRS_LLES_ASSIGNED_ADM = 2, /* TLLI assigned */ - GPRS_LLES_LOCAL_EST = 3, /* Local Establishment */ - GPRS_LLES_REMOTE_EST = 4, /* Remote Establishment */ - GPRS_LLES_ABM = 5, - GPRS_LLES_LOCAL_REL = 6, /* Local Release */ - GPRS_LLES_TIMER_REC = 7, /* Timer Recovery */ -}; - -enum gprs_llc_llme_state { - GPRS_LLMS_UNASSIGNED = 1, /* No TLLI yet */ - GPRS_LLMS_ASSIGNED = 2, /* TLLI assigned */ -}; - -/* Section 8.9.9 LLC layer parameter default values */ -struct gprs_llc_params { - uint16_t iov_i_exp; - uint16_t t200_201; - uint16_t n200; - uint16_t n201_u; - uint16_t n201_i; - uint16_t mD; - uint16_t mU; - uint16_t kD; - uint16_t kU; -}; - -/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */ -struct gprs_llc_lle { - struct llist_head list; - - uint32_t sapi; - - struct gprs_llc_llme *llme; - - enum gprs_llc_lle_state state; - - struct osmo_timer_list t200; - struct osmo_timer_list t201; /* wait for acknowledgement */ - - uint16_t v_sent; - uint16_t v_ack; - uint16_t v_recv; - - uint16_t vu_send; - uint16_t vu_recv; - - /* non-standard LLC state */ - uint16_t vu_recv_last; - uint16_t vu_recv_duplicates; - - /* Overflow Counter for ABM */ - uint32_t oc_i_send; - uint32_t oc_i_recv; - - /* Overflow Counter for unconfirmed transfer */ - uint32_t oc_ui_send; - uint32_t oc_ui_recv; - - unsigned int retrans_ctr; - - struct gprs_llc_params params; -}; - -#define NUM_SAPIS 16 - -struct gprs_llc_llme { - struct llist_head list; - - enum gprs_llc_llme_state state; - - uint32_t tlli; - uint32_t old_tlli; - - /* Crypto parameters */ - enum gprs_ciph_algo algo; - uint8_t kc[16]; - uint8_t cksn; - /* 3GPP TS 44.064 § 8.9.2: */ - uint32_t iov_ui; - - /* over which BSSGP BTS ctx do we need to transmit */ - uint16_t bvci; - uint16_t nsei; - struct gprs_llc_lle lle[NUM_SAPIS]; - - /* Copy of the XID fields we have sent with the last - * network originated XID-Request. Since the phone - * may strip the optional fields in the confirmation - * we need to remeber those fields in order to be - * able to create the compression entity. */ - struct llist_head *xid; - - /* Compression entities */ - struct { - /* In these two list_heads we will store the - * data and protocol compression entities, - * together with their compression states */ - struct llist_head *proto; - struct llist_head *data; - } comp; - - /* Internal management */ - uint32_t age_timestamp; -}; - -#define GPRS_LLME_RESET_AGE (0) - -extern struct llist_head gprs_llc_llmes; - -/* LLC low level types */ - -enum gprs_llc_cmd { - GPRS_LLC_NULL, - GPRS_LLC_RR, - GPRS_LLC_ACK, - GPRS_LLC_RNR, - GPRS_LLC_SACK, - GPRS_LLC_DM, - GPRS_LLC_DISC, - GPRS_LLC_UA, - GPRS_LLC_SABM, - GPRS_LLC_FRMR, - GPRS_LLC_XID, - GPRS_LLC_UI, -}; - -struct gprs_llc_hdr_parsed { - uint8_t sapi; - uint8_t is_cmd:1, - ack_req:1, - is_encrypted:1; - uint32_t seq_rx; - uint32_t seq_tx; - uint32_t fcs; - uint32_t fcs_calc; - uint8_t *data; - uint16_t data_len; - uint16_t crc_length; - enum gprs_llc_cmd cmd; -}; - - -/* BSSGP-UL-UNITDATA.ind */ -int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv); - -/* LL-UNITDATA.req */ -int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command, - struct sgsn_mm_ctx *mmctx, bool encryptable); - -/* Chapter 7.2.1.2 LLGMM-RESET.req */ -int gprs_llgmm_reset(struct gprs_llc_llme *llme); -int gprs_llgmm_reset_oldmsg(struct msgb* oldmsg, uint8_t sapi, - struct gprs_llc_llme *llme); - -/* Set of LL-XID negotiation (See also: TS 101 351, Section 7.2.2.4) */ -int gprs_ll_xid_req(struct gprs_llc_lle *lle, - struct gprs_llc_xid_field *l3_xid_field); - -/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */ -int gprs_llgmm_assign(struct gprs_llc_llme *llme, - uint32_t old_tlli, uint32_t new_tlli); -int gprs_llgmm_unassign(struct gprs_llc_llme *llme); - -int gprs_llc_init(const char *cipher_plugin_path); -int gprs_llc_vty_init(void); - -/** - * \short Check if N(U) should be considered a retransmit - * - * Implements the range check as of GSM 04.64 8.4.2 - * Receipt of unacknowledged information. - * - * @returns Returns 1 if (V(UR)-32) <= N(U) < V(UR) - * @param nu N(U) unconfirmed sequence number of the UI frame - * @param vur V(UR) unconfirmend received state variable - */ -static inline int gprs_llc_is_retransmit(uint16_t nu, uint16_t vur) -{ - int delta = (vur - nu) & 0x1ff; - return 0 < delta && delta < 32; -} - -/* LLC low level functions */ -void gprs_llme_copy_key(struct sgsn_mm_ctx *mm, struct gprs_llc_llme *llme); - -/* parse a GPRS LLC header, also check for invalid frames */ -int gprs_llc_hdr_parse(struct gprs_llc_hdr_parsed *ghp, - uint8_t *llc_hdr, int len); -void gprs_llc_hdr_dump(struct gprs_llc_hdr_parsed *gph, struct gprs_llc_lle *lle); -int gprs_llc_fcs(uint8_t *data, unsigned int len); - - -/* LLME handling routines */ -struct llist_head *gprs_llme_list(void); -struct gprs_llc_lle *gprs_lle_get_or_create(const uint32_t tlli, uint8_t sapi); - - -#endif diff --git a/include/openbsc/gprs_llc_xid.h b/include/openbsc/gprs_llc_xid.h deleted file mode 100644 index d340d40b7..000000000 --- a/include/openbsc/gprs_llc_xid.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GPRS LLC XID field encoding/decoding as per 3GPP TS 44.064 */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#pragma once - -#include -#include - -/* 3GPP TS 44.064 6.4.1.6 Exchange Identification (XID) - command/response parameter field */ -struct gprs_llc_xid_field { - struct llist_head list; - uint8_t type; /* See also Table 6: LLC layer parameter - negotiation */ - uint8_t *data; /* Payload data (memory is owned by the - * creator of the struct) */ - unsigned int data_len; /* Payload length */ -}; - -/* Transform a list with XID fields into a XID message (dst) */ -int gprs_llc_compile_xid(uint8_t *dst, int dst_maxlen, - const struct llist_head *xid_fields); - -/* Transform a XID message (dst) into a list of XID fields */ -struct llist_head *gprs_llc_parse_xid(const void *ctx, const uint8_t *src, - int src_len); - -/* Create a duplicate of an XID-Field */ -struct gprs_llc_xid_field *gprs_llc_dup_xid_field(const void *ctx, - const struct gprs_llc_xid_field *xid_field); - -/* Copy an llist with xid fields */ -struct llist_head *gprs_llc_copy_xid(const void *ctx, - const struct llist_head *xid_fields); - -/* Dump a list with XID fields (Debug) */ -void gprs_llc_dump_xid_fields(const struct llist_head *xid_fields, - unsigned int logl); - diff --git a/include/openbsc/gprs_sgsn.h b/include/openbsc/gprs_sgsn.h deleted file mode 100644 index 57995e018..000000000 --- a/include/openbsc/gprs_sgsn.h +++ /dev/null @@ -1,478 +0,0 @@ -#ifndef _GPRS_SGSN_H -#define _GPRS_SGSN_H - -#include -#include - -#include - -#include - -#include -#include - -#include - -#define GSM_EXTENSION_LENGTH 15 -#define GSM_APN_LENGTH 102 - -struct gprs_llc_lle; -struct ctrl_handle; -struct gprs_subscr; - -enum gsm48_gsm_cause; - -/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */ -enum gprs_gmm_state { - GMM_DEREGISTERED, /* 4.1.3.3.1.1 */ - GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */ - GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */ - GMM_REGISTERED_SUSPENDED, /* 4.1.3.3.2.2 */ - GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */ -}; - -/* TS 23.060 6.1.1 and 6.1.2 Mobility management states A/Gb and Iu mode */ -enum gprs_pmm_state { - PMM_DETACHED, - PMM_CONNECTED, - PMM_IDLE, - MM_IDLE, - MM_READY, - MM_STANDBY, -}; - -enum gprs_mm_ctr { - GMM_CTR_PKTS_SIG_IN, - GMM_CTR_PKTS_SIG_OUT, - GMM_CTR_PKTS_UDATA_IN, - GMM_CTR_PKTS_UDATA_OUT, - GMM_CTR_BYTES_UDATA_IN, - GMM_CTR_BYTES_UDATA_OUT, - GMM_CTR_PDP_CTX_ACT, - GMM_CTR_SUSPEND, - GMM_CTR_PAGING_PS, - GMM_CTR_PAGING_CS, - GMM_CTR_RA_UPDATE, -}; - -enum gprs_pdp_ctx { - PDP_CTR_PKTS_UDATA_IN, - PDP_CTR_PKTS_UDATA_OUT, - PDP_CTR_BYTES_UDATA_IN, - PDP_CTR_BYTES_UDATA_OUT, -}; - -enum gprs_t3350_mode { - GMM_T3350_MODE_NONE, - GMM_T3350_MODE_ATT, - GMM_T3350_MODE_RAU, - GMM_T3350_MODE_PTMSI_REALL, -}; - -/* Authorization/ACL handling */ -enum sgsn_auth_state { - SGSN_AUTH_UNKNOWN, - SGSN_AUTH_AUTHENTICATE, - SGSN_AUTH_UMTS_RESYNC, - SGSN_AUTH_ACCEPTED, - SGSN_AUTH_REJECTED -}; - -#define MS_RADIO_ACCESS_CAPA - -enum sgsn_ggsn_lookup_state { - SGSN_GGSN_2DIGIT, - SGSN_GGSN_3DIGIT, -}; - -struct sgsn_ggsn_lookup { - int state; - - struct sgsn_mm_ctx *mmctx; - - /* APN string */ - char apn_str[GSM_APN_LENGTH]; - - /* the original data */ - struct msgb *orig_msg; - struct tlv_parsed tp; - - /* for dealing with re-transmissions */ - uint8_t nsapi; - uint8_t sapi; - uint8_t ti; -}; - -enum sgsn_ran_type { - /* GPRS/EDGE via Gb */ - MM_CTX_T_GERAN_Gb, - /* UMTS via Iu */ - MM_CTX_T_UTRAN_Iu, - /* GPRS/EDGE via Iu */ - MM_CTX_T_GERAN_Iu, -}; - -struct service_info { - uint8_t type; - uint16_t pdp_status; -}; - -struct ranap_ue_conn_ctx; - -/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */ -/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */ -struct sgsn_mm_ctx { - struct llist_head list; - - enum sgsn_ran_type ran_type; - - char imsi[GSM23003_IMSI_MAX_DIGITS+1]; - enum gprs_gmm_state gmm_state; - enum gprs_pmm_state pmm_state; /* Iu: page when in PMM-IDLE mode */ - uint32_t p_tmsi; - uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */ - uint32_t p_tmsi_sig; - char imei[GSM23003_IMEISV_NUM_DIGITS+1]; - /* Opt: Software Version Numbber / TS 23.195 */ - char msisdn[GSM_EXTENSION_LENGTH]; - struct gprs_ra_id ra; - struct { - uint16_t cell_id; /* Gb only */ - uint32_t cell_id_age; /* Gb only */ - uint8_t radio_prio_sms; - - /* Additional bits not present in the GSM TS */ - uint16_t nsei; - uint16_t bvci; - struct gprs_llc_llme *llme; - uint32_t tlli; - uint32_t tlli_new; - } gb; - struct { - int new_key; - uint16_t sac; /* Iu: Service Area Code */ - uint32_t sac_age; /* Iu: Service Area Code age */ - /* CSG ID */ - /* CSG Membership */ - /* Access Mode */ - /* Seelected CN Operator ID (TS 23.251) */ - /* CSG Subscription Data */ - /* LIPA Allowed */ - /* Voice Support Match Indicator */ - struct ranap_ue_conn_ctx *ue_ctx; - struct service_info service; - } iu; - /* VLR number */ - uint32_t new_sgsn_addr; - /* Authentication Triplet */ - struct gsm_auth_tuple auth_triplet; - /* Kc */ - /* Iu: CK, IK, KSI */ - /* CKSN */ - enum gprs_ciph_algo ciph_algo; - /* Auth & Ciphering Request reference from 3GPP TS 24.008 § 10.5.5.19: */ - uint8_t ac_ref_nr_used; - - struct { - uint8_t len; - uint8_t buf[50]; /* GSM 04.08 10.5.5.12a, extended in TS 24.008 */ - } ms_radio_access_capa; - /* Supported Codecs (SRVCC) */ - struct { - uint8_t len; - uint8_t buf[8]; /* GSM 04.08 10.5.5.12, extended in TS 24.008 */ - } ms_network_capa; - /* UE Netowrk Capability (E-UTRAN) */ - uint16_t drx_parms; - /* Active Time value for PSM */ - int mnrg; /* MS reported to HLR? */ - int ngaf; /* MS reported to MSC/VLR? */ - int ppf; /* paging for GPRS + non-GPRS? */ - /* Subscribed Charging Characteristics */ - /* Trace Reference */ - /* Trace Type */ - /* Trigger ID */ - /* OMC Identity */ - /* SMS Parameters */ - int recovery; - /* Access Restriction */ - /* GPRS CSI (CAMEL) */ - /* MG-CSI (CAMEL) */ - /* Subscribed UE-AMBR */ - /* UE-AMBR */ - /* APN Subscribed */ - - struct llist_head pdp_list; - - struct rate_ctr_group *ctrg; - struct osmo_timer_list timer; - unsigned int T; /* Txxxx number */ - unsigned int num_T_exp; /* number of consecutive T expirations */ - - enum gprs_t3350_mode t3350_mode; - uint8_t t3370_id_type; - uint8_t pending_req; /* the request's message type */ - /* TODO: There isn't much semantic difference between t3350_mode - * (refers to the timer) and pending_req (refers to the procedure), - * where mm->T == 3350 => mm->t3350_mode == f(mm->pending_req). Check - * whether one of them can be dropped. */ - - enum sgsn_auth_state auth_state; - int is_authenticated; - - /* the string representation of the current hlr */ - char hlr[GSM_EXTENSION_LENGTH]; - - /* the current GGSN look-up operation */ - struct sgsn_ggsn_lookup *ggsn_lookup; - - struct gprs_subscr *subscr; -}; - -#define LOGMMCTXP(level, mm, fmt, args...) \ - LOGP(DMM, level, "MM(%s/%08x) " fmt, (mm) ? (mm)->imsi : "---", \ - (mm) ? (mm)->p_tmsi : GSM_RESERVED_TMSI, ## args) - -/* look-up a SGSN MM context based on TLLI + RAI */ -struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, - const struct gprs_ra_id *raid); -struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi); -struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi); -struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx); - -/* look-up by matching TLLI and P-TMSI (think twice before using this) */ -struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli, - const struct gprs_ra_id *raid); - -/* Allocate a new SGSN MM context */ -struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli, - const struct gprs_ra_id *raid); -struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx); - -void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx); - -struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, - struct tlv_parsed *tp, - enum gsm48_gsm_cause *gsm_cause, - char *apn_str); - -enum pdp_ctx_state { - PDP_STATE_NONE, - PDP_STATE_CR_REQ, - PDP_STATE_CR_CONF, - - /* 04.08 / Figure 6.2 / 6.1.2.2 */ - PDP_STATE_INACT_PEND, - PDP_STATE_INACTIVE = PDP_STATE_NONE, -}; - -enum pdp_type { - PDP_TYPE_NONE, - PDP_TYPE_ETSI_PPP, - PDP_TYPE_IANA_IPv4, - PDP_TYPE_IANA_IPv6, -}; - -struct sgsn_pdp_ctx { - struct llist_head list; /* list_head for mmctx->pdp_list */ - struct llist_head g_list; /* list_head for global list */ - struct sgsn_mm_ctx *mm; /* back pointer to MM CTX */ - int destroy_ggsn; /* destroy it on destruction */ - struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */ - struct rate_ctr_group *ctrg; - - //unsigned int id; - struct pdp_t *lib; /* pointer to libgtp PDP ctx */ - enum pdp_ctx_state state; - enum pdp_type type; - uint32_t address; - char *apn_subscribed; - //char *apn_used; - uint16_t nsapi; /* SNDCP */ - uint16_t sapi; /* LLC */ - uint8_t ti; /* transaction identifier */ - int vplmn_allowed; - uint32_t qos_profile_subscr; - //uint32_t qos_profile_req; - //uint32_t qos_profile_neg; - uint8_t radio_prio; - //uint32_t charging_id; - - struct osmo_timer_list timer; - unsigned int T; /* Txxxx number */ - unsigned int num_T_exp; /* number of consecutive T expirations */ - - struct osmo_timer_list cdr_timer; /* CDR record wird timer */ - struct timespec cdr_start; /* The start of the CDR */ - uint64_t cdr_bytes_in; - uint64_t cdr_bytes_out; - uint32_t cdr_charging_id; -}; - -#define LOGPDPCTXP(level, pdp, fmt, args...) \ - LOGP(DGPRS, level, "PDP(%s/%u) " \ - fmt, (pdp)->mm ? (pdp)->mm->imsi : "---", (pdp)->ti, ## args) - -/* look up PDP context by MM context and NSAPI */ -struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm, - uint8_t nsapi); -/* look up PDP context by MM context and transaction ID */ -struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm, - uint8_t tid); - -struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm, - uint8_t nsapi); -void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp); -void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp); - - -struct sgsn_ggsn_ctx { - struct llist_head list; - uint32_t id; - unsigned int gtp_version; - struct in_addr remote_addr; - int remote_restart_ctr; - struct gsn_t *gsn; -}; -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id); -void sgsn_ggsn_ctx_free(struct sgsn_ggsn_ctx *ggc); -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_id(uint32_t id); -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_addr(struct in_addr *addr); -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id); - -struct apn_ctx { - struct llist_head list; - struct sgsn_ggsn_ctx *ggsn; - char *name; - char *imsi_prefix; - char *description; -}; - -struct apn_ctx *sgsn_apn_ctx_find_alloc(const char *name, const char *imsi_prefix); -void sgsn_apn_ctx_free(struct apn_ctx *actx); -struct apn_ctx *sgsn_apn_ctx_by_name(const char *name, const char *imsi_prefix); -struct apn_ctx *sgsn_apn_ctx_match(const char *name, const char *imsi_prefix); - -extern struct llist_head sgsn_mm_ctxts; -extern struct llist_head sgsn_ggsn_ctxts; -extern struct llist_head sgsn_apn_ctxts; -extern struct llist_head sgsn_pdp_ctxts; - -uint32_t sgsn_alloc_ptmsi(void); -void sgsn_inst_init(void); - -/* High-level function to be called in case a GGSN has disappeared or - * ottherwise lost state (recovery procedure) */ -int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn); - -char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len); - -/* - * ctrl interface related work - */ -struct gsm_network; -struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *, - const char *bind_addr, uint16_t port); -int sgsn_ctrl_cmds_install(void); - -/* - * Authorization/ACL handling - */ -struct imsi_acl_entry { - struct llist_head list; - char imsi[16+1]; -}; - -/* see GSM 09.02, 17.7.1, PDP-Context and GPRSSubscriptionData */ -/* see GSM 09.02, B.1, gprsSubscriptionData */ -struct sgsn_subscriber_pdp_data { - struct llist_head list; - - unsigned int context_id; - uint16_t pdp_type; - char apn_str[GSM_APN_LENGTH]; - uint8_t qos_subscribed[20]; - size_t qos_subscribed_len; - uint8_t pdp_charg[2]; - bool has_pdp_charg; -}; - -struct sgsn_subscriber_data { - struct sgsn_mm_ctx *mm; - struct gsm_auth_tuple auth_triplets[5]; - int auth_triplets_updated; - struct llist_head pdp_list; - int error_cause; - - uint8_t msisdn[9]; - size_t msisdn_len; - - uint8_t hlr[9]; - size_t hlr_len; - - uint8_t pdp_charg[2]; - bool has_pdp_charg; -}; - -#define SGSN_ERROR_CAUSE_NONE (-1) - -#define LOGGSUBSCRP(level, subscr, fmt, args...) \ - LOGP(DGPRS, level, "SUBSCR(%s) " fmt, \ - (subscr) ? (subscr)->imsi : "---", \ - ## args) - -struct sgsn_config; -struct sgsn_instance; -extern const struct value_string *sgsn_auth_state_names; - -void sgsn_auth_init(void); -struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg); -int sgsn_acl_add(const char *imsi, struct sgsn_config *cfg); -int sgsn_acl_del(const char *imsi, struct sgsn_config *cfg); -/* Request authorization */ -int sgsn_auth_request(struct sgsn_mm_ctx *mm); -enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mm); -void sgsn_auth_update(struct sgsn_mm_ctx *mm); -struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx, - unsigned key_seq); - -/* - * GPRS subscriber data - */ -#define GPRS_SUBSCRIBER_FIRST_CONTACT 0x00000001 -#define GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING (1 << 16) -#define GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING (1 << 17) -#define GPRS_SUBSCRIBER_CANCELLED (1 << 18) -#define GPRS_SUBSCRIBER_ENABLE_PURGE (1 << 19) - -#define GPRS_SUBSCRIBER_UPDATE_PENDING_MASK ( \ - GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING | \ - GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING \ -) - -int gprs_subscr_init(struct sgsn_instance *sgi); -int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx); -int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, - const uint8_t *auts, - const uint8_t *auts_rand); -int gprs_subscr_auth_sync(struct gprs_subscr *subscr, - const uint8_t *auts, const uint8_t *auts_rand); -void gprs_subscr_cleanup(struct gprs_subscr *subscr); -struct gprs_subscr *gprs_subscr_get_or_create(const char *imsi); -struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx( struct sgsn_mm_ctx *mmctx); -struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi); -void gprs_subscr_cancel(struct gprs_subscr *subscr); -void gprs_subscr_update(struct gprs_subscr *subscr); -void gprs_subscr_update_auth_info(struct gprs_subscr *subscr); -int gprs_subscr_rx_gsup_message(struct msgb *msg); - -/* Called on subscriber data updates */ -void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx); - -int gprs_sndcp_vty_init(void); -struct sgsn_instance; -int sgsn_gtp_init(struct sgsn_instance *sgi); - -void sgsn_rate_ctr_init(); - -#endif /* _GPRS_SGSN_H */ diff --git a/include/openbsc/gprs_sndcp.h b/include/openbsc/gprs_sndcp.h deleted file mode 100644 index d970240e4..000000000 --- a/include/openbsc/gprs_sndcp.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _INT_SNDCP_H -#define _INT_SNDCP_H - -#include -#include - -/* A fragment queue header, maintaining list of fragments for one N-PDU */ -struct defrag_state { - /* PDU number for which the defragmentation state applies */ - uint16_t npdu; - /* highest segment number we have received so far */ - uint8_t highest_seg; - /* bitmask of the segments we already have */ - uint32_t seg_have; - /* do we still expect more segments? */ - unsigned int no_more; - /* total length of all segments together */ - unsigned int tot_len; - - /* linked list of defrag_queue_entry: one for each fragment */ - struct llist_head frag_list; - - struct osmo_timer_list timer; - - /* Holds state to know which compression mode is used - * when the packet is re-assembled */ - uint8_t pcomp; - uint8_t dcomp; - - /* Holds the pointers to the compression entity list - * that is used when the re-assembled packet is decompressed */ - struct llist_head *proto; - struct llist_head *data; -}; - -/* See 6.7.1.2 Reassembly */ -enum sndcp_rx_state { - SNDCP_RX_S_FIRST, - SNDCP_RX_S_SUBSEQ, - SNDCP_RX_S_DISCARD, -}; - -struct gprs_sndcp_entity { - struct llist_head list; - - /* FIXME: move this RA_ID up to the LLME or even higher */ - struct gprs_ra_id ra_id; - /* reference to the LLC Entity below this SNDCP entity */ - struct gprs_llc_lle *lle; - /* The NSAPI we shall use on top of LLC */ - uint8_t nsapi; - - /* NPDU number for the GTP->SNDCP side */ - uint16_t tx_npdu_nr; - /* SNDCP eeceiver state */ - enum sndcp_rx_state rx_state; - /* The defragmentation queue */ - struct defrag_state defrag; -}; - -extern struct llist_head gprs_sndcp_entities; - -/* Set of SNDCP-XID negotiation (See also: TS 144 065, - * Section 6.8 XID parameter negotiation) */ -int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); - -/* Process SNDCP-XID indication (See also: TS 144 065, - * Section 6.8 XID parameter negotiation) */ -int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, - struct gprs_llc_xid_field *xid_field_response, - struct gprs_llc_lle *lle); - -/* Process SNDCP-XID indication - * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ -int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, - struct gprs_llc_xid_field *xid_field_request, - struct gprs_llc_lle *lle); - -#endif /* INT_SNDCP_H */ diff --git a/include/openbsc/gprs_sndcp_comp.h b/include/openbsc/gprs_sndcp_comp.h deleted file mode 100644 index 87ab6382a..000000000 --- a/include/openbsc/gprs_sndcp_comp.h +++ /dev/null @@ -1,82 +0,0 @@ -/* GPRS SNDCP header compression entity management tools */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#pragma once - -#include -#include -#include - -/* Header / Data compression entity */ -struct gprs_sndcp_comp { - struct llist_head list; - - /* Serves as an ID in case we want to delete this entity later */ - unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ - - /* Specifies to which NSAPIs the compression entity is assigned */ - uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - - /* Assigned pcomp values */ - uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ - uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ - - /* Algorithm parameters */ - int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ - int compclass; /* See gprs_sndcp_xid.h/c */ - void *state; /* Algorithm status and parameters */ -}; - -#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ -#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ - -/* Allocate a compression enitiy list */ -struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); - -/* Free a compression entitiy list */ -void gprs_sndcp_comp_free(struct llist_head *comp_entities); - -/* Delete a compression entity */ -void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); - -/* Create and Add a new compression entity - * (returns a pointer to the compression entity that has just been created) */ -struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, - struct llist_head *comp_entities, - const struct gprs_sndcp_comp_field - *comp_field); - -/* Find which compression entity handles the specified pcomp/dcomp */ -struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head - *comp_entities, uint8_t comp); - -/* Find which compression entity handles the specified nsapi */ -struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head - *comp_entities, uint8_t nsapi); - -/* Find a comp_index for a given pcomp/dcomp value */ -uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, - uint8_t comp); - -/* Find a pcomp/dcomp value for a given comp_index */ -uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, - uint8_t comp_index); diff --git a/include/openbsc/gprs_sndcp_dcomp.h b/include/openbsc/gprs_sndcp_dcomp.h deleted file mode 100644 index a76b4a4b3..000000000 --- a/include/openbsc/gprs_sndcp_dcomp.h +++ /dev/null @@ -1,53 +0,0 @@ -/* GPRS SNDCP data compression handler */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#pragma once - -#include -#include -#include - -/* Note: The decompressed packet may have a maximum size of: - * Return value * MAX_DATADECOMPR_FAC */ -#define MAX_DATADECOMPR_FAC 10 - -/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset - * for every NPDU. The compressor needs a reasonably large payload to operate - * effectively (yield positive compression gain). For packets shorter than 100 - * byte, no positive compression gain can be expected so we will skip the - * compression for short packets. */ -#define MIN_COMPR_PAYLOAD 100 - -/* Initalize data compression */ -int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, - const struct gprs_sndcp_comp_field *comp_field); - -/* Terminate data compression */ -void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity); - -/* Expand packet */ -int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, - const struct llist_head *comp_entities); - -/* Compress packet */ -int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, - const struct llist_head *comp_entities, - uint8_t nsapi); diff --git a/include/openbsc/gprs_sndcp_pcomp.h b/include/openbsc/gprs_sndcp_pcomp.h deleted file mode 100644 index 4e15b9be2..000000000 --- a/include/openbsc/gprs_sndcp_pcomp.h +++ /dev/null @@ -1,46 +0,0 @@ -/* GPRS SNDCP header compression handler */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#pragma once - -#include -#include -#include - -/* Note: The decompressed packet may have a maximum size of: - * Return value + MAX_DECOMPR_INCR */ -#define MAX_HDRDECOMPR_INCR 64 - -/* Initalize header compression */ -int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, - const struct gprs_sndcp_comp_field *comp_field); - -/* Terminate header compression */ -void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); - -/* Expand packet header */ -int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, - const struct llist_head *comp_entities); - -/* Compress packet header */ -int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, - const struct llist_head *comp_entities, - uint8_t nsapi); diff --git a/include/openbsc/gprs_sndcp_xid.h b/include/openbsc/gprs_sndcp_xid.h deleted file mode 100644 index e64bc5237..000000000 --- a/include/openbsc/gprs_sndcp_xid.h +++ /dev/null @@ -1,218 +0,0 @@ -/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#pragma once - -#include -#include - -#define DEFAULT_SNDCP_VERSION 0 /* See 3GPP TS 44.065, clause 8 */ -#define MAX_ENTITIES 32 /* 3GPP TS 44.065 reserves 5 bit - * for compression enitity number */ - -#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ -#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ -#define MAX_ROHC 16 /* Maximum number of ROHC compression profiles */ - -/* According to: 3GPP TS 44.065, 6.5.1.1 Format of the protocol control - * information compression field (Figure 7) and 3GPP TS 44.065, - * 6.6.1.1 Format of the data compression field (Figure 9) */ -struct gprs_sndcp_comp_field { - struct llist_head list; - - /* Propose bit (P), see also: 6.5.1.1.2 and 6.6.1.1.2 */ - unsigned int p; - - /* Entity number, see also: 6.5.1.1.3 and 6.6.1.1.3 */ - unsigned int entity; - - /* Algorithm identifier, see also: 6.5.1.1.4 and 6.6.1.1.4 */ - int algo; - - /* Number of contained PCOMP / DCOMP values */ - uint8_t comp_len; - - /* PCOMP / DCOMP values, see also: 6.5.1.1.5 and 6.6.1.1.5 */ - uint8_t comp[MAX_COMP]; - - /* Note: Only one of the following struct pointers may, - be used. Unused pointers must be set to NULL! */ - struct gprs_sndcp_pcomp_rfc1144_params *rfc1144_params; - struct gprs_sndcp_pcomp_rfc2507_params *rfc2507_params; - struct gprs_sndcp_pcomp_rohc_params *rohc_params; - struct gprs_sndcp_dcomp_v42bis_params *v42bis_params; - struct gprs_sndcp_dcomp_v44_params *v44_params; -}; - -/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ -enum gprs_sndcp_hdr_comp_algo { - RFC_1144, /* TCP/IP header compression, see also 6.5.2 */ - RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */ - ROHC /* Robust Header Compression, see also 6.5.4 */ -}; - -/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ -enum gprs_sndcp_data_comp_algo { - V42BIS, /* V.42bis data compression, see also 6.6.2 */ - V44 /* V44 data compression, see also: 6.6.3 */ -}; - -/* According to: 3GPP TS 44.065, 8 SNDCP XID parameters */ -enum gprs_sndcp_xid_param_types { - SNDCP_XID_VERSION_NUMBER, - SNDCP_XID_DATA_COMPRESSION, /* See also: subclause 6.6.1 */ - SNDCP_XID_PROTOCOL_COMPRESSION, /* See also: subclause 6.5.1 */ -}; - -/* According to: 3GPP TS 44.065, 6.5.2.1 Parameters (Table 5) */ -struct gprs_sndcp_pcomp_rfc1144_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int s01; /* (default 15) */ -}; - -/* According to: 3GPP TS 44.065, 6.5.2.2 Assignment of PCOMP values */ -enum gprs_sndcp_pcomp_rfc1144_pcomp { - RFC1144_PCOMP1, /* Uncompressed TCP */ - RFC1144_PCOMP2, /* Compressed TCP */ - RFC1144_PCOMP_NUM /* Number of pcomp values */ -}; - -/* According to: 3GPP TS 44.065, 6.5.3.1 Parameters (Table 6) */ -struct gprs_sndcp_pcomp_rfc2507_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int f_max_period; /* (default 256) */ - int f_max_time; /* (default 5) */ - int max_header; /* (default 168) */ - int tcp_space; /* (default 15) */ - int non_tcp_space; /* (default 15) */ -}; - -/* According to: 3GPP TS 44.065, 6.5.3.2 Assignment of PCOMP values for RFC2507 */ -enum gprs_sndcp_pcomp_rfc2507_pcomp { - RFC2507_PCOMP1, /* Full Header */ - RFC2507_PCOMP2, /* Compressed TCP */ - RFC2507_PCOMP3, /* Compressed TCP non delta */ - RFC2507_PCOMP4, /* Compressed non TCP */ - RFC2507_PCOMP5, /* Context state */ - RFC2507_PCOMP_NUM /* Number of pcomp values */ -}; - -/* According to: 3GPP TS 44.065, 6.5.4.1 Parameter (Table 10) */ -struct gprs_sndcp_pcomp_rohc_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int max_cid; /* (default 15) */ - int max_header; /* (default 168) */ - uint8_t profile_len; /* (default 1) */ - uint16_t profile[MAX_ROHC]; /* (default 0, ROHC uncompressed) */ -}; - -/* According to: 3GPP TS 44.065, 6.5.4.2 Assignment of PCOMP values for ROHC */ -enum gprs_sndcp_pcomp_rohc_pcomp { - ROHC_PCOMP1, /* ROHC small CIDs */ - ROHC_PCOMP2, /* ROHC large CIDs */ - ROHC_PCOMP_NUM /* Number of pcomp values */ -}; - -/* ROHC compression profiles, see also: - http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.xhtml */ -enum gprs_sndcp_xid_rohc_profiles { - ROHC_UNCOMPRESSED = 0x0000, /* ROHC uncompressed [RFC5795] */ - ROHC_RTP = 0x0001, /* ROHC RTP [RFC3095] */ - ROHCV2_RTP = 0x0101, /* ROHCv2 RTP [RFC5225] */ - ROHC_UDP = 0x0002, /* ROHC UDP [RFC3095] */ - ROHCv2_UDP = 0x0102, /* ROHCv2 UDP [RFC5225] */ - ROHC_ESP = 0x0003, /* ROHC ESP [RFC3095] */ - ROHCV2_ESP = 0x0103, /* ROHCv2 ESP [RFC5225] */ - ROHC_IP = 0x0004, /* ROHC IP [RFC3843] */ - ROHCV2_IP = 0x0104, /* ROHCv2 IP [RFC5225] */ - ROHC_LLA = 0x0005, /* ROHC LLA [RFC4362] */ - ROHC_LLA_WITH_R_MODE = 0x0105, /* ROHC LLA with R-mode [RFC3408] */ - ROHC_TCP = 0x0006, /* ROHC TCP [RFC6846] */ - ROHC_RTP_UDP_LITE = 0x0007, /* ROHC RTP/UDP-Lite [RFC4019] */ - ROHCV2_RTP_UDP_LITE = 0x0107, /* ROHCv2 RTP/UDP-Lite [RFC5225] */ - ROHC_UDP_LITE = 0x0008, /* ROHC UDP-Lite [RFC4019] */ - ROHCV2_UDP_LITE = 0x0108, /* ROHCv2 UDP-Lite [RFC5225] */ -}; - -/* According to: 3GPP TS 44.065, 6.6.2.1 Parameters (Table 7a) */ -struct gprs_sndcp_dcomp_v42bis_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int p0; /* (default 3) */ - int p1; /* (default 2048) */ - int p2; /* (default 20) */ - -}; - -/* According to: 3GPP TS 44.065, 6.6.2.2 Assignment of DCOMP values */ -enum gprs_sndcp_dcomp_v42bis_dcomp { - V42BIS_DCOMP1, /* V.42bis enabled */ - V42BIS_DCOMP_NUM /* Number of dcomp values */ -}; - -/* According to: 3GPP TS 44.065, 6.6.3.1 Parameters (Table 7c) */ -struct gprs_sndcp_dcomp_v44_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int c0; /* (default 10000000) */ - int p0; /* (default 3) */ - int p1t; /* Refer to subclause 6.6.3.1.4 */ - int p1r; /* Refer to subclause 6.6.3.1.5 */ - int p3t; /* (default 3 x p1t) */ - int p3r; /* (default 3 x p1r) */ -}; - -/* According to: 3GPP TS 44.065, 6.6.3.2 Assignment of DCOMP values */ -enum gprs_sndcp_dcomp_v44_dcomp { - V44_DCOMP1, /* Packet method compressed */ - V44_DCOMP2, /* Multi packet method compressed */ - V44_DCOMP_NUM /* Number of dcomp values */ -}; - -/* Transform a list with compression fields into an SNDCP-XID message (dst) */ -int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, - const struct llist_head *comp_fields, int version); - -/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ -struct llist_head *gprs_sndcp_parse_xid(int *version, - const void *ctx, - const uint8_t *src, - unsigned int src_len, - const struct llist_head - *comp_fields_req); - -/* Find out to which compression class the specified comp-field belongs - * (header compression or data compression?) */ -int gprs_sndcp_get_compression_class( - const struct gprs_sndcp_comp_field *comp_field); - -/* Dump a list with SNDCP-XID fields (Debug) */ -void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, - unsigned int logl); - diff --git a/include/openbsc/gprs_subscriber.h b/include/openbsc/gprs_subscriber.h deleted file mode 100644 index be78febff..000000000 --- a/include/openbsc/gprs_subscriber.h +++ /dev/null @@ -1,31 +0,0 @@ -/* GPRS subscriber details for use in SGSN land */ -#pragma once - -#include - -#include -#include - -extern struct llist_head * const gprs_subscribers; - -struct gprs_subscr { - struct llist_head entry; - int use_count; - - char imsi[GSM23003_IMSI_MAX_DIGITS+1]; - uint32_t tmsi; - char imei[GSM23003_IMEISV_NUM_DIGITS+1]; - bool authorized; - bool keep_in_ram; - uint32_t flags; - uint16_t lac; - - struct sgsn_subscriber_data *sgsn_data; -}; - -struct gprs_subscr *_gprs_subscr_get(struct gprs_subscr *gsub, - const char *file, int line); -struct gprs_subscr *_gprs_subscr_put(struct gprs_subscr *gsub, - const char *file, int line); -#define gprs_subscr_get(gsub) _gprs_subscr_get(gsub, __BASE_FILE__, __LINE__) -#define gprs_subscr_put(gsub) _gprs_subscr_put(gsub, __BASE_FILE__, __LINE__) diff --git a/include/openbsc/gprs_utils.h b/include/openbsc/gprs_utils.h deleted file mode 100644 index 574f5c50c..000000000 --- a/include/openbsc/gprs_utils.h +++ /dev/null @@ -1,44 +0,0 @@ -/* GPRS utility functions */ - -/* (C) 2010 by Harald Welte - * (C) 2010-2014 by On-Waves - * (C) 2013 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ -#pragma once - -#include -#include - -struct msgb; -struct gprs_ra_id; - -struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name); -int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area, - size_t old_size, size_t new_size); -int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str); - -/* GSM 04.08, 10.5.7.3 GPRS Timer */ -int gprs_tmr_to_secs(uint8_t tmr); -uint8_t gprs_secs_to_tmr_floor(int secs); - -int gprs_is_mi_tmsi(const uint8_t *value, size_t value_len); -int gprs_is_mi_imsi(const uint8_t *value, size_t value_len); -int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi); -void gprs_parse_tmsi(const uint8_t *value, uint32_t *tmsi); - -int gprs_ra_id_equals(const struct gprs_ra_id *id1, const struct gprs_ra_id *id2); diff --git a/include/openbsc/gsm_04_08.h b/include/openbsc/gsm_04_08.h deleted file mode 100644 index ca251b00b..000000000 --- a/include/openbsc/gsm_04_08.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef _GSM_04_08_H -#define _GSM_04_08_H - -#include -#include -#include - -#include - -struct msgb; -struct gsm_bts; -struct gsm_network; -struct gsm_trans; -struct gsm_subscriber_connection; -struct amr_multirate_conf; -struct amr_mode; -struct bsc_subscr; - -#define GSM48_ALLOC_SIZE 2048 -#define GSM48_ALLOC_HEADROOM 256 - -static inline struct msgb *gsm48_msgb_alloc_name(const char *name) -{ - return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM, - name); -} - -void cm_service_request_concludes(struct gsm_subscriber_connection *conn, - struct msgb *msg); - -/* config options controlling the behaviour of the lower leves */ -void gsm0408_allow_everyone(int allow); -void gsm0408_clear_all_trans(struct gsm_network *net, int protocol); -int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg); - -int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id); -enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *bts, uint8_t ra); -/* don't use "enum gsm_chreq_reason_t" to avoid circular dependency */ -int get_reason_by_chreq(uint8_t ra, int neci); -void gsm_net_update_ctype(struct gsm_network *net); - -int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn); -int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand, - uint8_t *autn, int key_seq); -int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn); -int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn); -int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, - enum gsm48_reject_value value); -int gsm48_send_rr_release(struct gsm_lchan *lchan); -int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv); -int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_id, - uint8_t apdu_len, const uint8_t *apdu); -int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, uint8_t power_class); -int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan, - uint8_t power_command, uint8_t ho_ref); - -int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg); - -/* convert a ASCII phone number to call-control BCD */ -int encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len, - int h_len, const char *input); -int decode_bcd_number(char *output, int output_len, const uint8_t *bcd_lv, - int h_len); - -int send_siemens_mrpci(struct gsm_lchan *lchan, uint8_t *classmark2_lv); -int gsm48_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type); -int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, uint8_t *mi_type); - -int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t lchan_mode); -int gsm48_rx_rr_modif_ack(struct msgb *msg); -int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg); - -struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value); -struct msgb *gsm48_create_loc_upd_rej(uint8_t cause); -void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd, - const struct gsm_lchan *lchan); - -void release_security_operation(struct gsm_subscriber_connection *conn); -void allocate_security_operation(struct gsm_subscriber_connection *conn); - -int gsm48_multirate_config(uint8_t *lv, const struct amr_multirate_conf *mr, const struct amr_mode *modes); - -int gsm48_tch_rtp_create(struct gsm_trans *trans); - -#endif diff --git a/include/openbsc/gsm_04_08_utils.h b/include/openbsc/gsm_04_08_utils.h new file mode 100644 index 000000000..625f173ca --- /dev/null +++ b/include/openbsc/gsm_04_08_utils.h @@ -0,0 +1,32 @@ +#pragma once + +void gsm_net_update_ctype(struct gsm_network *network); +enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *network, uint8_t ra); +int get_reason_by_chreq(uint8_t ra, int neci); +int gsm48_send_rr_release(struct gsm_lchan *lchan); +int send_siemens_mrpci(struct gsm_lchan *lchan, + uint8_t *classmark2_lv); +int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, + struct msgb *msg, struct bsc_subscr *bsub); +int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv); +void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd, + const struct gsm_lchan *lchan); +int gsm48_multirate_config(uint8_t *lv, const struct amr_multirate_conf *mr, const struct amr_mode *modes); +int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan, + uint8_t power_command, uint8_t ho_ref); +int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, uint8_t power_command); +int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t mode); +int gsm48_rx_rr_modif_ack(struct msgb *msg); +int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg); +int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn); +int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, + enum gsm48_reject_value value); + +#define GSM48_ALLOC_SIZE 2048 +#define GSM48_ALLOC_HEADROOM 256 + +static inline struct msgb *gsm48_msgb_alloc_name(const char *name) +{ + return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM, + name); +} diff --git a/include/openbsc/gsm_04_11.h b/include/openbsc/gsm_04_11.h deleted file mode 100644 index 3305e3e61..000000000 --- a/include/openbsc/gsm_04_11.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _GSM_04_11_H -#define _GSM_04_11_H - -#include - -struct vlr_subscr; -struct gsm_subscriber_connection; -struct gsm_trans; - -#define UM_SAPI_SMS 3 /* See GSM 04.05/04.06 */ - -/* SMS deliver PDU */ -struct sms_deliver { - uint8_t mti:2; /* message type indicator */ - uint8_t mms:1; /* more messages to send */ - uint8_t rp:1; /* reply path */ - uint8_t udhi:1; /* user data header indicator */ - uint8_t sri:1; /* status report indication */ - uint8_t *orig_addr; /* originating address */ - uint8_t pid; /* protocol identifier */ - uint8_t dcs; /* data coding scheme */ - /* service centre time stamp */ - uint8_t ud_len; /* user data length */ - uint8_t *user_data; /* user data */ - - uint8_t msg_ref; /* message reference */ - uint8_t *smsc; -}; - -struct msgb; - -int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, struct msgb *msg); - -struct gsm_sms *sms_alloc(void); -void sms_free(struct gsm_sms *sms); -struct gsm_sms *sms_from_text(struct vlr_subscr *receiver, - struct vlr_subscr *sender, - int dcs, const char *text); - -void _gsm411_sms_trans_free(struct gsm_trans *trans); -int gsm411_send_sms_subscr(struct vlr_subscr *vsub, - struct gsm_sms *sms); -int gsm411_send_sms(struct gsm_subscriber_connection *conn, - struct gsm_sms *sms); -void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn); - -uint8_t sms_next_rp_msg_ref(uint8_t *next_rp_ref); - -int gsm411_send_rp_ack(struct gsm_trans *trans, uint8_t msg_ref); -int gsm411_send_rp_error(struct gsm_trans *trans, uint8_t msg_ref, - uint8_t cause); - -#endif diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h index 88a4f1067..74970b92e 100644 --- a/include/openbsc/gsm_data.h +++ b/include/openbsc/gsm_data.h @@ -31,6 +31,7 @@ struct bsc_subscr; struct vlr_instance; struct vlr_subscr; struct ranap_ue_conn_ctx; +struct gprs_ra_id; #define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3] diff --git a/include/openbsc/gsm_data_shared.h b/include/openbsc/gsm_data_shared.h index bed46d254..bef450430 100644 --- a/include/openbsc/gsm_data_shared.h +++ b/include/openbsc/gsm_data_shared.h @@ -25,6 +25,7 @@ #endif #include +#include /* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1: 4-bit index is used (2#1111 = 10#15) */ diff --git a/include/openbsc/gsup_client.h b/include/openbsc/gsup_client.h deleted file mode 100644 index 4a25490f6..000000000 --- a/include/openbsc/gsup_client.h +++ /dev/null @@ -1,63 +0,0 @@ -/* GPRS Subscriber Update Protocol client */ - -/* (C) 2014 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Jacob Erlbeck - * - * 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 Affero 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 . - * - */ -#pragma once - -#include - -#include - -#define GSUP_CLIENT_RECONNECT_INTERVAL 10 -#define GSUP_CLIENT_PING_INTERVAL 20 - -struct msgb; -struct ipa_client_conn; -struct gsup_client; - -/* Expects message in msg->l2h */ -typedef int (*gsup_client_read_cb_t)(struct gsup_client *gsupc, - struct msgb *msg); - -struct gsup_client { - const char *unit_name; - - struct ipa_client_conn *link; - gsup_client_read_cb_t read_cb; - void *data; - - struct oap_client_state oap_state; - - struct osmo_timer_list ping_timer; - struct osmo_timer_list connect_timer; - int is_connected; - int got_ipa_pong; -}; - -struct gsup_client *gsup_client_create(const char *unit_name, - const char *ip_addr, - unsigned int tcp_port, - gsup_client_read_cb_t read_cb, - struct oap_client_config *oapc_config); - -void gsup_client_destroy(struct gsup_client *gsupc); -int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg); -struct msgb *gsup_client_msgb_alloc(void); - diff --git a/include/openbsc/gtphub.h b/include/openbsc/gtphub.h deleted file mode 100644 index 9cb7605f8..000000000 --- a/include/openbsc/gtphub.h +++ /dev/null @@ -1,523 +0,0 @@ -/* GTP Hub Implementation */ - -/* (C) 2015 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - */ - -#pragma once - -#include -#include - -#include -#include -#include - -#include - - -/* support */ - -/* TODO move to osmocom/core/socket.c ? */ -#include /* for IPPROTO_* etc */ -struct osmo_sockaddr { - struct sockaddr_storage a; - socklen_t l; -}; - -/* TODO move to osmocom/core/socket.c ? */ -/*! \brief Initialize a sockaddr - * \param[out] addr Valid osmo_sockaddr pointer to write result to - * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC - * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM - * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP - * \param[in] host Remote host name or IP address in string form - * \param[in] port Remote port number in host byte order - * \returns 0 on success, otherwise an error code (from getaddrinfo()). - * - * Copy the first result from a getaddrinfo() call with the given parameters to - * *addr and *addr_len. On error, do not change *addr and return nonzero. - */ -int osmo_sockaddr_init(struct osmo_sockaddr *addr, - uint16_t family, uint16_t type, uint8_t proto, - const char *host, uint16_t port); - -/* Conveniently pass AF_UNSPEC, SOCK_DGRAM and IPPROTO_UDP to - * osmo_sockaddr_init(). */ -static inline int osmo_sockaddr_init_udp(struct osmo_sockaddr *addr, - const char *host, uint16_t port) -{ - return osmo_sockaddr_init(addr, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, - host, port); -} - -/*! \brief convert sockaddr to human readable string. - * \param[out] addr_str Valid pointer to a buffer of length addr_str_len. - * \param[in] addr_str_len Size of buffer addr_str points at. - * \param[out] port_str Valid pointer to a buffer of length port_str_len. - * \param[in] port_str_len Size of buffer port_str points at. - * \param[in] addr Binary representation as returned by osmo_sockaddr_init(). - * \param[in] flags flags as passed to getnameinfo(). - * \returns 0 on success, an error code on error. - * - * Return the IPv4 or IPv6 address string and the port (a.k.a. service) string - * representations of the given struct osmo_sockaddr in two caller provided - * char buffers. Flags of (NI_NUMERICHOST | NI_NUMERICSERV) return numeric - * address and port. Either one of addr_str or port_str may be NULL, in which - * case nothing is returned there. - * - * See also osmo_sockaddr_to_str() (less flexible, but much more convenient). */ -int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len, - char *port_str, size_t port_str_len, - const struct osmo_sockaddr *addr, - int flags); - - -/*! \brief concatenate the parts returned by osmo_sockaddr_to_strs(). - * \param[in] addr Binary representation as returned by osmo_sockaddr_init(). - * \param[in] buf A buffer to use for string operations. - * \param[in] buf_len Length of the buffer. - * \returns Address string (in buffer). - * - * Compose a string of the numeric IP-address and port represented by *addr of - * the form " port ". The returned string is valid until the - * next invocation of this function. - */ -const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr, - char *buf, size_t buf_len); - -/*! \brief conveniently return osmo_sockaddr_to_strb() in a static buffer. - * \param[in] addr Binary representation as returned by osmo_sockaddr_init(). - * \returns Address string in static buffer. - * - * See osmo_sockaddr_to_strb(). - * - * Note: only one osmo_sockaddr_to_str() call will work per print/log - * statement. For two or more, use osmo_sockaddr_to_strb() with a separate - * buffer each. - */ -const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *addr); - -/*! \brief compare two osmo_sockaddr. - * \param[in] a The first address to compare. - * \param[in] b The other address to compare. - * \returns 0 if equal, otherwise -1 or 1. - */ -int osmo_sockaddr_cmp(const struct osmo_sockaddr *a, - const struct osmo_sockaddr *b); - -/*! \brief Overwrite *dst with *src. - * Like memcpy(), but copy only the valid bytes. */ -void osmo_sockaddr_copy(struct osmo_sockaddr *dst, - const struct osmo_sockaddr *src); - - -/* general */ - -enum gtphub_plane_idx { - GTPH_PLANE_CTRL = 0, - GTPH_PLANE_USER = 1, - GTPH_PLANE_N -}; - -enum gtphub_side_idx { - GTPH_SIDE_SGSN = 0, - GTPH_SIDE_GGSN = 1, - GTPH_SIDE_N -}; - -#define for_each_side(I) for (I = 0; I < GTPH_SIDE_N; I++) -#define for_each_plane(I) for (I = 0; I < GTPH_PLANE_N; I++) -#define for_each_side_and_plane(I,J) for_each_side(I) for_each_plane(J) - -static inline int other_side_idx(int side_idx) -{ - return (side_idx + 1) & 1; -} - -extern const char* const gtphub_plane_idx_names[GTPH_PLANE_N]; -extern const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N]; - -extern const char* const gtphub_side_idx_names[GTPH_SIDE_N]; - -/* A host address in the form that is expected in the 7.7.32 GSN Address IE. - * len is either 4 (IPv4) or 16 (IPv6), any other value is invalid. If no - * address is set, len shall be 0. */ -struct gsn_addr { - uint16_t len; - uint8_t buf[16]; -}; - -void gsn_addr_copy(struct gsn_addr *gsna, const struct gsn_addr *src); -int gsn_addr_from_str(struct gsn_addr *gsna, const char *numeric_addr_str); - -/* Return gsna in numeric string form, in a static buffer. */ -const char *gsn_addr_to_str(const struct gsn_addr *gsna); - -/* note: strbuf_len doesn't need to be larger than INET6_ADDRSTRLEN + 1. */ -const char *gsn_addr_to_strb(const struct gsn_addr *gsna, - char *strbuf, int strbuf_len); - -/* Return 1 on match, zero otherwise. */ -int gsn_addr_same(const struct gsn_addr *a, const struct gsn_addr *b); - -/* Decode sa to gsna. Return 0 on success. If port is non-NULL, the port number - * from sa is also returned. */ -int gsn_addr_from_sockaddr(struct gsn_addr *gsna, uint16_t *port, - const struct osmo_sockaddr *sa); - -/* expiry */ - -struct expiring_item; -typedef void (*del_cb_t)(struct expiring_item *); - -struct expiring_item { - struct llist_head entry; - time_t expiry; - del_cb_t del_cb; -}; - -struct expiry { - int expiry_in_seconds; - struct llist_head items; -}; - -/* Initialize an expiry queue. */ -void expiry_init(struct expiry *exq, int expiry_in_seconds); - -/* Add a new mapping, or restart the expiry timeout for an already listed - * mapping. */ -void expiry_add(struct expiry *exq, struct expiring_item *item, time_t now); - -/* Initialize to all-empty; must be called before using the item in any way. */ -void expiring_item_init(struct expiring_item *item); - -/* Remove the given item from its expiry queue, and call item->del_cb, if set. - * This sets item->del_cb to NULL and is harmless when run a second time on the - * same item, so the del_cb may choose to call this function, too, to allow - * deleting items from several code paths. */ -void expiring_item_del(struct expiring_item *item); - -/* Carry out due expiry of mappings. Must be invoked regularly. - * 'now' is the current clock count in seconds and must correspond to the clock - * count passed to nr_map_add(). A monotonous clock counter should be used. */ -int expiry_tick(struct expiry *exq, time_t now); - -/* Expire all items. */ -void expiry_clear(struct expiry *exq); - - -/* number map */ - -/* A number map assigns a "random" mapped number to each user provided number. - * If the same number is requested multiple times, the same mapped number is - * returned. - * - * Number maps plug into possibly shared pools and expiry queues, for example: - * - * mapA -----------+-> pool1 <-+-- mapB - * {10->1, 11->5} | {1, 2, 3, ...} | {10->2, 11->3} - * | | - * | | - * /-> \-> expiry1 <-/ - * | (30 seconds) - * | - * mapC -------+-----> pool2 <-+-- mapD - * {10->1, 11->3} {1, 2, 3, ...} | {10->2, 11->5} - * | - * expiry2 <-/ - * (60 seconds) - * - * A map contains mappings ("10->1"). Each map needs a number pool, which can - * be shared with other maps. Each new mapping receives a number from the pool, - * which is then unavailable to any other map using the same pool. - * - * A map may point at an expiry queue, in which case all mappings added to it - * are also appended to the expiry queue (using a separate llist entry in the - * mapping). Any number of maps may submit to the same expiry queue, if they - * desire the same expiry timeout. An expiry queue stores the mappings in - * chronological order, so that expiry checking is needed only from the start - * of the queue; hence only mappings with identical expiry timeout can be added - * to the same expiry queue. Upon expiry, a mapping is dropped from the map it - * was submitted at. expiry_tick() needs to be called regularly for each expiry - * queue. - * - * A nr_mapping can be embedded in a larger struct: each mapping can have a - * distinct destructor (del_cb), and each del_cb can figure out the container - * struct's address and free that upon expiry or manual deletion. So in expiry - * queues (and even maps), mappings of different container types can be mixed. - * This can help to drastically reduce the amount of unnecessary visits during - * expiry checking, for the case that no expiry is pending. An expiry queue - * always knows which mappings to expire next, because they are right at the - * start of its list. - * - * Mapping allocation and a del_cb are provided by the caller. If del_cb is - * NULL, no deallocation will be done (allowing statically allocated entries). - */ - -typedef unsigned int nr_t; - -/* Generator for unused numbers. So far this counts upwards from zero, but the - * implementation may change in the future. Treat this like an opaque struct. - * If this becomes random, the tests need to be fixed. */ -struct nr_pool { - nr_t last_nr; - nr_t nr_min; - nr_t nr_max; -}; - -struct nr_mapping { - struct llist_head entry; - struct expiring_item expiry_entry; - - void *origin; - nr_t orig; - nr_t repl; -}; - -struct nr_map { - struct nr_pool *pool; /* multiple nr_maps can share a nr_pool. */ - struct expiry *add_items_to_expiry; - struct llist_head mappings; -}; - - -void nr_pool_init(struct nr_pool *pool, nr_t nr_min, nr_t nr_max); - -/* Return the next unused number from the nr_pool. */ -nr_t nr_pool_next(struct nr_pool *pool); - -/* Initialize the nr_mapping to zero/empty values. */ -void nr_mapping_init(struct nr_mapping *mapping); - -/* Remove the given mapping from its parent map and expiry queue, and call - * mapping->del_cb, if set. */ -void nr_mapping_del(struct nr_mapping *mapping); - -/* Initialize an (already allocated) nr_map, and set the map's number pool. - * Multiple nr_map instances may use the same nr_pool. Set the nr_map's expiry - * queue to exq, so that all added mappings are automatically expired after the - * time configured in exq. exq may be NULL to disable automatic expiry. */ -void nr_map_init(struct nr_map *map, struct nr_pool *pool, - struct expiry *exq); - -/* Add a new entry to the map. mapping->orig, mapping->origin and - * mapping->del_cb must be set before calling this function. The remaining - * fields of *mapping will be overwritten. mapping->repl is set to the next - * available mapped number from map->pool. 'now' is the current clock count in - * seconds; if no map->expiry is used, just pass 0 for 'now'. */ -void nr_map_add(struct nr_map *map, struct nr_mapping *mapping, - time_t now); - -/* Restart the timeout for the given mapping. mapping must be a member of map. - */ -void nr_map_refresh(struct nr_map *map, struct nr_mapping *mapping, - time_t now); - -/* Return a known mapping from nr_orig and the given origin. If nr_orig is - * unknown, return NULL. */ -struct nr_mapping *nr_map_get(const struct nr_map *map, - void *origin, nr_t nr_orig); - -/* Return a known mapping to nr_repl. If nr_repl is unknown, return NULL. */ -struct nr_mapping *nr_map_get_inv(const struct nr_map *map, nr_t nr_repl); - -/* Remove all mappings from map. */ -void nr_map_clear(struct nr_map *map); - -/* Return 1 if map has no entries, 0 otherwise. */ -int nr_map_empty(const struct nr_map *map); - - -/* config */ - -static const int GTPH_EXPIRE_QUICKLY_SECS = 30; /* TODO is there a spec for this? */ -static const int GTPH_EXPIRE_SLOWLY_MINUTES = 6 * 60; /* TODO is there a spec for this? */ - -struct gtphub_cfg_addr { - const char *addr_str; - uint16_t port; -}; - -struct gtphub_cfg_bind { - struct gtphub_cfg_addr bind; -}; - -struct gtphub_cfg { - struct gtphub_cfg_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N]; - struct gtphub_cfg_addr proxy[GTPH_SIDE_N][GTPH_PLANE_N]; - int sgsn_use_sender; /* Use sender, not GSN addr IE with std ports */ -}; - - -/* state */ - -struct gtphub_peer { - struct llist_head entry; - - struct llist_head addresses; /* Alternatives, not load balancing. */ - struct nr_pool seq_pool; - struct nr_map seq_map; -}; - -struct gtphub_peer_addr { - struct llist_head entry; - - struct gtphub_peer *peer; - struct gsn_addr addr; - struct llist_head ports; -}; - -struct gtphub_peer_port { - struct llist_head entry; - - struct gtphub_peer_addr *peer_addr; - uint16_t port; - unsigned int ref_count; /* references from other peers' seq_maps */ - struct osmo_sockaddr sa; /* a "cache" for (peer_addr->addr, port) */ - int last_restart_count; /* 0..255 = valid, all else means unknown */ - - struct rate_ctr_group *counters_io; -}; - -struct gtphub_tunnel_endpoint { - struct gtphub_peer_port *peer; - uint32_t tei_orig; /* from/to peer */ - - struct rate_ctr_group *counters_io; -}; - -struct gtphub_tunnel { - struct llist_head entry; - struct expiring_item expiry_entry; - - uint32_t tei_repl; /* unique TEI to replace peers' TEIs */ - struct gtphub_tunnel_endpoint endpoint[GTPH_SIDE_N][GTPH_PLANE_N]; -}; - -struct gtphub_bind { - struct gsn_addr local_addr; - uint16_t local_port; - struct osmo_fd ofd; - - /* list of struct gtphub_peer */ - struct llist_head peers; - - const char *label; /* For logging */ - struct rate_ctr_group *counters_io; -}; - -struct gtphub_resolved_ggsn { - struct llist_head entry; - struct expiring_item expiry_entry; - - /* The APN OI, the Operator Identifier, is the combined address, - * including parts of the IMSI and APN NI, and ending with ".gprs". */ - char apn_oi_str[GSM_APN_LENGTH]; - - /* Which address and port we resolved that to. */ - struct gtphub_peer_port *peer; -}; - -struct gtphub { - struct gtphub_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N]; - - /* pointers to an entry of to_gsns[s][p].peers */ - struct gtphub_peer_port *proxy[GTPH_SIDE_N][GTPH_PLANE_N]; - - /* The TEI numbers will simply wrap and be reused, which will work out - * in practice. Problems would arise if one given peer maintained the - * same TEI for a time long enough for the TEI nr map to wrap an entire - * uint32_t; if a new TEI were mapped every second, this would take - * more than 100 years (in which a single given TEI must not time out) - * to cause a problem. */ - struct nr_pool tei_pool; - - struct llist_head tunnels; /* struct gtphub_tunnel */ - struct llist_head pending_deletes; /* opaque (gtphub.c) */ - - struct llist_head ggsn_lookups; /* opaque (gtphub_ares.c) */ - struct llist_head resolved_ggsns; /* struct gtphub_resolved_ggsn */ - - struct osmo_timer_list gc_timer; - struct expiry expire_quickly; - struct expiry expire_slowly; - - uint8_t restart_counter; - - int sgsn_use_sender; -}; - -struct gtp_packet_desc; - - -/* api */ - -int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg); -int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file); - -/* Initialize and start gtphub: bind to ports, run expiry timers. */ -int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg, - uint8_t restart_counter); - -/* Close all sockets, expire all maps and peers and free all allocations. The - * struct is then unusable, unless gtphub_start() is run on it again. */ -void gtphub_stop(struct gtphub *hub); - -time_t gtphub_now(void); - -/* Remove expired items, empty peers, ... */ -void gtphub_gc(struct gtphub *hub, time_t now); - -/* Return the string of the first address for this peer. */ -const char *gtphub_peer_str(struct gtphub_peer *peer); - -/* Return a human readable description of tun in a static buffer. */ -const char *gtphub_tunnel_str(struct gtphub_tunnel *tun); - -/* Return 1 if all of tun's endpoints are fully established, 0 otherwise. */ -int gtphub_tunnel_complete(struct gtphub_tunnel *tun); - -int gtphub_handle_buf(struct gtphub *hub, - unsigned int side_idx, - unsigned int port_idx, - const struct osmo_sockaddr *from_addr, - uint8_t *buf, - size_t received, - time_t now, - uint8_t **reply_buf, - struct osmo_fd **to_ofd, - struct osmo_sockaddr *to_addr); - -struct gtphub_peer_port *gtphub_port_have(struct gtphub *hub, - struct gtphub_bind *bind, - const struct gsn_addr *addr, - uint16_t port); - -struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind, - const struct osmo_sockaddr *addr); - -void gtphub_resolved_ggsn(struct gtphub *hub, const char *apn_oi_str, - struct gsn_addr *resolved_addr, - time_t now); - -const char *gtphub_port_str(struct gtphub_peer_port *port); - -int gtphub_write(const struct osmo_fd *to, - const struct osmo_sockaddr *to_addr, - const uint8_t *buf, size_t buf_len); diff --git a/include/openbsc/iucs.h b/include/openbsc/iucs.h deleted file mode 100644 index b7d60645d..000000000 --- a/include/openbsc/iucs.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg, - uint16_t *lac); - -struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network, - struct ranap_ue_conn_ctx *ue); diff --git a/include/openbsc/iucs_ranap.h b/include/openbsc/iucs_ranap.h deleted file mode 100644 index c2ff5f90e..000000000 --- a/include/openbsc/iucs_ranap.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -struct gsm_network; -struct ranap_ue_conn_ctx; - -int iucs_rx_ranap_event(struct gsm_network *network, - struct ranap_ue_conn_ctx *ue_ctx, int type, void *data); diff --git a/include/openbsc/oap_client.h b/include/openbsc/oap_client.h deleted file mode 100644 index 80c86d5d6..000000000 --- a/include/openbsc/oap_client.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Osmocom Authentication Protocol API */ - -/* (C) 2015 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#pragma once - -#include - -struct msgb; -struct osmo_oap_message; - -/* This is the config part for vty. It is essentially copied in - * oap_client_state, where values are copied over once the config is - * considered valid. */ -struct oap_client_config { - uint16_t client_id; - int secret_k_present; - uint8_t secret_k[16]; - int secret_opc_present; - uint8_t secret_opc[16]; -}; - -/* The runtime state of the OAP client. client_id and the secrets are in fact - * duplicated from oap_client_config, so that a separate validation of the - * config data is possible, and so that only a struct oap_client_state* is - * passed around. */ -struct oap_client_state { - enum { - OAP_UNINITIALIZED = 0, /* just allocated. */ - OAP_DISABLED, /* disabled by config. */ - OAP_INITIALIZED, /* enabled, config is valid. */ - OAP_REQUESTED_CHALLENGE, - OAP_SENT_CHALLENGE_RESULT, - OAP_REGISTERED - } state; - uint16_t client_id; - uint8_t secret_k[16]; - uint8_t secret_opc[16]; - int registration_failures; -}; - -/* From config, initialize state. Return 0 on success. */ -int oap_client_init(struct oap_client_config *config, - struct oap_client_state *state); - -/* Construct an OAP registration message and return in *msg_tx. Use - * state->client_id and update state->state. - * Return 0 on success, or a negative value on error. - * If an error is returned, *msg_tx is guaranteed to be NULL. */ -int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx); - -/* Decode and act on a received OAP message msg_rx. Update state->state. If a - * non-NULL pointer is returned in *msg_tx, that msgb should be sent to the OAP - * server (and freed) by the caller. The received msg_rx is not freed. - * Return 0 on success, or a negative value on error. - * If an error is returned, *msg_tx is guaranteed to be NULL. */ -int oap_client_handle(struct oap_client_state *state, - const struct msgb *msg_rx, struct msgb **msg_tx); - -/* Allocate a msgb and in it, return the encoded oap_client_msg. Return - * NULL on error. (Like oap_client_encode(), but also allocates a msgb.) - * About the name: the idea is do_something(oap_client_encoded(my_struct)) - */ -struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_client_msg); diff --git a/include/openbsc/rest_octets.h b/include/openbsc/rest_octets.h index 49a231296..374b1ba10 100644 --- a/include/openbsc/rest_octets.h +++ b/include/openbsc/rest_octets.h @@ -2,9 +2,10 @@ #define _REST_OCTETS_H #include -#include #include +struct gsm_bts; + /* generate SI1 rest octets */ int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net); int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts); diff --git a/include/openbsc/slhc.h b/include/openbsc/slhc.h deleted file mode 100644 index cd5a47cf4..000000000 --- a/include/openbsc/slhc.h +++ /dev/null @@ -1,187 +0,0 @@ -#ifndef _SLHC_H -#define _SLHC_H -/* - * Definitions for tcp compression routines. - * - * $Header: slcompress.h,v 1.10 89/12/31 08:53:02 van Exp $ - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - * - * - * modified for KA9Q Internet Software Package by - * Katie Stevens (dkstevens@ucdavis.edu) - * University of California, Davis - * Computing Services - * - 01-31-90 initial adaptation - * - * - Feb 1991 Bill_Simpson@um.cc.umich.edu - * variable number of conversation slots - * allow zero or one slots - * separate routines - * status display - */ - -/* - * Compressed packet format: - * - * The first octet contains the packet type (top 3 bits), TCP - * 'push' bit, and flags that indicate which of the 4 TCP sequence - * numbers have changed (bottom 5 bits). The next octet is a - * conversation number that associates a saved IP/TCP header with - * the compressed packet. The next two octets are the TCP checksum - * from the original datagram. The next 0 to 15 octets are - * sequence number changes, one change per bit set in the header - * (there may be no changes and there are two special cases where - * the receiver implicitly knows what changed -- see below). - * - * There are 5 numbers which can change (they are always inserted - * in the following order): TCP urgent pointer, window, - * acknowledgment, sequence number and IP ID. (The urgent pointer - * is different from the others in that its value is sent, not the - * change in value.) Since typical use of SLIP links is biased - * toward small packets (see comments on MTU/MSS below), changes - * use a variable length coding with one octet for numbers in the - * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the - * range 256 - 65535 or 0. (If the change in sequence number or - * ack is more than 65535, an uncompressed packet is sent.) - */ - -/* - * Packet types (must not conflict with IP protocol version) - * - * The top nibble of the first octet is the packet type. There are - * three possible types: IP (not proto TCP or tcp with one of the - * control flags set); uncompressed TCP (a normal IP/TCP packet but - * with the 8-bit protocol field replaced by an 8-bit connection id -- - * this type of packet syncs the sender & receiver); and compressed - * TCP (described above). - * - * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and - * is logically part of the 4-bit "changes" field that follows. Top - * three bits are actual packet type. For backward compatibility - * and in the interest of conserving bits, numbers are chosen so the - * IP protocol version number (4) which normally appears in this nibble - * means "IP packet". - */ - - -#include -#include - -/* SLIP compression masks for len/vers byte */ -#define SL_TYPE_IP 0x40 -#define SL_TYPE_UNCOMPRESSED_TCP 0x70 -#define SL_TYPE_COMPRESSED_TCP 0x80 -#define SL_TYPE_ERROR 0x00 - -/* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -#define TCP_PUSH_BIT 0x10 - -/* - * data type and sizes conversion assumptions: - * - * VJ code KA9Q style generic - * u_char byte_t unsigned char 8 bits - * u_short int16 unsigned short 16 bits - * u_int int16 unsigned short 16 bits - * u_long unsigned long unsigned long 32 bits - * int int32 long 32 bits - */ - -typedef __u8 byte_t; -typedef __u32 int32; - -/* - * "state" data for each active tcp conversation on the wire. This is - * basically a copy of the entire IP/TCP header from the last packet - * we saw from the conversation together with a small identifier - * the transmit & receive ends of the line use to locate saved header. - */ -struct cstate { - byte_t cs_this; /* connection id number (xmit) */ - struct cstate *next; /* next in ring (xmit) */ - struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ - struct tcphdr cs_tcp; - unsigned char cs_ipopt[64]; - unsigned char cs_tcpopt[64]; - int cs_hsize; -}; -#define NULLSLSTATE (struct cstate *)0 - -/* - * all the state data for one serial line (we need one of these per line). - */ -struct slcompress { - struct cstate *tstate; /* transmit connection states (array)*/ - struct cstate *rstate; /* receive connection states (array)*/ - - byte_t tslot_limit; /* highest transmit slot id (0-l)*/ - byte_t rslot_limit; /* highest receive slot id (0-l)*/ - - byte_t xmit_oldest; /* oldest xmit in ring */ - byte_t xmit_current; /* most recent xmit id */ - byte_t recv_current; /* most recent rcvd id */ - - byte_t flags; -#define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ - - int32 sls_o_nontcp; /* outbound non-TCP packets */ - int32 sls_o_tcp; /* outbound TCP packets */ - int32 sls_o_uncompressed; /* outbound uncompressed packets */ - int32 sls_o_compressed; /* outbound compressed packets */ - int32 sls_o_searches; /* searches for connection state */ - int32 sls_o_misses; /* times couldn't find conn. state */ - - int32 sls_i_uncompressed; /* inbound uncompressed packets */ - int32 sls_i_compressed; /* inbound compressed packets */ - int32 sls_i_error; /* inbound error packets */ - int32 sls_i_tossed; /* inbound packets tossed because of error */ - - int32 sls_i_runt; - int32 sls_i_badcheck; -}; -#define NULLSLCOMPR (struct slcompress *)0 - -/* In slhc.c: */ -struct slcompress *slhc_init(const void *ctx, int rslots, int tslots); - -void slhc_free(struct slcompress *comp); - -int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, - unsigned char *ocp, unsigned char **cpp, int compress_cid); -int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize); -int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); -int slhc_toss(struct slcompress *comp); - -void slhc_i_status(struct slcompress *comp); -void slhc_o_status(struct slcompress *comp); - -#endif /* _SLHC_H */ diff --git a/include/openbsc/transaction.h b/include/openbsc/transaction.h index 4930fbd32..1e93fffda 100644 --- a/include/openbsc/transaction.h +++ b/include/openbsc/transaction.h @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/include/openbsc/v42bis.h b/include/openbsc/v42bis.h deleted file mode 100644 index 607a58e51..000000000 --- a/include/openbsc/v42bis.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * v42bis.h - * - * Written by Steve Underwood - * - * Copyright (C) 2005, 2011 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1, - * as published by the Free Software Foundation. - * - * 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*! \page v42bis_page V.42bis modem data compression -\section v42bis_page_sec_1 What does it do? -The v.42bis specification defines a data compression scheme, to work in -conjunction with the error correction scheme defined in V.42. - -\section v42bis_page_sec_2 How does it work? -*/ - -#include - -#if !defined(_SPANDSP_V42BIS_H_) -#define _SPANDSP_V42BIS_H_ - -#define SPAN_DECLARE(x) x - -#define V42BIS_MIN_STRING_SIZE 6 -#define V42BIS_MAX_STRING_SIZE 250 -#define V42BIS_MIN_DICTIONARY_SIZE 512 -#define V42BIS_MAX_BITS 12 -#define V42BIS_MAX_CODEWORDS 4096 /* 2^V42BIS_MAX_BITS */ -#define V42BIS_MAX_OUTPUT_LENGTH 1024 - -enum -{ - V42BIS_P0_NEITHER_DIRECTION = 0, - V42BIS_P0_INITIATOR_RESPONDER, - V42BIS_P0_RESPONDER_INITIATOR, - V42BIS_P0_BOTH_DIRECTIONS -}; - -enum -{ - V42BIS_COMPRESSION_MODE_DYNAMIC = 0, - V42BIS_COMPRESSION_MODE_ALWAYS, - V42BIS_COMPRESSION_MODE_NEVER -}; - -typedef void (*put_msg_func_t)(void *user_data, const uint8_t *msg, int len); - -/*! - V.42bis compression/decompression descriptor. This defines the working state for a - single instance of V.42bis compress/decompression. -*/ -typedef struct v42bis_state_s v42bis_state_t; - -#if defined(__cplusplus) -extern "C" -{ -#endif - -/*! Compress a block of octets. - \param s The V.42bis context. - \param buf The data to be compressed. - \param len The length of the data buffer. - \return 0 */ -SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *s, const uint8_t buf[], int len); - -/*! Flush out any data remaining in a compression buffer. - \param s The V.42bis context. - \return 0 */ -SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *s); - -/*! Decompress a block of octets. - \param s The V.42bis context. - \param buf The data to be decompressed. - \param len The length of the data buffer. - \return 0 */ -SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *s, const uint8_t buf[], int len); - -/*! Flush out any data remaining in the decompression buffer. - \param s The V.42bis context. - \return 0 */ -SPAN_DECLARE(int) v42bis_decompress_flush(v42bis_state_t *s); - -/*! Set the compression mode. - \param s The V.42bis context. - \param mode One of the V.42bis compression modes - - V42BIS_COMPRESSION_MODE_DYNAMIC, - V42BIS_COMPRESSION_MODE_ALWAYS, - V42BIS_COMPRESSION_MODE_NEVER */ -SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode); - -/*! Initialise a V.42bis context. - \param s The V.42bis context. - \param negotiated_p0 The negotiated P0 parameter, from the V.42bis spec. - \param negotiated_p1 The negotiated P1 parameter, from the V.42bis spec. - \param negotiated_p2 The negotiated P2 parameter, from the V.42bis spec. - \param encode_handler Encode callback handler. - \param encode_user_data An opaque pointer passed to the encode callback handler. - \param max_encode_len The maximum length that should be passed to the encode handler. - \param decode_handler Decode callback handler. - \param decode_user_data An opaque pointer passed to the decode callback handler. - \param max_decode_len The maximum length that should be passed to the decode handler. - \return The V.42bis context. */ -SPAN_DECLARE(v42bis_state_t *) v42bis_init(const void *ctx, - v42bis_state_t *s, - int negotiated_p0, - int negotiated_p1, - int negotiated_p2, - put_msg_func_t encode_handler, - void *encode_user_data, - int max_encode_len, - put_msg_func_t decode_handler, - void *decode_user_data, - int max_decode_len); - -/*! Release a V.42bis context. - \param s The V.42bis context. - \return 0 if OK */ -SPAN_DECLARE(int) v42bis_release(v42bis_state_t *s); - -/*! Free a V.42bis context. - \param s The V.42bis context. - \return 0 if OK */ -SPAN_DECLARE(int) v42bis_free(v42bis_state_t *s); - -#if defined(__cplusplus) -} -#endif - -#endif -/*- End of file ------------------------------------------------------------*/ diff --git a/include/openbsc/v42bis_private.h b/include/openbsc/v42bis_private.h deleted file mode 100644 index daa5ea315..000000000 --- a/include/openbsc/v42bis_private.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * private/v42bis.h - * - * Written by Steve Underwood - * - * Copyright (C) 2005 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1, - * as published by the Free Software Foundation. - * - * 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#if !defined(_SPANDSP_PRIVATE_V42BIS_H_) -#define _SPANDSP_PRIVATE_V42BIS_H_ - -/*! - V.42bis dictionary node. - Note that 0 is not a valid node to point to (0 is always a control code), so 0 is used - as a "no such value" marker in this structure. -*/ -typedef struct -{ - /*! \brief The value of the octet represented by the current dictionary node */ - uint8_t node_octet; - /*! \brief The parent of this node */ - uint16_t parent; - /*! \brief The first child of this node */ - uint16_t child; - /*! \brief The next node at the same depth */ - uint16_t next; -} v42bis_dict_node_t; - -/*! - V.42bis compression or decompression. This defines the working state for a single instance - of V.42bis compression or decompression. -*/ -typedef struct -{ - /*! \brief Compression enabled. */ - int v42bis_parm_p0; - /*! \brief Compression mode. */ - int compression_mode; - /*! \brief Callback function to handle output data. */ - put_msg_func_t handler; - /*! \brief An opaque pointer passed in calls to the data handler. */ - void *user_data; - /*! \brief The maximum amount to be passed to the data handler. */ - int max_output_len; - - /*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */ - int transparent; - /*! \brief Next empty dictionary entry */ - uint16_t v42bis_parm_c1; - /*! \brief Current codeword size */ - uint16_t v42bis_parm_c2; - /*! \brief Threshold for codeword size change */ - uint16_t v42bis_parm_c3; - /*! \brief The current update point in the dictionary */ - uint16_t update_at; - /*! \brief The last entry matched in the dictionary */ - uint16_t last_matched; - /*! \brief The last entry added to the dictionary */ - uint16_t last_added; - /*! \brief Total number of codewords in the dictionary */ - int v42bis_parm_n2; - /*! \brief Maximum permitted string length */ - int v42bis_parm_n7; - /*! \brief The dictionary */ - v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS]; - - /*! \brief The octet string in progress */ - uint8_t string[V42BIS_MAX_STRING_SIZE]; - /*! \brief The current length of the octet string in progress */ - int string_length; - /*! \brief The amount of the octet string in progress which has already - been flushed out of the buffer */ - int flushed_length; - - /*! \brief Compression performance metric */ - uint16_t compression_performance; - - /*! \brief Outgoing bit buffer (compression), or incoming bit buffer (decompression) */ - uint32_t bit_buffer; - /*! \brief Outgoing bit count (compression), or incoming bit count (decompression) */ - int bit_count; - - /*! \brief The output composition buffer */ - uint8_t output_buf[V42BIS_MAX_OUTPUT_LENGTH]; - /*! \brief The length of the contents of the output composition buffer */ - int output_octet_count; - - /*! \brief The current value of the escape code */ - uint8_t escape_code; - /*! \brief TRUE if we just hit an escape code, and are waiting for the following octet */ - int escaped; -} v42bis_comp_state_t; - -/*! - V.42bis compression/decompression descriptor. This defines the working state for a - single instance of V.42bis compress/decompression. -*/ -struct v42bis_state_s -{ - /*! \brief Compression state. */ - v42bis_comp_state_t compress; - /*! \brief Decompression state. */ - v42bis_comp_state_t decompress; - - /*! \brief Error and flow logging control */ -}; - -#endif -/*- End of file ------------------------------------------------------------*/ diff --git a/include/openbsc/vlr.h b/include/openbsc/vlr.h deleted file mode 100644 index 619971a52..000000000 --- a/include/openbsc/vlr.h +++ /dev/null @@ -1,422 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -// for GSM_NAME_LENGTH -#include - -struct log_target; - -/* from 3s to 10s */ -#define GSM_29002_TIMER_S 10 -/* from 15s to 30s */ -#define GSM_29002_TIMER_M 30 -/* from 1min to 10min */ -#define GSM_29002_TIMER_ML (10*60) -/* from 28h to 38h */ -#define GSM_29002_TIMER_L (32*60*60) - -/* VLR subscriber authentication state */ -enum vlr_subscr_auth_state { - /* subscriber needs to be autenticated */ - VLR_SUB_AS_NEEDS_AUTH, - /* waiting for AuthInfo from HLR/AUC */ - VLR_SUB_AS_NEEDS_AUTH_WAIT_AI, - /* waiting for response from subscriber */ - VLR_SUB_AS_WAIT_RESP, - /* successfully authenticated */ - VLR_SUB_AS_AUTHENTICATED, - /* subscriber needs re-sync */ - VLR_SUB_AS_NEEDS_RESYNC, - /* waiting for AuthInfo with ReSync */ - VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC, - /* waiting for response from subscr, resync case */ - VLR_SUB_AS_WAIT_RESP_RESYNC, - /* waiting for IMSI from subscriber */ - VLR_SUB_AS_WAIT_ID_IMSI, - /* authentication has failed */ - VLR_SUB_AS_AUTH_FAILED, -}; - -enum vlr_lu_event { - VLR_ULA_E_UPDATE_LA, /* Initial trigger (LU from MS) */ - VLR_ULA_E_SEND_ID_ACK, /* Result of Send-ID from PVLR */ - VLR_ULA_E_SEND_ID_NACK, /* Result of Send-ID from PVLR */ - VLR_ULA_E_AUTH_RES, /* Result of auth procedure */ - VLR_ULA_E_CIPH_RES, /* Result of Ciphering Mode Command */ - VLR_ULA_E_ID_IMSI, /* IMSI recieved from MS */ - VLR_ULA_E_ID_IMEI, /* IMEI received from MS */ - VLR_ULA_E_ID_IMEISV, /* IMEISV received from MS */ - VLR_ULA_E_HLR_LU_RES, /* HLR UpdateLocation result */ - VLR_ULA_E_UPD_HLR_COMPL,/* UpdatE_HLR_VLR result */ - VLR_ULA_E_LU_COMPL_SUCCESS,/* Location_Update_Completion_VLR result */ - VLR_ULA_E_LU_COMPL_FAILURE,/* Location_Update_Completion_VLR result */ - VLR_ULA_E_NEW_TMSI_ACK, /* TMSI Reallocation Complete */ -}; - -enum vlr_ciph_result_cause { - VLR_CIPH_REJECT, /* ? */ - VLR_CIPH_COMPL, -}; - -struct vlr_ciph_result { - enum vlr_ciph_result_cause cause; - const char *imeisv; -}; - -enum vlr_subscr_security_context { - VLR_SEC_CTX_NONE, - VLR_SEC_CTX_GSM, - VLR_SEC_CTX_UMTS, -}; - -enum vlr_lu_type { - VLR_LU_TYPE_PERIODIC, - VLR_LU_TYPE_IMSI_ATTACH, - VLR_LU_TYPE_REGULAR, -}; - -#define OSMO_LBUF_DECL(name, xlen) \ - struct { \ - uint8_t buf[xlen]; \ - size_t len; \ - } name - -struct sgsn_mm_ctx; -struct vlr_instance; - -/* The VLR subscriber is the part of the GSM subscriber state in VLR (CS) or - * SGSN (PS), particularly while interacting with the HLR via GSUP */ -struct vlr_subscr { - struct llist_head list; - struct vlr_instance *vlr; - - /* TODO either populate from HLR or drop this completely? */ - long long unsigned int id; - - /* Data from HLR */ /* 3GPP TS 23.008 */ - /* Always use vlr_subscr_set_imsi() to write to imsi[] */ - char imsi[GSM23003_IMSI_MAX_DIGITS+1]; /* 2.1.1.1 */ - char msisdn[GSM_EXTENSION_LENGTH+1]; /* 2.1.2 */ - char name[GSM_NAME_LENGTH+1]; /* proprietary */ - OSMO_LBUF_DECL(hlr, 16); /* 2.4.7 */ - uint32_t periodic_lu_timer; /* 2.4.24 */ - uint32_t age_indicator; /* 2.17.1 */ - - /* Authentication Data */ - struct gsm_auth_tuple auth_tuples[5]; /* 2.3.1-2.3.4 */ - struct gsm_auth_tuple *last_tuple; - enum vlr_subscr_security_context sec_ctx; - - /* Data local to VLR is below */ - uint32_t tmsi; /* 2.1.4 */ - /* Newly allocated TMSI that was not yet acked by MS */ - uint32_t tmsi_new; - - /* some redundancy in information below? */ - struct osmo_cell_global_id cgi; /* 2.4.16 */ - uint16_t lac; /* 2.4.2 */ - - char imeisv[GSM23003_IMEISV_NUM_DIGITS+1]; /* 2.2.3 */ - char imei[GSM23003_IMEISV_NUM_DIGITS+1]; /* 2.1.9 */ - bool imsi_detached_flag; /* 2.7.1 */ - bool conf_by_radio_contact_ind; /* 2.7.4.1 */ - bool sub_dataconf_by_hlr_ind; /* 2.7.4.2 */ - bool loc_conf_in_hlr_ind; /* 2.7.4.3 */ - bool dormant_ind; /* 2.7.8 */ - bool cancel_loc_rx; /* 2.7.8A */ - bool ms_not_reachable_flag; /* 2.10.2 (MNRF) */ - bool la_allowed; - - int use_count; - time_t expire_lu; /* FIXME: overlap with periodic_lu_timer/age_indicator */ - - struct osmo_fsm_inst *lu_fsm; - struct osmo_fsm_inst *auth_fsm; - struct osmo_fsm_inst *proc_arq_fsm; - - bool lu_complete; - - void *msc_conn_ref; - - /* PS (SGSN) specific parts */ - struct { - struct llist_head pdp_list; - uint8_t rac; - uint8_t sac; - struct gprs_mm_ctx *mmctx; - } ps; - /* CS (NITB/CSCN) specific parts */ - struct { - /* pending requests */ - bool is_paging; - /* list of struct subscr_request */ - struct llist_head requests; - uint8_t lac; - enum ran_type attached_via_ran; - } cs; -}; - -enum vlr_proc_arq_result; - -enum vlr_ciph { - VLR_CIPH_NONE, /*< A5/0, no encryption */ - VLR_CIPH_A5_1, /*< A5/1, encryption */ - VLR_CIPH_A5_2, /*< A5/2, deprecated export-grade encryption */ - VLR_CIPH_A5_3, /*< A5/3, 'new secure' encryption */ -}; - -struct vlr_ops { - /* encode + transmit an AUTH REQ towards the MS. - * \param[in] at auth tuple providing rand, key_seq and autn. - * \param[in] send_autn True to send AUTN, for r99 UMTS auth. - */ - int (*tx_auth_req)(void *msc_conn_ref, struct gsm_auth_tuple *at, - bool send_autn); - /* encode + transmit an AUTH REJECT towards the MS */ - int (*tx_auth_rej)(void *msc_conn_ref); - - /* encode + transmit an IDENTITY REQUEST towards the MS */ - int (*tx_id_req)(void *msc_conn_ref, uint8_t mi_type); - - int (*tx_lu_acc)(void *msc_conn_ref, uint32_t send_tmsi); - int (*tx_lu_rej)(void *msc_conn_ref, uint8_t cause); - int (*tx_cm_serv_acc)(void *msc_conn_ref); - int (*tx_cm_serv_rej)(void *msc_conn_ref, enum vlr_proc_arq_result result); - - int (*set_ciph_mode)(void *msc_conn_ref, enum vlr_ciph ciph_mode, - bool retrieve_imeisv); - - /* UTRAN: send Common Id (when auth+ciph are complete) */ - int (*tx_common_id)(void *msc_conn_ref); - - - /* notify MSC/SGSN that the subscriber data in VLR has been updated */ - void (*subscr_update)(struct vlr_subscr *vsub); - /* notify MSC/SGSN that the given subscriber has been associated - * with this msc_conn_ref */ - void (*subscr_assoc)(void *msc_conn_ref, struct vlr_subscr *vsub); -}; - -enum vlr_timer { - VLR_T_3250, - VLR_T_3260, - VLR_T_3270, - _NUM_VLR_TIMERS -}; - -/* An instance of the VLR codebase */ -struct vlr_instance { - struct llist_head subscribers; - struct llist_head operations; - struct gsup_client *gsup_client; - struct vlr_ops ops; - struct { - bool retrieve_imeisv_early; - bool retrieve_imeisv_ciphered; - bool assign_tmsi; - bool check_imei_rqd; - int auth_tuple_max_use_count; - bool auth_reuse_old_sets_on_error; - bool parq_retrieve_imsi; - bool is_ps; - uint32_t timer[_NUM_VLR_TIMERS]; - } cfg; - /* A free-form pointer for use by the caller */ - void *user_ctx; -}; - -extern const struct value_string vlr_ciph_names[]; -static inline const char *vlr_ciph_name(enum vlr_ciph val) -{ - return get_value_string(vlr_ciph_names, val); -} - -/* Location Updating request */ -struct osmo_fsm_inst * -vlr_loc_update(struct osmo_fsm_inst *parent, - uint32_t parent_event_success, - uint32_t parent_event_failure, - void *parent_event_data, - struct vlr_instance *vlr, void *msc_conn_ref, - enum vlr_lu_type type, uint32_t tmsi, const char *imsi, - const struct osmo_location_area_id *old_lai, - const struct osmo_location_area_id *new_lai, - bool authentication_required, - enum vlr_ciph ciphering_required, - bool is_r99, bool is_utran, - bool assign_tmsi); - -void vlr_loc_update_conn_timeout(struct osmo_fsm_inst *fi); - -/* tell the VLR that the subscriber connection is gone */ -int vlr_subscr_disconnected(struct vlr_subscr *vsub); - -int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const uint8_t *mi, size_t mi_len); -int vlr_subscr_rx_auth_resp(struct vlr_subscr *vsub, bool is_r99, bool is_utran, - const uint8_t *res, uint8_t res_len); -int vlr_subscr_rx_auth_fail(struct vlr_subscr *vsub, const uint8_t *auts); -int vlr_subscr_tx_auth_fail_rep(struct vlr_subscr *vsub); -void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, struct vlr_ciph_result *res); -int vlr_subscr_rx_tmsi_reall_compl(struct vlr_subscr *vsub); -int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub); -void vlr_subscr_conn_timeout(struct vlr_subscr *vsub); - -struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops); -int vlr_start(const char *gsup_unit_name, struct vlr_instance *vlr, - const char *gsup_server_addr_str, uint16_t gsup_server_port); - -/* internal use only */ - -struct osmo_fsm_inst *sub_pres_vlr_fsm_start(struct osmo_fsm_inst *parent, - struct vlr_subscr *vsub, - uint32_t term_event); -struct osmo_fsm_inst * -upd_hlr_vlr_proc_start(struct osmo_fsm_inst *parent, - struct vlr_subscr *vsub, - uint32_t parent_event); - -struct osmo_fsm_inst * -lu_compl_vlr_proc_start(struct osmo_fsm_inst *parent, - struct vlr_subscr *vsub, - void *msc_conn_ref, - uint32_t parent_event_success, - uint32_t parent_event_failure); - - -const char *vlr_subscr_name(struct vlr_subscr *vsub); -const char *vlr_subscr_msisdn_or_name(struct vlr_subscr *vsub); - -#define vlr_subscr_find_by_imsi(vlr, imsi) \ - _vlr_subscr_find_by_imsi(vlr, imsi, __BASE_FILE__, __LINE__) -#define vlr_subscr_find_or_create_by_imsi(vlr, imsi, created) \ - _vlr_subscr_find_or_create_by_imsi(vlr, imsi, created, \ - __BASE_FILE__, __LINE__) - -#define vlr_subscr_find_by_tmsi(vlr, tmsi) \ - _vlr_subscr_find_by_tmsi(vlr, tmsi, __BASE_FILE__, __LINE__) -#define vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created) \ - _vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created, \ - __BASE_FILE__, __LINE__) - -#define vlr_subscr_find_by_msisdn(vlr, msisdn) \ - _vlr_subscr_find_by_msisdn(vlr, msisdn, __BASE_FILE__, __LINE__) - -struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr, - const char *imsi, - const char *file, int line); -struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr, - const char *imsi, - bool *created, - const char *file, - int line); - -struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr, - uint32_t tmsi, - const char *file, int line); -struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr, - uint32_t tmsi, - bool *created, - const char *file, - int line); - -struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr, - const char *msisdn, - const char *file, int line); - -#define vlr_subscr_get(sub) _vlr_subscr_get(sub, __BASE_FILE__, __LINE__) -#define vlr_subscr_put(sub) _vlr_subscr_put(sub, __BASE_FILE__, __LINE__) -struct vlr_subscr *_vlr_subscr_get(struct vlr_subscr *sub, const char *file, int line); -struct vlr_subscr *_vlr_subscr_put(struct vlr_subscr *sub, const char *file, int line); - -struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr); -void vlr_subscr_free(struct vlr_subscr *vsub); -int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub); - -void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi); -void vlr_subscr_set_imei(struct vlr_subscr *vsub, const char *imei); -void vlr_subscr_set_imeisv(struct vlr_subscr *vsub, const char *imeisv); -void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn); - -bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi); -bool vlr_subscr_matches_tmsi(struct vlr_subscr *vsub, uint32_t tmsi); -bool vlr_subscr_matches_msisdn(struct vlr_subscr *vsub, const char *msisdn); -bool vlr_subscr_matches_imei(struct vlr_subscr *vsub, const char *imei); - -uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer); - -int vlr_subscr_changed(struct vlr_subscr *vsub); -int vlr_subscr_purge(struct vlr_subscr *vsub); -void vlr_subscr_cancel(struct vlr_subscr *vsub, enum gsm48_gmm_cause cause); - - -/* Process Acccess Request FSM */ - -enum vlr_proc_arq_result { - VLR_PR_ARQ_RES_NONE, - VLR_PR_ARQ_RES_SYSTEM_FAILURE, - VLR_PR_ARQ_RES_ILLEGAL_SUBSCR, - VLR_PR_ARQ_RES_UNIDENT_SUBSCR, - VLR_PR_ARQ_RES_ROAMING_NOTALLOWED, - VLR_PR_ARQ_RES_ILLEGAL_EQUIP, - VLR_PR_ARQ_RES_UNKNOWN_ERROR, - VLR_PR_ARQ_RES_TIMEOUT, - VLR_PR_ARQ_RES_PASSED, -}; - -extern const struct value_string vlr_proc_arq_result_names[]; -static inline const char *vlr_proc_arq_result_name(enum vlr_proc_arq_result res) -{ - return get_value_string(vlr_proc_arq_result_names, res); -} - -enum proc_arq_vlr_event { - PR_ARQ_E_START, - PR_ARQ_E_ID_IMSI, - PR_ARQ_E_AUTH_RES, - PR_ARQ_E_CIPH_RES, - PR_ARQ_E_UPD_LOC_RES, - PR_ARQ_E_TRACE_RES, - PR_ARQ_E_IMEI_RES, - PR_ARQ_E_PRES_RES, - PR_ARQ_E_TMSI_ACK, -}; - -enum vlr_parq_type { - VLR_PR_ARQ_T_INVALID = 0, /* to guard against unset vars */ - VLR_PR_ARQ_T_CM_SERV_REQ, - VLR_PR_ARQ_T_PAGING_RESP, - /* FIXME: differentiate between services of 24.008 10.5.3.3 */ -}; - -/* Process Access Request (CM SERV REQ / PAGING RESP) */ -void -vlr_proc_acc_req(struct osmo_fsm_inst *parent, - uint32_t parent_event_success, - uint32_t parent_event_failure, - void *parent_event_data, - struct vlr_instance *vlr, void *msc_conn_ref, - enum vlr_parq_type type, const uint8_t *mi_lv, - const struct osmo_location_area_id *lai, - bool authentication_required, - enum vlr_ciph ciphering_required, - bool is_r99, bool is_utran); - -void vlr_parq_conn_timeout(struct osmo_fsm_inst *fi); - -void vlr_parq_fsm_init(void); - -int vlr_set_ciph_mode(struct vlr_instance *vlr, - struct osmo_fsm_inst *fi, - void *msc_conn_ref, - enum vlr_ciph ciph_mode, - bool retrieve_imeisv); - -void log_set_filter_vlr_subscr(struct log_target *target, - struct vlr_subscr *vlr_subscr); diff --git a/osmoappdesc.py b/osmoappdesc.py index 22210d5bf..021bf5b61 100644 --- a/osmoappdesc.py +++ b/osmoappdesc.py @@ -30,23 +30,14 @@ nitb_e1_configs = [ app_configs = { "osmo-bsc": ["doc/examples/osmo-bsc/osmo-bsc.cfg"], "nat": ["doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg"], - "gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg", - "doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg"], - "sgsn": ["doc/examples/osmo-sgsn/osmo-sgsn.cfg"], - "msc": ["doc/examples/osmo-msc/osmo-msc.cfg"], - "gtphub": ["doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg"] } apps = [(4242, "src/osmo-bsc/osmo-bsc", "OsmoBSC", "osmo-bsc"), (4244, "src/osmo-bsc_nat/osmo-bsc_nat", "OsmoBSCNAT", "nat"), - (4246, "src/gprs/osmo-gbproxy", "OsmoGbProxy", "gbproxy"), - (4245, "src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn"), - (4254, "src/osmo-msc/osmo-msc", "OsmoMSC", "msc"), - (4253, "src/gprs/osmo-gtphub", "OsmoGTPhub", "gtphub") ] -vty_command = ["./src/osmo-msc/osmo-msc", "-c", - "doc/examples/osmo-msc/osmo-msc.cfg"] +vty_command = ["./src/osmo-bsc/osmo-bsc", "-c", + "doc/examples/osmo-bsc/osmo-bsc.cfg"] -vty_app = apps[4] # reference apps[] entry for osmo-msc +vty_app = apps[0] diff --git a/src/Makefile.am b/src/Makefile.am index 70e53ac3e..9a26a7b9e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,9 +22,7 @@ AM_LDFLAGS = \ # Libraries SUBDIRS = \ libcommon \ - libvlr \ libbsc \ - libmsc \ libtrau \ libfilter \ libcommon-cs \ @@ -32,10 +30,8 @@ SUBDIRS = \ # Programs SUBDIRS += \ - osmo-msc \ utils \ ipaccess \ - gprs \ $(NULL) # Conditional Programs diff --git a/src/gprs/.gitignore b/src/gprs/.gitignore deleted file mode 100644 index 7cfefbac2..000000000 --- a/src/gprs/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -gsn_restart -osmo_*.cfg* diff --git a/src/gprs/Makefile.am b/src/gprs/Makefile.am deleted file mode 100644 index 39a4c12a7..000000000 --- a/src/gprs/Makefile.am +++ /dev/null @@ -1,133 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - -I$(top_builddir) \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -fno-strict-aliasing \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOCTRL_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOGB_CFLAGS) \ - $(COVERAGE_CFLAGS) \ - $(LIBCARES_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) \ - $(LIBGTP_CFLAGS) \ - $(NULL) -if BUILD_IU -AM_CFLAGS += \ - $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) \ - $(LIBOSMORANAP_CFLAGS) \ - $(NULL) -endif - -OSMO_LIBS = \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOCTRL_LIBS) \ - $(LIBOSMOGB_LIBS) \ - $(LIBGTP_LIBS) \ - $(LIBOSMOSIGTRAN_LIBS) \ - $(NULL) - -bin_PROGRAMS = \ - osmo-gbproxy \ - $(NULL) -if HAVE_LIBGTP -if HAVE_LIBCARES -bin_PROGRAMS += \ - osmo-sgsn \ - osmo-gtphub \ - $(NULL) -endif -endif - -osmo_gbproxy_SOURCES = \ - gb_proxy.c \ - gb_proxy_main.c \ - gb_proxy_vty.c \ - gb_proxy_patch.c \ - gb_proxy_tlli.c \ - gb_proxy_peer.c \ - gprs_gb_parse.c \ - gprs_llc_parse.c \ - crc24.c \ - gprs_utils.c \ - $(NULL) -osmo_gbproxy_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) \ - $(LIBCRYPTO_LIBS) \ - -lrt \ - $(NULL) - -osmo_sgsn_SOURCES = \ - gprs_gmm.c \ - gprs_sgsn.c \ - gprs_sndcp.c \ - gprs_sndcp_comp.c \ - gprs_sndcp_dcomp.c \ - gprs_sndcp_pcomp.c \ - gprs_sndcp_vty.c \ - gprs_sndcp_xid.c \ - sgsn_main.c \ - sgsn_vty.c \ - sgsn_libgtp.c \ - gprs_llc.c \ - gprs_llc_parse.c \ - gprs_llc_vty.c \ - crc24.c \ - sgsn_ctrl.c \ - sgsn_auth.c \ - gprs_subscriber.c \ - gprs_utils.c \ - sgsn_cdr.c \ - sgsn_ares.c \ - slhc.c \ - gprs_llc_xid.c \ - v42bis.c \ - $(NULL) -osmo_sgsn_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(OSMO_LIBS) \ - $(LIBOSMOABIS_LIBS) \ - $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) \ - $(LIBGTP_LIBS) \ - -lrt \ - -lm \ - $(NULL) -if BUILD_IU -osmo_sgsn_LDADD += \ - $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBOSMORANAP_LIBS) \ - $(LIBASN1C_LIBS) \ - $(NULL) -endif - -osmo_gtphub_SOURCES = \ - gtphub_main.c \ - gtphub.c \ - gtphub_sock.c \ - gtphub_ares.c \ - gtphub_vty.c \ - sgsn_ares.c \ - gprs_utils.c \ - $(NULL) -osmo_gtphub_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOVTY_LIBS) \ - $(LIBCARES_LIBS) \ - $(LIBGTP_LIBS) \ - $(LIBOSMOSIGTRAN_LIBS) \ - -lrt \ - $(NULL) diff --git a/src/gprs/crc24.c b/src/gprs/crc24.c deleted file mode 100644 index 1a420ed66..000000000 --- a/src/gprs/crc24.c +++ /dev/null @@ -1,67 +0,0 @@ -/* GPRS LLC CRC-24 Implementation */ - -/* (C) 2008-2009 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include - -/* CRC24 table - FCS */ -static const uint32_t tbl_crc24[256] = { - 0x00000000, 0x00d6a776, 0x00f64557, 0x0020e221, 0x00b78115, 0x00612663, 0x0041c442, 0x00976334, - 0x00340991, 0x00e2aee7, 0x00c24cc6, 0x0014ebb0, 0x00838884, 0x00552ff2, 0x0075cdd3, 0x00a36aa5, - 0x00681322, 0x00beb454, 0x009e5675, 0x0048f103, 0x00df9237, 0x00093541, 0x0029d760, 0x00ff7016, - 0x005c1ab3, 0x008abdc5, 0x00aa5fe4, 0x007cf892, 0x00eb9ba6, 0x003d3cd0, 0x001ddef1, 0x00cb7987, - 0x00d02644, 0x00068132, 0x00266313, 0x00f0c465, 0x0067a751, 0x00b10027, 0x0091e206, 0x00474570, - 0x00e42fd5, 0x003288a3, 0x00126a82, 0x00c4cdf4, 0x0053aec0, 0x008509b6, 0x00a5eb97, 0x00734ce1, - 0x00b83566, 0x006e9210, 0x004e7031, 0x0098d747, 0x000fb473, 0x00d91305, 0x00f9f124, 0x002f5652, - 0x008c3cf7, 0x005a9b81, 0x007a79a0, 0x00acded6, 0x003bbde2, 0x00ed1a94, 0x00cdf8b5, 0x001b5fc3, - 0x00fb4733, 0x002de045, 0x000d0264, 0x00dba512, 0x004cc626, 0x009a6150, 0x00ba8371, 0x006c2407, - 0x00cf4ea2, 0x0019e9d4, 0x00390bf5, 0x00efac83, 0x0078cfb7, 0x00ae68c1, 0x008e8ae0, 0x00582d96, - 0x00935411, 0x0045f367, 0x00651146, 0x00b3b630, 0x0024d504, 0x00f27272, 0x00d29053, 0x00043725, - 0x00a75d80, 0x0071faf6, 0x005118d7, 0x0087bfa1, 0x0010dc95, 0x00c67be3, 0x00e699c2, 0x00303eb4, - 0x002b6177, 0x00fdc601, 0x00dd2420, 0x000b8356, 0x009ce062, 0x004a4714, 0x006aa535, 0x00bc0243, - 0x001f68e6, 0x00c9cf90, 0x00e92db1, 0x003f8ac7, 0x00a8e9f3, 0x007e4e85, 0x005eaca4, 0x00880bd2, - 0x00437255, 0x0095d523, 0x00b53702, 0x00639074, 0x00f4f340, 0x00225436, 0x0002b617, 0x00d41161, - 0x00777bc4, 0x00a1dcb2, 0x00813e93, 0x005799e5, 0x00c0fad1, 0x00165da7, 0x0036bf86, 0x00e018f0, - 0x00ad85dd, 0x007b22ab, 0x005bc08a, 0x008d67fc, 0x001a04c8, 0x00cca3be, 0x00ec419f, 0x003ae6e9, - 0x00998c4c, 0x004f2b3a, 0x006fc91b, 0x00b96e6d, 0x002e0d59, 0x00f8aa2f, 0x00d8480e, 0x000eef78, - 0x00c596ff, 0x00133189, 0x0033d3a8, 0x00e574de, 0x007217ea, 0x00a4b09c, 0x008452bd, 0x0052f5cb, - 0x00f19f6e, 0x00273818, 0x0007da39, 0x00d17d4f, 0x00461e7b, 0x0090b90d, 0x00b05b2c, 0x0066fc5a, - 0x007da399, 0x00ab04ef, 0x008be6ce, 0x005d41b8, 0x00ca228c, 0x001c85fa, 0x003c67db, 0x00eac0ad, - 0x0049aa08, 0x009f0d7e, 0x00bfef5f, 0x00694829, 0x00fe2b1d, 0x00288c6b, 0x00086e4a, 0x00dec93c, - 0x0015b0bb, 0x00c317cd, 0x00e3f5ec, 0x0035529a, 0x00a231ae, 0x007496d8, 0x005474f9, 0x0082d38f, - 0x0021b92a, 0x00f71e5c, 0x00d7fc7d, 0x00015b0b, 0x0096383f, 0x00409f49, 0x00607d68, 0x00b6da1e, - 0x0056c2ee, 0x00806598, 0x00a087b9, 0x007620cf, 0x00e143fb, 0x0037e48d, 0x001706ac, 0x00c1a1da, - 0x0062cb7f, 0x00b46c09, 0x00948e28, 0x0042295e, 0x00d54a6a, 0x0003ed1c, 0x00230f3d, 0x00f5a84b, - 0x003ed1cc, 0x00e876ba, 0x00c8949b, 0x001e33ed, 0x008950d9, 0x005ff7af, 0x007f158e, 0x00a9b2f8, - 0x000ad85d, 0x00dc7f2b, 0x00fc9d0a, 0x002a3a7c, 0x00bd5948, 0x006bfe3e, 0x004b1c1f, 0x009dbb69, - 0x0086e4aa, 0x005043dc, 0x0070a1fd, 0x00a6068b, 0x003165bf, 0x00e7c2c9, 0x00c720e8, 0x0011879e, - 0x00b2ed3b, 0x00644a4d, 0x0044a86c, 0x00920f1a, 0x00056c2e, 0x00d3cb58, 0x00f32979, 0x00258e0f, - 0x00eef788, 0x003850fe, 0x0018b2df, 0x00ce15a9, 0x0059769d, 0x008fd1eb, 0x00af33ca, 0x007994bc, - 0x00dafe19, 0x000c596f, 0x002cbb4e, 0x00fa1c38, 0x006d7f0c, 0x00bbd87a, 0x009b3a5b, 0x004d9d2d -}; - -#define INIT_CRC24 0xffffff - -uint32_t crc24_calc(uint32_t fcs, uint8_t *cp, unsigned int len) -{ - while (len--) - fcs = (fcs >> 8) ^ tbl_crc24[(fcs ^ *cp++) & 0xff]; - return fcs; -} diff --git a/src/gprs/gb_proxy.c b/src/gprs/gb_proxy.c deleted file mode 100644 index cd38d23bf..000000000 --- a/src/gprs/gb_proxy.c +++ /dev/null @@ -1,1438 +0,0 @@ -/* NS-over-IP proxy */ - -/* (C) 2010 by Harald Welte - * (C) 2010-2013 by On-Waves - * (C) 2013 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -static const struct rate_ctr_desc global_ctr_description[] = { - { "inv-bvci", "Invalid BVC Identifier " }, - { "inv-lai", "Invalid Location Area Identifier" }, - { "inv-rai", "Invalid Routing Area Identifier " }, - { "inv-nsei", "No BVC established for NSEI " }, - { "proto-err.bss", "BSSGP protocol error (BSS )" }, - { "proto-err.sgsn", "BSSGP protocol error (SGSN)" }, - { "not-supp.bss", "Feature not supported (BSS )" }, - { "not-supp.sgsn", "Feature not supported (SGSN)" }, - { "restart.sgsn", "Restarted RESET procedure (SGSN)" }, - { "tx-err.sgsn", "NS Transmission error (SGSN)" }, - { "error", "Other error " }, - { "mod-peer-err", "Patch error: no peer " }, -}; - -static const struct rate_ctr_group_desc global_ctrg_desc = { - .group_name_prefix = "gbproxy.global", - .group_description = "GBProxy Global Statistics", - .num_ctr = ARRAY_SIZE(global_ctr_description), - .ctr_desc = global_ctr_description, - .class_id = OSMO_STATS_CLASS_GLOBAL, -}; - -static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer, - uint16_t ns_bvci); -static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg, - uint16_t ns_bvci, uint16_t sgsn_nsei); -static void gbproxy_reset_imsi_acquisition(struct gbproxy_link_info* link_info); - -static int check_peer_nsei(struct gbproxy_peer *peer, uint16_t nsei) -{ - if (peer->nsei != nsei) { - LOGP(DGPRS, LOGL_NOTICE, "Peer entry doesn't match current NSEI " - "BVCI=%u via NSEI=%u (expected NSEI=%u)\n", - peer->bvci, nsei, peer->nsei); - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_INV_NSEI]); - return 0; - } - - return 1; -} - -/* strip off the NS header */ -static void strip_ns_hdr(struct msgb *msg) -{ - int strip_len = msgb_bssgph(msg) - msg->data; - msgb_pull(msg, strip_len); -} - -/* Transmit Chapter 9.2.10 Identity Request */ -static void gprs_put_identity_req(struct msgb *msg, uint8_t id_type) -{ - struct gsm48_hdr *gh; - - id_type &= GSM_MI_TYPE_MASK; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_ID_REQ; - gh->data[0] = id_type; -} - -/* Transmit Chapter 9.4.6.2 Detach Accept (mobile originated detach) */ -static void gprs_put_mo_detach_acc(struct msgb *msg) -{ - struct gsm48_hdr *gh; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_DETACH_ACK; - gh->data[0] = 0; /* no force to standby */ -} - -static void gprs_push_llc_ui(struct msgb *msg, - int is_uplink, unsigned sapi, unsigned nu) -{ - const uint8_t e_bit = 0; - const uint8_t pm_bit = 1; - const uint8_t cr_bit = is_uplink ? 0 : 1; - uint8_t *llc; - uint8_t *fcs_field; - uint32_t fcs; - - nu &= 0x01ff; /* 9 Bit */ - - llc = msgb_push(msg, 3); - llc[0] = (cr_bit << 6) | (sapi & 0x0f); - llc[1] = 0xc0 | (nu >> 6); /* UI frame */ - llc[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1); - - fcs = gprs_llc_fcs(llc, msgb_length(msg)); - fcs_field = msgb_put(msg, 3); - fcs_field[0] = (uint8_t)(fcs >> 0); - fcs_field[1] = (uint8_t)(fcs >> 8); - fcs_field[2] = (uint8_t)(fcs >> 16); -} - -static void gprs_push_bssgp_dl_unitdata(struct msgb *msg, - uint32_t tlli) -{ - struct bssgp_ud_hdr *budh; - uint8_t *llc = msgb_data(msg); - size_t llc_size = msgb_length(msg); - const size_t llc_ie_hdr_size = 3; - const uint8_t qos_profile[] = {0x00, 0x50, 0x20}; /* hard-coded */ - const uint8_t lifetime[] = {0x02, 0x58}; /* 6s hard-coded */ - - const size_t bssgp_overhead = sizeof(*budh) + - TVLV_GROSS_LEN(sizeof(lifetime)) + llc_ie_hdr_size; - uint8_t *ie; - uint32_t tlli_be = htonl(tlli); - - budh = (struct bssgp_ud_hdr *)msgb_push(msg, bssgp_overhead); - - budh->pdu_type = BSSGP_PDUT_DL_UNITDATA; - memcpy(&budh->tlli, &tlli_be, sizeof(budh->tlli)); - memcpy(&budh->qos_profile, qos_profile, sizeof(budh->qos_profile)); - - ie = budh->data; - tvlv_put(ie, BSSGP_IE_PDU_LIFETIME, sizeof(lifetime), lifetime); - ie += TVLV_GROSS_LEN(sizeof(lifetime)); - - /* Note: Add alignment before the LLC IE if inserting other IE */ - - *(ie++) = BSSGP_IE_LLC_PDU; - *(ie++) = llc_size / 256; - *(ie++) = llc_size % 256; - - OSMO_ASSERT(ie == llc); - - msgb_bssgph(msg) = (uint8_t *)budh; - msgb_tlli(msg) = tlli; -} - -/* update peer according to the BSS message */ -static void gbprox_update_current_raid(uint8_t *raid_enc, - struct gbproxy_peer *peer, - const char *log_text) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - const int old_local_mcc = state->local_mcc; - const int old_local_mnc = state->local_mnc; - struct gprs_ra_id raid; - - if (!raid_enc) - return; - - gsm48_parse_ra(&raid, raid_enc); - - /* save source side MCC/MNC */ - if (!peer->cfg->core_mcc || raid.mcc == peer->cfg->core_mcc) { - state->local_mcc = 0; - } else { - state->local_mcc = raid.mcc; - } - - if (!peer->cfg->core_mnc || raid.mnc == peer->cfg->core_mnc) { - state->local_mnc = 0; - } else { - state->local_mnc = raid.mnc; - } - - if (old_local_mcc != state->local_mcc || - old_local_mnc != state->local_mnc) - LOGP(DGPRS, LOGL_NOTICE, - "Patching RAID %sactivated, msg: %s, " - "local: %d-%d, core: %d-%d\n", - state->local_mcc || state->local_mnc ? - "" : "de", - log_text, - state->local_mcc, state->local_mnc, - peer->cfg->core_mcc, peer->cfg->core_mnc); -} - -uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer, - uint32_t sgsn_ptmsi) -{ - uint32_t bss_ptmsi; - int max_retries = 23; - if (!peer->cfg->patch_ptmsi) { - bss_ptmsi = sgsn_ptmsi; - } else { - do { - if (RAND_bytes((uint8_t *) &bss_ptmsi, sizeof(bss_ptmsi)) != 1) { - bss_ptmsi = GSM_RESERVED_TMSI; - break; - } - - bss_ptmsi = bss_ptmsi | 0xC0000000; - - if (gbproxy_link_info_by_ptmsi(peer, bss_ptmsi)) - bss_ptmsi = GSM_RESERVED_TMSI; - } while (bss_ptmsi == GSM_RESERVED_TMSI && max_retries--); - } - - if (bss_ptmsi == GSM_RESERVED_TMSI) - LOGP(DGPRS, LOGL_ERROR, "Failed to allocate a BSS P-TMSI\n"); - - return bss_ptmsi; -} - -uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, - uint32_t bss_tlli) -{ - uint32_t sgsn_tlli; - int max_retries = 23; - if (!peer->cfg->patch_ptmsi) { - sgsn_tlli = bss_tlli; - } else if (link_info->sgsn_tlli.ptmsi != GSM_RESERVED_TMSI && - gprs_tlli_type(bss_tlli) == TLLI_FOREIGN) { - sgsn_tlli = gprs_tmsi2tlli(link_info->sgsn_tlli.ptmsi, - TLLI_FOREIGN); - } else if (link_info->sgsn_tlli.ptmsi != GSM_RESERVED_TMSI && - gprs_tlli_type(bss_tlli) == TLLI_LOCAL) { - sgsn_tlli = gprs_tmsi2tlli(link_info->sgsn_tlli.ptmsi, - TLLI_LOCAL); - } else { - do { - /* create random TLLI, 0b01111xxx... */ - if (RAND_bytes((uint8_t *) &sgsn_tlli, sizeof(sgsn_tlli)) != 1) { - sgsn_tlli = 0; - break; - } - - sgsn_tlli = (sgsn_tlli & 0x7fffffff) | 0x78000000; - - if (gbproxy_link_info_by_any_sgsn_tlli(peer, sgsn_tlli)) - sgsn_tlli = 0; - } while (!sgsn_tlli && max_retries--); - } - - if (!sgsn_tlli) - LOGP(DGPRS, LOGL_ERROR, "Failed to allocate an SGSN TLLI\n"); - - return sgsn_tlli; -} - -void gbproxy_reset_link(struct gbproxy_link_info *link_info) -{ - gbproxy_reset_imsi_acquisition(link_info); -} - -/* Returns != 0 iff IMSI acquisition was in progress */ -static int gbproxy_restart_imsi_acquisition(struct gbproxy_link_info* link_info) -{ - int in_progress = 0; - if (!link_info) - return 0; - - if (link_info->imsi_acq_pending) - in_progress = 1; - - gbproxy_link_info_discard_messages(link_info); - link_info->imsi_acq_pending = 0; - - return in_progress; -} - -static void gbproxy_reset_imsi_acquisition(struct gbproxy_link_info* link_info) -{ - gbproxy_restart_imsi_acquisition(link_info); - link_info->vu_gen_tx_bss = GBPROXY_INIT_VU_GEN_TX; -} - -static int gbproxy_flush_stored_messages(struct gbproxy_peer *peer, - struct msgb *msg, - time_t now, - struct gbproxy_link_info* link_info, - struct gprs_gb_parse_context *parse_ctx) -{ - int rc; - struct msgb *stored_msg; - /* Got identity response with IMSI, assuming the request had - * been generated by the gbproxy */ - - LOGP(DLLC, LOGL_DEBUG, - "NSEI=%d(BSS) IMSI acquisition succeeded, " - "flushing stored messages\n", - msgb_nsei(msg)); - - /* Patch and flush stored messages towards the SGSN */ - while ((stored_msg = msgb_dequeue(&link_info->stored_msgs))) { - struct gprs_gb_parse_context tmp_parse_ctx = {0}; - tmp_parse_ctx.to_bss = 0; - tmp_parse_ctx.peer_nsei = msgb_nsei(stored_msg); - int len_change = 0; - - gprs_gb_parse_bssgp(msgb_bssgph(stored_msg), - msgb_bssgp_len(stored_msg), - &tmp_parse_ctx); - gbproxy_patch_bssgp(msg, msgb_bssgph(stored_msg), - msgb_bssgp_len(stored_msg), - peer, link_info, &len_change, - &tmp_parse_ctx); - - rc = gbproxy_update_link_state_after(peer, link_info, now, - &tmp_parse_ctx); - if (rc == 1) { - LOGP(DLLC, LOGL_NOTICE, "link_info deleted while flushing stored messages\n"); - msgb_free(stored_msg); - return -1; - } - - rc = gbprox_relay2sgsn(peer->cfg, stored_msg, - msgb_bvci(msg), link_info->sgsn_nsei); - - if (rc < 0) - LOGP(DLLC, LOGL_ERROR, - "NSEI=%d(BSS) failed to send stored message " - "(%s)\n", - msgb_nsei(msg), - parse_ctx->llc_msg_name ? - parse_ctx->llc_msg_name : "BSSGP"); - msgb_free(stored_msg); - } - - return 0; -} - -static int gbproxy_gsm48_to_peer(struct gbproxy_peer *peer, - struct gbproxy_link_info* link_info, - uint16_t bvci, - struct msgb *msg /* Takes msg ownership */) -{ - int rc; - - /* Workaround to avoid N(U) collisions and to enable a restart - * of the IMSI acquisition procedure. This will work unless the - * SGSN has an initial V(UT) within [256-32, 256+n_retries] - * (see GSM 04.64, 8.4.2). */ - gprs_push_llc_ui(msg, 0, GPRS_SAPI_GMM, link_info->vu_gen_tx_bss); - link_info->vu_gen_tx_bss = (link_info->vu_gen_tx_bss + 1) % 512; - - gprs_push_bssgp_dl_unitdata(msg, link_info->tlli.current); - rc = gbprox_relay2peer(msg, peer, bvci); - msgb_free(msg); - return rc; -} - -static void gbproxy_acquire_imsi(struct gbproxy_peer *peer, - struct gbproxy_link_info* link_info, - uint16_t bvci) -{ - struct msgb *idreq_msg; - - /* Send IDENT REQ */ - idreq_msg = gsm48_msgb_alloc_name("GSM 04.08 ACQ IMSI"); - gprs_put_identity_req(idreq_msg, GSM_MI_TYPE_IMSI); - gbproxy_gsm48_to_peer(peer, link_info, bvci, idreq_msg); -} - -static void gbproxy_tx_detach_acc(struct gbproxy_peer *peer, - struct gbproxy_link_info* link_info, - uint16_t bvci) -{ - struct msgb *detacc_msg; - - /* Send DETACH ACC */ - detacc_msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACC"); - gprs_put_mo_detach_acc(detacc_msg); - gbproxy_gsm48_to_peer(peer, link_info, bvci, detacc_msg); -} - -/* Return != 0 iff msg still needs to be processed */ -static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer, - struct msgb *msg, - time_t now, - struct gbproxy_link_info* link_info, - struct gprs_gb_parse_context *parse_ctx) -{ - struct msgb *stored_msg; - - if (!link_info) - return 1; - - if (!link_info->imsi_acq_pending && link_info->imsi_len > 0) - return 1; - - if (parse_ctx->g48_hdr) - switch (parse_ctx->g48_hdr->msg_type) - { - case GSM48_MT_GMM_RA_UPD_REQ: - case GSM48_MT_GMM_ATTACH_REQ: - if (gbproxy_restart_imsi_acquisition(link_info)) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI acquisition was in progress " - "when receiving an %s.\n", - msgb_nsei(msg), parse_ctx->llc_msg_name); - } - break; - case GSM48_MT_GMM_DETACH_REQ: - /* Nothing has been sent to the SGSN yet */ - if (link_info->imsi_acq_pending) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI acquisition was in progress " - "when receiving a DETACH_REQ.\n", - msgb_nsei(msg)); - } - if (!parse_ctx->invalidate_tlli) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI not yet acquired, " - "faking a DETACH_ACC.\n", - msgb_nsei(msg)); - gbproxy_tx_detach_acc(peer, link_info, msgb_bvci(msg)); - parse_ctx->invalidate_tlli = 1; - } - gbproxy_reset_imsi_acquisition(link_info); - gbproxy_update_link_state_after(peer, link_info, now, - parse_ctx); - return 0; - } - - if (link_info->imsi_acq_pending && link_info->imsi_len > 0) { - int is_ident_resp = - parse_ctx->g48_hdr && - gsm48_hdr_pdisc(parse_ctx->g48_hdr) == GSM48_PDISC_MM_GPRS && - gsm48_hdr_msg_type(parse_ctx->g48_hdr) == GSM48_MT_GMM_ID_RESP; - - /* The IMSI is now available. If flushing the messages fails, - * then link_info has been deleted and we should return - * immediately. */ - if (gbproxy_flush_stored_messages(peer, msg, now, link_info, - parse_ctx) < 0) - return 0; - - gbproxy_reset_imsi_acquisition(link_info); - - /* This message is most probably the response to the ident - * request sent by gbproxy_acquire_imsi(). Don't forward it to - * the SGSN. */ - return !is_ident_resp; - } - - /* The message cannot be processed since the IMSI is still missing */ - - /* Enqueue unpatched messages */ - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI acquisition in progress, " - "storing message (%s)\n", - msgb_nsei(msg), - parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP"); - - stored_msg = gprs_msgb_copy(msg, "process_bssgp_ul"); - msgb_enqueue(&link_info->stored_msgs, stored_msg); - - if (!link_info->imsi_acq_pending) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI is required but not available, " - "initiating identification procedure (%s)\n", - msgb_nsei(msg), - parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP"); - - gbproxy_acquire_imsi(peer, link_info, msgb_bvci(msg)); - - /* There is no explicit retransmission handling, the - * implementation relies on the MS doing proper retransmissions - * of the triggering message instead */ - - link_info->imsi_acq_pending = 1; - } - - return 0; -} - -struct gbproxy_peer *gbproxy_find_peer(struct gbproxy_config *cfg, - struct msgb *msg, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gbproxy_peer *peer = NULL; - - if (msgb_bvci(msg) >= 2) - peer = gbproxy_peer_by_bvci(cfg, msgb_bvci(msg)); - - if (!peer && !parse_ctx->to_bss) - peer = gbproxy_peer_by_nsei(cfg, msgb_nsei(msg)); - - if (!peer) - peer = gbproxy_peer_by_bssgp_tlv(cfg, &parse_ctx->bssgp_tp); - - if (!peer) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(%s) patching: didn't find peer for message, " - "PDU %d\n", - msgb_nsei(msg), parse_ctx->to_bss ? "BSS" : "SGSN", - parse_ctx->pdu_type); - /* Increment counter */ - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PATCH_PEER_ERR]); - } - return peer; -} - -/* patch BSSGP message */ -static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg, - struct msgb *msg, - struct gbproxy_peer *peer) -{ - struct gprs_gb_parse_context parse_ctx = {0}; - int rc; - int len_change = 0; - time_t now; - struct timespec ts = {0,}; - struct gbproxy_link_info *link_info = NULL; - uint32_t sgsn_nsei = cfg->nsip_sgsn_nsei; - - if (!cfg->core_mcc && !cfg->core_mnc && !cfg->core_apn && - !cfg->acquire_imsi && !cfg->patch_ptmsi && !cfg->route_to_sgsn2) - return 1; - - parse_ctx.to_bss = 0; - parse_ctx.peer_nsei = msgb_nsei(msg); - - /* Parse BSSGP/LLC */ - rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg), - &parse_ctx); - - if (!rc && !parse_ctx.need_decryption) { - LOGP(DGPRS, LOGL_ERROR, - "NSEI=%u(BSS) patching: failed to parse invalid %s message\n", - msgb_nsei(msg), gprs_gb_message_name(&parse_ctx, "NS_UNITDATA")); - gprs_gb_log_parse_context(LOGL_NOTICE, &parse_ctx, "NS_UNITDATA"); - LOGP(DGPRS, LOGL_NOTICE, - "NSEI=%u(BSS) invalid message was: %s\n", - msgb_nsei(msg), msgb_hexdump(msg)); - return 0; - } - - /* Get peer */ - if (!peer) - peer = gbproxy_find_peer(cfg, msg, &parse_ctx); - - if (!peer) - return 0; - - - clock_gettime(CLOCK_MONOTONIC, &ts); - now = ts.tv_sec; - - gbprox_update_current_raid(parse_ctx.bssgp_raid_enc, peer, - parse_ctx.llc_msg_name); - - gprs_gb_log_parse_context(LOGL_DEBUG, &parse_ctx, "NS_UNITDATA"); - - link_info = gbproxy_update_link_state_ul(peer, now, &parse_ctx); - - if (parse_ctx.g48_hdr) { - switch (parse_ctx.g48_hdr->msg_type) { - case GSM48_MT_GMM_ATTACH_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REQS]); - break; - case GSM48_MT_GMM_DETACH_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DETACH_REQS]); - break; - case GSM48_MT_GMM_ATTACH_COMPL: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_COMPLS]); - break; - case GSM48_MT_GMM_RA_UPD_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REQS]); - break; - case GSM48_MT_GMM_RA_UPD_COMPL: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_COMPLS]); - break; - case GSM48_MT_GMM_STATUS: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_BSS]); - break; - case GSM48_MT_GSM_ACT_PDP_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REQS]); - break; - case GSM48_MT_GSM_DEACT_PDP_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_REQS]); - break; - - default: - break; - } - } - - if (link_info && cfg->route_to_sgsn2) { - if (cfg->acquire_imsi && link_info->imsi_len == 0) - sgsn_nsei = 0xffff; - else if (gbproxy_imsi_matches(cfg, GBPROX_MATCH_ROUTING, - link_info)) - sgsn_nsei = cfg->nsip_sgsn2_nsei; - } - - if (link_info) - link_info->sgsn_nsei = sgsn_nsei; - - /* Handle IMSI acquisition */ - if (cfg->acquire_imsi) { - rc = gbproxy_imsi_acquisition(peer, msg, now, link_info, - &parse_ctx); - if (rc <= 0) - return rc; - } - - gbproxy_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg), - peer, link_info, &len_change, &parse_ctx); - - gbproxy_update_link_state_after(peer, link_info, now, &parse_ctx); - - if (sgsn_nsei != cfg->nsip_sgsn_nsei) { - /* Send message directly to the selected SGSN */ - rc = gbprox_relay2sgsn(cfg, msg, msgb_bvci(msg), sgsn_nsei); - /* Don't let the calling code handle the transmission */ - return 0; - } - - return 1; -} - -/* patch BSSGP message to use core_mcc/mnc on the SGSN side */ -static void gbprox_process_bssgp_dl(struct gbproxy_config *cfg, - struct msgb *msg, - struct gbproxy_peer *peer) -{ - struct gprs_gb_parse_context parse_ctx = {0}; - int rc; - int len_change = 0; - time_t now; - struct timespec ts = {0,}; - struct gbproxy_link_info *link_info = NULL; - - if (!cfg->core_mcc && !cfg->core_mnc && !cfg->core_apn && - !cfg->acquire_imsi && !cfg->patch_ptmsi && !cfg->route_to_sgsn2) - return; - - parse_ctx.to_bss = 1; - parse_ctx.peer_nsei = msgb_nsei(msg); - - rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg), - &parse_ctx); - - if (!rc && !parse_ctx.need_decryption) { - LOGP(DGPRS, LOGL_ERROR, - "NSEI=%u(SGSN) patching: failed to parse invalid %s message\n", - msgb_nsei(msg), gprs_gb_message_name(&parse_ctx, "NS_UNITDATA")); - gprs_gb_log_parse_context(LOGL_NOTICE, &parse_ctx, "NS_UNITDATA"); - LOGP(DGPRS, LOGL_NOTICE, - "NSEI=%u(SGSN) invalid message was: %s\n", - msgb_nsei(msg), msgb_hexdump(msg)); - return; - } - - /* Get peer */ - if (!peer) - peer = gbproxy_find_peer(cfg, msg, &parse_ctx); - - if (!peer) - return; - - clock_gettime(CLOCK_MONOTONIC, &ts); - now = ts.tv_sec; - - if (parse_ctx.g48_hdr) { - switch (parse_ctx.g48_hdr->msg_type) { - case GSM48_MT_GMM_ATTACH_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_ACKS]); - break; - case GSM48_MT_GMM_ATTACH_REJ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REJS]); - break; - case GSM48_MT_GMM_DETACH_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DETACH_ACKS]); - break; - case GSM48_MT_GMM_RA_UPD_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_ACKS]); - break; - case GSM48_MT_GMM_RA_UPD_REJ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REJS]); - break; - case GSM48_MT_GMM_STATUS: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_SGSN]); - break; - case GSM48_MT_GSM_ACT_PDP_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_ACKS]); - break; - case GSM48_MT_GSM_ACT_PDP_REJ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REJS]); - break; - case GSM48_MT_GSM_DEACT_PDP_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_ACKS]); - break; - - default: - break; - } - } - - gprs_gb_log_parse_context(LOGL_DEBUG, &parse_ctx, "NS_UNITDATA"); - - link_info = gbproxy_update_link_state_dl(peer, now, &parse_ctx); - - gbproxy_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg), - peer, link_info, &len_change, &parse_ctx); - - gbproxy_update_link_state_after(peer, link_info, now, &parse_ctx); - - return; -} - -/* feed a message down the NS-VC associated with the specified peer */ -static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg, - uint16_t ns_bvci, uint16_t sgsn_nsei) -{ - /* create a copy of the message so the old one can - * be free()d safely when we return from gbprox_rcvmsg() */ - struct msgb *msg = gprs_msgb_copy(old_msg, "msgb_relay2sgsn"); - int rc; - - DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n", - msgb_nsei(msg), ns_bvci, sgsn_nsei); - - msgb_bvci(msg) = ns_bvci; - msgb_nsei(msg) = sgsn_nsei; - - strip_ns_hdr(msg); - - rc = gprs_ns_sendmsg(bssgp_nsi, msg); - if (rc < 0) - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_TX_ERR_SGSN]); - - return rc; -} - -/* feed a message down the NS-VC associated with the specified peer */ -static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer, - uint16_t ns_bvci) -{ - /* create a copy of the message so the old one can - * be free()d safely when we return from gbprox_rcvmsg() */ - struct msgb *msg = gprs_msgb_copy(old_msg, "msgb_relay2peer"); - int rc; - - DEBUGP(DGPRS, "NSEI=%u proxying SGSN->BSS (NS_BVCI=%u, NSEI=%u)\n", - msgb_nsei(msg), ns_bvci, peer->nsei); - - msgb_bvci(msg) = ns_bvci; - msgb_nsei(msg) = peer->nsei; - - /* Strip the old NS header, it will be replaced with a new one */ - strip_ns_hdr(msg); - - rc = gprs_ns_sendmsg(bssgp_nsi, msg); - if (rc < 0) - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_TX_ERR]); - - return rc; -} - -static int block_unblock_peer(struct gbproxy_config *cfg, uint16_t ptp_bvci, uint8_t pdu_type) -{ - struct gbproxy_peer *peer; - - peer = gbproxy_peer_by_bvci(cfg, ptp_bvci); - if (!peer) { - LOGP(DGPRS, LOGL_ERROR, "BVCI=%u: Cannot find BSS\n", - ptp_bvci); - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_BVCI]); - return -ENOENT; - } - - switch (pdu_type) { - case BSSGP_PDUT_BVC_BLOCK_ACK: - peer->blocked = 1; - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_BLOCKED]); - break; - case BSSGP_PDUT_BVC_UNBLOCK_ACK: - peer->blocked = 0; - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_UNBLOCKED]); - break; - default: - break; - } - return 0; -} - -/* Send a message to a peer identified by ptp_bvci but using ns_bvci - * in the NS hdr */ -static int gbprox_relay2bvci(struct gbproxy_config *cfg, struct msgb *msg, uint16_t ptp_bvci, - uint16_t ns_bvci) -{ - struct gbproxy_peer *peer; - - peer = gbproxy_peer_by_bvci(cfg, ptp_bvci); - if (!peer) { - LOGP(DGPRS, LOGL_ERROR, "BVCI=%u: Cannot find BSS\n", - ptp_bvci); - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_BVCI]); - return -ENOENT; - } - - return gbprox_relay2peer(msg, peer, ns_bvci); -} - -int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) -{ - return 0; -} - -/* Receive an incoming PTP message from a BSS-side NS-VC */ -static int gbprox_rx_ptp_from_bss(struct gbproxy_config *cfg, - struct msgb *msg, uint16_t nsei, - uint16_t nsvci, uint16_t ns_bvci) -{ - struct gbproxy_peer *peer; - struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); - uint8_t pdu_type = bgph->pdu_type; - int rc; - - peer = gbproxy_peer_by_bvci(cfg, ns_bvci); - if (!peer) { - LOGP(DGPRS, LOGL_NOTICE, "Didn't find peer for " - "BVCI=%u for PTP message from NSVC=%u/NSEI=%u (BSS), " - "discarding message\n", - ns_bvci, nsvci, nsei); - return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, - &ns_bvci, msg); - } - - check_peer_nsei(peer, nsei); - - rc = gbprox_process_bssgp_ul(cfg, msg, peer); - if (!rc) - return 0; - - switch (pdu_type) { - case BSSGP_PDUT_FLOW_CONTROL_BVC: - if (!cfg->route_to_sgsn2) - break; - - /* Send a copy to the secondary SGSN */ - gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn2_nsei); - break; - default: - break; - } - - - return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei); -} - -/* Receive an incoming PTP message from a SGSN-side NS-VC */ -static int gbprox_rx_ptp_from_sgsn(struct gbproxy_config *cfg, - struct msgb *msg, uint16_t nsei, - uint16_t nsvci, uint16_t ns_bvci) -{ - struct gbproxy_peer *peer; - struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); - uint8_t pdu_type = bgph->pdu_type; - - peer = gbproxy_peer_by_bvci(cfg, ns_bvci); - - /* Send status messages before patching */ - - if (!peer) { - LOGP(DGPRS, LOGL_INFO, "Didn't find peer for " - "BVCI=%u for message from NSVC=%u/NSEI=%u (SGSN)\n", - ns_bvci, nsvci, nsei); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_INV_BVCI]); - return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, - &ns_bvci, msg); - } - - if (peer->blocked) { - LOGP(DGPRS, LOGL_NOTICE, "Dropping PDU for " - "blocked BVCI=%u via NSVC=%u/NSEI=%u\n", - ns_bvci, nsvci, nsei); - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DROPPED]); - return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, &ns_bvci, msg); - } - - switch (pdu_type) { - case BSSGP_PDUT_FLOW_CONTROL_BVC_ACK: - case BSSGP_PDUT_BVC_BLOCK_ACK: - case BSSGP_PDUT_BVC_UNBLOCK_ACK: - if (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei) - /* Hide ACKs from the secondary SGSN, the primary SGSN - * is responsible to send them. */ - return 0; - break; - default: - break; - } - - /* Optionally patch the message */ - gbprox_process_bssgp_dl(cfg, msg, peer); - - return gbprox_relay2peer(msg, peer, ns_bvci); -} - -/* Receive an incoming signalling message from a BSS-side NS-VC */ -static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg, - struct msgb *msg, uint16_t nsei, - uint16_t ns_bvci) -{ - struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); - struct tlv_parsed tp; - uint8_t pdu_type = bgph->pdu_type; - int data_len = msgb_bssgp_len(msg) - sizeof(*bgph); - struct gbproxy_peer *from_peer = NULL; - struct gprs_ra_id raid; - int copy_to_sgsn2 = 0; - int rc; - - if (ns_bvci != 0 && ns_bvci != 1) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u BVCI=%u is not signalling\n", - nsei, ns_bvci); - return -EINVAL; - } - - /* we actually should never see those two for BVCI == 0, but double-check - * just to make sure */ - if (pdu_type == BSSGP_PDUT_UL_UNITDATA || - pdu_type == BSSGP_PDUT_DL_UNITDATA) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u UNITDATA not allowed in " - "signalling\n", nsei); - return -EINVAL; - } - - bssgp_tlv_parse(&tp, bgph->data, data_len); - - switch (pdu_type) { - case BSSGP_PDUT_SUSPEND: - case BSSGP_PDUT_RESUME: - /* We implement RAI snooping during SUSPEND/RESUME, since it - * establishes a relationsip between BVCI/peer and the routeing - * area identification. The snooped information is then used - * for routing the {SUSPEND,RESUME}_[N]ACK back to the correct - * BSSGP */ - if (!TLVP_PRESENT(&tp, BSSGP_IE_ROUTEING_AREA)) - goto err_mand_ie; - from_peer = gbproxy_peer_by_nsei(cfg, nsei); - if (!from_peer) - goto err_no_peer; - memcpy(from_peer->ra, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA), - sizeof(from_peer->ra)); - gsm48_parse_ra(&raid, from_peer->ra); - LOGP(DGPRS, LOGL_INFO, "NSEI=%u BSSGP SUSPEND/RESUME " - "RAI snooping: RAI %u-%u-%u-%u behind BVCI=%u\n", - nsei, raid.mcc, raid.mnc, raid.lac, - raid.rac , from_peer->bvci); - /* FIXME: This only supports one BSS per RA */ - break; - case BSSGP_PDUT_BVC_RESET: - /* If we receive a BVC reset on the signalling endpoint, we - * don't want the SGSN to reset, as the signalling endpoint - * is common for all point-to-point BVCs (and thus all BTS) */ - if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) { - uint16_t bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); - LOGP(DGPRS, LOGL_INFO, "NSEI=%u Rx BVC RESET (BVCI=%u)\n", - nsei, bvci); - if (bvci == 0) { - /* FIXME: only do this if SGSN is alive! */ - LOGP(DGPRS, LOGL_INFO, "NSEI=%u Tx fake " - "BVC RESET ACK of BVCI=0\n", nsei); - return bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_RESET_ACK, - nsei, 0, ns_bvci); - } - from_peer = gbproxy_peer_by_bvci(cfg, bvci); - if (!from_peer) { - /* if a PTP-BVC is reset, and we don't know that - * PTP-BVCI yet, we should allocate a new peer */ - LOGP(DGPRS, LOGL_INFO, "Allocationg new peer for " - "BVCI=%u via NSEI=%u\n", bvci, nsei); - from_peer = gbproxy_peer_alloc(cfg, bvci); - from_peer->nsei = nsei; - } - - if (!check_peer_nsei(from_peer, nsei)) - from_peer->nsei = nsei; - - if (TLVP_PRESENT(&tp, BSSGP_IE_CELL_ID)) { - struct gprs_ra_id raid; - /* We have a Cell Identifier present in this - * PDU, this means we can extend our local - * state information about this particular cell - * */ - memcpy(from_peer->ra, - TLVP_VAL(&tp, BSSGP_IE_CELL_ID), - sizeof(from_peer->ra)); - gsm48_parse_ra(&raid, from_peer->ra); - LOGP(DGPRS, LOGL_INFO, "NSEI=%u/BVCI=%u " - "Cell ID %u-%u-%u-%u\n", nsei, - bvci, raid.mcc, raid.mnc, raid.lac, - raid.rac); - } - if (cfg->route_to_sgsn2) - copy_to_sgsn2 = 1; - } - break; - } - - /* Normally, we can simply pass on all signalling messages from BSS to - * SGSN */ - rc = gbprox_process_bssgp_ul(cfg, msg, from_peer); - if (!rc) - return 0; - - if (copy_to_sgsn2) - gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn2_nsei); - - return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei); -err_no_peer: - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(BSS) cannot find peer based on NSEI\n", - nsei); - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_NSEI]); - return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg); -err_mand_ie: - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(BSS) missing mandatory RA IE\n", - nsei); - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]); - return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg); -} - -/* Receive paging request from SGSN, we need to relay to proper BSS */ -static int gbprox_rx_paging(struct gbproxy_config *cfg, struct msgb *msg, struct tlv_parsed *tp, - uint32_t nsei, uint16_t ns_bvci) -{ - struct gbproxy_peer *peer = NULL; - int errctr = GBPROX_GLOB_CTR_PROTO_ERR_SGSN; - - LOGP(DGPRS, LOGL_INFO, "NSEI=%u(SGSN) BSSGP PAGING ", - nsei); - if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) { - uint16_t bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI)); - LOGPC(DGPRS, LOGL_INFO, "routing by BVCI to peer BVCI=%u\n", - bvci); - errctr = GBPROX_GLOB_CTR_OTHER_ERR; - } else if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) { - peer = gbproxy_peer_by_rai(cfg, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA)); - LOGPC(DGPRS, LOGL_INFO, "routing by RAI to peer BVCI=%u\n", - peer ? peer->bvci : -1); - errctr = GBPROX_GLOB_CTR_INV_RAI; - } else if (TLVP_PRESENT(tp, BSSGP_IE_LOCATION_AREA)) { - peer = gbproxy_peer_by_lai(cfg, TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA)); - LOGPC(DGPRS, LOGL_INFO, "routing by LAI to peer BVCI=%u\n", - peer ? peer->bvci : -1); - errctr = GBPROX_GLOB_CTR_INV_LAI; - } else - LOGPC(DGPRS, LOGL_INFO, "\n"); - - if (!peer) { - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(SGSN) BSSGP PAGING: " - "unable to route, missing IE\n", nsei); - rate_ctr_inc(&cfg->ctrg->ctr[errctr]); - return -EINVAL; - } - return gbprox_relay2peer(msg, peer, ns_bvci); -} - -/* Receive an incoming BVC-RESET message from the SGSN */ -static int rx_reset_from_sgsn(struct gbproxy_config *cfg, - struct msgb *orig_msg, - struct msgb *msg, struct tlv_parsed *tp, - uint32_t nsei, uint16_t ns_bvci) -{ - struct gbproxy_peer *peer; - uint16_t ptp_bvci; - - if (!TLVP_PRESENT(tp, BSSGP_IE_BVCI)) { - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]); - return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, - NULL, orig_msg); - } - ptp_bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI)); - - if (ptp_bvci >= 2) { - /* A reset for a PTP BVC was received, forward it to its - * respective peer */ - peer = gbproxy_peer_by_bvci(cfg, ptp_bvci); - if (!peer) { - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u BVCI=%u: Cannot find BSS\n", - nsei, ptp_bvci); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_INV_BVCI]); - return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, - &ptp_bvci, orig_msg); - } - return gbprox_relay2peer(msg, peer, ns_bvci); - } - - /* A reset for the Signalling entity has been received - * from the SGSN. As the signalling BVCI is shared - * among all the BSS's that we multiplex, it needs to - * be relayed */ - llist_for_each_entry(peer, &cfg->bts_peers, list) - gbprox_relay2peer(msg, peer, ns_bvci); - - return 0; -} - -/* Receive an incoming signalling message from the SGSN-side NS-VC */ -static int gbprox_rx_sig_from_sgsn(struct gbproxy_config *cfg, - struct msgb *orig_msg, uint32_t nsei, - uint16_t ns_bvci) -{ - struct bssgp_normal_hdr *bgph = - (struct bssgp_normal_hdr *) msgb_bssgph(orig_msg); - struct tlv_parsed tp; - uint8_t pdu_type = bgph->pdu_type; - int data_len; - struct gbproxy_peer *peer; - uint16_t bvci; - struct msgb *msg; - int rc = 0; - int cause; - - if (ns_bvci != 0 && ns_bvci != 1) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u(SGSN) BVCI=%u is not " - "signalling\n", nsei, ns_bvci); - /* FIXME: Send proper error message */ - return -EINVAL; - } - - /* we actually should never see those two for BVCI == 0, but double-check - * just to make sure */ - if (pdu_type == BSSGP_PDUT_UL_UNITDATA || - pdu_type == BSSGP_PDUT_DL_UNITDATA) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u(SGSN) UNITDATA not allowed in " - "signalling\n", nsei); - return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, orig_msg); - } - - msg = gprs_msgb_copy(orig_msg, "rx_sig_from_sgsn"); - gbprox_process_bssgp_dl(cfg, msg, NULL); - /* Update message info */ - bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); - data_len = msgb_bssgp_len(orig_msg) - sizeof(*bgph); - rc = bssgp_tlv_parse(&tp, bgph->data, data_len); - - switch (pdu_type) { - case BSSGP_PDUT_BVC_RESET: - rc = rx_reset_from_sgsn(cfg, msg, orig_msg, &tp, nsei, ns_bvci); - break; - case BSSGP_PDUT_BVC_RESET_ACK: - if (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei) - break; - /* fall through */ - case BSSGP_PDUT_FLUSH_LL: - /* simple case: BVCI IE is mandatory */ - if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) - goto err_mand_ie; - bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); - rc = gbprox_relay2bvci(cfg, msg, bvci, ns_bvci); - break; - case BSSGP_PDUT_PAGING_PS: - case BSSGP_PDUT_PAGING_CS: - /* process the paging request (LAI/RAI lookup) */ - rc = gbprox_rx_paging(cfg, msg, &tp, nsei, ns_bvci); - break; - case BSSGP_PDUT_STATUS: - /* Some exception has occurred */ - LOGP(DGPRS, LOGL_NOTICE, - "NSEI=%u(SGSN) BSSGP STATUS ", nsei); - if (!TLVP_PRESENT(&tp, BSSGP_IE_CAUSE)) { - LOGPC(DGPRS, LOGL_NOTICE, "\n"); - goto err_mand_ie; - } - cause = *TLVP_VAL(&tp, BSSGP_IE_CAUSE); - LOGPC(DGPRS, LOGL_NOTICE, - "cause=0x%02x(%s) ", *TLVP_VAL(&tp, BSSGP_IE_CAUSE), - bssgp_cause_str(cause)); - if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) { - bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); - LOGPC(DGPRS, LOGL_NOTICE, "BVCI=%u\n", bvci); - - if (cause == BSSGP_CAUSE_UNKNOWN_BVCI) - rc = gbprox_relay2bvci(cfg, msg, bvci, ns_bvci); - } else - LOGPC(DGPRS, LOGL_NOTICE, "\n"); - break; - /* those only exist in the SGSN -> BSS direction */ - case BSSGP_PDUT_SUSPEND_ACK: - case BSSGP_PDUT_SUSPEND_NACK: - case BSSGP_PDUT_RESUME_ACK: - case BSSGP_PDUT_RESUME_NACK: - /* RAI IE is mandatory */ - if (!TLVP_PRESENT(&tp, BSSGP_IE_ROUTEING_AREA)) - goto err_mand_ie; - peer = gbproxy_peer_by_rai(cfg, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA)); - if (!peer) - goto err_no_peer; - rc = gbprox_relay2peer(msg, peer, ns_bvci); - break; - case BSSGP_PDUT_BVC_BLOCK_ACK: - case BSSGP_PDUT_BVC_UNBLOCK_ACK: - if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) - goto err_mand_ie; - bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); - if (bvci == 0) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u(SGSN) BSSGP " - "%sBLOCK_ACK for signalling BVCI ?!?\n", nsei, - pdu_type == BSSGP_PDUT_BVC_UNBLOCK_ACK ? "UN":""); - /* should we send STATUS ? */ - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_INV_BVCI]); - } else { - /* Mark BVC as (un)blocked */ - block_unblock_peer(cfg, bvci, pdu_type); - } - rc = gbprox_relay2bvci(cfg, msg, bvci, ns_bvci); - break; - case BSSGP_PDUT_SGSN_INVOKE_TRACE: - LOGP(DGPRS, LOGL_ERROR, - "NSEI=%u(SGSN) BSSGP INVOKE TRACE not supported\n",nsei); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_NOT_SUPPORTED_SGSN]); - rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, orig_msg); - break; - default: - LOGP(DGPRS, LOGL_NOTICE, "BSSGP PDU type %s not supported\n", bssgp_pdu_str(pdu_type)); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]); - rc = bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, orig_msg); - break; - } - - msgb_free(msg); - - return rc; -err_mand_ie: - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(SGSN) missing mandatory IE\n", - nsei); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]); - msgb_free(msg); - return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, orig_msg); -err_no_peer: - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(SGSN) cannot find peer based on RAI\n", - nsei); - rate_ctr_inc(&cfg->ctrg-> ctr[GBPROX_GLOB_CTR_INV_RAI]); - msgb_free(msg); - return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, orig_msg); -} - -static int gbproxy_is_sgsn_nsei(struct gbproxy_config *cfg, uint16_t nsei) -{ - return nsei == cfg->nsip_sgsn_nsei || - (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei); -} - -/* Main input function for Gb proxy */ -int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei, - uint16_t ns_bvci, uint16_t nsvci) -{ - int rc; - int remote_end_is_sgsn = gbproxy_is_sgsn_nsei(cfg, nsei); - - /* Only BVCI=0 messages need special treatment */ - if (ns_bvci == 0 || ns_bvci == 1) { - if (remote_end_is_sgsn) - rc = gbprox_rx_sig_from_sgsn(cfg, msg, nsei, ns_bvci); - else - rc = gbprox_rx_sig_from_bss(cfg, msg, nsei, ns_bvci); - } else { - /* All other BVCI are PTP */ - if (remote_end_is_sgsn) - rc = gbprox_rx_ptp_from_sgsn(cfg, msg, nsei, nsvci, - ns_bvci); - else - rc = gbprox_rx_ptp_from_bss(cfg, msg, nsei, nsvci, - ns_bvci); - } - - return rc; -} - -int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi) -{ - struct gprs_nsvc *nsvc; - - llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) { - if (!nsvc->persistent) - continue; - gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION); - } - return 0; -} - -/* Signal handler for signals from NS layer */ -int gbprox_signal(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct gbproxy_config *cfg = handler_data; - struct ns_signal_data *nssd = signal_data; - struct gprs_nsvc *nsvc = nssd->nsvc; - struct gbproxy_peer *peer; - int remote_end_is_sgsn = gbproxy_is_sgsn_nsei(cfg, nsvc->nsei); - - if (subsys != SS_L_NS) - return 0; - - if (signal == S_NS_RESET && remote_end_is_sgsn) { - /* We have received a NS-RESET from the NSEI and NSVC - * of the SGSN. This might happen with SGSN that start - * their own NS-RESET procedure without waiting for our - * NS-RESET */ - nsvc->remote_end_is_sgsn = 1; - } - - if (signal == S_NS_ALIVE_EXP && nsvc->remote_end_is_sgsn) { - LOGP(DGPRS, LOGL_NOTICE, "Tns alive expired too often, " - "re-starting RESET procedure\n"); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_RESTART_RESET_SGSN]); - gprs_ns_nsip_connect(nsvc->nsi, &nsvc->ip.bts_addr, - nsvc->nsei, nsvc->nsvci); - } - - if (!nsvc->remote_end_is_sgsn) { - /* from BSS to SGSN */ - peer = gbproxy_peer_by_nsei(cfg, nsvc->nsei); - if (!peer) { - LOGP(DGPRS, LOGL_NOTICE, "signal '%s' for unknown peer NSEI=%u/NSVCI=%u\n", - get_value_string(gprs_ns_signal_ns_names, signal), nsvc->nsei, nsvc->nsvci); - return 0; - } - switch (signal) { - case S_NS_RESET: - case S_NS_BLOCK: - if (!peer->blocked) - break; - LOGP(DGPRS, LOGL_NOTICE, "Converting '%s' from NSEI=%u/NSVCI=%u into BSSGP_BVC_BLOCK to SGSN\n", - get_value_string(gprs_ns_signal_ns_names, signal), nsvc->nsei, nsvc->nsvci); - bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, nsvc->nsei, - peer->bvci, 0); - break; - } - } else { - /* Forward this message to all NS-VC to BSS */ - struct gprs_ns_inst *nsi = cfg->nsi; - struct gprs_nsvc *next_nsvc; - - llist_for_each_entry(next_nsvc, &nsi->gprs_nsvcs, list) { - if (next_nsvc->remote_end_is_sgsn) - continue; - - /* Note that the following does not start the full - * procedures including timer based retransmissions. */ - switch (signal) { - case S_NS_RESET: - gprs_ns_tx_reset(next_nsvc, nssd->cause); - break; - case S_NS_BLOCK: - gprs_ns_tx_block(next_nsvc, nssd->cause); - break; - case S_NS_UNBLOCK: - gprs_ns_tx_unblock(next_nsvc); - break; - } - } - } - return 0; -} - -void gbprox_reset(struct gbproxy_config *cfg) -{ - struct gbproxy_peer *peer, *tmp; - - llist_for_each_entry_safe(peer, tmp, &cfg->bts_peers, list) - gbproxy_peer_free(peer); - - rate_ctr_group_free(cfg->ctrg); - gbproxy_init_config(cfg); -} - -int gbproxy_init_config(struct gbproxy_config *cfg) -{ - struct timespec tp; - - INIT_LLIST_HEAD(&cfg->bts_peers); - cfg->ctrg = rate_ctr_group_alloc(tall_bsc_ctx, &global_ctrg_desc, 0); - if (!cfg->ctrg) { - LOGP(DGPRS, LOGL_ERROR, "Cannot allocate global counter group!\n"); - return -1; - } - clock_gettime(CLOCK_REALTIME, &tp); - - return 0; -} diff --git a/src/gprs/gb_proxy_main.c b/src/gprs/gb_proxy_main.c deleted file mode 100644 index caff27f6f..000000000 --- a/src/gprs/gb_proxy_main.c +++ /dev/null @@ -1,317 +0,0 @@ -/* NS-over-IP proxy */ - -/* (C) 2010 by Harald Welte - * (C) 2010 by On-Waves - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "../../bscconfig.h" - -#define _GNU_SOURCE -#include - -void *tall_bsc_ctx; - -const char *openbsc_copyright = - "Copyright (C) 2010 Harald Welte and On-Waves\r\n" - "License AGPLv3+: GNU AGPL version 3 or later \r\n" - "This is free software: you are free to change and redistribute it.\r\n" - "There is NO WARRANTY, to the extent permitted by law.\r\n"; - -static char *config_file = "osmo_gbproxy.cfg"; -struct gbproxy_config gbcfg = {0}; -static int daemonize = 0; - -/* Pointer to the SGSN peer */ -extern struct gbprox_peer *gbprox_peer_sgsn; - -/* call-back function for the NS protocol */ -static int proxy_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, - struct msgb *msg, uint16_t bvci) -{ - int rc = 0; - - switch (event) { - case GPRS_NS_EVT_UNIT_DATA: - rc = gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci); - break; - default: - LOGP(DGPRS, LOGL_ERROR, "SGSN: Unknown event %u from NS\n", event); - if (msg) - msgb_free(msg); - rc = -EIO; - break; - } - return rc; -} - -static void signal_handler(int signal) -{ - fprintf(stdout, "signal %u received\n", signal); - - switch (signal) { - case SIGINT: - case SIGTERM: - osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); - sleep(1); - exit(0); - break; - case SIGABRT: - /* in case of abort, we want to obtain a talloc report - * and then return to the caller, who will abort the process */ - case SIGUSR1: - talloc_report(tall_vty_ctx, stderr); - talloc_report_full(tall_bsc_ctx, stderr); - break; - case SIGUSR2: - talloc_report_full(tall_vty_ctx, stderr); - break; - default: - break; - } -} - -static void print_usage() -{ - printf("Usage: bsc_hack\n"); -} - -static void print_help() -{ - printf(" Some useful help...\n"); - printf(" -h --help this text\n"); - printf(" -d option --debug=DNS:DGPRS,0:0 enable debugging\n"); - printf(" -D --daemonize Fork the process into a background daemon\n"); - printf(" -c --config-file filename The config file to use.\n"); - printf(" -s --disable-color\n"); - printf(" -T --timestamp Prefix every log line with a timestamp\n"); - printf(" -V --version. Print the version of OpenBSC.\n"); - printf(" -e --log-level number. Set a global loglevel.\n"); -} - -static void handle_options(int argc, char **argv) -{ - while (1) { - int option_index = 0, c; - static struct option long_options[] = { - { "help", 0, 0, 'h' }, - { "debug", 1, 0, 'd' }, - { "daemonize", 0, 0, 'D' }, - { "config-file", 1, 0, 'c' }, - { "disable-color", 0, 0, 's' }, - { "timestamp", 0, 0, 'T' }, - { "version", 0, 0, 'V' }, - { "log-level", 1, 0, 'e' }, - { 0, 0, 0, 0 } - }; - - c = getopt_long(argc, argv, "hd:Dc:sTVe:", - long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - print_usage(); - print_help(); - exit(0); - case 's': - log_set_use_color(osmo_stderr_target, 0); - break; - case 'd': - log_parse_category_mask(osmo_stderr_target, optarg); - break; - case 'D': - daemonize = 1; - break; - case 'c': - config_file = optarg; - break; - case 'T': - log_set_print_timestamp(osmo_stderr_target, 1); - break; - case 'e': - log_set_log_level(osmo_stderr_target, atoi(optarg)); - break; - case 'V': - print_version(1); - exit(0); - break; - default: - break; - } - } -} - -extern int bsc_vty_go_parent(struct vty *vty); - -static struct vty_app_info vty_info = { - .name = "OsmoGbProxy", - .version = PACKAGE_VERSION, - .go_parent_cb = bsc_vty_go_parent, - .is_config_node = bsc_vty_is_config_node, -}; - -/* default categories */ -static struct log_info_cat gprs_categories[] = { - [DGPRS] = { - .name = "DGPRS", - .description = "GPRS Packet Service", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DNS] = { - .name = "DNS", - .description = "GPRS Network Service (NS)", - .enabled = 1, .loglevel = LOGL_INFO, - }, - [DBSSGP] = { - .name = "DBSSGP", - .description = "GPRS BSS Gateway Protocol (BSSGP)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, -}; - -static const struct log_info gprs_log_info = { - .filter_fn = gprs_log_filter_fn, - .cat = gprs_categories, - .num_cat = ARRAY_SIZE(gprs_categories), -}; - -int main(int argc, char **argv) -{ - struct gsm_network dummy_network; - int rc; - - tall_bsc_ctx = talloc_named_const(NULL, 0, "nsip_proxy"); - msgb_talloc_ctx_init(tall_bsc_ctx, 0); - - signal(SIGINT, &signal_handler); - signal(SIGTERM, &signal_handler); - signal(SIGABRT, &signal_handler); - signal(SIGUSR1, &signal_handler); - signal(SIGUSR2, &signal_handler); - osmo_init_ignore_signals(); - - osmo_init_logging(&gprs_log_info); - - vty_info.copyright = openbsc_copyright; - vty_init(&vty_info); - logging_vty_add_cmds(NULL); - osmo_stats_vty_add_cmds(&gprs_log_info); - gbproxy_vty_init(); - - handle_options(argc, argv); - - rate_ctr_init(tall_bsc_ctx); - osmo_stats_init(tall_bsc_ctx); - - bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb, tall_bsc_ctx); - if (!bssgp_nsi) { - LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n"); - exit(1); - } - gbproxy_init_config(&gbcfg); - gbcfg.nsi = bssgp_nsi; - gprs_ns_vty_init(bssgp_nsi); - gprs_ns_set_log_ss(DNS); - bssgp_set_log_ss(DBSSGP); - osmo_signal_register_handler(SS_L_NS, &gbprox_signal, &gbcfg); - - rc = gbproxy_parse_config(config_file, &gbcfg); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Cannot parse config file\n"); - exit(2); - } - - /* start telnet after reading config for vty_get_bind_addr() */ - rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network, - vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY); - if (rc < 0) - exit(1); - - if (!gprs_nsvc_by_nsei(gbcfg.nsi, gbcfg.nsip_sgsn_nsei)) { - LOGP(DGPRS, LOGL_FATAL, "You cannot proxy to NSEI %u " - "without creating that NSEI before\n", - gbcfg.nsip_sgsn_nsei); - exit(2); - } - - rc = gprs_ns_nsip_listen(bssgp_nsi); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on NSIP socket\n"); - exit(2); - } - - rc = gprs_ns_frgre_listen(bssgp_nsi); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen GRE " - "socket. Do you have CAP_NET_RAW?\n"); - exit(2); - } - - if (daemonize) { - rc = osmo_daemonize(); - if (rc < 0) { - perror("Error during daemonize"); - exit(1); - } - } - - /* Reset all the persistent NS-VCs that we've read from the config */ - gbprox_reset_persistent_nsvcs(bssgp_nsi); - - while (1) { - rc = osmo_select_main(0); - if (rc < 0) - exit(3); - } - - exit(0); -} diff --git a/src/gprs/gb_proxy_patch.c b/src/gprs/gb_proxy_patch.c deleted file mode 100644 index 210fb2b96..000000000 --- a/src/gprs/gb_proxy_patch.c +++ /dev/null @@ -1,459 +0,0 @@ -/* Gb-proxy message patching */ - -/* (C) 2014 by On-Waves - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include - -#include -#include - -#include -#include - -#include -#include -#include - -/* patch RA identifier in place */ -static void gbproxy_patch_raid(uint8_t *raid_enc, struct gbproxy_peer *peer, - int to_bss, const char *log_text) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - int old_mcc; - int old_mnc; - struct gprs_ra_id raid; - enum gbproxy_peer_ctr counter = - to_bss ? - GBPROX_PEER_CTR_RAID_PATCHED_SGSN : - GBPROX_PEER_CTR_RAID_PATCHED_BSS; - - if (!state->local_mcc || !state->local_mnc) - return; - - gsm48_parse_ra(&raid, raid_enc); - - old_mcc = raid.mcc; - old_mnc = raid.mnc; - - if (!to_bss) { - /* BSS -> SGSN */ - if (state->local_mcc) - raid.mcc = peer->cfg->core_mcc; - - if (state->local_mnc) - raid.mnc = peer->cfg->core_mnc; - } else { - /* SGSN -> BSS */ - if (state->local_mcc) - raid.mcc = state->local_mcc; - - if (state->local_mnc) - raid.mnc = state->local_mnc; - } - - LOGP(DGPRS, LOGL_DEBUG, - "Patching %s to %s: " - "%d-%d-%d-%d -> %d-%d-%d-%d\n", - log_text, - to_bss ? "BSS" : "SGSN", - old_mcc, old_mnc, raid.lac, raid.rac, - raid.mcc, raid.mnc, raid.lac, raid.rac); - - gsm48_construct_ra(raid_enc, &raid); - rate_ctr_inc(&peer->ctrg->ctr[counter]); -} - -static void gbproxy_patch_apn_ie(struct msgb *msg, - uint8_t *apn_ie, size_t apn_ie_len, - struct gbproxy_peer *peer, - size_t *new_apn_ie_len, const char *log_text) -{ - struct apn_ie_hdr { - uint8_t iei; - uint8_t apn_len; - uint8_t apn[0]; - } *hdr = (void *)apn_ie; - - size_t apn_len = hdr->apn_len; - uint8_t *apn = hdr->apn; - - OSMO_ASSERT(apn_ie_len == apn_len + sizeof(struct apn_ie_hdr)); - OSMO_ASSERT(apn_ie_len > 2 && apn_ie_len <= 102); - - if (peer->cfg->core_apn_size == 0) { - char str1[110]; - /* Remove the IE */ - LOGP(DGPRS, LOGL_DEBUG, - "Patching %s to SGSN: Removing APN '%s'\n", - log_text, - osmo_apn_to_str(str1, apn, apn_len)); - - *new_apn_ie_len = 0; - gprs_msgb_resize_area(msg, apn_ie, apn_ie_len, 0); - } else { - /* Resize the IE */ - char str1[110]; - char str2[110]; - - OSMO_ASSERT(peer->cfg->core_apn_size <= 100); - - LOGP(DGPRS, LOGL_DEBUG, - "Patching %s to SGSN: " - "Replacing APN '%s' -> '%s'\n", - log_text, - osmo_apn_to_str(str1, apn, apn_len), - osmo_apn_to_str(str2, peer->cfg->core_apn, - peer->cfg->core_apn_size)); - - *new_apn_ie_len = peer->cfg->core_apn_size + 2; - gprs_msgb_resize_area(msg, apn, apn_len, peer->cfg->core_apn_size); - memcpy(apn, peer->cfg->core_apn, peer->cfg->core_apn_size); - hdr->apn_len = peer->cfg->core_apn_size; - } - - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_APN_PATCHED]); -} - -static int gbproxy_patch_tlli(uint8_t *tlli_enc, - struct gbproxy_peer *peer, - uint32_t new_tlli, - int to_bss, const char *log_text) -{ - uint32_t tlli_be; - uint32_t tlli; - enum gbproxy_peer_ctr counter = - to_bss ? - GBPROX_PEER_CTR_TLLI_PATCHED_SGSN : - GBPROX_PEER_CTR_TLLI_PATCHED_BSS; - - memcpy(&tlli_be, tlli_enc, sizeof(tlli_be)); - tlli = ntohl(tlli_be); - - if (tlli == new_tlli) - return 0; - - LOGP(DGPRS, LOGL_DEBUG, - "Patching %ss: " - "Replacing %08x -> %08x\n", - log_text, tlli, new_tlli); - - tlli_be = htonl(new_tlli); - memcpy(tlli_enc, &tlli_be, sizeof(tlli_be)); - - rate_ctr_inc(&peer->ctrg->ctr[counter]); - - return 1; -} - -static int gbproxy_patch_ptmsi(uint8_t *ptmsi_enc, - struct gbproxy_peer *peer, - uint32_t new_ptmsi, - int to_bss, const char *log_text) -{ - uint32_t ptmsi_be; - uint32_t ptmsi; - enum gbproxy_peer_ctr counter = - to_bss ? - GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN : - GBPROX_PEER_CTR_PTMSI_PATCHED_BSS; - memcpy(&ptmsi_be, ptmsi_enc, sizeof(ptmsi_be)); - ptmsi = ntohl(ptmsi_be); - - if (ptmsi == new_ptmsi) - return 0; - - LOGP(DGPRS, LOGL_DEBUG, - "Patching %ss: " - "Replacing %08x -> %08x\n", - log_text, ptmsi, new_ptmsi); - - ptmsi_be = htonl(new_ptmsi); - memcpy(ptmsi_enc, &ptmsi_be, sizeof(ptmsi_be)); - - rate_ctr_inc(&peer->ctrg->ctr[counter]); - - return 1; -} - -int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len, - struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, int *len_change, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gprs_llc_hdr_parsed *ghp = &parse_ctx->llc_hdr_parsed; - int have_patched = 0; - int fcs; - struct gbproxy_config *cfg = peer->cfg; - - if (parse_ctx->ptmsi_enc && link_info && - !parse_ctx->old_raid_is_foreign && peer->cfg->patch_ptmsi) { - uint32_t ptmsi; - if (parse_ctx->to_bss) - ptmsi = link_info->tlli.ptmsi; - else - ptmsi = link_info->sgsn_tlli.ptmsi; - - if (ptmsi != GSM_RESERVED_TMSI) { - if (gbproxy_patch_ptmsi(parse_ctx->ptmsi_enc, peer, - ptmsi, parse_ctx->to_bss, "P-TMSI")) - have_patched = 1; - } else { - /* TODO: invalidate old RAI if present (see below) */ - } - } - - if (parse_ctx->new_ptmsi_enc && link_info && cfg->patch_ptmsi) { - uint32_t ptmsi; - if (parse_ctx->to_bss) - ptmsi = link_info->tlli.ptmsi; - else - ptmsi = link_info->sgsn_tlli.ptmsi; - - OSMO_ASSERT(ptmsi); - if (gbproxy_patch_ptmsi(parse_ctx->new_ptmsi_enc, peer, - ptmsi, parse_ctx->to_bss, "new P-TMSI")) - have_patched = 1; - } - - if (parse_ctx->raid_enc) { - gbproxy_patch_raid(parse_ctx->raid_enc, peer, parse_ctx->to_bss, - parse_ctx->llc_msg_name); - have_patched = 1; - } - - if (parse_ctx->old_raid_enc && !parse_ctx->old_raid_is_foreign) { - /* TODO: Patch to invalid if P-TMSI unknown. */ - gbproxy_patch_raid(parse_ctx->old_raid_enc, peer, parse_ctx->to_bss, - parse_ctx->llc_msg_name); - have_patched = 1; - } - - if (parse_ctx->apn_ie && - cfg->core_apn && - !parse_ctx->to_bss && - gbproxy_imsi_matches(cfg, GBPROX_MATCH_PATCHING, link_info) && - cfg->core_apn) { - size_t new_len; - gbproxy_patch_apn_ie(msg, - parse_ctx->apn_ie, parse_ctx->apn_ie_len, - peer, &new_len, parse_ctx->llc_msg_name); - *len_change += (int)new_len - (int)parse_ctx->apn_ie_len; - - have_patched = 1; - } - - if (have_patched) { - llc_len += *len_change; - ghp->crc_length += *len_change; - - /* Fix FCS */ - fcs = gprs_llc_fcs(llc, ghp->crc_length); - LOGP(DLLC, LOGL_DEBUG, "Updated LLC message, CRC: %06x -> %06x\n", - ghp->fcs, fcs); - - llc[llc_len - 3] = fcs & 0xff; - llc[llc_len - 2] = (fcs >> 8) & 0xff; - llc[llc_len - 1] = (fcs >> 16) & 0xff; - } - - return have_patched; -} - -/* patch BSSGP message to use core_mcc/mnc on the SGSN side */ -void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len, - struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, int *len_change, - struct gprs_gb_parse_context *parse_ctx) -{ - const char *err_info = NULL; - int err_ctr = -1; - - if (parse_ctx->bssgp_raid_enc) - gbproxy_patch_raid(parse_ctx->bssgp_raid_enc, peer, - parse_ctx->to_bss, "BSSGP"); - - if (parse_ctx->need_decryption && - (peer->cfg->patch_ptmsi || peer->cfg->core_apn)) { - /* Patching LLC messages has been requested - * explicitly, but the message (including the - * type) is encrypted, so we possibly fail to - * patch the LLC part of the message. */ - err_ctr = GBPROX_PEER_CTR_PATCH_CRYPT_ERR; - err_info = "GMM message is encrypted"; - goto patch_error; - } - - if (!link_info && parse_ctx->tlli_enc && parse_ctx->to_bss) { - /* Happens with unknown (not cached) TLLI coming from - * the SGSN */ - /* TODO: What shall be done with the message in this case? */ - err_ctr = GBPROX_PEER_CTR_TLLI_UNKNOWN; - err_info = "TLLI sent by the SGSN is unknown"; - goto patch_error; - } - - if (!link_info) - return; - - if (parse_ctx->tlli_enc && peer->cfg->patch_ptmsi) { - uint32_t tlli = gbproxy_map_tlli(parse_ctx->tlli, - link_info, parse_ctx->to_bss); - - if (tlli) { - gbproxy_patch_tlli(parse_ctx->tlli_enc, peer, tlli, - parse_ctx->to_bss, "TLLI"); - parse_ctx->tlli = tlli; - } else { - /* Internal error */ - err_ctr = GBPROX_PEER_CTR_PATCH_ERR; - err_info = "Replacement TLLI is 0"; - goto patch_error; - } - } - - if (parse_ctx->bssgp_ptmsi_enc && peer->cfg->patch_ptmsi) { - uint32_t ptmsi; - if (parse_ctx->to_bss) - ptmsi = link_info->tlli.ptmsi; - else - ptmsi = link_info->sgsn_tlli.ptmsi; - - if (ptmsi != GSM_RESERVED_TMSI) - gbproxy_patch_ptmsi( - parse_ctx->bssgp_ptmsi_enc, peer, - ptmsi, parse_ctx->to_bss, "BSSGP P-TMSI"); - } - - if (parse_ctx->llc) { - uint8_t *llc = parse_ctx->llc; - size_t llc_len = parse_ctx->llc_len; - int llc_len_change = 0; - - gbproxy_patch_llc(msg, llc, llc_len, peer, link_info, - &llc_len_change, parse_ctx); - /* Note that the APN might have been resized here, but no - * pointer int the parse_ctx will refer to an adress after the - * APN. So it's possible to patch first and do the TLLI - * handling afterwards. */ - - if (llc_len_change) { - llc_len += llc_len_change; - - /* Fix LLC IE len */ - /* TODO: This is a kludge, but the a pointer to the - * start of the IE is not available here */ - if (llc[-2] == BSSGP_IE_LLC_PDU && llc[-1] & 0x80) { - /* most probably a one byte length */ - if (llc_len > 127) { - err_info = "Cannot increase size"; - err_ctr = GBPROX_PEER_CTR_PATCH_ERR; - goto patch_error; - } - llc[-1] = llc_len | 0x80; - } else { - llc[-2] = (llc_len >> 8) & 0x7f; - llc[-1] = llc_len & 0xff; - } - *len_change += llc_len_change; - } - /* Note that the tp struct might contain invalid pointers here - * if the LLC field has changed its size */ - parse_ctx->llc_len = llc_len; - } - return; - -patch_error: - OSMO_ASSERT(err_ctr >= 0); - rate_ctr_inc(&peer->ctrg->ctr[err_ctr]); - LOGP(DGPRS, LOGL_ERROR, - "NSEI=%u(%s) failed to patch BSSGP message as requested: %s.\n", - msgb_nsei(msg), parse_ctx->to_bss ? "SGSN" : "BSS", - err_info); -} - -void gbproxy_clear_patch_filter(struct gbproxy_match *match) -{ - if (match->enable) { - regfree(&match->re_comp); - match->enable = 0; - } - talloc_free(match->re_str); - match->re_str = NULL; -} - -int gbproxy_set_patch_filter(struct gbproxy_match *match, const char *filter, - const char **err_msg) -{ - static char err_buf[300]; - int rc; - - gbproxy_clear_patch_filter(match); - - if (!filter) - return 0; - - rc = regcomp(&match->re_comp, filter, - REG_EXTENDED | REG_NOSUB | REG_ICASE); - - if (rc == 0) { - match->enable = 1; - match->re_str = talloc_strdup(tall_bsc_ctx, filter); - return 0; - } - - if (err_msg) { - regerror(rc, &match->re_comp, - err_buf, sizeof(err_buf)); - *err_msg = err_buf; - } - - return -1; -} - -int gbproxy_check_imsi(struct gbproxy_match *match, - const uint8_t *imsi, size_t imsi_len) -{ - char mi_buf[200]; - int rc; - - if (!match->enable) - return 1; - - rc = gprs_is_mi_imsi(imsi, imsi_len); - if (rc > 0) - rc = gsm48_mi_to_string(mi_buf, sizeof(mi_buf), imsi, imsi_len); - if (rc <= 0) { - LOGP(DGPRS, LOGL_NOTICE, "Invalid IMSI %s\n", - osmo_hexdump(imsi, imsi_len)); - return -1; - } - - LOGP(DGPRS, LOGL_DEBUG, "Checking IMSI '%s' (%d)\n", mi_buf, rc); - - rc = regexec(&match->re_comp, mi_buf, 0, NULL, 0); - if (rc == REG_NOMATCH) { - LOGP(DGPRS, LOGL_INFO, - "IMSI '%s' doesn't match pattern '%s'\n", - mi_buf, match->re_str); - return 0; - } - - return 1; -} - diff --git a/src/gprs/gb_proxy_peer.c b/src/gprs/gb_proxy_peer.c deleted file mode 100644 index 890968717..000000000 --- a/src/gprs/gb_proxy_peer.c +++ /dev/null @@ -1,222 +0,0 @@ -/* Gb proxy peer handling */ - -/* (C) 2010 by Harald Welte - * (C) 2010-2013 by On-Waves - * (C) 2013 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -static const struct rate_ctr_desc peer_ctr_description[] = { - { "blocked", "BVC Block " }, - { "unblocked", "BVC Unblock " }, - { "dropped", "BVC blocked, dropped packet " }, - { "inv-nsei", "NSEI mismatch " }, - { "tx-err", "NS Transmission error " }, - { "raid-mod.bss", "RAID patched (BSS )" }, - { "raid-mod.sgsn", "RAID patched (SGSN)" }, - { "apn-mod.sgsn", "APN patched " }, - { "tlli-mod.bss", "TLLI patched (BSS )" }, - { "tlli-mod.sgsn", "TLLI patched (SGSN)" }, - { "ptmsi-mod.bss", "P-TMSI patched (BSS )" }, - { "ptmsi-mod.sgsn","P-TMSI patched (SGSN)" }, - { "mod-crypt-err", "Patch error: encrypted " }, - { "mod-err", "Patch error: other " }, - { "attach-reqs", "Attach Request count " }, - { "attach-rejs", "Attach Reject count " }, - { "attach-acks", "Attach Accept count " }, - { "attach-cpls", "Attach Completed count " }, - { "ra-upd-reqs", "RoutingArea Update Request count" }, - { "ra-upd-rejs", "RoutingArea Update Reject count " }, - { "ra-upd-acks", "RoutingArea Update Accept count " }, - { "ra-upd-cpls", "RoutingArea Update Compltd count" }, - { "gmm-status", "GMM Status count (BSS)" }, - { "gmm-status", "GMM Status count (SGSN)" }, - { "detach-reqs", "Detach Request count " }, - { "detach-acks", "Detach Accept count " }, - { "pdp-act-reqs", "PDP Activation Request count " }, - { "pdp-act-rejs", "PDP Activation Reject count " }, - { "pdp-act-acks", "PDP Activation Accept count " }, - { "pdp-deact-reqs","PDP Deactivation Request count " }, - { "pdp-deact-acks","PDP Deactivation Accept count " }, - { "tlli-unknown", "TLLI from SGSN unknown " }, - { "tlli-cache", "TLLI cache size " }, -}; - -osmo_static_assert(ARRAY_SIZE(peer_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described); - -static const struct rate_ctr_group_desc peer_ctrg_desc = { - .group_name_prefix = "gbproxy.peer", - .group_description = "GBProxy Peer Statistics", - .num_ctr = ARRAY_SIZE(peer_ctr_description), - .ctr_desc = peer_ctr_description, - .class_id = OSMO_STATS_CLASS_PEER, -}; - - -/* Find the gbprox_peer by its BVCI */ -struct gbproxy_peer *gbproxy_peer_by_bvci(struct gbproxy_config *cfg, uint16_t bvci) -{ - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (peer->bvci == bvci) - return peer; - } - return NULL; -} - -/* Find the gbprox_peer by its NSEI */ -struct gbproxy_peer *gbproxy_peer_by_nsei(struct gbproxy_config *cfg, - uint16_t nsei) -{ - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (peer->nsei == nsei) - return peer; - } - return NULL; -} - -/* look-up a peer by its Routeing Area Identification (RAI) */ -struct gbproxy_peer *gbproxy_peer_by_rai(struct gbproxy_config *cfg, - const uint8_t *ra) -{ - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (!memcmp(peer->ra, ra, 6)) - return peer; - } - return NULL; -} - -/* look-up a peer by its Location Area Identification (LAI) */ -struct gbproxy_peer *gbproxy_peer_by_lai(struct gbproxy_config *cfg, - const uint8_t *la) -{ - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (!memcmp(peer->ra, la, 5)) - return peer; - } - return NULL; -} - -/* look-up a peer by its Location Area Code (LAC) */ -struct gbproxy_peer *gbproxy_peer_by_lac(struct gbproxy_config *cfg, - const uint8_t *la) -{ - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (!memcmp(peer->ra + 3, la + 3, 2)) - return peer; - } - return NULL; -} - -struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(struct gbproxy_config *cfg, - struct tlv_parsed *tp) -{ - if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) { - uint16_t bvci; - - bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI)); - if (bvci >= 2) - return gbproxy_peer_by_bvci(cfg, bvci); - } - - if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) { - uint8_t *rai = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA); - /* Only compare LAC part, since MCC/MNC are possibly patched. - * Since the LAC of different BSS must be different when - * MCC/MNC are patched, collisions shouldn't happen. */ - return gbproxy_peer_by_lac(cfg, rai); - } - - if (TLVP_PRESENT(tp, BSSGP_IE_LOCATION_AREA)) { - uint8_t *lai = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA); - return gbproxy_peer_by_lac(cfg, lai); - } - - return NULL; -} - - -struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci) -{ - struct gbproxy_peer *peer; - - peer = talloc_zero(tall_bsc_ctx, struct gbproxy_peer); - if (!peer) - return NULL; - - peer->bvci = bvci; - peer->ctrg = rate_ctr_group_alloc(peer, &peer_ctrg_desc, bvci); - if (!peer->ctrg) { - talloc_free(peer); - return NULL; - } - peer->cfg = cfg; - - llist_add(&peer->list, &cfg->bts_peers); - - INIT_LLIST_HEAD(&peer->patch_state.logical_links); - - return peer; -} - -void gbproxy_peer_free(struct gbproxy_peer *peer) -{ - llist_del(&peer->list); - - gbproxy_delete_link_infos(peer); - - rate_ctr_group_free(peer->ctrg); - peer->ctrg = NULL; - - talloc_free(peer); -} - -int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci) -{ - int counter = 0; - struct gbproxy_peer *peer, *tmp; - - llist_for_each_entry_safe(peer, tmp, &cfg->bts_peers, list) { - if (peer->nsei != nsei) - continue; - if (bvci && peer->bvci != bvci) - continue; - - gbproxy_peer_free(peer); - counter += 1; - } - - return counter; -} - diff --git a/src/gprs/gb_proxy_tlli.c b/src/gprs/gb_proxy_tlli.c deleted file mode 100644 index 3b3b976a5..000000000 --- a/src/gprs/gb_proxy_tlli.c +++ /dev/null @@ -1,723 +0,0 @@ -/* Gb-proxy TLLI state handling */ - -/* (C) 2014 by On-Waves - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include - -#include - -#include -#include - -#include - -#include - -#include -#include - -struct gbproxy_link_info *gbproxy_link_info_by_tlli(struct gbproxy_peer *peer, - uint32_t tlli) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (!tlli) - return NULL; - - llist_for_each_entry(link_info, &state->logical_links, list) - if (link_info->tlli.current == tlli || - link_info->tlli.assigned == tlli) - return link_info; - - return NULL; -} - -struct gbproxy_link_info *gbproxy_link_info_by_ptmsi( - struct gbproxy_peer *peer, - uint32_t ptmsi) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (ptmsi == GSM_RESERVED_TMSI) - return NULL; - - llist_for_each_entry(link_info, &state->logical_links, list) - if (link_info->tlli.ptmsi == ptmsi) - return link_info; - - return NULL; -} - -struct gbproxy_link_info *gbproxy_link_info_by_any_sgsn_tlli( - struct gbproxy_peer *peer, - uint32_t tlli) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (!tlli) - return NULL; - - /* Don't care about the NSEI */ - llist_for_each_entry(link_info, &state->logical_links, list) - if (link_info->sgsn_tlli.current == tlli || - link_info->sgsn_tlli.assigned == tlli) - return link_info; - - return NULL; -} - -struct gbproxy_link_info *gbproxy_link_info_by_sgsn_tlli( - struct gbproxy_peer *peer, - uint32_t tlli, uint32_t sgsn_nsei) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (!tlli) - return NULL; - - llist_for_each_entry(link_info, &state->logical_links, list) - if ((link_info->sgsn_tlli.current == tlli || - link_info->sgsn_tlli.assigned == tlli) && - link_info->sgsn_nsei == sgsn_nsei) - return link_info; - - return NULL; -} - -struct gbproxy_link_info *gbproxy_link_info_by_imsi( - struct gbproxy_peer *peer, - const uint8_t *imsi, - size_t imsi_len) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (!gprs_is_mi_imsi(imsi, imsi_len)) - return NULL; - - llist_for_each_entry(link_info, &state->logical_links, list) { - if (link_info->imsi_len != imsi_len) - continue; - if (memcmp(link_info->imsi, imsi, imsi_len) != 0) - continue; - - return link_info; - } - - return NULL; -} - -void gbproxy_link_info_discard_messages(struct gbproxy_link_info *link_info) -{ - struct msgb *msg, *nxt; - - llist_for_each_entry_safe(msg, nxt, &link_info->stored_msgs, list) { - llist_del(&msg->list); - msgb_free(msg); - } -} - -void gbproxy_delete_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - - gbproxy_link_info_discard_messages(link_info); - - llist_del(&link_info->list); - talloc_free(link_info); - state->logical_link_count -= 1; - - peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current = - state->logical_link_count; -} - -void gbproxy_delete_link_infos(struct gbproxy_peer *peer) -{ - struct gbproxy_link_info *link_info, *nxt; - struct gbproxy_patch_state *state = &peer->patch_state; - - llist_for_each_entry_safe(link_info, nxt, &state->logical_links, list) - gbproxy_delete_link_info(peer, link_info); - - OSMO_ASSERT(state->logical_link_count == 0); - OSMO_ASSERT(llist_empty(&state->logical_links)); -} - -void gbproxy_attach_link_info(struct gbproxy_peer *peer, time_t now, - struct gbproxy_link_info *link_info) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - - link_info->timestamp = now; - llist_add(&link_info->list, &state->logical_links); - state->logical_link_count += 1; - - peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current = - state->logical_link_count; -} - -int gbproxy_remove_stale_link_infos(struct gbproxy_peer *peer, time_t now) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - int exceeded_max_len = 0; - int deleted_count = 0; - int check_for_age; - - if (peer->cfg->tlli_max_len > 0) - exceeded_max_len = - state->logical_link_count - peer->cfg->tlli_max_len; - - check_for_age = peer->cfg->tlli_max_age > 0; - - for (; exceeded_max_len > 0; exceeded_max_len--) { - struct gbproxy_link_info *link_info; - OSMO_ASSERT(!llist_empty(&state->logical_links)); - link_info = llist_entry(state->logical_links.prev, - struct gbproxy_link_info, - list); - LOGP(DGPRS, LOGL_INFO, - "Removing TLLI %08x from list " - "(stale, length %d, max_len exceeded)\n", - link_info->tlli.current, state->logical_link_count); - - gbproxy_delete_link_info(peer, link_info); - deleted_count += 1; - } - - while (check_for_age && !llist_empty(&state->logical_links)) { - time_t age; - struct gbproxy_link_info *link_info; - link_info = llist_entry(state->logical_links.prev, - struct gbproxy_link_info, - list); - age = now - link_info->timestamp; - /* age < 0 only happens after system time jumps, discard entry */ - if (age <= peer->cfg->tlli_max_age && age >= 0) { - check_for_age = 0; - continue; - } - - LOGP(DGPRS, LOGL_INFO, - "Removing TLLI %08x from list " - "(stale, age %d, max_age exceeded)\n", - link_info->tlli.current, (int)age); - - gbproxy_delete_link_info(peer, link_info); - deleted_count += 1; - } - - return deleted_count; -} - -struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_peer *peer) -{ - struct gbproxy_link_info *link_info; - - link_info = talloc_zero(peer, struct gbproxy_link_info); - link_info->tlli.ptmsi = GSM_RESERVED_TMSI; - link_info->sgsn_tlli.ptmsi = GSM_RESERVED_TMSI; - - link_info->vu_gen_tx_bss = GBPROXY_INIT_VU_GEN_TX; - - INIT_LLIST_HEAD(&link_info->stored_msgs); - - return link_info; -} - -void gbproxy_detach_link_info( - struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - - llist_del(&link_info->list); - OSMO_ASSERT(state->logical_link_count > 0); - state->logical_link_count -= 1; - - peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current = - state->logical_link_count; -} - -void gbproxy_update_link_info(struct gbproxy_link_info *link_info, - const uint8_t *imsi, size_t imsi_len) -{ - if (!gprs_is_mi_imsi(imsi, imsi_len)) - return; - - link_info->imsi_len = imsi_len; - link_info->imsi = - talloc_realloc_size(link_info, link_info->imsi, imsi_len); - OSMO_ASSERT(link_info->imsi != NULL); - memcpy(link_info->imsi, imsi, imsi_len); -} - -void gbproxy_reassign_tlli(struct gbproxy_tlli_state *tlli_state, - struct gbproxy_peer *peer, uint32_t new_tlli) -{ - if (new_tlli == tlli_state->current) - return; - - LOGP(DGPRS, LOGL_INFO, - "The TLLI has been reassigned from %08x to %08x\n", - tlli_state->current, new_tlli); - - /* Remember assigned TLLI */ - tlli_state->assigned = new_tlli; - tlli_state->bss_validated = 0; - tlli_state->net_validated = 0; -} - -uint32_t gbproxy_map_tlli(uint32_t other_tlli, - struct gbproxy_link_info *link_info, int to_bss) -{ - uint32_t tlli = 0; - struct gbproxy_tlli_state *src, *dst; - if (to_bss) { - src = &link_info->sgsn_tlli; - dst = &link_info->tlli; - } else { - src = &link_info->tlli; - dst = &link_info->sgsn_tlli; - } - if (src->current == other_tlli) - tlli = dst->current; - else if (src->assigned == other_tlli) - tlli = dst->assigned; - - return tlli; -} - -static void gbproxy_validate_tlli(struct gbproxy_tlli_state *tlli_state, - uint32_t tlli, int to_bss) -{ - LOGP(DGPRS, LOGL_DEBUG, - "%s({current = %08x, assigned = %08x, net_vld = %d, bss_vld = %d}, %08x)\n", - __func__, tlli_state->current, tlli_state->assigned, - tlli_state->net_validated, tlli_state->bss_validated, tlli); - - if (!tlli_state->assigned || tlli_state->assigned != tlli) - return; - - /* TODO: Is this ok? Check spec */ - if (gprs_tlli_type(tlli) != TLLI_LOCAL) - return; - - /* See GSM 04.08, 4.7.1.5 */ - if (to_bss) - tlli_state->net_validated = 1; - else - tlli_state->bss_validated = 1; - - if (!tlli_state->bss_validated || !tlli_state->net_validated) - return; - - LOGP(DGPRS, LOGL_INFO, - "The TLLI %08x has been validated (was %08x)\n", - tlli_state->assigned, tlli_state->current); - - tlli_state->current = tlli; - tlli_state->assigned = 0; -} - -static void gbproxy_touch_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, - time_t now) -{ - gbproxy_detach_link_info(peer, link_info); - gbproxy_attach_link_info(peer, now, link_info); -} - -static int gbproxy_unregister_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info) -{ - if (!link_info) - return 1; - - if (link_info->tlli.ptmsi == GSM_RESERVED_TMSI && !link_info->imsi_len) { - LOGP(DGPRS, LOGL_INFO, - "Removing TLLI %08x from list (P-TMSI or IMSI are not set)\n", - link_info->tlli.current); - gbproxy_delete_link_info(peer, link_info); - return 1; - } - - link_info->tlli.current = 0; - link_info->tlli.assigned = 0; - link_info->sgsn_tlli.current = 0; - link_info->sgsn_tlli.assigned = 0; - - link_info->is_deregistered = 1; - - gbproxy_reset_link(link_info); - - return 0; -} - -int gbproxy_imsi_matches(struct gbproxy_config *cfg, - enum gbproxy_match_id match_id, - struct gbproxy_link_info *link_info) -{ - struct gbproxy_match *match; - OSMO_ASSERT(match_id >= 0 && match_id < ARRAY_SIZE(cfg->matches)); - - match = &cfg->matches[match_id]; - if (!match->enable) - return 1; - - return link_info != NULL && link_info->is_matching[match_id]; -} - -void gbproxy_assign_imsi(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, - struct gprs_gb_parse_context *parse_ctx) -{ - int imsi_matches; - struct gbproxy_link_info *other_link_info; - enum gbproxy_match_id match_id; - - /* Make sure that there is a second entry with the same IMSI */ - other_link_info = gbproxy_link_info_by_imsi( - peer, parse_ctx->imsi, parse_ctx->imsi_len); - - if (other_link_info && other_link_info != link_info) { - char mi_buf[200]; - mi_buf[0] = '\0'; - gsm48_mi_to_string(mi_buf, sizeof(mi_buf), - parse_ctx->imsi, parse_ctx->imsi_len); - LOGP(DGPRS, LOGL_INFO, - "Removing TLLI %08x from list (IMSI %s re-used)\n", - other_link_info->tlli.current, mi_buf); - gbproxy_delete_link_info(peer, other_link_info); - } - - /* Update the IMSI field */ - gbproxy_update_link_info(link_info, - parse_ctx->imsi, parse_ctx->imsi_len); - - /* Check, whether the IMSI matches */ - OSMO_ASSERT(ARRAY_SIZE(link_info->is_matching) == - ARRAY_SIZE(peer->cfg->matches)); - for (match_id = 0; match_id < ARRAY_SIZE(link_info->is_matching); - ++match_id) { - imsi_matches = gbproxy_check_imsi( - &peer->cfg->matches[match_id], - parse_ctx->imsi, parse_ctx->imsi_len); - if (imsi_matches >= 0) - link_info->is_matching[match_id] = imsi_matches; - } -} - -static int gbproxy_tlli_match(const struct gbproxy_tlli_state *a, - const struct gbproxy_tlli_state *b) -{ - if (a->current && a->current == b->current) - return 1; - - if (a->assigned && a->assigned == b->assigned) - return 1; - - if (a->ptmsi != GSM_RESERVED_TMSI && a->ptmsi == b->ptmsi) - return 1; - - return 0; -} - -static void gbproxy_remove_matching_link_infos( - struct gbproxy_peer *peer, struct gbproxy_link_info *link_info) -{ - struct gbproxy_link_info *info, *nxt; - struct gbproxy_patch_state *state = &peer->patch_state; - - /* Make sure that there is no second entry with the same P-TMSI or TLLI */ - llist_for_each_entry_safe(info, nxt, &state->logical_links, list) { - if (info == link_info) - continue; - - if (!gbproxy_tlli_match(&link_info->tlli, &info->tlli) && - (link_info->sgsn_nsei != info->sgsn_nsei || - !gbproxy_tlli_match(&link_info->sgsn_tlli, &info->sgsn_tlli))) - continue; - - LOGP(DGPRS, LOGL_INFO, - "Removing TLLI %08x from list (P-TMSI/TLLI re-used)\n", - info->tlli.current); - gbproxy_delete_link_info(peer, info); - } -} - -static struct gbproxy_link_info *gbproxy_get_link_info_ul( - struct gbproxy_peer *peer, - int *tlli_is_valid, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gbproxy_link_info *link_info = NULL; - - if (parse_ctx->tlli_enc) { - link_info = gbproxy_link_info_by_tlli(peer, parse_ctx->tlli); - - if (link_info) { - *tlli_is_valid = 1; - return link_info; - } - } - - *tlli_is_valid = 0; - - if (!link_info && parse_ctx->imsi) { - link_info = gbproxy_link_info_by_imsi( - peer, parse_ctx->imsi, parse_ctx->imsi_len); - } - - if (!link_info && parse_ctx->ptmsi_enc && !parse_ctx->old_raid_is_foreign) { - uint32_t bss_ptmsi; - gprs_parse_tmsi(parse_ctx->ptmsi_enc, &bss_ptmsi); - link_info = gbproxy_link_info_by_ptmsi(peer, bss_ptmsi); - } - - if (!link_info) - return NULL; - - link_info->is_deregistered = 0; - - return link_info; -} - -struct gbproxy_link_info *gbproxy_update_link_state_ul( - struct gbproxy_peer *peer, - time_t now, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gbproxy_link_info *link_info; - int tlli_is_valid; - - link_info = gbproxy_get_link_info_ul(peer, &tlli_is_valid, parse_ctx); - - if (parse_ctx->tlli_enc && parse_ctx->llc) { - uint32_t sgsn_tlli; - - if (!link_info) { - LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", - parse_ctx->tlli); - link_info = gbproxy_link_info_alloc(peer); - gbproxy_attach_link_info(peer, now, link_info); - - /* Setup TLLIs */ - sgsn_tlli = gbproxy_make_sgsn_tlli(peer, link_info, - parse_ctx->tlli); - link_info->sgsn_tlli.current = sgsn_tlli; - link_info->tlli.current = parse_ctx->tlli; - } else if (!tlli_is_valid) { - /* New TLLI (info found by IMSI or P-TMSI) */ - link_info->tlli.current = parse_ctx->tlli; - link_info->tlli.assigned = 0; - link_info->sgsn_tlli.current = - gbproxy_make_sgsn_tlli(peer, link_info, - parse_ctx->tlli); - link_info->sgsn_tlli.assigned = 0; - gbproxy_touch_link_info(peer, link_info, now); - } else { - sgsn_tlli = gbproxy_map_tlli(parse_ctx->tlli, link_info, 0); - if (!sgsn_tlli) - sgsn_tlli = gbproxy_make_sgsn_tlli(peer, link_info, - parse_ctx->tlli); - - gbproxy_validate_tlli(&link_info->tlli, - parse_ctx->tlli, 0); - gbproxy_validate_tlli(&link_info->sgsn_tlli, - sgsn_tlli, 0); - gbproxy_touch_link_info(peer, link_info, now); - } - } else if (link_info) { - gbproxy_touch_link_info(peer, link_info, now); - } - - if (parse_ctx->imsi && link_info && link_info->imsi_len == 0) - gbproxy_assign_imsi(peer, link_info, parse_ctx); - - return link_info; -} - -static struct gbproxy_link_info *gbproxy_get_link_info_dl( - struct gbproxy_peer *peer, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gbproxy_link_info *link_info = NULL; - - /* Which key to use depends on its availability only, if that fails, do - * not retry it with another key (e.g. IMSI). */ - if (parse_ctx->tlli_enc) - link_info = gbproxy_link_info_by_sgsn_tlli(peer, parse_ctx->tlli, - parse_ctx->peer_nsei); - - /* TODO: Get link_info by (SGSN) P-TMSI if that is available (see - * GSM 08.18, 7.2) instead of using the IMSI as key. */ - else if (parse_ctx->imsi) - link_info = gbproxy_link_info_by_imsi( - peer, parse_ctx->imsi, parse_ctx->imsi_len); - - if (link_info) - link_info->is_deregistered = 0; - - return link_info; -} - -struct gbproxy_link_info *gbproxy_update_link_state_dl( - struct gbproxy_peer *peer, - time_t now, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gbproxy_link_info *link_info = NULL; - - link_info = gbproxy_get_link_info_dl(peer, parse_ctx); - - if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && link_info) { - /* A new P-TMSI has been signalled in the message, - * register new TLLI */ - uint32_t new_sgsn_ptmsi; - uint32_t new_bss_ptmsi = GSM_RESERVED_TMSI; - gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_sgsn_ptmsi); - - if (link_info->sgsn_tlli.ptmsi == new_sgsn_ptmsi) - new_bss_ptmsi = link_info->tlli.ptmsi; - - if (new_bss_ptmsi == GSM_RESERVED_TMSI) - new_bss_ptmsi = gbproxy_make_bss_ptmsi(peer, new_sgsn_ptmsi); - - LOGP(DGPRS, LOGL_INFO, - "Got new PTMSI %08x from SGSN, using %08x for BSS\n", - new_sgsn_ptmsi, new_bss_ptmsi); - /* Setup PTMSIs */ - link_info->sgsn_tlli.ptmsi = new_sgsn_ptmsi; - link_info->tlli.ptmsi = new_bss_ptmsi; - } else if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && !link_info && - !peer->cfg->patch_ptmsi) { - /* A new P-TMSI has been signalled in the message with an unknown - * TLLI, create a new link_info */ - /* TODO: Add a test case for this branch */ - uint32_t new_ptmsi; - gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi); - - LOGP(DGPRS, LOGL_INFO, - "Adding TLLI %08x to list (SGSN, new P-TMSI is %08x)\n", - parse_ctx->tlli, new_ptmsi); - - link_info = gbproxy_link_info_alloc(peer); - link_info->sgsn_tlli.current = parse_ctx->tlli; - link_info->tlli.current = parse_ctx->tlli; - link_info->sgsn_tlli.ptmsi = new_ptmsi; - link_info->tlli.ptmsi = new_ptmsi; - gbproxy_attach_link_info(peer, now, link_info); - } else if (parse_ctx->tlli_enc && parse_ctx->llc && !link_info && - !peer->cfg->patch_ptmsi) { - /* Unknown SGSN TLLI, create a new link_info */ - uint32_t new_ptmsi; - link_info = gbproxy_link_info_alloc(peer); - LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list (SGSN)\n", - parse_ctx->tlli); - - gbproxy_attach_link_info(peer, now, link_info); - - /* Setup TLLIs */ - link_info->sgsn_tlli.current = parse_ctx->tlli; - link_info->tlli.current = parse_ctx->tlli; - - if (!parse_ctx->new_ptmsi_enc) - return link_info; - /* A new P-TMSI has been signalled in the message */ - - gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi); - LOGP(DGPRS, LOGL_INFO, - "Assigning new P-TMSI %08x\n", new_ptmsi); - /* Setup P-TMSIs */ - link_info->sgsn_tlli.ptmsi = new_ptmsi; - link_info->tlli.ptmsi = new_ptmsi; - } else if (parse_ctx->tlli_enc && parse_ctx->llc && link_info) { - uint32_t bss_tlli = gbproxy_map_tlli(parse_ctx->tlli, - link_info, 1); - gbproxy_validate_tlli(&link_info->sgsn_tlli, parse_ctx->tlli, 1); - gbproxy_validate_tlli(&link_info->tlli, bss_tlli, 1); - gbproxy_touch_link_info(peer, link_info, now); - } else if (link_info) { - gbproxy_touch_link_info(peer, link_info, now); - } - - if (parse_ctx->imsi && link_info && link_info->imsi_len == 0) - gbproxy_assign_imsi(peer, link_info, parse_ctx); - - return link_info; -} - -int gbproxy_update_link_state_after( - struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, - time_t now, - struct gprs_gb_parse_context *parse_ctx) -{ - int rc = 0; - if (parse_ctx->invalidate_tlli && link_info) { - int keep_info = - peer->cfg->keep_link_infos == GBPROX_KEEP_ALWAYS || - (peer->cfg->keep_link_infos == GBPROX_KEEP_REATTACH && - parse_ctx->await_reattach) || - (peer->cfg->keep_link_infos == GBPROX_KEEP_IDENTIFIED && - link_info->imsi_len > 0); - if (keep_info) { - LOGP(DGPRS, LOGL_INFO, "Unregistering TLLI %08x\n", - link_info->tlli.current); - rc = gbproxy_unregister_link_info(peer, link_info); - } else { - LOGP(DGPRS, LOGL_INFO, "Removing TLLI %08x from list\n", - link_info->tlli.current); - gbproxy_delete_link_info(peer, link_info); - rc = 1; - } - } else if (parse_ctx->to_bss && parse_ctx->tlli_enc && - parse_ctx->new_ptmsi_enc && link_info) { - /* A new PTMSI has been signaled in the message, - * register new TLLI */ - uint32_t new_sgsn_ptmsi = link_info->sgsn_tlli.ptmsi; - uint32_t new_bss_ptmsi = link_info->tlli.ptmsi; - uint32_t new_sgsn_tlli; - uint32_t new_bss_tlli = 0; - - new_sgsn_tlli = gprs_tmsi2tlli(new_sgsn_ptmsi, TLLI_LOCAL); - if (new_bss_ptmsi != GSM_RESERVED_TMSI) - new_bss_tlli = gprs_tmsi2tlli(new_bss_ptmsi, TLLI_LOCAL); - LOGP(DGPRS, LOGL_INFO, - "Assigning new TLLI %08x to SGSN, %08x to BSS\n", - new_sgsn_tlli, new_bss_tlli); - - gbproxy_reassign_tlli(&link_info->sgsn_tlli, - peer, new_sgsn_tlli); - gbproxy_reassign_tlli(&link_info->tlli, - peer, new_bss_tlli); - gbproxy_remove_matching_link_infos(peer, link_info); - } - - gbproxy_remove_stale_link_infos(peer, now); - - return rc; -} - - diff --git a/src/gprs/gb_proxy_vty.c b/src/gprs/gb_proxy_vty.c deleted file mode 100644 index 86d65a8e3..000000000 --- a/src/gprs/gb_proxy_vty.c +++ /dev/null @@ -1,853 +0,0 @@ -/* - * (C) 2010 by Harald Welte - * (C) 2010 by On-Waves - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -static struct gbproxy_config *g_cfg = NULL; - -/* - * vty code for mgcp below - */ -static struct cmd_node gbproxy_node = { - GBPROXY_NODE, - "%s(config-gbproxy)# ", - 1, -}; - -static const struct value_string keep_modes[] = { - {GBPROX_KEEP_NEVER, "never"}, - {GBPROX_KEEP_REATTACH, "re-attach"}, - {GBPROX_KEEP_IDENTIFIED, "identified"}, - {GBPROX_KEEP_ALWAYS, "always"}, - {0, NULL} -}; - -static const struct value_string match_ids[] = { - {GBPROX_MATCH_PATCHING, "patching"}, - {GBPROX_MATCH_ROUTING, "routing"}, - {0, NULL} -}; - -static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer) -{ - struct gprs_ra_id raid; - gsm48_parse_ra(&raid, peer->ra); - - vty_out(vty, "NSEI %5u, PTP-BVCI %5u, " - "RAI %u-%u-%u-%u", - peer->nsei, peer->bvci, - raid.mcc, raid.mnc, raid.lac, raid.rac); - if (peer->blocked) - vty_out(vty, " [BVC-BLOCKED]"); - - vty_out(vty, "%s", VTY_NEWLINE); -} - -static int config_write_gbproxy(struct vty *vty) -{ - enum gbproxy_match_id match_id; - - vty_out(vty, "gbproxy%s", VTY_NEWLINE); - - vty_out(vty, " sgsn nsei %u%s", g_cfg->nsip_sgsn_nsei, - VTY_NEWLINE); - - if (g_cfg->core_mcc > 0) - vty_out(vty, " core-mobile-country-code %d%s", - g_cfg->core_mcc, VTY_NEWLINE); - if (g_cfg->core_mnc > 0) - vty_out(vty, " core-mobile-network-code %d%s", - g_cfg->core_mnc, VTY_NEWLINE); - - for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) { - struct gbproxy_match *match = &g_cfg->matches[match_id]; - if (match->re_str) - vty_out(vty, " match-imsi %s %s%s", - get_value_string(match_ids, match_id), - match->re_str, VTY_NEWLINE); - } - - if (g_cfg->core_apn != NULL) { - if (g_cfg->core_apn_size > 0) { - char str[500] = {0}; - vty_out(vty, " core-access-point-name %s%s", - osmo_apn_to_str(str, g_cfg->core_apn, - g_cfg->core_apn_size), - VTY_NEWLINE); - } else { - vty_out(vty, " core-access-point-name none%s", - VTY_NEWLINE); - } - } - - if (g_cfg->route_to_sgsn2) - vty_out(vty, " secondary-sgsn nsei %u%s", g_cfg->nsip_sgsn2_nsei, - VTY_NEWLINE); - - if (g_cfg->tlli_max_age > 0) - vty_out(vty, " link-list max-age %d%s", - g_cfg->tlli_max_age, VTY_NEWLINE); - if (g_cfg->tlli_max_len > 0) - vty_out(vty, " link-list max-length %d%s", - g_cfg->tlli_max_len, VTY_NEWLINE); - vty_out(vty, " link-list keep-mode %s%s", - get_value_string(keep_modes, g_cfg->keep_link_infos), - VTY_NEWLINE); - - - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy, - cfg_gbproxy_cmd, - "gbproxy", - "Configure the Gb proxy") -{ - vty->node = GBPROXY_NODE; - return CMD_SUCCESS; -} - -DEFUN(cfg_nsip_sgsn_nsei, - cfg_nsip_sgsn_nsei_cmd, - "sgsn nsei <0-65534>", - "SGSN information\n" - "NSEI to be used in the connection with the SGSN\n" - "The NSEI\n") -{ - unsigned int nsei = atoi(argv[0]); - - if (g_cfg->route_to_sgsn2 && g_cfg->nsip_sgsn2_nsei == nsei) { - vty_out(vty, "SGSN NSEI %d conflicts with secondary SGSN NSEI%s", - nsei, VTY_NEWLINE); - return CMD_WARNING; - } - - g_cfg->nsip_sgsn_nsei = nsei; - return CMD_SUCCESS; -} - -#define GBPROXY_CORE_MNC_STR "Use this network code for the core network\n" - -DEFUN(cfg_gbproxy_core_mnc, - cfg_gbproxy_core_mnc_cmd, - "core-mobile-network-code <1-999>", - GBPROXY_CORE_MNC_STR "NCC value\n") -{ - g_cfg->core_mnc = atoi(argv[0]); - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_no_core_mnc, - cfg_gbproxy_no_core_mnc_cmd, - "no core-mobile-network-code", - NO_STR GBPROXY_CORE_MNC_STR) -{ - g_cfg->core_mnc = 0; - return CMD_SUCCESS; -} - -#define GBPROXY_CORE_MCC_STR "Use this country code for the core network\n" - -DEFUN(cfg_gbproxy_core_mcc, - cfg_gbproxy_core_mcc_cmd, - "core-mobile-country-code <1-999>", - GBPROXY_CORE_MCC_STR "MCC value\n") -{ - g_cfg->core_mcc = atoi(argv[0]); - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_no_core_mcc, - cfg_gbproxy_no_core_mcc_cmd, - "no core-mobile-country-code", - NO_STR GBPROXY_CORE_MCC_STR) -{ - g_cfg->core_mcc = 0; - return CMD_SUCCESS; -} - -#define GBPROXY_MATCH_IMSI_STR "Restrict actions to certain IMSIs\n" - -DEFUN(cfg_gbproxy_match_imsi, - cfg_gbproxy_match_imsi_cmd, - "match-imsi (patching|routing) .REGEXP", - GBPROXY_MATCH_IMSI_STR - "Patch MS related information elements on match only\n" - "Route to the secondary SGSN on match only\n" - "Regular expression for the IMSI match\n") -{ - const char *filter = argv[1]; - const char *err_msg = NULL; - struct gbproxy_match *match; - enum gbproxy_match_id match_id = get_string_value(match_ids, argv[0]); - - OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING && - match_id < GBPROX_MATCH_LAST); - match = &g_cfg->matches[match_id]; - - if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) { - vty_out(vty, "Match expression invalid: %s%s", - err_msg, VTY_NEWLINE); - return CMD_WARNING; - } - - g_cfg->acquire_imsi = 1; - - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_no_match_imsi, - cfg_gbproxy_no_match_imsi_cmd, - "no match-imsi", - NO_STR GBPROXY_MATCH_IMSI_STR) -{ - enum gbproxy_match_id match_id; - - for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) - gbproxy_clear_patch_filter(&g_cfg->matches[match_id]); - - g_cfg->acquire_imsi = 0; - - return CMD_SUCCESS; -} - -#define GBPROXY_CORE_APN_STR "Use this access point name (APN) for the backbone\n" -#define GBPROXY_CORE_APN_ARG_STR "Replace APN by this string\n" "Remove APN\n" - -static int set_core_apn(struct vty *vty, const char *apn) -{ - int apn_len; - - if (!apn) { - talloc_free(g_cfg->core_apn); - g_cfg->core_apn = NULL; - g_cfg->core_apn_size = 0; - return CMD_SUCCESS; - } - - apn_len = strlen(apn); - - if (apn_len >= 100) { - vty_out(vty, "APN string too long (max 99 chars)%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - if (apn_len == 0) { - talloc_free(g_cfg->core_apn); - /* TODO: replace NULL */ - g_cfg->core_apn = talloc_zero_size(NULL, 2); - g_cfg->core_apn_size = 0; - } else { - /* TODO: replace NULL */ - g_cfg->core_apn = - talloc_realloc_size(NULL, g_cfg->core_apn, apn_len + 1); - g_cfg->core_apn_size = - gprs_str_to_apn(g_cfg->core_apn, apn_len + 1, apn); - } - - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_core_apn, - cfg_gbproxy_core_apn_cmd, - "core-access-point-name (APN|none)", - GBPROXY_CORE_APN_STR GBPROXY_CORE_APN_ARG_STR) -{ - if (strcmp(argv[0], "none") == 0) - return set_core_apn(vty, ""); - else - return set_core_apn(vty, argv[0]); -} - -DEFUN(cfg_gbproxy_no_core_apn, - cfg_gbproxy_no_core_apn_cmd, - "no core-access-point-name", - NO_STR GBPROXY_CORE_APN_STR) -{ - return set_core_apn(vty, NULL); -} - -/* TODO: Remove the patch-ptmsi command, since P-TMSI patching is enabled - * automatically when needed. This command is only left for manual testing - * (e.g. doing P-TMSI patching without using a secondary SGSN) - */ -#define GBPROXY_PATCH_PTMSI_STR "Patch P-TMSI/TLLI\n" - -DEFUN(cfg_gbproxy_patch_ptmsi, - cfg_gbproxy_patch_ptmsi_cmd, - "patch-ptmsi", - GBPROXY_PATCH_PTMSI_STR) -{ - g_cfg->patch_ptmsi = 1; - - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_no_patch_ptmsi, - cfg_gbproxy_no_patch_ptmsi_cmd, - "no patch-ptmsi", - NO_STR GBPROXY_PATCH_PTMSI_STR) -{ - g_cfg->patch_ptmsi = 0; - - return CMD_SUCCESS; -} - -/* TODO: Remove the acquire-imsi command, since that feature is enabled - * automatically when IMSI matching is enabled. This command is only left for - * manual testing (e.g. doing IMSI acquisition without IMSI based patching) - */ -#define GBPROXY_ACQUIRE_IMSI_STR "Acquire the IMSI before establishing a LLC connection (Experimental)\n" - -DEFUN(cfg_gbproxy_acquire_imsi, - cfg_gbproxy_acquire_imsi_cmd, - "acquire-imsi", - GBPROXY_ACQUIRE_IMSI_STR) -{ - g_cfg->acquire_imsi = 1; - - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_no_acquire_imsi, - cfg_gbproxy_no_acquire_imsi_cmd, - "no acquire-imsi", - NO_STR GBPROXY_ACQUIRE_IMSI_STR) -{ - g_cfg->acquire_imsi = 0; - - return CMD_SUCCESS; -} - -#define GBPROXY_SECOND_SGSN_STR "Route matching LLC connections to a second SGSN (Experimental)\n" - -DEFUN(cfg_gbproxy_secondary_sgsn, - cfg_gbproxy_secondary_sgsn_cmd, - "secondary-sgsn nsei <0-65534>", - GBPROXY_SECOND_SGSN_STR - "NSEI to be used in the connection with the SGSN\n" - "The NSEI\n") -{ - unsigned int nsei = atoi(argv[0]); - - if (g_cfg->nsip_sgsn_nsei == nsei) { - vty_out(vty, "Secondary SGSN NSEI %d conflicts with primary SGSN NSEI%s", - nsei, VTY_NEWLINE); - return CMD_WARNING; - } - - g_cfg->route_to_sgsn2 = 1; - g_cfg->nsip_sgsn2_nsei = nsei; - - g_cfg->patch_ptmsi = 1; - - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_no_secondary_sgsn, - cfg_gbproxy_no_secondary_sgsn_cmd, - "no secondary-sgsn", - NO_STR GBPROXY_SECOND_SGSN_STR) -{ - g_cfg->route_to_sgsn2 = 0; - g_cfg->nsip_sgsn2_nsei = 0xFFFF; - - g_cfg->patch_ptmsi = 0; - - return CMD_SUCCESS; -} - -#define GBPROXY_LINK_LIST_STR "Set TLLI list parameters\n" -#define GBPROXY_MAX_AGE_STR "Limit maximum age\n" - -DEFUN(cfg_gbproxy_link_list_max_age, - cfg_gbproxy_link_list_max_age_cmd, - "link-list max-age <1-999999>", - GBPROXY_LINK_LIST_STR GBPROXY_MAX_AGE_STR - "Maximum age in seconds\n") -{ - g_cfg->tlli_max_age = atoi(argv[0]); - - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_link_list_no_max_age, - cfg_gbproxy_link_list_no_max_age_cmd, - "no link-list max-age", - NO_STR GBPROXY_LINK_LIST_STR GBPROXY_MAX_AGE_STR) -{ - g_cfg->tlli_max_age = 0; - - return CMD_SUCCESS; -} - -#define GBPROXY_MAX_LEN_STR "Limit list length\n" - -DEFUN(cfg_gbproxy_link_list_max_len, - cfg_gbproxy_link_list_max_len_cmd, - "link-list max-length <1-99999>", - GBPROXY_LINK_LIST_STR GBPROXY_MAX_LEN_STR - "Maximum number of logical links in the list\n") -{ - g_cfg->tlli_max_len = atoi(argv[0]); - - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_link_list_no_max_len, - cfg_gbproxy_link_list_no_max_len_cmd, - "no link-list max-length", - NO_STR GBPROXY_LINK_LIST_STR GBPROXY_MAX_LEN_STR) -{ - g_cfg->tlli_max_len = 0; - - return CMD_SUCCESS; -} - -DEFUN(cfg_gbproxy_link_list_keep_mode, - cfg_gbproxy_link_list_keep_mode_cmd, - "link-list keep-mode (never|re-attach|identified|always)", - GBPROXY_LINK_LIST_STR "How to keep entries for detached logical links\n" - "Discard entry immediately after detachment\n" - "Keep entry if a re-attachment has be requested\n" - "Keep entry if it associated with an IMSI\n" - "Don't discard entries after detachment\n") -{ - int val = get_string_value(keep_modes, argv[0]); - OSMO_ASSERT(val >= GBPROX_KEEP_NEVER && val <= GBPROX_KEEP_ALWAYS); - g_cfg->keep_link_infos = val; - - return CMD_SUCCESS; -} - - -DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]", - SHOW_STR "Display information about the Gb proxy\n" "Show statistics\n") -{ - struct gbproxy_peer *peer; - int show_stats = argc >= 1; - - if (show_stats) - vty_out_rate_ctr_group(vty, "", g_cfg->ctrg); - - llist_for_each_entry(peer, &g_cfg->bts_peers, list) { - gbprox_vty_print_peer(vty, peer); - - if (show_stats) - vty_out_rate_ctr_group(vty, " ", peer->ctrg); - } - return CMD_SUCCESS; -} - -DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links", - SHOW_STR "Display information about the Gb proxy\n" "Show logical links\n") -{ - struct gbproxy_peer *peer; - char mi_buf[200]; - time_t now; - struct timespec ts = {0,}; - - clock_gettime(CLOCK_MONOTONIC, &ts); - now = ts.tv_sec; - - llist_for_each_entry(peer, &g_cfg->bts_peers, list) { - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - gbprox_vty_print_peer(vty, peer); - - llist_for_each_entry(link_info, &state->logical_links, list) { - time_t age = now - link_info->timestamp; - int stored_msgs = 0; - struct llist_head *iter; - llist_for_each(iter, &link_info->stored_msgs) - stored_msgs++; - - if (link_info->imsi > 0) { - snprintf(mi_buf, sizeof(mi_buf), "(invalid)"); - gsm48_mi_to_string(mi_buf, sizeof(mi_buf), - link_info->imsi, - link_info->imsi_len); - } else { - snprintf(mi_buf, sizeof(mi_buf), "(none)"); - } - vty_out(vty, " TLLI %08x, IMSI %s, AGE %d", - link_info->tlli.current, mi_buf, (int)age); - - if (stored_msgs) - vty_out(vty, ", STORED %d", stored_msgs); - - if (g_cfg->route_to_sgsn2) - vty_out(vty, ", SGSN NSEI %d", - link_info->sgsn_nsei); - - if (link_info->is_deregistered) - vty_out(vty, ", DE-REGISTERED"); - - vty_out(vty, "%s", VTY_NEWLINE); - } - } - return CMD_SUCCESS; -} - -DEFUN(delete_gb_bvci, delete_gb_bvci_cmd, - "delete-gbproxy-peer <0-65534> bvci <2-65534>", - "Delete a GBProxy peer by NSEI and optionally BVCI\n" - "NSEI number\n" - "Only delete peer with a matching BVCI\n" - "BVCI number\n") -{ - const uint16_t nsei = atoi(argv[0]); - const uint16_t bvci = atoi(argv[1]); - int counter; - - counter = gbproxy_cleanup_peers(g_cfg, nsei, bvci); - - if (counter == 0) { - vty_out(vty, "BVC not found%s", VTY_NEWLINE); - return CMD_WARNING; - } - - return CMD_SUCCESS; -} - -DEFUN(delete_gb_nsei, delete_gb_nsei_cmd, - "delete-gbproxy-peer <0-65534> (only-bvc|only-nsvc|all) [dry-run]", - "Delete a GBProxy peer by NSEI and optionally BVCI\n" - "NSEI number\n" - "Only delete BSSGP connections (BVC)\n" - "Only delete dynamic NS connections (NS-VC)\n" - "Delete BVC and dynamic NS connections\n" - "Show what would be deleted instead of actually deleting\n" - ) -{ - const uint16_t nsei = atoi(argv[0]); - const char *mode = argv[1]; - int dry_run = argc > 2; - int delete_bvc = 0; - int delete_nsvc = 0; - int counter; - - if (strcmp(mode, "only-bvc") == 0) - delete_bvc = 1; - else if (strcmp(mode, "only-nsvc") == 0) - delete_nsvc = 1; - else - delete_bvc = delete_nsvc = 1; - - if (delete_bvc) { - if (!dry_run) - counter = gbproxy_cleanup_peers(g_cfg, nsei, 0); - else { - struct gbproxy_peer *peer; - counter = 0; - llist_for_each_entry(peer, &g_cfg->bts_peers, list) { - if (peer->nsei != nsei) - continue; - - vty_out(vty, "BVC: "); - gbprox_vty_print_peer(vty, peer); - counter += 1; - } - } - vty_out(vty, "%sDeleted %d BVC%s", - dry_run ? "Not " : "", counter, VTY_NEWLINE); - } - - if (delete_nsvc) { - struct gprs_ns_inst *nsi = g_cfg->nsi; - struct gprs_nsvc *nsvc, *nsvc2; - - counter = 0; - llist_for_each_entry_safe(nsvc, nsvc2, &nsi->gprs_nsvcs, list) { - if (nsvc->nsei != nsei) - continue; - if (nsvc->persistent) - continue; - - if (!dry_run) - gprs_nsvc_delete(nsvc); - else - vty_out(vty, "NS-VC: NSEI %5u, NS-VCI %5u, " - "remote %s%s", - nsvc->nsei, nsvc->nsvci, - gprs_ns_ll_str(nsvc), VTY_NEWLINE); - counter += 1; - } - vty_out(vty, "%sDeleted %d NS-VC%s", - dry_run ? "Not " : "", counter, VTY_NEWLINE); - } - - return CMD_SUCCESS; -} - -#define GBPROXY_DELETE_LINK_STR \ - "Delete a GBProxy logical link entry by NSEI and identification\nNSEI number\n" - -DEFUN(delete_gb_link_by_id, delete_gb_link_by_id_cmd, - "delete-gbproxy-link <0-65534> (tlli|imsi|sgsn-nsei) IDENT", - GBPROXY_DELETE_LINK_STR - "Delete entries with a matching TLLI (hex)\n" - "Delete entries with a matching IMSI\n" - "Delete entries with a matching SGSN NSEI\n" - "Identification to match\n") -{ - const uint16_t nsei = atoi(argv[0]); - enum {MATCH_TLLI = 't', MATCH_IMSI = 'i', MATCH_SGSN = 's'} match; - uint32_t ident = 0; - const char *imsi = NULL; - struct gbproxy_peer *peer = 0; - struct gbproxy_link_info *link_info, *nxt; - struct gbproxy_patch_state *state; - char mi_buf[200]; - int found = 0; - - match = argv[1][0]; - - switch (match) { - case MATCH_TLLI: ident = strtoll(argv[2], NULL, 16); break; - case MATCH_IMSI: imsi = argv[2]; break; - case MATCH_SGSN: ident = strtoll(argv[2], NULL, 0); break; - }; - - peer = gbproxy_peer_by_nsei(g_cfg, nsei); - if (!peer) { - vty_out(vty, "Didn't find peer with NSEI %d%s", - nsei, VTY_NEWLINE); - return CMD_WARNING; - } - - state = &peer->patch_state; - - llist_for_each_entry_safe(link_info, nxt, &state->logical_links, list) { - switch (match) { - case MATCH_TLLI: - if (link_info->tlli.current != ident) - continue; - break; - case MATCH_SGSN: - if (link_info->sgsn_nsei != ident) - continue; - break; - case MATCH_IMSI: - if (!link_info->imsi) - continue; - mi_buf[0] = '\0'; - gsm48_mi_to_string(mi_buf, sizeof(mi_buf), - link_info->imsi, - link_info->imsi_len); - - if (strcmp(mi_buf, imsi) != 0) - continue; - break; - } - - vty_out(vty, "Deleting link with TLLI %08x%s", link_info->tlli.current, - VTY_NEWLINE); - gbproxy_delete_link_info(peer, link_info); - found += 1; - } - - if (!found && argc >= 2) { - vty_out(vty, "Didn't find link entry with %s %s%s", - argv[1], argv[2], VTY_NEWLINE); - } - - return CMD_SUCCESS; -} - -DEFUN(delete_gb_link, delete_gb_link_cmd, - "delete-gbproxy-link <0-65534> (stale|de-registered)", - GBPROXY_DELETE_LINK_STR - "Delete stale entries\n" - "Delete de-registered entries\n") -{ - const uint16_t nsei = atoi(argv[0]); - enum {MATCH_STALE = 's', MATCH_DEREGISTERED = 'd'} match; - struct gbproxy_peer *peer = 0; - struct gbproxy_link_info *link_info, *nxt; - struct gbproxy_patch_state *state; - time_t now; - struct timespec ts = {0,}; - - int found = 0; - - match = argv[1][0]; - - peer = gbproxy_peer_by_nsei(g_cfg, nsei); - if (!peer) { - vty_out(vty, "Didn't find peer with NSEI %d%s", - nsei, VTY_NEWLINE); - return CMD_WARNING; - } - - state = &peer->patch_state; - - clock_gettime(CLOCK_MONOTONIC, &ts); - now = ts.tv_sec; - - if (match == MATCH_STALE) { - found = gbproxy_remove_stale_link_infos(peer, now); - if (found) - vty_out(vty, "Deleted %d stale logical link%s%s", - found, found == 1 ? "" : "s", VTY_NEWLINE); - } else { - llist_for_each_entry_safe(link_info, nxt, - &state->logical_links, list) { - if (!link_info->is_deregistered) - continue; - - gbproxy_delete_link_info(peer, link_info); - found += 1; - } - } - - if (found) - vty_out(vty, "Deleted %d %s logical link%s%s", - found, argv[1], found == 1 ? "" : "s", VTY_NEWLINE); - - return CMD_SUCCESS; -} - -/* - * legacy commands to provide an upgrade path from "broken" releases - * or pre-releases - */ -DEFUN_DEPRECATED(cfg_gbproxy_broken_apn_match, - cfg_gbproxy_broken_apn_match_cmd, - "core-access-point-name none match-imsi .REGEXP", - GBPROXY_CORE_APN_STR GBPROXY_MATCH_IMSI_STR "Remove APN\n" - "Patch MS related information elements on match only\n" - "Route to the secondary SGSN on match only\n" - "Regular expression for the IMSI match\n") -{ - const char *filter = argv[0]; - const char *err_msg = NULL; - struct gbproxy_match *match; - enum gbproxy_match_id match_id = get_string_value(match_ids, "patching"); - - /* apply APN none */ - set_core_apn(vty, ""); - - /* do the matching... with copy and paste */ - OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING && - match_id < GBPROX_MATCH_LAST); - match = &g_cfg->matches[match_id]; - - if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) { - vty_out(vty, "Match expression invalid: %s%s", - err_msg, VTY_NEWLINE); - return CMD_WARNING; - } - - g_cfg->acquire_imsi = 1; - - return CMD_SUCCESS; -} - -#define GBPROXY_TLLI_LIST_STR "Set TLLI list parameters\n" -#define GBPROXY_MAX_LEN_STR "Limit list length\n" -DEFUN_DEPRECATED(cfg_gbproxy_depr_tlli_list_max_len, - cfg_gbproxy_depr_tlli_list_max_len_cmd, - "tlli-list max-length <1-99999>", - GBPROXY_TLLI_LIST_STR GBPROXY_MAX_LEN_STR - "Maximum number of TLLIs in the list\n") -{ - g_cfg->tlli_max_len = atoi(argv[0]); - - return CMD_SUCCESS; -} - -int gbproxy_vty_init(void) -{ - install_element_ve(&show_gbproxy_cmd); - install_element_ve(&show_gbproxy_links_cmd); - - install_element(ENABLE_NODE, &delete_gb_bvci_cmd); - install_element(ENABLE_NODE, &delete_gb_nsei_cmd); - install_element(ENABLE_NODE, &delete_gb_link_by_id_cmd); - install_element(ENABLE_NODE, &delete_gb_link_cmd); - - install_element(CONFIG_NODE, &cfg_gbproxy_cmd); - install_node(&gbproxy_node, config_write_gbproxy); - vty_install_default(GBPROXY_NODE); - install_element(GBPROXY_NODE, &cfg_nsip_sgsn_nsei_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_core_mcc_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_core_mnc_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_match_imsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_core_apn_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_secondary_sgsn_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_patch_ptmsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_acquire_imsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_age_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_len_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_keep_mode_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mcc_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mnc_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_match_imsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_apn_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_secondary_sgsn_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_patch_ptmsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd); - - /* broken or deprecated to allow an upgrade path */ - install_element(GBPROXY_NODE, &cfg_gbproxy_broken_apn_match_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_depr_tlli_list_max_len_cmd); - - return 0; -} - -int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg) -{ - int rc; - - g_cfg = cfg; - rc = vty_read_config_file(config_file, NULL); - if (rc < 0) { - fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file); - return rc; - } - - return 0; -} - diff --git a/src/gprs/gprs_gb_parse.c b/src/gprs/gprs_gb_parse.c deleted file mode 100644 index d5a122bda..000000000 --- a/src/gprs/gprs_gb_parse.c +++ /dev/null @@ -1,636 +0,0 @@ -/* GPRS Gb message parser */ - -/* (C) 2014 by On-Waves - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include - -#include - -#include - -#include - -#include - -static int gprs_gb_parse_gmm_attach_req(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - uint8_t *value; - size_t value_len; - - parse_ctx->llc_msg_name = "ATTACH_REQ"; - - /* Skip MS network capability */ - if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 || - value_len < 1 || value_len > 8) - /* invalid */ - return 0; - - /* Skip Attach type */ - /* Skip Ciphering key sequence number */ - /* Skip DRX parameter */ - osmo_shift_v_fixed(&data, &data_len, 3, NULL); - - /* Get Mobile identity */ - if (osmo_shift_lv(&data, &data_len, &value, &value_len) <= 0 || - value_len < 5 || value_len > 8) - /* invalid */ - return 0; - - if (gprs_is_mi_tmsi(value, value_len)) { - parse_ctx->ptmsi_enc = value + 1; - } else if (gprs_is_mi_imsi(value, value_len)) { - parse_ctx->imsi = value; - parse_ctx->imsi_len = value_len; - } - - if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0) - return 0; - - parse_ctx->old_raid_enc = value; - - return 1; -} - -static int gprs_gb_parse_gmm_attach_ack(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - uint8_t *value; - size_t value_len; - - parse_ctx->llc_msg_name = "ATTACH_ACK"; - - /* Skip Attach result */ - /* Skip Force to standby */ - /* Skip Periodic RA update timer */ - /* Skip Radio priority for SMS */ - /* Skip Spare half octet */ - osmo_shift_v_fixed(&data, &data_len, 3, NULL); - - if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0) - return 0; - - parse_ctx->raid_enc = value; - - /* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */ - osmo_match_shift_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL); - - /* Skip Negotiated READY timer value (GPRS timer, opt, TV, length 2) */ - osmo_match_shift_tv_fixed(&data, &data_len, GSM48_IE_GMM_TIMER_READY, 1, NULL); - - /* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */ - if (osmo_match_shift_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI, - &value, &value_len) > 0 && - gprs_is_mi_tmsi(value, value_len)) - parse_ctx->new_ptmsi_enc = value + 1; - return 1; -} - -static int gprs_gb_parse_gmm_attach_rej(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - uint8_t *value; - - parse_ctx->llc_msg_name = "ATTACH_REJ"; - - /* GMM cause */ - if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0) - return 0; - - parse_ctx->invalidate_tlli = 1; - - return 1; -} - - -static int gprs_gb_parse_gmm_detach_req(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - uint8_t *value; - size_t value_len; - int detach_type; - int power_off; - - parse_ctx->llc_msg_name = "DETACH_REQ"; - - /* Skip spare half octet */ - /* Get Detach type */ - if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0) - /* invalid */ - return 0; - - detach_type = *value & 0x07; - power_off = *value & 0x08 ? 1 : 0; - - if (parse_ctx->to_bss) { - /* Network originated */ - if (detach_type == GPRS_DET_T_MT_REATT_REQ) - parse_ctx->await_reattach = 1; - } else { - /* Mobile originated */ - - if (power_off) - parse_ctx->invalidate_tlli = 1; - - /* Get P-TMSI (Mobile identity), see GSM 24.008, 9.4.5.2 */ - if (osmo_match_shift_tlv(&data, &data_len, - GSM48_IE_GMM_ALLOC_PTMSI, &value, &value_len) > 0) - { - if (gprs_is_mi_tmsi(value, value_len)) - parse_ctx->ptmsi_enc = value + 1; - } - } - - return 1; -} - -static int gprs_gb_parse_gmm_ra_upd_req(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - uint8_t *value; - - parse_ctx->llc_msg_name = "RA_UPD_REQ"; - - /* Skip Update type */ - /* Skip GPRS ciphering key sequence number */ - osmo_shift_v_fixed(&data, &data_len, 1, NULL); - - if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0) - return 0; - - parse_ctx->old_raid_enc = value; - - return 1; -} - -static int gprs_gb_parse_gmm_ra_upd_rej(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - uint8_t *value; - uint8_t cause; - int force_standby; - - parse_ctx->llc_msg_name = "RA_UPD_REJ"; - - /* GMM cause */ - if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0) - return 0; - - cause = value[0]; - - /* Force to standby, 1/2 */ - /* spare bits, 1/2 */ - if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0) - return 0; - - force_standby = (value[0] & 0x07) == 0x01; - - if (cause == GMM_CAUSE_IMPL_DETACHED && !force_standby) - parse_ctx->await_reattach = 1; - - parse_ctx->invalidate_tlli = 1; - - return 1; -} - -static int gprs_gb_parse_gmm_ra_upd_ack(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - uint8_t *value; - size_t value_len; - - parse_ctx->llc_msg_name = "RA_UPD_ACK"; - - /* Skip Force to standby */ - /* Skip Update result */ - /* Skip Periodic RA update timer */ - osmo_shift_v_fixed(&data, &data_len, 2, NULL); - - if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0) - return 0; - - parse_ctx->raid_enc = value; - - /* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */ - osmo_match_shift_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL); - - /* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */ - if (osmo_match_shift_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI, - &value, &value_len) > 0 && - gprs_is_mi_tmsi(value, value_len)) - parse_ctx->new_ptmsi_enc = value + 1; - - return 1; -} - -static int gprs_gb_parse_gmm_ptmsi_reall_cmd(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - uint8_t *value; - size_t value_len; - - parse_ctx->llc_msg_name = "PTMSI_REALL_CMD"; - - LOGP(DLLC, LOGL_NOTICE, - "Got P-TMSI Reallocation Command which is not covered by unit tests yet.\n"); - - /* Allocated P-TMSI */ - if (osmo_shift_lv(&data, &data_len, &value, &value_len) > 0 && - gprs_is_mi_tmsi(value, value_len)) - parse_ctx->new_ptmsi_enc = value + 1; - - if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0) - return 0; - - parse_ctx->raid_enc = value; - - return 1; -} - -static int gprs_gb_parse_gmm_id_resp(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - uint8_t *value; - size_t value_len; - - parse_ctx->llc_msg_name = "ID_RESP"; - - /* Mobile identity, Mobile identity 10.5.1.4, M LV 2-10 */ - if (osmo_shift_lv(&data, &data_len, &value, &value_len) <= 0 || - value_len < 1 || value_len > 9) - /* invalid */ - return 0; - - if (gprs_is_mi_tmsi(value, value_len)) { - parse_ctx->ptmsi_enc = value + 1; - } else if (gprs_is_mi_imsi(value, value_len)) { - parse_ctx->imsi = value; - parse_ctx->imsi_len = value_len; - } - - return 1; -} - -static int gprs_gb_parse_gsm_act_pdp_req(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - ssize_t old_len; - uint8_t *value; - size_t value_len; - - parse_ctx->llc_msg_name = "ACT_PDP_REQ"; - - /* Skip Requested NSAPI */ - /* Skip Requested LLC SAPI */ - osmo_shift_v_fixed(&data, &data_len, 2, NULL); - - /* Skip Requested QoS (support 04.08 and 24.008) */ - if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 || - value_len < 4 || value_len > 14) - /* invalid */ - return 0; - - /* Skip Requested PDP address */ - if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 || - value_len < 2 || value_len > 18) - /* invalid */ - return 0; - - /* Access point name */ - old_len = osmo_match_shift_tlv(&data, &data_len, - GSM48_IE_GSM_APN, &value, &value_len); - - if (old_len > 0 && value_len >=1 && value_len <= 100) { - parse_ctx->apn_ie = data - old_len; - parse_ctx->apn_ie_len = old_len; - } - - return 1; -} - -int gprs_gb_parse_dtap(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gsm48_hdr *g48h; - uint8_t pdisc; - uint8_t msg_type; - - if (osmo_shift_v_fixed(&data, &data_len, sizeof(*g48h), (uint8_t **)&g48h) <= 0) - return 0; - - parse_ctx->g48_hdr = g48h; - - pdisc = gsm48_hdr_pdisc(g48h); - if (pdisc != GSM48_PDISC_MM_GPRS && pdisc != GSM48_PDISC_SM_GPRS) - return 1; - - msg_type = gsm48_hdr_msg_type(g48h); - switch (msg_type) { - case GSM48_MT_GMM_ATTACH_REQ: - return gprs_gb_parse_gmm_attach_req(data, data_len, parse_ctx); - - case GSM48_MT_GMM_ATTACH_REJ: - return gprs_gb_parse_gmm_attach_rej(data, data_len, parse_ctx); - - case GSM48_MT_GMM_ATTACH_ACK: - return gprs_gb_parse_gmm_attach_ack(data, data_len, parse_ctx); - - case GSM48_MT_GMM_RA_UPD_REQ: - return gprs_gb_parse_gmm_ra_upd_req(data, data_len, parse_ctx); - - case GSM48_MT_GMM_RA_UPD_REJ: - return gprs_gb_parse_gmm_ra_upd_rej(data, data_len, parse_ctx); - - case GSM48_MT_GMM_RA_UPD_ACK: - return gprs_gb_parse_gmm_ra_upd_ack(data, data_len, parse_ctx); - - case GSM48_MT_GMM_PTMSI_REALL_CMD: - return gprs_gb_parse_gmm_ptmsi_reall_cmd(data, data_len, parse_ctx); - - case GSM48_MT_GSM_ACT_PDP_REQ: - return gprs_gb_parse_gsm_act_pdp_req(data, data_len, parse_ctx); - - case GSM48_MT_GMM_ID_RESP: - return gprs_gb_parse_gmm_id_resp(data, data_len, parse_ctx); - - case GSM48_MT_GMM_DETACH_REQ: - return gprs_gb_parse_gmm_detach_req(data, data_len, parse_ctx); - - case GSM48_MT_GMM_DETACH_ACK: - parse_ctx->llc_msg_name = "DETACH_ACK"; - parse_ctx->invalidate_tlli = 1; - break; - - default: - LOGP(DLLC, LOGL_NOTICE, - "Unhandled GSM 04.08 message type %s for protocol discriminator %s.\n", - get_value_string(gprs_msgt_gmm_names, msg_type), get_value_string(gsm48_pdisc_names, pdisc)); - break; - }; - - return 1; -} - -int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gprs_llc_hdr_parsed *ghp = &parse_ctx->llc_hdr_parsed; - int rc; - int fcs; - - /* parse LLC */ - rc = gprs_llc_hdr_parse(ghp, llc, llc_len); - gprs_llc_hdr_dump(ghp, NULL); - if (rc != 0) { - LOGP(DLLC, LOGL_NOTICE, "Error during LLC header parsing\n"); - return 0; - } - - fcs = gprs_llc_fcs(llc, ghp->crc_length); - LOGP(DLLC, LOGL_DEBUG, "Got LLC message, CRC: %06x (computed %06x)\n", - ghp->fcs, fcs); - - if (!ghp->data) - return 0; - - if (ghp->sapi != GPRS_SAPI_GMM) - return 1; - - if (ghp->cmd != GPRS_LLC_UI) - return 1; - - if (ghp->is_encrypted) { - parse_ctx->need_decryption = 1; - return 0; - } - - return gprs_gb_parse_dtap(ghp->data, ghp->data_len, parse_ctx); -} - -int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len, - struct gprs_gb_parse_context *parse_ctx) -{ - struct bssgp_normal_hdr *bgph; - struct bssgp_ud_hdr *budh = NULL; - struct tlv_parsed *tp = &parse_ctx->bssgp_tp; - uint8_t pdu_type; - uint8_t *data; - size_t data_len; - int rc; - - if (bssgp_len < sizeof(struct bssgp_normal_hdr)) - return 0; - - bgph = (struct bssgp_normal_hdr *)bssgp; - pdu_type = bgph->pdu_type; - - if (pdu_type == BSSGP_PDUT_UL_UNITDATA || - pdu_type == BSSGP_PDUT_DL_UNITDATA) { - if (bssgp_len < sizeof(struct bssgp_ud_hdr)) - return 0; - budh = (struct bssgp_ud_hdr *)bssgp; - bgph = NULL; - data = budh->data; - data_len = bssgp_len - sizeof(*budh); - } else { - data = bgph->data; - data_len = bssgp_len - sizeof(*bgph); - } - - parse_ctx->pdu_type = pdu_type; - parse_ctx->bud_hdr = budh; - parse_ctx->bgp_hdr = bgph; - parse_ctx->bssgp_data = data; - parse_ctx->bssgp_data_len = data_len; - - if (bssgp_tlv_parse(tp, data, data_len) < 0) - return 0; - - if (budh) - parse_ctx->tlli_enc = (uint8_t *)&budh->tlli; - - if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) - parse_ctx->bssgp_raid_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA); - - if (TLVP_PRESENT(tp, BSSGP_IE_CELL_ID)) - parse_ctx->bssgp_raid_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_CELL_ID); - - if (TLVP_PRESENT(tp, BSSGP_IE_IMSI)) { - parse_ctx->imsi = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_IMSI); - parse_ctx->imsi_len = TLVP_LEN(tp, BSSGP_IE_IMSI); - } - - if (TLVP_PRESENT(tp, BSSGP_IE_TLLI)) { - if (parse_ctx->tlli_enc) - /* This is TLLI old, don't confuse it with TLLI current */ - parse_ctx->old_tlli_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_TLLI); - else - parse_ctx->tlli_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_TLLI); - } - - if (TLVP_PRESENT(tp, BSSGP_IE_TMSI) && pdu_type == BSSGP_PDUT_PAGING_PS) - parse_ctx->bssgp_ptmsi_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_TMSI); - - if (TLVP_PRESENT(tp, BSSGP_IE_LLC_PDU)) { - uint8_t *llc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_LLC_PDU); - size_t llc_len = TLVP_LEN(tp, BSSGP_IE_LLC_PDU); - - rc = gprs_gb_parse_llc(llc, llc_len, parse_ctx); - if (!rc) - return 0; - - parse_ctx->llc = llc; - parse_ctx->llc_len = llc_len; - } - - if (parse_ctx->tlli_enc) { - uint32_t tmp_tlli; - memcpy(&tmp_tlli, parse_ctx->tlli_enc, sizeof(tmp_tlli)); - parse_ctx->tlli = ntohl(tmp_tlli); - } - - if (parse_ctx->bssgp_raid_enc && parse_ctx->old_raid_enc && - memcmp(parse_ctx->bssgp_raid_enc, parse_ctx->old_raid_enc, 6) != 0) - parse_ctx->old_raid_is_foreign = 1; - - return 1; -} - -void gprs_gb_log_parse_context(int log_level, - struct gprs_gb_parse_context *parse_ctx, - const char *default_msg_name) -{ - const char *msg_name; - const char *sep = ""; - - if (!parse_ctx->tlli_enc && - !parse_ctx->ptmsi_enc && - !parse_ctx->new_ptmsi_enc && - !parse_ctx->bssgp_ptmsi_enc && - !parse_ctx->imsi) - return; - - msg_name = gprs_gb_message_name(parse_ctx, default_msg_name); - - if (parse_ctx->llc_msg_name) - msg_name = parse_ctx->llc_msg_name; - - LOGP(DGPRS, log_level, "%s: Got", msg_name); - - if (parse_ctx->tlli_enc) { - LOGPC(DGPRS, log_level, "%s TLLI %08x", sep, parse_ctx->tlli); - sep = ","; - } - - if (parse_ctx->old_tlli_enc) { - LOGPC(DGPRS, log_level, "%s old TLLI %02x%02x%02x%02x", sep, - parse_ctx->old_tlli_enc[0], - parse_ctx->old_tlli_enc[1], - parse_ctx->old_tlli_enc[2], - parse_ctx->old_tlli_enc[3]); - sep = ","; - } - - if (parse_ctx->bssgp_raid_enc) { - struct gprs_ra_id raid; - gsm48_parse_ra(&raid, parse_ctx->bssgp_raid_enc); - LOGPC(DGPRS, log_level, "%s BSSGP RAID %u-%u-%u-%u", sep, - raid.mcc, raid.mnc, raid.lac, raid.rac); - sep = ","; - } - - if (parse_ctx->raid_enc) { - struct gprs_ra_id raid; - gsm48_parse_ra(&raid, parse_ctx->raid_enc); - LOGPC(DGPRS, log_level, "%s RAID %u-%u-%u-%u", sep, - raid.mcc, raid.mnc, raid.lac, raid.rac); - sep = ","; - } - - if (parse_ctx->old_raid_enc) { - struct gprs_ra_id raid; - gsm48_parse_ra(&raid, parse_ctx->old_raid_enc); - LOGPC(DGPRS, log_level, "%s old RAID %u-%u-%u-%u", sep, - raid.mcc, raid.mnc, raid.lac, raid.rac); - sep = ","; - } - - if (parse_ctx->bssgp_ptmsi_enc) { - uint32_t ptmsi = GSM_RESERVED_TMSI; - gprs_parse_tmsi(parse_ctx->bssgp_ptmsi_enc, &ptmsi); - LOGPC(DGPRS, log_level, "%s BSSGP PTMSI %08x", sep, ptmsi); - sep = ","; - } - - if (parse_ctx->ptmsi_enc) { - uint32_t ptmsi = GSM_RESERVED_TMSI; - gprs_parse_tmsi(parse_ctx->ptmsi_enc, &ptmsi); - LOGPC(DGPRS, log_level, "%s PTMSI %08x", sep, ptmsi); - sep = ","; - } - - if (parse_ctx->new_ptmsi_enc) { - uint32_t new_ptmsi = GSM_RESERVED_TMSI; - gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi); - LOGPC(DGPRS, log_level, "%s new PTMSI %08x", sep, new_ptmsi); - sep = ","; - } - - if (parse_ctx->imsi) { - char mi_buf[200]; - mi_buf[0] = '\0'; - gsm48_mi_to_string(mi_buf, sizeof(mi_buf), - parse_ctx->imsi, parse_ctx->imsi_len); - LOGPC(DGPRS, log_level, "%s IMSI %s", - sep, mi_buf); - sep = ","; - } - if (parse_ctx->invalidate_tlli) { - LOGPC(DGPRS, log_level, "%s invalidate", sep); - sep = ","; - } - if (parse_ctx->await_reattach) { - LOGPC(DGPRS, log_level, "%s re-attach", sep); - sep = ","; - } - - LOGPC(DGPRS, log_level, "\n"); -} - -const char *gprs_gb_message_name(const struct gprs_gb_parse_context *parse_ctx, - const char *default_msg_name) -{ - if (parse_ctx->llc_msg_name) - return parse_ctx->llc_msg_name; - - if (parse_ctx->g48_hdr) - return "GMM"; - - if (parse_ctx->llc) - return "LLC"; - - if (parse_ctx->bud_hdr) - return "BSSGP-UNITDATA"; - - if (parse_ctx->bgp_hdr) - return "BSSGP"; - - return "unknown"; -} diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c deleted file mode 100644 index 032137f0b..000000000 --- a/src/gprs/gprs_gmm.c +++ /dev/null @@ -1,2937 +0,0 @@ -/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface - * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */ - -/* (C) 2009-2015 by Harald Welte - * (C) 2010 by On-Waves - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "bscconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef BUILD_IU -#include -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define PTMSI_ALLOC - -extern struct sgsn_instance *sgsn; - -static const struct tlv_definition gsm48_gmm_att_tlvdef = { - .def = { - [GSM48_IE_GMM_CIPH_CKSN] = { TLV_TYPE_FIXED, 1 }, - [GSM48_IE_GMM_TIMER_READY] = { TLV_TYPE_TV, 1 }, - [GSM48_IE_GMM_ALLOC_PTMSI] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GMM_PTMSI_SIG] = { TLV_TYPE_FIXED, 3 }, - [GSM48_IE_GMM_AUTH_RAND] = { TLV_TYPE_FIXED, 16 }, - [GSM48_IE_GMM_AUTH_SRES] = { TLV_TYPE_FIXED, 4 }, - [GSM48_IE_GMM_AUTH_RES_EXT] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GMM_AUTH_FAIL_PAR] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GMM_IMEISV] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GMM_DRX_PARAM] = { TLV_TYPE_FIXED, 2 }, - [GSM48_IE_GMM_MS_NET_CAPA] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GMM_PDP_CTX_STATUS] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GMM_PS_LCS_CAPA] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GMM_GMM_MBMS_CTX_ST] = { TLV_TYPE_TLV, 0 }, - }, -}; - -static const struct tlv_definition gsm48_sm_att_tlvdef = { - .def = { - [GSM48_IE_GSM_APN] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GSM_PROTO_CONF_OPT] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GSM_PDP_ADDR] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GSM_AA_TMR] = { TLV_TYPE_TV, 1 }, - [GSM48_IE_GSM_NAME_FULL] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GSM_NAME_SHORT] = { TLV_TYPE_TLV, 0 }, - [GSM48_IE_GSM_TIMEZONE] = { TLV_TYPE_FIXED, 1 }, - [GSM48_IE_GSM_UTC_AND_TZ] = { TLV_TYPE_FIXED, 7 }, - [GSM48_IE_GSM_LSA_ID] = { TLV_TYPE_TLV, 0 }, - }, -}; - -static const struct value_string gprs_pmm_state_names[] = { - { PMM_DETACHED, "PMM DETACH" }, - { PMM_CONNECTED, "PMM CONNECTED" }, - { PMM_IDLE, "PMM IDLE" }, - { MM_IDLE, "MM IDLE" }, - { MM_READY, "MM READY" }, - { MM_STANDBY, "MM STANDBY" }, - { 0, NULL } -}; - -static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx); - -static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx) -{ - struct sgsn_pdp_ctx *pdp; - llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) { - sgsn_pdp_upd_gtp_u(pdp, - &sgsn->cfg.gtp_listenaddr.sin_addr, - sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); - } -} - -void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state) -{ - if (ctx->ran_type != MM_CTX_T_UTRAN_Iu) - return; - - if (ctx->pmm_state == state) - return; - - LOGMMCTXP(LOGL_INFO, ctx, "Changing PMM state from %s to %s\n", - get_value_string(gprs_pmm_state_names, ctx->pmm_state), - get_value_string(gprs_pmm_state_names, state)); - - switch (state) { - case PMM_IDLE: - /* TODO: start RA Upd timer */ - mmctx_change_gtpu_endpoints_to_sgsn(ctx); - break; - case PMM_CONNECTED: - break; - default: - break; - } - - ctx->pmm_state = state; -} - -void mmctx_set_mm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state) -{ - if (ctx->ran_type != MM_CTX_T_GERAN_Gb) - return; - - if (ctx->pmm_state == state) - return; - - LOGMMCTXP(LOGL_INFO, ctx, "Changing MM state from %s to %s\n", - get_value_string(gprs_pmm_state_names, ctx->pmm_state), - get_value_string(gprs_pmm_state_names, state)); - - ctx->pmm_state = state; -} - -#ifdef BUILD_IU -int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies); -int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type, void *data) -{ - struct sgsn_mm_ctx *mm; - int rc = -1; - - mm = sgsn_mm_ctx_by_ue_ctx(ctx); - -#define REQUIRE_MM \ - if (!mm) { \ - LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %d\n", type); \ - return rc; \ - } - - switch (type) { - case RANAP_IU_EVENT_RAB_ASSIGN: - REQUIRE_MM - rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data); - break; - case RANAP_IU_EVENT_IU_RELEASE: - /* fall thru */ - case RANAP_IU_EVENT_LINK_INVALIDATED: - /* Clean up ranap_ue_conn_ctx here */ - if (mm) - LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi); - else - LOGMMCTXP(LOGL_INFO, mm, "IU release for UE conn 0x%x\n", - ctx->conn_id); - if (mm && mm->pmm_state == PMM_CONNECTED) - mmctx_set_pmm_state(mm, PMM_IDLE); - rc = 0; - break; - case RANAP_IU_EVENT_SECURITY_MODE_COMPLETE: - REQUIRE_MM - /* Continue authentication here */ - mm->iu.ue_ctx->integrity_active = 1; - rc = gsm48_gmm_authorize(mm); - break; - default: - LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type); - rc = -1; - break; - } - return rc; -} -#endif - - -/* Our implementation, should be kept in SGSN */ - -static void mmctx_timer_cb(void *_mm); - -static void mmctx_timer_start(struct sgsn_mm_ctx *mm, unsigned int T, - unsigned int seconds) -{ - if (osmo_timer_pending(&mm->timer)) - LOGMMCTXP(LOGL_ERROR, mm, "Starting MM timer %u while old " - "timer %u pending\n", T, mm->T); - mm->T = T; - mm->num_T_exp = 0; - - /* FIXME: we should do this only once ? */ - osmo_timer_setup(&mm->timer, mmctx_timer_cb, mm); - osmo_timer_schedule(&mm->timer, seconds, 0); -} - -static void mmctx_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T) -{ - if (mm->T != T) - LOGMMCTXP(LOGL_ERROR, mm, "Stopping MM timer %u but " - "%u is running\n", T, mm->T); - osmo_timer_del(&mm->timer); -} - -time_t gprs_max_time_to_idle(void) -{ - return sgsn->cfg.timers.T3314 + (sgsn->cfg.timers.T3312 + 4 * 60); -} - -/* Send a message through the underlying layer. - * For param encryptable, see 3GPP TS 24.008 § 4.7.1.2 and - * gsm48_hdr_gmm_cipherable(). Pass false for not cipherable messages. */ -static int gsm48_gmm_sendmsg(struct msgb *msg, int command, - struct sgsn_mm_ctx *mm, bool encryptable) -{ - if (mm) { - rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PKTS_SIG_OUT]); -#ifdef BUILD_IU - if (mm->ran_type == MM_CTX_T_UTRAN_Iu) - return ranap_iu_tx(msg, GPRS_SAPI_GMM); -#endif - } - -#ifdef BUILD_IU - /* In Iu mode, msg->dst contains the ranap_ue_conn_ctx pointer, in Gb mode - * dst is empty. */ - /* FIXME: have a more explicit indicator for Iu messages */ - if (msg->dst) - return ranap_iu_tx(msg, GPRS_SAPI_GMM); -#endif - - /* caller needs to provide TLLI, BVCI and NSEI */ - return gprs_llc_tx_ui(msg, GPRS_SAPI_GMM, command, mm, encryptable); -} - -/* copy identifiers from old message to new message, this - * is required so lower layers can route it correctly */ -static void gmm_copy_id(struct msgb *msg, const struct msgb *old) -{ - msgb_tlli(msg) = msgb_tlli(old); - msgb_bvci(msg) = msgb_bvci(old); - msgb_nsei(msg) = msgb_nsei(old); - msg->dst = old->dst; -} - -/* Store BVCI/NSEI in MM context */ -static void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg) -{ - mm->gb.bvci = msgb_bvci(msg); - mm->gb.nsei = msgb_nsei(msg); - /* In case a Iu connection is reconnected we need to update the ue ctx */ - mm->iu.ue_ctx = msg->dst; - if (mm->ran_type == MM_CTX_T_UTRAN_Iu - && mm->iu.ue_ctx) { -#ifdef BUILD_IU - mm->iu.ue_ctx->rab_assign_addr_enc = - sgsn->cfg.iu.rab_assign_addr_enc; -#endif - } -} - -/* Store BVCI/NSEI in MM context */ -static void mmctx2msgid(struct msgb *msg, const struct sgsn_mm_ctx *mm) -{ - msgb_tlli(msg) = mm->gb.tlli; - msgb_bvci(msg) = mm->gb.bvci; - msgb_nsei(msg) = mm->gb.nsei; - msg->dst = mm->iu.ue_ctx; -} - -static void mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx, const char *log_text) -{ - LOGMMCTXP(LOGL_INFO, ctx, "Cleaning MM context due to %s\n", log_text); - - /* Mark MM state as deregistered */ - ctx->gmm_state = GMM_DEREGISTERED; - mmctx_set_pmm_state(ctx, PMM_DETACHED); - mmctx_set_pmm_state(ctx, MM_IDLE); - - sgsn_mm_ctx_cleanup_free(ctx); -} - -/* Chapter 9.4.18 */ -static int _tx_status(struct msgb *msg, uint8_t cause, - struct sgsn_mm_ctx *mmctx, int sm) -{ - struct gsm48_hdr *gh; - - /* MMCTX might be NULL! */ - - DEBUGP(DMM, "<- GPRS MM STATUS (cause: %s)\n", - get_value_string(gsm48_gmm_cause_names, cause)); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - if (sm) { - gh->proto_discr = GSM48_PDISC_SM_GPRS; - gh->msg_type = GSM48_MT_GSM_STATUS; - } else { - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_STATUS; - } - gh->data[0] = cause; - - return gsm48_gmm_sendmsg(msg, 0, mmctx, true); -} - -static int gsm48_tx_gmm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 GMM STATUS"); - - mmctx2msgid(msg, mmctx); - return _tx_status(msg, cause, mmctx, 0); -} - -static int gsm48_tx_sm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SM STATUS"); - - mmctx2msgid(msg, mmctx); - return _tx_status(msg, cause, mmctx, 1); -} - -static int _tx_detach_req(struct msgb *msg, uint8_t detach_type, uint8_t cause, - struct sgsn_mm_ctx *mmctx) -{ - struct gsm48_hdr *gh; - - /* MMCTX might be NULL! */ - - DEBUGP(DMM, "<- GPRS MM DETACH REQ (type: %s, cause: %s)\n", - get_value_string(gprs_det_t_mt_strs, detach_type), - get_value_string(gsm48_gmm_cause_names, cause)); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_DETACH_REQ; - gh->data[0] = detach_type & 0x07; - - msgb_tv_put(msg, GSM48_IE_GMM_CAUSE, cause); - - return gsm48_gmm_sendmsg(msg, 0, mmctx, true); -} - -static int gsm48_tx_gmm_detach_req(struct sgsn_mm_ctx *mmctx, - uint8_t detach_type, uint8_t cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET REQ"); - - mmctx2msgid(msg, mmctx); - return _tx_detach_req(msg, detach_type, cause, mmctx); -} - -static int gsm48_tx_gmm_detach_req_oldmsg(struct msgb *oldmsg, - uint8_t detach_type, uint8_t cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET OLD"); - - gmm_copy_id(msg, oldmsg); - return _tx_detach_req(msg, detach_type, cause, NULL); -} - -static struct gsm48_qos default_qos = { - .delay_class = 4, /* best effort */ - .reliab_class = GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT, - .peak_tput = GSM48_QOS_PEAK_TPUT_32000bps, - .preced_class = GSM48_QOS_PC_NORMAL, - .mean_tput = GSM48_QOS_MEAN_TPUT_BEST_EFFORT, - .traf_class = GSM48_QOS_TC_INTERACTIVE, - .deliv_order = GSM48_QOS_DO_UNORDERED, - .deliv_err_sdu = GSM48_QOS_ERRSDU_YES, - .max_sdu_size = GSM48_QOS_MAXSDU_1520, - .max_bitrate_up = GSM48_QOS_MBRATE_63k, - .max_bitrate_down = GSM48_QOS_MBRATE_63k, - .resid_ber = GSM48_QOS_RBER_5e_2, - .sdu_err_ratio = GSM48_QOS_SERR_1e_2, - .handling_prio = 3, - .xfer_delay = 0x10, /* 200ms */ - .guar_bitrate_up = GSM48_QOS_MBRATE_0k, - .guar_bitrate_down = GSM48_QOS_MBRATE_0k, - .sig_ind = 0, /* not optimised for signalling */ - .max_bitrate_down_ext = 0, /* use octet 9 */ - .guar_bitrate_down_ext = 0, /* use octet 13 */ -}; - -/* Chapter 9.4.2: Attach accept */ -static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT ACK"); - struct gsm48_hdr *gh; - struct gsm48_attach_ack *aa; - uint8_t *mid; -#if 0 - uint8_t *ptsig; -#endif - - LOGMMCTXP(LOGL_INFO, mm, "<- GPRS ATTACH ACCEPT (new P-TMSI=0x%08x)\n", mm->p_tmsi); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ATTACH_ACKED]); - - mmctx2msgid(msg, mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_ATTACH_ACK; - - aa = (struct gsm48_attach_ack *) msgb_put(msg, sizeof(*aa)); - aa->force_stby = 0; /* not indicated */ - aa->att_result = 1; /* GPRS only */ - aa->ra_upd_timer = gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3312); - aa->radio_prio = 4; /* lowest */ - gsm48_construct_ra(aa->ra_id.digits, &mm->ra); - -#if 0 - /* Optional: P-TMSI signature */ - msgb_v_put(msg, GSM48_IE_GMM_PTMSI_SIG); - ptsig = msgb_put(msg, 3); - ptsig[0] = mm->p_tmsi_sig >> 16; - ptsig[1] = mm->p_tmsi_sig >> 8; - ptsig[2] = mm->p_tmsi_sig & 0xff; - -#endif - /* Optional: Negotiated Ready timer value - * (fixed 44s, default value, GSM 04.08, table 11.4a) to safely limit - * the inactivity time READY->STANDBY. - */ - msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY, - gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3314)); - -#ifdef PTMSI_ALLOC - /* Optional: Allocated P-TMSI */ - mid = msgb_put(msg, GSM48_MID_TMSI_LEN); - gsm48_generate_mid_from_tmsi(mid, mm->p_tmsi); - mid[0] = GSM48_IE_GMM_ALLOC_PTMSI; -#endif - - /* Optional: MS-identity (combined attach) */ - /* Optional: GMM cause (partial attach result for combined attach) */ - - return gsm48_gmm_sendmsg(msg, 0, mm, true); -} - -/* Chapter 9.4.5: Attach reject */ -static int _tx_gmm_att_rej(struct msgb *msg, uint8_t gmm_cause, - const struct sgsn_mm_ctx *mm) -{ - struct gsm48_hdr *gh; - - LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS ATTACH REJECT: %s\n", - get_value_string(gsm48_gmm_cause_names, gmm_cause)); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ATTACH_REJECTED]); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_ATTACH_REJ; - gh->data[0] = gmm_cause; - - return gsm48_gmm_sendmsg(msg, 0, NULL, false); -} -static int gsm48_tx_gmm_att_rej_oldmsg(const struct msgb *old_msg, - uint8_t gmm_cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT REJ OLD"); - gmm_copy_id(msg, old_msg); - return _tx_gmm_att_rej(msg, gmm_cause, NULL); -} -static int gsm48_tx_gmm_att_rej(struct sgsn_mm_ctx *mm, - uint8_t gmm_cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT REJ"); - mmctx2msgid(msg, mm); - return _tx_gmm_att_rej(msg, gmm_cause, mm); -} - -/* Chapter 9.4.6.2 Detach accept */ -static int _tx_detach_ack(struct msgb *msg, uint8_t force_stby, - struct sgsn_mm_ctx *mm) -{ - struct gsm48_hdr *gh; - - /* MMCTX might be NULL! */ - - DEBUGP(DMM, "<- GPRS MM DETACH ACC (force-standby: %d)\n", force_stby); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_DETACH_ACKED]); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_DETACH_ACK; - gh->data[0] = force_stby; - - return gsm48_gmm_sendmsg(msg, 0, mm, true); -} - -static int gsm48_tx_gmm_det_ack(struct sgsn_mm_ctx *mm, uint8_t force_stby) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACK"); - - mmctx2msgid(msg, mm); - return _tx_detach_ack(msg, force_stby, mm); -} - -static int gsm48_tx_gmm_det_ack_oldmsg(struct msgb *oldmsg, uint8_t force_stby) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACK OLD"); - - gmm_copy_id(msg, oldmsg); - return _tx_detach_ack(msg, force_stby, NULL); -} - -/* Transmit Chapter 9.4.12 Identity Request */ -static int gsm48_tx_gmm_id_req(struct sgsn_mm_ctx *mm, uint8_t id_type) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ"); - struct gsm48_hdr *gh; - - LOGMMCTXP(LOGL_DEBUG, mm, "<- GPRS IDENTITY REQUEST: mi_type=%s\n", - gsm48_mi_type_name(id_type)); - - mmctx2msgid(msg, mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_ID_REQ; - /* 10.5.5.9 ID type 2 + identity type and 10.5.5.7 'force to standby' IE */ - gh->data[0] = id_type & 0xf; - - return gsm48_gmm_sendmsg(msg, 1, mm, false); -} - -/* determine if the MS/UE supports R99 or later */ -static bool mmctx_is_r99(const struct sgsn_mm_ctx *mm) -{ - if (mm->ms_network_capa.len < 1) - return false; - if (mm->ms_network_capa.buf[0] & 0x01) - return true; - return false; -} - -/* 3GPP TS 24.008 Section 9.4.9: Authentication and Ciphering Request */ -static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm, - const struct osmo_auth_vector *vec, - uint8_t key_seq, bool force_standby) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH CIPH REQ"); - struct gsm48_hdr *gh; - struct gsm48_auth_ciph_req *acreq; - uint8_t *m_rand, *m_cksn, rbyte; - - LOGMMCTXP(LOGL_INFO, mm, "<- GPRS AUTH AND CIPHERING REQ (rand = %s", - osmo_hexdump(vec->rand, sizeof(vec->rand))); - if (mmctx_is_r99(mm) && vec - && (vec->auth_types & OSMO_AUTH_TYPE_UMTS)) { - LOGPC(DMM, LOGL_INFO, ", autn = %s)\n", - osmo_hexdump(vec->autn, sizeof(vec->autn))); - } else - LOGPC(DMM, LOGL_INFO, ")\n"); - - mmctx2msgid(msg, mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_AUTH_CIPH_REQ; - - acreq = (struct gsm48_auth_ciph_req *) msgb_put(msg, sizeof(*acreq)); - acreq->ciph_alg = mm->ciph_algo & 0xf; - /* § 10.5.5.10: */ - acreq->imeisv_req = 0x1; - /* § 10.5.5.7: */ - acreq->force_stby = force_standby; - /* 3GPP TS 24.008 § 10.5.5.19: */ - if (RAND_bytes(&rbyte, 1) != 1) { - LOGP(DMM, LOGL_NOTICE, "RAND_bytes failed for A&C ref, falling " - "back to rand()\n"); - acreq->ac_ref_nr = rand(); - } else - acreq->ac_ref_nr = rbyte; - mm->ac_ref_nr_used = acreq->ac_ref_nr; - - /* Only if authentication is requested we need to set RAND + CKSN */ - if (vec) { - m_rand = msgb_put(msg, sizeof(vec->rand) + 1); - m_rand[0] = GSM48_IE_GMM_AUTH_RAND; - memcpy(m_rand + 1, vec->rand, sizeof(vec->rand)); - - /* § 10.5.1.2: */ - m_cksn = msgb_put(msg, 1); - m_cksn[0] = (GSM48_IE_GMM_CIPH_CKSN << 4) | (key_seq & 0x07); - - /* A Release99 or higher MS/UE must be able to handle - * the optional AUTN IE. If a classic GSM SIM is - * inserted, it will simply ignore AUTN and just use - * RAND */ - if (mmctx_is_r99(mm) && - (vec->auth_types & OSMO_AUTH_TYPE_UMTS)) { - msgb_tlv_put(msg, GSM48_IE_GMM_AUTN, - sizeof(vec->autn), vec->autn); - } - } - - return gsm48_gmm_sendmsg(msg, 1, mm, false); -} - -/* Section 9.4.11: Authentication and Ciphering Reject */ -static int gsm48_tx_gmm_auth_ciph_rej(struct sgsn_mm_ctx *mm) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH CIPH REJ"); - struct gsm48_hdr *gh; - - LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS AUTH AND CIPH REJECT\n"); - - mmctx2msgid(msg, mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_AUTH_CIPH_REJ; - - return gsm48_gmm_sendmsg(msg, 0, mm, false); -} - -/* check if the received authentication response matches */ -static bool check_auth_resp(struct sgsn_mm_ctx *ctx, - bool is_utran, - const struct osmo_auth_vector *vec, - const uint8_t *res, uint8_t res_len) -{ - const uint8_t *expect_res; - uint8_t expect_res_len; - enum osmo_sub_auth_type expect_type; - const char *expect_str; - - if (!vec) - return true; /* really!? */ - - /* On UTRAN (3G) we always expect UMTS AKA. On GERAN (2G) we sent AUTN - * and expect UMTS AKA if there is R99 capability and our vector - * supports UMTS AKA, otherwise we expect GSM AKA. */ - if (is_utran - || (mmctx_is_r99(ctx) && (vec->auth_types & OSMO_AUTH_TYPE_UMTS))) { - expect_type = OSMO_AUTH_TYPE_UMTS; - expect_str = "UMTS RES"; - expect_res = vec->res; - expect_res_len = vec->res_len; - } else { - expect_type = OSMO_AUTH_TYPE_GSM; - expect_str = "GSM SRES"; - expect_res = vec->sres; - expect_res_len = sizeof(vec->sres); - } - - if (!(vec->auth_types & expect_type)) { - LOGMMCTXP(LOGL_ERROR, ctx, "Auth error: auth vector does" - " not provide the expected auth type:" - " expected %s = 0x%x, auth_types are 0x%x\n", - expect_str, expect_type, vec->auth_types); - return false; - } - - if (!res) - goto auth_mismatch; - - if (res_len != expect_res_len) - goto auth_mismatch; - - if (memcmp(res, expect_res, res_len) != 0) - goto auth_mismatch; - - /* Authorized! */ - return true; - -auth_mismatch: - LOGMMCTXP(LOGL_ERROR, ctx, "Auth mismatch: expected %s = %s\n", - expect_str, osmo_hexdump_nospc(expect_res, expect_res_len)); - return false; -} - -/* Section 9.4.10: Authentication and Ciphering Response */ -static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx, - struct msgb *msg) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - struct gsm48_auth_ciph_resp *acr = (struct gsm48_auth_ciph_resp *)gh->data; - struct tlv_parsed tp; - struct gsm_auth_tuple *at; - const char *res_name = "(no response)"; - uint8_t res[16]; - uint8_t res_len; - int rc; - - LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS AUTH AND CIPH RESPONSE\n"); - - if (ctx->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) { - LOGMMCTXP(LOGL_NOTICE, ctx, - "Unexpected Auth & Ciph Response (ignored)\n"); - return 0; - } - - if (acr->ac_ref_nr != ctx->ac_ref_nr_used) { - LOGMMCTXP(LOGL_NOTICE, ctx, "Reference mismatch for Auth & Ciph" - " Response: %u received, %u expected\n", - acr->ac_ref_nr, ctx->ac_ref_nr_used); - return 0; - } - - /* Stop T3360 */ - mmctx_timer_stop(ctx, 3360); - - tlv_parse(&tp, &gsm48_gmm_att_tlvdef, acr->data, - (msg->data + msg->len) - acr->data, 0, 0); - - if (!TLVP_PRESENT(&tp, GSM48_IE_GMM_AUTH_SRES) || - !TLVP_PRESENT(&tp, GSM48_IE_GMM_IMEISV) || - TLVP_LEN(&tp,GSM48_IE_GMM_AUTH_SRES) != 4) { - /* TODO: missing mandatory IE, return STATUS or REJ? */ - LOGMMCTXP(LOGL_ERROR, ctx, "Missing mandantory IE\n"); - return -EINVAL; - } - - /* Start with the good old 4-byte SRES */ - memcpy(res, TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), 4); - res_len = 4; - res_name = "GSM SRES"; - - /* Append extended RES as part of UMTS AKA, if any */ - if (TLVP_PRESENT(&tp, GSM48_IE_GMM_AUTH_RES_EXT)) { - unsigned int l = TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_RES_EXT); - if (l > sizeof(res)-4) - l = sizeof(res)-4; - memcpy(res+4, TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_RES_EXT), l); - res_len += l; - res_name = "UMTS RES"; - } - - at = &ctx->auth_triplet; - - LOGMMCTXP(LOGL_DEBUG, ctx, "checking auth: received %s = %s\n", - res_name, osmo_hexdump(res, res_len)); - rc = check_auth_resp(ctx, false, &at->vec, res, res_len); - if (!rc) { - rc = gsm48_tx_gmm_auth_ciph_rej(ctx); - mm_ctx_cleanup_free(ctx, "GPRS AUTH AND CIPH REJECT"); - return rc; - } - - ctx->is_authenticated = 1; - - if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) - ctx->iu.new_key = 1; - - /* FIXME: enable LLC cipheirng */ - - /* Check if we can let the mobile station enter */ - return gsm48_gmm_authorize(ctx); -} - -/* Section 9.4.10: Authentication and Ciphering Failure */ -static int gsm48_rx_gmm_auth_ciph_fail(struct sgsn_mm_ctx *ctx, - struct msgb *msg) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - struct tlv_parsed tp; - const uint8_t gmm_cause = gh->data[0]; - const uint8_t *auts; - int rc; - - LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS AUTH AND CIPH FAILURE (cause = %s)\n", - get_value_string(gsm48_gmm_cause_names, gmm_cause)); - - tlv_parse(&tp, &gsm48_gmm_att_tlvdef, gh->data+1, msg->len - 1, 0, 0); - - /* Only if GMM cause is present and the AUTS is provided, we can - * start re-sync procedure */ - if (gmm_cause == GMM_CAUSE_SYNC_FAIL && - TLVP_PRESENT(&tp, GSM48_IE_GMM_AUTH_FAIL_PAR)) { - if (TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_FAIL_PAR) != 14) { - LOGMMCTXP(LOGL_ERROR, ctx, "AUTS IE has wrong size:" - " expected %d, got %u\n", 14, - TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_FAIL_PAR)); - return -EINVAL; - } - auts = TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_FAIL_PAR); - - LOGMMCTXP(LOGL_INFO, ctx, - "R99 AUTHENTICATION SYNCH (AUTS = %s)\n", - osmo_hexdump_nospc(auts, 14)); - - /* make sure we'll refresh the auth_triplet in - * sgsn_auth_update() */ - ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL; - - /* make sure we'll retry authentication after the resync */ - ctx->auth_state = SGSN_AUTH_UMTS_RESYNC; - - /* Send AUTS to HLR and wait for new Auth Info Result */ - rc = gprs_subscr_request_auth_info(ctx, auts, - ctx->auth_triplet.vec.rand); - if (!rc) - return 0; - /* on error, fall through to send a reject */ - LOGMMCTXP(LOGL_ERROR, ctx, - "Sending AUTS to HLR failed (rc = %d)\n", rc); - } - - LOGMMCTXP(LOGL_NOTICE, ctx, "Authentication failed\n"); - rc = gsm48_tx_gmm_auth_ciph_rej(ctx); - mm_ctx_cleanup_free(ctx, "GPRS AUTH FAILURE"); - return rc; -} - -static void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx) -{ - struct gsm_mncc_number called; - uint8_t msisdn[sizeof(ctx->subscr->sgsn_data->msisdn) + 1]; - - /* Convert MSISDN from encoded to string.. */ - if (!ctx->subscr) - return; - - if (ctx->subscr->sgsn_data->msisdn_len < 1) - return; - - /* prepare the data for the decoder */ - memset(&called, 0, sizeof(called)); - msisdn[0] = ctx->subscr->sgsn_data->msisdn_len; - memcpy(&msisdn[1], ctx->subscr->sgsn_data->msisdn, - ctx->subscr->sgsn_data->msisdn_len); - - /* decode the string now */ - gsm48_decode_called(&called, msisdn); - - /* Prepend a '+' for international numbers */ - if (called.plan == 1 && called.type == 1) { - ctx->msisdn[0] = '+'; - osmo_strlcpy(&ctx->msisdn[1], called.number, - sizeof(ctx->msisdn)); - } else { - osmo_strlcpy(ctx->msisdn, called.number, sizeof(ctx->msisdn)); - } -} - -static void extract_subscr_hlr(struct sgsn_mm_ctx *ctx) -{ - struct gsm_mncc_number called; - uint8_t hlr_number[sizeof(ctx->subscr->sgsn_data->hlr) + 1]; - - if (!ctx->subscr) - return; - - if (ctx->subscr->sgsn_data->hlr_len < 1) - return; - - /* prepare the data for the decoder */ - memset(&called, 0, sizeof(called)); - hlr_number[0] = ctx->subscr->sgsn_data->hlr_len; - memcpy(&hlr_number[1], ctx->subscr->sgsn_data->hlr, - ctx->subscr->sgsn_data->hlr_len); - - /* decode the string now */ - gsm48_decode_called(&called, hlr_number); - - if (called.plan != 1) { - LOGMMCTXP(LOGL_ERROR, ctx, - "Numbering plan(%d) not allowed\n", - called.plan); - return; - } - - if (called.type != 1) { - LOGMMCTXP(LOGL_ERROR, ctx, - "Numbering type(%d) not allowed\n", - called.type); - return; - } - - osmo_strlcpy(ctx->hlr, called.number, sizeof(ctx->hlr)); -} - -#ifdef BUILD_IU -/* Chapter 9.4.21: Service accept */ -static int gsm48_tx_gmm_service_ack(struct sgsn_mm_ctx *mm) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE ACK"); - struct gsm48_hdr *gh; - - LOGMMCTXP(LOGL_INFO, mm, "<- GPRS SERVICE ACCEPT (P-TMSI=0x%08x)\n", mm->p_tmsi); - - mmctx2msgid(msg, mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_SERVICE_ACK; - - /* Optional: PDP context status */ - /* Optional: MBMS context status */ - - return gsm48_gmm_sendmsg(msg, 0, mm, false); -} -#endif - -/* Chapter 9.4.22: Service reject */ -static int _tx_gmm_service_rej(struct msgb *msg, uint8_t gmm_cause, - const struct sgsn_mm_ctx *mm) -{ - struct gsm48_hdr *gh; - - LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS SERVICE REJECT: %s\n", - get_value_string(gsm48_gmm_cause_names, gmm_cause)); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_SERVICE_REJ; - gh->data[0] = gmm_cause; - - return gsm48_gmm_sendmsg(msg, 0, NULL, true); -} -static int gsm48_tx_gmm_service_rej_oldmsg(const struct msgb *old_msg, - uint8_t gmm_cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ OLD"); - gmm_copy_id(msg, old_msg); - return _tx_gmm_service_rej(msg, gmm_cause, NULL); -} -#if 0 --- currently unused -- -static int gsm48_tx_gmm_service_rej(struct sgsn_mm_ctx *mm, - uint8_t gmm_cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ"); - mmctx2msgid(msg, mm); - return _tx_gmm_service_rej(msg, gmm_cause, mm); -} -#endif - -static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm); - -#ifdef BUILD_IU -/* Send RAB activation requests for all PDP contexts */ -void activate_pdp_rabs(struct sgsn_mm_ctx *ctx) -{ - struct sgsn_pdp_ctx *pdp; - if (ctx->ran_type != MM_CTX_T_UTRAN_Iu) - return; - llist_for_each_entry(pdp, &ctx->pdp_list, list) { - iu_rab_act_ps(pdp->nsapi, pdp); - } -} -#endif - -/* Check if we can already authorize a subscriber */ -static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) -{ -#ifdef BUILD_IU - int rc; -#endif -#ifndef PTMSI_ALLOC - struct sgsn_signal_data sig_data; -#endif - - /* Request IMSI and IMEI from the MS if they are unknown */ - if (!strlen(ctx->imei)) { - ctx->t3370_id_type = GSM_MI_TYPE_IMEI; - mmctx_timer_start(ctx, 3370, sgsn->cfg.timers.T3370); - return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMEI); - } - if (!strlen(ctx->imsi)) { - ctx->t3370_id_type = GSM_MI_TYPE_IMSI; - mmctx_timer_start(ctx, 3370, sgsn->cfg.timers.T3370); - return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMSI); - } - - /* All information required for authentication is available */ - ctx->t3370_id_type = GSM_MI_TYPE_NONE; - - if (ctx->auth_state == SGSN_AUTH_UNKNOWN) { - /* Request authorization, this leads to a call to - * sgsn_auth_update which in turn calls - * gsm0408_gprs_access_granted or gsm0408_gprs_access_denied */ - - sgsn_auth_request(ctx); - /* Note that gsm48_gmm_authorize can be called recursively via - * sgsn_auth_request iff ctx->auth_info changes to AUTH_ACCEPTED - */ - return 0; - } - - if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && !ctx->is_authenticated) { - struct gsm_auth_tuple *at = &ctx->auth_triplet; - - mmctx_timer_start(ctx, 3360, sgsn->cfg.timers.T3360); - return gsm48_tx_gmm_auth_ciph_req(ctx, &at->vec, at->key_seq, - false); - } - - if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && ctx->is_authenticated && - ctx->auth_triplet.key_seq != GSM_KEY_SEQ_INVAL) { - /* Check again for authorization */ - sgsn_auth_request(ctx); - return 0; - } - - if (ctx->auth_state != SGSN_AUTH_ACCEPTED) { - LOGMMCTXP(LOGL_NOTICE, ctx, - "authorization is denied, aborting procedure\n"); - return -EACCES; - } - - /* The MS is authorized */ -#ifdef BUILD_IU - if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && !ctx->iu.ue_ctx->integrity_active) { - rc = ranap_iu_tx_sec_mode_cmd(ctx->iu.ue_ctx, &ctx->auth_triplet.vec, 0, ctx->iu.new_key); - ctx->iu.new_key = 0; - return rc; - } -#endif - - switch (ctx->pending_req) { - case 0: - LOGMMCTXP(LOGL_INFO, ctx, - "no pending request, authorization completed\n"); - break; - case GSM48_MT_GMM_ATTACH_REQ: - ctx->pending_req = 0; - - extract_subscr_msisdn(ctx); - extract_subscr_hlr(ctx); -#ifdef PTMSI_ALLOC - /* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */ - mmctx_timer_start(ctx, 3350, sgsn->cfg.timers.T3350); - ctx->t3350_mode = GMM_T3350_MODE_ATT; -#else - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.mm = mmctx; - osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data); - ctx->gmm_state = GMM_REGISTERED_NORMAL; -#endif - - return gsm48_tx_gmm_att_ack(ctx); -#ifdef BUILD_IU - case GSM48_MT_GMM_SERVICE_REQ: - ctx->pending_req = 0; - mmctx_set_pmm_state(ctx, PMM_CONNECTED); - rc = gsm48_tx_gmm_service_ack(ctx); - - if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING) - activate_pdp_rabs(ctx); - - return rc; -#endif - case GSM48_MT_GMM_RA_UPD_REQ: - ctx->pending_req = 0; - /* Send RA UPDATE ACCEPT */ - return gsm48_tx_gmm_ra_upd_ack(ctx); - - default: - LOGMMCTXP(LOGL_ERROR, ctx, - "only Attach Request is supported yet, " - "got request type %u\n", ctx->pending_req); - break; - } - - return 0; -} - -void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *ctx) -{ - ctx->is_authenticated = 0; - - gsm48_gmm_authorize(ctx); -} - -void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *ctx) -{ - switch (ctx->gmm_state) { - case GMM_COMMON_PROC_INIT: - LOGMMCTXP(LOGL_NOTICE, ctx, - "Authorized, continuing procedure, IMSI=%s\n", - ctx->imsi); - /* Continue with the authorization */ - gsm48_gmm_authorize(ctx); - break; - default: - LOGMMCTXP(LOGL_INFO, ctx, - "Authorized, ignored, IMSI=%s\n", - ctx->imsi); - } -} - -void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *ctx, int gmm_cause) -{ - if (gmm_cause == SGSN_ERROR_CAUSE_NONE) - gmm_cause = GMM_CAUSE_GPRS_NOTALLOWED; - - switch (ctx->gmm_state) { - case GMM_COMMON_PROC_INIT: - LOGMMCTXP(LOGL_NOTICE, ctx, - "Not authorized, rejecting ATTACH REQUEST " - "with cause '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gmm_cause), - gmm_cause); - gsm48_tx_gmm_att_rej(ctx, gmm_cause); - mm_ctx_cleanup_free(ctx, "GPRS ATTACH REJECT"); - break; - case GMM_REGISTERED_NORMAL: - case GMM_REGISTERED_SUSPENDED: - LOGMMCTXP(LOGL_NOTICE, ctx, - "Authorization lost, detaching " - "with cause '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gmm_cause), - gmm_cause); - gsm48_tx_gmm_detach_req( - ctx, GPRS_DET_T_MT_REATT_NOTREQ, gmm_cause); - - mm_ctx_cleanup_free(ctx, "auth lost"); - break; - default: - LOGMMCTXP(LOGL_INFO, ctx, - "Authorization lost, cause is '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gmm_cause), - gmm_cause); - mm_ctx_cleanup_free(ctx, "auth lost"); - } -} - -void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *ctx, int gmm_cause) -{ - if (gmm_cause != SGSN_ERROR_CAUSE_NONE) { - LOGMMCTXP(LOGL_INFO, ctx, - "Cancelled with cause '%s' (%d), deleting context\n", - get_value_string(gsm48_gmm_cause_names, gmm_cause), - gmm_cause); - gsm0408_gprs_access_denied(ctx, gmm_cause); - return; - } - - LOGMMCTXP(LOGL_INFO, ctx, "Cancelled, deleting context silently\n"); - mm_ctx_cleanup_free(ctx, "access cancelled"); -} - -/* Parse Chapter 9.4.13 Identity Response */ -static int gsm48_rx_gmm_id_resp(struct sgsn_mm_ctx *ctx, struct msgb *msg) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK; - char mi_string[GSM48_MI_SIZE]; - - gsm48_mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]); - if (!ctx) { - DEBUGP(DMM, "from unknown TLLI 0x%08x?!? This should not happen\n", msgb_tlli(msg)); - return -EINVAL; - } - - LOGMMCTXP(LOGL_DEBUG, ctx, "-> GMM IDENTITY RESPONSE: MI(%s)=%s\n", - gsm48_mi_type_name(mi_type), mi_string); - - if (ctx->t3370_id_type == GSM_MI_TYPE_NONE) { - LOGMMCTXP(LOGL_NOTICE, ctx, - "Got unexpected IDENTITY RESPONSE: MI(%s)=%s, " - "ignoring message\n", - gsm48_mi_type_name(mi_type), mi_string); - return -EINVAL; - } - - if (mi_type == ctx->t3370_id_type) - mmctx_timer_stop(ctx, 3370); - - switch (mi_type) { - case GSM_MI_TYPE_IMSI: - /* we already have a mm context with current TLLI, but no - * P-TMSI / IMSI yet. What we now need to do is to fill - * this initial context with data from the HLR */ - if (strlen(ctx->imsi) == 0) { - /* Check if we already have a MM context for this IMSI */ - struct sgsn_mm_ctx *ictx; - ictx = sgsn_mm_ctx_by_imsi(mi_string); - if (ictx) { - /* Handle it like in gsm48_rx_gmm_det_req, - * except that no messages are sent to the BSS */ - - LOGMMCTXP(LOGL_NOTICE, ctx, "Deleting old MM Context for same IMSI " - "p_tmsi_old=0x%08x\n", - ictx->p_tmsi); - - mm_ctx_cleanup_free(ictx, "GPRS IMSI re-use"); - } - } - osmo_strlcpy(ctx->imsi, mi_string, sizeof(ctx->imsi)); - break; - case GSM_MI_TYPE_IMEI: - osmo_strlcpy(ctx->imei, mi_string, sizeof(ctx->imei)); - break; - case GSM_MI_TYPE_IMEISV: - break; - } - - /* Check if we can let the mobile station enter */ - return gsm48_gmm_authorize(ctx); -} - -/* Section 9.4.1 Attach request */ -static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg, - struct gprs_llc_llme *llme) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t *cur = gh->data, *msnc, *mi, *ms_ra_acc_cap; - uint8_t msnc_len, att_type, mi_len, mi_type, ms_ra_acc_cap_len; - uint16_t drx_par; - uint32_t tmsi; - char mi_string[GSM48_MI_SIZE]; - struct gprs_ra_id ra_id; - uint16_t cid = 0; - enum gsm48_gmm_cause reject_cause; - int rc; - - LOGMMCTXP(LOGL_INFO, ctx, "-> GMM ATTACH REQUEST "); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ATTACH_REQUEST]); - - /* As per TS 04.08 Chapter 4.7.1.4, the attach request arrives either - * with a foreign TLLI (P-TMSI that was allocated to the MS before), - * or with random TLLI. */ - - /* In Iu mode, msg->dst contains the ranap_ue_conn_ctx pointer, in Gb mode - * dst is empty. */ - /* FIXME: have a more explicit indicator for Iu messages */ - if (!msg->dst) { - /* Gb mode */ - cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg)); - } else { -#ifdef BUILD_IU - ra_id = ((struct ranap_ue_conn_ctx*)msg->dst)->ra_id; -#else - LOGMMCTXP(LOGL_ERROR, ctx, "Cannot handle Iu Attach Request, built without Iu support\n"); - return -ENOTSUP; -#endif - } - - /* MS network capability 10.5.5.12 */ - msnc_len = *cur++; - msnc = cur; - if (msnc_len > sizeof(ctx->ms_network_capa.buf)) - goto err_inval; - cur += msnc_len; - - /* TODO: In iu mode - handle follow-on request */ - - /* aTTACH Type 10.5.5.2 */ - att_type = *cur++ & 0x07; - - /* DRX parameter 10.5.5.6 */ - drx_par = *cur++ << 8; - drx_par |= *cur++; - - /* Mobile Identity (P-TMSI or IMSI) 10.5.1.4 */ - mi_len = *cur++; - mi = cur; - if (mi_len > 8) - goto err_inval; - mi_type = *mi & GSM_MI_TYPE_MASK; - cur += mi_len; - - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); - - DEBUGPC(DMM, "MI(%s) type=\"%s\" ", mi_string, - get_value_string(gprs_att_t_strs, att_type)); - - /* Old routing area identification 10.5.5.15. Skip it */ - cur += 6; - - /* MS Radio Access Capability 10.5.5.12a */ - ms_ra_acc_cap_len = *cur++; - ms_ra_acc_cap = cur; - if (ms_ra_acc_cap_len > sizeof(ctx->ms_radio_access_capa.buf)) - goto err_inval; - cur += ms_ra_acc_cap_len; - - LOGPC(DMM, LOGL_INFO, "\n"); - - /* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status */ - - switch (mi_type) { - case GSM_MI_TYPE_IMSI: - /* Try to find MM context based on IMSI */ - if (!ctx) - ctx = sgsn_mm_ctx_by_imsi(mi_string); - if (!ctx) { -#if 0 - return gsm48_tx_gmm_att_rej(msg, GMM_CAUSE_IMSI_UNKNOWN); -#else - if (msg->dst) - ctx = sgsn_mm_ctx_alloc_iu(msg->dst); - else - ctx = sgsn_mm_ctx_alloc_gb(0, &ra_id); - if (!ctx) { - reject_cause = GMM_CAUSE_NET_FAIL; - goto rejected; - } - osmo_strlcpy(ctx->imsi, mi_string, sizeof(ctx->imsi)); -#endif - } - if (ctx->ran_type == MM_CTX_T_GERAN_Gb) { - ctx->gb.tlli = msgb_tlli(msg); - ctx->gb.llme = llme; - } - msgid2mmctx(ctx, msg); - break; - case GSM_MI_TYPE_TMSI: - memcpy(&tmsi, mi+1, 4); - tmsi = ntohl(tmsi); - /* Try to find MM context based on P-TMSI */ - if (!ctx) - ctx = sgsn_mm_ctx_by_ptmsi(tmsi); - if (!ctx) { - /* Allocate a context as most of our code expects one. - * Context will not have an IMSI ultil ID RESP is received */ - if (msg->dst) - ctx = sgsn_mm_ctx_alloc_iu(msg->dst); - else - ctx = sgsn_mm_ctx_alloc_gb(msgb_tlli(msg), &ra_id); - ctx->p_tmsi = tmsi; - } - if (ctx->ran_type == MM_CTX_T_GERAN_Gb) { - ctx->gb.tlli = msgb_tlli(msg); - ctx->gb.llme = llme; - } - msgid2mmctx(ctx, msg); - break; - default: - LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting ATTACH REQUEST with " - "MI type %s\n", gsm48_mi_type_name(mi_type)); - reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED; - goto rejected; - } - /* Update MM Context with currient RA and Cell ID */ - ctx->ra = ra_id; - if (ctx->ran_type == MM_CTX_T_GERAN_Gb) - ctx->gb.cell_id = cid; - - /* Update MM Context with other data */ - ctx->drx_parms = drx_par; - ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len; - memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap, - ctx->ms_radio_access_capa.len); - ctx->ms_network_capa.len = msnc_len; - memcpy(ctx->ms_network_capa.buf, msnc, msnc_len); - if (!gprs_ms_net_cap_gea_supported(ctx->ms_network_capa.buf, msnc_len, - ctx->ciph_algo)) { - reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC; - LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting ATTACH REQUEST with MI " - "type %s because MS do not support required %s " - "encryption\n", gsm48_mi_type_name(mi_type), - get_value_string(gprs_cipher_names,ctx->ciph_algo)); - goto rejected; - } -#ifdef PTMSI_ALLOC - /* Allocate a new P-TMSI (+ P-TMSI signature) and update TLLI */ - /* Don't change the P-TMSI if a P-TMSI re-assignment is under way */ - if (ctx->gmm_state != GMM_COMMON_PROC_INIT) { - ctx->p_tmsi_old = ctx->p_tmsi; - ctx->p_tmsi = sgsn_alloc_ptmsi(); - } - ctx->gmm_state = GMM_COMMON_PROC_INIT; -#endif - - if (ctx->ran_type == MM_CTX_T_GERAN_Gb) { - /* Even if there is no P-TMSI allocated, the MS will - * switch from foreign TLLI to local TLLI */ - ctx->gb.tlli_new = gprs_tmsi2tlli(ctx->p_tmsi, TLLI_LOCAL); - - /* Inform LLC layer about new TLLI but keep old active */ - if (ctx->is_authenticated) - gprs_llme_copy_key(ctx, ctx->gb.llme); - - gprs_llgmm_assign(ctx->gb.llme, ctx->gb.tlli, ctx->gb.tlli_new); - } - - ctx->pending_req = GSM48_MT_GMM_ATTACH_REQ; - return gsm48_gmm_authorize(ctx); - -err_inval: - LOGPC(DMM, LOGL_INFO, "\n"); - reject_cause = GMM_CAUSE_SEM_INCORR_MSG; - -rejected: - /* Send ATTACH REJECT */ - LOGMMCTXP(LOGL_NOTICE, ctx, - "Rejecting Attach Request with cause '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, reject_cause), reject_cause); - rc = gsm48_tx_gmm_att_rej_oldmsg(msg, reject_cause); - if (ctx) - mm_ctx_cleanup_free(ctx, "GPRS ATTACH REJ"); - else - gprs_llgmm_unassign(llme); - - return rc; - -} - -/* Section 4.7.4.1 / 9.4.5.2 MO Detach request */ -static int gsm48_rx_gmm_det_req(struct sgsn_mm_ctx *ctx, struct msgb *msg) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t detach_type, power_off; - int rc = 0; - - detach_type = gh->data[0] & 0x7; - power_off = gh->data[0] & 0x8; - - /* FIXME: In 24.008 there is an optional P-TMSI and P-TMSI signature IE */ - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_DETACH_REQUEST]); - LOGMMCTXP(LOGL_INFO, ctx, "-> GMM DETACH REQUEST TLLI=0x%08x type=%s %s\n", - msgb_tlli(msg), get_value_string(gprs_det_t_mo_strs, detach_type), - power_off ? "Power-off" : ""); - - /* Only send the Detach Accept (MO) if power off isn't indicated, - * see 04.08, 4.7.4.1.2/3 for details */ - if (!power_off) { - /* force_stby = 0 */ - if (ctx) - rc = gsm48_tx_gmm_det_ack(ctx, 0); - else - rc = gsm48_tx_gmm_det_ack_oldmsg(msg, 0); - } - - if (ctx) { - struct sgsn_signal_data sig_data; - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.mm = ctx; - osmo_signal_dispatch(SS_SGSN, S_SGSN_DETACH, &sig_data); - mm_ctx_cleanup_free(ctx, "GPRS DETACH REQUEST"); - } - - return rc; -} - -/* Chapter 9.4.15: Routing area update accept */ -static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 UPD ACK"); - struct gsm48_hdr *gh; - struct gsm48_ra_upd_ack *rua; - uint8_t *mid; - - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_ACKED]); - LOGMMCTXP(LOGL_INFO, mm, "<- ROUTING AREA UPDATE ACCEPT\n"); - - mmctx2msgid(msg, mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_RA_UPD_ACK; - - rua = (struct gsm48_ra_upd_ack *) msgb_put(msg, sizeof(*rua)); - rua->force_stby = 0; /* not indicated */ - rua->upd_result = 0; /* RA updated */ - rua->ra_upd_timer = gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3312); - - gsm48_construct_ra(rua->ra_id.digits, &mm->ra); - -#if 0 - /* Optional: P-TMSI signature */ - msgb_v_put(msg, GSM48_IE_GMM_PTMSI_SIG); - ptsig = msgb_put(msg, 3); - ptsig[0] = mm->p_tmsi_sig >> 16; - ptsig[1] = mm->p_tmsi_sig >> 8; - ptsig[2] = mm->p_tmsi_sig & 0xff; -#endif - -#ifdef PTMSI_ALLOC - /* Optional: Allocated P-TMSI */ - mid = msgb_put(msg, GSM48_MID_TMSI_LEN); - gsm48_generate_mid_from_tmsi(mid, mm->p_tmsi); - mid[0] = GSM48_IE_GMM_ALLOC_PTMSI; -#endif - - /* Optional: Negotiated READY timer value */ - msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY, - gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3314)); - - /* Option: MS ID, ... */ - return gsm48_gmm_sendmsg(msg, 0, mm, true); -} - -/* Chapter 9.4.17: Routing area update reject */ -static int gsm48_tx_gmm_ra_upd_rej(struct msgb *old_msg, uint8_t cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RA UPD REJ"); - struct gsm48_hdr *gh; - - LOGP(DMM, LOGL_NOTICE, "<- ROUTING AREA UPDATE REJECT\n"); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_REJECT]); - - gmm_copy_id(msg, old_msg); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 2); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_RA_UPD_REJ; - gh->data[0] = cause; - gh->data[1] = 0; /* ? */ - - /* Option: P-TMSI signature, allocated P-TMSI, MS ID, ... */ - return gsm48_gmm_sendmsg(msg, 0, NULL, false); -} - -static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx, - const uint8_t *pdp_status) -{ - struct sgsn_pdp_ctx *pdp, *pdp2; - /* 24.008 4.7.5.1.3: If the PDP context status information element is - * included in ROUTING AREA UPDATE REQUEST message, then the network - * shall deactivate all those PDP contexts locally (without peer to - * peer signalling between the MS and the network), which are not in SM - * state PDP-INACTIVE on network side but are indicated by the MS as - * being in state PDP-INACTIVE. */ - - llist_for_each_entry_safe(pdp, pdp2, &mmctx->pdp_list, list) { - if (pdp->nsapi < 8) { - if (!(pdp_status[0] & (1 << pdp->nsapi))) { - LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping PDP context for NSAPI=%u " - "due to PDP CTX STATUS IE= 0x%02x%02x\n", - pdp->nsapi, pdp_status[1], pdp_status[0]); - sgsn_delete_pdp_ctx(pdp); - } - } else { - if (!(pdp_status[1] & (1 << (pdp->nsapi - 8)))) { - LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping PDP context for NSAPI=%u " - "due to PDP CTX STATUS IE= 0x%02x%02x\n", - pdp->nsapi, pdp_status[1], pdp_status[0]); - sgsn_delete_pdp_ctx(pdp); - } - } - } -} - -/* Chapter 9.4.14: Routing area update request */ -static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, - struct gprs_llc_llme *llme) -{ -#ifndef PTMSI_ALLOC - struct sgsn_signal_data sig_data; -#endif - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t *cur = gh->data; - uint8_t ms_ra_acc_cap_len; - struct gprs_ra_id old_ra_id; - struct tlv_parsed tp; - uint8_t upd_type; - enum gsm48_gmm_cause reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC; - int rc; - - /* TODO: In iu mode - handle follow-on request */ - - /* Update Type 10.5.5.18 */ - upd_type = *cur++ & 0x07; - - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_REQUEST]); - LOGP(DMM, LOGL_INFO, "-> GMM RA UPDATE REQUEST type=\"%s\"\n", - get_value_string(gprs_upd_t_strs, upd_type)); - - /* Old routing area identification 10.5.5.15 */ - gsm48_parse_ra(&old_ra_id, cur); - cur += 6; - - /* MS Radio Access Capability 10.5.5.12a */ - ms_ra_acc_cap_len = *cur++; - if (ms_ra_acc_cap_len > 52) { - reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC; - goto rejected; - } - cur += ms_ra_acc_cap_len; - - /* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status, - * DRX parameter, MS network capability */ - tlv_parse(&tp, &gsm48_gmm_att_tlvdef, cur, - (msg->data + msg->len) - cur, 0, 0); - - switch (upd_type) { - case GPRS_UPD_T_RA_LA: - case GPRS_UPD_T_RA_LA_IMSI_ATT: - LOGP(DMM, LOGL_NOTICE, "Update type %i unsupported in Mode III, is your SI13 corrupt?\n", upd_type); - reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC; - goto rejected; - case GPRS_UPD_T_RA: - case GPRS_UPD_T_PERIODIC: - break; - } - - if (!mmctx) { - /* BSSGP doesn't give us an mmctx */ - - /* TODO: Check if there is an MM CTX with old_ra_id and - * the P-TMSI (if given, reguired for UMTS) or as last resort - * if the TLLI matches foreign_tlli (P-TMSI). Note that this - * is an optimization to avoid the RA reject (impl detached) - * below, which will cause a new attach cycle. */ - /* Look-up the MM context based on old RA-ID and TLLI */ - /* In Iu mode, msg->dst contains the ranap_ue_conn_ctx pointer, in Gb - * mode dst is empty. */ - /* FIXME: have a more explicit indicator for Iu messages */ - if (!msg->dst) { - mmctx = sgsn_mm_ctx_by_tlli_and_ptmsi(msgb_tlli(msg), &old_ra_id); - } else if (TLVP_PRESENT(&tp, GSM48_IE_GMM_ALLOC_PTMSI)) { -#ifdef BUILD_IU - /* In Iu mode search only for ptmsi */ - char mi_string[GSM48_MI_SIZE]; - uint8_t mi_len = TLVP_LEN(&tp, GSM48_IE_GMM_ALLOC_PTMSI); - uint8_t *mi = TLVP_VAL(&tp, GSM48_IE_GMM_ALLOC_PTMSI); - uint8_t mi_type = *mi & GSM_MI_TYPE_MASK; - uint32_t tmsi; - - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); - - if (mi_type == GSM_MI_TYPE_TMSI) { - memcpy(&tmsi, mi+1, 4); - tmsi = ntohl(tmsi); - mmctx = sgsn_mm_ctx_by_ptmsi(tmsi); - } -#else - goto rejected; -#endif - } - if (mmctx) { - LOGMMCTXP(LOGL_INFO, mmctx, - "Looked up by matching TLLI and P_TMSI. " - "BSSGP TLLI: %08x, P-TMSI: %08x (%08x), " - "TLLI: %08x (%08x), RA: %d-%d-%d-%d\n", - msgb_tlli(msg), - mmctx->p_tmsi, mmctx->p_tmsi_old, - mmctx->gb.tlli, mmctx->gb.tlli_new, - mmctx->ra.mcc, mmctx->ra.mnc, - mmctx->ra.lac, mmctx->ra.rac); - - mmctx->gmm_state = GMM_COMMON_PROC_INIT; - } - } else if (!gprs_ra_id_equals(&mmctx->ra, &old_ra_id) || - mmctx->gmm_state == GMM_DEREGISTERED) - { - /* We cannot use the mmctx */ - LOGMMCTXP(LOGL_INFO, mmctx, - "The MM context cannot be used, RA: %d-%d-%d-%d\n", - mmctx->ra.mcc, mmctx->ra.mnc, - mmctx->ra.lac, mmctx->ra.rac); - mmctx = NULL; - } - - if (!mmctx) { - if (llme) { - /* send a XID reset to re-set all LLC sequence numbers - * in the MS */ - LOGMMCTXP(LOGL_NOTICE, mmctx, "LLC XID RESET\n"); - gprs_llgmm_reset(llme); - } - /* The MS has to perform GPRS attach */ - /* Device is still IMSI attached for CS but initiate GPRS ATTACH, - * see GSM 04.08, 4.7.5.1.4 and G.6 */ - reject_cause = GMM_CAUSE_IMPL_DETACHED; - goto rejected; - } - - /* Store new BVCI/NSEI in MM context (FIXME: delay until we ack?) */ - msgid2mmctx(mmctx, msg); - /* Bump the statistics of received signalling msgs for this MM context */ - rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]); - - /* Update the MM context with the new RA-ID */ - if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) { - bssgp_parse_cell_id(&mmctx->ra, msgb_bcid(msg)); - /* Update the MM context with the new (i.e. foreign) TLLI */ - mmctx->gb.tlli = msgb_tlli(msg); - } - /* FIXME: Update the MM context with the MS radio acc capabilities */ - /* FIXME: Update the MM context with the MS network capabilities */ - - rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_RA_UPDATE]); - -#ifdef PTMSI_ALLOC - /* Don't change the P-TMSI if a P-TMSI re-assignment is under way */ - if (mmctx->gmm_state != GMM_COMMON_PROC_INIT) { - mmctx->p_tmsi_old = mmctx->p_tmsi; - mmctx->p_tmsi = sgsn_alloc_ptmsi(); - } - /* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */ - mmctx->t3350_mode = GMM_T3350_MODE_RAU; - mmctx_timer_start(mmctx, 3350, sgsn->cfg.timers.T3350); - - mmctx->gmm_state = GMM_COMMON_PROC_INIT; -#else - /* Make sure we are NORMAL (i.e. not SUSPENDED anymore) */ - mmctx->gmm_state = GMM_REGISTERED_NORMAL; - - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.mm = mmctx; - osmo_signal_dispatch(SS_SGSN, S_SGSN_UPDATE, &sig_data); -#endif - if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) { - /* Even if there is no P-TMSI allocated, the MS will switch from - * foreign TLLI to local TLLI */ - mmctx->gb.tlli_new = gprs_tmsi2tlli(mmctx->p_tmsi, TLLI_LOCAL); - - /* Inform LLC layer about new TLLI but keep old active */ - gprs_llgmm_assign(mmctx->gb.llme, mmctx->gb.tlli, - mmctx->gb.tlli_new); - } - - /* Look at PDP Context Status IE and see if MS's view of - * activated/deactivated NSAPIs agrees with our view */ - if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) { - const uint8_t *pdp_status = TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS); - process_ms_ctx_status(mmctx, pdp_status); - } - - /* Send RA UPDATE ACCEPT. In Iu, the RA upd request can be called from - * a new Iu connection, so we might need to re-authenticate the - * connection as well as turn on integrity protection. */ - mmctx->pending_req = GSM48_MT_GMM_RA_UPD_REQ; - return gsm48_gmm_authorize(mmctx); - -rejected: - /* Send RA UPDATE REJECT */ - LOGMMCTXP(LOGL_NOTICE, mmctx, - "Rejecting RA Update Request with cause '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, reject_cause), reject_cause); - rc = gsm48_tx_gmm_ra_upd_rej(msg, reject_cause); - if (mmctx) - mm_ctx_cleanup_free(mmctx, "GPRS RA UPDATE REJ"); - else { - if (llme) - gprs_llgmm_unassign(llme); - } - - return rc; -} - -/* 3GPP TS 24.008 Section 9.4.20 Service request. - * In Iu, a UE in PMM-IDLE mode can use GSM48_MT_GMM_SERVICE_REQ to switch back - * to PMM-CONNECTED mode. */ -static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t *cur = gh->data, *mi; - uint8_t ciph_seq_nr, service_type, mi_len, mi_type; - uint32_t tmsi; - struct tlv_parsed tp; - char mi_string[GSM48_MI_SIZE]; - enum gsm48_gmm_cause reject_cause; - int rc; - - LOGMMCTXP(LOGL_INFO, ctx, "-> GMM SERVICE REQUEST "); - - /* This message is only valid in Iu mode */ - if (!msg->dst) { - LOGPC(DMM, LOGL_INFO, "Invalid if not in Iu mode\n"); - return -1; - } - - /* Skip Ciphering key sequence number 10.5.1.2 */ - ciph_seq_nr = *cur & 0x07; - - /* Service type 10.5.5.20 */ - service_type = (*cur++ >> 4) & 0x07; - - /* Mobile Identity (P-TMSI or IMSI) 10.5.1.4 */ - mi_len = *cur++; - mi = cur; - if (mi_len > 8) - goto err_inval; - mi_type = *mi & GSM_MI_TYPE_MASK; - cur += mi_len; - - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); - - DEBUGPC(DMM, "MI(%s) type=\"%s\" ", mi_string, - get_value_string(gprs_service_t_strs, service_type)); - - LOGPC(DMM, LOGL_INFO, "\n"); - - /* Optional: PDP context status, MBMS context status, Uplink data status, Device properties */ - tlv_parse(&tp, &gsm48_gmm_att_tlvdef, cur, (msg->data + msg->len) - cur, 0, 0); - - switch (mi_type) { - case GSM_MI_TYPE_IMSI: - /* Try to find MM context based on IMSI */ - if (!ctx) - ctx = sgsn_mm_ctx_by_imsi(mi_string); - if (!ctx) { - /* FIXME: We need to have a context for service request? */ - reject_cause = GMM_CAUSE_NET_FAIL; - goto rejected; - } - msgid2mmctx(ctx, msg); - break; - case GSM_MI_TYPE_TMSI: - memcpy(&tmsi, mi+1, 4); - tmsi = ntohl(tmsi); - /* Try to find MM context based on P-TMSI */ - if (!ctx) - ctx = sgsn_mm_ctx_by_ptmsi(tmsi); - if (!ctx) { - /* FIXME: We need to have a context for service request? */ - reject_cause = GMM_CAUSE_NET_FAIL; - goto rejected; - } - msgid2mmctx(ctx, msg); - break; - default: - LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting SERVICE REQUEST with " - "MI type %s\n", gsm48_mi_type_name(mi_type)); - reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED; - goto rejected; - } - - ctx->gmm_state = GMM_COMMON_PROC_INIT; - - ctx->iu.service.type = service_type; - - /* TODO: Handle those only in case of accept? */ - /* Look at PDP Context Status IE and see if MS's view of - * activated/deactivated NSAPIs agrees with our view */ - if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) { - const uint8_t *pdp_status = TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS); - process_ms_ctx_status(ctx, pdp_status); - } - - - ctx->pending_req = GSM48_MT_GMM_SERVICE_REQ; - return gsm48_gmm_authorize(ctx); - -err_inval: - LOGPC(DMM, LOGL_INFO, "\n"); - reject_cause = GMM_CAUSE_SEM_INCORR_MSG; - -rejected: - /* Send SERVICE REJECT */ - LOGMMCTXP(LOGL_NOTICE, ctx, - "Rejecting Service Request with cause '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, reject_cause), reject_cause); - rc = gsm48_tx_gmm_service_rej_oldmsg(msg, reject_cause); - - return rc; - -} - - -static int gsm48_rx_gmm_status(struct sgsn_mm_ctx *mmctx, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - - LOGMMCTXP(LOGL_INFO, mmctx, "-> GPRS MM STATUS (cause: %s)\n", - get_value_string(gsm48_gmm_cause_names, gh->data[0])); - - return 0; -} - -/* GPRS Mobility Management */ -static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, - struct gprs_llc_llme *llme, bool drop_cipherable) -{ - struct sgsn_signal_data sig_data; - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - int rc; - - /* MMCTX can be NULL when called */ - if (drop_cipherable && gsm48_hdr_gmm_cipherable(gh)) { - LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping cleartext GMM %s which " - "is expected to be encrypted for TLLI 0x%08x\n", - get_value_string(gprs_msgt_gmm_names, gh->msg_type), - llme->tlli); - return -EBADMSG; - } - - if (llme && !mmctx && - gh->msg_type != GSM48_MT_GMM_ATTACH_REQ && - gh->msg_type != GSM48_MT_GMM_RA_UPD_REQ) { - LOGP(DMM, LOGL_NOTICE, "Cannot handle GMM for unknown MM CTX\n"); - /* 4.7.10 */ - if (gh->msg_type == GSM48_MT_GMM_STATUS) { - /* TLLI unassignment */ - gprs_llgmm_unassign(llme); - return 0; - } - - /* Don't reply or establish a LLME on DETACH_ACK */ - if (gh->msg_type == GSM48_MT_GMM_DETACH_ACK) - return gprs_llgmm_unassign(llme); - - gprs_llgmm_reset(llme); - - /* Don't force it into re-attachment */ - if (gh->msg_type == GSM48_MT_GMM_DETACH_REQ) { - /* Handle Detach Request */ - rc = gsm48_rx_gmm_det_req(NULL, msg); - - /* TLLI unassignment */ - gprs_llgmm_unassign(llme); - return rc; - } - - /* Force the MS to re-attach */ - rc = gsm0408_gprs_force_reattach_oldmsg(msg, llme); - - /* TLLI unassignment */ - gprs_llgmm_unassign(llme); - return rc; - } - - /* - * For a few messages, mmctx may be NULL. For most, we want to ensure a - * non-NULL mmctx. At the same time, we want to keep the message - * validity check intact, so that all message types appear in the - * switch statement and the default case thus means "unknown message". - * If we split the switch in two parts to check non-NULL halfway, the - * unknown-message check breaks, or we'd need to duplicate the switch - * cases in both parts. Just keep one large switch and add some gotos. - */ - switch (gh->msg_type) { - case GSM48_MT_GMM_RA_UPD_REQ: - rc = gsm48_rx_gmm_ra_upd_req(mmctx, msg, llme); - break; - case GSM48_MT_GMM_ATTACH_REQ: - rc = gsm48_rx_gmm_att_req(mmctx, msg, llme); - break; - case GSM48_MT_GMM_SERVICE_REQ: - rc = gsm48_rx_gmm_service_req(mmctx, msg); - break; - /* For all the following types mmctx can not be NULL */ - case GSM48_MT_GMM_ID_RESP: - if (!mmctx) - goto null_mmctx; - rc = gsm48_rx_gmm_id_resp(mmctx, msg); - break; - case GSM48_MT_GMM_STATUS: - if (!mmctx) - goto null_mmctx; - rc = gsm48_rx_gmm_status(mmctx, msg); - break; - case GSM48_MT_GMM_DETACH_REQ: - if (!mmctx) - goto null_mmctx; - rc = gsm48_rx_gmm_det_req(mmctx, msg); - break; - case GSM48_MT_GMM_DETACH_ACK: - if (!mmctx) - goto null_mmctx; - LOGMMCTXP(LOGL_INFO, mmctx, "-> DETACH ACK\n"); - mm_ctx_cleanup_free(mmctx, "GPRS DETACH ACK"); - rc = 0; - break; - case GSM48_MT_GMM_ATTACH_COMPL: - if (!mmctx) - goto null_mmctx; - /* only in case SGSN offered new P-TMSI */ - LOGMMCTXP(LOGL_INFO, mmctx, "-> ATTACH COMPLETE\n"); - mmctx_timer_stop(mmctx, 3350); - mmctx->t3350_mode = GMM_T3350_MODE_NONE; - mmctx->p_tmsi_old = 0; - mmctx->pending_req = 0; - if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) { - /* Unassign the old TLLI */ - mmctx->gb.tlli = mmctx->gb.tlli_new; - gprs_llme_copy_key(mmctx, mmctx->gb.llme); - gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff, - mmctx->gb.tlli_new); - } - mmctx->gmm_state = GMM_REGISTERED_NORMAL; - mmctx_set_pmm_state(mmctx, PMM_CONNECTED); - mmctx_set_mm_state(mmctx, MM_READY); - rc = 0; - - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.mm = mmctx; - osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data); - break; - case GSM48_MT_GMM_RA_UPD_COMPL: - if (!mmctx) - goto null_mmctx; - /* only in case SGSN offered new P-TMSI */ - LOGMMCTXP(LOGL_INFO, mmctx, "-> ROUTING AREA UPDATE COMPLETE\n"); - mmctx_timer_stop(mmctx, 3350); - mmctx->t3350_mode = GMM_T3350_MODE_NONE; - mmctx->p_tmsi_old = 0; - mmctx->pending_req = 0; - if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) { - /* Unassign the old TLLI */ - mmctx->gb.tlli = mmctx->gb.tlli_new; - gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff, - mmctx->gb.tlli_new); - } - mmctx->gmm_state = GMM_REGISTERED_NORMAL; - mmctx_set_pmm_state(mmctx, PMM_CONNECTED); - mmctx_set_mm_state(mmctx, MM_READY); - rc = 0; - - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.mm = mmctx; - osmo_signal_dispatch(SS_SGSN, S_SGSN_UPDATE, &sig_data); - break; - case GSM48_MT_GMM_PTMSI_REALL_COMPL: - if (!mmctx) - goto null_mmctx; - LOGMMCTXP(LOGL_INFO, mmctx, "-> PTMSI REALLLICATION COMPLETE\n"); - mmctx_timer_stop(mmctx, 3350); - mmctx->t3350_mode = GMM_T3350_MODE_NONE; - mmctx->p_tmsi_old = 0; - mmctx->pending_req = 0; - if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) { - /* Unassign the old TLLI */ - mmctx->gb.tlli = mmctx->gb.tlli_new; - //gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff, mmctx->gb.tlli_new, GPRS_ALGO_GEA0, NULL); - } - rc = 0; - break; - case GSM48_MT_GMM_AUTH_CIPH_RESP: - if (!mmctx) - goto null_mmctx; - rc = gsm48_rx_gmm_auth_ciph_resp(mmctx, msg); - break; - case GSM48_MT_GMM_AUTH_CIPH_FAIL: - rc = gsm48_rx_gmm_auth_ciph_fail(mmctx, msg); - break; - default: - LOGMMCTXP(LOGL_NOTICE, mmctx, "Unknown GSM 04.08 GMM msg type 0x%02x\n", - gh->msg_type); - if (mmctx) - rc = gsm48_tx_gmm_status(mmctx, GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL); - else - rc = -EINVAL; - break; - } - - return rc; - -null_mmctx: - LOGP(DMM, LOGL_ERROR, - "Received GSM 04.08 message type 0x%02x," - " but no MM context available\n", - gh->msg_type); - return -EINVAL; -} - -static void mmctx_timer_cb(void *_mm) -{ - struct sgsn_mm_ctx *mm = _mm; - struct gsm_auth_tuple *at; - - mm->num_T_exp++; - - switch (mm->T) { - case 3350: /* waiting for ATTACH COMPLETE */ - if (mm->num_T_exp >= 5) { - LOGMMCTXP(LOGL_NOTICE, mm, "T3350 expired >= 5 times\n"); - mm_ctx_cleanup_free(mm, "T3350"); - /* FIXME: should we return some error? */ - break; - } - /* re-transmit the respective msg and re-start timer */ - switch (mm->t3350_mode) { - case GMM_T3350_MODE_ATT: - gsm48_tx_gmm_att_ack(mm); - break; - case GMM_T3350_MODE_RAU: - gsm48_tx_gmm_ra_upd_ack(mm); - break; - case GMM_T3350_MODE_PTMSI_REALL: - /* FIXME */ - break; - case GMM_T3350_MODE_NONE: - LOGMMCTXP(LOGL_NOTICE, mm, - "T3350 mode wasn't set, ignoring timeout\n"); - break; - } - osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3350, 0); - break; - case 3360: /* waiting for AUTH AND CIPH RESP */ - if (mm->num_T_exp >= 5) { - LOGMMCTXP(LOGL_NOTICE, mm, "T3360 expired >= 5 times\n"); - mm_ctx_cleanup_free(mm, "T3360"); - break; - } - /* Re-transmit the respective msg and re-start timer */ - if (mm->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) { - LOGMMCTXP(LOGL_ERROR, mm, - "timeout: invalid auth triplet reference\n"); - mm_ctx_cleanup_free(mm, "T3360"); - break; - } - at = &mm->auth_triplet; - - gsm48_tx_gmm_auth_ciph_req(mm, &at->vec, at->key_seq, false); - osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3360, 0); - break; - case 3370: /* waiting for IDENTITY RESPONSE */ - if (mm->num_T_exp >= 5) { - LOGMMCTXP(LOGL_NOTICE, mm, "T3370 expired >= 5 times\n"); - gsm48_tx_gmm_att_rej(mm, GMM_CAUSE_MS_ID_NOT_DERIVED); - mm_ctx_cleanup_free(mm, "GPRS ATTACH REJECT (T3370)"); - break; - } - /* re-tranmit IDENTITY REQUEST and re-start timer */ - gsm48_tx_gmm_id_req(mm, mm->t3370_id_type); - osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3370, 0); - break; - default: - LOGMMCTXP(LOGL_ERROR, mm, "timer expired in unknown mode %u\n", - mm->T); - } -} - -/* GPRS SESSION MANAGEMENT */ - -static void pdpctx_timer_cb(void *_mm); - -static void pdpctx_timer_start(struct sgsn_pdp_ctx *pdp, unsigned int T, - unsigned int seconds) -{ - if (osmo_timer_pending(&pdp->timer)) - LOGPDPCTXP(LOGL_ERROR, pdp, "Starting PDP timer %u while old " - "timer %u pending\n", T, pdp->T); - pdp->T = T; - pdp->num_T_exp = 0; - - /* FIXME: we should do this only once ? */ - osmo_timer_setup(&pdp->timer, pdpctx_timer_cb, pdp); - osmo_timer_schedule(&pdp->timer, seconds, 0); -} - -static void pdpctx_timer_stop(struct sgsn_pdp_ctx *pdp, unsigned int T) -{ - if (pdp->T != T) - LOGPDPCTXP(LOGL_ERROR, pdp, "Stopping PDP timer %u but " - "%u is running\n", T, pdp->T); - osmo_timer_del(&pdp->timer); -} - -#if 0 -static void msgb_put_pdp_addr_ipv4(struct msgb *msg, uint32_t ipaddr) -{ - uint8_t v[6]; - - v[0] = PDP_TYPE_ORG_IETF; - v[1] = PDP_TYPE_N_IETF_IPv4; - *(uint32_t *)(v+2) = htonl(ipaddr); - - msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v); -} - -static void msgb_put_pdp_addr_ppp(struct msgb *msg) -{ - uint8_t v[2]; - - v[0] = PDP_TYPE_ORG_ETSI; - v[1] = PDP_TYPE_N_ETSI_PPP; - - msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v); -} -#endif - -/* Section 9.5.2: Activate PDP Context Accept */ -int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP ACC"); - struct gsm48_hdr *gh; - uint8_t transaction_id = pdp->ti ^ 0x8; /* flip */ - - LOGPDPCTXP(LOGL_INFO, pdp, "<- ACTIVATE PDP CONTEXT ACK\n"); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_ACCEPT]); - - mmctx2msgid(msg, pdp->mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4); - gh->msg_type = GSM48_MT_GSM_ACT_PDP_ACK; - - /* Negotiated LLC SAPI */ - msgb_v_put(msg, pdp->sapi); - - /* FIXME: copy QoS parameters from original request */ - //msgb_lv_put(msg, pdp->lib->qos_neg.l, pdp->lib->qos_neg.v); - msgb_lv_put(msg, sizeof(default_qos), (uint8_t *)&default_qos); - - /* Radio priority 10.5.7.2 */ - msgb_v_put(msg, pdp->lib->radio_pri); - - /* PDP address */ - /* Highest 4 bits of first byte need to be set to 1, otherwise - * the IE is identical with the 04.08 PDP Address IE */ - pdp->lib->eua.v[0] &= ~0xf0; - msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, - pdp->lib->eua.l, pdp->lib->eua.v); - pdp->lib->eua.v[0] |= 0xf0; - - /* Optional: Protocol configuration options (FIXME: why 'req') */ - if (pdp->lib->pco_req.l) - msgb_tlv_put(msg, GSM48_IE_GSM_PROTO_CONF_OPT, - pdp->lib->pco_req.l, pdp->lib->pco_req.v); - - /* Optional: Packet Flow Identifier */ - - return gsm48_gmm_sendmsg(msg, 0, pdp->mm, true); -} - -/* Section 9.5.3: Activate PDP Context reject */ -int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid, - uint8_t cause, uint8_t pco_len, uint8_t *pco_v) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP REJ"); - struct gsm48_hdr *gh; - uint8_t transaction_id = tid ^ 0x8; /* flip */ - - LOGMMCTXP(LOGL_NOTICE, mm, "<- ACTIVATE PDP CONTEXT REJ(cause=%u)\n", cause); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_REJECT]); - - mmctx2msgid(msg, mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4); - gh->msg_type = GSM48_MT_GSM_ACT_PDP_REJ; - - msgb_v_put(msg, cause); - if (pco_len && pco_v) - msgb_tlv_put(msg, GSM48_IE_GSM_PROTO_CONF_OPT, pco_len, pco_v); - - return gsm48_gmm_sendmsg(msg, 0, mm, true); -} - -/* Section 9.5.8: Deactivate PDP Context Request */ -static int _gsm48_tx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, uint8_t tid, - uint8_t sm_cause) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET REQ"); - struct gsm48_hdr *gh; - uint8_t transaction_id = tid ^ 0x8; /* flip */ - - LOGMMCTXP(LOGL_INFO, mm, "<- DEACTIVATE PDP CONTEXT REQ\n"); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_DL_DEACTIVATE_REQUEST]); - - mmctx2msgid(msg, mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4); - gh->msg_type = GSM48_MT_GSM_DEACT_PDP_REQ; - - msgb_v_put(msg, sm_cause); - - return gsm48_gmm_sendmsg(msg, 0, mm, true); -} -int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause) -{ - pdpctx_timer_start(pdp, 3395, sgsn->cfg.timers.T3395); - - return _gsm48_tx_gsm_deact_pdp_req(pdp->mm, pdp->ti, sm_cause); -} - -/* Section 9.5.9: Deactivate PDP Context Accept */ -static int _gsm48_tx_gsm_deact_pdp_acc(struct sgsn_mm_ctx *mm, uint8_t tid) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET ACC"); - struct gsm48_hdr *gh; - uint8_t transaction_id = tid ^ 0x8; /* flip */ - - LOGMMCTXP(LOGL_INFO, mm, "<- DEACTIVATE PDP CONTEXT ACK\n"); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_DL_DEACTIVATE_ACCEPT]); - - mmctx2msgid(msg, mm); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4); - gh->msg_type = GSM48_MT_GSM_DEACT_PDP_ACK; - - return gsm48_gmm_sendmsg(msg, 0, mm, true); -} -int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp) -{ - return _gsm48_tx_gsm_deact_pdp_acc(pdp->mm, pdp->ti); -} - -static int activate_ggsn(struct sgsn_mm_ctx *mmctx, - struct sgsn_ggsn_ctx *ggsn, const uint8_t transaction_id, - const uint8_t req_nsapi, const uint8_t req_llc_sapi, - struct tlv_parsed *tp, int destroy_ggsn) -{ - struct sgsn_pdp_ctx *pdp; - - LOGMMCTXP(LOGL_DEBUG, mmctx, "Using GGSN %u\n", ggsn->id); - ggsn->gsn = sgsn->gsn; - pdp = sgsn_create_pdp_ctx(ggsn, mmctx, req_nsapi, tp); - if (!pdp) - return -1; - - /* Store SAPI and Transaction Identifier */ - pdp->sapi = req_llc_sapi; - pdp->ti = transaction_id; - pdp->destroy_ggsn = destroy_ggsn; - - return 0; -} - -static void ggsn_lookup_cb(void *arg, int status, int timeouts, struct hostent *hostent) -{ - struct sgsn_ggsn_ctx *ggsn; - struct sgsn_ggsn_lookup *lookup = arg; - struct in_addr *addr = NULL; - - /* The context is gone while we made a request */ - if (!lookup->mmctx) { - talloc_free(lookup->orig_msg); - talloc_free(lookup); - return; - } - - if (status != ARES_SUCCESS) { - struct sgsn_mm_ctx *mmctx = lookup->mmctx; - - LOGMMCTXP(LOGL_ERROR, mmctx, "DNS query failed.\n"); - - /* Need to try with three digits now */ - if (lookup->state == SGSN_GGSN_2DIGIT) { - char *hostname; - int rc; - - lookup->state = SGSN_GGSN_3DIGIT; - hostname = osmo_apn_qualify_from_imsi(mmctx->imsi, - lookup->apn_str, 1); - LOGMMCTXP(LOGL_DEBUG, mmctx, - "Going to query %s\n", hostname); - rc = sgsn_ares_query(sgsn, hostname, - ggsn_lookup_cb, lookup); - if (rc != 0) { - LOGMMCTXP(LOGL_ERROR, mmctx, "Couldn't start GGSN\n"); - goto reject_due_failure; - } - return; - } - - LOGMMCTXP(LOGL_ERROR, mmctx, "Couldn't resolve GGSN\n"); - goto reject_due_failure; - } - - if (hostent->h_length != sizeof(struct in_addr)) { - LOGMMCTXP(LOGL_ERROR, lookup->mmctx, - "Wrong addr size(%zu)\n", sizeof(struct in_addr)); - goto reject_due_failure; - } - - /* Get the first addr from the list */ - addr = (struct in_addr *) hostent->h_addr_list[0]; - if (!addr) { - LOGMMCTXP(LOGL_ERROR, lookup->mmctx, "No host address.\n"); - goto reject_due_failure; - } - - ggsn = sgsn_ggsn_ctx_alloc(UINT32_MAX); - if (!ggsn) { - LOGMMCTXP(LOGL_ERROR, lookup->mmctx, "Failed to create ggsn.\n"); - goto reject_due_failure; - } - ggsn->remote_addr = *addr; - LOGMMCTXP(LOGL_NOTICE, lookup->mmctx, - "Selected %s as GGSN.\n", inet_ntoa(*addr)); - - /* forget about the ggsn look-up */ - lookup->mmctx->ggsn_lookup = NULL; - - activate_ggsn(lookup->mmctx, ggsn, lookup->ti, lookup->nsapi, - lookup->sapi, &lookup->tp, 1); - - /* Now free it */ - talloc_free(lookup->orig_msg); - talloc_free(lookup); - return; - -reject_due_failure: - gsm48_tx_gsm_act_pdp_rej(lookup->mmctx, lookup->ti, - GMM_CAUSE_NET_FAIL, 0, NULL); - lookup->mmctx->ggsn_lookup = NULL; - talloc_free(lookup->orig_msg); - talloc_free(lookup); -} - -static int do_act_pdp_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, bool *delete) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - struct gsm48_act_pdp_ctx_req *act_req = (struct gsm48_act_pdp_ctx_req *) gh->data; - uint8_t req_qos_len, req_pdpa_len; - uint8_t *req_qos, *req_pdpa; - struct tlv_parsed tp; - uint8_t transaction_id = gsm48_hdr_trans_id(gh); - struct sgsn_ggsn_ctx *ggsn; - struct sgsn_pdp_ctx *pdp; - enum gsm48_gsm_cause gsm_cause; - char apn_str[GSM_APN_LENGTH] = { 0, }; - char *hostname; - int rc; - struct gprs_llc_lle *lle; - - LOGMMCTXP(LOGL_INFO, mmctx, "-> ACTIVATE PDP CONTEXT REQ: SAPI=%u NSAPI=%u ", - act_req->req_llc_sapi, act_req->req_nsapi); - - /* FIXME: length checks! */ - req_qos_len = act_req->data[0]; - req_qos = act_req->data + 1; /* 10.5.6.5 */ - req_pdpa_len = act_req->data[1 + req_qos_len]; - req_pdpa = act_req->data + 1 + req_qos_len + 1; /* 10.5.6.4 */ - - switch (req_pdpa[0] & 0xf) { - case 0x0: - DEBUGPC(DMM, "ETSI "); - break; - case 0x1: - DEBUGPC(DMM, "IETF "); - break; - case 0xf: - DEBUGPC(DMM, "Empty "); - break; - } - - switch (req_pdpa[1]) { - case 0x21: - DEBUGPC(DMM, "IPv4 "); - if (req_pdpa_len >= 6) { - struct in_addr ia; - ia.s_addr = ntohl(*((uint32_t *) (req_pdpa+2))); - DEBUGPC(DMM, "%s ", inet_ntoa(ia)); - } - break; - case 0x57: - DEBUGPC(DMM, "IPv6 "); - if (req_pdpa_len >= 18) { - /* FIXME: print IPv6 address */ - } - break; - default: - DEBUGPC(DMM, "0x%02x ", req_pdpa[1]); - break; - } - - LOGPC(DMM, LOGL_INFO, "\n"); - - /* Check if NSAPI is out of range (TS 04.65 / 7.2) */ - if (act_req->req_nsapi < 5 || act_req->req_nsapi > 15) { - /* Send reject with GSM_CAUSE_INV_MAND_INFO */ - return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id, - GSM_CAUSE_INV_MAND_INFO, - 0, NULL); - } - - /* Optional: Access Point Name, Protocol Config Options */ - if (req_pdpa + req_pdpa_len < msg->data + msg->len) - tlv_parse(&tp, &gsm48_sm_att_tlvdef, req_pdpa + req_pdpa_len, - (msg->data + msg->len) - (req_pdpa + req_pdpa_len), 0, 0); - else - memset(&tp, 0, sizeof(tp)); - - - /* put the non-TLV elements in the TLV parser structure to - * pass them on to the SGSN / GTP code */ - tp.lv[OSMO_IE_GSM_REQ_QOS].len = req_qos_len; - tp.lv[OSMO_IE_GSM_REQ_QOS].val = req_qos; - tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].len = req_pdpa_len; - tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].val = req_pdpa; - - /* Check if NSAPI is already in use */ - pdp = sgsn_pdp_ctx_by_nsapi(mmctx, act_req->req_nsapi); - if (pdp) { - /* We already have a PDP context for this TLLI + NSAPI tuple */ - if (pdp->sapi == act_req->req_llc_sapi && - pdp->ti == transaction_id) { - /* This apparently is a re-transmission of a PDP CTX - * ACT REQ (our ACT ACK must have got dropped) */ - rc = gsm48_tx_gsm_act_pdp_acc(pdp); - if (rc < 0) - return rc; - - if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) { - /* Also re-transmit the SNDCP XID message */ - lle = &pdp->mm->gb.llme->lle[pdp->sapi]; - rc = sndcp_sn_xid_req(lle,pdp->nsapi); - if (rc < 0) - return rc; - } - - return 0; - } - - /* Send reject with GSM_CAUSE_NSAPI_IN_USE */ - return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id, - GSM_CAUSE_NSAPI_IN_USE, - 0, NULL); - } - - if (mmctx->ggsn_lookup) { - if (mmctx->ggsn_lookup->sapi == act_req->req_llc_sapi && - mmctx->ggsn_lookup->ti == transaction_id) { - LOGMMCTXP(LOGL_NOTICE, mmctx, - "Re-transmission while doing look-up. Ignoring.\n"); - return 0; - } - } - - /* Only increment counter for a real activation, after we checked - * for re-transmissions */ - rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PDP_CTX_ACT]); - - /* Determine GGSN based on APN and subscription options */ - ggsn = sgsn_mm_ctx_find_ggsn_ctx(mmctx, &tp, &gsm_cause, apn_str); - if (ggsn) - return activate_ggsn(mmctx, ggsn, transaction_id, - act_req->req_nsapi, act_req->req_llc_sapi, - &tp, 0); - - if (strlen(apn_str) == 0) - goto no_context; - if (!sgsn->cfg.dynamic_lookup) - goto no_context; - - /* schedule a dynamic look-up */ - mmctx->ggsn_lookup = talloc_zero(tall_bsc_ctx, struct sgsn_ggsn_lookup); - if (!mmctx->ggsn_lookup) - goto no_context; - - mmctx->ggsn_lookup->state = SGSN_GGSN_2DIGIT; - mmctx->ggsn_lookup->mmctx = mmctx; - strcpy(mmctx->ggsn_lookup->apn_str, apn_str); - - mmctx->ggsn_lookup->orig_msg = msg; - mmctx->ggsn_lookup->tp = tp; - - mmctx->ggsn_lookup->ti = transaction_id; - mmctx->ggsn_lookup->nsapi = act_req->req_nsapi; - mmctx->ggsn_lookup->sapi = act_req->req_llc_sapi; - - hostname = osmo_apn_qualify_from_imsi(mmctx->imsi, - mmctx->ggsn_lookup->apn_str, 0); - - LOGMMCTXP(LOGL_DEBUG, mmctx, "Going to query %s\n", hostname); - rc = sgsn_ares_query(sgsn, hostname, - ggsn_lookup_cb, mmctx->ggsn_lookup); - if (rc != 0) { - LOGMMCTXP(LOGL_ERROR, mmctx, "Failed to start ares query.\n"); - goto no_context; - } - *delete = 0; - - return 0; - -no_context: - LOGMMCTXP(LOGL_ERROR, mmctx, "No GGSN context found!\n"); - return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id, - gsm_cause, 0, NULL); -} - -/* Section 9.5.1: Activate PDP Context Request */ -static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx, - struct msgb *_msg) -{ - bool delete = 1; - struct msgb *msg; - int rc; - - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_REQUEST]); - - /* - * This is painful. We might not have a static GGSN - * configuration and then would need to copy the msg - * and re-do most of this routine (or call it again - * and make sure it only goes through the dynamic - * resolving. The question is what to optimize for - * and the dynamic resolution will be the right thing - * in the long run. - */ - msg = gprs_msgb_copy(_msg, __func__); - if (!msg) { - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(_msg); - uint8_t transaction_id = gsm48_hdr_trans_id(gh); - - LOGMMCTXP(LOGL_ERROR, mmctx, "-> ACTIVATE PDP CONTEXT REQ failed copy.\n"); - /* Send reject with GSM_CAUSE_INV_MAND_INFO */ - return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id, - GSM_CAUSE_NET_FAIL, - 0, NULL); - } - - rc = do_act_pdp_req(mmctx, msg, &delete); - if (delete) - msgb_free(msg); - return rc; -} - -/* Section 9.5.8: Deactivate PDP Context Request */ -static int gsm48_rx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, struct msgb *msg) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t transaction_id = gsm48_hdr_trans_id(gh); - struct sgsn_pdp_ctx *pdp; - - LOGMMCTXP(LOGL_INFO, mm, "-> DEACTIVATE PDP CONTEXT REQ (cause: %s)\n", - get_value_string(gsm48_gsm_cause_names, gh->data[0])); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_UL_DEACTIVATE_REQUEST]); - - pdp = sgsn_pdp_ctx_by_tid(mm, transaction_id); - if (!pdp) { - LOGMMCTXP(LOGL_NOTICE, mm, "Deactivate PDP Context Request for " - "non-existing PDP Context (IMSI=%s, TI=%u)\n", - mm->imsi, transaction_id); - return _gsm48_tx_gsm_deact_pdp_acc(mm, transaction_id); - } - - return sgsn_delete_pdp_ctx(pdp); -} - -/* Section 9.5.9: Deactivate PDP Context Accept */ -static int gsm48_rx_gsm_deact_pdp_ack(struct sgsn_mm_ctx *mm, struct msgb *msg) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t transaction_id = gsm48_hdr_trans_id(gh); - struct sgsn_pdp_ctx *pdp; - - LOGMMCTXP(LOGL_INFO, mm, "-> DEACTIVATE PDP CONTEXT ACK\n"); - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_UL_DEACTIVATE_ACCEPT]); - - pdp = sgsn_pdp_ctx_by_tid(mm, transaction_id); - if (!pdp) { - LOGMMCTXP(LOGL_NOTICE, mm, "Deactivate PDP Context Accept for " - "non-existing PDP Context (IMSI=%s, TI=%u)\n", - mm->imsi, transaction_id); - return 0; - } - /* stop timer 3395 */ - pdpctx_timer_stop(pdp, 3395); - return sgsn_delete_pdp_ctx(pdp); -} - -static int gsm48_rx_gsm_status(struct sgsn_mm_ctx *ctx, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - - LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS SM STATUS (cause: %s)\n", - get_value_string(gsm48_gsm_cause_names, gh->data[0])); - - return 0; -} - -static void pdpctx_timer_cb(void *_pdp) -{ - struct sgsn_pdp_ctx *pdp = _pdp; - - pdp->num_T_exp++; - - switch (pdp->T) { - case 3395: /* waiting for PDP CTX DEACT ACK */ - if (pdp->num_T_exp >= 4) { - LOGPDPCTXP(LOGL_NOTICE, pdp, "T3395 expired >= 5 times\n"); - pdp->state = PDP_STATE_INACTIVE; - sgsn_delete_pdp_ctx(pdp); - break; - } - gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL); - break; - default: - LOGPDPCTXP(LOGL_ERROR, pdp, "timer expired in unknown mode %u\n", - pdp->T); - } -} - - -/* GPRS Session Management */ -static int gsm0408_rcv_gsm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, - struct gprs_llc_llme *llme) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - int rc; - - /* MMCTX can be NULL when called */ - - if (!mmctx) { - LOGP(DMM, LOGL_NOTICE, "Cannot handle SM for unknown MM CTX\n"); - /* 6.1.3.6 */ - if (gh->msg_type == GSM48_MT_GSM_STATUS) - return 0; - - return gsm0408_gprs_force_reattach_oldmsg(msg, llme); - } - - switch (gh->msg_type) { - case GSM48_MT_GSM_ACT_PDP_REQ: - rc = gsm48_rx_gsm_act_pdp_req(mmctx, msg); - break; - case GSM48_MT_GSM_DEACT_PDP_REQ: - rc = gsm48_rx_gsm_deact_pdp_req(mmctx, msg); - break; - case GSM48_MT_GSM_DEACT_PDP_ACK: - rc = gsm48_rx_gsm_deact_pdp_ack(mmctx, msg); - break; - case GSM48_MT_GSM_STATUS: - rc = gsm48_rx_gsm_status(mmctx, msg); - break; - case GSM48_MT_GSM_REQ_PDP_ACT_REJ: - case GSM48_MT_GSM_ACT_AA_PDP_REQ: - case GSM48_MT_GSM_DEACT_AA_PDP_REQ: - LOGMMCTXP(LOGL_NOTICE, mmctx, "Unimplemented GSM 04.08 GSM msg type 0x%02x: %s\n", - gh->msg_type, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg))); - rc = gsm48_tx_sm_status(mmctx, GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL); - break; - default: - LOGMMCTXP(LOGL_NOTICE, mmctx, "Unknown GSM 04.08 GSM msg type 0x%02x: %s\n", - gh->msg_type, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg))); - rc = gsm48_tx_sm_status(mmctx, GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL); - break; - - } - - return rc; -} - -int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg, - struct gprs_llc_llme *llme) -{ - int rc; - if (llme) - gprs_llgmm_reset_oldmsg(msg, GPRS_SAPI_GMM, llme); - - rc = gsm48_tx_gmm_detach_req_oldmsg( - msg, GPRS_DET_T_MT_REATT_REQ, GMM_CAUSE_IMPL_DETACHED); - - return rc; -} - -int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx) -{ - int rc; - if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) - gprs_llgmm_reset(mmctx->gb.llme); - - rc = gsm48_tx_gmm_detach_req( - mmctx, GPRS_DET_T_MT_REATT_REQ, GMM_CAUSE_IMPL_DETACHED); - - mm_ctx_cleanup_free(mmctx, "forced reattach"); - - return rc; -} - -/* Main entry point for incoming 04.08 GPRS messages from Iu */ -int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, - uint16_t *sai) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t pdisc = gsm48_hdr_pdisc(gh); - struct sgsn_mm_ctx *mmctx; - int rc = -EINVAL; - - mmctx = sgsn_mm_ctx_by_ue_ctx(msg->dst); - if (mmctx) { - rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]); - if (ra_id) - memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra)); - } - - /* MMCTX can be NULL */ - - switch (pdisc) { - case GSM48_PDISC_MM_GPRS: - rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false); -#warning "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?" - break; - case GSM48_PDISC_SM_GPRS: - rc = gsm0408_rcv_gsm(mmctx, msg, NULL); - break; - default: - LOGMMCTXP(LOGL_NOTICE, mmctx, - "Unknown GSM 04.08 discriminator 0x%02x: %s\n", - pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg))); - /* FIXME: return status message */ - break; - } - - /* MMCTX can be invalid */ - - return rc; -} - -/* Main entry point for incoming 04.08 GPRS messages from Gb */ -int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, - bool drop_cipherable) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t pdisc = gsm48_hdr_pdisc(gh); - struct sgsn_mm_ctx *mmctx; - struct gprs_ra_id ra_id; - int rc = -EINVAL; - - bssgp_parse_cell_id(&ra_id, msgb_bcid(msg)); - mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id); - if (mmctx) { - msgid2mmctx(mmctx, msg); - rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]); - mmctx->gb.llme = llme; - } - - /* MMCTX can be NULL */ - - switch (pdisc) { - case GSM48_PDISC_MM_GPRS: - rc = gsm0408_rcv_gmm(mmctx, msg, llme, drop_cipherable); - break; - case GSM48_PDISC_SM_GPRS: - rc = gsm0408_rcv_gsm(mmctx, msg, llme); - break; - default: - LOGMMCTXP(LOGL_NOTICE, mmctx, - "Unknown GSM 04.08 discriminator 0x%02x: %s\n", - pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg))); - /* FIXME: return status message */ - break; - } - - /* MMCTX can be invalid */ - - return rc; -} - -int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli) -{ - struct sgsn_mm_ctx *mmctx; - - mmctx = sgsn_mm_ctx_by_tlli(tlli, raid); - if (!mmctx) { - LOGP(DMM, LOGL_NOTICE, "SUSPEND request for unknown " - "TLLI=%08x\n", tlli); - return -EINVAL; - } - - if (mmctx->gmm_state != GMM_REGISTERED_NORMAL && - mmctx->gmm_state != GMM_REGISTERED_SUSPENDED) { - LOGMMCTXP(LOGL_NOTICE, mmctx, "SUSPEND request while state " - "!= REGISTERED (TLLI=%08x)\n", tlli); - return -EINVAL; - } - - /* Transition from REGISTERED_NORMAL to REGISTERED_SUSPENDED */ - mmctx->gmm_state = GMM_REGISTERED_SUSPENDED; - return 0; -} - -int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli, - uint8_t suspend_ref) -{ - struct sgsn_mm_ctx *mmctx; - - /* FIXME: make use of suspend reference? */ - - mmctx = sgsn_mm_ctx_by_tlli(tlli, raid); - if (!mmctx) { - LOGP(DMM, LOGL_NOTICE, "RESUME request for unknown " - "TLLI=%08x\n", tlli); - return -EINVAL; - } - - if (mmctx->gmm_state != GMM_REGISTERED_NORMAL && - mmctx->gmm_state != GMM_REGISTERED_SUSPENDED) { - LOGMMCTXP(LOGL_NOTICE, mmctx, "RESUME request while state " - "!= SUSPENDED (TLLI=%08x)\n", tlli); - /* FIXME: should we not simply ignore it? */ - return -EINVAL; - } - - /* Transition from SUSPENDED to NORMAL */ - mmctx->gmm_state = GMM_REGISTERED_NORMAL; - return 0; -} - -#ifdef BUILD_IU -int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp) -{ - struct msgb *msg; - struct sgsn_mm_ctx *mm = pdp->mm; - struct ranap_ue_conn_ctx *uectx; - uint32_t ggsn_ip; - bool use_x213_nsap; - - uectx = mm->iu.ue_ctx; - use_x213_nsap = (uectx->rab_assign_addr_enc == RANAP_NSAP_ADDR_ENC_X213); - - /* Get the IP address for ggsn user plane */ - memcpy(&ggsn_ip, pdp->lib->gsnru.v, pdp->lib->gsnru.l); - ggsn_ip = htonl(ggsn_ip); - - LOGP(DRANAP, LOGL_DEBUG, "Assigning RAB: rab_id=%d, ggsn_ip=%x," - " teid_gn=%x, use_x213_nsap=%d\n", - rab_id, ggsn_ip, pdp->lib->teid_gn, use_x213_nsap); - - msg = ranap_new_msg_rab_assign_data(rab_id, ggsn_ip, - pdp->lib->teid_gn, use_x213_nsap); - msg->l2h = msg->data; - return ranap_iu_rab_act(uectx, msg); -} -#endif diff --git a/src/gprs/gprs_llc.c b/src/gprs/gprs_llc.c deleted file mode 100644 index 2be663f98..000000000 --- a/src/gprs/gprs_llc.c +++ /dev/null @@ -1,1132 +0,0 @@ -/* GPRS LLC protocol implementation as per 3GPP TS 04.64 */ - -/* (C) 2009-2010 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct gprs_llc_llme *llme_alloc(uint32_t tlli); -static int gprs_llc_tx_xid(struct gprs_llc_lle *lle, struct msgb *msg, - int command); -static int gprs_llc_tx_u(struct msgb *msg, uint8_t sapi, - int command, enum gprs_llc_u_cmd u_cmd, int pf_bit); - -/* BEGIN XID RELATED */ - -/* Generate XID message */ -static int gprs_llc_generate_xid(uint8_t *bytes, int bytes_len, - struct gprs_llc_xid_field *l3_xid_field, - struct gprs_llc_llme *llme) -{ - /* Note: Called by gprs_ll_xid_req() */ - - LLIST_HEAD(xid_fields); - - struct gprs_llc_xid_field xid_version; - struct gprs_llc_xid_field xid_n201u; - struct gprs_llc_xid_field xid_n201i; - - xid_version.type = GPRS_LLC_XID_T_VERSION; - xid_version.data = (uint8_t *) "\x00"; - xid_version.data_len = 1; - - xid_n201u.type = GPRS_LLC_XID_T_N201_U; - xid_n201u.data = (uint8_t *) "\x05\xf0"; - xid_n201u.data_len = 2; - - xid_n201i.type = GPRS_LLC_XID_T_N201_I; - xid_n201i.data = (uint8_t *) "\x05\xf0"; - xid_n201i.data_len = 2; - - /* Add locally managed XID Fields */ - llist_add(&xid_version.list, &xid_fields); - llist_add(&xid_n201u.list, &xid_fields); - llist_add(&xid_n201i.list, &xid_fields); - - /* Append layer 3 XID field (if present) */ - if (l3_xid_field) { - /* Enforce layer 3 XID type (just to be sure) */ - l3_xid_field->type = GPRS_LLC_XID_T_L3_PAR; - - /* Add Layer 3 XID field to the list */ - llist_add(&l3_xid_field->list, &xid_fields); - } - - /* Store generated XID for later reference */ - talloc_free(llme->xid); - llme->xid = gprs_llc_copy_xid(llme, &xid_fields); - - return gprs_llc_compile_xid(bytes, bytes_len, &xid_fields); -} - -/* Generate XID message that will cause the GMM to reset */ -static int gprs_llc_generate_xid_for_gmm_reset(uint8_t *bytes, - int bytes_len, uint32_t iov_ui, - struct gprs_llc_llme *llme) -{ - /* Called by gprs_llgmm_reset() and - * gprs_llgmm_reset_oldmsg() */ - - LLIST_HEAD(xid_fields); - - struct gprs_llc_xid_field xid_reset; - struct gprs_llc_xid_field xid_iovui; - - /* First XID component must be RESET */ - xid_reset.type = GPRS_LLC_XID_T_RESET; - xid_reset.data = NULL; - xid_reset.data_len = 0; - - /* Add new IOV-UI */ - xid_iovui.type = GPRS_LLC_XID_T_IOV_UI; - xid_iovui.data = (uint8_t *) & iov_ui; - xid_iovui.data_len = 4; - - /* Add locally managed XID Fields */ - llist_add(&xid_iovui.list, &xid_fields); - llist_add(&xid_reset.list, &xid_fields); - - /* Store generated XID for later reference */ - talloc_free(llme->xid); - llme->xid = gprs_llc_copy_xid(llme, &xid_fields); - - return gprs_llc_compile_xid(bytes, bytes_len, &xid_fields); -} - -/* Process an incoming XID confirmation */ -static int gprs_llc_process_xid_conf(uint8_t *bytes, int bytes_len, - struct gprs_llc_lle *lle) -{ - /* Note: This function handles the response of a network originated - * XID-Request. There XID messages reflected by the MS are analyzed - * and processed here. The caller is called by rx_llc_xid(). */ - - struct llist_head *xid_fields; - struct gprs_llc_xid_field *xid_field; - struct gprs_llc_xid_field *xid_field_request; - struct gprs_llc_xid_field *xid_field_request_l3 = NULL; - - /* Pick layer3 XID from the XID request we have sent last */ - if (lle->llme->xid) { - llist_for_each_entry(xid_field_request, lle->llme->xid, list) { - if (xid_field_request->type == GPRS_LLC_XID_T_L3_PAR) - xid_field_request_l3 = xid_field_request; - } - } - - /* Parse and analyze XID-Response */ - xid_fields = gprs_llc_parse_xid(NULL, bytes, bytes_len); - - if (xid_fields) { - - gprs_llc_dump_xid_fields(xid_fields, LOGL_DEBUG); - llist_for_each_entry(xid_field, xid_fields, list) { - - /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ - if (xid_field->type == GPRS_LLC_XID_T_L3_PAR && - xid_field_request_l3) { - sndcp_sn_xid_conf(xid_field, - xid_field_request_l3, lle); - } - - /* Process LLC-XID fields: */ - else { - - /* FIXME: Do something more useful with the - * echoed XID-Information. Currently we - * just ignore the response completely and - * by doing so we blindly accept any changes - * the MS might have done to the our XID - * inquiry. There is a remainig risk of - * malfunction! */ - LOGP(DLLC, LOGL_NOTICE, - "Ignoring XID-Field: XID: type %s, data_len=%d, data=%s\n", - get_value_string(gprs_llc_xid_type_names, - xid_field->type), - xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); - } - } - talloc_free(xid_fields); - } - - /* Flush pending XID fields */ - talloc_free(lle->llme->xid); - lle->llme->xid = NULL; - - return 0; -} - -/* Process an incoming XID indication and generate an appropiate response */ -static int gprs_llc_process_xid_ind(uint8_t *bytes_request, - int bytes_request_len, - uint8_t *bytes_response, - int bytes_response_maxlen, - struct gprs_llc_lle *lle) -{ - /* Note: This function computes the response that is sent back to the - * MS when a mobile originated XID is received. The function is - * called by rx_llc_xid() */ - - int rc = -EINVAL; - - struct llist_head *xid_fields; - struct llist_head *xid_fields_response; - - struct gprs_llc_xid_field *xid_field; - struct gprs_llc_xid_field *xid_field_response; - - /* Parse and analyze XID-Request */ - xid_fields = - gprs_llc_parse_xid(lle->llme, bytes_request, bytes_request_len); - if (xid_fields) { - xid_fields_response = talloc_zero(lle->llme, struct llist_head); - INIT_LLIST_HEAD(xid_fields_response); - gprs_llc_dump_xid_fields(xid_fields, LOGL_DEBUG); - - /* Process LLC-XID fields: */ - llist_for_each_entry(xid_field, xid_fields, list) { - - if (xid_field->type != GPRS_LLC_XID_T_L3_PAR) { - /* FIXME: Check the incoming XID parameters for - * for validity. Currently we just blindly - * accept all XID fields by just echoing them. - * There is a remaining risk of malfunction - * when a MS submits values which defer from - * the default! */ - LOGP(DLLC, LOGL_NOTICE, - "Echoing XID-Field: XID: type %s, data_len=%d, data=%s\n", - get_value_string(gprs_llc_xid_type_names, - xid_field->type), - xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); - xid_field_response = - gprs_llc_dup_xid_field - (lle->llme, xid_field); - llist_add(&xid_field_response->list, - xid_fields_response); - } - } - - /* Forward SNDCP-XID fields to Layer 3 (SNDCP) */ - llist_for_each_entry(xid_field, xid_fields, list) { - if (xid_field->type == GPRS_LLC_XID_T_L3_PAR) { - - xid_field_response = - talloc_zero(lle->llme, - struct gprs_llc_xid_field); - rc = sndcp_sn_xid_ind(xid_field, - xid_field_response, lle); - if (rc == 0) - llist_add(&xid_field_response->list, - xid_fields_response); - else - talloc_free(xid_field_response); - } - } - - rc = gprs_llc_compile_xid(bytes_response, - bytes_response_maxlen, - xid_fields_response); - talloc_free(xid_fields_response); - talloc_free(xid_fields); - } - - return rc; -} - -/* Dispatch XID indications and responses comming from the MS */ -static void rx_llc_xid(struct gprs_llc_lle *lle, - struct gprs_llc_hdr_parsed *gph) -{ - uint8_t response[1024]; - int response_len; - - /* FIXME: 8.5.3.3: check if XID is invalid */ - if (gph->is_cmd) { - LOGP(DLLC, LOGL_NOTICE, - "Received XID indication from MS.\n"); - - struct msgb *resp; - uint8_t *xid; - resp = msgb_alloc_headroom(4096, 1024, "LLC_XID"); - - response_len = - gprs_llc_process_xid_ind(gph->data, gph->data_len, - response, sizeof(response), - lle); - if (response_len < 0) { - LOGP(DLLC, LOGL_ERROR, - "invalid XID indication received!\n"); - } else { - xid = msgb_put(resp, response_len); - memcpy(xid, response, response_len); - } - gprs_llc_tx_xid(lle, resp, 0); - } else { - LOGP(DLLC, LOGL_NOTICE, - "Received XID confirmation from MS.\n"); - gprs_llc_process_xid_conf(gph->data, gph->data_len, lle); - /* FIXME: if we had sent a XID reset, send - * LLGMM-RESET.conf to GMM */ - } -} - -/* Set of LL-XID negotiation (See also: TS 101 351, Section 7.2.2.4) */ -int gprs_ll_xid_req(struct gprs_llc_lle *lle, - struct gprs_llc_xid_field *l3_xid_field) -{ - /* Note: This functions is calle from gprs_sndcp.c */ - - uint8_t xid_bytes[1024];; - int xid_bytes_len; - uint8_t *xid; - struct msgb *msg; - const char *ftype; - - /* Generate XID */ - xid_bytes_len = - gprs_llc_generate_xid(xid_bytes, sizeof(xid_bytes), - l3_xid_field, lle->llme); - - /* Only perform XID sending if the XID message contains something */ - if (xid_bytes_len > 0) { - /* Transmit XID bytes */ - msg = msgb_alloc_headroom(4096, 1024, "LLC_XID"); - xid = msgb_put(msg, xid_bytes_len); - memcpy(xid, xid_bytes, xid_bytes_len); - if (l3_xid_field) - ftype = get_value_string(gprs_llc_xid_type_names, - l3_xid_field->type); - else - ftype = "NULL"; - LOGP(DLLC, LOGL_NOTICE, "Sending XID type %s (%d bytes) request" - " to MS...\n", ftype, xid_bytes_len); - gprs_llc_tx_xid(lle, msg, 1); - } else { - LOGP(DLLC, LOGL_ERROR, - "XID-Message generation failed, XID not sent!\n"); - return -EINVAL; - } - - return 0; -} -/* END XID RELATED */ - - - - -/* Entry function from upper level (LLC), asking us to transmit a BSSGP PDU - * to a remote MS (identified by TLLI) at a BTS identified by its BVCI and NSEI */ -static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx) -{ - struct bssgp_dl_ud_par dup; - const uint8_t qos_profile_default[3] = { 0x00, 0x00, 0x20 }; - - memset(&dup, 0, sizeof(dup)); - /* before we have received some identity from the MS, we might - * not yet have a MMC context (e.g. XID negotiation of primarly - * LLC connection from GMM sapi). */ - if (mmctx) { - dup.imsi = mmctx->imsi; - dup.drx_parms = mmctx->drx_parms; - dup.ms_ra_cap.len = mmctx->ms_radio_access_capa.len; - dup.ms_ra_cap.v = mmctx->ms_radio_access_capa.buf; - - /* make sure we only send it to the right llme */ - OSMO_ASSERT(msgb_tlli(msg) == mmctx->gb.llme->tlli - || msgb_tlli(msg) == mmctx->gb.llme->old_tlli); - } - memcpy(&dup.qos_profile, qos_profile_default, - sizeof(qos_profile_default)); - - return bssgp_tx_dl_ud(msg, 1000, &dup); -} - - -/* Section 8.9.9 LLC layer parameter default values */ -static const struct gprs_llc_params llc_default_params[NUM_SAPIS] = { - [1] = { - .t200_201 = 5, - .n200 = 3, - .n201_u = 400, - }, - [2] = { - .t200_201 = 5, - .n200 = 3, - .n201_u = 270, - }, - [3] = { - .iov_i_exp = 27, - .t200_201 = 5, - .n200 = 3, - .n201_u = 500, - .n201_i = 1503, - .mD = 1520, - .mU = 1520, - .kD = 16, - .kU = 16, - }, - [5] = { - .iov_i_exp = 27, - .t200_201 = 10, - .n200 = 3, - .n201_u = 500, - .n201_i = 1503, - .mD = 760, - .mU = 760, - .kD = 8, - .kU = 8, - }, - [7] = { - .t200_201 = 20, - .n200 = 3, - .n201_u = 270, - }, - [8] = { - .t200_201 = 20, - .n200 = 3, - .n201_u = 270, - }, - [9] = { - .iov_i_exp = 27, - .t200_201 = 20, - .n200 = 3, - .n201_u = 500, - .n201_i = 1503, - .mD = 380, - .mU = 380, - .kD = 4, - .kU = 4, - }, - [11] = { - .iov_i_exp = 27, - .t200_201 = 40, - .n200 = 3, - .n201_u = 500, - .n201_i = 1503, - .mD = 190, - .mU = 190, - .kD = 2, - .kU = 2, - }, -}; - -LLIST_HEAD(gprs_llc_llmes); -void *llc_tall_ctx; - -/* lookup LLC Entity based on DLCI (TLLI+SAPI tuple) */ -static struct gprs_llc_lle *lle_by_tlli_sapi(const uint32_t tlli, uint8_t sapi) -{ - struct gprs_llc_llme *llme; - - llist_for_each_entry(llme, &gprs_llc_llmes, list) { - if (llme->tlli == tlli || llme->old_tlli == tlli) - return &llme->lle[sapi]; - } - return NULL; -} - -struct gprs_llc_lle *gprs_lle_get_or_create(const uint32_t tlli, uint8_t sapi) -{ - struct gprs_llc_llme *llme; - struct gprs_llc_lle *lle; - - lle = lle_by_tlli_sapi(tlli, sapi); - if (lle) - return lle; - - LOGP(DLLC, LOGL_NOTICE, "LLC: unknown TLLI 0x%08x, " - "creating LLME on the fly\n", tlli); - llme = llme_alloc(tlli); - lle = &llme->lle[sapi]; - return lle; -} - -struct llist_head *gprs_llme_list(void) -{ - return &gprs_llc_llmes; -} - -/* lookup LLC Entity for RX based on DLCI (TLLI+SAPI tuple) */ -static struct gprs_llc_lle *lle_for_rx_by_tlli_sapi(const uint32_t tlli, - uint8_t sapi, enum gprs_llc_cmd cmd) -{ - struct gprs_llc_lle *lle; - - /* We already know about this TLLI */ - lle = lle_by_tlli_sapi(tlli, sapi); - if (lle) - return lle; - - /* Maybe it is a routing area update but we already know this sapi? */ - if (gprs_tlli_type(tlli) == TLLI_FOREIGN) { - lle = lle_by_tlli_sapi(tlli, sapi); - if (lle) { - LOGP(DLLC, LOGL_NOTICE, - "LLC RX: Found a local entry for TLLI 0x%08x\n", - tlli); - return lle; - } - } - - /* 7.2.1.1 LLC belonging to unassigned TLLI+SAPI shall be discarded, - * except UID and XID frames with SAPI=1 */ - if (sapi == GPRS_SAPI_GMM && - (cmd == GPRS_LLC_XID || cmd == GPRS_LLC_UI)) { - struct gprs_llc_llme *llme; - /* FIXME: don't use the TLLI but the 0xFFFF unassigned? */ - llme = llme_alloc(tlli); - LOGP(DLLC, LOGL_NOTICE, "LLC RX: unknown TLLI 0x%08x, " - "creating LLME on the fly\n", tlli); - lle = &llme->lle[sapi]; - return lle; - } - - LOGP(DLLC, LOGL_NOTICE, - "unknown TLLI(0x%08x)/SAPI(%d): Silently dropping\n", - tlli, sapi); - return NULL; -} - -static void lle_init(struct gprs_llc_llme *llme, uint8_t sapi) -{ - struct gprs_llc_lle *lle = &llme->lle[sapi]; - - lle->llme = llme; - lle->sapi = sapi; - lle->state = GPRS_LLES_UNASSIGNED; - - /* Initialize according to parameters */ - memcpy(&lle->params, &llc_default_params[sapi], sizeof(lle->params)); -} - -static struct gprs_llc_llme *llme_alloc(uint32_t tlli) -{ - struct gprs_llc_llme *llme; - uint32_t i; - - llme = talloc_zero(llc_tall_ctx, struct gprs_llc_llme); - if (!llme) - return NULL; - - llme->tlli = tlli; - llme->old_tlli = 0xffffffff; - llme->state = GPRS_LLMS_UNASSIGNED; - llme->age_timestamp = GPRS_LLME_RESET_AGE; - llme->cksn = GSM_KEY_SEQ_INVAL; - - for (i = 0; i < ARRAY_SIZE(llme->lle); i++) - lle_init(llme, i); - - llist_add(&llme->list, &gprs_llc_llmes); - - llme->comp.proto = gprs_sndcp_comp_alloc(llme); - llme->comp.data = gprs_sndcp_comp_alloc(llme); - - return llme; -} - -static void llme_free(struct gprs_llc_llme *llme) -{ - gprs_sndcp_comp_free(llme->comp.proto); - gprs_sndcp_comp_free(llme->comp.data); - talloc_free(llme->xid); - llist_del(&llme->list); - talloc_free(llme); -} - -#if 0 -/* FIXME: Unused code... */ -static void t200_expired(void *data) -{ - struct gprs_llc_lle *lle = data; - - /* 8.5.1.3: Expiry of T200 */ - - if (lle->retrans_ctr >= lle->params.n200) { - /* FIXME: LLGM-STATUS-IND, LL-RELEASE-IND/CNF */ - lle->state = GPRS_LLES_ASSIGNED_ADM; - } - - switch (lle->state) { - case GPRS_LLES_LOCAL_EST: - /* FIXME: retransmit SABM */ - /* FIXME: re-start T200 */ - lle->retrans_ctr++; - break; - case GPRS_LLES_LOCAL_REL: - /* FIXME: retransmit DISC */ - /* FIXME: re-start T200 */ - lle->retrans_ctr++; - break; - default: - LOGP(DLLC, LOGL_ERROR, "LLC unhandled state: %d\n", lle->state); - break; - } - -} - -static void t201_expired(void *data) -{ - struct gprs_llc_lle *lle = data; - - if (lle->retrans_ctr < lle->params.n200) { - /* FIXME: transmit apropriate supervisory frame (8.6.4.1) */ - /* FIXME: set timer T201 */ - lle->retrans_ctr++; - } -} -#endif - -int gprs_llc_tx_u(struct msgb *msg, uint8_t sapi, int command, - enum gprs_llc_u_cmd u_cmd, int pf_bit) -{ - uint8_t *fcs, *llch; - uint8_t addr, ctrl; - uint32_t fcs_calc; - - /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ - - /* Address Field */ - addr = sapi & 0xf; - if (command) - addr |= 0x40; - - /* 6.3 Figure 8 */ - ctrl = 0xe0 | u_cmd; - if (pf_bit) - ctrl |= 0x10; - - /* prepend LLC UI header */ - llch = msgb_push(msg, 2); - llch[0] = addr; - llch[1] = ctrl; - - /* append FCS to end of frame */ - fcs = msgb_put(msg, 3); - fcs_calc = gprs_llc_fcs(llch, fcs - llch); - fcs[0] = fcs_calc & 0xff; - fcs[1] = (fcs_calc >> 8) & 0xff; - fcs[2] = (fcs_calc >> 16) & 0xff; - - /* Identifiers passed down: (BVCI, NSEI) */ - - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_LLC_DL_PACKETS]); - rate_ctr_add(&sgsn->rate_ctrs->ctr[CTR_LLC_DL_BYTES], msg->len); - - /* Send BSSGP-DL-UNITDATA.req */ - return _bssgp_tx_dl_ud(msg, NULL); -} - -/* Send XID response to LLE */ -static int gprs_llc_tx_xid(struct gprs_llc_lle *lle, struct msgb *msg, - int command) -{ - /* copy identifiers from LLE to ensure lower layers can route */ - msgb_tlli(msg) = lle->llme->tlli; - msgb_bvci(msg) = lle->llme->bvci; - msgb_nsei(msg) = lle->llme->nsei; - - return gprs_llc_tx_u(msg, lle->sapi, command, GPRS_LLC_U_XID, 1); -} - -/* encrypt information field + FCS, if needed! */ -static int apply_gea(struct gprs_llc_lle *lle, uint16_t crypt_len, uint16_t nu, - uint32_t oc, uint8_t sapi, uint8_t *fcs, uint8_t *data) -{ - uint8_t cipher_out[GSM0464_CIPH_MAX_BLOCK]; - - if (lle->llme->algo == GPRS_ALGO_GEA0) - return -EINVAL; - - /* Compute the 'Input' Paraemeter */ - uint32_t fcs_calc, iv = gprs_cipher_gen_input_ui(lle->llme->iov_ui, sapi, - nu, oc); - /* Compute gamma that we need to XOR with the data */ - int r = gprs_cipher_run(cipher_out, crypt_len, lle->llme->algo, - lle->llme->kc, iv, - fcs ? GPRS_CIPH_SGSN2MS : GPRS_CIPH_MS2SGSN); - if (r < 0) { - LOGP(DLLC, LOGL_ERROR, "Error producing %s gamma for UI " - "frame: %d\n", get_value_string(gprs_cipher_names, - lle->llme->algo), r); - return -ENOMSG; - } - - if (fcs) { - /* Mark frame as encrypted and update FCS */ - data[2] |= 0x02; - fcs_calc = gprs_llc_fcs(data, fcs - data); - fcs[0] = fcs_calc & 0xff; - fcs[1] = (fcs_calc >> 8) & 0xff; - fcs[2] = (fcs_calc >> 16) & 0xff; - data += 3; - } - - /* XOR the cipher output with the data */ - for (r = 0; r < crypt_len; r++) - *(data + r) ^= cipher_out[r]; - - return 0; -} - -/* Transmit a UI frame over the given SAPI: - 'encryptable' indicates whether particular message can be encrypted according - to 3GPP TS 24.008 § 4.7.1.2 - */ -int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command, - struct sgsn_mm_ctx *mmctx, bool encryptable) -{ - struct gprs_llc_lle *lle; - uint8_t *fcs, *llch; - uint8_t addr, ctrl[2]; - uint32_t fcs_calc; - uint16_t nu = 0; - uint32_t oc; - - /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ - - /* look-up or create the LL Entity for this (TLLI, SAPI) tuple */ - lle = gprs_lle_get_or_create(msgb_tlli(msg), sapi); - - if (msg->len > lle->params.n201_u) { - LOGP(DLLC, LOGL_ERROR, "Cannot Tx %u bytes (N201-U=%u)\n", - msg->len, lle->params.n201_u); - msgb_free(msg); - return -EFBIG; - } - - gprs_llme_copy_key(mmctx, lle->llme); - - /* Update LLE's (BVCI, NSEI) tuple */ - lle->llme->bvci = msgb_bvci(msg); - lle->llme->nsei = msgb_nsei(msg); - - /* Obtain current values for N(u) and OC */ - nu = lle->vu_send; - oc = lle->oc_ui_send; - /* Increment V(U) */ - lle->vu_send = (lle->vu_send + 1) % 512; - /* Increment Overflow Counter, if needed */ - if ((lle->vu_send + 1) / 512) - lle->oc_ui_send += 512; - - /* Address Field */ - addr = sapi & 0xf; - if (command) - addr |= 0x40; - - /* Control Field */ - ctrl[0] = 0xc0; - ctrl[0] |= nu >> 6; - ctrl[1] = (nu << 2) & 0xfc; - ctrl[1] |= 0x01; /* Protected Mode */ - - /* prepend LLC UI header */ - llch = msgb_push(msg, 3); - llch[0] = addr; - llch[1] = ctrl[0]; - llch[2] = ctrl[1]; - - /* append FCS to end of frame */ - fcs = msgb_put(msg, 3); - fcs_calc = gprs_llc_fcs(llch, fcs - llch); - fcs[0] = fcs_calc & 0xff; - fcs[1] = (fcs_calc >> 8) & 0xff; - fcs[2] = (fcs_calc >> 16) & 0xff; - - if (lle->llme->algo != GPRS_ALGO_GEA0 && encryptable) { - int rc = apply_gea(lle, fcs - llch, nu, oc, sapi, fcs, llch); - if (rc < 0) { - msgb_free(msg); - return rc; - } - } - - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_LLC_DL_PACKETS]); - rate_ctr_add(&sgsn->rate_ctrs->ctr[CTR_LLC_DL_BYTES], msg->len); - - /* Identifiers passed down: (BVCI, NSEI) */ - - /* Send BSSGP-DL-UNITDATA.req */ - return _bssgp_tx_dl_ud(msg, mmctx); -} - -static int gprs_llc_hdr_rx(struct gprs_llc_hdr_parsed *gph, - struct gprs_llc_lle *lle) -{ - switch (gph->cmd) { - case GPRS_LLC_SABM: /* Section 6.4.1.1 */ - lle->v_sent = lle->v_ack = lle->v_recv = 0; - if (lle->state == GPRS_LLES_ASSIGNED_ADM) { - /* start re-establishment (8.7.1) */ - } - lle->state = GPRS_LLES_REMOTE_EST; - /* FIXME: Send UA */ - lle->state = GPRS_LLES_ABM; - /* FIXME: process data */ - break; - case GPRS_LLC_DISC: /* Section 6.4.1.2 */ - /* FIXME: Send UA */ - /* terminate ABM */ - lle->state = GPRS_LLES_ASSIGNED_ADM; - break; - case GPRS_LLC_UA: /* Section 6.4.1.3 */ - if (lle->state == GPRS_LLES_LOCAL_EST) - lle->state = GPRS_LLES_ABM; - break; - case GPRS_LLC_DM: /* Section 6.4.1.4: ABM cannot be performed */ - if (lle->state == GPRS_LLES_LOCAL_EST) - lle->state = GPRS_LLES_ASSIGNED_ADM; - break; - case GPRS_LLC_FRMR: /* Section 6.4.1.5 */ - break; - case GPRS_LLC_XID: /* Section 6.4.1.6 */ - rx_llc_xid(lle, gph); - break; - case GPRS_LLC_UI: - if (gprs_llc_is_retransmit(gph->seq_tx, lle->vu_recv)) { - LOGP(DLLC, LOGL_NOTICE, - "TLLI=%08x dropping UI, N(U=%d) not in window V(URV(UR:%d).\n", - lle->llme ? lle->llme->tlli : -1, - gph->seq_tx, lle->vu_recv); - - /* HACK: non-standard recovery handling. If remote LLE - * is re-transmitting the same sequence number for - * three times, don't discard the frame but pass it on - * and 'learn' the new sequence number */ - if (gph->seq_tx != lle->vu_recv_last) { - lle->vu_recv_last = gph->seq_tx; - lle->vu_recv_duplicates = 0; - } else { - lle->vu_recv_duplicates++; - if (lle->vu_recv_duplicates < 3) - return -EIO; - LOGP(DLLC, LOGL_NOTICE, "TLLI=%08x recovering " - "N(U=%d) after receiving %u duplicates\n", - lle->llme ? lle->llme->tlli : -1, - gph->seq_tx, lle->vu_recv_duplicates); - } - } - /* Increment the sequence number that we expect in the next frame */ - lle->vu_recv = (gph->seq_tx + 1) % 512; - /* Increment Overflow Counter */ - if ((gph->seq_tx + 1) / 512) - lle->oc_ui_recv += 512; - break; - default: - LOGP(DLLC, LOGL_NOTICE, "Unhandled command: %d\n", gph->cmd); - break; - } - - return 0; -} - -/* receive an incoming LLC PDU (BSSGP-UL-UNITDATA-IND, 7.2.4.2) */ -int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv) -{ - struct gprs_llc_hdr *lh = (struct gprs_llc_hdr *) msgb_llch(msg); - struct gprs_llc_hdr_parsed llhp; - struct gprs_llc_lle *lle = NULL; - bool drop_cipherable = false; - int rc = 0; - - /* Identifiers from DOWN: NSEI, BVCI, TLLI */ - - memset(&llhp, 0, sizeof(llhp)); - rc = gprs_llc_hdr_parse(&llhp, (uint8_t *) lh, TLVP_LEN(tv, BSSGP_IE_LLC_PDU)); - if (rc < 0) { - LOGP(DLLC, LOGL_NOTICE, "Error during LLC header parsing\n"); - return rc; - } - - switch (gprs_tlli_type(msgb_tlli(msg))) { - case TLLI_LOCAL: - case TLLI_FOREIGN: - case TLLI_RANDOM: - case TLLI_AUXILIARY: - break; - default: - LOGP(DLLC, LOGL_ERROR, - "Discarding frame with strange TLLI type\n"); - break; - } - - /* find the LLC Entity for this TLLI+SAPI tuple */ - lle = lle_for_rx_by_tlli_sapi(msgb_tlli(msg), llhp.sapi, llhp.cmd); - if (!lle) { - switch (llhp.sapi) { - case GPRS_SAPI_SNDCP3: - case GPRS_SAPI_SNDCP5: - case GPRS_SAPI_SNDCP9: - case GPRS_SAPI_SNDCP11: - /* Ask an upper layer for help. */ - return gsm0408_gprs_force_reattach_oldmsg(msg, NULL); - default: - break; - } - return 0; - } - gprs_llc_hdr_dump(&llhp, lle); - /* reset age computation */ - lle->llme->age_timestamp = GPRS_LLME_RESET_AGE; - - /* decrypt information field + FCS, if needed! */ - if (llhp.is_encrypted) { - if (lle->llme->algo != GPRS_ALGO_GEA0) { - rc = apply_gea(lle, llhp.data_len + 3, llhp.seq_tx, - lle->oc_ui_recv, lle->sapi, NULL, - llhp.data); - if (rc < 0) - return rc; - llhp.fcs = *(llhp.data + llhp.data_len); - llhp.fcs |= *(llhp.data + llhp.data_len + 1) << 8; - llhp.fcs |= *(llhp.data + llhp.data_len + 2) << 16; - } else { - LOGP(DLLC, LOGL_NOTICE, "encrypted frame for LLC that " - "has no KC/Algo! Dropping.\n"); - return 0; - } - } else { - if (lle->llme->algo != GPRS_ALGO_GEA0 && - lle->llme->cksn != GSM_KEY_SEQ_INVAL) - drop_cipherable = true; - } - - /* We have to do the FCS check _after_ decryption */ - llhp.fcs_calc = gprs_llc_fcs((uint8_t *)lh, llhp.crc_length); - if (llhp.fcs != llhp.fcs_calc) { - LOGP(DLLC, LOGL_INFO, "Dropping frame with invalid FCS\n"); - return -EIO; - } - - /* Update LLE's (BVCI, NSEI) tuple */ - lle->llme->bvci = msgb_bvci(msg); - lle->llme->nsei = msgb_nsei(msg); - - /* Receive and Process the actual LLC frame */ - rc = gprs_llc_hdr_rx(&llhp, lle); - if (rc < 0) - return rc; - - rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_LLC_UL_PACKETS]); - rate_ctr_add(&sgsn->rate_ctrs->ctr[CTR_LLC_UL_BYTES], msg->len); - - /* llhp.data is only set when we need to send LL_[UNIT]DATA_IND up */ - if (llhp.cmd == GPRS_LLC_UI && llhp.data && llhp.data_len) { - msgb_gmmh(msg) = llhp.data; - switch (llhp.sapi) { - case GPRS_SAPI_GMM: - /* send LL_UNITDATA_IND to GMM */ - rc = gsm0408_gprs_rcvmsg_gb(msg, lle->llme, - drop_cipherable); - break; - case GPRS_SAPI_SNDCP3: - case GPRS_SAPI_SNDCP5: - case GPRS_SAPI_SNDCP9: - case GPRS_SAPI_SNDCP11: - /* send LL_DATA_IND/LL_UNITDATA_IND to SNDCP */ - rc = sndcp_llunitdata_ind(msg, lle, llhp.data, llhp.data_len); - break; - case GPRS_SAPI_SMS: - /* FIXME */ - case GPRS_SAPI_TOM2: - case GPRS_SAPI_TOM8: - /* FIXME: send LL_DATA_IND/LL_UNITDATA_IND to TOM */ - default: - LOGP(DLLC, LOGL_NOTICE, "Unsupported SAPI %u\n", llhp.sapi); - rc = -EINVAL; - break; - } - } - - return rc; -} - -/* Propagate crypto parameters MM -> LLME */ -void gprs_llme_copy_key(struct sgsn_mm_ctx *mm, struct gprs_llc_llme *llme) -{ - if (!mm) - return; - if (mm->ciph_algo != GPRS_ALGO_GEA0) { - llme->algo = mm->ciph_algo; - if (llme->cksn != mm->auth_triplet.key_seq && - mm->auth_triplet.key_seq != GSM_KEY_SEQ_INVAL) { - memcpy(llme->kc, mm->auth_triplet.vec.kc, - gprs_cipher_key_length(mm->ciph_algo)); - llme->cksn = mm->auth_triplet.key_seq; - } - } else - llme->cksn = GSM_KEY_SEQ_INVAL; -} - -/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */ -int gprs_llgmm_assign(struct gprs_llc_llme *llme, - uint32_t old_tlli, uint32_t new_tlli) -{ - unsigned int i; - - if (old_tlli == 0xffffffff && new_tlli != 0xffffffff) { - /* TLLI Assignment 8.3.1 */ - /* New TLLI shall be assigned and used when (re)transmitting LLC frames */ - /* If old TLLI != 0xffffffff was assigned to LLME, then TLLI - * old is unassigned. Only TLLI new shall be accepted when - * received from peer. */ - if (llme->old_tlli != 0xffffffff) { - llme->old_tlli = 0xffffffff; - llme->tlli = new_tlli; - } else { - /* If TLLI old == 0xffffffff was assigned to LLME, then this is - * TLLI assignmemt according to 8.3.1 */ - llme->old_tlli = 0xffffffff; - llme->tlli = new_tlli; - llme->state = GPRS_LLMS_ASSIGNED; - /* 8.5.3.1 For all LLE's */ - for (i = 0; i < ARRAY_SIZE(llme->lle); i++) { - struct gprs_llc_lle *l = &llme->lle[i]; - l->vu_send = l->vu_recv = 0; - l->retrans_ctr = 0; - l->state = GPRS_LLES_ASSIGNED_ADM; - /* FIXME Set parameters according to table 9 */ - } - } - } else if (old_tlli != 0xffffffff && new_tlli != 0xffffffff) { - /* TLLI Change 8.3.2 */ - /* Both TLLI Old and TLLI New are assigned; use New when - * (re)transmitting. Accept both Old and New on Rx */ - llme->old_tlli = old_tlli; - llme->tlli = new_tlli; - llme->state = GPRS_LLMS_ASSIGNED; - } else if (old_tlli != 0xffffffff && new_tlli == 0xffffffff) { - /* TLLI Unassignment 8.3.3) */ - llme->tlli = llme->old_tlli = 0; - llme->state = GPRS_LLMS_UNASSIGNED; - for (i = 0; i < ARRAY_SIZE(llme->lle); i++) { - struct gprs_llc_lle *l = &llme->lle[i]; - l->state = GPRS_LLES_UNASSIGNED; - } - llme_free(llme); - } else - return -EINVAL; - - return 0; -} - -/* TLLI unassignment */ -int gprs_llgmm_unassign(struct gprs_llc_llme *llme) -{ - return gprs_llgmm_assign(llme, llme->tlli, 0xffffffff); -} - -/* Chapter 7.2.1.2 LLGMM-RESET.req */ -int gprs_llgmm_reset(struct gprs_llc_llme *llme) -{ - struct msgb *msg = msgb_alloc_headroom(4096, 1024, "LLC_XID"); - struct gprs_llc_lle *lle = &llme->lle[1]; - uint8_t xid_bytes[1024]; - int xid_bytes_len; - uint8_t *xid; - - LOGP(DLLC, LOGL_NOTICE, "LLGM Reset\n"); - if (RAND_bytes((uint8_t *) &llme->iov_ui, 4) != 1) { - LOGP(DLLC, LOGL_NOTICE, "RAND_bytes failed for LLC XID reset, " - "falling back to rand()\n"); - llme->iov_ui = rand(); - } - - /* Generate XID message */ - xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes, - sizeof(xid_bytes),llme->iov_ui,llme); - if (xid_bytes_len < 0) - return -EINVAL; - xid = msgb_put(msg, xid_bytes_len); - memcpy(xid, xid_bytes, xid_bytes_len); - - /* Reset some of the LLC parameters. See GSM 04.64, 8.5.3.1 */ - lle->vu_recv = 0; - lle->vu_send = 0; - lle->oc_ui_send = 0; - lle->oc_ui_recv = 0; - - /* FIXME: Start T200, wait for XID response */ - return gprs_llc_tx_xid(lle, msg, 1); -} - -int gprs_llgmm_reset_oldmsg(struct msgb* oldmsg, uint8_t sapi, - struct gprs_llc_llme *llme) -{ - struct msgb *msg = msgb_alloc_headroom(4096, 1024, "LLC_XID"); - uint8_t xid_bytes[1024]; - int xid_bytes_len; - uint8_t *xid; - - LOGP(DLLC, LOGL_NOTICE, "LLGM Reset\n"); - if (RAND_bytes((uint8_t *) &llme->iov_ui, 4) != 1) { - LOGP(DLLC, LOGL_NOTICE, "RAND_bytes failed for LLC XID reset, " - "falling back to rand()\n"); - llme->iov_ui = rand(); - } - - /* Generate XID message */ - xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes, - sizeof(xid_bytes),llme->iov_ui,llme); - if (xid_bytes_len < 0) - return -EINVAL; - xid = msgb_put(msg, xid_bytes_len); - memcpy(xid, xid_bytes, xid_bytes_len); - - /* FIXME: Start T200, wait for XID response */ - - msgb_tlli(msg) = msgb_tlli(oldmsg); - msgb_bvci(msg) = msgb_bvci(oldmsg); - msgb_nsei(msg) = msgb_nsei(oldmsg); - - return gprs_llc_tx_u(msg, sapi, 1, GPRS_LLC_U_XID, 1); -} - -int gprs_llc_init(const char *cipher_plugin_path) -{ - return gprs_cipher_load(cipher_plugin_path); -} diff --git a/src/gprs/gprs_llc_parse.c b/src/gprs/gprs_llc_parse.c deleted file mode 100644 index a5a7a7122..000000000 --- a/src/gprs/gprs_llc_parse.c +++ /dev/null @@ -1,251 +0,0 @@ -/* GPRS LLC protocol implementation as per 3GPP TS 04.64 */ - -/* (C) 2009-2010 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static const struct value_string llc_cmd_strs[] = { - { GPRS_LLC_NULL, "NULL" }, - { GPRS_LLC_RR, "RR" }, - { GPRS_LLC_ACK, "ACK" }, - { GPRS_LLC_RNR, "RNR" }, - { GPRS_LLC_SACK, "SACK" }, - { GPRS_LLC_DM, "DM" }, - { GPRS_LLC_DISC, "DISC" }, - { GPRS_LLC_UA, "UA" }, - { GPRS_LLC_SABM, "SABM" }, - { GPRS_LLC_FRMR, "FRMR" }, - { GPRS_LLC_XID, "XID" }, - { GPRS_LLC_UI, "UI" }, - { 0, NULL } -}; - -#define LLC_ALLOC_SIZE 16384 -#define UI_HDR_LEN 3 -#define N202 4 -#define CRC24_LENGTH 3 - -int gprs_llc_fcs(uint8_t *data, unsigned int len) -{ - uint32_t fcs_calc; - - fcs_calc = crc24_calc(INIT_CRC24, data, len); - fcs_calc = ~fcs_calc; - fcs_calc &= 0xffffff; - - return fcs_calc; -} - -void gprs_llc_hdr_dump(struct gprs_llc_hdr_parsed *gph, struct gprs_llc_lle *lle) -{ - const char *gea; - uint32_t iov_ui = 0; - if (lle) { - gea = get_value_string(gprs_cipher_names, lle->llme->algo); - iov_ui = lle->llme->iov_ui; - } else - gea = "GEA?"; - DEBUGP(DLLC, "LLC SAPI=%u %c %c %c %s IOV-UI=0x%06x FCS=0x%06x ", - gph->sapi, gph->is_cmd ? 'C' : 'R', gph->ack_req ? 'A' : ' ', - gph->is_encrypted ? 'E' : 'U', - gea, iov_ui, gph->fcs); - - if (gph->cmd) - DEBUGPC(DLLC, "CMD=%s ", get_value_string(llc_cmd_strs, gph->cmd)); - - if (gph->data) - DEBUGPC(DLLC, "DATA "); - - DEBUGPC(DLLC, "\n"); -} - -/* parse a GPRS LLC header, also check for invalid frames */ -int gprs_llc_hdr_parse(struct gprs_llc_hdr_parsed *ghp, - uint8_t *llc_hdr, int len) -{ - uint8_t *ctrl = llc_hdr+1; - - if (len <= CRC24_LENGTH) - return -EIO; - - ghp->crc_length = len - CRC24_LENGTH; - - ghp->ack_req = 0; - - /* Section 5.5: FCS */ - ghp->fcs = *(llc_hdr + len - 3); - ghp->fcs |= *(llc_hdr + len - 2) << 8; - ghp->fcs |= *(llc_hdr + len - 1) << 16; - - /* Section 6.2.1: invalid PD field */ - if (llc_hdr[0] & 0x80) - return -EIO; - - /* This only works for the MS->SGSN direction */ - if (llc_hdr[0] & 0x40) - ghp->is_cmd = 0; - else - ghp->is_cmd = 1; - - ghp->sapi = llc_hdr[0] & 0xf; - - /* Section 6.2.3: check for reserved SAPI */ - switch (ghp->sapi) { - case 0: - case 4: - case 6: - case 0xa: - case 0xc: - case 0xd: - case 0xf: - return -EINVAL; - } - - if ((ctrl[0] & 0x80) == 0) { - /* I (Information transfer + Supervisory) format */ - uint8_t k; - - ghp->data = ctrl + 3; - - if (ctrl[0] & 0x40) - ghp->ack_req = 1; - - ghp->seq_tx = (ctrl[0] & 0x1f) << 4; - ghp->seq_tx |= (ctrl[1] >> 4); - - ghp->seq_rx = (ctrl[1] & 0x7) << 6; - ghp->seq_rx |= (ctrl[2] >> 2); - - switch (ctrl[2] & 0x03) { - case 0: - ghp->cmd = GPRS_LLC_RR; - break; - case 1: - ghp->cmd = GPRS_LLC_ACK; - break; - case 2: - ghp->cmd = GPRS_LLC_RNR; - break; - case 3: - ghp->cmd = GPRS_LLC_SACK; - k = ctrl[3] & 0x1f; - ghp->data += 1 + k; - break; - } - ghp->data_len = (llc_hdr + len - 3) - ghp->data; - } else if ((ctrl[0] & 0xc0) == 0x80) { - /* S (Supervisory) format */ - ghp->data = NULL; - ghp->data_len = 0; - - if (ctrl[0] & 0x20) - ghp->ack_req = 1; - ghp->seq_rx = (ctrl[0] & 0x7) << 6; - ghp->seq_rx |= (ctrl[1] >> 2); - - switch (ctrl[1] & 0x03) { - case 0: - ghp->cmd = GPRS_LLC_RR; - break; - case 1: - ghp->cmd = GPRS_LLC_ACK; - break; - case 2: - ghp->cmd = GPRS_LLC_RNR; - break; - case 3: - ghp->cmd = GPRS_LLC_SACK; - break; - } - } else if ((ctrl[0] & 0xe0) == 0xc0) { - /* UI (Unconfirmed Inforamtion) format */ - ghp->cmd = GPRS_LLC_UI; - ghp->data = ctrl + 2; - ghp->data_len = (llc_hdr + len - 3) - ghp->data; - - ghp->seq_tx = (ctrl[0] & 0x7) << 6; - ghp->seq_tx |= (ctrl[1] >> 2); - if (ctrl[1] & 0x02) { - ghp->is_encrypted = 1; - /* FIXME: encryption */ - } - if (ctrl[1] & 0x01) { - /* FCS over hdr + all inf fields */ - } else { - /* FCS over hdr + N202 octets (4) */ - if (ghp->crc_length > UI_HDR_LEN + N202) - ghp->crc_length = UI_HDR_LEN + N202; - } - } else { - /* U (Unnumbered) format: 1 1 1 P/F M4 M3 M2 M1 */ - ghp->data = NULL; - ghp->data_len = 0; - - switch (ctrl[0] & 0xf) { - case GPRS_LLC_U_NULL_CMD: - ghp->cmd = GPRS_LLC_NULL; - break; - case GPRS_LLC_U_DM_RESP: - ghp->cmd = GPRS_LLC_DM; - break; - case GPRS_LLC_U_DISC_CMD: - ghp->cmd = GPRS_LLC_DISC; - break; - case GPRS_LLC_U_UA_RESP: - ghp->cmd = GPRS_LLC_UA; - break; - case GPRS_LLC_U_SABM_CMD: - ghp->cmd = GPRS_LLC_SABM; - break; - case GPRS_LLC_U_FRMR_RESP: - ghp->cmd = GPRS_LLC_FRMR; - break; - case GPRS_LLC_U_XID: - ghp->cmd = GPRS_LLC_XID; - ghp->data = ctrl + 1; - ghp->data_len = (llc_hdr + len - 3) - ghp->data; - break; - default: - return -EIO; - } - } - - /* FIXME: parse sack frame */ - if (ghp->cmd == GPRS_LLC_SACK) { - LOGP(DLLC, LOGL_NOTICE, "Unsupported SACK frame\n"); - return -EIO; - } - - return 0; -} diff --git a/src/gprs/gprs_llc_vty.c b/src/gprs/gprs_llc_vty.c deleted file mode 100644 index bf34e9782..000000000 --- a/src/gprs/gprs_llc_vty.c +++ /dev/null @@ -1,116 +0,0 @@ -/* VTY interface for our GPRS LLC implementation */ - -/* (C) 2010 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -struct value_string gprs_llc_state_strs[] = { - { GPRS_LLES_UNASSIGNED, "TLLI Unassigned" }, - { GPRS_LLES_ASSIGNED_ADM, "TLLI Assigned" }, - { GPRS_LLES_LOCAL_EST, "Local Establishment" }, - { GPRS_LLES_REMOTE_EST, "Remote Establishment" }, - { GPRS_LLES_ABM, "Asynchronous Balanced Mode" }, - { GPRS_LLES_LOCAL_REL, "Local Release" }, - { GPRS_LLES_TIMER_REC, "Timer Recovery" }, - { 0, NULL } -}; - -static void vty_dump_lle(struct vty *vty, struct gprs_llc_lle *lle) -{ - struct gprs_llc_params *par = &lle->params; - vty_out(vty, " SAPI %2u State %s VUsend=%u, VUrecv=%u", lle->sapi, - get_value_string(gprs_llc_state_strs, lle->state), - lle->vu_send, lle->vu_recv); - vty_out(vty, " Vsent=%u Vack=%u Vrecv=%u, RetransCtr=%u%s", - lle->v_sent, lle->v_ack, lle->v_recv, - lle->retrans_ctr, VTY_NEWLINE); - vty_out(vty, " T200=%u, N200=%u, N201-U=%u, N201-I=%u, mD=%u, " - "mU=%u, kD=%u, kU=%u%s", par->t200_201, par->n200, - par->n201_u, par->n201_i, par->mD, par->mU, par->kD, - par->kU, VTY_NEWLINE); -} - -static uint8_t valid_sapis[] = { 1, 2, 3, 5, 7, 8, 9, 11 }; - -static void vty_dump_llme(struct vty *vty, struct gprs_llc_llme *llme) -{ - unsigned int i; - struct timespec now_tp = {0}; - clock_gettime(CLOCK_MONOTONIC, &now_tp); - - vty_out(vty, "TLLI %08x (Old TLLI %08x) BVCI=%u NSEI=%u %s: " - "IOV-UI=0x%06x CKSN=%d Age=%d: State %s%s", llme->tlli, - llme->old_tlli, llme->bvci, llme->nsei, - get_value_string(gprs_cipher_names, llme->algo), llme->iov_ui, - llme->cksn, llme->age_timestamp == GPRS_LLME_RESET_AGE ? 0 : - (int)(now_tp.tv_sec - (time_t)llme->age_timestamp), - get_value_string(gprs_llc_state_strs, llme->state), VTY_NEWLINE); - - for (i = 0; i < ARRAY_SIZE(valid_sapis); i++) { - struct gprs_llc_lle *lle; - uint8_t sapi = valid_sapis[i]; - - if (sapi >= ARRAY_SIZE(llme->lle)) - continue; - - lle = &llme->lle[sapi]; - vty_dump_lle(vty, lle); - } -} - - -DEFUN(show_llc, show_llc_cmd, - "show llc", - SHOW_STR "Display information about the LLC protocol") -{ - struct gprs_llc_llme *llme; - - vty_out(vty, "State of LLC Entities%s", VTY_NEWLINE); - llist_for_each_entry(llme, &gprs_llc_llmes, list) { - vty_dump_llme(vty, llme); - } - return CMD_SUCCESS; -} - -int gprs_llc_vty_init(void) -{ - install_element_ve(&show_llc_cmd); - - return 0; -} diff --git a/src/gprs/gprs_llc_xid.c b/src/gprs/gprs_llc_xid.c deleted file mode 100644 index fe631715a..000000000 --- a/src/gprs/gprs_llc_xid.c +++ /dev/null @@ -1,281 +0,0 @@ -/* GPRS LLC XID field encoding/decoding as per 3GPP TS 44.064 */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -const struct value_string gprs_llc_xid_type_names[] = { - { GPRS_LLC_XID_T_VERSION, "VERSION"}, - { GPRS_LLC_XID_T_IOV_UI, "IOV_UI"}, - { GPRS_LLC_XID_T_IOV_I, "IOV_I"}, - { GPRS_LLC_XID_T_T200, "T200"}, - { GPRS_LLC_XID_T_N200, "N200"}, - { GPRS_LLC_XID_T_N201_U, "N201_"}, - { GPRS_LLC_XID_T_N201_I, "N201_I"}, - { GPRS_LLC_XID_T_mD, "mD"}, - { GPRS_LLC_XID_T_mU, "mU"}, - { GPRS_LLC_XID_T_kD, "kD"}, - { GPRS_LLC_XID_T_kU, "kU"}, - { GPRS_LLC_XID_T_L3_PAR, "L3_PAR"}, - { GPRS_LLC_XID_T_RESET, "RESET"}, - { 0, NULL }, -}; - -/* Parse XID parameter field */ -static int decode_xid_field(struct gprs_llc_xid_field *xid_field, - const uint8_t *src, uint8_t src_len) -{ - uint8_t xl; - uint8_t type; - uint8_t len; - int src_counter = 0; - - /* Exit immediately if it is clear that no - * parseable data is present */ - if (src_len < 1 || !src) - return -EINVAL; - - /* Extract header info */ - xl = (*src >> 7) & 1; - type = (*src >> 2) & 0x1F; - - /* Extract length field */ - len = (*src) & 0x3; - src++; - src_counter++; - if (xl) { - if (src_len < 2) - return -EINVAL; - len = (len << 6) & 0xC0; - len |= ((*src) >> 2) & 0x3F; - src++; - src_counter++; - } - - /* Fill out struct */ - xid_field->type = type; - xid_field->data_len = len; - if (len > 0) { - if (src_len < src_counter + len) - return -EINVAL; - xid_field->data = - talloc_memdup(xid_field,src,xid_field->data_len); - } else - xid_field->data = NULL; - - /* Return consumed length */ - return src_counter + len; -} - -/* Encode XID parameter field */ -static int encode_xid_field(uint8_t *dst, int dst_maxlen, - const struct gprs_llc_xid_field *xid_field) -{ - int xl = 0; - - /* When the length does not fit into 2 bits, - * we need extended length fields */ - if (xid_field->data_len > 3) - xl = 1; - - /* Exit immediately if it is clear that no - * encoding result can be stored */ - if (dst_maxlen < xid_field->data_len + 1 + xl) - return -EINVAL; - - /* There are only 5 bits reserved for the type, exit on exceed */ - if (xid_field->type > 31) - return -EINVAL; - - /* Encode header */ - memset(dst, 0, dst_maxlen); - if (xl) - dst[0] |= 0x80; - dst[0] |= (((xid_field->type) & 0x1F) << 2); - - if (xl) { - dst[0] |= (((xid_field->data_len) >> 6) & 0x03); - dst[1] = ((xid_field->data_len) << 2) & 0xFC; - } else - dst[0] |= ((xid_field->data_len) & 0x03); - - /* Append payload data */ - if (xid_field->data && xid_field->data_len) - memcpy(dst + 1 + xl, xid_field->data, xid_field->data_len); - - /* Return generated length */ - return xid_field->data_len + 1 + xl; -} - -/* Transform a list with XID fields into a XID message (dst) */ -int gprs_llc_compile_xid(uint8_t *dst, int dst_maxlen, - const struct llist_head *xid_fields) -{ - struct gprs_llc_xid_field *xid_field; - int rc; - int byte_counter = 0; - - OSMO_ASSERT(xid_fields); - OSMO_ASSERT(dst); - - llist_for_each_entry_reverse(xid_field, xid_fields, list) { - /* Encode XID-Field */ - rc = encode_xid_field(dst, dst_maxlen, xid_field); - if (rc < 0) - return -EINVAL; - - /* Advance pointer and lower maxlen for the - * next encoding round */ - dst += rc; - byte_counter += rc; - dst_maxlen -= rc; - } - - /* Return generated length */ - return byte_counter; -} - -/* Transform a XID message (dst) into a list of XID fields */ -struct llist_head *gprs_llc_parse_xid(const void *ctx, const uint8_t *src, - int src_len) -{ - struct gprs_llc_xid_field *xid_field; - struct llist_head *xid_fields; - - int rc; - int max_loops = src_len; - - OSMO_ASSERT(src); - - xid_fields = talloc_zero(ctx, struct llist_head); - INIT_LLIST_HEAD(xid_fields); - - while (1) { - /* Bail in case decode_xid_field() constantly returns zero */ - if (max_loops <= 0) { - talloc_free(xid_fields); - return NULL; - } - - /* Decode XID field */ - xid_field = talloc_zero(xid_fields, struct gprs_llc_xid_field); - rc = decode_xid_field(xid_field, src, src_len); - - /* Immediately stop on error */ - if (rc < 0) { - talloc_free(xid_fields); - return NULL; - } - - /* Add parsed XID field to list */ - llist_add(&xid_field->list, xid_fields); - - /* Advance pointer and lower dst_len for the next - * decoding round */ - src += rc; - src_len -= rc; - - /* We are (scuccessfully) done when no further byes are left */ - if (src_len == 0) - return xid_fields; - - max_loops--; - } -} - -/* Create a duplicate of an XID-Field */ -struct gprs_llc_xid_field *gprs_llc_dup_xid_field(const void *ctx, const struct - gprs_llc_xid_field - *xid_field) -{ - struct gprs_llc_xid_field *dup; - - OSMO_ASSERT(xid_field); - - /* Create a copy of the XID field in memory */ - dup = talloc_memdup(ctx, xid_field, sizeof(*xid_field)); - dup->data = talloc_memdup(ctx, xid_field->data, xid_field->data_len); - - /* Unlink duplicate from source list */ - INIT_LLIST_HEAD(&dup->list); - - return dup; -} - -/* Copy an llist with xid fields */ -struct llist_head *gprs_llc_copy_xid(const void *ctx, - const struct llist_head *xid_fields) -{ - struct gprs_llc_xid_field *xid_field; - struct llist_head *xid_fields_copy; - - OSMO_ASSERT(xid_fields); - - xid_fields_copy = talloc_zero(ctx, struct llist_head); - INIT_LLIST_HEAD(xid_fields_copy); - - /* Create duplicates and add them to the target list */ - llist_for_each_entry(xid_field, xid_fields, list) { - llist_add(&gprs_llc_dup_xid_field(ctx, xid_field)->list, - xid_fields_copy); - } - - return xid_fields_copy; -} - -/* Dump a list with XID fields (Debug) */ -void gprs_llc_dump_xid_fields(const struct llist_head *xid_fields, - unsigned int logl) -{ - struct gprs_llc_xid_field *xid_field; - - OSMO_ASSERT(xid_fields); - - llist_for_each_entry(xid_field, xid_fields, list) { - if (xid_field->data_len) { - OSMO_ASSERT(xid_field->data); - LOGP(DLLC, logl, - "XID: type %s, data_len=%d, data=%s\n", - get_value_string(gprs_llc_xid_type_names, - xid_field->type), - xid_field->data_len, - osmo_hexdump_nospc(xid_field->data, - xid_field->data_len)); - } else { - LOGP(DLLC, logl, - "XID: type=%d, data_len=%d, data=NULL\n", - xid_field->type, xid_field->data_len); - } - } -} diff --git a/src/gprs/gprs_sgsn.c b/src/gprs/gprs_sgsn.c deleted file mode 100644 index de79afb1a..000000000 --- a/src/gprs/gprs_sgsn.c +++ /dev/null @@ -1,933 +0,0 @@ -/* GPRS SGSN functionality */ - -/* (C) 2009 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "openbsc/gprs_llc.h" - -#include - -#include - -#include - -#include "../../bscconfig.h" - -#if BUILD_IU -#include -#endif - -#define GPRS_LLME_CHECK_TICK 30 - -extern struct sgsn_instance *sgsn; - -LLIST_HEAD(sgsn_mm_ctxts); -LLIST_HEAD(sgsn_ggsn_ctxts); -LLIST_HEAD(sgsn_apn_ctxts); -LLIST_HEAD(sgsn_pdp_ctxts); - -static const struct rate_ctr_desc mmctx_ctr_description[] = { - { "sign.packets.in", "Signalling Messages ( In)" }, - { "sign.packets.out", "Signalling Messages (Out)" }, - { "udata.packets.in", "User Data Messages ( In)" }, - { "udata.packets.out", "User Data Messages (Out)" }, - { "udata.bytes.in", "User Data Bytes ( In)" }, - { "udata.bytes.out", "User Data Bytes (Out)" }, - { "pdp_ctx_act", "PDP Context Activations " }, - { "suspend", "SUSPEND Count " }, - { "paging.ps", "Paging Packet Switched " }, - { "paging.cs", "Paging Circuit Switched " }, - { "ra_update", "Routing Area Update " }, -}; - -static const struct rate_ctr_group_desc mmctx_ctrg_desc = { - .group_name_prefix = "sgsn.mmctx", - .group_description = "SGSN MM Context Statistics", - .num_ctr = ARRAY_SIZE(mmctx_ctr_description), - .ctr_desc = mmctx_ctr_description, - .class_id = OSMO_STATS_CLASS_SUBSCRIBER, -}; - -static const struct rate_ctr_desc pdpctx_ctr_description[] = { - { "udata.packets.in", "User Data Messages ( In)" }, - { "udata.packets.out", "User Data Messages (Out)" }, - { "udata.bytes.in", "User Data Bytes ( In)" }, - { "udata.bytes.out", "User Data Bytes (Out)" }, -}; - -static const struct rate_ctr_group_desc pdpctx_ctrg_desc = { - .group_name_prefix = "sgsn.pdpctx", - .group_description = "SGSN PDP Context Statistics", - .num_ctr = ARRAY_SIZE(pdpctx_ctr_description), - .ctr_desc = pdpctx_ctr_description, - .class_id = OSMO_STATS_CLASS_SUBSCRIBER, -}; - -static const struct rate_ctr_desc sgsn_ctr_description[] = { - { "llc.dl_bytes", "Count sent LLC bytes before giving it to the bssgp layer" }, - { "llc.ul_bytes", "Count sucessful received LLC bytes (encrypt & fcs correct)" }, - { "llc.dl_packets", "Count sucessful sent LLC packets before giving it to the bssgp layer" }, - { "llc.ul_packets", "Count sucessful received LLC packets (encrypt & fcs correct)" }, - { "gprs.attach_requested", "Received attach requests" }, - { "gprs.attach_accepted", "Sent attach accepts" }, - { "gprs.attach_rejected", "Sent attach rejects" }, - { "gprs.detach_requested", "Received detach requests" }, - { "gprs.detach_acked", "Sent detach acks" }, - { "gprs.routing_area_requested", "Received routing area requests" }, - { "gprs.routing_area_requested", "Sent routing area acks" }, - { "gprs.routing_area_requested", "Sent routing area rejects" }, - { "pdp.activate_requested", "Received activate requests" }, - { "pdp.activate_rejected", "Sent activate rejects" }, - { "pdp.activate_accepted", "Sent activate accepts" }, - { "pdp.request_activated", "unused" }, - { "pdp.request_activate_rejected", "unused" }, - { "pdp.modify_requested", "unused" }, - { "pdp.modify_accepted", "unused" }, - { "pdp.dl_deactivate_requested", "Sent deactivate requests" }, - { "pdp.dl_deactivate_accepted", "Sent deactivate accepted" }, - { "pdp.ul_deactivate_requested", "Received deactivate requests" }, - { "pdp.ul_deactivate_accepted", "Received deactivate accepts" }, -}; - -static const struct rate_ctr_group_desc sgsn_ctrg_desc = { - "sgsn", - "SGSN Overall Statistics", - OSMO_STATS_CLASS_GLOBAL, - ARRAY_SIZE(sgsn_ctr_description), - sgsn_ctr_description, -}; - -void sgsn_rate_ctr_init() { - sgsn->rate_ctrs = rate_ctr_group_alloc(tall_bsc_ctx, &sgsn_ctrg_desc, 0); - OSMO_ASSERT(sgsn->rate_ctrs); -} - -/* look-up an SGSN MM context based on Iu UE context (struct ue_conn_ctx)*/ -struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx) -{ - struct sgsn_mm_ctx *ctx; - - llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { - if (ctx->ran_type == MM_CTX_T_UTRAN_Iu - && uectx == ctx->iu.ue_ctx) - return ctx; - } - - return NULL; -} - -/* look-up a SGSN MM context based on TLLI + RAI */ -struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, - const struct gprs_ra_id *raid) -{ - struct sgsn_mm_ctx *ctx; - - llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { - if ((tlli == ctx->gb.tlli || tlli == ctx->gb.tlli_new) && - gprs_ra_id_equals(raid, &ctx->ra)) - return ctx; - } - - return NULL; -} - -struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli, - const struct gprs_ra_id *raid) -{ - struct sgsn_mm_ctx *ctx; - int tlli_type; - - /* TODO: Also check the P_TMSI signature to be safe. That signature - * should be different (at least with a sufficiently high probability) - * after SGSN restarts and for multiple SGSN instances. - */ - - tlli_type = gprs_tlli_type(tlli); - if (tlli_type != TLLI_FOREIGN && tlli_type != TLLI_LOCAL) - return NULL; - - llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { - if ((gprs_tmsi2tlli(ctx->p_tmsi, tlli_type) == tlli || - gprs_tmsi2tlli(ctx->p_tmsi_old, tlli_type) == tlli) && - gprs_ra_id_equals(raid, &ctx->ra)) - return ctx; - } - - return NULL; -} - -struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t p_tmsi) -{ - struct sgsn_mm_ctx *ctx; - - llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { - if (p_tmsi == ctx->p_tmsi || - (ctx->p_tmsi_old && ctx->p_tmsi_old == p_tmsi)) - return ctx; - } - return NULL; -} - -struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi) -{ - struct sgsn_mm_ctx *ctx; - - llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { - if (!strcmp(imsi, ctx->imsi)) - return ctx; - } - return NULL; - -} - -/* Allocate a new SGSN MM context for GERAN_Gb */ -struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli, - const struct gprs_ra_id *raid) -{ - struct sgsn_mm_ctx *ctx; - - ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx); - if (!ctx) - return NULL; - - memcpy(&ctx->ra, raid, sizeof(ctx->ra)); - ctx->ran_type = MM_CTX_T_GERAN_Gb; - ctx->gb.tlli = tlli; - ctx->gmm_state = GMM_DEREGISTERED; - ctx->pmm_state = MM_IDLE; - ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL; - ctx->ciph_algo = sgsn->cfg.cipher; - LOGMMCTXP(LOGL_DEBUG, ctx, "Allocated with %s cipher.\n", - get_value_string(gprs_cipher_names, ctx->ciph_algo)); - ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, tlli); - if (!ctx->ctrg) { - LOGMMCTXP(LOGL_ERROR, ctx, "Cannot allocate counter group\n"); - talloc_free(ctx); - return NULL; - } - INIT_LLIST_HEAD(&ctx->pdp_list); - - llist_add(&ctx->list, &sgsn_mm_ctxts); - - return ctx; -} - -/* Allocate a new SGSN MM context */ -struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx) -{ -#if BUILD_IU - struct sgsn_mm_ctx *ctx; - - ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx); - if (!ctx) - return NULL; - - ctx->ran_type = MM_CTX_T_UTRAN_Iu; - ctx->iu.ue_ctx = uectx; - ctx->iu.ue_ctx->rab_assign_addr_enc = sgsn->cfg.iu.rab_assign_addr_enc; - ctx->iu.new_key = 1; - ctx->gmm_state = GMM_DEREGISTERED; - ctx->pmm_state = PMM_DETACHED; - ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL; - ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0); - if (!ctx->ctrg) { - LOGMMCTXP(LOGL_ERROR, ctx, "Cannot allocate counter group\n"); - talloc_free(ctx); - return NULL; - } - - /* Need to get RAID from IU conn */ - ctx->ra = ctx->iu.ue_ctx->ra_id; - - INIT_LLIST_HEAD(&ctx->pdp_list); - - llist_add(&ctx->list, &sgsn_mm_ctxts); - - return ctx; -#else - return NULL; -#endif -} - - -/* this is a hard _free_ function, it doesn't clean up the PDP contexts - * in libgtp! */ -static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm) -{ - struct sgsn_pdp_ctx *pdp, *pdp2; - - /* Unlink from global list of MM contexts */ - llist_del(&mm->list); - - /* Free all PDP contexts */ - llist_for_each_entry_safe(pdp, pdp2, &mm->pdp_list, list) - sgsn_pdp_ctx_free(pdp); - - rate_ctr_group_free(mm->ctrg); - - talloc_free(mm); -} - -void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm) -{ - struct gprs_llc_llme *llme = NULL; - uint32_t tlli = mm->gb.tlli; - struct sgsn_pdp_ctx *pdp, *pdp2; - struct sgsn_signal_data sig_data; - - if (mm->ran_type == MM_CTX_T_GERAN_Gb) - llme = mm->gb.llme; - else - OSMO_ASSERT(mm->gb.llme == NULL); - - /* Forget about ongoing look-ups */ - if (mm->ggsn_lookup) { - LOGMMCTXP(LOGL_NOTICE, mm, - "Cleaning mmctx with on-going query.\n"); - mm->ggsn_lookup->mmctx = NULL; - mm->ggsn_lookup = NULL; - } - - /* delete all existing PDP contexts for this MS */ - llist_for_each_entry_safe(pdp, pdp2, &mm->pdp_list, list) { - LOGMMCTXP(LOGL_NOTICE, mm, - "Dropping PDP context for NSAPI=%u\n", pdp->nsapi); - sgsn_pdp_ctx_terminate(pdp); - } - - if (osmo_timer_pending(&mm->timer)) { - LOGMMCTXP(LOGL_INFO, mm, "Cancelling MM timer %u\n", mm->T); - osmo_timer_del(&mm->timer); - } - - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.mm = mm; - osmo_signal_dispatch(SS_SGSN, S_SGSN_MM_FREE, &sig_data); - - - /* Detach from subscriber which is possibly freed then */ - if (mm->subscr) { - struct gprs_subscr *subscr = gprs_subscr_get(mm->subscr); - gprs_subscr_cleanup(subscr); - gprs_subscr_put(subscr); - } - - sgsn_mm_ctx_free(mm); - mm = NULL; - - if (llme) { - /* TLLI unassignment, must be called after sgsn_mm_ctx_free */ - gprs_llgmm_assign(llme, tlli, 0xffffffff); - } -} - - -/* look up PDP context by MM context and NSAPI */ -struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm, - uint8_t nsapi) -{ - struct sgsn_pdp_ctx *pdp; - - llist_for_each_entry(pdp, &mm->pdp_list, list) { - if (pdp->nsapi == nsapi) - return pdp; - } - return NULL; -} - -/* look up PDP context by MM context and transaction ID */ -struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm, - uint8_t tid) -{ - struct sgsn_pdp_ctx *pdp; - - llist_for_each_entry(pdp, &mm->pdp_list, list) { - if (pdp->ti == tid) - return pdp; - } - return NULL; -} - -/* you don't want to use this directly, call sgsn_create_pdp_ctx() */ -struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm, - uint8_t nsapi) -{ - struct sgsn_pdp_ctx *pdp; - - pdp = sgsn_pdp_ctx_by_nsapi(mm, nsapi); - if (pdp) - return NULL; - - pdp = talloc_zero(tall_bsc_ctx, struct sgsn_pdp_ctx); - if (!pdp) - return NULL; - - pdp->mm = mm; - pdp->nsapi = nsapi; - pdp->ctrg = rate_ctr_group_alloc(pdp, &pdpctx_ctrg_desc, nsapi); - if (!pdp->ctrg) { - LOGPDPCTXP(LOGL_ERROR, pdp, "Error allocation counter group\n"); - talloc_free(pdp); - return NULL; - } - llist_add(&pdp->list, &mm->pdp_list); - llist_add(&pdp->g_list, &sgsn_pdp_ctxts); - - return pdp; -} - -/* - * This function will not trigger any GSM DEACT PDP ACK messages, so you - * probably want to call sgsn_delete_pdp_ctx() instead if the connection - * isn't detached already. - */ -void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp) -{ - struct sgsn_signal_data sig_data; - - OSMO_ASSERT(pdp->mm != NULL); - - /* There might still be pending callbacks in libgtp. So the parts of - * this object relevant to GTP need to remain intact in this case. */ - - LOGPDPCTXP(LOGL_INFO, pdp, "Forcing release of PDP context\n"); - - if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) { - /* Force the deactivation of the SNDCP layer */ - sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi); - } - - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.pdp = pdp; - osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_TERMINATE, &sig_data); - - /* Detach from MM context */ - llist_del(&pdp->list); - pdp->mm = NULL; - - sgsn_delete_pdp_ctx(pdp); -} - -/* - * Don't call this function directly unless you know what you are doing. - * In normal conditions use sgsn_delete_pdp_ctx and in unspecified or - * implementation dependent abnormal ones sgsn_pdp_ctx_terminate. - */ -void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp) -{ - struct sgsn_signal_data sig_data; - - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.pdp = pdp; - osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_FREE, &sig_data); - - rate_ctr_group_free(pdp->ctrg); - if (pdp->mm) - llist_del(&pdp->list); - llist_del(&pdp->g_list); - - /* _if_ we still have a library handle, at least set it to NULL - * to avoid any dereferences of the now-deleted PDP context from - * sgsn_libgtp:cb_data_ind() */ - if (pdp->lib) { - struct pdp_t *lib = pdp->lib; - LOGPDPCTXP(LOGL_NOTICE, pdp, "freeing PDP context that still " - "has a libgtp handle attached to it, this shouldn't " - "happen!\n"); - osmo_generate_backtrace(); - lib->priv = NULL; - } - - if (pdp->destroy_ggsn) - sgsn_ggsn_ctx_free(pdp->ggsn); - talloc_free(pdp); -} - -/* GGSN contexts */ - -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id) -{ - struct sgsn_ggsn_ctx *ggc; - - ggc = talloc_zero(tall_bsc_ctx, struct sgsn_ggsn_ctx); - if (!ggc) - return NULL; - - ggc->id = id; - ggc->gtp_version = 1; - ggc->remote_restart_ctr = -1; - /* if we are called from config file parse, this gsn doesn't exist yet */ - ggc->gsn = sgsn->gsn; - llist_add(&ggc->list, &sgsn_ggsn_ctxts); - - return ggc; -} - -void sgsn_ggsn_ctx_free(struct sgsn_ggsn_ctx *ggc) -{ - llist_del(&ggc->list); - talloc_free(ggc); -} - -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_id(uint32_t id) -{ - struct sgsn_ggsn_ctx *ggc; - - llist_for_each_entry(ggc, &sgsn_ggsn_ctxts, list) { - if (id == ggc->id) - return ggc; - } - return NULL; -} - -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_addr(struct in_addr *addr) -{ - struct sgsn_ggsn_ctx *ggc; - - llist_for_each_entry(ggc, &sgsn_ggsn_ctxts, list) { - if (!memcmp(addr, &ggc->remote_addr, sizeof(*addr))) - return ggc; - } - return NULL; -} - - -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id) -{ - struct sgsn_ggsn_ctx *ggc; - - ggc = sgsn_ggsn_ctx_by_id(id); - if (!ggc) - ggc = sgsn_ggsn_ctx_alloc(id); - return ggc; -} - -/* APN contexts */ - -static struct apn_ctx *sgsn_apn_ctx_alloc(const char *ap_name, const char *imsi_prefix) -{ - struct apn_ctx *actx; - - actx = talloc_zero(tall_bsc_ctx, struct apn_ctx); - if (!actx) - return NULL; - actx->name = talloc_strdup(actx, ap_name); - actx->imsi_prefix = talloc_strdup(actx, imsi_prefix); - - llist_add_tail(&actx->list, &sgsn_apn_ctxts); - - return actx; -} - -void sgsn_apn_ctx_free(struct apn_ctx *actx) -{ - llist_del(&actx->list); - talloc_free(actx); -} - -struct apn_ctx *sgsn_apn_ctx_match(const char *name, const char *imsi) -{ - struct apn_ctx *actx; - struct apn_ctx *found_actx = NULL; - size_t imsi_prio = 0; - size_t name_prio = 0; - size_t name_req_len = strlen(name); - - llist_for_each_entry(actx, &sgsn_apn_ctxts, list) { - size_t name_ref_len, imsi_ref_len; - const char *name_ref_start, *name_match_start; - - imsi_ref_len = strlen(actx->imsi_prefix); - if (strncmp(actx->imsi_prefix, imsi, imsi_ref_len) != 0) - continue; - - if (imsi_ref_len < imsi_prio) - continue; - - /* IMSI matches */ - - name_ref_start = &actx->name[0]; - if (name_ref_start[0] == '*') { - /* Suffix match */ - name_ref_start += 1; - name_ref_len = strlen(name_ref_start); - if (name_ref_len > name_req_len) - continue; - } else { - name_ref_len = strlen(name_ref_start); - if (name_ref_len != name_req_len) - continue; - } - - name_match_start = name + (name_req_len - name_ref_len); - if (strcasecmp(name_match_start, name_ref_start) != 0) - continue; - - /* IMSI and name match */ - - if (imsi_ref_len == imsi_prio && name_ref_len < name_prio) - /* Lower priority, skip */ - continue; - - imsi_prio = imsi_ref_len; - name_prio = name_ref_len; - found_actx = actx; - } - return found_actx; -} - -struct apn_ctx *sgsn_apn_ctx_by_name(const char *name, const char *imsi_prefix) -{ - struct apn_ctx *actx; - - llist_for_each_entry(actx, &sgsn_apn_ctxts, list) { - if (strcasecmp(name, actx->name) == 0 && - strcasecmp(imsi_prefix, actx->imsi_prefix) == 0) - return actx; - } - return NULL; -} - -struct apn_ctx *sgsn_apn_ctx_find_alloc(const char *name, const char *imsi_prefix) -{ - struct apn_ctx *actx; - - actx = sgsn_apn_ctx_by_name(name, imsi_prefix); - if (!actx) - actx = sgsn_apn_ctx_alloc(name, imsi_prefix); - - return actx; -} - -uint32_t sgsn_alloc_ptmsi(void) -{ - struct sgsn_mm_ctx *mm; - uint32_t ptmsi = 0xdeadbeef; - int max_retries = 100; - -restart: - if (RAND_bytes((uint8_t *) &ptmsi, sizeof(ptmsi)) != 1) - goto failed; - - /* Enforce that the 2 MSB are set without loosing the distance between - * identical values. Since rand() has no duplicate values within a - * period (because the size of the state is the same like the size of - * the random value), this leads to a distance of period/4 when the - * distribution of the 2 MSB is uniform. This approach fails with a - * probability of (3/4)^max_retries, only 1% of the approaches will - * need more than 16 numbers (even distribution assumed). - * - * Alternatively, a freeze list could be used if another PRNG is used - * or when this approach proves to be not sufficient. - */ - if (ptmsi >= 0xC0000000) { - if (!max_retries--) - goto failed; - goto restart; - } - ptmsi |= 0xC0000000; - - if (ptmsi == GSM_RESERVED_TMSI) { - if (!max_retries--) - goto failed; - goto restart; - } - - llist_for_each_entry(mm, &sgsn_mm_ctxts, list) { - if (mm->p_tmsi == ptmsi) { - if (!max_retries--) - goto failed; - goto restart; - } - } - - return ptmsi; - -failed: - LOGP(DGPRS, LOGL_ERROR, "Failed to allocate a P-TMSI\n"); - return GSM_RESERVED_TMSI; -} - -static void drop_one_pdp(struct sgsn_pdp_ctx *pdp) -{ - if (pdp->mm->gmm_state == GMM_REGISTERED_NORMAL) - gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL); - else { - /* FIXME: GPRS paging in case MS is SUSPENDED */ - LOGPDPCTXP(LOGL_NOTICE, pdp, "Hard-dropping PDP ctx due to GGSN " - "recovery\n"); - /* FIXME: how to tell this to libgtp? */ - sgsn_pdp_ctx_free(pdp); - } -} - -/* High-level function to be called in case a GGSN has disappeared or - * otherwise lost state (recovery procedure) */ -int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn) -{ - struct sgsn_mm_ctx *mm; - int num = 0; - - llist_for_each_entry(mm, &sgsn_mm_ctxts, list) { - struct sgsn_pdp_ctx *pdp; - llist_for_each_entry(pdp, &mm->pdp_list, list) { - if (pdp->ggsn == ggsn) { - drop_one_pdp(pdp); - num++; - } - } - } - - return num; -} - -void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx) -{ - OSMO_ASSERT(mmctx != NULL); - LOGMMCTXP(LOGL_INFO, mmctx, "Subscriber data update\n"); - - sgsn_auth_update(mmctx); -} - -static void insert_extra(struct tlv_parsed *tp, - struct sgsn_subscriber_data *data, - struct sgsn_subscriber_pdp_data *pdp) -{ - tp->lv[OSMO_IE_GSM_SUB_QOS].len = pdp->qos_subscribed_len; - tp->lv[OSMO_IE_GSM_SUB_QOS].val = pdp->qos_subscribed; - - /* Prefer PDP charging characteristics of per subscriber one */ - if (pdp->has_pdp_charg) { - tp->lv[OSMO_IE_GSM_CHARG_CHAR].len = sizeof(pdp->pdp_charg); - tp->lv[OSMO_IE_GSM_CHARG_CHAR].val = &pdp->pdp_charg[0]; - } else if (data->has_pdp_charg) { - tp->lv[OSMO_IE_GSM_CHARG_CHAR].len = sizeof(data->pdp_charg); - tp->lv[OSMO_IE_GSM_CHARG_CHAR].val = &data->pdp_charg[0]; - } -} - -/** - * The tlv_parsed tp parameter will be modified to insert a - * OSMO_IE_GSM_SUB_QOS in case the data is available in the - * PDP context handling. - */ -struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, - struct tlv_parsed *tp, - enum gsm48_gsm_cause *gsm_cause, - char *out_apn_str) -{ - char req_apn_str[GSM_APN_LENGTH] = {0}; - const struct apn_ctx *apn_ctx = NULL; - const char *selected_apn_str = NULL; - struct sgsn_subscriber_pdp_data *pdp; - struct sgsn_ggsn_ctx *ggsn = NULL; - int allow_any_apn = 0; - - out_apn_str[0] = '\0'; - - if (TLVP_PRESENT(tp, GSM48_IE_GSM_APN)) { - if (TLVP_LEN(tp, GSM48_IE_GSM_APN) >= GSM_APN_LENGTH - 1) { - LOGMMCTXP(LOGL_ERROR, mmctx, "APN IE too long\n"); - *gsm_cause = GSM_CAUSE_INV_MAND_INFO; - return NULL; - } - - osmo_apn_to_str(req_apn_str, - TLVP_VAL(tp, GSM48_IE_GSM_APN), - TLVP_LEN(tp, GSM48_IE_GSM_APN)); - - if (strcmp(req_apn_str, "*") == 0) - req_apn_str[0] = 0; - } - - if (mmctx->subscr == NULL) - allow_any_apn = 1; - - if (strlen(req_apn_str) == 0 && !allow_any_apn) { - /* No specific APN requested, check for an APN that is both - * granted and configured */ - - llist_for_each_entry(pdp, &mmctx->subscr->sgsn_data->pdp_list, list) { - if (strcmp(pdp->apn_str, "*") == 0) - { - allow_any_apn = 1; - selected_apn_str = ""; - insert_extra(tp, mmctx->subscr->sgsn_data, pdp); - continue; - } - if (!llist_empty(&sgsn_apn_ctxts)) { - apn_ctx = sgsn_apn_ctx_match(req_apn_str, mmctx->imsi); - /* Not configured */ - if (apn_ctx == NULL) - continue; - } - insert_extra(tp, mmctx->subscr->sgsn_data, pdp); - selected_apn_str = pdp->apn_str; - break; - } - } else if (!allow_any_apn) { - /* Check whether the given APN is granted */ - llist_for_each_entry(pdp, &mmctx->subscr->sgsn_data->pdp_list, list) { - if (strcmp(pdp->apn_str, "*") == 0) { - insert_extra(tp, mmctx->subscr->sgsn_data, pdp); - selected_apn_str = req_apn_str; - allow_any_apn = 1; - continue; - } - if (strcasecmp(pdp->apn_str, req_apn_str) == 0) { - insert_extra(tp, mmctx->subscr->sgsn_data, pdp); - selected_apn_str = req_apn_str; - break; - } - } - } else if (strlen(req_apn_str) != 0) { - /* Any APN is allowed */ - selected_apn_str = req_apn_str; - } else { - /* Prefer the GGSN associated with the wildcard APN */ - selected_apn_str = ""; - } - - if (!allow_any_apn && selected_apn_str == NULL) { - /* Access not granted */ - LOGMMCTXP(LOGL_NOTICE, mmctx, - "The requested APN '%s' is not allowed\n", - req_apn_str); - *gsm_cause = GSM_CAUSE_REQ_SERV_OPT_NOTSUB; - return NULL; - } - - /* copy the selected apn_str */ - if (selected_apn_str) - strcpy(out_apn_str, selected_apn_str); - else - out_apn_str[0] = '\0'; - - if (apn_ctx == NULL && selected_apn_str) - apn_ctx = sgsn_apn_ctx_match(selected_apn_str, mmctx->imsi); - - if (apn_ctx != NULL) { - ggsn = apn_ctx->ggsn; - } else if (llist_empty(&sgsn_apn_ctxts)) { - /* No configuration -> use GGSN 0 */ - ggsn = sgsn_ggsn_ctx_by_id(0); - } else if (allow_any_apn && - (selected_apn_str == NULL || strlen(selected_apn_str) == 0)) { - /* No APN given and no default configuration -> Use GGSN 0 */ - ggsn = sgsn_ggsn_ctx_by_id(0); - } else { - /* No matching configuration found */ - LOGMMCTXP(LOGL_NOTICE, mmctx, - "The selected APN '%s' has not been configured\n", - selected_apn_str); - *gsm_cause = GSM_CAUSE_MISSING_APN; - return NULL; - } - - if (!ggsn) { - LOGMMCTXP(LOGL_NOTICE, mmctx, - "No static GGSN configured. Selected APN '%s'\n", - selected_apn_str); - return NULL; - } - - LOGMMCTXP(LOGL_INFO, mmctx, - "Found GGSN %d for APN '%s' (requested '%s')\n", - ggsn->id, selected_apn_str ? selected_apn_str : "---", - req_apn_str); - - return ggsn; -} - -static void sgsn_llme_cleanup_free(struct gprs_llc_llme *llme) -{ - struct sgsn_mm_ctx *mmctx = NULL; - - llist_for_each_entry(mmctx, &sgsn_mm_ctxts, list) { - if (llme == mmctx->gb.llme) { - gsm0408_gprs_access_cancelled(mmctx, SGSN_ERROR_CAUSE_NONE); - return; - } - } - - /* No MM context found */ - LOGP(DGPRS, LOGL_INFO, "Deleting orphaned LLME, TLLI 0x%08x\n", - llme->tlli); - gprs_llgmm_unassign(llme); -} - -static void sgsn_llme_check_cb(void *data_) -{ - struct gprs_llc_llme *llme, *llme_tmp; - struct timespec now_tp; - time_t now, age; - time_t max_age = gprs_max_time_to_idle(); - - int rc; - - rc = clock_gettime(CLOCK_MONOTONIC, &now_tp); - OSMO_ASSERT(rc >= 0); - now = now_tp.tv_sec; - - LOGP(DGPRS, LOGL_DEBUG, - "Checking for inactive LLMEs, time = %u\n", (unsigned)now); - - llist_for_each_entry_safe(llme, llme_tmp, &gprs_llc_llmes, list) { - if (llme->age_timestamp == GPRS_LLME_RESET_AGE) - llme->age_timestamp = now; - - age = now - llme->age_timestamp; - - if (age > max_age || age < 0) { - LOGP(DGPRS, LOGL_INFO, - "Inactivity timeout for TLLI 0x%08x, age %d\n", - llme->tlli, (int)age); - sgsn_llme_cleanup_free(llme); - } - } - - osmo_timer_schedule(&sgsn->llme_timer, GPRS_LLME_CHECK_TICK, 0); -} - -void sgsn_inst_init() -{ - osmo_timer_setup(&sgsn->llme_timer, sgsn_llme_check_cb, NULL); - osmo_timer_schedule(&sgsn->llme_timer, GPRS_LLME_CHECK_TICK, 0); -} - diff --git a/src/gprs/gprs_sndcp.c b/src/gprs/gprs_sndcp.c deleted file mode 100644 index a18998f9e..000000000 --- a/src/gprs/gprs_sndcp.c +++ /dev/null @@ -1,1258 +0,0 @@ -/* GPRS SNDCP protocol implementation as per 3GPP TS 04.65 */ - -/* (C) 2010 by Harald Welte - * (C) 2010 by On-Waves - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ - -#if DEBUG_IP_PACKETS == 1 -/* Calculate TCP/IP checksum */ -static uint16_t calc_ip_csum(uint8_t *data, int len) -{ - int i; - uint32_t accumulator = 0; - uint16_t *pointer = (uint16_t *) data; - - for (i = len; i > 1; i -= 2) { - accumulator += *pointer; - pointer++; - } - - if (len % 2) - accumulator += *pointer; - - accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); - accumulator += (accumulator >> 16) & 0xffff; - return (~accumulator); -} - -/* Calculate TCP/IP checksum */ -static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) -{ - uint8_t *buf; - uint16_t csum; - - buf = talloc_zero_size(ctx, len); - memset(buf, 0, len); - memcpy(buf, packet + 12, 8); - buf[9] = packet[9]; - buf[11] = (len - 20) & 0xFF; - buf[10] = (len - 20) >> 8 & 0xFF; - memcpy(buf + 12, packet + 20, len - 20); - csum = calc_ip_csum(buf, len - 20 + 12); - talloc_free(buf); - return csum; -} - -/* Show some ip packet details */ -static void debug_ip_packet(uint8_t *data, int len, int dir, char *info) -{ - uint8_t tcp_flags; - char flags_debugmsg[256]; - int len_short; - static unsigned int packet_count = 0; - static unsigned int tcp_csum_err_count = 0; - static unsigned int ip_csum_err_count = 0; - - packet_count++; - - if (len > 80) - len_short = 80; - else - len_short = len; - - if (dir) - DEBUGP(DSNDCP, "%s: MS => SGSN: %s\n", info, - osmo_hexdump_nospc(data, len_short)); - else - DEBUGP(DSNDCP, "%s: MS <= SGSN: %s\n", info, - osmo_hexdump_nospc(data, len_short)); - - DEBUGP(DSNDCP, "%s: Length.: %d\n", info, len); - DEBUGP(DSNDCP, "%s: NO.: %d\n", info, packet_count); - - if (len < 20) { - DEBUGP(DSNDCP, "%s: Error: Short IP packet!\n", info); - return; - } - - if (calc_ip_csum(data, 20) != 0) { - DEBUGP(DSNDCP, "%s: Bad IP-Header checksum!\n", info); - ip_csum_err_count++; - } else - DEBUGP(DSNDCP, "%s: IP-Header checksum ok.\n", info); - - if (data[9] == 0x06) { - if (len < 40) { - DEBUGP(DSNDCP, "%s: Error: Short TCP packet!\n", info); - return; - } - - DEBUGP(DSNDCP, "%s: Protocol type: TCP\n", info); - tcp_flags = data[33]; - - if (calc_tcpip_csum(NULL, data, len) != 0) { - DEBUGP(DSNDCP, "%s: Bad TCP checksum!\n", info); - tcp_csum_err_count++; - } else - DEBUGP(DSNDCP, "%s: TCP checksum ok.\n", info); - - memset(flags_debugmsg, 0, sizeof(flags_debugmsg)); - if (tcp_flags & 1) - strcat(flags_debugmsg, "FIN "); - if (tcp_flags & 2) - strcat(flags_debugmsg, "SYN "); - if (tcp_flags & 4) - strcat(flags_debugmsg, "RST "); - if (tcp_flags & 8) - strcat(flags_debugmsg, "PSH "); - if (tcp_flags & 16) - strcat(flags_debugmsg, "ACK "); - if (tcp_flags & 32) - strcat(flags_debugmsg, "URG "); - DEBUGP(DSNDCP, "%s: FLAGS: %s\n", info, flags_debugmsg); - } else if (data[9] == 0x11) { - DEBUGP(DSNDCP, "%s: Protocol type: UDP\n", info); - } else { - DEBUGP(DSNDCP, "%s: Protocol type: (%02x)\n", info, data[9]); - } - - DEBUGP(DSNDCP, "%s: IP-Header checksum errors: %d\n", info, - ip_csum_err_count); - DEBUGP(DSNDCP, "%s: TCP-Checksum errors: %d\n", info, - tcp_csum_err_count); -} -#endif - -/* Chapter 7.2: SN-PDU Formats */ -struct sndcp_common_hdr { - /* octet 1 */ - uint8_t nsapi:4; - uint8_t more:1; - uint8_t type:1; - uint8_t first:1; - uint8_t spare:1; -} __attribute__((packed)); - -/* PCOMP / DCOMP only exist in first fragment */ -struct sndcp_comp_hdr { - /* octet 2 */ - uint8_t pcomp:4; - uint8_t dcomp:4; -} __attribute__((packed)); - -struct sndcp_udata_hdr { - /* octet 3 */ - uint8_t npdu_high:4; - uint8_t seg_nr:4; - /* octet 4 */ - uint8_t npdu_low; -} __attribute__((packed)); - - -static void *tall_sndcp_ctx; - -/* A fragment queue entry, containing one framgent of a N-PDU */ -struct defrag_queue_entry { - struct llist_head list; - /* segment number of this fragment */ - uint32_t seg_nr; - /* length of the data area of this fragment */ - uint32_t data_len; - /* pointer to the data of this fragment */ - uint8_t *data; -}; - -LLIST_HEAD(gprs_sndcp_entities); - -/* Check if any compression parameters are set in the sgsn configuration */ -static inline int any_pcomp_or_dcomp_active(struct sgsn_instance *sgsn) { - if (sgsn->cfg.pcomp_rfc1144.active || sgsn->cfg.pcomp_rfc1144.passive || - sgsn->cfg.dcomp_v42bis.active || sgsn->cfg.dcomp_v42bis.passive) - return true; - else - return false; -} - -/* Enqueue a fragment into the defragment queue */ -static int defrag_enqueue(struct gprs_sndcp_entity *sne, uint8_t seg_nr, - uint8_t *data, uint32_t data_len) -{ - struct defrag_queue_entry *dqe; - - dqe = talloc_zero(tall_sndcp_ctx, struct defrag_queue_entry); - if (!dqe) - return -ENOMEM; - dqe->data = talloc_zero_size(dqe, data_len); - if (!dqe->data) { - talloc_free(dqe); - return -ENOMEM; - } - dqe->seg_nr = seg_nr; - dqe->data_len = data_len; - - llist_add(&dqe->list, &sne->defrag.frag_list); - - if (seg_nr > sne->defrag.highest_seg) - sne->defrag.highest_seg = seg_nr; - - sne->defrag.seg_have |= (1 << seg_nr); - sne->defrag.tot_len += data_len; - - memcpy(dqe->data, data, data_len); - - return 0; -} - -/* return if we have all segments of this N-PDU */ -static int defrag_have_all_segments(struct gprs_sndcp_entity *sne) -{ - uint32_t seg_needed = 0; - unsigned int i; - - /* create a bitmask of needed segments */ - for (i = 0; i <= sne->defrag.highest_seg; i++) - seg_needed |= (1 << i); - - if (seg_needed == sne->defrag.seg_have) - return 1; - - return 0; -} - -static struct defrag_queue_entry *defrag_get_seg(struct gprs_sndcp_entity *sne, - uint32_t seg_nr) -{ - struct defrag_queue_entry *dqe; - - llist_for_each_entry(dqe, &sne->defrag.frag_list, list) { - if (dqe->seg_nr == seg_nr) { - llist_del(&dqe->list); - return dqe; - } - } - return NULL; -} - -/* Perform actual defragmentation and create an output packet */ -static int defrag_segments(struct gprs_sndcp_entity *sne) -{ - struct msgb *msg; - unsigned int seg_nr; - uint8_t *npdu; - int npdu_len; - int rc; - uint8_t *expnd = NULL; - - LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Defragment output PDU %u " - "num_seg=%u tot_len=%u\n", sne->lle->llme->tlli, sne->nsapi, - sne->defrag.npdu, sne->defrag.highest_seg, sne->defrag.tot_len); - msg = msgb_alloc_headroom(sne->defrag.tot_len+256, 128, "SNDCP Defrag"); - if (!msg) - return -ENOMEM; - - /* FIXME: message headers + identifiers */ - - npdu = msg->data; - - for (seg_nr = 0; seg_nr <= sne->defrag.highest_seg; seg_nr++) { - struct defrag_queue_entry *dqe; - uint8_t *data; - - dqe = defrag_get_seg(sne, seg_nr); - if (!dqe) { - LOGP(DSNDCP, LOGL_ERROR, "Segment %u missing\n", seg_nr); - msgb_free(msg); - return -EIO; - } - /* actually append the segment to the N-PDU */ - data = msgb_put(msg, dqe->data_len); - memcpy(data, dqe->data, dqe->data_len); - - /* release memory for the fragment queue entry */ - talloc_free(dqe); - } - - npdu_len = sne->defrag.tot_len; - - /* FIXME: cancel timer */ - - /* actually send the N-PDU to the SGSN core code, which then - * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - - /* Decompress packet */ -#if DEBUG_IP_PACKETS == 1 - DEBUGP(DSNDCP, " \n"); - DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); - DEBUGP(DSNDCP, "===================================================\n"); -#endif - if (any_pcomp_or_dcomp_active(sgsn)) { - - expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + - MAX_HDRDECOMPR_INCR); - memcpy(expnd, npdu, npdu_len); - - /* Apply data decompression */ - rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, - sne->defrag.data); - if (rc < 0) { - LOGP(DSNDCP, LOGL_ERROR, - "Data decompression failed!\n"); - talloc_free(expnd); - return -EIO; - } - - /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, - sne->defrag.proto); - if (rc < 0) { - LOGP(DSNDCP, LOGL_ERROR, - "TCP/IP Header decompression failed!\n"); - talloc_free(expnd); - return -EIO; - } - - /* Modify npu length, expnd is handed directly handed - * over to gsn_rx_sndcp_ud_ind(), see below */ - npdu_len = rc; - } else - expnd = npdu; -#if DEBUG_IP_PACKETS == 1 - debug_ip_packet(expnd, npdu_len, 1, "defrag_segments()"); - DEBUGP(DSNDCP, "===================================================\n"); - DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); - DEBUGP(DSNDCP, " \n"); -#endif - - /* Hand off packet to gtp */ - rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, - sne->nsapi, msg, npdu_len, expnd); - - if (any_pcomp_or_dcomp_active(sgsn)) - talloc_free(expnd); - - return rc; -} - -static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, - uint8_t *hdr, unsigned int len) -{ - struct sndcp_common_hdr *sch; - struct sndcp_udata_hdr *suh; - uint16_t npdu_num; - uint8_t *data; - int rc; - - sch = (struct sndcp_common_hdr *) hdr; - if (sch->first) { - suh = (struct sndcp_udata_hdr *) (hdr + 1 + sizeof(struct sndcp_common_hdr)); - } else - suh = (struct sndcp_udata_hdr *) (hdr + sizeof(struct sndcp_common_hdr)); - - data = (uint8_t *)suh + sizeof(struct sndcp_udata_hdr); - - npdu_num = (suh->npdu_high << 8) | suh->npdu_low; - - LOGP(DSNDCP, LOGL_DEBUG, "TLLI=0x%08x NSAPI=%u: Input PDU %u Segment %u " - "Length %u %s %s\n", sne->lle->llme->tlli, sne->nsapi, npdu_num, - suh->seg_nr, len, sch->first ? "F " : "", sch->more ? "M" : ""); - - if (sch->first) { - /* first segment of a new packet. Discard all leftover fragments of - * previous packet */ - if (!llist_empty(&sne->defrag.frag_list)) { - struct defrag_queue_entry *dqe, *dqe2; - LOGP(DSNDCP, LOGL_INFO, "TLLI=0x%08x NSAPI=%u: Dropping " - "SN-PDU %u due to insufficient segments (%04x)\n", - sne->lle->llme->tlli, sne->nsapi, sne->defrag.npdu, - sne->defrag.seg_have); - llist_for_each_entry_safe(dqe, dqe2, &sne->defrag.frag_list, list) { - llist_del(&dqe->list); - talloc_free(dqe); - } - } - /* store the currently de-fragmented PDU number */ - sne->defrag.npdu = npdu_num; - - /* Re-set fragmentation state */ - sne->defrag.no_more = sne->defrag.highest_seg = sne->defrag.seg_have = 0; - sne->defrag.tot_len = 0; - /* FIXME: (re)start timer */ - } - - if (sne->defrag.npdu != npdu_num) { - LOGP(DSNDCP, LOGL_INFO, "Segment for different SN-PDU " - "(%u != %u)\n", npdu_num, sne->defrag.npdu); - /* FIXME */ - } - - /* FIXME: check if seg_nr already exists */ - /* make sure to subtract length of SNDCP header from 'len' */ - rc = defrag_enqueue(sne, suh->seg_nr, data, len - (data - hdr)); - if (rc < 0) - return rc; - - if (!sch->more) { - /* this is suppsed to be the last segment of the N-PDU, but it - * might well be not the last to arrive */ - sne->defrag.no_more = 1; - } - - if (sne->defrag.no_more) { - /* we have already received the last segment before, let's check - * if all the previous segments exist */ - if (defrag_have_all_segments(sne)) - return defrag_segments(sne); - } - - return 0; -} - -static struct gprs_sndcp_entity *gprs_sndcp_entity_by_lle(const struct gprs_llc_lle *lle, - uint8_t nsapi) -{ - struct gprs_sndcp_entity *sne; - - llist_for_each_entry(sne, &gprs_sndcp_entities, list) { - if (sne->lle == lle && sne->nsapi == nsapi) - return sne; - } - return NULL; -} - -static struct gprs_sndcp_entity *gprs_sndcp_entity_alloc(struct gprs_llc_lle *lle, - uint8_t nsapi) -{ - struct gprs_sndcp_entity *sne; - - sne = talloc_zero(tall_sndcp_ctx, struct gprs_sndcp_entity); - if (!sne) - return NULL; - - sne->lle = lle; - sne->nsapi = nsapi; - sne->defrag.timer.data = sne; - //sne->fqueue.timer.cb = FIXME; - sne->rx_state = SNDCP_RX_S_FIRST; - INIT_LLIST_HEAD(&sne->defrag.frag_list); - - llist_add(&sne->list, &gprs_sndcp_entities); - - return sne; -} - -/* Entry point for the SNSM-ACTIVATE.indication */ -int sndcp_sm_activate_ind(struct gprs_llc_lle *lle, uint8_t nsapi) -{ - LOGP(DSNDCP, LOGL_INFO, "SNSM-ACTIVATE.ind (lle=%p TLLI=%08x, " - "SAPI=%u, NSAPI=%u)\n", lle, lle->llme->tlli, lle->sapi, nsapi); - - if (gprs_sndcp_entity_by_lle(lle, nsapi)) { - LOGP(DSNDCP, LOGL_ERROR, "Trying to ACTIVATE " - "already-existing entity (TLLI=%08x, NSAPI=%u)\n", - lle->llme->tlli, nsapi); - return -EEXIST; - } - - if (!gprs_sndcp_entity_alloc(lle, nsapi)) { - LOGP(DSNDCP, LOGL_ERROR, "Out of memory during ACTIVATE\n"); - return -ENOMEM; - } - - return 0; -} - -/* Entry point for the SNSM-DEACTIVATE.indication */ -int sndcp_sm_deactivate_ind(struct gprs_llc_lle *lle, uint8_t nsapi) -{ - struct gprs_sndcp_entity *sne; - - LOGP(DSNDCP, LOGL_INFO, "SNSM-DEACTIVATE.ind (lle=%p, TLLI=%08x, " - "SAPI=%u, NSAPI=%u)\n", lle, lle->llme->tlli, lle->sapi, nsapi); - - sne = gprs_sndcp_entity_by_lle(lle, nsapi); - if (!sne) { - LOGP(DSNDCP, LOGL_ERROR, "SNSM-DEACTIVATE.ind for non-" - "existing TLLI=%08x SAPI=%u NSAPI=%u\n", lle->llme->tlli, - lle->sapi, nsapi); - return -ENOENT; - } - llist_del(&sne->list); - /* frag queue entries are hierarchically allocated, so no need to - * free them explicitly here */ - talloc_free(sne); - - return 0; -} - -/* Fragmenter state */ -struct sndcp_frag_state { - uint8_t frag_nr; - struct msgb *msg; /* original message */ - uint8_t *next_byte; /* first byte of next fragment */ - - struct gprs_sndcp_entity *sne; - void *mmcontext; -}; - -/* returns '1' if there are more fragments to send, '0' if none */ -static int sndcp_send_ud_frag(struct sndcp_frag_state *fs, - uint8_t pcomp, uint8_t dcomp) -{ - struct gprs_sndcp_entity *sne = fs->sne; - struct gprs_llc_lle *lle = sne->lle; - struct sndcp_common_hdr *sch; - struct sndcp_comp_hdr *scomph; - struct sndcp_udata_hdr *suh; - struct msgb *fmsg; - unsigned int max_payload_len; - unsigned int len; - uint8_t *data; - int rc, more; - - fmsg = msgb_alloc_headroom(fs->sne->lle->params.n201_u+256, 128, - "SNDCP Frag"); - if (!fmsg) { - msgb_free(fs->msg); - return -ENOMEM; - } - - /* make sure lower layers route the fragment like the original */ - msgb_tlli(fmsg) = msgb_tlli(fs->msg); - msgb_bvci(fmsg) = msgb_bvci(fs->msg); - msgb_nsei(fmsg) = msgb_nsei(fs->msg); - - /* prepend common SNDCP header */ - sch = (struct sndcp_common_hdr *) msgb_put(fmsg, sizeof(*sch)); - sch->nsapi = sne->nsapi; - /* Set FIRST bit if we are the first fragment in a series */ - if (fs->frag_nr == 0) - sch->first = 1; - sch->type = 1; - - /* append the compression header for first fragment */ - if (sch->first) { - scomph = (struct sndcp_comp_hdr *) - msgb_put(fmsg, sizeof(*scomph)); - scomph->pcomp = pcomp; - scomph->dcomp = dcomp; - } - - /* append the user-data header */ - suh = (struct sndcp_udata_hdr *) msgb_put(fmsg, sizeof(*suh)); - suh->npdu_low = sne->tx_npdu_nr & 0xff; - suh->npdu_high = (sne->tx_npdu_nr >> 8) & 0xf; - suh->seg_nr = fs->frag_nr % 0xf; - - /* calculate remaining length to be sent */ - len = (fs->msg->data + fs->msg->len) - fs->next_byte; - /* how much payload can we actually send via LLC? */ - max_payload_len = lle->params.n201_u - (sizeof(*sch) + sizeof(*suh)); - if (sch->first) - max_payload_len -= sizeof(*scomph); - /* check if we're exceeding the max */ - if (len > max_payload_len) - len = max_payload_len; - - /* copy the actual fragment data into our fmsg */ - data = msgb_put(fmsg, len); - memcpy(data, fs->next_byte, len); - - /* Increment fragment number and data pointer to next fragment */ - fs->frag_nr++; - fs->next_byte += len; - - /* determine if we have more fragemnts to send */ - if ((fs->msg->data + fs->msg->len) <= fs->next_byte) - more = 0; - else - more = 1; - - /* set the MORE bit of the SNDCP header accordingly */ - sch->more = more; - - rc = gprs_llc_tx_ui(fmsg, lle->sapi, 0, fs->mmcontext, true); - /* abort in case of error, do not advance frag_nr / next_byte */ - if (rc < 0) { - msgb_free(fs->msg); - return rc; - } - - if (!more) { - /* we've sent all fragments */ - msgb_free(fs->msg); - memset(fs, 0, sizeof(*fs)); - /* increment NPDU number for next frame */ - sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff; - return 0; - } - - /* default: more fragments to send */ - return 1; -} - -/* Request transmission of a SN-PDU over specified LLC Entity + SAPI */ -int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi, - void *mmcontext) -{ - struct gprs_sndcp_entity *sne; - struct sndcp_common_hdr *sch; - struct sndcp_comp_hdr *scomph; - struct sndcp_udata_hdr *suh; - struct sndcp_frag_state fs; - uint8_t pcomp = 0; - uint8_t dcomp = 0; - int rc; - - /* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */ - - /* Compress packet */ -#if DEBUG_IP_PACKETS == 1 - DEBUGP(DSNDCP, " \n"); - DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); - DEBUGP(DSNDCP, "===================================================\n"); - debug_ip_packet(msg->data, msg->len, 0, "sndcp_initdata_req()"); -#endif - if (any_pcomp_or_dcomp_active(sgsn)) { - - /* Apply header compression */ - rc = gprs_sndcp_pcomp_compress(msg->data, msg->len, &pcomp, - lle->llme->comp.proto, nsapi); - if (rc < 0) { - LOGP(DSNDCP, LOGL_ERROR, - "TCP/IP Header compression failed!\n"); - return -EIO; - } - - /* Fixup pointer locations and sizes in message buffer to match - * the new, compressed buffer size */ - msgb_get(msg, msg->len); - msgb_put(msg, rc); - - /* Apply data compression */ - rc = gprs_sndcp_dcomp_compress(msg->data, msg->len, &dcomp, - lle->llme->comp.data, nsapi); - if (rc < 0) { - LOGP(DSNDCP, LOGL_ERROR, "Data compression failed!\n"); - return -EIO; - } - - /* Fixup pointer locations and sizes in message buffer to match - * the new, compressed buffer size */ - msgb_get(msg, msg->len); - msgb_put(msg, rc); - } -#if DEBUG_IP_PACKETS == 1 - DEBUGP(DSNDCP, "===================================================\n"); - DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); - DEBUGP(DSNDCP, " \n"); -#endif - - sne = gprs_sndcp_entity_by_lle(lle, nsapi); - if (!sne) { - LOGP(DSNDCP, LOGL_ERROR, "Cannot find SNDCP Entity\n"); - msgb_free(msg); - return -EIO; - } - - /* Check if we need to fragment this N-PDU into multiple SN-PDUs */ - if (msg->len > lle->params.n201_u - - (sizeof(*sch) + sizeof(*suh) + sizeof(*scomph))) { - /* initialize the fragmenter state */ - fs.msg = msg; - fs.frag_nr = 0; - fs.next_byte = msg->data; - fs.sne = sne; - fs.mmcontext = mmcontext; - - /* call function to generate and send fragments until all - * of the N-PDU has been sent */ - while (1) { - int rc = sndcp_send_ud_frag(&fs,pcomp,dcomp); - if (rc == 0) - return 0; - if (rc < 0) - return rc; - } - /* not reached */ - return 0; - } - - /* this is the non-fragmenting case where we only build 1 SN-PDU */ - - /* prepend the user-data header */ - suh = (struct sndcp_udata_hdr *) msgb_push(msg, sizeof(*suh)); - suh->npdu_low = sne->tx_npdu_nr & 0xff; - suh->npdu_high = (sne->tx_npdu_nr >> 8) & 0xf; - suh->seg_nr = 0; - sne->tx_npdu_nr = (sne->tx_npdu_nr + 1) % 0xfff; - - scomph = (struct sndcp_comp_hdr *) msgb_push(msg, sizeof(*scomph)); - scomph->pcomp = pcomp; - scomph->dcomp = dcomp; - - /* prepend common SNDCP header */ - sch = (struct sndcp_common_hdr *) msgb_push(msg, sizeof(*sch)); - sch->first = 1; - sch->type = 1; - sch->nsapi = nsapi; - - return gprs_llc_tx_ui(msg, lle->sapi, 0, mmcontext, true); -} - -/* Section 5.1.2.17 LL-UNITDATA.ind */ -int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle, - uint8_t *hdr, uint16_t len) -{ - struct gprs_sndcp_entity *sne; - struct sndcp_common_hdr *sch = (struct sndcp_common_hdr *)hdr; - struct sndcp_comp_hdr *scomph = NULL; - struct sndcp_udata_hdr *suh; - uint8_t *npdu; - uint16_t npdu_num __attribute__((unused)); - int npdu_len; - int rc; - uint8_t *expnd = NULL; - - sch = (struct sndcp_common_hdr *) hdr; - if (sch->first) { - scomph = (struct sndcp_comp_hdr *) (hdr + 1); - suh = (struct sndcp_udata_hdr *) (hdr + 1 + sizeof(struct sndcp_common_hdr)); - } else - suh = (struct sndcp_udata_hdr *) (hdr + sizeof(struct sndcp_common_hdr)); - - if (sch->type == 0) { - LOGP(DSNDCP, LOGL_ERROR, "SN-DATA PDU at unitdata_ind() function\n"); - return -EINVAL; - } - - if (len < sizeof(*sch) + sizeof(*suh)) { - LOGP(DSNDCP, LOGL_ERROR, "SN-UNITDATA PDU too short (%u)\n", len); - return -EIO; - } - - sne = gprs_sndcp_entity_by_lle(lle, sch->nsapi); - if (!sne) { - LOGP(DSNDCP, LOGL_ERROR, "Message for non-existing SNDCP Entity " - "(lle=%p, TLLI=%08x, SAPI=%u, NSAPI=%u)\n", lle, - lle->llme->tlli, lle->sapi, sch->nsapi); - return -EIO; - } - /* FIXME: move this RA_ID up to the LLME or even higher */ - bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); - - if (scomph) { - sne->defrag.pcomp = scomph->pcomp; - sne->defrag.dcomp = scomph->dcomp; - sne->defrag.proto = lle->llme->comp.proto; - sne->defrag.data = lle->llme->comp.data; - } - - /* any non-first segment is by definition something to defragment - * as is any segment that tells us there are more segments */ - if (!sch->first || sch->more) - return defrag_input(sne, msg, hdr, len); - - npdu_num = (suh->npdu_high << 8) | suh->npdu_low; - npdu = (uint8_t *)suh + sizeof(*suh); - npdu_len = (msg->data + msg->len) - npdu - 3; /* -3 'removes' the FCS */ - - if (npdu_len <= 0) { - LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len); - return -EIO; - } - /* actually send the N-PDU to the SGSN core code, which then - * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - - /* Decompress packet */ -#if DEBUG_IP_PACKETS == 1 - DEBUGP(DSNDCP, " \n"); - DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); - DEBUGP(DSNDCP, "===================================================\n"); -#endif - if (any_pcomp_or_dcomp_active(sgsn)) { - - expnd = talloc_zero_size(msg, npdu_len * MAX_DATADECOMPR_FAC + - MAX_HDRDECOMPR_INCR); - memcpy(expnd, npdu, npdu_len); - - /* Apply data decompression */ - rc = gprs_sndcp_dcomp_expand(expnd, npdu_len, sne->defrag.dcomp, - sne->defrag.data); - if (rc < 0) { - LOGP(DSNDCP, LOGL_ERROR, - "Data decompression failed!\n"); - talloc_free(expnd); - return -EIO; - } - - /* Apply header decompression */ - rc = gprs_sndcp_pcomp_expand(expnd, rc, sne->defrag.pcomp, - sne->defrag.proto); - if (rc < 0) { - LOGP(DSNDCP, LOGL_ERROR, - "TCP/IP Header decompression failed!\n"); - talloc_free(expnd); - return -EIO; - } - - /* Modify npu length, expnd is handed directly handed - * over to gsn_rx_sndcp_ud_ind(), see below */ - npdu_len = rc; - } else - expnd = npdu; -#if DEBUG_IP_PACKETS == 1 - debug_ip_packet(expnd, npdu_len, 1, "sndcp_llunitdata_ind()"); - DEBUGP(DSNDCP, "===================================================\n"); - DEBUGP(DSNDCP, ":::::::::::::::::::::::::::::::::::::::::::::::::::\n"); - DEBUGP(DSNDCP, " \n"); -#endif - - /* Hand off packet to gtp */ - rc = sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, - sne->nsapi, msg, npdu_len, expnd); - - if (any_pcomp_or_dcomp_active(sgsn)) - talloc_free(expnd); - - return rc; -} - -#if 0 -/* Section 5.1.2.1 LL-RESET.ind */ -static int sndcp_ll_reset_ind(struct gprs_sndcp_entity *se) -{ - /* treat all outstanding SNDCP-LLC request type primitives as not sent */ - /* reset all SNDCP XID parameters to default values */ - LOGP(DSNDCP, LOGL_NOTICE, "not implemented.\n"); - return 0; -} - -static int sndcp_ll_status_ind() -{ - /* inform the SM sub-layer by means of SNSM-STATUS.req */ - LOGP(DSNDCP, LOGL_NOTICE, "not implemented.\n"); - return 0; -} - -static struct sndcp_state_list {{ - uint32_t states; - unsigned int type; - int (*rout)(struct gprs_sndcp_entity *se, struct msgb *msg); -} sndcp_state_list[] = { - { ALL_STATES, - LL_RESET_IND, sndcp_ll_reset_ind }, - { ALL_STATES, - LL_ESTABLISH_IND, sndcp_ll_est_ind }, - { SBIT(SNDCP_S_EST_RQD), - LL_ESTABLISH_RESP, sndcp_ll_est_ind }, - { SBIT(SNDCP_S_EST_RQD), - LL_ESTABLISH_CONF, sndcp_ll_est_conf }, - { SBIT(SNDCP_S_ -}; - -static int sndcp_rx_llc_prim() -{ - case LL_ESTABLISH_REQ: - case LL_RELEASE_REQ: - case LL_XID_REQ: - case LL_DATA_REQ: - LL_UNITDATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */ - - switch (prim) { - case LL_RESET_IND: - case LL_ESTABLISH_IND: - case LL_ESTABLISH_RESP: - case LL_ESTABLISH_CONF: - case LL_RELEASE_IND: - case LL_RELEASE_CONF: - case LL_XID_IND: - case LL_XID_RESP: - case LL_XID_CONF: - case LL_DATA_IND: - case LL_DATA_CONF: - case LL_UNITDATA_IND: - case LL_STATUS_IND: - } -} -#endif - -/* Generate SNDCP-XID message */ -static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi) -{ - int entity = 0; - LLIST_HEAD(comp_fields); - struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; - struct gprs_sndcp_comp_field rfc1144_comp_field; - struct gprs_sndcp_dcomp_v42bis_params v42bis_params; - struct gprs_sndcp_comp_field v42bis_comp_field; - - memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); - memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); - - /* Setup rfc1144 */ - if (sgsn->cfg.pcomp_rfc1144.active) { - rfc1144_params.nsapi[0] = nsapi; - rfc1144_params.nsapi_len = 1; - rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01; - rfc1144_comp_field.p = 1; - rfc1144_comp_field.entity = entity; - rfc1144_comp_field.algo = RFC_1144; - rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; - rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; - rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; - rfc1144_comp_field.rfc1144_params = &rfc1144_params; - entity++; - llist_add(&rfc1144_comp_field.list, &comp_fields); - } - - /* Setup V.42bis */ - if (sgsn->cfg.dcomp_v42bis.active) { - v42bis_params.nsapi[0] = nsapi; - v42bis_params.nsapi_len = 1; - v42bis_params.p0 = sgsn->cfg.dcomp_v42bis.p0; - v42bis_params.p1 = sgsn->cfg.dcomp_v42bis.p1; - v42bis_params.p2 = sgsn->cfg.dcomp_v42bis.p2; - v42bis_comp_field.p = 1; - v42bis_comp_field.entity = entity; - v42bis_comp_field.algo = V42BIS; - v42bis_comp_field.comp[V42BIS_DCOMP1] = 1; - v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; - v42bis_comp_field.v42bis_params = &v42bis_params; - entity++; - llist_add(&v42bis_comp_field.list, &comp_fields); - } - - /* Do not attempt to compile anything if there is no data in the list */ - if (llist_empty(&comp_fields)) - return 0; - - /* Compile bytestream */ - return gprs_sndcp_compile_xid(bytes, bytes_len, &comp_fields, - DEFAULT_SNDCP_VERSION); -} - -/* Set of SNDCP-XID bnegotiation (See also: TS 144 065, - * Section 6.8 XID parameter negotiation) */ -int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi) -{ - /* Note: The specification requires the SNDCP-User to set of an - * SNDCP xid request. See also 3GPP TS 44.065, 6.8 XID parameter - * negotiation, Figure 11: SNDCP XID negotiation procedure. In - * our case the SNDCP-User is sgsn_libgtp.c, which calls - * sndcp_sn_xid_req directly. */ - - uint8_t l3params[1024]; - int xid_len; - struct gprs_llc_xid_field xid_field_request; - - /* Wipe off all compression entities and their states to - * get rid of possible leftovers from a previous session */ - gprs_sndcp_comp_free(lle->llme->comp.proto); - gprs_sndcp_comp_free(lle->llme->comp.data); - lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme); - lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme); - talloc_free(lle->llme->xid); - lle->llme->xid = NULL; - - /* Generate compression parameter bytestream */ - xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi); - - /* Send XID with the SNDCP-XID bytetsream included */ - if (xid_len > 0) { - xid_field_request.type = GPRS_LLC_XID_T_L3_PAR; - xid_field_request.data = l3params; - xid_field_request.data_len = xid_len; - return gprs_ll_xid_req(lle, &xid_field_request); - } - - /* When bytestream can not be generated, proceed without SNDCP-XID */ - return gprs_ll_xid_req(lle, NULL); - -} - -/* Handle header compression entites */ -static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field, - struct gprs_llc_lle *lle) -{ - /* Note: This functions also transforms the comp_field into its - * echo form (strips comp values, resets propose bit etc...) - * the processed comp_fields can then be sent back as XID- - * Response without further modification. */ - - /* Delete propose bit */ - comp_field->p = 0; - - /* Process proposed parameters */ - switch (comp_field->algo) { - case RFC_1144: - if (sgsn->cfg.pcomp_rfc1144.passive - && comp_field->rfc1144_params->nsapi_len > 0) { - DEBUGP(DSNDCP, - "Accepting RFC1144 header compression...\n"); - gprs_sndcp_comp_add(lle->llme, lle->llme->comp.proto, - comp_field); - } else { - DEBUGP(DSNDCP, - "Rejecting RFC1144 header compression...\n"); - gprs_sndcp_comp_delete(lle->llme->comp.proto, - comp_field->entity); - comp_field->rfc1144_params->nsapi_len = 0; - } - break; - case RFC_2507: - /* RFC 2507 is not yet supported, - * so we set applicable nsapis to zero */ - DEBUGP(DSNDCP, "Rejecting RFC2507 header compression...\n"); - comp_field->rfc2507_params->nsapi_len = 0; - gprs_sndcp_comp_delete(lle->llme->comp.proto, - comp_field->entity); - break; - case ROHC: - /* ROHC is not yet supported, - * so we set applicable nsapis to zero */ - DEBUGP(DSNDCP, "Rejecting ROHC header compression...\n"); - comp_field->rohc_params->nsapi_len = 0; - gprs_sndcp_comp_delete(lle->llme->comp.proto, - comp_field->entity); - break; - } - - return 0; -} - -/* Hanle data compression entites */ -static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field, - struct gprs_llc_lle *lle) -{ - /* See note in handle_pcomp_entities() */ - - /* Delete propose bit */ - comp_field->p = 0; - - /* Process proposed parameters */ - switch (comp_field->algo) { - case V42BIS: - if (sgsn->cfg.dcomp_v42bis.passive && - comp_field->v42bis_params->nsapi_len > 0) { - DEBUGP(DSNDCP, - "Accepting V.42bis data compression...\n"); - gprs_sndcp_comp_add(lle->llme, lle->llme->comp.data, - comp_field); - } else { - LOGP(DSNDCP, LOGL_DEBUG, - "Rejecting V.42bis data compression...\n"); - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); - comp_field->v42bis_params->nsapi_len = 0; - } - break; - case V44: - /* V44 is not yet supported, - * so we set applicable nsapis to zero */ - DEBUGP(DSNDCP, "Rejecting V.44 data compression...\n"); - comp_field->v44_params->nsapi_len = 0; - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); - break; - } - - return 0; - -} - -/* Process SNDCP-XID indication - * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ -int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, - struct gprs_llc_xid_field *xid_field_response, - struct gprs_llc_lle *lle) -{ - /* Note: This function computes the SNDCP-XID response that is sent - * back to the ms when a ms originated XID is received. The - * Input XID fields are directly processed and the result is directly - * handed back. */ - - int rc; - int compclass; - int version; - - struct llist_head *comp_fields; - struct gprs_sndcp_comp_field *comp_field; - - OSMO_ASSERT(xid_field_indication); - OSMO_ASSERT(xid_field_response); - OSMO_ASSERT(lle); - - /* Parse SNDCP-CID XID-Field */ - comp_fields = gprs_sndcp_parse_xid(&version, lle->llme, - xid_field_indication->data, - xid_field_indication->data_len, - NULL); - if (!comp_fields) - return -EINVAL; - - /* Handle compression entites */ - DEBUGP(DSNDCP, "SNDCP-XID-IND (ms):\n"); - gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); - - llist_for_each_entry(comp_field, comp_fields, list) { - compclass = gprs_sndcp_get_compression_class(comp_field); - if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) - rc = handle_pcomp_entities(comp_field, lle); - else if (compclass == SNDCP_XID_DATA_COMPRESSION) - rc = handle_dcomp_entities(comp_field, lle); - else { - gprs_sndcp_comp_delete(lle->llme->comp.proto, - comp_field->entity); - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); - rc = 0; - } - - if (rc < 0) { - talloc_free(comp_fields); - return -EINVAL; - } - } - - DEBUGP(DSNDCP, "SNDCP-XID-RES (sgsn):\n"); - gprs_sndcp_dump_comp_fields(comp_fields, LOGL_DEBUG); - - /* Reserve some memory to store the modified SNDCP-XID bytes */ - xid_field_response->data = - talloc_zero_size(lle->llme, xid_field_indication->data_len); - - /* Set Type flag for response */ - xid_field_response->type = GPRS_LLC_XID_T_L3_PAR; - - /* Compile modified SNDCP-XID bytes */ - rc = gprs_sndcp_compile_xid(xid_field_response->data, - xid_field_indication->data_len, - comp_fields, 0); - - if (rc > 0) - xid_field_response->data_len = rc; - else { - talloc_free(xid_field_response->data); - xid_field_response->data = NULL; - xid_field_response->data_len = 0; - return -EINVAL; - } - - talloc_free(comp_fields); - - return 0; -} - -/* Process SNDCP-XID indication - * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ -int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, - struct gprs_llc_xid_field *xid_field_request, - struct gprs_llc_lle *lle) -{ - /* Note: This function handles an incomming SNDCP-XID confirmiation. - * Since the confirmation fields may lack important parameters we - * will reconstruct these missing fields using the original request - * we have sent. After that we will create (or delete) the - * compression entites */ - - struct llist_head *comp_fields_req; - struct llist_head *comp_fields_conf; - struct gprs_sndcp_comp_field *comp_field; - int rc; - int compclass; - - /* We need both, the confirmation that is sent back by the ms, - * and the original request we have sent. If one of this is missing - * we can not process the confirmation, the caller must check if - * request and confirmation fields are available. */ - OSMO_ASSERT(xid_field_conf); - OSMO_ASSERT(xid_field_request); - - /* Parse SNDCP-CID XID-Field */ - comp_fields_req = gprs_sndcp_parse_xid(NULL, lle->llme, - xid_field_request->data, - xid_field_request->data_len, - NULL); - if (!comp_fields_req) - return -EINVAL; - - DEBUGP(DSNDCP, "SNDCP-XID-REQ (sgsn):\n"); - gprs_sndcp_dump_comp_fields(comp_fields_req, LOGL_DEBUG); - - /* Parse SNDCP-CID XID-Field */ - comp_fields_conf = gprs_sndcp_parse_xid(NULL, lle->llme, - xid_field_conf->data, - xid_field_conf->data_len, - comp_fields_req); - if (!comp_fields_conf) - return -EINVAL; - - DEBUGP(DSNDCP, "SNDCP-XID-CONF (ms):\n"); - gprs_sndcp_dump_comp_fields(comp_fields_conf, LOGL_DEBUG); - - /* Handle compression entites */ - llist_for_each_entry(comp_field, comp_fields_conf, list) { - compclass = gprs_sndcp_get_compression_class(comp_field); - if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) - rc = handle_pcomp_entities(comp_field, lle); - else if (compclass == SNDCP_XID_DATA_COMPRESSION) - rc = handle_dcomp_entities(comp_field, lle); - else { - gprs_sndcp_comp_delete(lle->llme->comp.proto, - comp_field->entity); - gprs_sndcp_comp_delete(lle->llme->comp.data, - comp_field->entity); - rc = 0; - } - - if (rc < 0) { - talloc_free(comp_fields_req); - talloc_free(comp_fields_conf); - return -EINVAL; - } - } - - talloc_free(comp_fields_req); - talloc_free(comp_fields_conf); - - return 0; -} diff --git a/src/gprs/gprs_sndcp_comp.c b/src/gprs/gprs_sndcp_comp.c deleted file mode 100644 index a12c39aa6..000000000 --- a/src/gprs/gprs_sndcp_comp.c +++ /dev/null @@ -1,323 +0,0 @@ -/* GPRS SNDCP header compression entity management tools */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -/* Create a new compression entity from a XID-Field */ -static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, - const struct - gprs_sndcp_comp_field - *comp_field) -{ - struct gprs_sndcp_comp *comp_entity; - comp_entity = talloc_zero(ctx, struct gprs_sndcp_comp); - - /* Copy relevant information from the SNDCP-XID field */ - comp_entity->entity = comp_field->entity; - comp_entity->comp_len = comp_field->comp_len; - memcpy(comp_entity->comp, comp_field->comp, sizeof(comp_entity->comp)); - - if (comp_field->rfc1144_params) { - comp_entity->nsapi_len = comp_field->rfc1144_params->nsapi_len; - memcpy(comp_entity->nsapi, - comp_field->rfc1144_params->nsapi, - sizeof(comp_entity->nsapi)); - } else if (comp_field->rfc2507_params) { - comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len; - memcpy(comp_entity->nsapi, - comp_field->rfc2507_params->nsapi, - sizeof(comp_entity->nsapi)); - } else if (comp_field->rohc_params) { - comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len; - memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi, - sizeof(comp_entity->nsapi)); - } else if (comp_field->v42bis_params) { - comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len; - memcpy(comp_entity->nsapi, - comp_field->v42bis_params->nsapi, - sizeof(comp_entity->nsapi)); - } else if (comp_field->v44_params) { - comp_entity->nsapi_len = comp_field->v44_params->nsapi_len; - memcpy(comp_entity->nsapi, - comp_field->v44_params->nsapi, - sizeof(comp_entity->nsapi)); - } else { - /* The caller is expected to check carefully if the all - * data fields required for compression entity creation - * are present. Otherwise we blow an assertion here */ - OSMO_ASSERT(false); - } - comp_entity->algo = comp_field->algo; - - /* Check if an NSAPI is selected, if not, it does not make sense - * to create the compression entity, since the caller should - * have checked the presence of the NSAPI, we blow an assertion - * in case of missing NSAPIs */ - OSMO_ASSERT(comp_entity->nsapi_len > 0); - - /* Determine of which class our compression entity will be - * (Protocol or Data compresson ?) */ - comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field); - - OSMO_ASSERT(comp_entity->compclass != -1); - - /* Create an algorithm specific compression context */ - if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { - if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) { - talloc_free(comp_entity); - comp_entity = NULL; - } - } else { - if (gprs_sndcp_dcomp_init(ctx, comp_entity, comp_field) != 0) { - talloc_free(comp_entity); - comp_entity = NULL; - } - } - - /* Bail on failure */ - if (comp_entity == NULL) { - LOGP(DSNDCP, LOGL_ERROR, - "Compression entity creation failed!\n"); - return NULL; - } - - /* Display info message */ - if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { - LOGP(DSNDCP, LOGL_INFO, - "New header compression entity (%d) created.\n", - comp_entity->entity); - } else { - LOGP(DSNDCP, LOGL_INFO, - "New data compression entity (%d) created.\n", - comp_entity->entity); - } - - return comp_entity; -} - -/* Allocate a compression enitiy list */ -struct llist_head *gprs_sndcp_comp_alloc(const void *ctx) -{ - struct llist_head *lh; - - lh = talloc_zero(ctx, struct llist_head); - INIT_LLIST_HEAD(lh); - - return lh; -} - -/* Free a compression entitiy list */ -void gprs_sndcp_comp_free(struct llist_head *comp_entities) -{ - struct gprs_sndcp_comp *comp_entity; - - /* We expect the caller to take care of allocating a - * compression entity list properly. Attempting to - * free a non existing list clearly points out - * a malfunction. */ - OSMO_ASSERT(comp_entities); - - llist_for_each_entry(comp_entity, comp_entities, list) { - /* Free compression entity */ - if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { - LOGP(DSNDCP, LOGL_INFO, - "Deleting header compression entity %d ...\n", - comp_entity->entity); - gprs_sndcp_pcomp_term(comp_entity); - } else { - LOGP(DSNDCP, LOGL_INFO, - "Deleting data compression entity %d ...\n", - comp_entity->entity); - gprs_sndcp_dcomp_term(comp_entity); - } - } - - talloc_free(comp_entities); -} - -/* Delete a compression entity */ -void gprs_sndcp_comp_delete(struct llist_head *comp_entities, - unsigned int entity) -{ - struct gprs_sndcp_comp *comp_entity; - struct gprs_sndcp_comp *comp_entity_to_delete = NULL; - - OSMO_ASSERT(comp_entities); - - llist_for_each_entry(comp_entity, comp_entities, list) { - if (comp_entity->entity == entity) { - comp_entity_to_delete = comp_entity; - break; - } - } - - if (!comp_entity_to_delete) - return; - - if (comp_entity_to_delete->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { - LOGP(DSNDCP, LOGL_INFO, - "Deleting header compression entity %d ...\n", - comp_entity_to_delete->entity); - gprs_sndcp_pcomp_term(comp_entity_to_delete); - } else { - LOGP(DSNDCP, LOGL_INFO, - "Deleting data compression entity %d ...\n", - comp_entity_to_delete->entity); - } - - /* Delete compression entity */ - llist_del(&comp_entity_to_delete->list); - talloc_free(comp_entity_to_delete); -} - -/* Create and Add a new compression entity - * (returns a pointer to the compression entity that has just been created) */ -struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, - struct llist_head *comp_entities, - const struct gprs_sndcp_comp_field - *comp_field) -{ - struct gprs_sndcp_comp *comp_entity; - - OSMO_ASSERT(comp_entities); - OSMO_ASSERT(comp_field); - - /* Just to be sure, if the entity is already in - * the list it will be deleted now */ - gprs_sndcp_comp_delete(comp_entities, comp_field->entity); - - /* Create and add a new entity to the list */ - comp_entity = gprs_sndcp_comp_create(ctx, comp_field); - - if (!comp_entity) - return NULL; - - llist_add(&comp_entity->list, comp_entities); - return comp_entity; -} - -/* Find which compression entity handles the specified pcomp/dcomp */ -struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head - *comp_entities, uint8_t comp) -{ - struct gprs_sndcp_comp *comp_entity; - int i; - - OSMO_ASSERT(comp_entities); - - llist_for_each_entry(comp_entity, comp_entities, list) { - for (i = 0; i < comp_entity->comp_len; i++) { - if (comp_entity->comp[i] == comp) - return comp_entity; - } - } - - LOGP(DSNDCP, LOGL_ERROR, - "Could not find a matching compression entity for given pcomp/dcomp value %d.\n", - comp); - return NULL; -} - -/* Find which compression entity handles the specified nsapi */ -struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head - *comp_entities, uint8_t nsapi) -{ - struct gprs_sndcp_comp *comp_entity; - int i; - - OSMO_ASSERT(comp_entities); - - llist_for_each_entry(comp_entity, comp_entities, list) { - for (i = 0; i < comp_entity->nsapi_len; i++) { - if (comp_entity->nsapi[i] == nsapi) - return comp_entity; - } - } - - return NULL; -} - -/* Find a comp_index for a given pcomp/dcomp value */ -uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, - uint8_t comp) -{ - /* Note: This function returns a normalized version of the comp value, - * which matches up with the position of the comp field. Since comp=0 - * is reserved for "no compression", the index value starts counting - * at one. The return value is the PCOMPn/DCOMPn value one can find - * in the Specification (see e.g. 3GPP TS 44.065, 6.5.3.2, Table 7) */ - - int i; - OSMO_ASSERT(comp_entity); - - /* A pcomp/dcomp value of zero is reserved for "no comproession", - * So we just bail and return zero in this case */ - if (comp == 0) - return 0; - - /* Look in the pcomp/dcomp list for the index */ - for (i = 0; i < comp_entity->comp_len; i++) { - if (comp_entity->comp[i] == comp) - return i + 1; - } - - LOGP(DSNDCP, LOGL_ERROR, - "Could not find a matching comp_index for given pcomp/dcomp value %d\n", - comp); - return 0; -} - -/* Find a pcomp/dcomp value for a given comp_index */ -uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, - uint8_t comp_index) -{ - OSMO_ASSERT(comp_entity); - - /* A comp_index of zero translates to zero right away. */ - if (comp_index == 0) - return 0; - - if (comp_index > comp_entity->comp_len) { - LOGP(DSNDCP, LOGL_ERROR, - "Could not find a matching pcomp/dcomp value for given comp_index value %d.\n", - comp_index); - return 0; - } - - /* Look in the pcomp/dcomp list for the comp_index, see - * note in gprs_sndcp_comp_get_idx() */ - return comp_entity->comp[comp_index - 1]; -} diff --git a/src/gprs/gprs_sndcp_dcomp.c b/src/gprs/gprs_sndcp_dcomp.c deleted file mode 100644 index b0f95b486..000000000 --- a/src/gprs/gprs_sndcp_dcomp.c +++ /dev/null @@ -1,358 +0,0 @@ -/* GPRS SNDCP data compression handler */ - -/* (C) 2016 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* A struct to capture the output data of compressor and decompressor */ -struct v42bis_output_buffer { - uint8_t *buf; - uint8_t *buf_pointer; - int len; -}; - -/* Handler to capture the output data from the compressor */ -void tx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len) -{ - struct v42bis_output_buffer *output_buffer = - (struct v42bis_output_buffer *)user_data; - memcpy(output_buffer->buf_pointer, pkt, len); - output_buffer->buf_pointer += len; - output_buffer->len += len; - return; -} - -/* Handler to capture the output data from the decompressor */ -void rx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len) -{ - struct v42bis_output_buffer *output_buffer = - (struct v42bis_output_buffer *)user_data; - memcpy(output_buffer->buf_pointer, buf, len); - output_buffer->buf_pointer += len; - output_buffer->len += len; - return; -} - -/* Initalize data compression */ -int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, - const struct gprs_sndcp_comp_field *comp_field) -{ - /* Note: This function is automatically called from - * gprs_sndcp_comp.c when a new data compression - * entity is created by gprs_sndcp.c */ - - OSMO_ASSERT(comp_entity); - OSMO_ASSERT(comp_field); - - if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION - && comp_entity->algo == V42BIS) { - OSMO_ASSERT(comp_field->v42bis_params); - comp_entity->state = - v42bis_init(ctx, NULL, comp_field->v42bis_params->p0, - comp_field->v42bis_params->p1, - comp_field->v42bis_params->p2, - &tx_v42bis_frame_handler, NULL, - V42BIS_MAX_OUTPUT_LENGTH, - &rx_v42bis_data_handler, NULL, - V42BIS_MAX_OUTPUT_LENGTH); - LOGP(DSNDCP, LOGL_INFO, - "V.42bis data compression initalized.\n"); - return 0; - } - - /* Just in case someone tries to initalize an unknown or unsupported - * data compresson. Since everything is checked during the SNDCP - * negotiation process, this should never happen! */ - OSMO_ASSERT(false); -} - -/* Terminate data compression */ -void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity) -{ - /* Note: This function is automatically called from - * gprs_sndcp_comp.c when a data compression - * entity is deleted by gprs_sndcp.c */ - - OSMO_ASSERT(comp_entity); - - if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION - && comp_entity->algo == V42BIS) { - if (comp_entity->state) { - v42bis_free((v42bis_state_t *) comp_entity->state); - comp_entity->state = NULL; - } - LOGP(DSNDCP, LOGL_INFO, - "V.42bis data compression terminated.\n"); - return; - } - - /* Just in case someone tries to terminate an unknown or unsupported - * data compresson. Since everything is checked during the SNDCP - * negotiation process, this should never happen! */ - OSMO_ASSERT(false); -} - -/* Perform a full reset of the V.42bis compression state */ -static void v42bis_reset(v42bis_state_t *comp) -{ - /* This function performs a complete reset of the V.42bis compression - * state by reinitalizing the state withe the previously negotiated - * parameters. */ - - int p0, p1, p2; - p0 = comp->decompress.v42bis_parm_p0 | comp->compress.v42bis_parm_p0; - p1 = comp->decompress.v42bis_parm_n2; - p2 = comp->decompress.v42bis_parm_n7; - - DEBUGP(DSNDCP, "Resetting compression state: %p, p0=%d, p1=%d, p2=%d\n", - comp, p0, p1, p2); - - v42bis_init(NULL, comp, p0, p1, p2, &tx_v42bis_frame_handler, NULL, - V42BIS_MAX_OUTPUT_LENGTH, &rx_v42bis_data_handler, NULL, - V42BIS_MAX_OUTPUT_LENGTH); -} - -/* Compress a packet using V.42bis data compression */ -static int v42bis_compress_unitdata(uint8_t *pcomp_index, uint8_t *data, - unsigned int len, v42bis_state_t *comp) -{ - /* Note: This implementation may only be used to compress SN_UNITDATA - * packets, since it resets the compression state for each NPDU. */ - - uint8_t *data_o; - int rc; - int skip = 0; - struct v42bis_output_buffer compressed_data; - - /* Don't bother with short packets */ - if (len < MIN_COMPR_PAYLOAD) - skip = 1; - - /* Skip if compression is not enabled for TX direction */ - if (!comp->compress.v42bis_parm_p0) - skip = 1; - - /* Skip compression */ - if (skip) { - *pcomp_index = 0; - return len; - } - - /* Reset V.42bis compression state */ - v42bis_reset(comp); - - /* Run compressor */ - data_o = talloc_zero_size(comp, len * MAX_DATADECOMPR_FAC); - compressed_data.buf = data_o; - compressed_data.buf_pointer = data_o; - compressed_data.len = 0; - comp->compress.user_data = (&compressed_data); - rc = v42bis_compress(comp, data, len); - if (rc < 0) { - LOGP(DSNDCP, LOGL_ERROR, - "Data compression failed, skipping...\n"); - skip = 1; - } - rc = v42bis_compress_flush(comp); - if (rc < 0) { - LOGP(DSNDCP, LOGL_ERROR, - "Data compression failed, skipping...\n"); - skip = 1; - } - - /* The compressor might yield negative compression gain, in - * this case, we just decide to send the packat as normal, - * uncompressed payload => skip compresssion */ - if (compressed_data.len >= len) { - LOGP(DSNDCP, LOGL_ERROR, - "Data compression ineffective, skipping...\n"); - skip = 1; - } - - /* Skip compression */ - if (skip) { - *pcomp_index = 0; - talloc_free(data_o); - return len; - } - - *pcomp_index = 1; - memcpy(data, data_o, compressed_data.len); - talloc_free(data_o); - - return compressed_data.len; -} - -/* Expand a packet using V.42bis data compression */ -static int v42bis_expand_unitdata(uint8_t *data, unsigned int len, - uint8_t pcomp_index, v42bis_state_t *comp) -{ - /* Note: This implementation may only be used to compress SN_UNITDATA - * packets, since it resets the compression state for each NPDU. */ - - int rc; - struct v42bis_output_buffer uncompressed_data; - uint8_t *data_i; - - /* Skip when the packet is marked as uncompressed */ - if (pcomp_index == 0) { - return len; - } - - /* Reset V.42bis compression state */ - v42bis_reset(comp); - - /* Decompress packet */ - data_i = talloc_zero_size(comp, len); - memcpy(data_i, data, len); - uncompressed_data.buf = data; - uncompressed_data.buf_pointer = data; - uncompressed_data.len = 0; - comp->decompress.user_data = (&uncompressed_data); - rc = v42bis_decompress(comp, data_i, len); - talloc_free(data_i); - if (rc < 0) - return -EINVAL; - rc = v42bis_decompress_flush(comp); - if (rc < 0) - return -EINVAL; - - return uncompressed_data.len; -} - -/* Expand packet */ -int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, - const struct llist_head *comp_entities) -{ - int rc; - uint8_t pcomp_index = 0; - struct gprs_sndcp_comp *comp_entity; - - OSMO_ASSERT(data); - OSMO_ASSERT(comp_entities); - - LOGP(DSNDCP, LOGL_DEBUG, - "Data compression entity list: comp_entities=%p\n", comp_entities); - - LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", pcomp); - - /* Skip on pcomp=0 */ - if (pcomp == 0) { - return len; - } - - /* Find out which compression entity handles the data */ - comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); - - /* Skip compression if no suitable compression entity can be found */ - if (!comp_entity) { - return len; - } - - /* Note: Only data compression entities may appear in - * data compression context */ - OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); - - /* Note: Currently V42BIS is the only compression method we - * support, so the only allowed algorithm is V42BIS */ - OSMO_ASSERT(comp_entity->algo == V42BIS); - - /* Find pcomp_index */ - pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); - - /* Run decompression algo */ - rc = v42bis_expand_unitdata(data, len, pcomp_index, comp_entity->state); - - LOGP(DSNDCP, LOGL_DEBUG, - "Data expansion done, old length=%d, new length=%d, entity=%p\n", - len, rc, comp_entity); - - return rc; -} - -/* Compress packet */ -int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, - const struct llist_head *comp_entities, - uint8_t nsapi) -{ - int rc; - uint8_t pcomp_index = 0; - struct gprs_sndcp_comp *comp_entity; - - OSMO_ASSERT(data); - OSMO_ASSERT(pcomp); - OSMO_ASSERT(comp_entities); - - LOGP(DSNDCP, LOGL_DEBUG, - "Data compression entity list: comp_entities=%p\n", comp_entities); - - /* Find out which compression entity handles the data */ - comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); - - /* Skip compression if no suitable compression entity can be found */ - if (!comp_entity) { - *pcomp = 0; - return len; - } - - /* Note: Only data compression entities may appear in - * data compression context */ - OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION); - - /* Note: Currently V42BIS is the only compression method we - * support, so the only allowed algorithm is V42BIS */ - OSMO_ASSERT(comp_entity->algo == V42BIS); - - /* Run compression algo */ - rc = v42bis_compress_unitdata(&pcomp_index, data, len, - comp_entity->state); - - /* Find pcomp value */ - *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); - - LOGP(DSNDCP, LOGL_DEBUG, "Data compression mode: dcomp=%d\n", *pcomp); - - LOGP(DSNDCP, LOGL_DEBUG, - "Data compression done, old length=%d, new length=%d, entity=%p\n", - len, rc, comp_entity); - - return rc; -} diff --git a/src/gprs/gprs_sndcp_pcomp.c b/src/gprs/gprs_sndcp_pcomp.c deleted file mode 100644 index a2236c3b1..000000000 --- a/src/gprs/gprs_sndcp_pcomp.c +++ /dev/null @@ -1,282 +0,0 @@ -/* GPRS SNDCP header compression handler */ - -/* (C) 2016 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Initalize header compression */ -int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, - const struct gprs_sndcp_comp_field *comp_field) -{ - /* Note: This function is automatically called from - * gprs_sndcp_comp.c when a new header compression - * entity is created by gprs_sndcp.c */ - - OSMO_ASSERT(comp_entity); - OSMO_ASSERT(comp_field); - - if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION - && comp_entity->algo == RFC_1144) { - OSMO_ASSERT(comp_field->rfc1144_params); - comp_entity->state = - slhc_init(ctx, comp_field->rfc1144_params->s01 + 1, - comp_field->rfc1144_params->s01 + 1); - LOGP(DSNDCP, LOGL_INFO, - "RFC1144 header compression initalized.\n"); - return 0; - } - - /* Just in case someone tries to initalize an unknown or unsupported - * header compresson. Since everything is checked during the SNDCP - * negotiation process, this should never happen! */ - OSMO_ASSERT(false); -} - -/* Terminate header compression */ -void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity) -{ - /* Note: This function is automatically called from - * gprs_sndcp_comp.c when a header compression - * entity is deleted by gprs_sndcp.c */ - - OSMO_ASSERT(comp_entity); - - if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION - && comp_entity->algo == RFC_1144) { - if (comp_entity->state) { - slhc_free((struct slcompress *)comp_entity->state); - comp_entity->state = NULL; - } - LOGP(DSNDCP, LOGL_INFO, - "RFC1144 header compression terminated.\n"); - return; - } - - /* Just in case someone tries to terminate an unknown or unsupported - * data compresson. Since everything is checked during the SNDCP - * negotiation process, this should never happen! */ - OSMO_ASSERT(false); -} - -/* Compress a packet using Van Jacobson RFC1144 header compression */ -static int rfc1144_compress(uint8_t *pcomp_index, uint8_t *data, - unsigned int len, struct slcompress *comp) -{ - uint8_t *comp_ptr; - int compr_len; - uint8_t *data_o; - - /* Create a working copy of the incoming data */ - data_o = talloc_zero_size(comp, len); - memcpy(data_o, data, len); - - /* Run compressor */ - compr_len = slhc_compress(comp, data, len, data_o, &comp_ptr, 0); - - /* Generate pcomp_index */ - if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { - *pcomp_index = 2; - data_o[0] &= ~SL_TYPE_COMPRESSED_TCP; - memcpy(data, data_o, compr_len); - } else if ((data_o[0] & SL_TYPE_UNCOMPRESSED_TCP) == - SL_TYPE_UNCOMPRESSED_TCP) { - *pcomp_index = 1; - data_o[0] &= 0x4F; - memcpy(data, data_o, compr_len); - } else - *pcomp_index = 0; - - talloc_free(data_o); - return compr_len; -} - -/* Expand a packet using Van Jacobson RFC1144 header compression */ -static int rfc1144_expand(uint8_t *data, unsigned int len, uint8_t pcomp_index, - struct slcompress *comp) -{ - int data_decompressed_len; - int type; - - /* Note: this function should never be called with pcomp_index=0, - * since this condition is already filtered - * out by gprs_sndcp_pcomp_expand() */ - - /* Determine the data type by the PCOMP index */ - switch (pcomp_index) { - case 0: - type = SL_TYPE_IP; - break; - case 1: - type = SL_TYPE_UNCOMPRESSED_TCP; - break; - case 2: - type = SL_TYPE_COMPRESSED_TCP; - break; - default: - LOGP(DSNDCP, LOGL_ERROR, - "rfc1144_expand() Invalid pcomp_index value (%d) detected, assuming no compression!\n", - pcomp_index); - type = SL_TYPE_IP; - break; - } - - /* Restore the original version nibble on - * marked uncompressed packets */ - if (type == SL_TYPE_UNCOMPRESSED_TCP) { - /* Just in case the phone tags uncompressed tcp-data - * (normally this is handled by pcomp so there is - * no need for tagging the data) */ - data[0] &= 0x4F; - data_decompressed_len = slhc_remember(comp, data, len); - return data_decompressed_len; - } - - /* Uncompress compressed packets */ - else if (type == SL_TYPE_COMPRESSED_TCP) { - data_decompressed_len = slhc_uncompress(comp, data, len); - return data_decompressed_len; - } - - /* Regular or unknown packets will not be touched */ - return len; -} - -/* Expand packet header */ -int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, - const struct llist_head *comp_entities) -{ - int rc; - uint8_t pcomp_index = 0; - struct gprs_sndcp_comp *comp_entity; - - OSMO_ASSERT(data); - OSMO_ASSERT(comp_entities); - - LOGP(DSNDCP, LOGL_DEBUG, - "Header compression entity list: comp_entities=%p\n", - comp_entities); - - LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", pcomp); - - /* Skip on pcomp=0 */ - if (pcomp == 0) { - return len; - } - - /* Find out which compression entity handles the data */ - comp_entity = gprs_sndcp_comp_by_comp(comp_entities, pcomp); - - /* Skip compression if no suitable compression entity can be found */ - if (!comp_entity) { - return len; - } - - /* Note: Only protocol compression entities may appear in - * protocol compression context */ - OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); - - /* Note: Currently RFC1144 is the only compression method we - * support, so the only allowed algorithm is RFC1144 */ - OSMO_ASSERT(comp_entity->algo == RFC_1144); - - /* Find pcomp_index */ - pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp); - - /* Run decompression algo */ - rc = rfc1144_expand(data, len, pcomp_index, comp_entity->state); - slhc_i_status(comp_entity->state); - slhc_o_status(comp_entity->state); - - LOGP(DSNDCP, LOGL_DEBUG, - "Header expansion done, old length=%d, new length=%d, entity=%p\n", - len, rc, comp_entity); - - return rc; -} - -/* Compress packet header */ -int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, - const struct llist_head *comp_entities, - uint8_t nsapi) -{ - int rc; - uint8_t pcomp_index = 0; - struct gprs_sndcp_comp *comp_entity; - - OSMO_ASSERT(data); - OSMO_ASSERT(pcomp); - OSMO_ASSERT(comp_entities); - - LOGP(DSNDCP, LOGL_DEBUG, - "Header compression entity list: comp_entities=%p\n", - comp_entities); - - /* Find out which compression entity handles the data */ - comp_entity = gprs_sndcp_comp_by_nsapi(comp_entities, nsapi); - - /* Skip compression if no suitable compression entity can be found */ - if (!comp_entity) { - *pcomp = 0; - return len; - } - - /* Note: Only protocol compression entities may appear in - * protocol compression context */ - OSMO_ASSERT(comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION); - - /* Note: Currently RFC1144 is the only compression method we - * support, so the only allowed algorithm is RFC1144 */ - OSMO_ASSERT(comp_entity->algo == RFC_1144); - - /* Run compression algo */ - rc = rfc1144_compress(&pcomp_index, data, len, comp_entity->state); - slhc_i_status(comp_entity->state); - slhc_o_status(comp_entity->state); - - /* Find pcomp value */ - *pcomp = gprs_sndcp_comp_get_comp(comp_entity, pcomp_index); - - LOGP(DSNDCP, LOGL_DEBUG, "Header compression mode: pcomp=%d\n", *pcomp); - - LOGP(DSNDCP, LOGL_DEBUG, - "Header compression done, old length=%d, new length=%d, entity=%p\n", - len, rc, comp_entity); - return rc; -} diff --git a/src/gprs/gprs_sndcp_vty.c b/src/gprs/gprs_sndcp_vty.c deleted file mode 100644 index 430881fc8..000000000 --- a/src/gprs/gprs_sndcp_vty.c +++ /dev/null @@ -1,71 +0,0 @@ -/* VTY interface for our GPRS SNDCP implementation */ - -/* (C) 2010 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static void vty_dump_sne(struct vty *vty, struct gprs_sndcp_entity *sne) -{ - vty_out(vty, " TLLI %08x SAPI=%u NSAPI=%u:%s", - sne->lle->llme->tlli, sne->lle->sapi, sne->nsapi, VTY_NEWLINE); - vty_out(vty, " Defrag: npdu=%u highest_seg=%u seg_have=0x%08x tot_len=%u%s", - sne->defrag.npdu, sne->defrag.highest_seg, sne->defrag.seg_have, - sne->defrag.tot_len, VTY_NEWLINE); -} - - -DEFUN(show_sndcp, show_sndcp_cmd, - "show sndcp", - SHOW_STR "Display information about the SNDCP protocol") -{ - struct gprs_sndcp_entity *sne; - - vty_out(vty, "State of SNDCP Entities%s", VTY_NEWLINE); - llist_for_each_entry(sne, &gprs_sndcp_entities, list) - vty_dump_sne(vty, sne); - - return CMD_SUCCESS; -} - -int gprs_sndcp_vty_init(void) -{ - install_element_ve(&show_sndcp_cmd); - - return 0; -} diff --git a/src/gprs/gprs_sndcp_xid.c b/src/gprs/gprs_sndcp_xid.c deleted file mode 100644 index dfea5febc..000000000 --- a/src/gprs/gprs_sndcp_xid.c +++ /dev/null @@ -1,1822 +0,0 @@ -/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* When the propose bit in an SNDCP-XID compression field is set to zero, - * the algorithm identifier is stripped. The algoritm parameters are specific - * for each algorithms. The following struct is used to pass the information - * about the referenced algorithm to the parser. */ -struct entity_algo_table { - unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ - unsigned int algo; /* see also: 6.5.1.1.4 and 6.6.1.1.4 */ - unsigned int compclass; /* Can be either SNDCP_XID_DATA_COMPRESSION or - SNDCP_XID_PROTOCOL_COMPRESSION */ -}; - -/* FUNCTIONS RELATED TO SNDCP-XID ENCODING */ - -/* Encode applicable sapis (works the same in all three compression schemes) */ -static int encode_pcomp_applicable_sapis(uint8_t *dst, - const uint8_t *nsapis, - uint8_t nsapis_len) -{ - /* NOTE: Buffer *dst needs offer at 2 bytes - * of space to store the generation results */ - - uint16_t blob; - uint8_t nsapi; - int i; - - /* Bail if number of possible nsapis exceeds valid range - * (Only 11 nsapis possible for PDP-Contexts) */ - OSMO_ASSERT(nsapis_len <= 11); - - /* Encode applicable SAPIs */ - blob = 0; - for (i = 0; i < nsapis_len; i++) { - nsapi = nsapis[i]; - /* Only NSAPI 5 to 15 are applicable for user traffic (PDP- - * contexts). Only for these NSAPIs SNDCP-XID parameters - * can apply. See also 3GPP TS 44.065, 5.1 Service primitives */ - OSMO_ASSERT(nsapi >= 5 && nsapi <= 15); - blob |= (1 << nsapi); - } - - /* Store result */ - *dst = (blob >> 8) & 0xFF; - dst++; - *dst = blob & 0xFF; - - return 2; -} - -/* Encode rfc1144 parameter field - * (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ -static int encode_pcomp_rfc1144_params(uint8_t *dst, unsigned int dst_maxlen, - const struct - gprs_sndcp_pcomp_rfc1144_params *params) -{ - /* NOTE: Buffer *dst should offer at least 3 bytes - * of space to store the generation results */ - - int dst_counter = 0; - int rc; - - OSMO_ASSERT(dst_maxlen >= 3); - - /* Zero out buffer */ - memset(dst, 0, dst_maxlen); - - /* Encode applicable SAPIs */ - rc = encode_pcomp_applicable_sapis(dst, params->nsapi, - params->nsapi_len); - dst += rc; - dst_counter += rc; - - /* Encode s01 (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ - OSMO_ASSERT(params->s01 >= 0); - OSMO_ASSERT(params->s01 <= 255); - *dst = params->s01; - dst++; - dst_counter++; - - /* Return generated length */ - return dst_counter; -} - -/* - * Encode rfc2507 parameter field - * (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) - */ -static int encode_pcomp_rfc2507_params(uint8_t *dst, unsigned int dst_maxlen, - const struct - gprs_sndcp_pcomp_rfc2507_params *params) -{ - /* NOTE: Buffer *dst should offer at least 3 bytes - * of space to store the generation results */ - - int dst_counter = 0; - int rc; - - OSMO_ASSERT(dst_maxlen >= 9); - - /* Zero out buffer */ - memset(dst, 0, dst_maxlen); - - /* Encode applicable SAPIs */ - rc = encode_pcomp_applicable_sapis(dst, params->nsapi, - params->nsapi_len); - dst += rc; - dst_counter += rc; - - /* Encode F_MAX_PERIOD (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - OSMO_ASSERT(params->f_max_period >= 1); - OSMO_ASSERT(params->f_max_period <= 65535); - *dst = (params->f_max_period >> 8) & 0xFF; - dst++; - dst_counter++; - *dst = (params->f_max_period) & 0xFF; - dst++; - dst_counter++; - - /* Encode F_MAX_TIME (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - OSMO_ASSERT(params->f_max_time >= 1); - OSMO_ASSERT(params->f_max_time <= 255); - *dst = params->f_max_time; - dst++; - dst_counter++; - - /* Encode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - OSMO_ASSERT(params->max_header >= 60); - OSMO_ASSERT(params->max_header <= 255); - *dst = params->max_header; - dst++; - dst_counter++; - - /* Encode TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - OSMO_ASSERT(params->tcp_space >= 3); - OSMO_ASSERT(params->tcp_space <= 255); - *dst = params->tcp_space; - dst++; - dst_counter++; - - /* Encode NON_TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - OSMO_ASSERT(params->non_tcp_space >= 3); - OSMO_ASSERT(params->non_tcp_space <= 65535); - *dst = (params->non_tcp_space >> 8) & 0xFF; - dst++; - dst_counter++; - *dst = (params->non_tcp_space) & 0xFF; - dst++; - dst_counter++; - - /* Return generated length */ - return dst_counter; -} - -/* Encode ROHC parameter field - * (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ -static int encode_pcomp_rohc_params(uint8_t *dst, unsigned int dst_maxlen, - const struct gprs_sndcp_pcomp_rohc_params - *params) -{ - /* NOTE: Buffer *dst should offer at least 36 - * (2 * 16 Profiles + 2 * 3 Parameter) bytes - * of memory space to store generation results */ - - int i; - int dst_counter = 0; - int rc; - - OSMO_ASSERT(dst_maxlen >= 38); - - /* Bail if number of ROHC profiles exceeds limit - * (ROHC supports only a maximum of 16 different profiles) */ - OSMO_ASSERT(params->profile_len <= 16); - - /* Zero out buffer */ - memset(dst, 0, dst_maxlen); - - /* Encode applicable SAPIs */ - rc = encode_pcomp_applicable_sapis(dst, params->nsapi, - params->nsapi_len); - dst += rc; - dst_counter += rc; - - /* Encode MAX_CID (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ - OSMO_ASSERT(params->max_cid >= 0); - OSMO_ASSERT(params->max_cid <= 16383); - *dst = (params->max_cid >> 8) & 0xFF; - dst++; - *dst = params->max_cid & 0xFF; - dst++; - dst_counter += 2; - - /* Encode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ - OSMO_ASSERT(params->max_header >= 60); - OSMO_ASSERT(params->max_header <= 255); - *dst = (params->max_header >> 8) & 0xFF; - dst++; - *dst = params->max_header & 0xFF; - dst++; - dst_counter += 2; - - /* Encode ROHC Profiles (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ - for (i = 0; i < params->profile_len; i++) { - *dst = (params->profile[i] >> 8) & 0xFF; - dst++; - *dst = params->profile[i] & 0xFF; - dst++; - dst_counter += 2; - } - - /* Return generated length */ - return dst_counter; -} - -/* Encode V.42bis parameter field - * (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ -static int encode_dcomp_v42bis_params(uint8_t *dst, unsigned int dst_maxlen, - const struct - gprs_sndcp_dcomp_v42bis_params *params) -{ - /* NOTE: Buffer *dst should offer at least 6 bytes - * of space to store the generation results */ - - int dst_counter = 0; - int rc; - - OSMO_ASSERT(dst_maxlen >= 6); - - /* Zero out buffer */ - memset(dst, 0, dst_maxlen); - - /* Encode applicable SAPIs */ - rc = encode_pcomp_applicable_sapis(dst, params->nsapi, - params->nsapi_len); - dst += rc; - dst_counter += rc; - - /* Encode P0 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ - OSMO_ASSERT(params->p0 >= 0); - OSMO_ASSERT(params->p0 <= 3); - *dst = params->p0 & 0x03; - dst++; - dst_counter++; - - /* Encode P1 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ - OSMO_ASSERT(params->p1 >= 512); - OSMO_ASSERT(params->p1 <= 65535); - *dst = (params->p1 >> 8) & 0xFF; - dst++; - *dst = params->p1 & 0xFF; - dst++; - dst_counter += 2; - - /* Encode P2 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ - OSMO_ASSERT(params->p2 >= 6); - OSMO_ASSERT(params->p2 <= 250); - *dst = params->p2; - dst++; - dst_counter++; - - /* Return generated length */ - return dst_counter; -} - -/* Encode V44 parameter field - * (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ -static int encode_dcomp_v44_params(uint8_t *dst, unsigned int dst_maxlen, - const struct gprs_sndcp_dcomp_v44_params - *params) -{ - /* NOTE: Buffer *dst should offer at least 12 bytes - * of space to store the generation results */ - - int dst_counter = 0; - int rc; - - OSMO_ASSERT(dst_maxlen >= 12); - - /* Zero out buffer */ - memset(dst, 0, dst_maxlen); - - /* Encode applicable SAPIs */ - rc = encode_pcomp_applicable_sapis(dst, params->nsapi, - params->nsapi_len); - dst += rc; - dst_counter += rc; - - /* Encode C0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - OSMO_ASSERT(params->c0 == 0x80 || params->c0 == 0xC0); - *dst = params->c0 & 0xC0; - dst++; - dst_counter++; - - /* Encode P0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - OSMO_ASSERT(params->p0 >= 0); - OSMO_ASSERT(params->p0 <= 3); - *dst = params->p0 & 0x03; - dst++; - dst_counter++; - - /* Encode P1T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - OSMO_ASSERT(params->p1t >= 256); - OSMO_ASSERT(params->p1t <= 65535); - *dst = (params->p1t >> 8) & 0xFF; - dst++; - *dst = params->p1t & 0xFF; - dst++; - dst_counter += 2; - - /* Encode P1R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - OSMO_ASSERT(params->p1r >= 256); - OSMO_ASSERT(params->p1r <= 65535); - *dst = (params->p1r >> 8) & 0xFF; - dst++; - *dst = params->p1r & 0xFF; - dst++; - dst_counter += 2; - - /* Encode P3T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - OSMO_ASSERT(params->p3t >= 0); - OSMO_ASSERT(params->p3t <= 65535); - OSMO_ASSERT(params->p3t >= 2 * params->p1t); - *dst = (params->p3t >> 8) & 0xFF; - dst++; - *dst = params->p3t & 0xFF; - dst++; - dst_counter += 2; - - /* Encode P3R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - OSMO_ASSERT(params->p3r >= 0); - OSMO_ASSERT(params->p3r <= 65535); - OSMO_ASSERT(params->p3r >= 2 * params->p1r); - *dst = (params->p3r >> 8) & 0xFF; - dst++; - *dst = params->p3r & 0xFF; - dst++; - dst_counter += 2; - - /* Return generated length */ - return dst_counter; -} - -/* Encode data or protocol control information compression field - * (see also: 3GPP TS 44.065, 6.6.1.1, Figure 9 and - * 3GPP TS 44.065, 6.5.1.1, Figure 7) */ -static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen, - const struct gprs_sndcp_comp_field *comp_field) -{ - int dst_counter = 0; - int len; - int expected_length; - int i; - - uint8_t payload_bytes[256]; - int payload_bytes_len = -1; - - /* If possible, try do encode payload bytes first */ - if (comp_field->rfc1144_params) { - payload_bytes_len = - encode_pcomp_rfc1144_params(payload_bytes, - sizeof(payload_bytes), - comp_field->rfc1144_params); - } else if (comp_field->rfc2507_params) { - payload_bytes_len = - encode_pcomp_rfc2507_params(payload_bytes, - sizeof(payload_bytes), - comp_field->rfc2507_params); - } else if (comp_field->rohc_params) { - payload_bytes_len = - encode_pcomp_rohc_params(payload_bytes, - sizeof(payload_bytes), - comp_field->rohc_params); - } else if (comp_field->v42bis_params) { - payload_bytes_len = - encode_dcomp_v42bis_params(payload_bytes, - sizeof(payload_bytes), - comp_field->v42bis_params); - } else if (comp_field->v44_params) { - payload_bytes_len = - encode_dcomp_v44_params(payload_bytes, - sizeof(payload_bytes), - comp_field->v44_params); - } else - OSMO_ASSERT(false); - - /* Bail immediately if payload byte generation failed */ - OSMO_ASSERT(payload_bytes_len >= 0); - - /* Bail if comp_len is out of bounds */ - OSMO_ASSERT(comp_field->comp_len <= sizeof(comp_field->comp)); - - /* Calculate length field of the data block */ - if (comp_field->p) { - len = - payload_bytes_len + - ceil((double)(comp_field->comp_len) / 2.0); - expected_length = len + 3; - } else { - len = payload_bytes_len; - expected_length = len + 2; - } - - /* Bail immediately if no sufficient memory space is supplied */ - OSMO_ASSERT(dst_maxlen >= expected_length); - - /* Check if the entity number is within bounds */ - OSMO_ASSERT(comp_field->entity <= 0x1f); - - /* Check if the algorithm number is within bounds */ - OSMO_ASSERT(comp_field->algo >= 0 || comp_field->algo <= 0x1f); - - /* Zero out buffer */ - memset(dst, 0, dst_maxlen); - - /* Encode Propose bit */ - if (comp_field->p) - *dst |= (1 << 7); - - /* Encode entity number */ - *dst |= comp_field->entity & 0x1F; - dst++; - dst_counter++; - - /* Encode algorithm number */ - if (comp_field->p) { - *dst |= comp_field->algo & 0x1F; - dst++; - dst_counter++; - } - - /* Encode length field */ - *dst |= len & 0xFF; - dst++; - dst_counter++; - - /* Encode PCOMP/DCOMP values */ - if (comp_field->p) { - for (i = 0; i < comp_field->comp_len; i++) { - /* Check if submitted PCOMP/DCOMP - values are within bounds */ - if (comp_field->comp[i] > 0x0F) - return -EINVAL; - - if (i & 1) { - *dst |= comp_field->comp[i] & 0x0F; - dst++; - dst_counter++; - } else - *dst |= (comp_field->comp[i] << 4) & 0xF0; - } - - if (i & 1) { - dst++; - dst_counter++; - } - } - - /* Append payload bytes */ - memcpy(dst, payload_bytes, payload_bytes_len); - dst_counter += payload_bytes_len; - - /* Return generated length */ - return dst_counter; -} - -/* Find out to which compression class the specified comp-field belongs - * (header compression or data compression?) */ -int gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field - *comp_field) -{ - OSMO_ASSERT(comp_field); - - if (comp_field->rfc1144_params) - return SNDCP_XID_PROTOCOL_COMPRESSION; - else if (comp_field->rfc2507_params) - return SNDCP_XID_PROTOCOL_COMPRESSION; - else if (comp_field->rohc_params) - return SNDCP_XID_PROTOCOL_COMPRESSION; - else if (comp_field->v42bis_params) - return SNDCP_XID_DATA_COMPRESSION; - else if (comp_field->v44_params) - return SNDCP_XID_DATA_COMPRESSION; - else - return -EINVAL; -} - -/* Convert all compression fields to bytstreams */ -static int gprs_sndcp_pack_fields(const struct llist_head *comp_fields, - uint8_t *dst, - unsigned int dst_maxlen, int class) -{ - struct gprs_sndcp_comp_field *comp_field; - int byte_counter = 0; - int rc; - - llist_for_each_entry_reverse(comp_field, comp_fields, list) { - if (class == gprs_sndcp_get_compression_class(comp_field)) { - rc = encode_comp_field(dst + byte_counter, - dst_maxlen - byte_counter, - comp_field); - - /* When input data is correct, there is - * no reason for the encoder to fail! */ - OSMO_ASSERT(rc >= 0); - - byte_counter += rc; - } - } - - /* Return generated length */ - return byte_counter; -} - -/* Transform a list with compression fields into an SNDCP-XID message (dst) */ -int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, - const struct llist_head *comp_fields, int version) -{ - int rc; - int byte_counter = 0; - uint8_t comp_bytes[512]; - uint8_t xid_version_number[1]; - - OSMO_ASSERT(comp_fields); - OSMO_ASSERT(dst); - OSMO_ASSERT(dst_maxlen >= 2 + sizeof(xid_version_number)); - - /* Prepend header with version number */ - if (version >= 0) { - xid_version_number[0] = (uint8_t) (version & 0xff); - dst = - tlv_put(dst, SNDCP_XID_VERSION_NUMBER, - sizeof(xid_version_number), xid_version_number); - byte_counter += (sizeof(xid_version_number) + 2); - } - - /* Stop if there is no compression fields supplied */ - if (llist_empty(comp_fields)) - return byte_counter; - - /* Add data compression fields */ - rc = gprs_sndcp_pack_fields(comp_fields, comp_bytes, - sizeof(comp_bytes), - SNDCP_XID_DATA_COMPRESSION); - OSMO_ASSERT(rc >= 0); - - if (rc > 0) { - dst = tlv_put(dst, SNDCP_XID_DATA_COMPRESSION, rc, comp_bytes); - byte_counter += rc + 2; - } - - /* Add header compression fields */ - rc = gprs_sndcp_pack_fields(comp_fields, comp_bytes, - sizeof(comp_bytes), - SNDCP_XID_PROTOCOL_COMPRESSION); - OSMO_ASSERT(rc >= 0); - - if (rc > 0) { - dst = tlv_put(dst, SNDCP_XID_PROTOCOL_COMPRESSION, rc, - comp_bytes); - byte_counter += rc + 2; - } - - /* Return generated length */ - return byte_counter; -} - -/* FUNCTIONS RELATED TO SNDCP-XID DECODING */ - -/* Decode applicable sapis (works the same in all three compression schemes) */ -static int decode_pcomp_applicable_sapis(uint8_t *nsapis, - uint8_t *nsapis_len, - const uint8_t *src, - unsigned int src_len) -{ - uint16_t blob; - int i; - int nsapi_len = 0; - - /* Exit immediately if no result can be stored */ - if (!nsapis) - return -EINVAL; - - /* Exit immediately if not enough input data is available */ - if (src_len < 2) - return -EINVAL; - - /* Read bitmask */ - blob = *src; - blob = (blob << 8) & 0xFF00; - src++; - blob |= (*src) & 0xFF; - blob = (blob >> 5); - - /* Decode applicable SAPIs */ - for (i = 0; i < 15; i++) { - if ((blob >> i) & 1) { - nsapis[nsapi_len] = i + 5; - nsapi_len++; - } - } - - /* Return consumed length */ - *nsapis_len = nsapi_len; - return 2; -} - -/* Decode 16 bit field */ -static int decode_pcomp_16_bit_field(int *value_int, uint16_t * value_uint16, - const uint8_t *src, - unsigned int src_len, - int value_min, int value_max) -{ - uint16_t blob; - - /* Reset values to zero (just to be sure) */ - if (value_int) - *value_int = -1; - if (value_uint16) - *value_uint16 = 0; - - /* Exit if not enough src are available */ - if (src_len < 2) - return -EINVAL; - - /* Decode bit value */ - blob = *src; - blob = (blob << 8) & 0xFF00; - src++; - blob |= *src; - - /* Check if parsed value is within bounds */ - if (blob < value_min) - return -EINVAL; - if (blob > value_max) - return -EINVAL; - - /* Hand back results to the caller */ - if (value_int) - *value_int = blob; - if (value_uint16) - *value_uint16 = blob; - - /* Return consumed length */ - return 2; -} - -/* Decode 8 bit field */ -static int decode_pcomp_8_bit_field(int *value_int, uint8_t *value_uint8, - const uint8_t *src, - unsigned int src_len, - int value_min, int value_max) -{ - uint8_t blob; - - /* Reset values to invalid (just to be sure) */ - if (value_int) - *value_int = -1; - if (value_uint8) - *value_uint8 = 0; - - /* Exit if not enough src are available */ - if (src_len < 1) - return -EINVAL; - - /* Decode bit value */ - blob = *src; - - /* Check if parsed value is within bounds */ - if (blob < value_min) - return -EINVAL; - if (blob > value_max) - return -EINVAL; - - /* Hand back results to the caller */ - if (value_int) - *value_int = blob; - if (value_uint8) - *value_uint8 = blob; - - /* Return consumed length */ - return 1; -} - -/* Decode rfc1144 parameter field see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ -static int decode_pcomp_rfc1144_params(struct gprs_sndcp_pcomp_rfc1144_params - *params, const uint8_t *src, - unsigned int src_len) -{ - int rc; - int byte_counter = 0; - - /* Mark all optional parameters invalid by default */ - params->s01 = -1; - - /* Decode applicable SAPIs */ - rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, - src, src_len); - if (rc > 0) { - byte_counter += rc; - src += rc; - } else - return byte_counter; - - /* Decode parameter S0 -1 - * (see also: 3GPP TS 44.065, 6.5.2.1, Table 5) */ - rc = decode_pcomp_8_bit_field(¶ms->s01, NULL, src, - src_len - byte_counter, 0, 255); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Return consumed length */ - return byte_counter; -} - -/* Decode rfc2507 parameter field - * (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ -static int decode_pcomp_rfc2507_params(struct gprs_sndcp_pcomp_rfc2507_params - *params, const uint8_t *src, - unsigned int src_len) -{ - int rc; - int byte_counter = 0; - - /* Mark all optional parameters invalid by default */ - params->f_max_period = -1; - params->f_max_time = -1; - params->max_header = -1; - params->tcp_space = -1; - params->non_tcp_space = -1; - - /* Decode applicable SAPIs */ - rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, - src, src_len); - if (rc > 0) { - byte_counter += rc; - src += rc; - } else - return byte_counter; - - /* Decode F_MAX_PERIOD (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - rc = decode_pcomp_16_bit_field(¶ms->f_max_period, NULL, src, - src_len - byte_counter, 1, 65535); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode F_MAX_TIME (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - rc = decode_pcomp_8_bit_field(¶ms->f_max_time, NULL, src, - src_len - byte_counter, 1, 255); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - rc = decode_pcomp_8_bit_field(¶ms->max_header, NULL, src, - src_len - byte_counter, 60, 255); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - rc = decode_pcomp_8_bit_field(¶ms->tcp_space, NULL, src, - src_len - byte_counter, 3, 255); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode NON_TCP_SPACE (see also: 3GPP TS 44.065, 6.5.3.1, Table 6) */ - rc = decode_pcomp_16_bit_field(¶ms->non_tcp_space, NULL, src, - src_len - byte_counter, 3, 65535); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Return consumed length */ - return byte_counter; -} - -/* Decode ROHC parameter field (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ -static int decode_pcomp_rohc_params(struct gprs_sndcp_pcomp_rohc_params *params, - const uint8_t *src, unsigned int src_len) -{ - int rc; - int byte_counter = 0; - int i; - - /* Mark all optional parameters invalid by default */ - params->max_cid = -1; - params->max_header = -1; - - /* Decode applicable SAPIs */ - rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, - src, src_len); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode MAX_CID (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ - rc = decode_pcomp_16_bit_field(¶ms->max_cid, NULL, src, - src_len - byte_counter, 0, 16383); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode MAX_HEADER (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ - rc = decode_pcomp_16_bit_field(¶ms->max_header, NULL, src, - src_len - byte_counter, 60, 255); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode Profiles (see also: 3GPP TS 44.065, 6.5.4.1, Table 10) */ - for (i = 0; i < 16; i++) { - params->profile_len = 0; - rc = decode_pcomp_16_bit_field(NULL, ¶ms->profile[i], src, - src_len - byte_counter, 0, - 65535); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - params->profile_len = i + 1; - } - - /* Return consumed length */ - return byte_counter; -} - -/* Decode V.42bis parameter field - * (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ -static int decode_dcomp_v42bis_params(struct gprs_sndcp_dcomp_v42bis_params - *params, const uint8_t *src, - unsigned int src_len) -{ - int rc; - int byte_counter = 0; - - /* Mark all optional parameters invalid by default */ - params->p0 = -1; - params->p1 = -1; - params->p2 = -1; - - /* Decode applicable SAPIs */ - rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, - src, src_len); - if (rc > 0) { - byte_counter += rc; - src += rc; - } else - return byte_counter; - - /* Decode P0 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ - rc = decode_pcomp_8_bit_field(¶ms->p0, NULL, src, - src_len - byte_counter, 0, 3); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode P1 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ - rc = decode_pcomp_16_bit_field(¶ms->p1, NULL, src, - src_len - byte_counter, 512, 65535); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode P2 (see also: 3GPP TS 44.065, 6.6.2.1, Table 7a) */ - rc = decode_pcomp_8_bit_field(¶ms->p2, NULL, src, - src_len - byte_counter, 6, 250); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Return consumed length */ - return byte_counter; -} - -/* Decode V44 parameter field (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ -static int decode_dcomp_v44_params(struct gprs_sndcp_dcomp_v44_params *params, - const uint8_t *src, unsigned int src_len) -{ - int rc; - int byte_counter = 0; - - /* Mark all optional parameters invalid by default */ - params->c0 = -1; - params->p0 = -1; - params->p1t = -1; - params->p1r = -1; - params->p3t = -1; - params->p3r = -1; - - /* Decode applicable SAPIs */ - rc = decode_pcomp_applicable_sapis(params->nsapi, ¶ms->nsapi_len, - src, src_len); - if (rc > 0) { - byte_counter += rc; - src += rc; - } else - return byte_counter; - - /* Decode C0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - rc = decode_pcomp_8_bit_field(¶ms->c0, NULL, src, - src_len - byte_counter, 0, 255); - if (rc <= 0) - return byte_counter; - if ((params->c0 != 0x80) && (params->c0 != 0xC0)) - return -EINVAL; - byte_counter += rc; - src += rc; - - /* Decode P0 (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - rc = decode_pcomp_8_bit_field(¶ms->p0, NULL, src, - src_len - byte_counter, 0, 3); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode P1T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - rc = decode_pcomp_16_bit_field(¶ms->p1t, NULL, src, - src_len - byte_counter, 265, 65535); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode P1R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - rc = decode_pcomp_16_bit_field(¶ms->p1r, NULL, src, - src_len - byte_counter, 265, 65535); - if (rc <= 0) - return byte_counter; - byte_counter += rc; - src += rc; - - /* Decode P3T (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - rc = decode_pcomp_16_bit_field(¶ms->p3t, NULL, src, - src_len - byte_counter, 265, 65535); - if (rc <= 0) - return byte_counter; - if (params->p3t < 2 * params->p1t) - return -EINVAL; - byte_counter += rc; - src += rc; - - /* Decode P3R (see also: 3GPP TS 44.065, 6.6.3.1, Table 7c) */ - rc = decode_pcomp_16_bit_field(¶ms->p3r, NULL, src, - src_len - byte_counter, 265, 65535); - if (rc <= 0) - return byte_counter; - if (params->p3r < 2 * params->p1r) - return -EINVAL; - byte_counter += rc; - src += rc; - - /* Return consumed length */ - return byte_counter; -} - -/* Lookup algorithm identfier by entity ID */ -static int lookup_algorithm_identifier(int entity, const struct - entity_algo_table - *lt, unsigned int lt_len, int compclass) -{ - int i; - - if (!lt) - return -1; - - for (i = 0; i < lt_len; i++) { - if ((lt[i].entity == entity) - && (lt[i].compclass == compclass)) - return lt[i].algo; - } - - return -1; -} - -/* Helper function for decode_comp_field(), decodes - * numeric pcomp/dcomp values */ -static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field, - const uint8_t *src, int compclass) -{ - int src_counter = 0; - int i; - - if (comp_field->p) { - /* Determine the number of expected PCOMP/DCOMP values */ - if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { - /* For protocol compression */ - switch (comp_field->algo) { - case RFC_1144: - comp_field->comp_len = RFC1144_PCOMP_NUM; - break; - case RFC_2507: - comp_field->comp_len = RFC2507_PCOMP_NUM; - break; - case ROHC: - comp_field->comp_len = ROHC_PCOMP_NUM; - break; - - /* Exit if the algorithem type encodes - something unknown / unspecified */ - default: - return -EINVAL; - } - } else { - /* For data compression */ - switch (comp_field->algo) { - case V42BIS: - comp_field->comp_len = V42BIS_DCOMP_NUM; - break; - case V44: - comp_field->comp_len = V44_DCOMP_NUM; - break; - - /* Exit if the algorithem type encodes - something unknown / unspecified */ - default: - return -EINVAL; - } - } - - for (i = 0; i < comp_field->comp_len; i++) { - if (i & 1) { - comp_field->comp[i] = (*src) & 0x0F; - src++; - src_counter++; - } else - comp_field->comp[i] = ((*src) >> 4) & 0x0F; - } - - if (i & 1) { - src++; - src_counter++; - } - } - - return src_counter; -} - -/* Helper function for decode_comp_field(), decodes the parameters - * which are protocol compression specific */ -static int decode_pcomp_params(struct gprs_sndcp_comp_field *comp_field, - const uint8_t *src, int src_len) -{ - int rc; - - switch (comp_field->algo) { - case RFC_1144: - comp_field->rfc1144_params = talloc_zero(comp_field, struct - gprs_sndcp_pcomp_rfc1144_params); - rc = decode_pcomp_rfc1144_params(comp_field->rfc1144_params, - src, src_len); - if (rc < 0) - talloc_free(comp_field->rfc1144_params); - break; - case RFC_2507: - comp_field->rfc2507_params = talloc_zero(comp_field, struct - gprs_sndcp_pcomp_rfc2507_params); - rc = decode_pcomp_rfc2507_params(comp_field->rfc2507_params, - src, src_len); - if (rc < 0) - talloc_free(comp_field->rfc1144_params); - break; - case ROHC: - comp_field->rohc_params = talloc_zero(comp_field, struct - gprs_sndcp_pcomp_rohc_params); - rc = decode_pcomp_rohc_params(comp_field->rohc_params, src, - src_len); - if (rc < 0) - talloc_free(comp_field->rohc_params); - break; - - /* If no suitable decoder is detected, - leave the remaining bytes undecoded */ - default: - rc = src_len; - } - - if (rc < 0) { - comp_field->rfc1144_params = NULL; - comp_field->rfc2507_params = NULL; - comp_field->rohc_params = NULL; - } - - return rc; -} - -/* Helper function for decode_comp_field(), decodes the parameters - * which are data compression specific */ -static int decode_dcomp_params(struct gprs_sndcp_comp_field *comp_field, - const uint8_t *src, int src_len) -{ - int rc; - - switch (comp_field->algo) { - case V42BIS: - comp_field->v42bis_params = talloc_zero(comp_field, struct - gprs_sndcp_dcomp_v42bis_params); - rc = decode_dcomp_v42bis_params(comp_field->v42bis_params, src, - src_len); - if (rc < 0) - talloc_free(comp_field->v42bis_params); - break; - case V44: - comp_field->v44_params = talloc_zero(comp_field, struct - gprs_sndcp_dcomp_v44_params); - rc = decode_dcomp_v44_params(comp_field->v44_params, src, - src_len); - if (rc < 0) - talloc_free(comp_field->v44_params); - break; - - /* If no suitable decoder is detected, - * leave the remaining bytes undecoded */ - default: - rc = src_len; - } - - if (rc < 0) { - comp_field->v42bis_params = NULL; - comp_field->v44_params = NULL; - } - - return rc; -} - -/* Decode data or protocol control information compression field - * (see also: 3GPP TS 44.065, 6.6.1.1, Figure 9 and - * 3GPP TS 44.065, 6.5.1.1, Figure 7) */ -static int decode_comp_field(struct gprs_sndcp_comp_field *comp_field, - const uint8_t *src, unsigned int src_len, - const struct entity_algo_table *lt, - unsigned int lt_len, int compclass) -{ - int src_counter = 0; - unsigned int len; - int rc; - - OSMO_ASSERT(comp_field); - - /* Exit immediately if it is clear that no - parseable data is present */ - if (src_len < 1 || !src) - return -EINVAL; - - /* Zero out target struct */ - memset(comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); - - /* Decode Propose bit and Entity number */ - if ((*src) & 0x80) - comp_field->p = 1; - comp_field->entity = (*src) & 0x1F; - src_counter++; - src++; - - /* Decode algorithm number (if present) */ - if (comp_field->p) { - comp_field->algo = (*src) & 0x1F; - src_counter++; - src++; - } - /* Alternatively take the information from the lookup table */ - else - comp_field->algo = - lookup_algorithm_identifier(comp_field->entity, lt, - lt_len, compclass); - - /* Decode length field */ - len = *src; - src_counter++; - src++; - - /* Decode PCOMP/DCOMP values */ - rc = decode_comp_values(comp_field, src, compclass); - if (rc < 0) - return -EINVAL; - src_counter += rc; - src += rc; - len -= rc; - - /* Decode algorithm specific payload data */ - if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) - rc = decode_pcomp_params(comp_field, src, len); - else if (compclass == SNDCP_XID_DATA_COMPRESSION) - rc = decode_dcomp_params(comp_field, src, len); - else - return -EINVAL; - - if (rc >= 0) - src_counter += rc; - else - return -EINVAL; - - /* Return consumed length */ - return src_counter; -} - -/* Helper function for gprs_sndcp_decode_xid() to decode XID blocks */ -static int decode_xid_block(struct llist_head *comp_fields, uint8_t tag, - uint16_t tag_len, const uint8_t *val, - const struct entity_algo_table *lt, - unsigned int lt_len) -{ - struct gprs_sndcp_comp_field *comp_field; - int byte_counter = 0; - int comp_field_count = 0; - int rc; - - byte_counter = 0; - do { - /* Bail if more than the maximum number of - comp_fields is generated */ - if (comp_field_count > MAX_ENTITIES * 2) { - return -EINVAL; - } - - /* Parse and add comp_field */ - comp_field = - talloc_zero(comp_fields, struct gprs_sndcp_comp_field); - - rc = decode_comp_field(comp_field, val + byte_counter, - tag_len - byte_counter, lt, lt_len, tag); - - if (rc < 0) { - talloc_free(comp_field); - return -EINVAL; - } - - byte_counter += rc; - llist_add(&comp_field->list, comp_fields); - comp_field_count++; - } - while (tag_len - byte_counter > 0); - - return byte_counter; -} - -/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ -static int gprs_sndcp_decode_xid(int *version, struct llist_head *comp_fields, - const uint8_t *src, unsigned int src_len, - const struct entity_algo_table *lt, - unsigned int lt_len) -{ - int src_pos = 0; - uint8_t tag; - uint16_t tag_len; - const uint8_t *val; - int byte_counter = 0; - int rc; - int tlv_count = 0; - - /* Preset version value as invalid */ - if (version) - *version = -1; - - /* Valid TLV-Tag and types */ - static const struct tlv_definition sndcp_xid_def = { - .def = { - [SNDCP_XID_VERSION_NUMBER] = {TLV_TYPE_TLV,}, - [SNDCP_XID_DATA_COMPRESSION] = {TLV_TYPE_TLV,}, - [SNDCP_XID_PROTOCOL_COMPRESSION] = {TLV_TYPE_TLV,}, - }, - }; - - /* Parse TLV-Encoded SNDCP-XID message and defer payload - to the apporpiate sub-parser functions */ - while (1) { - - /* Bail if an the maximum number of TLV fields - * have been parsed */ - if (tlv_count >= 3) { - talloc_free(comp_fields); - return -EINVAL; - } - - /* Parse TLV field */ - rc = tlv_parse_one(&tag, &tag_len, &val, &sndcp_xid_def, - src + src_pos, src_len - src_pos); - if (rc > 0) - src_pos += rc; - else { - talloc_free(comp_fields); - return -EINVAL; - } - - /* Decode sndcp xid version number */ - if (version && tag == SNDCP_XID_VERSION_NUMBER) - *version = val[0]; - - /* Decode compression parameters */ - if ((tag == SNDCP_XID_PROTOCOL_COMPRESSION) - || (tag == SNDCP_XID_DATA_COMPRESSION)) { - rc = decode_xid_block(comp_fields, tag, tag_len, val, - lt, lt_len); - - if (rc < 0) { - talloc_free(comp_fields); - return -EINVAL; - } else - byte_counter += rc; - } - - /* Stop when no further TLV elements can be expected */ - if (src_len - src_pos <= 2) - break; - - tlv_count++; - } - - return 0; -} - -/* Fill up lookutable from a list with comression entitiy fields */ -static int gprs_sndcp_fill_table(struct - entity_algo_table *lt, - unsigned int lt_len, - const struct llist_head *comp_fields) -{ - struct gprs_sndcp_comp_field *comp_field; - int i = 0; - int rc; - - if (!comp_fields) - return -EINVAL; - if (!lt) - return -EINVAL; - - memset(lt, 0, sizeof(*lt)); - - llist_for_each_entry(comp_field, comp_fields, list) { - if (comp_field->algo >= 0) { - lt[i].entity = comp_field->entity; - lt[i].algo = comp_field->algo; - rc = gprs_sndcp_get_compression_class(comp_field); - - if (rc < 0) { - memset(lt, 0, sizeof(*lt)); - return -EINVAL; - } - - lt[i].compclass = rc; - i++; - } - } - - return i; -} - -/* Complete comp field params - * (if a param (dst) is not valid, it will be copied from source (src) */ -static int complete_comp_field_params(struct gprs_sndcp_comp_field - *comp_field_dst, const struct - gprs_sndcp_comp_field *comp_field_src) -{ - if (comp_field_dst->algo < 0) - return -EINVAL; - - if (comp_field_dst->rfc1144_params && comp_field_src->rfc1144_params) { - if (comp_field_dst->rfc1144_params->s01 < 0) { - comp_field_dst->rfc1144_params->s01 = - comp_field_src->rfc1144_params->s01; - } - return 0; - } - - if (comp_field_dst->rfc2507_params && comp_field_src->rfc2507_params) { - - if (comp_field_dst->rfc2507_params->f_max_period < 0) { - comp_field_dst->rfc2507_params->f_max_period = - comp_field_src->rfc2507_params->f_max_period; - } - if (comp_field_dst->rfc2507_params->f_max_time < 0) { - comp_field_dst->rfc2507_params->f_max_time = - comp_field_src->rfc2507_params->f_max_time; - } - if (comp_field_dst->rfc2507_params->max_header < 0) { - comp_field_dst->rfc2507_params->max_header = - comp_field_src->rfc2507_params->max_header; - } - if (comp_field_dst->rfc2507_params->tcp_space < 0) { - comp_field_dst->rfc2507_params->tcp_space = - comp_field_src->rfc2507_params->tcp_space; - } - if (comp_field_dst->rfc2507_params->non_tcp_space < 0) { - comp_field_dst->rfc2507_params->non_tcp_space = - comp_field_src->rfc2507_params->non_tcp_space; - } - return 0; - } - - if (comp_field_dst->rohc_params && comp_field_src->rohc_params) { - if (comp_field_dst->rohc_params->max_cid < 0) { - comp_field_dst->rohc_params->max_cid = - comp_field_src->rohc_params->max_cid; - } - if (comp_field_dst->rohc_params->max_header < 0) { - comp_field_dst->rohc_params->max_header = - comp_field_src->rohc_params->max_header; - } - if (comp_field_dst->rohc_params->profile_len > 0) { - memcpy(comp_field_dst->rohc_params->profile, - comp_field_src->rohc_params->profile, - sizeof(comp_field_dst->rohc_params->profile)); - comp_field_dst->rohc_params->profile_len = - comp_field_src->rohc_params->profile_len; - } - - return 0; - } - - if (comp_field_dst->v42bis_params && comp_field_src->v42bis_params) { - if (comp_field_dst->v42bis_params->p0 < 0) { - comp_field_dst->v42bis_params->p0 = - comp_field_src->v42bis_params->p0; - } - if (comp_field_dst->v42bis_params->p1 < 0) { - comp_field_dst->v42bis_params->p1 = - comp_field_src->v42bis_params->p1; - } - if (comp_field_dst->v42bis_params->p2 < 0) { - comp_field_dst->v42bis_params->p2 = - comp_field_src->v42bis_params->p2; - } - return 0; - } - - if (comp_field_dst->v44_params && comp_field_src->v44_params) { - if (comp_field_dst->v44_params->c0 < 0) { - comp_field_dst->v44_params->c0 = - comp_field_src->v44_params->c0; - } - if (comp_field_dst->v44_params->p0 < 0) { - comp_field_dst->v44_params->p0 = - comp_field_src->v44_params->p0; - } - if (comp_field_dst->v44_params->p1t < 0) { - comp_field_dst->v44_params->p1t = - comp_field_src->v44_params->p1t; - } - if (comp_field_dst->v44_params->p1r < 0) { - comp_field_dst->v44_params->p1r = - comp_field_src->v44_params->p1r; - } - if (comp_field_dst->v44_params->p3t < 0) { - comp_field_dst->v44_params->p3t = - comp_field_src->v44_params->p3t; - } - if (comp_field_dst->v44_params->p3r < 0) { - comp_field_dst->v44_params->p3r = - comp_field_src->v44_params->p3r; - } - return 0; - } - - /* There should be at least exist one param set - * in the destination struct, otherwise something - * must be wrong! */ - return -EINVAL; -} - -/* Complete missing parameters in a comp_field */ -static int gprs_sndcp_complete_comp_field(struct gprs_sndcp_comp_field - *comp_field, const struct llist_head - *comp_fields) -{ - struct gprs_sndcp_comp_field *comp_field_src; - int rc = 0; - - llist_for_each_entry(comp_field_src, comp_fields, list) { - if (comp_field_src->entity == comp_field->entity) { - - /* Complete header fields */ - if (comp_field_src->comp_len > 0) { - memcpy(comp_field->comp, - comp_field_src->comp, - sizeof(comp_field_src->comp)); - comp_field->comp_len = comp_field_src->comp_len; - } - - /* Complete parameter fields */ - rc = complete_comp_field_params(comp_field, - comp_field_src); - } - } - - return rc; -} - -/* Complete missing parameters of all comp_field in a list */ -static int gprs_sndcp_complete_comp_fields(struct llist_head - *comp_fields_incomplete, - const struct llist_head *comp_fields) -{ - struct gprs_sndcp_comp_field *comp_field_incomplete; - int rc; - - llist_for_each_entry(comp_field_incomplete, comp_fields_incomplete, - list) { - - rc = gprs_sndcp_complete_comp_field(comp_field_incomplete, - comp_fields); - if (rc < 0) - return -EINVAL; - - } - - return 0; -} - -/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ -struct llist_head *gprs_sndcp_parse_xid(int *version, - const void *ctx, - const uint8_t *src, - unsigned int src_len, - const struct llist_head - *comp_fields_req) -{ - int rc; - int lt_len; - struct llist_head *comp_fields; - struct entity_algo_table lt[MAX_ENTITIES * 2]; - - /* In case of a zero length field, just exit */ - if (src_len == 0) - return NULL; - - /* We should go any further if we have a field length greater - * zero and a null pointer as buffer! */ - OSMO_ASSERT(src); - - comp_fields = talloc_zero(ctx, struct llist_head); - INIT_LLIST_HEAD(comp_fields); - - if (comp_fields_req) { - /* Generate lookup table */ - lt_len = - gprs_sndcp_fill_table(lt, MAX_ENTITIES * 2, - comp_fields_req); - if (lt_len < 0) { - talloc_free(comp_fields); - return NULL; - } - - /* Parse SNDCP-CID XID-Field */ - rc = gprs_sndcp_decode_xid(version, comp_fields, src, src_len, - lt, lt_len); - if (rc < 0) { - talloc_free(comp_fields); - return NULL; - } - - rc = gprs_sndcp_complete_comp_fields(comp_fields, - comp_fields_req); - if (rc < 0) { - talloc_free(comp_fields); - return NULL; - } - - } else { - /* Parse SNDCP-CID XID-Field */ - rc = gprs_sndcp_decode_xid(version, comp_fields, src, src_len, - NULL, 0); - if (rc < 0) { - talloc_free(comp_fields); - return NULL; - } - } - - return comp_fields; -} - -/* Helper for gprs_sndcp_dump_comp_fields(), - * dumps protocol compression parameters */ -static void dump_pcomp_params(const struct gprs_sndcp_comp_field - *comp_field, unsigned int logl) -{ - int i; - - switch (comp_field->algo) { - case RFC_1144: - if (comp_field->rfc1144_params == NULL) { - LOGP(DSNDCP, logl, - " gprs_sndcp_pcomp_rfc1144_params=NULL\n"); - break; - } - LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rfc1144_params {\n"); - LOGP(DSNDCP, logl, - " nsapi_len=%d;\n", - comp_field->rfc1144_params->nsapi_len); - if (comp_field->rfc1144_params->nsapi_len == 0) - LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); - for (i = 0; i < comp_field->rfc1144_params->nsapi_len; i++) { - LOGP(DSNDCP, logl, - " nsapi[%d]=%d;\n", i, - comp_field->rfc1144_params->nsapi[i]); - } - LOGP(DSNDCP, logl, " s01=%d;\n", - comp_field->rfc1144_params->s01); - LOGP(DSNDCP, logl, " }\n"); - break; - case RFC_2507: - if (comp_field->rfc2507_params == NULL) { - LOGP(DSNDCP, logl, - " gprs_sndcp_pcomp_rfc2507_params=NULL\n"); - break; - } - LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rfc2507_params {\n"); - LOGP(DSNDCP, logl, - " nsapi_len=%d;\n", - comp_field->rfc2507_params->nsapi_len); - if (comp_field->rfc2507_params->nsapi_len == 0) - LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); - for (i = 0; i < comp_field->rfc2507_params->nsapi_len; i++) { - LOGP(DSNDCP, logl, - " nsapi[%d]=%d;\n", i, - comp_field->rfc2507_params->nsapi[i]); - } - LOGP(DSNDCP, logl, - " f_max_period=%d;\n", - comp_field->rfc2507_params->f_max_period); - LOGP(DSNDCP, logl, - " f_max_time=%d;\n", - comp_field->rfc2507_params->f_max_time); - LOGP(DSNDCP, logl, - " max_header=%d;\n", - comp_field->rfc2507_params->max_header); - LOGP(DSNDCP, logl, - " tcp_space=%d;\n", - comp_field->rfc2507_params->tcp_space); - LOGP(DSNDCP, logl, - " non_tcp_space=%d;\n", - comp_field->rfc2507_params->non_tcp_space); - LOGP(DSNDCP, logl, " }\n"); - break; - case ROHC: - if (comp_field->rohc_params == NULL) { - LOGP(DSNDCP, logl, - " gprs_sndcp_pcomp_rohc_params=NULL\n"); - break; - } - LOGP(DSNDCP, logl, " gprs_sndcp_pcomp_rohc_params {\n"); - LOGP(DSNDCP, logl, - " nsapi_len=%d;\n", - comp_field->rohc_params->nsapi_len); - if (comp_field->rohc_params->nsapi_len == 0) - LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); - for (i = 0; i < comp_field->rohc_params->nsapi_len; i++) { - LOGP(DSNDCP, logl, - " nsapi[%d]=%d;\n", i, - comp_field->rohc_params->nsapi[i]); - } - LOGP(DSNDCP, logl, - " max_cid=%d;\n", comp_field->rohc_params->max_cid); - LOGP(DSNDCP, logl, - " max_header=%d;\n", - comp_field->rohc_params->max_header); - LOGP(DSNDCP, logl, - " profile_len=%d;\n", - comp_field->rohc_params->profile_len); - if (comp_field->rohc_params->profile_len == 0) - LOGP(DSNDCP, logl, " profile[] = NULL;\n"); - for (i = 0; i < comp_field->rohc_params->profile_len; i++) - LOGP(DSNDCP, logl, - " profile[%d]=%04x;\n", - i, comp_field->rohc_params->profile[i]); - LOGP(DSNDCP, logl, " }\n"); - break; - } - -} - -/* Helper for gprs_sndcp_dump_comp_fields(), - * data protocol compression parameters */ -static void dump_dcomp_params(const struct gprs_sndcp_comp_field - *comp_field, unsigned int logl) -{ - int i; - - switch (comp_field->algo) { - case V42BIS: - if (comp_field->v42bis_params == NULL) { - LOGP(DSNDCP, logl, - " gprs_sndcp_dcomp_v42bis_params=NULL\n"); - break; - } - LOGP(DSNDCP, logl, " gprs_sndcp_dcomp_v42bis_params {\n"); - LOGP(DSNDCP, logl, - " nsapi_len=%d;\n", - comp_field->v42bis_params->nsapi_len); - if (comp_field->v42bis_params->nsapi_len == 0) - LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); - for (i = 0; i < comp_field->v42bis_params->nsapi_len; i++) - LOGP(DSNDCP, logl, - " nsapi[%d]=%d;\n", i, - comp_field->v42bis_params->nsapi[i]); - LOGP(DSNDCP, logl, " p0=%d;\n", - comp_field->v42bis_params->p0); - LOGP(DSNDCP, logl, " p1=%d;\n", - comp_field->v42bis_params->p1); - LOGP(DSNDCP, logl, " p2=%d;\n", - comp_field->v42bis_params->p2); - LOGP(DSNDCP, logl, " }\n"); - break; - case V44: - if (comp_field->v44_params == NULL) { - LOGP(DSNDCP, logl, - " gprs_sndcp_dcomp_v44_params=NULL\n"); - break; - } - LOGP(DSNDCP, logl, " gprs_sndcp_dcomp_v44_params {\n"); - LOGP(DSNDCP, logl, - " nsapi_len=%d;\n", - comp_field->v44_params->nsapi_len); - if (comp_field->v44_params->nsapi_len == 0) - LOGP(DSNDCP, logl, " nsapi[] = NULL;\n"); - for (i = 0; i < comp_field->v44_params->nsapi_len; i++) { - LOGP(DSNDCP, logl, - " nsapi[%d]=%d;\n", i, - comp_field->v44_params->nsapi[i]); - } - LOGP(DSNDCP, logl, " c0=%d;\n", - comp_field->v44_params->c0); - LOGP(DSNDCP, logl, " p0=%d;\n", - comp_field->v44_params->p0); - LOGP(DSNDCP, logl, " p1t=%d;\n", - comp_field->v44_params->p1t); - LOGP(DSNDCP, logl, " p1r=%d;\n", - comp_field->v44_params->p1r); - LOGP(DSNDCP, logl, " p3t=%d;\n", - comp_field->v44_params->p3t); - LOGP(DSNDCP, logl, " p3r=%d;\n", - comp_field->v44_params->p3r); - LOGP(DSNDCP, logl, " }\n"); - break; - } -} - -/* Dump a list with SNDCP-XID fields (Debug) */ -void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, - unsigned int logl) -{ - struct gprs_sndcp_comp_field *comp_field; - int i; - int compclass; - - OSMO_ASSERT(comp_fields); - - llist_for_each_entry(comp_field, comp_fields, list) { - LOGP(DSNDCP, logl, "SNDCP-XID:\n"); - LOGP(DSNDCP, logl, "struct gprs_sndcp_comp_field {\n"); - LOGP(DSNDCP, logl, " entity=%d;\n", comp_field->entity); - LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo); - LOGP(DSNDCP, logl, " comp_len=%d;\n", comp_field->comp_len); - if (comp_field->comp_len == 0) - LOGP(DSNDCP, logl, " comp[] = NULL;\n"); - for (i = 0; i < comp_field->comp_len; i++) { - LOGP(DSNDCP, logl, " comp[%d]=%d;\n", i, - comp_field->comp[i]); - } - - compclass = gprs_sndcp_get_compression_class(comp_field); - - if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) { - dump_pcomp_params(comp_field, logl); - } else if (compclass == SNDCP_XID_DATA_COMPRESSION) { - dump_dcomp_params(comp_field, logl); - } - - LOGP(DSNDCP, logl, "}\n"); - } - -} diff --git a/src/gprs/gprs_subscriber.c b/src/gprs/gprs_subscriber.c deleted file mode 100644 index 94297d0d6..000000000 --- a/src/gprs/gprs_subscriber.c +++ /dev/null @@ -1,937 +0,0 @@ -/* MS subscriber data handling */ - -/* (C) 2014 by sysmocom s.f.m.c. GmbH - * (C) 2015 by Holger Hans Peter Freyther - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#define SGSN_SUBSCR_MAX_RETRIES 3 -#define SGSN_SUBSCR_RETRY_INTERVAL 10 - -#define LOGGSUPP(level, gsup, fmt, args...) \ - LOGP(DGPRS, level, "GSUP(%s) " fmt, \ - (gsup)->imsi, \ - ## args) - -extern void *tall_bsc_ctx; - -LLIST_HEAD(_gprs_subscribers); -struct llist_head * const gprs_subscribers = &_gprs_subscribers; - -static int gsup_read_cb(struct gsup_client *gsupc, struct msgb *msg); - -/* TODO: Some functions are specific to the SGSN, but this file is more general - * (it has gprs_* name). Either move these functions elsewhere, split them and - * move a part, or replace the gprs_ prefix by sgsn_. The applies to - * gprs_subscr_init, gsup_read_cb, and gprs_subscr_tx_gsup_message. - */ - -int gprs_subscr_init(struct sgsn_instance *sgi) -{ - const char *addr_str; - - if (!sgi->cfg.gsup_server_addr.sin_addr.s_addr) - return 0; - - addr_str = inet_ntoa(sgi->cfg.gsup_server_addr.sin_addr); - - sgi->gsup_client = gsup_client_create( - "SGSN", - addr_str, sgi->cfg.gsup_server_port, - &gsup_read_cb, - &sgi->cfg.oap); - - if (!sgi->gsup_client) - return -1; - - return 1; -} - -static int gsup_read_cb(struct gsup_client *gsupc, struct msgb *msg) -{ - int rc; - - rc = gprs_subscr_rx_gsup_message(msg); - msgb_free(msg); - if (rc < 0) - return -1; - - return rc; -} - -int gprs_subscr_purge(struct gprs_subscr *subscr); - -static struct sgsn_subscriber_data *sgsn_subscriber_data_alloc(void *ctx) -{ - struct sgsn_subscriber_data *sdata; - int idx; - - sdata = talloc_zero(ctx, struct sgsn_subscriber_data); - - sdata->error_cause = SGSN_ERROR_CAUSE_NONE; - - for (idx = 0; idx < ARRAY_SIZE(sdata->auth_triplets); idx++) - sdata->auth_triplets[idx].key_seq = GSM_KEY_SEQ_INVAL; - - INIT_LLIST_HEAD(&sdata->pdp_list); - - return sdata; -} - -struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc( - struct sgsn_subscriber_data *sdata) -{ - struct sgsn_subscriber_pdp_data* pdata; - - pdata = talloc_zero(sdata, struct sgsn_subscriber_pdp_data); - - llist_add_tail(&pdata->list, &sdata->pdp_list); - - return pdata; -} - -struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi) -{ - struct gprs_subscr *gsub; - - if (!imsi || !*imsi) - return NULL; - - llist_for_each_entry(gsub, gprs_subscribers, entry) { - if (!strcmp(gsub->imsi, imsi)) - return gprs_subscr_get(gsub); - } - return NULL; -} - -static struct gprs_subscr *gprs_subscr_alloc(void) -{ - struct gprs_subscr *gsub; - gsub = talloc_zero(tall_bsc_ctx, struct gprs_subscr); - if (!gsub) - return NULL; - llist_add_tail(&gsub->entry, gprs_subscribers); - gsub->use_count = 1; - gsub->tmsi = GSM_RESERVED_TMSI; - return gsub; -} - -struct gprs_subscr *gprs_subscr_get_or_create(const char *imsi) -{ - struct gprs_subscr *gsub; - - gsub = gprs_subscr_get_by_imsi(imsi); - if (!gsub) { - gsub = gprs_subscr_alloc(); - if (!gsub) - return NULL; - osmo_strlcpy(gsub->imsi, imsi, sizeof(gsub->imsi)); - } - - if (!gsub->sgsn_data) - gsub->sgsn_data = sgsn_subscriber_data_alloc(gsub); - return gsub; -} - -void gprs_subscr_cleanup(struct gprs_subscr *subscr) -{ - if (subscr->sgsn_data->mm) { - gprs_subscr_put(subscr->sgsn_data->mm->subscr); - subscr->sgsn_data->mm->subscr = NULL; - subscr->sgsn_data->mm = NULL; - } - - if (subscr->flags & GPRS_SUBSCRIBER_ENABLE_PURGE) { - gprs_subscr_purge(subscr); - subscr->flags &= ~GPRS_SUBSCRIBER_ENABLE_PURGE; - } -} - -void gprs_subscr_cancel(struct gprs_subscr *subscr) -{ - subscr->authorized = 0; - subscr->flags |= GPRS_SUBSCRIBER_CANCELLED; - subscr->flags &= ~GPRS_SUBSCRIBER_ENABLE_PURGE; - - gprs_subscr_update(subscr); - gprs_subscr_cleanup(subscr); -} - -static int gprs_subscr_tx_gsup_message(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - struct msgb *msg = gsup_client_msgb_alloc(); - - if (strlen(gsup_msg->imsi) == 0 && subscr) - osmo_strlcpy(gsup_msg->imsi, subscr->imsi, - sizeof(gsup_msg->imsi)); - gsup_msg->cn_domain = OSMO_GSUP_CN_DOMAIN_PS; - osmo_gsup_encode(msg, gsup_msg); - - LOGGSUBSCRP(LOGL_INFO, subscr, - "Sending GSUP, will send: %s\n", msgb_hexdump(msg)); - - if (!sgsn->gsup_client) { - msgb_free(msg); - return -ENOTSUP; - } - - return gsup_client_send(sgsn->gsup_client, msg); -} - -static int gprs_subscr_tx_gsup_error_reply(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_orig, - enum gsm48_gmm_cause cause) -{ - struct osmo_gsup_message gsup_reply = {0}; - - osmo_strlcpy(gsup_reply.imsi, gsup_orig->imsi, - sizeof(gsup_reply.imsi)); - gsup_reply.cause = cause; - gsup_reply.message_type = - OSMO_GSUP_TO_MSGT_ERROR(gsup_orig->message_type); - - return gprs_subscr_tx_gsup_message(subscr, &gsup_reply); -} - -static int gprs_subscr_handle_gsup_auth_res(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - unsigned idx; - struct sgsn_subscriber_data *sdata = subscr->sgsn_data; - - LOGGSUBSCRP(LOGL_INFO, subscr, - "Got SendAuthenticationInfoResult, num_auth_vectors = %zu\n", - gsup_msg->num_auth_vectors); - - if (gsup_msg->num_auth_vectors > 0) { - memset(sdata->auth_triplets, 0, sizeof(sdata->auth_triplets)); - - for (idx = 0; idx < ARRAY_SIZE(sdata->auth_triplets); idx++) - sdata->auth_triplets[idx].key_seq = GSM_KEY_SEQ_INVAL; - } - - for (idx = 0; idx < gsup_msg->num_auth_vectors; idx++) { - size_t key_seq = idx; - LOGGSUBSCRP(LOGL_DEBUG, subscr, - "Adding auth tuple, cksn = %zu\n", key_seq); - if (key_seq >= ARRAY_SIZE(sdata->auth_triplets)) { - LOGGSUBSCRP(LOGL_NOTICE, subscr, - "Skipping auth triplet with invalid cksn %zu\n", - key_seq); - continue; - } - sdata->auth_triplets[key_seq].vec = gsup_msg->auth_vectors[idx]; - sdata->auth_triplets[key_seq].key_seq = key_seq; - } - - sdata->auth_triplets_updated = 1; - sdata->error_cause = SGSN_ERROR_CAUSE_NONE; - - gprs_subscr_update_auth_info(subscr); - - return 0; -} - -static int gprs_subscr_pdp_data_clear(struct gprs_subscr *subscr) -{ - struct sgsn_subscriber_pdp_data *pdp, *pdp2; - int count = 0; - - llist_for_each_entry_safe(pdp, pdp2, &subscr->sgsn_data->pdp_list, list) { - llist_del(&pdp->list); - talloc_free(pdp); - count += 1; - } - - return count; -} - -static struct sgsn_subscriber_pdp_data *gprs_subscr_pdp_data_get_by_id( - struct gprs_subscr *subscr, unsigned context_id) -{ - struct sgsn_subscriber_pdp_data *pdp; - - llist_for_each_entry(pdp, &subscr->sgsn_data->pdp_list, list) { - if (pdp->context_id == context_id) - return pdp; - } - - return NULL; -} - - -static void gprs_subscr_gsup_insert_data(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - struct sgsn_subscriber_data *sdata = subscr->sgsn_data; - unsigned idx; - int rc; - - if (gsup_msg->msisdn_enc) { - if (gsup_msg->msisdn_enc_len > sizeof(sdata->msisdn)) { - LOGP(DGPRS, LOGL_ERROR, "MSISDN too long (%zu)\n", - gsup_msg->msisdn_enc_len); - sdata->msisdn_len = 0; - } else { - memcpy(sdata->msisdn, gsup_msg->msisdn_enc, - gsup_msg->msisdn_enc_len); - sdata->msisdn_len = gsup_msg->msisdn_enc_len; - } - } - - if (gsup_msg->hlr_enc) { - if (gsup_msg->hlr_enc_len > sizeof(sdata->hlr)) { - LOGP(DGPRS, LOGL_ERROR, "HLR-Number too long (%zu)\n", - gsup_msg->hlr_enc_len); - sdata->hlr_len = 0; - } else { - memcpy(sdata->hlr, gsup_msg->hlr_enc, - gsup_msg->hlr_enc_len); - sdata->hlr_len = gsup_msg->hlr_enc_len; - } - } - - if (gsup_msg->pdp_charg_enc && gsup_msg->pdp_charg_enc_len >= sizeof(sdata->pdp_charg)) { - memcpy(&sdata->pdp_charg, gsup_msg->pdp_charg_enc, sizeof(sdata->pdp_charg)); - sdata->has_pdp_charg = 1; - } else { - sdata->has_pdp_charg = 0; - } - - if (gsup_msg->pdp_info_compl) { - rc = gprs_subscr_pdp_data_clear(subscr); - if (rc > 0) - LOGP(DGPRS, LOGL_INFO, "Cleared existing PDP info\n"); - } - - for (idx = 0; idx < gsup_msg->num_pdp_infos; idx++) { - struct osmo_gsup_pdp_info *pdp_info = &gsup_msg->pdp_infos[idx]; - size_t ctx_id = pdp_info->context_id; - struct sgsn_subscriber_pdp_data *pdp_data; - - if (pdp_info->apn_enc_len >= sizeof(pdp_data->apn_str)-1) { - LOGGSUBSCRP(LOGL_ERROR, subscr, - "APN too long, context id = %zu, APN = %s\n", - ctx_id, osmo_hexdump(pdp_info->apn_enc, - pdp_info->apn_enc_len)); - continue; - } - - if (pdp_info->qos_enc_len > sizeof(pdp_data->qos_subscribed)) { - LOGGSUBSCRP(LOGL_ERROR, subscr, - "QoS info too long (%zu)\n", - pdp_info->qos_enc_len); - continue; - } - - LOGGSUBSCRP(LOGL_INFO, subscr, - "Will set PDP info, context id = %zu, APN = %s\n", - ctx_id, osmo_hexdump(pdp_info->apn_enc, pdp_info->apn_enc_len)); - - /* Set PDP info [ctx_id] */ - pdp_data = gprs_subscr_pdp_data_get_by_id(subscr, ctx_id); - if (!pdp_data) { - pdp_data = sgsn_subscriber_pdp_data_alloc(subscr->sgsn_data); - pdp_data->context_id = ctx_id; - } - - OSMO_ASSERT(pdp_data != NULL); - pdp_data->pdp_type = pdp_info->pdp_type; - osmo_apn_to_str(pdp_data->apn_str, - pdp_info->apn_enc, pdp_info->apn_enc_len); - memcpy(pdp_data->qos_subscribed, pdp_info->qos_enc, pdp_info->qos_enc_len); - pdp_data->qos_subscribed_len = pdp_info->qos_enc_len; - - if (pdp_info->pdp_charg_enc && pdp_info->pdp_charg_enc_len >= sizeof(pdp_data->pdp_charg)) { - memcpy(&pdp_data->pdp_charg, pdp_info->pdp_charg_enc, sizeof(pdp_data->pdp_charg)); - pdp_data->has_pdp_charg = 1; - } else { - pdp_data->has_pdp_charg = 0; - } - } -} - -static int gprs_subscr_handle_gsup_upd_loc_res(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - /* contrary to MAP, we allow piggy-backing subscriber data onto - * the UPDATE LOCATION RESULT, and don't mandate the use of a - * separate nested INSERT SUBSCRIBER DATA transaction */ - gprs_subscr_gsup_insert_data(subscr, gsup_msg); - - subscr->authorized = 1; - subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE; - - subscr->flags |= GPRS_SUBSCRIBER_ENABLE_PURGE; - - gprs_subscr_update(subscr); - return 0; -} - -static int gprs_subscr_handle_gsup_dsd_req(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - struct osmo_gsup_message gsup_reply = {0}; - - if (gsup_msg->cn_domain != OSMO_GSUP_CN_DOMAIN_PS) { - LOGGSUBSCRP(LOGL_ERROR, subscr, - "Rx GSUP message %s not supported for CS\n", - osmo_gsup_message_type_name(gsup_msg->message_type)); - gsup_reply.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; - gsup_reply.message_type = OSMO_GSUP_MSGT_DELETE_DATA_ERROR; - } else { - gsm0408_gprs_access_cancelled(subscr->sgsn_data->mm, - GMM_CAUSE_GPRS_NOTALLOWED); - gsup_reply.message_type = OSMO_GSUP_MSGT_DELETE_DATA_RESULT; - } - - return gprs_subscr_tx_gsup_message(subscr, &gsup_reply); -} - -static int gprs_subscr_handle_gsup_isd_req(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - struct osmo_gsup_message gsup_reply = {0}; - - gprs_subscr_gsup_insert_data(subscr, gsup_msg); - - subscr->authorized = 1; - subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE; - subscr->flags |= GPRS_SUBSCRIBER_ENABLE_PURGE; - gprs_subscr_update(subscr); - - gsup_reply.message_type = OSMO_GSUP_MSGT_INSERT_DATA_RESULT; - return gprs_subscr_tx_gsup_message(subscr, &gsup_reply); -} - -static int check_cause(int cause) -{ - switch (cause) { - case GMM_CAUSE_IMSI_UNKNOWN ... GMM_CAUSE_ILLEGAL_ME: - case GMM_CAUSE_GPRS_NOTALLOWED ... GMM_CAUSE_NO_GPRS_PLMN: - return EACCES; - - case GMM_CAUSE_MSC_TEMP_NOTREACH ... GMM_CAUSE_CONGESTION: - return EHOSTUNREACH; - - case GMM_CAUSE_SEM_INCORR_MSG ... GMM_CAUSE_PROTO_ERR_UNSPEC: - default: - return EINVAL; - } -} - -static int gprs_subscr_handle_gsup_auth_err(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - unsigned idx; - struct sgsn_subscriber_data *sdata = subscr->sgsn_data; - int cause_err; - - cause_err = check_cause(gsup_msg->cause); - - LOGGSUBSCRP(LOGL_DEBUG, subscr, - "Send authentication info has failed with cause %d, " - "handled as: %s\n", - gsup_msg->cause, strerror(cause_err)); - - switch (cause_err) { - case EACCES: - LOGGSUBSCRP(LOGL_NOTICE, subscr, - "GPRS send auth info req failed, access denied, " - "GMM cause = '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - /* Clear auth tuples */ - memset(sdata->auth_triplets, 0, sizeof(sdata->auth_triplets)); - for (idx = 0; idx < ARRAY_SIZE(sdata->auth_triplets); idx++) - sdata->auth_triplets[idx].key_seq = GSM_KEY_SEQ_INVAL; - - subscr->authorized = 0; - sdata->error_cause = gsup_msg->cause; - gprs_subscr_update_auth_info(subscr); - break; - - case EHOSTUNREACH: - LOGGSUBSCRP(LOGL_NOTICE, subscr, - "GPRS send auth info req failed, GMM cause = '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - - sdata->error_cause = gsup_msg->cause; - gprs_subscr_update_auth_info(subscr); - break; - - default: - case EINVAL: - LOGGSUBSCRP(LOGL_ERROR, subscr, - "GSUP protocol remote error, GMM cause = '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - break; - } - - return -gsup_msg->cause; -} - -static int gprs_subscr_handle_gsup_upd_loc_err(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - int cause_err; - - cause_err = check_cause(gsup_msg->cause); - - LOGGSUBSCRP(LOGL_DEBUG, subscr, - "Update location has failed with cause %d, handled as: %s\n", - gsup_msg->cause, strerror(cause_err)); - - switch (cause_err) { - case EACCES: - LOGGSUBSCRP(LOGL_NOTICE, subscr, - "GPRS update location failed, access denied, " - "GMM cause = '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - - subscr->authorized = 0; - subscr->sgsn_data->error_cause = gsup_msg->cause; - gprs_subscr_update_auth_info(subscr); - break; - - case EHOSTUNREACH: - LOGGSUBSCRP(LOGL_NOTICE, subscr, - "GPRS update location failed, GMM cause = '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - - subscr->sgsn_data->error_cause = gsup_msg->cause; - gprs_subscr_update_auth_info(subscr); - break; - - default: - case EINVAL: - LOGGSUBSCRP(LOGL_ERROR, subscr, - "GSUP protocol remote error, GMM cause = '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - break; - } - - return -gsup_msg->cause; -} - -static int gprs_subscr_handle_gsup_purge_no_subscr( - struct osmo_gsup_message *gsup_msg) -{ - if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) { - LOGGSUPP(LOGL_NOTICE, gsup_msg, - "Purge MS has failed with cause '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - return -gsup_msg->cause; - } - - LOGGSUPP(LOGL_INFO, gsup_msg, "Completing purge MS\n"); - return 0; -} - -static int gprs_subscr_handle_gsup_purge_res(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - LOGGSUBSCRP(LOGL_INFO, subscr, "Completing purge MS\n"); - - /* Force silent cancellation */ - subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE; - gprs_subscr_cancel(subscr); - - return 0; -} - -static int gprs_subscr_handle_gsup_purge_err(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - LOGGSUBSCRP(LOGL_NOTICE, subscr, - "Purge MS has failed with cause '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - - /* In GSM 09.02, 19.1.4.4, the text and the SDL diagram imply that - * the subscriber data is not removed if the request has failed. On the - * other hand, keeping the subscriber data in either error case - * (subscriber unknown, syntactical message error, connection error) - * doesn't seem to give any advantage, since the data will be restored - * on the next Attach Request anyway. - * This approach ensures, that the subscriber record will not stick if - * an error happens. - */ - - /* TODO: Check whether this behaviour is acceptable and either just - * remove this TODO-notice or change the implementation to not delete - * the subscriber data (eventually resetting the ENABLE_PURGE flag and - * restarting the expiry timer based on the cause). - * - * Subscriber Unknown: cancel subscr - * Temporary network problems: do nothing (handled by timer based retry) - * Message problems (syntax, nyi, ...): cancel subscr (retry won't help) - */ - - gprs_subscr_handle_gsup_purge_res(subscr, gsup_msg); - - return -gsup_msg->cause; -} - -static int gprs_subscr_handle_loc_cancel_req(struct gprs_subscr *subscr, - struct osmo_gsup_message *gsup_msg) -{ - struct osmo_gsup_message gsup_reply = {0}; - int is_update_procedure = !gsup_msg->cancel_type || - gsup_msg->cancel_type == OSMO_GSUP_CANCEL_TYPE_UPDATE; - - LOGGSUBSCRP(LOGL_INFO, subscr, "Cancelling MS subscriber (%s)\n", - is_update_procedure ? - "update procedure" : "subscription withdraw"); - - gsup_reply.message_type = OSMO_GSUP_MSGT_LOCATION_CANCEL_RESULT; - gprs_subscr_tx_gsup_message(subscr, &gsup_reply); - - if (is_update_procedure) - subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE; - else - /* Since a withdraw cause is not specified, just abort the - * current attachment. The following re-attachment should then - * be rejected with a proper cause value. - */ - subscr->sgsn_data->error_cause = GMM_CAUSE_IMPL_DETACHED; - - gprs_subscr_cancel(subscr); - - return 0; -} - -static int gprs_subscr_handle_unknown_imsi(struct osmo_gsup_message *gsup_msg) -{ - if (OSMO_GSUP_IS_MSGT_REQUEST(gsup_msg->message_type)) { - gprs_subscr_tx_gsup_error_reply(NULL, gsup_msg, - GMM_CAUSE_IMSI_UNKNOWN); - LOGP(DGPRS, LOGL_NOTICE, - "Unknown IMSI %s, discarding GSUP request " - "of type 0x%02x\n", - gsup_msg->imsi, gsup_msg->message_type); - } else if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) { - LOGP(DGPRS, LOGL_NOTICE, - "Unknown IMSI %s, discarding GSUP error " - "of type 0x%02x, cause '%s' (%d)\n", - gsup_msg->imsi, gsup_msg->message_type, - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - } else { - LOGP(DGPRS, LOGL_NOTICE, - "Unknown IMSI %s, discarding GSUP response " - "of type 0x%02x\n", - gsup_msg->imsi, gsup_msg->message_type); - } - - return -GMM_CAUSE_IMSI_UNKNOWN; -} - -int gprs_subscr_rx_gsup_message(struct msgb *msg) -{ - uint8_t *data = msgb_l2(msg); - size_t data_len = msgb_l2len(msg); - int rc = 0; - - struct osmo_gsup_message gsup_msg = {0}; - struct gprs_subscr *subscr; - - rc = osmo_gsup_decode(data, data_len, &gsup_msg); - if (rc < 0) { - LOGP(DGPRS, LOGL_ERROR, - "decoding GSUP message fails with error '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, -rc), -rc); - return rc; - } - - if (!gsup_msg.imsi[0]) { - LOGP(DGPRS, LOGL_ERROR, "Missing IMSI in GSUP message\n"); - - if (OSMO_GSUP_IS_MSGT_REQUEST(gsup_msg.message_type)) - gprs_subscr_tx_gsup_error_reply(NULL, &gsup_msg, - GMM_CAUSE_INV_MAND_INFO); - return -GMM_CAUSE_INV_MAND_INFO; - } - - if (!gsup_msg.cause && OSMO_GSUP_IS_MSGT_ERROR(gsup_msg.message_type)) - gsup_msg.cause = GMM_CAUSE_NET_FAIL; - - subscr = gprs_subscr_get_by_imsi(gsup_msg.imsi); - - if (!subscr) { - switch (gsup_msg.message_type) { - case OSMO_GSUP_MSGT_PURGE_MS_RESULT: - case OSMO_GSUP_MSGT_PURGE_MS_ERROR: - return gprs_subscr_handle_gsup_purge_no_subscr(&gsup_msg); - default: - return gprs_subscr_handle_unknown_imsi(&gsup_msg); - } - } - - LOGGSUBSCRP(LOGL_INFO, subscr, - "Received GSUP message %s\n", - osmo_gsup_message_type_name(gsup_msg.message_type)); - - switch (gsup_msg.message_type) { - case OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST: - rc = gprs_subscr_handle_loc_cancel_req(subscr, &gsup_msg); - break; - - case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: - rc = gprs_subscr_handle_gsup_auth_res(subscr, &gsup_msg); - break; - - case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: - rc = gprs_subscr_handle_gsup_auth_err(subscr, &gsup_msg); - break; - - case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: - rc = gprs_subscr_handle_gsup_upd_loc_res(subscr, &gsup_msg); - break; - - case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: - rc = gprs_subscr_handle_gsup_upd_loc_err(subscr, &gsup_msg); - break; - - case OSMO_GSUP_MSGT_PURGE_MS_ERROR: - rc = gprs_subscr_handle_gsup_purge_err(subscr, &gsup_msg); - break; - - case OSMO_GSUP_MSGT_PURGE_MS_RESULT: - rc = gprs_subscr_handle_gsup_purge_res(subscr, &gsup_msg); - break; - - case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: - rc = gprs_subscr_handle_gsup_isd_req(subscr, &gsup_msg); - break; - - case OSMO_GSUP_MSGT_DELETE_DATA_REQUEST: - rc = gprs_subscr_handle_gsup_dsd_req(subscr, &gsup_msg); - break; - - default: - LOGGSUBSCRP(LOGL_ERROR, subscr, - "Rx GSUP message %s not valid at SGSN\n", - osmo_gsup_message_type_name(gsup_msg.message_type)); - if (OSMO_GSUP_IS_MSGT_REQUEST(gsup_msg.message_type)) - gprs_subscr_tx_gsup_error_reply( - subscr, &gsup_msg, GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL); - rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; - break; - }; - - gprs_subscr_put(subscr); - - return rc; -} - -int gprs_subscr_purge(struct gprs_subscr *subscr) -{ - struct sgsn_subscriber_data *sdata = subscr->sgsn_data; - struct osmo_gsup_message gsup_msg = {0}; - - LOGGSUBSCRP(LOGL_INFO, subscr, "purging MS subscriber\n"); - - gsup_msg.message_type = OSMO_GSUP_MSGT_PURGE_MS_REQUEST; - - /* Provide the HLR number in case it is known */ - gsup_msg.hlr_enc_len = sdata->hlr_len; - gsup_msg.hlr_enc = sdata->hlr; - - return gprs_subscr_tx_gsup_message(subscr, &gsup_msg); -} - -static int gprs_subscr_query_auth_info(struct gprs_subscr *subscr, - const uint8_t *auts, - const uint8_t *auts_rand) -{ - struct osmo_gsup_message gsup_msg = {0}; - - /* Make sure we have a complete resync or clearly no resync. */ - OSMO_ASSERT((auts != NULL) == (auts_rand != NULL)); - - LOGGSUBSCRP(LOGL_INFO, subscr, "requesting auth info%s\n", - auts ? " with AUTS (UMTS Resynch)" : ""); - - gsup_msg.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST; - gsup_msg.auts = auts; - gsup_msg.rand = auts_rand; - return gprs_subscr_tx_gsup_message(subscr, &gsup_msg); -} - -int gprs_subscr_location_update(struct gprs_subscr *subscr) -{ - struct osmo_gsup_message gsup_msg = {0}; - - LOGGSUBSCRP(LOGL_INFO, subscr, - "subscriber data is not available\n"); - - gsup_msg.message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST; - return gprs_subscr_tx_gsup_message(subscr, &gsup_msg); -} - -void gprs_subscr_update(struct gprs_subscr *subscr) -{ - LOGGSUBSCRP(LOGL_DEBUG, subscr, "Updating subscriber data\n"); - - subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING; - subscr->flags &= ~GPRS_SUBSCRIBER_FIRST_CONTACT; - - if (subscr->sgsn_data->mm) - sgsn_update_subscriber_data(subscr->sgsn_data->mm); -} - -void gprs_subscr_update_auth_info(struct gprs_subscr *subscr) -{ - LOGGSUBSCRP(LOGL_DEBUG, subscr, - "Updating subscriber authentication info\n"); - - subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING; - subscr->flags &= ~GPRS_SUBSCRIBER_FIRST_CONTACT; - - if (subscr->sgsn_data->mm) - sgsn_update_subscriber_data(subscr->sgsn_data->mm); -} - -struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx(struct sgsn_mm_ctx *mmctx) -{ - struct gprs_subscr *subscr = NULL; - - if (mmctx->subscr) - return gprs_subscr_get(mmctx->subscr); - - if (mmctx->imsi[0]) - subscr = gprs_subscr_get_by_imsi(mmctx->imsi); - - if (!subscr) { - subscr = gprs_subscr_get_or_create(mmctx->imsi); - subscr->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; - subscr->flags &= ~GPRS_SUBSCRIBER_ENABLE_PURGE; - } - - osmo_strlcpy(subscr->imei, mmctx->imei, sizeof(subscr->imei)); - - if (subscr->lac != mmctx->ra.lac) - subscr->lac = mmctx->ra.lac; - - subscr->sgsn_data->mm = mmctx; - mmctx->subscr = gprs_subscr_get(subscr); - - return subscr; -} - -int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) -{ - struct gprs_subscr *subscr = NULL; - int rc; - - LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n"); - - subscr = gprs_subscr_get_or_create_by_mmctx(mmctx); - - subscr->flags |= GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING; - - rc = gprs_subscr_location_update(subscr); - gprs_subscr_put(subscr); - return rc; -} - -/*! \brief Send Update Auth Info request via GSUP, with or without resync. - * \param[in] mmctx MM context to request authentication tuples for. - * \param[in] auts 14 octet AUTS token for UMTS resync, or NULL. - * \param[in] auts_rand 16 octet Random token for UMTS resync, or NULL. - * In case of normal Authentication Info request, both \a auts and \a auts_rand - * must be NULL. For resync, both must be non-NULL. - */ -int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, - const uint8_t *auts, - const uint8_t *auts_rand) -{ - struct gprs_subscr *subscr = NULL; - int rc; - - LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber authentication info\n"); - - subscr = gprs_subscr_get_or_create_by_mmctx(mmctx); - - subscr->flags |= GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING; - - rc = gprs_subscr_query_auth_info(subscr, auts, auts_rand); - gprs_subscr_put(subscr); - return rc; -} - -static void gprs_subscr_free(struct gprs_subscr *gsub) -{ - llist_del(&gsub->entry); - talloc_free(gsub); -} - -struct gprs_subscr *_gprs_subscr_get(struct gprs_subscr *gsub, - const char *file, int line) -{ - OSMO_ASSERT(gsub->use_count < INT_MAX); - gsub->use_count++; - LOGPSRC(DREF, LOGL_DEBUG, file, line, - "subscr %s usage increases to: %d\n", - gsub->imsi, gsub->use_count); - return gsub; -} - -struct gprs_subscr *_gprs_subscr_put(struct gprs_subscr *gsub, - const char *file, int line) -{ - gsub->use_count--; - LOGPSRC(DREF, gsub->use_count >= 0? LOGL_DEBUG : LOGL_ERROR, - file, line, - "subscr %s usage decreases to: %d%s\n", - gsub->imsi, gsub->use_count, - gsub->keep_in_ram? ", keep-in-ram flag is set" : ""); - if (gsub->use_count > 0) - return gsub; - if (gsub->keep_in_ram) - return gsub; - gprs_subscr_free(gsub); - return NULL; -} diff --git a/src/gprs/gprs_utils.c b/src/gprs/gprs_utils.c deleted file mode 100644 index 91a09d2db..000000000 --- a/src/gprs/gprs_utils.c +++ /dev/null @@ -1,246 +0,0 @@ -/* GPRS utility functions */ - -/* (C) 2010 by Harald Welte - * (C) 2010-2014 by On-Waves - * (C) 2013 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ -#include - -#include -#include - -#include -#include -#include - -#include - -/* FIXME: this needs to go to libosmocore/msgb.c */ -struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name) -{ - struct libgb_msgb_cb *old_cb, *new_cb; - struct msgb *new_msg; - - new_msg = msgb_alloc(msg->data_len, name); - if (!new_msg) - return NULL; - - /* copy data */ - memcpy(new_msg->_data, msg->_data, new_msg->data_len); - - /* copy header */ - new_msg->len = msg->len; - new_msg->data += msg->data - msg->_data; - new_msg->head += msg->head - msg->_data; - new_msg->tail += msg->tail - msg->_data; - - if (msg->l1h) - new_msg->l1h = new_msg->_data + (msg->l1h - msg->_data); - if (msg->l2h) - new_msg->l2h = new_msg->_data + (msg->l2h - msg->_data); - if (msg->l3h) - new_msg->l3h = new_msg->_data + (msg->l3h - msg->_data); - if (msg->l4h) - new_msg->l4h = new_msg->_data + (msg->l4h - msg->_data); - - /* copy GB specific data */ - old_cb = LIBGB_MSGB_CB(msg); - new_cb = LIBGB_MSGB_CB(new_msg); - - if (old_cb->bssgph) - new_cb->bssgph = new_msg->_data + (old_cb->bssgph - msg->_data); - if (old_cb->llch) - new_cb->llch = new_msg->_data + (old_cb->llch - msg->_data); - - /* bssgp_cell_id is a pointer into the old msgb, so we need to make - * it a pointer into the new msgb */ - if (old_cb->bssgp_cell_id) - new_cb->bssgp_cell_id = new_msg->_data + - (old_cb->bssgp_cell_id - msg->_data); - new_cb->nsei = old_cb->nsei; - new_cb->bvci = old_cb->bvci; - new_cb->tlli = old_cb->tlli; - - return new_msg; -} - -/* TODO: Move this to libosmocore/msgb.c */ -int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area, - size_t old_size, size_t new_size) -{ - int rc; - uint8_t *rest = area + old_size; - int rest_len = msg->len - old_size - (area - msg->data); - int delta_size = (int)new_size - (int)old_size; - - if (delta_size == 0) - return 0; - - if (delta_size > 0) { - rc = msgb_trim(msg, msg->len + delta_size); - if (rc < 0) - return rc; - } - - memmove(area + new_size, area + old_size, rest_len); - - if (msg->l1h >= rest) - msg->l1h += delta_size; - if (msg->l2h >= rest) - msg->l2h += delta_size; - if (msg->l3h >= rest) - msg->l3h += delta_size; - if (msg->l4h >= rest) - msg->l4h += delta_size; - - if (delta_size < 0) - msgb_trim(msg, msg->len + delta_size); - - return 0; -} - -int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str) -{ - uint8_t *last_len_field; - int len; - - /* Can we even write the length field to the output? */ - if (max_len == 0) - return -1; - - /* Remember where we need to put the length once we know it */ - last_len_field = apn_enc; - len = 1; - apn_enc += 1; - - while (str[0]) { - if (len >= max_len) - return -1; - - if (str[0] == '.') { - *last_len_field = (apn_enc - last_len_field) - 1; - last_len_field = apn_enc; - } else { - *apn_enc = str[0]; - } - apn_enc += 1; - str += 1; - len += 1; - } - - *last_len_field = (apn_enc - last_len_field) - 1; - - return len; -} - -/* GSM 04.08, 10.5.7.3 GPRS Timer */ -int gprs_tmr_to_secs(uint8_t tmr) -{ - switch (tmr & GPRS_TMR_UNIT_MASK) { - case GPRS_TMR_2SECONDS: - return 2 * (tmr & GPRS_TMR_FACT_MASK); - default: - case GPRS_TMR_MINUTE: - return 60 * (tmr & GPRS_TMR_FACT_MASK); - case GPRS_TMR_6MINUTE: - return 360 * (tmr & GPRS_TMR_FACT_MASK); - case GPRS_TMR_DEACTIVATED: - return -1; - } -} - -/* This functions returns a tmr value such that - * - f is monotonic - * - f(s) <= s - * - f(s) == s if a tmr exists with s = gprs_tmr_to_secs(tmr) - * - the best possible resolution is used - * where - * f(s) = gprs_tmr_to_secs(gprs_secs_to_tmr_floor(s)) - */ -uint8_t gprs_secs_to_tmr_floor(int secs) -{ - if (secs < 0) - return GPRS_TMR_DEACTIVATED; - if (secs < 2 * 32) - return GPRS_TMR_2SECONDS | (secs / 2); - if (secs < 60 * 2) - /* Ensure monotonicity */ - return GPRS_TMR_2SECONDS | GPRS_TMR_FACT_MASK; - if (secs < 60 * 32) - return GPRS_TMR_MINUTE | (secs / 60); - if (secs < 360 * 6) - /* Ensure monotonicity */ - return GPRS_TMR_MINUTE | GPRS_TMR_FACT_MASK; - if (secs < 360 * 32) - return GPRS_TMR_6MINUTE | (secs / 360); - - return GPRS_TMR_6MINUTE | GPRS_TMR_FACT_MASK; -} - -/* GSM 04.08, 10.5.1.4 */ -int gprs_is_mi_tmsi(const uint8_t *value, size_t value_len) -{ - if (value_len != GSM48_TMSI_LEN) - return 0; - - if (!value || (value[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_TMSI) - return 0; - - return 1; -} - -/* GSM 04.08, 10.5.1.4 */ -int gprs_is_mi_imsi(const uint8_t *value, size_t value_len) -{ - if (value_len == 0) - return 0; - - if (!value || (value[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_IMSI) - return 0; - - return 1; -} - -int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi) -{ - uint32_t tmsi_be; - - if (!gprs_is_mi_tmsi(value, value_len)) - return 0; - - memcpy(&tmsi_be, value + 1, sizeof(tmsi_be)); - - *tmsi = ntohl(tmsi_be); - return 1; -} - -void gprs_parse_tmsi(const uint8_t *value, uint32_t *tmsi) -{ - uint32_t tmsi_be; - - memcpy(&tmsi_be, value, sizeof(tmsi_be)); - - *tmsi = ntohl(tmsi_be); -} - -int gprs_ra_id_equals(const struct gprs_ra_id *id1, - const struct gprs_ra_id *id2) -{ - return (id1->mcc == id2->mcc && id1->mnc == id2->mnc && - id1->lac == id2->lac && id1->rac == id2->rac); -} diff --git a/src/gprs/gtphub.c b/src/gprs/gtphub.c deleted file mode 100644 index 0a8e375ab..000000000 --- a/src/gprs/gtphub.c +++ /dev/null @@ -1,2937 +0,0 @@ -/* GTP Hub Implementation */ - -/* (C) 2015 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - - -static const int GTPH_GC_TICK_SECONDS = 1; - -void *osmo_gtphub_ctx; - -/* Convenience makro, note: only within this C file. */ -#define LOG(level, fmt, args...) \ - LOGP(DGTPHUB, level, fmt, ##args) - -#define ZERO_STRUCT(struct_pointer) memset(struct_pointer, '\0', \ - sizeof(*(struct_pointer))) - -/* TODO move this to osmocom/core/select.h ? */ -typedef int (*osmo_fd_cb_t)(struct osmo_fd *fd, unsigned int what); - -/* TODO move this to osmocom/core/linuxlist.h ? */ -#define __llist_first(head) (((head)->next == (head)) ? NULL : (head)->next) -#define llist_first(head, type, entry) \ - llist_entry(__llist_first(head), type, entry) - -#define __llist_last(head) (((head)->next == (head)) ? NULL : (head)->prev) -#define llist_last(head, type, entry) \ - llist_entry(__llist_last(head), type, entry) - -/* TODO move GTP header stuff to openggsn/gtp/ ? See gtp_decaps*() */ - -enum gtp_rc { - GTP_RC_UNKNOWN = 0, - GTP_RC_TINY = 1, /* no IEs (like ping/pong) */ - GTP_RC_PDU_C = 2, /* a real packet with IEs */ - GTP_RC_PDU_U = 3, /* a real packet with User data */ - - GTP_RC_TOOSHORT = -1, - GTP_RC_UNSUPPORTED_VERSION = -2, - GTP_RC_INVALID_IE = -3, -}; - -struct gtp_packet_desc { - union gtp_packet *data; - int data_len; - int header_len; - int version; - uint8_t type; - uint16_t seq; - uint32_t header_tei_rx; - uint32_t header_tei; - int rc; /* enum gtp_rc */ - unsigned int plane_idx; - unsigned int side_idx; - struct gtphub_tunnel *tun; - time_t timestamp; - union gtpie_member *ie[GTPIE_SIZE]; -}; - -struct pending_delete { - struct llist_head entry; - struct expiring_item expiry_entry; - - struct gtphub_tunnel *tun; - uint8_t teardown_ind; - uint8_t nsapi; -}; - - -/* counters */ - -enum gtphub_counters_io { - GTPH_CTR_PKTS_IN = 0, - GTPH_CTR_PKTS_OUT, - GTPH_CTR_BYTES_IN, - GTPH_CTR_BYTES_OUT -}; - -static const struct rate_ctr_desc gtphub_counters_io_desc[] = { - { "packets.in", "Packets ( In)" }, - { "packets.out", "Packets (Out)" }, - { "bytes.in", "Bytes ( In)" }, - { "bytes.out", "Bytes (Out)" }, -}; - -static const struct rate_ctr_group_desc gtphub_ctrg_io_desc = { - .group_name_prefix = "gtphub.bind", - .group_description = "I/O Statistics", - .num_ctr = ARRAY_SIZE(gtphub_counters_io_desc), - .ctr_desc = gtphub_counters_io_desc, - .class_id = OSMO_STATS_CLASS_GLOBAL, -}; - - -/* support */ - -static const char *gtp_type_str(uint8_t type) -{ - switch (type) { - case 1: - return " (Echo Request)"; - case 2: - return " (Echo Response)"; - case 16: - return " (Create PDP Ctx Request)"; - case 17: - return " (Create PDP Ctx Response)"; - case 18: - return " (Update PDP Ctx Request)"; - case 19: - return " (Update PDP Ctx Response)"; - case 20: - return " (Delete PDP Ctx Request)"; - case 21: - return " (Delete PDP Ctx Response)"; - case 255: - return " (User Data)"; - default: - return ""; - } -} - -void gsn_addr_copy(struct gsn_addr *gsna, const struct gsn_addr *src) -{ - *gsna = *src; -} - -int gsn_addr_from_sockaddr(struct gsn_addr *gsna, uint16_t *port, - const struct osmo_sockaddr *sa) -{ - char addr_str[256]; - char port_str[6]; - - if (osmo_sockaddr_to_strs(addr_str, sizeof(addr_str), - port_str, sizeof(port_str), - sa, (NI_NUMERICHOST | NI_NUMERICSERV)) - != 0) { - return -1; - } - - if (port) - *port = atoi(port_str); - - return gsn_addr_from_str(gsna, addr_str); -} - -int gsn_addr_from_str(struct gsn_addr *gsna, const char *numeric_addr_str) -{ - if ((!gsna) || (!numeric_addr_str)) - return -1; - - int af = AF_INET; - gsna->len = 4; - const char *pos = numeric_addr_str; - for (; *pos; pos++) { - if (*pos == ':') { - af = AF_INET6; - gsna->len = 16; - break; - } - } - - int rc = inet_pton(af, numeric_addr_str, gsna->buf); - if (rc != 1) { - LOG(LOGL_ERROR, "Cannot resolve numeric address: '%s'\n", - numeric_addr_str); - return -1; - } - return 0; -} - -const char *gsn_addr_to_str(const struct gsn_addr *gsna) -{ - static char buf[INET6_ADDRSTRLEN + 1]; - return gsn_addr_to_strb(gsna, buf, sizeof(buf)); -} - -const char *gsn_addr_to_strb(const struct gsn_addr *gsna, - char *strbuf, - int strbuf_len) -{ - int af; - switch (gsna->len) { - case 4: - af = AF_INET; - break; - case 16: - af = AF_INET6; - break; - default: - return NULL; - } - - const char *r = inet_ntop(af, gsna->buf, strbuf, strbuf_len); - if (!r) { - LOG(LOGL_ERROR, "Cannot convert gsn_addr to string:" - " %s: len=%d, buf=%s\n", - strerror(errno), - (int)gsna->len, - osmo_hexdump(gsna->buf, sizeof(gsna->buf))); - } - return r; -} - -int gsn_addr_same(const struct gsn_addr *a, const struct gsn_addr *b) -{ - if (a == b) - return 1; - if ((!a) || (!b)) - return 0; - if (a->len != b->len) - return 0; - return (memcmp(a->buf, b->buf, a->len) == 0)? 1 : 0; -} - -static int gsn_addr_get(struct gsn_addr *gsna, const struct gtp_packet_desc *p, - int idx) -{ - if (p->rc != GTP_RC_PDU_C) - return -1; - - unsigned int len; - /* gtpie.h fails to declare gtpie_gettlv()'s first arg as const. */ - if (gtpie_gettlv((union gtpie_member**)p->ie, GTPIE_GSN_ADDR, idx, - &len, gsna->buf, sizeof(gsna->buf)) - != 0) - return -1; - gsna->len = len; - return 0; -} - -static int gsn_addr_put(const struct gsn_addr *gsna, struct gtp_packet_desc *p, - int idx) -{ - if (p->rc != GTP_RC_PDU_C) - return -1; - - int ie_idx; - ie_idx = gtpie_getie(p->ie, GTPIE_GSN_ADDR, idx); - - if (ie_idx < 0) - return -1; - - struct gtpie_tlv *ie = &p->ie[ie_idx]->tlv; - int ie_l = ntoh16(ie->l); - if (ie_l != gsna->len) { - LOG(LOGL_ERROR, "Not implemented:" - " replace an IE address of different size:" - " replace %d with %d\n", (int)ie_l, (int)gsna->len); - return -1; - } - - memcpy(ie->v, gsna->buf, (int)ie_l); - return 0; -} - -/* Validate GTP version 0 data; analogous to validate_gtp1_header(), see there. - */ -void validate_gtp0_header(struct gtp_packet_desc *p) -{ - const struct gtp0_header *pheader = &(p->data->gtp0.h); - p->rc = GTP_RC_UNKNOWN; - p->header_len = 0; - - OSMO_ASSERT(p->data_len >= 1); - OSMO_ASSERT(p->version == 0); - - if (p->data_len < GTP0_HEADER_SIZE) { - LOG(LOGL_ERROR, "GTP0 packet too short: %d\n", p->data_len); - p->rc = GTP_RC_TOOSHORT; - return; - } - - p->type = ntoh8(pheader->type); - p->seq = ntoh16(pheader->seq); - p->header_tei_rx = 0; /* TODO */ - p->header_tei = p->header_tei_rx; - - if (p->data_len == GTP0_HEADER_SIZE) { - p->rc = GTP_RC_TINY; - p->header_len = GTP0_HEADER_SIZE; - return; - } - - /* Check packet length field versus length of packet */ - if (p->data_len != (ntoh16(pheader->length) + GTP0_HEADER_SIZE)) { - LOG(LOGL_ERROR, "GTP packet length field (%d + %d) does not" - " match actual length (%d)\n", - GTP0_HEADER_SIZE, (int)ntoh16(pheader->length), - p->data_len); - p->rc = GTP_RC_TOOSHORT; - return; - } - - LOG(LOGL_DEBUG, "GTP v0 TID = %" PRIu64 "\n", pheader->tid); - p->header_len = GTP0_HEADER_SIZE; - p->rc = GTP_RC_PDU_C; -} - -/* Validate GTP version 1 data, and update p->rc with the result, as well as - * p->header_len in case of a valid header. */ -void validate_gtp1_header(struct gtp_packet_desc *p) -{ - const struct gtp1_header_long *pheader = &(p->data->gtp1l.h); - p->rc = GTP_RC_UNKNOWN; - p->header_len = 0; - - OSMO_ASSERT(p->data_len >= 1); - OSMO_ASSERT(p->version == 1); - - if ((p->data_len < GTP1_HEADER_SIZE_LONG) - && (p->data_len != GTP1_HEADER_SIZE_SHORT)){ - LOG(LOGL_ERROR, "GTP packet too short: %d\n", p->data_len); - p->rc = GTP_RC_TOOSHORT; - return; - } - - p->type = ntoh8(pheader->type); - p->header_tei_rx = ntoh32(pheader->tei); - p->header_tei = p->header_tei_rx; - p->seq = ntoh16(pheader->seq); - - LOG(LOGL_DEBUG, "| GTPv1\n"); - LOG(LOGL_DEBUG, "| type = %" PRIu8 " 0x%02" PRIx8 "\n", p->type, p->type); - LOG(LOGL_DEBUG, "| length = %" PRIu16 " 0x%04" PRIx16 "\n", ntoh16(pheader->length), ntoh16(pheader->length)); - LOG(LOGL_DEBUG, "| TEI = %" PRIu32 " 0x%08" PRIx32 "\n", p->header_tei_rx, p->header_tei_rx); - LOG(LOGL_DEBUG, "| seq = %" PRIu16 " 0x%04" PRIx16 "\n", p->seq, p->seq); - LOG(LOGL_DEBUG, "| npdu = %" PRIu8 " 0x%02" PRIx8 "\n", pheader->npdu, pheader->npdu); - LOG(LOGL_DEBUG, "| next = %" PRIu8 " 0x%02" PRIx8 "\n", pheader->next, pheader->next); - - if (p->data_len <= GTP1_HEADER_SIZE_LONG) { - p->rc = GTP_RC_TINY; - p->header_len = GTP1_HEADER_SIZE_SHORT; - return; - } - - /* Check packet length field versus length of packet */ - int announced_len = ntoh16(pheader->length) + GTP1_HEADER_SIZE_SHORT; - if (p->data_len != announced_len) { - LOG(LOGL_ERROR, "GTP packet length field (%d + %d) does not" - " match actual length (%d)\n", - GTP1_HEADER_SIZE_SHORT, (int)ntoh16(pheader->length), - p->data_len); - p->rc = GTP_RC_TOOSHORT; - return; - } - - p->rc = GTP_RC_PDU_C; - p->header_len = GTP1_HEADER_SIZE_LONG; -} - -/* Examine whether p->data of size p->data_len has a valid GTP header. Set - * p->version, p->rc and p->header_len. On error, p->rc <= 0 (see enum - * gtp_rc). p->data must point at a buffer with p->data_len set. */ -void validate_gtp_header(struct gtp_packet_desc *p) -{ - p->rc = GTP_RC_UNKNOWN; - - /* Need at least 1 byte in order to check version */ - if (p->data_len < 1) { - LOG(LOGL_ERROR, "Discarding packet - too small: %d\n", - p->data_len); - p->rc = GTP_RC_TOOSHORT; - return; - } - - p->version = p->data->flags >> 5; - - switch (p->version) { - case 0: - validate_gtp0_header(p); - break; - case 1: - validate_gtp1_header(p); - break; - default: - LOG(LOGL_ERROR, "Unsupported GTP version: %d\n", p->version); - p->rc = GTP_RC_UNSUPPORTED_VERSION; - break; - } -} - - -/* Return the value of the i'th IMSI IEI by copying to *imsi. - * The first IEI is reached by passing i = 0. - * imsi must point at allocated space of (at least) 8 bytes. - * Return 1 on success, or 0 if not found. */ -static int get_ie_imsi(union gtpie_member *ie[], int i, uint8_t *imsi) -{ - return gtpie_gettv0(ie, GTPIE_IMSI, i, imsi, 8) == 0; -} - -/* Analogous to get_ie_imsi(). nsapi must point at a single uint8_t. */ -static int get_ie_nsapi(union gtpie_member *ie[], int i, uint8_t *nsapi) -{ - return gtpie_gettv1(ie, GTPIE_NSAPI, i, nsapi) == 0; -} - -static char imsi_digit_to_char(uint8_t nibble) -{ - nibble &= 0x0f; - if (nibble > 9) - return (nibble == 0x0f) ? '\0' : '?'; - return '0' + nibble; -} - -/* Return a human readable IMSI string, in a static buffer. - * imsi must point at 8 octets of IMSI IE encoded IMSI data. */ -static int imsi_to_str(uint8_t *imsi, const char **imsi_str) -{ - static char str[17]; - int i; - - for (i = 0; i < 8; i++) { - char c; - c = imsi_digit_to_char(imsi[i]); - if (c == '?') - return -1; - str[2*i] = c; - - c = imsi_digit_to_char(imsi[i] >> 4); - if (c == '?') - return -1; - str[2*i + 1] = c; - } - str[16] = '\0'; - *imsi_str = str; - return 1; -} - -/* Return 0 if not present, 1 if present and decoded successfully, -1 if - * present but cannot be decoded. */ -static int get_ie_imsi_str(union gtpie_member *ie[], int i, - const char **imsi_str) -{ - uint8_t imsi_buf[8]; - if (!get_ie_imsi(ie, i, imsi_buf)) - return 0; - return imsi_to_str(imsi_buf, imsi_str); -} - -/* Return 0 if not present, 1 if present and decoded successfully, -1 if - * present but cannot be decoded. */ -static int get_ie_apn_str(union gtpie_member *ie[], const char **apn_str) -{ - static char apn_buf[GSM_APN_LENGTH]; - unsigned int len; - if (gtpie_gettlv(ie, GTPIE_APN, 0, - &len, apn_buf, sizeof(apn_buf)) != 0) - return 0; - - if (len < 2) { - LOG(LOGL_ERROR, "APN IE: invalid length: %d\n", - (int)len); - return -1; - } - - if (len > (sizeof(apn_buf) - 1)) - len = sizeof(apn_buf) - 1; - apn_buf[len] = '\0'; - - *apn_str = osmo_apn_to_str(apn_buf, (uint8_t*)apn_buf, len); - if (!(*apn_str)) { - LOG(LOGL_ERROR, "APN IE: present but cannot be decoded: %s\n", - osmo_hexdump((uint8_t*)apn_buf, len)); - return -1; - } - return 1; -} - - -/* Validate header, and index information elements. Write decoded packet - * information to *res. res->data will point at the given data buffer. On - * error, p->rc is set <= 0 (see enum gtp_rc). */ -static void gtp_decode(const uint8_t *data, int data_len, - unsigned int from_side_idx, - unsigned int from_plane_idx, - struct gtp_packet_desc *res, - time_t now) -{ - ZERO_STRUCT(res); - res->data = (union gtp_packet*)data; - res->data_len = data_len; - res->side_idx = from_side_idx; - res->plane_idx = from_plane_idx; - res->timestamp = now; - - validate_gtp_header(res); - - if (res->rc <= 0) - return; - - LOG(LOGL_DEBUG, "Valid GTP header (v%d)\n", res->version); - - if (from_plane_idx == GTPH_PLANE_USER) { - res->rc = GTP_RC_PDU_U; - return; - } - - if (res->rc != GTP_RC_PDU_C) { - LOG(LOGL_DEBUG, "no IEs in this GTP packet\n"); - return; - } - - if (gtpie_decaps(res->ie, res->version, - (void*)(data + res->header_len), - res->data_len - res->header_len) != 0) { - res->rc = GTP_RC_INVALID_IE; - LOG(LOGL_ERROR, "INVALID: cannot decode IEs." - " Dropping GTP packet%s.\n", - gtp_type_str(res->type) - ); - return; - } - -#if 1 - /* TODO if () - (waiting for a commit from jerlbeck) */ - int i; - - for (i = 0; i < 10; i++) { - const char *imsi; - if (get_ie_imsi_str(res->ie, i, &imsi) < 1) - break; - LOG(LOGL_DEBUG, "| IMSI %s\n", imsi); - } - - for (i = 0; i < 10; i++) { - uint8_t nsapi; - if (!get_ie_nsapi(res->ie, i, &nsapi)) - break; - LOG(LOGL_DEBUG, "| NSAPI %d\n", (int)nsapi); - } - - for (i = 0; i < 2; i++) { - struct gsn_addr addr; - if (gsn_addr_get(&addr, res, i) == 0) - LOG(LOGL_DEBUG, "| addr %s\n", gsn_addr_to_str(&addr)); - } - - for (i = 0; i < 10; i++) { - uint32_t tei; - if (gtpie_gettv4(res->ie, GTPIE_TEI_DI, i, &tei) != 0) - break; - LOG(LOGL_DEBUG, "| TEI DI (USER) %" PRIu32 " 0x%08" PRIx32 "\n", - tei, tei); - } - - for (i = 0; i < 10; i++) { - uint32_t tei; - if (gtpie_gettv4(res->ie, GTPIE_TEI_C, i, &tei) != 0) - break; - LOG(LOGL_DEBUG, "| TEI (CTRL) %" PRIu32 " 0x%08" PRIx32 "\n", - tei, tei); - } -#endif -} - - -/* expiry */ - -void expiry_init(struct expiry *exq, int expiry_in_seconds) -{ - ZERO_STRUCT(exq); - exq->expiry_in_seconds = expiry_in_seconds; - INIT_LLIST_HEAD(&exq->items); -} - -void expiry_add(struct expiry *exq, struct expiring_item *item, time_t now) -{ - item->expiry = now + exq->expiry_in_seconds; - - OSMO_ASSERT(llist_empty(&exq->items) - || (item->expiry - >= llist_last(&exq->items, struct expiring_item, entry)->expiry)); - - /* Add/move to the tail to always sort by expiry, ascending. */ - llist_del(&item->entry); - llist_add_tail(&item->entry, &exq->items); -} - -int expiry_tick(struct expiry *exq, time_t now) -{ - int expired = 0; - struct expiring_item *m, *n; - llist_for_each_entry_safe(m, n, &exq->items, entry) { - if (m->expiry <= now) { - expiring_item_del(m); - expired ++; - } else { - /* The items are added sorted by expiry. So when we hit - * an unexpired entry, only more unexpired ones will - * follow. */ - break; - } - } - return expired; -} - -void expiry_clear(struct expiry *exq) -{ - struct expiring_item *m, *n; - llist_for_each_entry_safe(m, n, &exq->items, entry) { - expiring_item_del(m); - } -} - -void expiring_item_init(struct expiring_item *item) -{ - ZERO_STRUCT(item); - INIT_LLIST_HEAD(&item->entry); -} - -void expiring_item_del(struct expiring_item *item) -{ - OSMO_ASSERT(item); - llist_del(&item->entry); - INIT_LLIST_HEAD(&item->entry); - if (item->del_cb) { - /* avoid loops */ - del_cb_t del_cb = item->del_cb; - item->del_cb = 0; - (del_cb)(item); - } -} - - -/* nr_map, nr_pool */ - -void nr_pool_init(struct nr_pool *pool, nr_t nr_min, nr_t nr_max) -{ - *pool = (struct nr_pool){ - .nr_min = nr_min, - .nr_max = nr_max, - .last_nr = nr_max - }; -} - -nr_t nr_pool_next(struct nr_pool *pool) -{ - if (pool->last_nr >= pool->nr_max) - pool->last_nr = pool->nr_min; - else - pool->last_nr ++; - - return pool->last_nr; -} - -void nr_map_init(struct nr_map *map, struct nr_pool *pool, - struct expiry *exq) -{ - ZERO_STRUCT(map); - map->pool = pool; - map->add_items_to_expiry = exq; - INIT_LLIST_HEAD(&map->mappings); -} - -void nr_mapping_init(struct nr_mapping *m) -{ - ZERO_STRUCT(m); - INIT_LLIST_HEAD(&m->entry); - expiring_item_init(&m->expiry_entry); -} - -void nr_map_add(struct nr_map *map, struct nr_mapping *mapping, time_t now) -{ - /* Generate a mapped number */ - mapping->repl = nr_pool_next(map->pool); - - /* Add to the tail to always yield a list sorted by expiry, in - * ascending order. */ - llist_add_tail(&mapping->entry, &map->mappings); - nr_map_refresh(map, mapping, now); -} - -void nr_map_refresh(struct nr_map *map, struct nr_mapping *mapping, time_t now) -{ - if (!map->add_items_to_expiry) - return; - expiry_add(map->add_items_to_expiry, - &mapping->expiry_entry, - now); -} - -void nr_map_clear(struct nr_map *map) -{ - struct nr_mapping *m; - struct nr_mapping *n; - llist_for_each_entry_safe(m, n, &map->mappings, entry) { - nr_mapping_del(m); - } -} - -int nr_map_empty(const struct nr_map *map) -{ - return llist_empty(&map->mappings); -} - -struct nr_mapping *nr_map_get(const struct nr_map *map, - void *origin, nr_t nr_orig) -{ - struct nr_mapping *mapping; - llist_for_each_entry(mapping, &map->mappings, entry) { - if ((mapping->origin == origin) - && (mapping->orig == nr_orig)) - return mapping; - } - /* Not found. */ - return NULL; -} - -struct nr_mapping *nr_map_get_inv(const struct nr_map *map, nr_t nr_repl) -{ - struct nr_mapping *mapping; - llist_for_each_entry(mapping, &map->mappings, entry) { - if (mapping->repl == nr_repl) { - return mapping; - } - } - /* Not found. */ - return NULL; -} - -void nr_mapping_del(struct nr_mapping *mapping) -{ - OSMO_ASSERT(mapping); - llist_del(&mapping->entry); - INIT_LLIST_HEAD(&mapping->entry); - expiring_item_del(&mapping->expiry_entry); -} - - -/* gtphub */ - -const char* const gtphub_plane_idx_names[GTPH_PLANE_N] = { - "CTRL", - "USER", -}; - -const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N] = { - 2123, - 2152, -}; - -const char* const gtphub_side_idx_names[GTPH_SIDE_N] = { - "SGSN", - "GGSN", -}; - -time_t gtphub_now(void) -{ - struct timespec now_tp; - OSMO_ASSERT(clock_gettime(CLOCK_MONOTONIC, &now_tp) >= 0); - return now_tp.tv_sec; -} - -/* Remove a gtphub_peer from its list and free it. */ -static void gtphub_peer_del(struct gtphub_peer *peer) -{ - OSMO_ASSERT(llist_empty(&peer->addresses)); - nr_map_clear(&peer->seq_map); - llist_del(&peer->entry); - talloc_free(peer); -} - -static void gtphub_peer_addr_del(struct gtphub_peer_addr *pa) -{ - OSMO_ASSERT(llist_empty(&pa->ports)); - llist_del(&pa->entry); - talloc_free(pa); -} - -static void gtphub_peer_port_del(struct gtphub_peer_port *pp) -{ - OSMO_ASSERT(pp->ref_count == 0); - llist_del(&pp->entry); - rate_ctr_group_free(pp->counters_io); - talloc_free(pp); -} - -/* From the information in the gtp_packet_desc, return the address of a GGSN. - * Return -1 on error. */ -static int gtphub_resolve_ggsn(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port **pp); - -/* See gtphub_ext.c (wrapped by unit test) */ -struct gtphub_peer_port *gtphub_resolve_ggsn_addr(struct gtphub *hub, - const char *imsi_str, - const char *apn_ni_str); -int gtphub_ares_init(struct gtphub *hub); - -static void gtphub_zero(struct gtphub *hub) -{ - ZERO_STRUCT(hub); - INIT_LLIST_HEAD(&hub->ggsn_lookups); - INIT_LLIST_HEAD(&hub->resolved_ggsns); -} - -static int gtphub_sock_init(struct osmo_fd *ofd, - const struct gtphub_cfg_addr *addr, - osmo_fd_cb_t cb, - void *data, - int ofd_id) -{ - if (!addr->addr_str) { - LOG(LOGL_FATAL, "Cannot bind: empty address.\n"); - return -1; - } - if (!addr->port) { - LOG(LOGL_FATAL, "Cannot bind: zero port not permitted.\n"); - return -1; - } - - ofd->when = BSC_FD_READ; - ofd->cb = cb; - ofd->data = data; - ofd->priv_nr = ofd_id; - - int rc; - rc = osmo_sock_init_ofd(ofd, - AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, - addr->addr_str, addr->port, - OSMO_SOCK_F_BIND); - if (rc < 1) { - LOG(LOGL_FATAL, "Cannot bind to %s port %d (rc %d)\n", - addr->addr_str, (int)addr->port, rc); - return -1; - } - - return 0; -} - -static void gtphub_sock_close(struct osmo_fd *ofd) -{ - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->cb = NULL; -} - -static void gtphub_bind_init(struct gtphub_bind *b) -{ - ZERO_STRUCT(b); - - INIT_LLIST_HEAD(&b->peers); - - b->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx, - >phub_ctrg_io_desc, 0); - OSMO_ASSERT(b->counters_io); -} - -static int gtphub_bind_start(struct gtphub_bind *b, - const struct gtphub_cfg_bind *cfg, - osmo_fd_cb_t cb, void *cb_data, - unsigned int ofd_id) -{ - LOG(LOGL_DEBUG, "Starting bind %s\n", b->label); - if (gsn_addr_from_str(&b->local_addr, cfg->bind.addr_str) != 0) { - LOG(LOGL_FATAL, "Invalid bind address for %s: %s\n", - b->label, cfg->bind.addr_str); - return -1; - } - if (gtphub_sock_init(&b->ofd, &cfg->bind, cb, cb_data, ofd_id) != 0) { - LOG(LOGL_FATAL, "Cannot bind for %s: %s\n", - b->label, cfg->bind.addr_str); - return -1; - } - b->local_port = cfg->bind.port; - return 0; -} - -static void gtphub_bind_free(struct gtphub_bind *b) -{ - OSMO_ASSERT(llist_empty(&b->peers)); - rate_ctr_group_free(b->counters_io); -} - -static void gtphub_bind_stop(struct gtphub_bind *b) { - gtphub_sock_close(&b->ofd); - gtphub_bind_free(b); -} - -/* Recv datagram from from->fd, write sender's address to *from_addr. - * Return the number of bytes read, zero on error. */ -static int gtphub_read(const struct osmo_fd *from, - struct osmo_sockaddr *from_addr, - uint8_t *buf, size_t buf_len) -{ - OSMO_ASSERT(from_addr); - - /* recvfrom requires the available length set in *from_addr_len. */ - from_addr->l = sizeof(from_addr->a); - errno = 0; - ssize_t received = recvfrom(from->fd, buf, buf_len, 0, - (struct sockaddr*)&from_addr->a, - &from_addr->l); - /* TODO use recvmsg and get a MSG_TRUNC flag to make sure the message - * is not truncated. Then maybe reduce buf's size. */ - - if (received <= 0) { - LOG((errno == EAGAIN? LOGL_DEBUG : LOGL_ERROR), - "error: %s\n", strerror(errno)); - return 0; - } - - LOG(LOGL_DEBUG, "Received %d bytes from %s: %s%s\n", - (int)received, osmo_sockaddr_to_str(from_addr), - osmo_hexdump(buf, received > 1000? 1000 : received), - received > 1000 ? "..." : ""); - - return received; -} - -static inline void gtphub_port_ref_count_inc(struct gtphub_peer_port *pp) -{ - OSMO_ASSERT(pp); - OSMO_ASSERT(pp->ref_count < UINT_MAX); - pp->ref_count++; -} - -static inline void gtphub_port_ref_count_dec(struct gtphub_peer_port *pp) -{ - OSMO_ASSERT(pp); - OSMO_ASSERT(pp->ref_count > 0); - pp->ref_count--; -} - -static inline void set_seq(struct gtp_packet_desc *p, uint16_t seq) -{ - OSMO_ASSERT(p->version == 1); - p->data->gtp1l.h.seq = hton16(seq); - p->seq = seq; -} - -static inline void set_tei(struct gtp_packet_desc *p, uint32_t tei) -{ - OSMO_ASSERT(p->version == 1); - p->data->gtp1l.h.tei = hton32(tei); - p->header_tei = tei; -} - -static void gtphub_mapping_del_cb(struct expiring_item *expi); - -static struct nr_mapping *gtphub_mapping_new() -{ - struct nr_mapping *nrm; - nrm = talloc_zero(osmo_gtphub_ctx, struct nr_mapping); - OSMO_ASSERT(nrm); - - nr_mapping_init(nrm); - nrm->expiry_entry.del_cb = gtphub_mapping_del_cb; - return nrm; -} - - -#define APPEND(args...) \ - l = snprintf(pos, left, args); \ - pos += l; \ - left -= l - -static const char *gtphub_tunnel_side_str(struct gtphub_tunnel *tun, - int side_idx) -{ - static char buf[256]; - char *pos = buf; - int left = sizeof(buf); - int l; - - struct gtphub_tunnel_endpoint *c, *u; - c = &tun->endpoint[side_idx][GTPH_PLANE_CTRL]; - u = &tun->endpoint[side_idx][GTPH_PLANE_USER]; - - /* print both only if they differ. */ - if (!c->peer) { - APPEND("(uninitialized)"); - } else { - APPEND("%s", gsn_addr_to_str(&c->peer->peer_addr->addr)); - } - - if (!u->peer) { - if (c->peer) { - APPEND("/(uninitialized)"); - } - } else if ((!c->peer) - || (!gsn_addr_same(&u->peer->peer_addr->addr, - &c->peer->peer_addr->addr))) { - APPEND("/%s", gsn_addr_to_str(&u->peer->peer_addr->addr)); - } - - APPEND(" (TEI C=%x U=%x)", - c->tei_orig, - u->tei_orig); - return buf; -} - -const char *gtphub_tunnel_str(struct gtphub_tunnel *tun) -{ - static char buf[512]; - char *pos = buf; - int left = sizeof(buf); - int l; - - if (!tun) - return "null-tunnel"; - - APPEND("TEI=%x: ", tun->tei_repl); - APPEND("%s", gtphub_tunnel_side_str(tun, GTPH_SIDE_SGSN)); - APPEND(" <-> %s", gtphub_tunnel_side_str(tun, GTPH_SIDE_GGSN)); - - return buf; -} - -#undef APPEND - -void gtphub_tunnel_endpoint_set_peer(struct gtphub_tunnel_endpoint *te, - struct gtphub_peer_port *pp) -{ - if (te->peer) - gtphub_port_ref_count_dec(te->peer); - te->peer = pp; - if (te->peer) - gtphub_port_ref_count_inc(te->peer); -} - -int gtphub_tunnel_complete(struct gtphub_tunnel *tun) -{ - if (!tun) - return 0; - if (!tun->tei_repl) - return 0; - int side_idx; - int plane_idx; - for_each_side_and_plane(side_idx, plane_idx) { - struct gtphub_tunnel_endpoint *te = - &tun->endpoint[side_idx][plane_idx]; - if (!(te->peer && te->tei_orig)) - return 0; - } - return 1; -} - -static void gtphub_tunnel_del_cb(struct expiring_item *expi) -{ - struct gtphub_tunnel *tun = container_of(expi, - struct gtphub_tunnel, - expiry_entry); - LOG(LOGL_DEBUG, "expired: %s\n", gtphub_tunnel_str(tun)); - - llist_del(&tun->entry); - INIT_LLIST_HEAD(&tun->entry); /* mark unused */ - - expi->del_cb = 0; /* avoid recursion loops */ - expiring_item_del(&tun->expiry_entry); /* usually already done, but make sure. */ - - int side_idx; - int plane_idx; - for_each_side_and_plane(side_idx, plane_idx) { - struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][plane_idx]; - - /* clear ref count */ - gtphub_tunnel_endpoint_set_peer(te, NULL); - - rate_ctr_group_free(te->counters_io); - } - - talloc_free(tun); -} - -static struct gtphub_tunnel *gtphub_tunnel_new() -{ - struct gtphub_tunnel *tun; - tun = talloc_zero(osmo_gtphub_ctx, struct gtphub_tunnel); - OSMO_ASSERT(tun); - - INIT_LLIST_HEAD(&tun->entry); - expiring_item_init(&tun->expiry_entry); - - int side_idx, plane_idx; - for_each_side_and_plane(side_idx, plane_idx) { - struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][plane_idx]; - te->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx, - >phub_ctrg_io_desc, - 0); - OSMO_ASSERT(te->counters_io); - } - - tun->expiry_entry.del_cb = gtphub_tunnel_del_cb; - return tun; -} - -static const char *gtphub_peer_strb(struct gtphub_peer *peer, char *buf, - int buflen) -{ - if (llist_empty(&peer->addresses)) - return "(addressless)"; - - struct gtphub_peer_addr *a = llist_first(&peer->addresses, - struct gtphub_peer_addr, - entry); - return gsn_addr_to_strb(&a->addr, buf, buflen); -} - -static const char *gtphub_port_strb(struct gtphub_peer_port *port, char *buf, - int buflen) -{ - if (!port) - return "(null port)"; - - snprintf(buf, buflen, "%s port %d", - gsn_addr_to_str(&port->peer_addr->addr), - (int)port->port); - return buf; -} - -const char *gtphub_peer_str(struct gtphub_peer *peer) -{ - static char buf[256]; - return gtphub_peer_strb(peer, buf, sizeof(buf)); -} - -const char *gtphub_port_str(struct gtphub_peer_port *port) -{ - static char buf[256]; - return gtphub_port_strb(port, buf, sizeof(buf)); -} - -static const char *gtphub_port_str2(struct gtphub_peer_port *port) -{ - static char buf[256]; - return gtphub_port_strb(port, buf, sizeof(buf)); -} - -static void gtphub_mapping_del_cb(struct expiring_item *expi) -{ - expi->del_cb = 0; /* avoid recursion loops */ - expiring_item_del(expi); /* usually already done, but make sure. */ - - struct nr_mapping *nrm = container_of(expi, - struct nr_mapping, - expiry_entry); - llist_del(&nrm->entry); - INIT_LLIST_HEAD(&nrm->entry); /* mark unused */ - - /* Just for log */ - struct gtphub_peer_port *from = nrm->origin; - OSMO_ASSERT(from); - LOG(LOGL_DEBUG, "expired: %d: nr mapping from %s: %u->%u\n", - (int)nrm->expiry_entry.expiry, - gtphub_port_str(from), - (unsigned int)nrm->orig, (unsigned int)nrm->repl); - - gtphub_port_ref_count_dec(from); - - talloc_free(nrm); -} - -static struct nr_mapping *gtphub_mapping_have(struct nr_map *map, - struct gtphub_peer_port *from, - nr_t orig_nr, - time_t now) -{ - struct nr_mapping *nrm; - - nrm = nr_map_get(map, from, orig_nr); - - if (!nrm) { - nrm = gtphub_mapping_new(); - nrm->orig = orig_nr; - nrm->origin = from; - nr_map_add(map, nrm, now); - gtphub_port_ref_count_inc(from); - LOG(LOGL_DEBUG, "peer %s: sequence map %d --> %d\n", - gtphub_port_str(from), - (int)(nrm->orig), (int)(nrm->repl)); - } else { - nr_map_refresh(map, nrm, now); - } - - OSMO_ASSERT(nrm); - return nrm; -} - -static void gtphub_map_seq(struct gtp_packet_desc *p, - struct gtphub_peer_port *from_port, - struct gtphub_peer_port *to_port) -{ - /* Store a mapping in to_peer's map, so when we later receive a GTP - * packet back from to_peer, the seq nr can be unmapped back to its - * origin (from_peer here). */ - struct nr_mapping *nrm; - nrm = gtphub_mapping_have(&to_port->peer_addr->peer->seq_map, - from_port, p->seq, p->timestamp); - - /* Change the GTP packet to yield the new, mapped seq nr */ - set_seq(p, nrm->repl); -} - -static struct gtphub_peer_port *gtphub_unmap_seq(struct gtp_packet_desc *p, - struct gtphub_peer_port *responding_port) -{ - OSMO_ASSERT(p->version == 1); - struct nr_mapping *nrm = - nr_map_get_inv(&responding_port->peer_addr->peer->seq_map, - p->seq); - if (!nrm) - return NULL; - LOG(LOGL_DEBUG, "peer %p: sequence unmap %d <-- %d\n", - nrm->origin, (int)(nrm->orig), (int)(nrm->repl)); - set_seq(p, nrm->orig); - return nrm->origin; -} - -static int gtphub_check_mapped_tei(struct gtphub_tunnel *new_tun, - struct gtphub_tunnel *iterated_tun, - uint32_t *tei_min, - uint32_t *tei_max) -{ - if (!new_tun->tei_repl || !iterated_tun->tei_repl) - return 1; - - *tei_min = (*tei_min < iterated_tun->tei_repl)? *tei_min : iterated_tun->tei_repl; - *tei_max = (*tei_max > iterated_tun->tei_repl)? *tei_max : iterated_tun->tei_repl; - - if (new_tun->tei_repl != iterated_tun->tei_repl) - return 1; - - /* new_tun->tei_repl is already taken. Try to find one out of the known - * range. */ - LOG(LOGL_DEBUG, "TEI replacement %d already taken.\n", new_tun->tei_repl); - - if ((*tei_max) < 0xffffffff) { - (*tei_max)++; - new_tun->tei_repl = *tei_max; - LOG(LOGL_DEBUG, "Using TEI %d instead.\n", new_tun->tei_repl); - return 1; - } else if ((*tei_min) > 1) { - (*tei_min)--; - new_tun->tei_repl = *tei_min; - LOG(LOGL_DEBUG, "Using TEI %d instead.\n", new_tun->tei_repl); - return 1; - } - - /* None seems to be available. */ - return 0; -} - -static int gtphub_check_reused_teis(struct gtphub *hub, - struct gtphub_tunnel *new_tun) -{ - uint32_t tei_min = 0xffffffff; - uint32_t tei_max = 0; - int side_idx; - int plane_idx; - struct gtphub_tunnel_endpoint *te; - struct gtphub_tunnel_endpoint *te2; - - struct gtphub_tunnel *tun, *ntun; - - llist_for_each_entry_safe(tun, ntun, &hub->tunnels, entry) { - if (tun == new_tun) - continue; - - /* Check whether the GSN sent a TEI that it is reusing from a - * previous tunnel. */ - int tun_continue = 0; - for_each_side(side_idx) { - for_each_plane(plane_idx) { - te = &tun->endpoint[side_idx][plane_idx]; - te2 = &new_tun->endpoint[side_idx][plane_idx]; - if ((te->tei_orig == 0) - || (te->tei_orig != te2->tei_orig) - || (!te->peer) - || (!te2->peer) - || !gsn_addr_same(&te->peer->peer_addr->addr, - &te2->peer->peer_addr->addr)) - continue; - - /* The peer is reusing a TEI that I believe to - * be part of another tunnel. The other tunnel - * must be stale, then. */ - LOG(LOGL_NOTICE, - "Expiring tunnel due to reused TEI:" - " %s peer %s sent %s TEI %x," - " previously used by tunnel %s...\n", - gtphub_side_idx_names[side_idx], - gtphub_port_str(te->peer), - gtphub_plane_idx_names[plane_idx], - te->tei_orig, - gtphub_tunnel_str(tun)); - LOG(LOGL_NOTICE, "...while establishing tunnel %s\n", - gtphub_tunnel_str(new_tun)); - - expiring_item_del(&tun->expiry_entry); - /* continue to find more matches. There shouldn't be - * any, but let's make sure. However, tun is deleted, - * so we need to skip to the next tunnel. */ - tun_continue = 1; - break; - } - if (tun_continue) - break; - } - if (tun_continue) - continue; - - /* Check whether the mapped TEI is already used by another - * tunnel. */ - if (!gtphub_check_mapped_tei(new_tun, tun, &tei_min, &tei_max)) { - LOG(LOGL_ERROR, - "No mapped TEI is readily available." - " Searching for holes between occupied" - " TEIs not implemented."); - return 0; - } - - } - - return 1; -} - -static void gtphub_tunnel_refresh(struct gtphub *hub, - struct gtphub_tunnel *tun, - time_t now) -{ - expiry_add(&hub->expire_slowly, - &tun->expiry_entry, - now); -} - -static struct gtphub_tunnel_endpoint *gtphub_unmap_tei(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port *from, - struct gtphub_tunnel **unmapped_from_tun) -{ - OSMO_ASSERT(from); - int other_side = other_side_idx(p->side_idx); - - struct gtphub_tunnel *tun; - llist_for_each_entry(tun, &hub->tunnels, entry) { - struct gtphub_tunnel_endpoint *te_from = - &tun->endpoint[p->side_idx][p->plane_idx]; - struct gtphub_tunnel_endpoint *te_to = - &tun->endpoint[other_side][p->plane_idx]; - if ((tun->tei_repl == p->header_tei_rx) - && te_from->peer - && gsn_addr_same(&te_from->peer->peer_addr->addr, - &from->peer_addr->addr)) { - gtphub_tunnel_refresh(hub, tun, p->timestamp); - if (unmapped_from_tun) - *unmapped_from_tun = tun; - return te_to; - } - } - - if (unmapped_from_tun) - *unmapped_from_tun = NULL; - return NULL; -} - -static void gtphub_map_restart_counter(struct gtphub *hub, - struct gtp_packet_desc *p) -{ - if (p->rc != GTP_RC_PDU_C) - return; - - int ie_idx; - ie_idx = gtpie_getie(p->ie, GTPIE_RECOVERY, 0); - if (ie_idx < 0) - return; - - /* Always send gtphub's own restart counter */ - p->ie[ie_idx]->tv1.v = hton8(hub->restart_counter); -} - -static int gtphub_unmap_header_tei(struct gtphub_peer_port **to_port_p, - struct gtphub_tunnel **unmapped_from_tun, - struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port *from_port) -{ - OSMO_ASSERT(p->version == 1); - *to_port_p = NULL; - if (unmapped_from_tun) - *unmapped_from_tun = NULL; - - /* If the header's TEI is zero, no PDP context has been established - * yet. If nonzero, a mapping should actually already exist for this - * TEI, since it must have been announced in a PDP context creation. */ - if (!p->header_tei_rx) - return 0; - - /* to_peer has previously announced a TEI, which was stored and - * mapped in a tunnel struct. */ - struct gtphub_tunnel_endpoint *to; - to = gtphub_unmap_tei(hub, p, from_port, unmapped_from_tun); - if (!to) { - LOG(LOGL_ERROR, "Received unknown TEI %" PRIx32 " from %s\n", - p->header_tei_rx, gtphub_port_str(from_port)); - return -1; - } - - if (unmapped_from_tun) { - OSMO_ASSERT(*unmapped_from_tun); - LOG(LOGL_DEBUG, "Unmapped TEI coming from: %s\n", - gtphub_tunnel_str(*unmapped_from_tun)); - } - - uint32_t unmapped_tei = to->tei_orig; - set_tei(p, unmapped_tei); - - /* May be NULL for an invalidated tunnel. */ - *to_port_p = to->peer; - - return 0; -} - -static int gtphub_handle_create_pdp_ctx(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port *from_ctrl, - struct gtphub_peer_port *to_ctrl) -{ - int plane_idx; - - osmo_static_assert((GTPH_PLANE_CTRL == 0) && (GTPH_PLANE_USER == 1), - plane_nrs_match_GSN_addr_IE_indices); - - struct gtphub_tunnel *tun = p->tun; - - if (p->type == GTP_CREATE_PDP_REQ) { - if (p->side_idx != GTPH_SIDE_SGSN) { - LOG(LOGL_ERROR, "Wrong side: Create PDP Context" - " Request from the GGSN side: %s", - gtphub_port_str(from_ctrl)); - return -1; - } - - if (tun) { - LOG(LOGL_ERROR, "Not implemented: Received" - " Create PDP Context Request for an already" - " established tunnel:" - " from %s, tunnel %s\n", - gtphub_port_str(from_ctrl), - gtphub_tunnel_str(p->tun)); - return -1; - } - - /* A new tunnel. */ - p->tun = tun = gtphub_tunnel_new(); - - /* Create TEI mapping */ - tun->tei_repl = nr_pool_next(&hub->tei_pool); - - llist_add(&tun->entry, &hub->tunnels); - gtphub_tunnel_refresh(hub, tun, p->timestamp); - /* The endpoint peers on this side (SGSN) will be set from IEs - * below. Also set the GGSN Ctrl endpoint, for logging. */ - gtphub_tunnel_endpoint_set_peer(&tun->endpoint[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], - to_ctrl); - } else if (p->type == GTP_CREATE_PDP_RSP) { - if (p->side_idx != GTPH_SIDE_GGSN) { - LOG(LOGL_ERROR, "Wrong side: Create PDP Context" - " Response from the SGSN side: %s", - gtphub_port_str(from_ctrl)); - return -1; - } - - /* The tunnel should already have been resolved from the header - * TEI and be available in tun (== p->tun). Just fill in the - * GSN Addresses below.*/ - OSMO_ASSERT(tun); - OSMO_ASSERT(tun->tei_repl == p->header_tei_rx); - OSMO_ASSERT(to_ctrl); - } - - uint8_t ie_type[] = { GTPIE_TEI_C, GTPIE_TEI_DI }; - int ie_mandatory = (p->type == GTP_CREATE_PDP_REQ); - unsigned int side_idx = p->side_idx; - - for (plane_idx = 0; plane_idx < 2; plane_idx++) { - int rc; - struct gsn_addr use_addr; - uint16_t use_port; - uint32_t tei_from_ie; - int ie_idx; - - /* Fetch GSN Address and TEI from IEs. As ensured by above - * static asserts, plane_idx corresponds to the GSN Address IE - * index (the first one = 0 = ctrl, second one = 1 = user). */ - rc = gsn_addr_get(&use_addr, p, plane_idx); - if (rc) { - LOG(LOGL_ERROR, "Cannot read %s GSN Address IE\n", - gtphub_plane_idx_names[plane_idx]); - return -1; - } - LOG(LOGL_DEBUG, "Read %s GSN addr %s (%d)\n", - gtphub_plane_idx_names[plane_idx], - gsn_addr_to_str(&use_addr), - use_addr.len); - - ie_idx = gtpie_getie(p->ie, ie_type[plane_idx], 0); - if (ie_idx < 0) { - if (ie_mandatory) { - LOG(LOGL_ERROR, - "Create PDP Context message invalid:" - " missing IE %d\n", - (int)ie_type[plane_idx]); - return -1; - } - tei_from_ie = 0; - } - else - tei_from_ie = ntoh32(p->ie[ie_idx]->tv4.v); - - /* Make sure an entry for this peer address with default port - * exists. - * - * Exception: if sgsn_use_sender is set, instead use the - * sender's address and port for Ctrl -- the User port is not - * known until the first User packet arrives. - * - * Note: doing this here is just an optimization, because - * gtphub_handle_buf() has code to replace the tunnel - * endpoints' addresses with the sender (needed for User - * plane). We could just ignore sgsn_use_sender here. But if we - * set up a default port here and replace it in - * gtphub_handle_buf(), we'd be creating a peer port just to - * expire it right away. */ - if (hub->sgsn_use_sender && (side_idx == GTPH_SIDE_SGSN)) { - gsn_addr_from_sockaddr(&use_addr, &use_port, &from_ctrl->sa); - } else { - use_port = gtphub_plane_idx_default_port[plane_idx]; - - } - - struct gtphub_peer_port *peer_from_ie; - peer_from_ie = gtphub_port_have(hub, - &hub->to_gsns[side_idx][plane_idx], - &use_addr, use_port); - - gtphub_tunnel_endpoint_set_peer(&tun->endpoint[side_idx][plane_idx], - peer_from_ie); - - if (!tei_from_ie && - !tun->endpoint[side_idx][plane_idx].tei_orig) { - LOG(LOGL_ERROR, - "Create PDP Context message omits %s TEI, but" - " no TEI has been announced for this tunnel: %s\n", - gtphub_plane_idx_names[plane_idx], - gtphub_tunnel_str(tun)); - return -1; - } - - if (tei_from_ie) { - /* Replace TEI in GTP packet IE */ - tun->endpoint[side_idx][plane_idx].tei_orig = tei_from_ie; - p->ie[ie_idx]->tv4.v = hton32(tun->tei_repl); - - if (!gtphub_check_reused_teis(hub, tun)) { - /* It's highly unlikely that all TEIs are - * taken. But the code looking for an unused - * TEI is, at the time of writing this comment, - * not able to find gaps in the TEI space. To - * explicitly alert the user of this problem, - * rather abort than carry on. */ - LOG(LOGL_FATAL, "TEI range exhausted. Cannot create TEI mapping, aborting.\n"); - abort(); - } - } - - /* Replace the GSN address to reflect gtphub. */ - rc = gsn_addr_put(&hub->to_gsns[other_side_idx(side_idx)][plane_idx].local_addr, - p, plane_idx); - if (rc) { - LOG(LOGL_ERROR, "Cannot write %s GSN Address IE\n", - gtphub_plane_idx_names[plane_idx]); - return -1; - } - } - - if (p->type == GTP_CREATE_PDP_REQ) { - LOG(LOGL_DEBUG, "New tunnel, first half: %s\n", - gtphub_tunnel_str(tun)); - } else if (p->type == GTP_CREATE_PDP_RSP) { - LOG(LOGL_DEBUG, "New tunnel: %s\n", - gtphub_tunnel_str(tun)); - } - - return 0; -} - -static void pending_delete_del_cb(struct expiring_item *expi) -{ - struct pending_delete *pd; - pd = container_of(expi, struct pending_delete, expiry_entry); - - llist_del(&pd->entry); - INIT_LLIST_HEAD(&pd->entry); - - pd->expiry_entry.del_cb = 0; - expiring_item_del(&pd->expiry_entry); - - talloc_free(pd); -} - -static struct pending_delete *pending_delete_new(void) -{ - struct pending_delete *pd = talloc_zero(osmo_gtphub_ctx, struct pending_delete); - INIT_LLIST_HEAD(&pd->entry); - expiring_item_init(&pd->expiry_entry); - pd->expiry_entry.del_cb = pending_delete_del_cb; - return pd; -} - -static int gtphub_handle_delete_pdp_ctx(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port *from_ctrl, - struct gtphub_peer_port *to_ctrl) -{ - struct gtphub_tunnel *known_tun = p->tun; - - if (p->type == GTP_DELETE_PDP_REQ) { - if (!known_tun) { - LOG(LOGL_ERROR, "Cannot find tunnel for Delete PDP Context Request.\n"); - return -1; - } - - /* Store the Delete Request until a successful Response is seen. */ - uint8_t teardown_ind; - uint8_t nsapi; - - if (gtpie_gettv1(p->ie, GTPIE_TEARDOWN, 0, &teardown_ind) != 0) { - LOG(LOGL_ERROR, "Missing Teardown Ind IE in Delete PDP Context Request.\n"); - return -1; - } - - if (gtpie_gettv1(p->ie, GTPIE_NSAPI, 0, &nsapi) != 0) { - LOG(LOGL_ERROR, "Missing NSAPI IE in Delete PDP Context Request.\n"); - return -1; - } - - struct pending_delete *pd = NULL; - - struct pending_delete *pdi = NULL; - llist_for_each_entry(pdi, &hub->pending_deletes, entry) { - if ((pdi->tun == known_tun) - && (pdi->teardown_ind == teardown_ind) - && (pdi->nsapi == nsapi)) { - pd = pdi; - break; - } - } - - if (!pd) { - pd = pending_delete_new(); - pd->tun = known_tun; - pd->teardown_ind = teardown_ind; - pd->nsapi = nsapi; - - LOG(LOGL_DEBUG, "Tunnel delete pending: %s\n", - gtphub_tunnel_str(known_tun)); - llist_add(&pd->entry, &hub->pending_deletes); - } - - /* Add or refresh timeout. */ - expiry_add(&hub->expire_quickly, &pd->expiry_entry, p->timestamp); - - /* If a pending_delete should expire before the response to - * indicate success comes in, the responding peer will have the - * tunnel deactivated, while the requesting peer gets no reply - * and keeps the tunnel. The hope is that the requesting peer - * will try again and get a useful response. */ - } else if (p->type == GTP_DELETE_PDP_RSP) { - /* Find the Delete Request for this Response. */ - struct pending_delete *pd = NULL; - - struct pending_delete *pdi; - llist_for_each_entry(pdi, &hub->pending_deletes, entry) { - if (known_tun == pdi->tun) { - pd = pdi; - break; - } - } - - if (!pd) { - LOG(LOGL_ERROR, "Delete PDP Context Response:" - " Cannot find matching request."); - /* If we delete the tunnel now, anyone can send a - * Delete response to kill tunnels at will. */ - return -1; - } - - /* TODO handle teardown_ind and nsapi */ - - expiring_item_del(&pd->expiry_entry); - - uint8_t cause; - if (gtpie_gettv1(p->ie, GTPIE_CAUSE, 0, &cause) != 0) { - LOG(LOGL_ERROR, "Delete PDP Context Response:" - " Missing Cause IE."); - /* If we delete the tunnel now, at least one of the - * peers may still think it is active. */ - return -1; - } - - if (cause != GTPCAUSE_ACC_REQ) { - LOG(LOGL_NOTICE, - "Delete PDP Context Response indicates failure;" - "for %s\n", - gtphub_tunnel_str(known_tun)); - return -1; - } - - LOG(LOGL_DEBUG, "Delete PDP Context: removing tunnel %s\n", - gtphub_tunnel_str(known_tun)); - p->tun = NULL; - expiring_item_del(&known_tun->expiry_entry); - } - - return 0; -} - -static int gtphub_handle_update_pdp_ctx(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port *from_ctrl, - struct gtphub_peer_port *to_ctrl) -{ - /* TODO */ - return 0; -} - -/* Read GSN address IEs from p, and make sure these peer addresses exist in - * bind[plane_idx] with default ports, in their respective planes (both Ctrl - * and User). Map TEIs announced in IEs, and write mapped TEIs in-place into - * the packet p. */ -static int gtphub_handle_pdp_ctx(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port *from_ctrl, - struct gtphub_peer_port *to_ctrl) -{ - OSMO_ASSERT(p->plane_idx == GTPH_PLANE_CTRL); - - switch (p->type) { - case GTP_CREATE_PDP_REQ: - case GTP_CREATE_PDP_RSP: - return gtphub_handle_create_pdp_ctx(hub, p, - from_ctrl, to_ctrl); - - case GTP_DELETE_PDP_REQ: - case GTP_DELETE_PDP_RSP: - return gtphub_handle_delete_pdp_ctx(hub, p, - from_ctrl, to_ctrl); - - case GTP_UPDATE_PDP_REQ: - case GTP_UPDATE_PDP_RSP: - return gtphub_handle_update_pdp_ctx(hub, p, - from_ctrl, to_ctrl); - - default: - /* Nothing to do for this message type. */ - return 0; - } - -} - -static int gtphub_send_del_pdp_ctx(struct gtphub *hub, - struct gtphub_tunnel *tun, - int to_side) -{ - static uint8_t del_ctx_msg[16] = { - 0x32, /* GTP v1 flags */ - GTP_DELETE_PDP_REQ, - 0x00, 0x08, /* Length in network byte order */ - 0x00, 0x00, 0x00, 0x00, /* TEI to be replaced */ - 0, 0, /* Seq, to be replaced */ - 0, 0, /* no extensions */ - 0x13, 0xff, /* 19: Teardown ind = 1 */ - 0x14, 0 /* 20: NSAPI = 0 */ - }; - - uint32_t *tei = (uint32_t*)&del_ctx_msg[4]; - uint16_t *seq = (uint16_t*)&del_ctx_msg[8]; - - struct gtphub_tunnel_endpoint *te = - &tun->endpoint[to_side][GTPH_PLANE_CTRL]; - - if (! te->peer) - return 0; - - *tei = hton32(te->tei_orig); - *seq = hton16(nr_pool_next(&te->peer->peer_addr->peer->seq_pool)); - - struct gtphub_bind *to_bind = &hub->to_gsns[to_side][GTPH_PLANE_CTRL]; - int rc = gtphub_write(&to_bind->ofd, &te->peer->sa, - del_ctx_msg, sizeof(del_ctx_msg)); - if (rc != 0) { - LOG(LOGL_ERROR, - "Failed to send out-of-band Delete PDP Context Request to %s\n", - gtphub_port_str(te->peer)); - } - return rc; -} - -/* Tell all peers on the other end of tunnels that PDP contexts are void. */ -static void gtphub_restarted(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port *pp) -{ - LOG(LOGL_NOTICE, "Peer has restarted: %s\n", - gtphub_port_str(pp)); - - int deleted_count = 0; - struct gtphub_tunnel *tun; - llist_for_each_entry(tun, &hub->tunnels, entry) { - int side_idx; - for_each_side(side_idx) { - struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][GTPH_PLANE_CTRL]; - struct gtphub_tunnel_endpoint *te2 = &tun->endpoint[other_side_idx(side_idx)][GTPH_PLANE_CTRL]; - if ((!te->peer) - || (!te2->tei_orig) - || (pp->peer_addr->peer != te->peer->peer_addr->peer)) - continue; - - LOG(LOGL_DEBUG, "Deleting tunnel due to peer restart: %s\n", - gtphub_tunnel_str(tun)); - deleted_count ++; - - /* Send a Delete PDP Context Request to the - * peer on the other side, remember the pending - * delete and wait for the response to delete - * the tunnel. Clear this side of the tunnel to - * make sure it isn't used. - * - * Should the delete message send fail, or if no - * response is received, this tunnel will expire. If - * its TEIs come up in a new PDP Context Request, it - * will be removed. If messages for this tunnel should - * come in (from the not restarted side), they will be - * dropped because the tunnel is rendered unusable. */ - gtphub_send_del_pdp_ctx(hub, tun, other_side_idx(side_idx)); - - gtphub_tunnel_endpoint_set_peer(&tun->endpoint[side_idx][GTPH_PLANE_CTRL], - NULL); - gtphub_tunnel_endpoint_set_peer(&tun->endpoint[side_idx][GTPH_PLANE_USER], - NULL); - } - } - - if (deleted_count) - LOG(LOGL_NOTICE, "Deleting %d tunnels due to restart of: %s\n", - deleted_count, - gtphub_port_str(pp)); -} - -static int get_restart_count(struct gtp_packet_desc *p) -{ - int ie_idx; - ie_idx = gtpie_getie(p->ie, GTPIE_RECOVERY, 0); - if (ie_idx < 0) - return -1; - return ntoh8(p->ie[ie_idx]->tv1.v); -} - -static void gtphub_check_restart_counter(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port *from) -{ - /* If the peer is sending a Recovery IE (7.7.11) with a restart counter - * that doesn't match the peer's previously sent restart counter, clear - * that peer and cancel PDP contexts. */ - - int restart = get_restart_count(p); - - if ((restart < 0) || (restart > 255)) - return; - - if ((from->last_restart_count >= 0) && (from->last_restart_count <= 255)) { - if (from->last_restart_count != restart) { - gtphub_restarted(hub, p, from); - } - } - - from->last_restart_count = restart; -} - -static int from_sgsns_read_cb(struct osmo_fd *from_sgsns_ofd, unsigned int what) -{ - unsigned int plane_idx = from_sgsns_ofd->priv_nr; - OSMO_ASSERT(plane_idx < GTPH_PLANE_N); - LOG(LOGL_DEBUG, "=== reading from SGSN (%s)\n", - gtphub_plane_idx_names[plane_idx]); - - if (!(what & BSC_FD_READ)) - return 0; - - struct gtphub *hub = from_sgsns_ofd->data; - - static uint8_t buf[4096]; - struct osmo_sockaddr from_addr; - struct osmo_sockaddr to_addr; - struct osmo_fd *to_ofd; - int len; - uint8_t *reply_buf; - - len = gtphub_read(from_sgsns_ofd, &from_addr, buf, sizeof(buf)); - if (len < 1) - return 0; - - len = gtphub_handle_buf(hub, GTPH_SIDE_SGSN, plane_idx, &from_addr, - buf, len, gtphub_now(), - &reply_buf, &to_ofd, &to_addr); - if (len < 1) - return 0; - - return gtphub_write(to_ofd, &to_addr, reply_buf, len); -} - -static int from_ggsns_read_cb(struct osmo_fd *from_ggsns_ofd, unsigned int what) -{ - unsigned int plane_idx = from_ggsns_ofd->priv_nr; - OSMO_ASSERT(plane_idx < GTPH_PLANE_N); - LOG(LOGL_DEBUG, "=== reading from GGSN (%s)\n", - gtphub_plane_idx_names[plane_idx]); - if (!(what & BSC_FD_READ)) - return 0; - - struct gtphub *hub = from_ggsns_ofd->data; - - static uint8_t buf[4096]; - struct osmo_sockaddr from_addr; - struct osmo_sockaddr to_addr; - struct osmo_fd *to_ofd; - int len; - uint8_t *reply_buf; - - len = gtphub_read(from_ggsns_ofd, &from_addr, buf, sizeof(buf)); - if (len < 1) - return 0; - - len = gtphub_handle_buf(hub, GTPH_SIDE_GGSN, plane_idx, &from_addr, - buf, len, gtphub_now(), - &reply_buf, &to_ofd, &to_addr); - if (len < 1) - return 0; - - return gtphub_write(to_ofd, &to_addr, reply_buf, len); -} - -static int gtphub_unmap(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port *from, - struct gtphub_peer_port *to_proxy, - struct gtphub_peer_port **final_unmapped, - struct gtphub_peer_port **unmapped_from_seq) -{ - /* Always (try to) unmap sequence and TEI numbers, which need to be - * replaced in the packet. Either way, give precedence to the proxy, if - * configured. */ - - if (unmapped_from_seq) - *unmapped_from_seq = NULL; - if (final_unmapped) - *final_unmapped = NULL; - p->tun = NULL; - - struct gtphub_peer_port *from_seq = NULL; - struct gtphub_peer_port *from_tei = NULL; - struct gtphub_peer_port *unmapped = NULL; - - from_seq = gtphub_unmap_seq(p, from); - - if (gtphub_unmap_header_tei(&from_tei, &p->tun, hub, p, from) < 0) - return -1; - - struct gtphub_peer *from_peer = from->peer_addr->peer; - if (from_seq && from_tei && (from_seq != from_tei)) { - LOG(LOGL_DEBUG, - "Seq unmap and TEI unmap yield two different peers." - " Using seq unmap." - " (from %s %s: seq %d yields %s, tei %u yields %s)\n", - gtphub_plane_idx_names[p->plane_idx], - gtphub_peer_str(from_peer), - (int)p->seq, - gtphub_port_str(from_seq), - (unsigned int)p->header_tei_rx, - gtphub_port_str2(from_tei) - ); - } - unmapped = (from_seq? from_seq : from_tei); - - if (unmapped && to_proxy && (unmapped != to_proxy)) { - LOG(LOGL_NOTICE, - "Unmap yields a different peer than the configured proxy." - " Using proxy." - " unmapped: %s proxy: %s\n", - gtphub_port_str(unmapped), - gtphub_port_str2(to_proxy) - ); - } - unmapped = (to_proxy? to_proxy : unmapped); - - if (!unmapped) { - /* Return no error, but returned pointers are all NULL. */ - return 0; - } - - if (unmapped_from_seq) - *unmapped_from_seq = from_seq; - if (final_unmapped) - *final_unmapped = unmapped; - return 0; -} - -static int gsn_addr_to_sockaddr(struct gsn_addr *src, - uint16_t port, - struct osmo_sockaddr *dst) -{ - return osmo_sockaddr_init_udp(dst, gsn_addr_to_str(src), port); -} - -/* If p is an Echo request, replace p's data with the matching response and - * return 1. If p is no Echo request, return 0, or -1 if an invalid packet is - * detected. */ -static int gtphub_handle_echo_req(struct gtphub *hub, struct gtp_packet_desc *p, - uint8_t **reply_buf) -{ - if (p->type != GTP_ECHO_REQ) - return 0; - - static uint8_t echo_response_data[14] = { - 0x32, /* GTP v1 flags */ - GTP_ECHO_RSP, - 0x00, 14 - 8, /* Length in network byte order */ - 0x00, 0x00, 0x00, 0x00, /* Zero TEI */ - 0, 0, /* Seq, to be replaced */ - 0, 0, /* no extensions */ - 0x0e, /* Recovery IE */ - 0 /* Restart counter, to be replaced */ - }; - uint16_t *seq = (uint16_t*)&echo_response_data[8]; - uint8_t *recovery = &echo_response_data[13]; - - *seq = hton16(p->seq); - *recovery = hub->restart_counter; - - *reply_buf = echo_response_data; - - return sizeof(echo_response_data); -} - -struct gtphub_peer_port *gtphub_known_addr_have_port(const struct gtphub_bind *bind, - const struct osmo_sockaddr *addr); - -/* Parse buffer as GTP packet, replace elements in-place and return the ofd and - * address to forward to. Return a pointer to the osmo_fd, but copy the - * sockaddr to *to_addr. The reason for this is that the sockaddr may expire at - * any moment, while the osmo_fd is guaranteed to persist. Return the number of - * bytes to forward, 0 or less on failure. */ -int gtphub_handle_buf(struct gtphub *hub, - unsigned int side_idx, - unsigned int plane_idx, - const struct osmo_sockaddr *from_addr, - uint8_t *buf, - size_t received, - time_t now, - uint8_t **reply_buf, - struct osmo_fd **to_ofd, - struct osmo_sockaddr *to_addr) -{ - struct gtphub_bind *from_bind = &hub->to_gsns[side_idx][plane_idx]; - struct gtphub_bind *to_bind = &hub->to_gsns[other_side_idx(side_idx)][plane_idx]; - - rate_ctr_add(&from_bind->counters_io->ctr[GTPH_CTR_BYTES_IN], - received); - - struct gtp_packet_desc p; - gtp_decode(buf, received, side_idx, plane_idx, &p, now); - - LOG(LOGL_DEBUG, "%s rx %s from %s %s%s\n", - (side_idx == GTPH_SIDE_GGSN)? "<-" : "->", - gtphub_plane_idx_names[plane_idx], - gtphub_side_idx_names[side_idx], - osmo_sockaddr_to_str(from_addr), - gtp_type_str(p.type)); - - if (p.rc <= 0) { - LOG(LOGL_ERROR, "INVALID: dropping GTP packet%s from %s %s %s\n", - gtp_type_str(p.type), - gtphub_side_idx_names[side_idx], - gtphub_plane_idx_names[plane_idx], - osmo_sockaddr_to_str(from_addr)); - return -1; - } - - rate_ctr_inc(&from_bind->counters_io->ctr[GTPH_CTR_PKTS_IN]); - - int reply_len; - reply_len = gtphub_handle_echo_req(hub, &p, reply_buf); - if (reply_len > 0) { - /* It was an echo. Nothing left to do. */ - osmo_sockaddr_copy(to_addr, from_addr); - *to_ofd = &from_bind->ofd; - - rate_ctr_inc(&from_bind->counters_io->ctr[GTPH_CTR_PKTS_OUT]); - rate_ctr_add(&from_bind->counters_io->ctr[GTPH_CTR_BYTES_OUT], - reply_len); - LOG(LOGL_DEBUG, "%s Echo response to %s: %d bytes to %s\n", - (side_idx == GTPH_SIDE_GGSN)? "-->" : "<--", - gtphub_side_idx_names[side_idx], - (int)reply_len, osmo_sockaddr_to_str(to_addr)); - return reply_len; - } - if (reply_len < 0) - return -1; - - *to_ofd = &to_bind->ofd; - - /* If a proxy is configured, check that it's indeed that proxy talking - * to us. A proxy is a forced 1:1 connection, e.g. to another gtphub, - * so no-one else is allowed to talk to us from that side. */ - struct gtphub_peer_port *from_peer = hub->proxy[side_idx][plane_idx]; - if (from_peer) { - if (osmo_sockaddr_cmp(&from_peer->sa, from_addr) != 0) { - LOG(LOGL_ERROR, - "Rejecting: %s proxy configured, but GTP packet" - " received on %s bind is from another sender:" - " proxy: %s sender: %s\n", - gtphub_side_idx_names[side_idx], - gtphub_side_idx_names[side_idx], - gtphub_port_str(from_peer), - osmo_sockaddr_to_str(from_addr)); - return -1; - } - } - - if (!from_peer) { - /* Find or create a peer with a matching address. The sender's - * port may in fact differ. */ - from_peer = gtphub_known_addr_have_port(from_bind, from_addr); - } - - /* If any PDP context has been created, we already have an entry for - * this GSN. If we don't have an entry, a GGSN has nothing to tell us - * about, while an SGSN may initiate a PDP context. */ - if (!from_peer) { - if (side_idx == GTPH_SIDE_GGSN) { - LOG(LOGL_ERROR, "Dropping packet%s: unknown GGSN peer: %s\n", - gtp_type_str(p.type), - osmo_sockaddr_to_str(from_addr)); - return -1; - } else { - /* SGSN */ - /* A new peer. If this is on the Ctrl plane, an SGSN - * may make first contact without being known yet, so - * create the peer struct for the current sender. */ - if (plane_idx != GTPH_PLANE_CTRL) { - LOG(LOGL_ERROR, - "Dropping packet%s: User plane peer was not" - "announced by PDP Context: %s\n", - gtp_type_str(p.type), - osmo_sockaddr_to_str(from_addr)); - return -1; - } - - struct gsn_addr from_gsna; - uint16_t from_port; - if (gsn_addr_from_sockaddr(&from_gsna, &from_port, from_addr) != 0) - return -1; - - from_peer = gtphub_port_have(hub, from_bind, &from_gsna, from_port); - } - } - - if (!from_peer) { - /* This could theoretically happen for invalid address data or - * somesuch. */ - LOG(LOGL_ERROR, "Dropping packet%s: invalid %s peer: %s\n", - gtp_type_str(p.type), - gtphub_side_idx_names[side_idx], - osmo_sockaddr_to_str(from_addr)); - return -1; - } - - rate_ctr_add(&from_peer->counters_io->ctr[GTPH_CTR_BYTES_IN], - received); - rate_ctr_inc(&from_peer->counters_io->ctr[GTPH_CTR_PKTS_IN]); - - LOG(LOGL_DEBUG, "from %s peer: %s\n", gtphub_side_idx_names[side_idx], - gtphub_port_str(from_peer)); - - gtphub_check_restart_counter(hub, &p, from_peer); - gtphub_map_restart_counter(hub, &p); - - struct gtphub_peer_port *to_peer_from_seq; - struct gtphub_peer_port *to_peer; - if (gtphub_unmap(hub, &p, from_peer, - hub->proxy[other_side_idx(side_idx)][plane_idx], - &to_peer, &to_peer_from_seq) - != 0) { - return -1; - } - - if (p.tun) { - struct gtphub_tunnel_endpoint *te = &p.tun->endpoint[p.side_idx][p.plane_idx]; - rate_ctr_add(&te->counters_io->ctr[GTPH_CTR_BYTES_IN], - received); - rate_ctr_inc(&te->counters_io->ctr[GTPH_CTR_PKTS_IN]); - } - - if ((!to_peer) && (side_idx == GTPH_SIDE_SGSN)) { - if (gtphub_resolve_ggsn(hub, &p, &to_peer) < 0) - return -1; - } - - if (!to_peer && p.tun && p.type == GTP_DELETE_PDP_RSP) { - /* It's a delete confirmation for a tunnel that is partly - * invalid, probably marked unsuable due to a restarted peer. - * Remove the tunnel and be happy without forwarding. */ - expiring_item_del(&p.tun->expiry_entry); - p.tun = NULL; - return 0; - } - - if (!to_peer) { - LOG(LOGL_ERROR, "No %s to send to. Dropping packet%s" - " (type=%" PRIu8 ", header-TEI=%" PRIx32 ", seq=%" PRIx16 ").\n", - gtphub_side_idx_names[other_side_idx(side_idx)], - gtp_type_str(p.type), - p.type, p.header_tei_rx, p.seq - ); - return -1; - } - - if (plane_idx == GTPH_PLANE_CTRL) { - /* This may be a Create PDP Context response. If it is, there - * are other addresses in the GTP message to set up apart from - * the sender. */ - if (gtphub_handle_pdp_ctx(hub, &p, from_peer, to_peer) - != 0) - return -1; - } - - /* Either to_peer was resolved from an existing tunnel, - * or a PDP Ctx and thus a tunnel has just been created, - * or the tunnel has been deleted due to this message. */ - OSMO_ASSERT(p.tun || (p.type == GTP_DELETE_PDP_RSP)); - - /* If the GGSN is replying to an SGSN request, the sequence nr has - * already been unmapped above (to_peer_from_seq != NULL), and we need not - * create a new mapping. */ - if (!to_peer_from_seq) - gtphub_map_seq(&p, from_peer, to_peer); - - osmo_sockaddr_copy(to_addr, &to_peer->sa); - - *reply_buf = (uint8_t*)p.data; - - if (received) { - rate_ctr_inc(&to_bind->counters_io->ctr[GTPH_CTR_PKTS_OUT]); - rate_ctr_add(&to_bind->counters_io->ctr[GTPH_CTR_BYTES_OUT], - received); - - rate_ctr_inc(&to_peer->counters_io->ctr[GTPH_CTR_PKTS_OUT]); - rate_ctr_add(&to_peer->counters_io->ctr[GTPH_CTR_BYTES_OUT], - received); - } - - if (p.tun) { - struct gtphub_tunnel_endpoint *te = &p.tun->endpoint[other_side_idx(p.side_idx)][p.plane_idx]; - rate_ctr_inc(&te->counters_io->ctr[GTPH_CTR_PKTS_OUT]); - rate_ctr_add(&te->counters_io->ctr[GTPH_CTR_BYTES_OUT], - received); - } - - LOG(LOGL_DEBUG, "%s Forward to %s:" - " header-TEI %" PRIx32", seq %" PRIx16", %d bytes to %s\n", - (side_idx == GTPH_SIDE_SGSN)? "-->" : "<--", - gtphub_side_idx_names[other_side_idx(side_idx)], - p.header_tei, p.seq, - (int)received, osmo_sockaddr_to_str(to_addr)); - return received; -} - -static void resolved_gssn_del_cb(struct expiring_item *expi) -{ - struct gtphub_resolved_ggsn *ggsn; - ggsn = container_of(expi, struct gtphub_resolved_ggsn, expiry_entry); - - gtphub_port_ref_count_dec(ggsn->peer); - llist_del(&ggsn->entry); - - ggsn->expiry_entry.del_cb = 0; - expiring_item_del(&ggsn->expiry_entry); - - talloc_free(ggsn); -} - -void gtphub_resolved_ggsn(struct gtphub *hub, const char *apn_oi_str, - struct gsn_addr *resolved_addr, - time_t now) -{ - struct gtphub_peer_port *pp; - struct gtphub_resolved_ggsn *ggsn; - - LOG(LOGL_DEBUG, "Resolved GGSN callback: %s %s\n", - apn_oi_str, osmo_hexdump((unsigned char*)resolved_addr, - sizeof(*resolved_addr))); - - pp = gtphub_port_have(hub, &hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], - resolved_addr, 2123); - if (!pp) { - LOG(LOGL_ERROR, "Internal: Cannot create/find peer '%s'\n", - gsn_addr_to_str(resolved_addr)); - return; - } - - ggsn = talloc_zero(osmo_gtphub_ctx, struct gtphub_resolved_ggsn); - OSMO_ASSERT(ggsn); - INIT_LLIST_HEAD(&ggsn->entry); - expiring_item_init(&ggsn->expiry_entry); - - ggsn->peer = pp; - gtphub_port_ref_count_inc(pp); - - osmo_strlcpy(ggsn->apn_oi_str, apn_oi_str, sizeof(ggsn->apn_oi_str)); - - ggsn->expiry_entry.del_cb = resolved_gssn_del_cb; - expiry_add(&hub->expire_slowly, &ggsn->expiry_entry, now); - - llist_add(&ggsn->entry, &hub->resolved_ggsns); -} - -static int gtphub_gc_peer_port(struct gtphub_peer_port *pp) -{ - return pp->ref_count == 0; -} - -static int gtphub_gc_peer_addr(struct gtphub_peer_addr *pa) -{ - struct gtphub_peer_port *pp, *npp; - llist_for_each_entry_safe(pp, npp, &pa->ports, entry) { - if (gtphub_gc_peer_port(pp)) { - LOG(LOGL_DEBUG, "expired: peer %s\n", - gtphub_port_str(pp)); - gtphub_peer_port_del(pp); - } - } - return llist_empty(&pa->ports); -} - -static int gtphub_gc_peer(struct gtphub_peer *p) -{ - struct gtphub_peer_addr *pa, *npa; - llist_for_each_entry_safe(pa, npa, &p->addresses, entry) { - if (gtphub_gc_peer_addr(pa)) { - gtphub_peer_addr_del(pa); - } - } - - /* Note that there's a ref_count in each gtphub_peer_port instance - * listed within p->addresses, referenced by TEI mappings from - * hub->tei_map. As long as those don't expire, this peer will stay. */ - - return llist_empty(&p->addresses) - && nr_map_empty(&p->seq_map); -} - -static void gtphub_gc_bind(struct gtphub_bind *b) -{ - struct gtphub_peer *p, *n; - llist_for_each_entry_safe(p, n, &b->peers, entry) { - if (gtphub_gc_peer(p)) { - gtphub_peer_del(p); - } - } -} - -void gtphub_gc(struct gtphub *hub, time_t now) -{ - int expired; - expired = expiry_tick(&hub->expire_quickly, now); - expired += expiry_tick(&hub->expire_slowly, now); - - /* ... */ - - if (expired) { - int s, p; - for_each_side_and_plane(s, p) { - gtphub_gc_bind(&hub->to_gsns[s][p]); - } - } -} - -static void gtphub_gc_cb(void *data) -{ - struct gtphub *hub = data; - gtphub_gc(hub, gtphub_now()); - osmo_timer_schedule(&hub->gc_timer, GTPH_GC_TICK_SECONDS, 0); -} - -static void gtphub_gc_start(struct gtphub *hub) -{ - osmo_timer_setup(&hub->gc_timer, gtphub_gc_cb, hub); - osmo_timer_schedule(&hub->gc_timer, GTPH_GC_TICK_SECONDS, 0); -} - -/* called by unit tests */ -void gtphub_init(struct gtphub *hub) -{ - gtphub_zero(hub); - - INIT_LLIST_HEAD(&hub->tunnels); - INIT_LLIST_HEAD(&hub->pending_deletes); - - expiry_init(&hub->expire_quickly, GTPH_EXPIRE_QUICKLY_SECS); - expiry_init(&hub->expire_slowly, GTPH_EXPIRE_SLOWLY_MINUTES * 60); - - nr_pool_init(&hub->tei_pool, 1, 0xffffffff); - - int side_idx; - int plane_idx; - for_each_side_and_plane(side_idx, plane_idx) { - gtphub_bind_init(&hub->to_gsns[side_idx][plane_idx]); - } - - hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].label = "SGSN Ctrl"; - hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].label = "GGSN Ctrl"; - hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].label = "SGSN User"; - hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].label = "GGSN User"; -} - -/* For the test suite, this is kept separate from gtphub_stop(), which also - * closes sockets. The test suite avoids using sockets and would cause - * segfaults when trying to close uninitialized ofds. */ -void gtphub_free(struct gtphub *hub) -{ - /* By expiring all mappings, a garbage collection should free - * everything else. A gtphub_bind_free() will assert that everything is - * indeed empty. */ - expiry_clear(&hub->expire_quickly); - expiry_clear(&hub->expire_slowly); - - int side_idx; - int plane_idx; - for_each_side_and_plane(side_idx, plane_idx) { - gtphub_gc_bind(&hub->to_gsns[side_idx][plane_idx]); - gtphub_bind_free(&hub->to_gsns[side_idx][plane_idx]); - } -} - -void gtphub_stop(struct gtphub *hub) -{ - int side_idx; - int plane_idx; - for_each_side_and_plane(side_idx, plane_idx) { - gtphub_bind_stop(&hub->to_gsns[side_idx][plane_idx]); - } - gtphub_free(hub); -} - -static int gtphub_make_proxy(struct gtphub *hub, - struct gtphub_peer_port **pp, - struct gtphub_bind *bind, - const struct gtphub_cfg_addr *addr) -{ - if (!addr->addr_str) - return 0; - - struct gsn_addr gsna; - if (gsn_addr_from_str(&gsna, addr->addr_str) != 0) - return -1; - - *pp = gtphub_port_have(hub, bind, &gsna, addr->port); - - /* This is *the* proxy. Make sure it is never expired. */ - gtphub_port_ref_count_inc(*pp); - return 0; -} - -int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg, - uint8_t restart_counter) -{ - gtphub_init(hub); - - hub->restart_counter = restart_counter; - hub->sgsn_use_sender = cfg->sgsn_use_sender? 1 : 0; - - /* If a Ctrl plane proxy is configured, ares will never be used. */ - if (!cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str) { - if (gtphub_ares_init(hub) != 0) { - LOG(LOGL_FATAL, "Failed to initialize ares\n"); - return -1; - } - } - - int side_idx; - int plane_idx; - for_each_side_and_plane(side_idx, plane_idx) { - int rc; - rc = gtphub_bind_start(&hub->to_gsns[side_idx][plane_idx], - &cfg->to_gsns[side_idx][plane_idx], - (side_idx == GTPH_SIDE_SGSN) - ? from_sgsns_read_cb - : from_ggsns_read_cb, - hub, plane_idx); - if (rc) { - LOG(LOGL_FATAL, "Failed to bind for %ss (%s)\n", - gtphub_side_idx_names[side_idx], - gtphub_plane_idx_names[plane_idx]); - return rc; - } - } - - for_each_side_and_plane(side_idx, plane_idx) { - if (gtphub_make_proxy(hub, - &hub->proxy[side_idx][plane_idx], - &hub->to_gsns[side_idx][plane_idx], - &cfg->proxy[side_idx][plane_idx]) - != 0) { - LOG(LOGL_FATAL, "Cannot configure %s proxy" - " %s port %d.\n", - gtphub_side_idx_names[side_idx], - cfg->proxy[side_idx][plane_idx].addr_str, - (int)cfg->proxy[side_idx][plane_idx].port); - return -1; - } - } - - for_each_side_and_plane(side_idx, plane_idx) { - if (hub->proxy[side_idx][plane_idx]) - LOG(LOGL_NOTICE, "Using %s %s proxy %s\n", - gtphub_side_idx_names[side_idx], - gtphub_plane_idx_names[plane_idx], - gtphub_port_str(hub->proxy[side_idx][plane_idx])); - } - - if (hub->sgsn_use_sender) - LOG(LOGL_NOTICE, "Using sender address and port for SGSN instead of GSN Addr IE and default ports.\n"); - - gtphub_gc_start(hub); - return 0; -} - -static struct gtphub_peer_addr *gtphub_peer_find_addr(const struct gtphub_peer *peer, - const struct gsn_addr *addr) -{ - struct gtphub_peer_addr *a; - llist_for_each_entry(a, &peer->addresses, entry) { - if (gsn_addr_same(&a->addr, addr)) - return a; - } - return NULL; -} - -static struct gtphub_peer_port *gtphub_addr_find_port(const struct gtphub_peer_addr *a, - uint16_t port) -{ - OSMO_ASSERT(port); - struct gtphub_peer_port *pp; - llist_for_each_entry(pp, &a->ports, entry) { - if (pp->port == port) - return pp; - } - return NULL; -} - -static struct gtphub_peer_addr *gtphub_addr_find(const struct gtphub_bind *bind, - const struct gsn_addr *addr) -{ - struct gtphub_peer *peer; - llist_for_each_entry(peer, &bind->peers, entry) { - struct gtphub_peer_addr *a = gtphub_peer_find_addr(peer, addr); - if (a) - return a; - } - return NULL; -} - -static struct gtphub_peer_port *gtphub_port_find(const struct gtphub_bind *bind, - const struct gsn_addr *addr, - uint16_t port) -{ - struct gtphub_peer_addr *a = gtphub_addr_find(bind, addr); - if (!a) - return NULL; - return gtphub_addr_find_port(a, port); -} - -struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind, - const struct osmo_sockaddr *addr) -{ - struct gsn_addr gsna; - uint16_t port; - gsn_addr_from_sockaddr(&gsna, &port, addr); - return gtphub_port_find(bind, &gsna, port); -} - -static struct gtphub_peer *gtphub_peer_new(struct gtphub *hub, - struct gtphub_bind *bind) -{ - struct gtphub_peer *peer = talloc_zero(osmo_gtphub_ctx, - struct gtphub_peer); - OSMO_ASSERT(peer); - - INIT_LLIST_HEAD(&peer->addresses); - - nr_pool_init(&peer->seq_pool, 0, 0xffff); - nr_map_init(&peer->seq_map, &peer->seq_pool, &hub->expire_quickly); - - /* TODO use something random to pick the initial sequence nr. - 0x6d31 produces the ASCII character sequence 'm1', currently used in - gtphub_nc_test.sh. */ - peer->seq_pool.last_nr = 0x6d31 - 1; - - llist_add(&peer->entry, &bind->peers); - return peer; -} - -static struct gtphub_peer_addr *gtphub_peer_add_addr(struct gtphub_peer *peer, - const struct gsn_addr *addr) -{ - struct gtphub_peer_addr *a; - a = talloc_zero(osmo_gtphub_ctx, struct gtphub_peer_addr); - OSMO_ASSERT(a); - a->peer = peer; - gsn_addr_copy(&a->addr, addr); - INIT_LLIST_HEAD(&a->ports); - llist_add(&a->entry, &peer->addresses); - - return a; -} - -static struct gtphub_peer_addr *gtphub_addr_have(struct gtphub *hub, - struct gtphub_bind *bind, - const struct gsn_addr *addr) -{ - struct gtphub_peer_addr *a = gtphub_addr_find(bind, addr); - if (a) - return a; - - /* If we haven't found an address, that means we need to create an - * entirely new peer for the new address. More addresses may be added - * to this peer later, but not via this function. */ - struct gtphub_peer *peer = gtphub_peer_new(hub, bind); - - a = gtphub_peer_add_addr(peer, addr); - - LOG(LOGL_DEBUG, "New peer address: %s %s\n", - bind->label, - gsn_addr_to_str(&a->addr)); - - return a; -} - -static struct gtphub_peer_port *gtphub_addr_add_port(struct gtphub_peer_addr *a, - uint16_t port) -{ - struct gtphub_peer_port *pp; - - pp = talloc_zero(osmo_gtphub_ctx, struct gtphub_peer_port); - OSMO_ASSERT(pp); - pp->peer_addr = a; - pp->port = port; - pp->last_restart_count = -1; - - if (gsn_addr_to_sockaddr(&a->addr, port, &pp->sa) != 0) { - talloc_free(pp); - return NULL; - } - - pp->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx, - >phub_ctrg_io_desc, 0); - if (!pp->counters_io) { - talloc_free(pp); - return NULL; - } - - llist_add(&pp->entry, &a->ports); - - LOG(LOGL_DEBUG, "New peer port: %s port %d\n", - gsn_addr_to_str(&a->addr), - (int)port); - - return pp; -} - -struct gtphub_peer_port *gtphub_port_have(struct gtphub *hub, - struct gtphub_bind *bind, - const struct gsn_addr *addr, - uint16_t port) -{ - struct gtphub_peer_addr *a = gtphub_addr_have(hub, bind, addr); - - struct gtphub_peer_port *pp = gtphub_addr_find_port(a, port); - if (pp) - return pp; - - return gtphub_addr_add_port(a, port); -} - -/* Find a GGSN peer with a matching address. If the address is known but the - * port not, create a new port for that peer address. */ -struct gtphub_peer_port *gtphub_known_addr_have_port(const struct gtphub_bind *bind, - const struct osmo_sockaddr *addr) -{ - struct gtphub_peer_addr *pa; - struct gtphub_peer_port *pp; - - struct gsn_addr gsna; - uint16_t port; - gsn_addr_from_sockaddr(&gsna, &port, addr); - - pa = gtphub_addr_find(bind, &gsna); - if (!pa) - return NULL; - - pp = gtphub_addr_find_port(pa, port); - - if (!pp) - pp = gtphub_addr_add_port(pa, port); - - return pp; -} - - -/* Return 0 if the message in p is not applicable for GGSN resolution, -1 if - * resolution should be possible but failed, and 1 if resolution was - * successful. *pp will be set to NULL if <1 is returned. */ -static int gtphub_resolve_ggsn(struct gtphub *hub, - struct gtp_packet_desc *p, - struct gtphub_peer_port **pp) -{ - *pp = NULL; - - /* TODO determine from message type whether IEs should be present? */ - - int rc; - const char *imsi_str; - rc = get_ie_imsi_str(p->ie, 0, &imsi_str); - if (rc < 1) - return rc; - OSMO_ASSERT(imsi_str); - - const char *apn_str; - rc = get_ie_apn_str(p->ie, &apn_str); - if (rc < 1) - return rc; - OSMO_ASSERT(apn_str); - - *pp = gtphub_resolve_ggsn_addr(hub, imsi_str, apn_str); - return (*pp)? 1 : -1; -} - - -/* TODO move to osmocom/core/socket.c ? */ -/* use this in osmo_sock_init() to remove dup. */ -/* Internal: call getaddrinfo for osmo_sockaddr_init(). The caller is required - to call freeaddrinfo(*result), iff zero is returned. */ -static int _osmo_getaddrinfo(struct addrinfo **result, - uint16_t family, uint16_t type, uint8_t proto, - const char *host, uint16_t port) -{ - struct addrinfo hints; - char portbuf[16]; - - sprintf(portbuf, "%u", port); - memset(&hints, '\0', sizeof(struct addrinfo)); - hints.ai_family = family; - if (type == SOCK_RAW) { - /* Workaround for glibc, that returns EAI_SERVICE (-8) if - * SOCK_RAW and IPPROTO_GRE is used. - */ - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - } else { - hints.ai_socktype = type; - hints.ai_protocol = proto; - } - - return getaddrinfo(host, portbuf, &hints, result); -} - -/* TODO move to osmocom/core/socket.c ? */ -int osmo_sockaddr_init(struct osmo_sockaddr *addr, - uint16_t family, uint16_t type, uint8_t proto, - const char *host, uint16_t port) -{ - struct addrinfo *res; - int rc; - rc = _osmo_getaddrinfo(&res, family, type, proto, host, port); - - if (rc != 0) { - LOG(LOGL_ERROR, "getaddrinfo returned error %d\n", (int)rc); - return -EINVAL; - } - - OSMO_ASSERT(res->ai_addrlen <= sizeof(addr->a)); - memcpy(&addr->a, res->ai_addr, res->ai_addrlen); - addr->l = res->ai_addrlen; - freeaddrinfo(res); - - return 0; -} - -int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len, - char *port_str, size_t port_str_len, - const struct osmo_sockaddr *addr, - int flags) -{ - int rc; - - if ((addr->l < 1) || (addr->l > sizeof(addr->a))) { - LOGP(DGTPHUB, LOGL_ERROR, "Invalid address size: %d\n", addr->l); - return -1; - } - - if (addr->l > sizeof(addr->a)) { - LOGP(DGTPHUB, LOGL_ERROR, "Invalid address: too long: %d\n", - addr->l); - return -1; - } - - rc = getnameinfo((struct sockaddr*)&addr->a, addr->l, - addr_str, addr_str_len, - port_str, port_str_len, - flags); - - if (rc) - LOGP(DGTPHUB, LOGL_ERROR, "Invalid address: %s: %s\n", - gai_strerror(rc), osmo_hexdump((uint8_t*)&addr->a, - addr->l)); - - return rc; -} - -const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr, - char *buf, size_t buf_len) -{ - const int portbuf_len = 6; - OSMO_ASSERT(buf_len > portbuf_len); - char *portbuf = buf + buf_len - portbuf_len; - buf_len -= portbuf_len; - if (osmo_sockaddr_to_strs(buf, buf_len, - portbuf, portbuf_len, - addr, - NI_NUMERICHOST | NI_NUMERICSERV)) - return NULL; - - char *pos = buf + strnlen(buf, buf_len-1); - size_t len = buf_len - (pos - buf); - - snprintf(pos, len, " port %s", portbuf); - buf[buf_len-1] = '\0'; - - return buf; -} - -const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *addr) -{ - static char buf[256]; - const char *result = osmo_sockaddr_to_strb(addr, buf, sizeof(buf)); - if (! result) - return "(invalid)"; - return result; -} - -int osmo_sockaddr_cmp(const struct osmo_sockaddr *a, - const struct osmo_sockaddr *b) -{ - if (a == b) - return 0; - if (!a) - return -1; - if (!b) - return 1; - if (a->l != b->l) { - /* Lengths are not the same, but determine the order. Will - * anyone ever sort a list by osmo_sockaddr though...? */ - int cmp = memcmp(&a->a, &b->a, (a->l < b->l)? a->l : b->l); - if (cmp == 0) { - if (a->l < b->l) - return -1; - else - return 1; - } - return cmp; - } - return memcmp(&a->a, &b->a, a->l); -} - -void osmo_sockaddr_copy(struct osmo_sockaddr *dst, - const struct osmo_sockaddr *src) -{ - OSMO_ASSERT(src->l <= sizeof(dst->a)); - memcpy(&dst->a, &src->a, src->l); - dst->l = src->l; -} diff --git a/src/gprs/gtphub_ares.c b/src/gprs/gtphub_ares.c deleted file mode 100644 index afeeda657..000000000 --- a/src/gprs/gtphub_ares.c +++ /dev/null @@ -1,220 +0,0 @@ -/* GTP Hub Implementation */ - -/* (C) 2015 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * gtphub_ares.c. - * - * This file is kept separate so that these functions can be wrapped for - * gtphub_test.c. When a function and its callers are in the same compilational - * unit, the wrappability may be optimized away. - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - */ - -#include -#include - -#include -#include - -#include -#include - -/* TODO split GRX ares from sgsn into a separate struct and allow use without - * globals. */ -#include -extern struct sgsn_instance *sgsn; - -struct sgsn_instance sgsn_inst = { 0 }; -struct sgsn_instance *sgsn = &sgsn_inst; - -extern void *osmo_gtphub_ctx; - -int gtphub_ares_init(struct gtphub *hub) -{ - return sgsn_ares_init(sgsn); -} - -struct ggsn_lookup { - struct llist_head entry; - struct expiring_item expiry_entry; - - struct gtphub *hub; - - char imsi_str[GSM23003_IMSI_MAX_DIGITS+1]; - char apn_ni_str[GSM_APN_LENGTH]; - char apn_oi_str[GSM_APN_LENGTH]; - int have_3dig_mnc; -}; - -static int start_ares_query(struct ggsn_lookup *lookup); - -static void ggsn_lookup_cb(void *arg, int status, int timeouts, - struct hostent *hostent) -{ - struct ggsn_lookup *lookup = arg; - LOGP(DGTPHUB, LOGL_NOTICE, "ggsn_lookup_cb(%p / %p)", lookup, - &lookup->expiry_entry); - - if (status != ARES_SUCCESS) { - LOGP(DGTPHUB, LOGL_ERROR, "DNS query failed.\n"); - - /* Need to try with three digits now */ - if (!lookup->have_3dig_mnc) { - lookup->have_3dig_mnc = 1; - if (start_ares_query(lookup) == 0) - return; - } - - LOGP(DGTPHUB, LOGL_ERROR, "Failed to resolve GGSN. (%p)\n", - lookup); - goto remove_from_queue; - } - - struct gsn_addr resolved_addr; - if (hostent->h_length > sizeof(resolved_addr.buf)) { - LOGP(DGTPHUB, LOGL_ERROR, "Addr size too large: %d > %d\n", - (int)hostent->h_length, (int)sizeof(resolved_addr.buf)); - goto remove_from_queue; - } - - /* Get the first addr from the list */ - char *addr0 = hostent->h_addr_list[0]; - if (!addr0) { - LOGP(DGTPHUB, LOGL_ERROR, "No host address.\n"); - goto remove_from_queue; - } - - memcpy(resolved_addr.buf, addr0, hostent->h_length); - resolved_addr.len = hostent->h_length; - - LOGP(DGTPHUB, LOGL_NOTICE, "resolved addr %s\n", - osmo_hexdump((unsigned char*)&resolved_addr, - sizeof(resolved_addr))); - - gtphub_resolved_ggsn(lookup->hub, lookup->apn_oi_str, &resolved_addr, - gtphub_now()); - -remove_from_queue: - LOGP(DGTPHUB, LOGL_ERROR, "Removing GGSN lookup. (%p / %p)\n", lookup, - &lookup->expiry_entry); - expiring_item_del(&lookup->expiry_entry); -} - -static void make_addr_str(struct ggsn_lookup *lookup) -{ - char *apn_oi_str; - apn_oi_str = osmo_apn_qualify_from_imsi(lookup->imsi_str, - lookup->apn_ni_str, - lookup->have_3dig_mnc); - osmo_strlcpy(lookup->apn_oi_str, apn_oi_str, - sizeof(lookup->apn_oi_str)); -} - -static int start_ares_query(struct ggsn_lookup *lookup) -{ - LOGP(DGTPHUB, LOGL_DEBUG, "Going to query %s (%p / %p)\n", - lookup->apn_oi_str, lookup, &lookup->expiry_entry); - - int rc = sgsn_ares_query(sgsn, lookup->apn_oi_str, ggsn_lookup_cb, - lookup); - if (rc != 0) - LOGP(DGTPHUB, LOGL_ERROR, "Failed to start ares query.\n"); - return rc; -} - -static void ggsn_lookup_del_cb(struct expiring_item *expi) -{ - struct ggsn_lookup *lookup; - lookup = container_of(expi, struct ggsn_lookup, expiry_entry); - - LOGP(DGTPHUB, LOGL_NOTICE, "ggsn_lookup_del_cb(%p / %p)\n", lookup, - expi); - - lookup->expiry_entry.del_cb = 0; - expiring_item_del(expi); - - llist_del(&lookup->entry); - talloc_free(lookup); -} - -struct gtphub_peer_port *gtphub_resolve_ggsn_addr(struct gtphub *hub, - const char *imsi_str, - const char *apn_ni_str) -{ - OSMO_ASSERT(imsi_str); - OSMO_ASSERT(apn_ni_str); - - struct ggsn_lookup *lookup = talloc_zero(osmo_gtphub_ctx, - struct ggsn_lookup); - OSMO_ASSERT(lookup); - - LOGP(DGTPHUB, LOGL_DEBUG, "Request to resolve IMSI" - " '%s' with APN-NI '%s' (%p / %p)\n", - imsi_str, apn_ni_str, lookup, &lookup->expiry_entry); - - expiring_item_init(&lookup->expiry_entry); - lookup->hub = hub; - - osmo_strlcpy(lookup->imsi_str, imsi_str, sizeof(lookup->imsi_str)); - osmo_strlcpy(lookup->apn_ni_str, apn_ni_str, - sizeof(lookup->apn_ni_str)); - - make_addr_str(lookup); - - struct ggsn_lookup *active; - llist_for_each_entry(active, &hub->ggsn_lookups, entry) { - if (strncmp(active->apn_oi_str, lookup->apn_oi_str, - sizeof(lookup->apn_oi_str)) == 0) { - LOGP(DGTPHUB, LOGL_DEBUG, - "Query already pending for %s\n", - lookup->apn_oi_str); - /* A query already pending. Just tip our hat. */ - return NULL; - } - } - - struct gtphub_resolved_ggsn *resolved; - llist_for_each_entry(resolved, &hub->resolved_ggsns, entry) { - if (strncmp(resolved->apn_oi_str, lookup->apn_oi_str, - sizeof(lookup->apn_oi_str)) == 0) { - LOGP(DGTPHUB, LOGL_DEBUG, - "GGSN resolved from cache: %s -> %s\n", - lookup->apn_oi_str, - gtphub_port_str(resolved->peer)); - return resolved->peer; - } - } - - /* Kick off a resolution, but so far return nothing. The hope is that - * the peer will resend the request (a couple of times), and by then - * the GGSN will be resolved. */ - LOGP(DGTPHUB, LOGL_DEBUG, - "Sending out DNS query for %s..." - " (Returning failure, hoping for a retry once resolution" - " has concluded)\n", - lookup->apn_oi_str); - - llist_add(&lookup->entry, &hub->ggsn_lookups); - - lookup->expiry_entry.del_cb = ggsn_lookup_del_cb; - expiry_add(&hub->expire_quickly, &lookup->expiry_entry, gtphub_now()); - - start_ares_query(lookup); - - return NULL; -} diff --git a/src/gprs/gtphub_main.c b/src/gprs/gtphub_main.c deleted file mode 100644 index 2b87d19ef..000000000 --- a/src/gprs/gtphub_main.c +++ /dev/null @@ -1,359 +0,0 @@ -/* GTP Hub main program */ - -/* (C) 2015 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - */ - -#include -#include -#include -#include -#include -#include - -#define _GNU_SOURCE -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "../../bscconfig.h" - -extern void *osmo_gtphub_ctx; - - -const char *gtphub_copyright = - "Copyright (C) 2015 sysmocom s.f.m.c GmbH \r\n" - "License AGPLv3+: GNU AGPL version 2 or later \r\n" - "This is free software: you are free to change and redistribute it.\r\n" - "There is NO WARRANTY, to the extent permitted by law.\r\n"; - -static struct log_info_cat gtphub_categories[] = { - [DGTPHUB] = { - .name = "DGTPHUB", - .description = "GTP Hub", - .color = "\033[1;33m", - .enabled = 1, - .loglevel = LOGL_INFO, - }, -}; - -int gtphub_log_filter_fn(const struct log_context *ctx, - struct log_target *tar) -{ - return 0; -} - -static const struct log_info gtphub_log_info = { - .filter_fn = gtphub_log_filter_fn, - .cat = gtphub_categories, - .num_cat = ARRAY_SIZE(gtphub_categories), -}; - -void log_cfg(struct gtphub_cfg *cfg) -{ - int side_idx, plane_idx; - for_each_side_and_plane(side_idx, plane_idx) { - struct gtphub_cfg_addr *a; - a = &cfg->to_gsns[side_idx][plane_idx].bind; - LOGP(DGTPHUB, LOGL_NOTICE, - "to-%ss bind, %s: %s port %d\n", - gtphub_side_idx_names[side_idx], - gtphub_plane_idx_names[plane_idx], - a->addr_str, a->port); - } -} - -static void signal_handler(int signal) -{ - fprintf(stdout, "signal %d received\n", signal); - - switch (signal) { - case SIGINT: - case SIGTERM: - osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); - sleep(1); - exit(0); - break; - case SIGABRT: - /* in case of abort, we want to obtain a talloc report - * and then return to the caller, who will abort the process */ - case SIGUSR1: - case SIGUSR2: - talloc_report_full(osmo_gtphub_ctx, stderr); - break; - default: - break; - } -} - -extern int bsc_vty_go_parent(struct vty *vty); - -static struct vty_app_info vty_info = { - .name = "OsmoGTPhub", - .version = PACKAGE_VERSION, - .go_parent_cb = bsc_vty_go_parent, - .is_config_node = bsc_vty_is_config_node, -}; - -struct cmdline_cfg { - const char *config_file; - const char *restart_counter_file; - int daemonize; -}; - -static uint8_t next_restart_count(const char *path) -{ - int umask_was = umask(022); - - uint8_t counter = 0; - - FILE *f = fopen(path, "r"); - if (f) { - int rc = fscanf(f, "%hhu", &counter); - - if (rc != 1) - goto failed_to_read; - - char c; - while (fread(&c, 1, 1, f) > 0) { - switch (c) { - case ' ': - case '\t': - case '\n': - case '\r': - break; - default: - goto failed_to_read; - } - } - fclose(f); - } - - counter ++; - - f = fopen(path, "w"); - if (!f) - goto failed_to_write; - if (fprintf(f, "%" PRIu8 "\n", counter) < 2) - goto failed_to_write; - if (fclose(f)) { - f = NULL; - goto failed_to_write; - } - - umask(umask_was); - - LOGP(DGTPHUB, LOGL_NOTICE, "Restarted with counter %hhu\n", counter); - return counter; - -failed_to_read: - fclose(f); - umask(umask_was); - LOGP(DGTPHUB, LOGL_FATAL, "Restart counter file cannot be parsed:" - " %s\n", path); - exit(1); - -failed_to_write: - if (f) - fclose(f); - umask(umask_was); - LOGP(DGTPHUB, LOGL_FATAL, "Restart counter file cannot be written:" - " %s\n", path); - exit(1); -} - -static void print_help(struct cmdline_cfg *ccfg) -{ - printf("gtphub commandline options\n"); - printf(" -h,--help This text.\n"); - printf(" -D,--daemonize Fork the process into a background daemon.\n"); - printf(" -d,--debug Enable Debugging for this category.\n"); - printf(" Pass '-d list' to get a category listing.\n"); - printf(" -s,--disable-color\n"); - printf(" -c,--config-file The config file to use [%s].\n", - ccfg->config_file); - printf(" -e,--log-level Set a global log level.\n"); - printf(" -r,--restart-file File for counting restarts [%s].\n", - ccfg->restart_counter_file); -} - -static void list_categories(void) -{ - printf("Avaliable debug categories:\n"); - int i; - for (i = 0; i < gtphub_log_info.num_cat; ++i) { - if (!gtphub_log_info.cat[i].name) - continue; - - printf("%s\n", gtphub_log_info.cat[i].name); - } -} - -static void handle_options(struct cmdline_cfg *ccfg, int argc, char **argv) -{ - while (1) { - int option_index = 0, c; - static struct option long_options[] = { - {"help", 0, 0, 'h'}, - {"debug", 1, 0, 'd'}, - {"daemonize", 0, 0, 'D'}, - {"config-file", 1, 0, 'c'}, - {"disable-color", 0, 0, 's'}, - {"timestamp", 0, 0, 'T'}, - {"log-level", 1, 0, 'e'}, - {"restart-file", 1, 0, 'r'}, - {NULL, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "hd:Dc:sTe:r:", - long_options, &option_index); - if (c == -1) { - if (optind < argc) { - LOGP(DGTPHUB, LOGL_FATAL, - "Excess commandline arguments ('%s').\n", - argv[optind]); - exit(2); - } - break; - } - - switch (c) { - case 'h': - //print_usage(); - print_help(ccfg); - exit(0); - case 's': - log_set_use_color(osmo_stderr_target, 0); - break; - case 'd': - if (strcmp("list", optarg) == 0) { - list_categories(); - exit(0); - } else - log_parse_category_mask(osmo_stderr_target, optarg); - break; - case 'D': - ccfg->daemonize = 1; - break; - case 'c': - ccfg->config_file = optarg; - break; - case 'T': - log_set_print_timestamp(osmo_stderr_target, 1); - break; - case 'e': - log_set_log_level(osmo_stderr_target, atoi(optarg)); - break; - case 'r': - ccfg->restart_counter_file = optarg; - break; - default: - LOGP(DGTPHUB, LOGL_FATAL, "Invalid command line argument, abort.\n"); - exit(1); - break; - } - } -} - -int main(int argc, char **argv) -{ - int rc; - - struct cmdline_cfg _ccfg; - struct cmdline_cfg *ccfg = &_ccfg; - memset(ccfg, '\0', sizeof(*ccfg)); - ccfg->config_file = "./gtphub.conf"; - ccfg->restart_counter_file = "./gtphub_restart_count"; - - struct gtphub_cfg _cfg; - struct gtphub_cfg *cfg = &_cfg; - memset(cfg, '\0', sizeof(*cfg)); - - struct gtphub _hub; - struct gtphub *hub = &_hub; - - osmo_gtphub_ctx = talloc_named_const(NULL, 0, "osmo_gtphub"); - msgb_talloc_ctx_init(osmo_gtphub_ctx, 0); - - signal(SIGINT, &signal_handler); - signal(SIGTERM, &signal_handler); - signal(SIGABRT, &signal_handler); - signal(SIGUSR1, &signal_handler); - signal(SIGUSR2, &signal_handler); - osmo_init_ignore_signals(); - - osmo_init_logging(>phub_log_info); - - vty_info.copyright = gtphub_copyright; - vty_init(&vty_info); - logging_vty_add_cmds(NULL); - gtphub_vty_init(hub, cfg); - - rate_ctr_init(osmo_gtphub_ctx); - - handle_options(ccfg, argc, argv); - - rc = gtphub_cfg_read(cfg, ccfg->config_file); - if (rc < 0) { - LOGP(DGTPHUB, LOGL_FATAL, "Cannot parse config file '%s'\n", - ccfg->config_file); - exit(2); - } - - /* start telnet after reading config for vty_get_bind_addr() */ - rc = telnet_init_dynif(osmo_gtphub_ctx, 0, vty_get_bind_addr(), - OSMO_VTY_PORT_GTPHUB); - if (rc < 0) - exit(1); - - if (gtphub_start(hub, cfg, - next_restart_count(ccfg->restart_counter_file)) - != 0) - return -1; - - log_cfg(cfg); - - if (ccfg->daemonize) { - rc = osmo_daemonize(); - if (rc < 0) { - LOGP(DGTPHUB, LOGL_FATAL, "Error during daemonize"); - exit(1); - } - } - - while (1) { - rc = osmo_select_main(0); - if (rc < 0) - exit(3); - } - - /* not reached */ - exit(0); -} diff --git a/src/gprs/gtphub_sock.c b/src/gprs/gtphub_sock.c deleted file mode 100644 index 60bebaaeb..000000000 --- a/src/gprs/gtphub_sock.c +++ /dev/null @@ -1,60 +0,0 @@ -/* GTP Hub Implementation */ - -/* (C) 2015 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * gtphub_sock.c. - * - * This file is kept separate so that these functions can be wrapped for - * gtphub_test.c. When a function and its callers are in the same compilational - * unit, the wrappability may be optimized away. - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - */ - -#include -#include - -/* Convenience makro, note: only within this C file. */ -#define LOG(level, fmt, args...) \ - LOGP(DGTPHUB, level, fmt, ##args) - -int gtphub_write(const struct osmo_fd *to, - const struct osmo_sockaddr *to_addr, - const uint8_t *buf, size_t buf_len) -{ - errno = 0; - ssize_t sent = sendto(to->fd, buf, buf_len, 0, - (struct sockaddr*)&to_addr->a, to_addr->l); - LOG(LOGL_DEBUG, "to %s\n", osmo_sockaddr_to_str(to_addr)); - - if (sent == -1) { - LOG(LOGL_ERROR, "error: %s\n", strerror(errno)); - return -EINVAL; - } - - if (sent != buf_len) - LOG(LOGL_ERROR, "sent(%d) != data_len(%d)\n", - (int)sent, (int)buf_len); - else - LOG(LOGL_DEBUG, "Sent %d: %s%s\n", - (int)sent, - osmo_hexdump(buf, sent > 1000? 1000 : sent), - sent > 1000 ? "..." : ""); - - return 0; -} - diff --git a/src/gprs/gtphub_vty.c b/src/gprs/gtphub_vty.c deleted file mode 100644 index a30ad2a54..000000000 --- a/src/gprs/gtphub_vty.c +++ /dev/null @@ -1,613 +0,0 @@ -/* (C) 2015 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -/* TODO split GRX ares from sgsn into a separate struct and allow use without - * globals. */ -#include -extern struct sgsn_instance *sgsn; - -static struct gtphub *g_hub = 0; -static struct gtphub_cfg *g_cfg = 0; - -static struct cmd_node gtphub_node = { - GTPHUB_NODE, - "%s(config-gtphub)# ", - 1, -}; - -#define GTPH_DEFAULT_CONTROL_PORT 2123 -#define GTPH_DEFAULT_USER_PORT 2152 - -static void write_addrs(struct vty *vty, const char *name, - struct gtphub_cfg_addr *c, struct gtphub_cfg_addr *u) -{ - if ((c->port == GTPH_DEFAULT_CONTROL_PORT) - && (u->port == GTPH_DEFAULT_USER_PORT) - && (strcmp(c->addr_str, u->addr_str) == 0)) { - /* Default port numbers and same IP address: write "short" - * variant. */ - vty_out(vty, " %s %s%s", - name, - c->addr_str, - VTY_NEWLINE); - return; - } - - vty_out(vty, " %s ctrl %s %d user %s %d%s", - name, - c->addr_str, (int)c->port, - u->addr_str, (int)u->port, - VTY_NEWLINE); - - struct ares_addr_node *server; - for (server = sgsn->ares_servers; server; server = server->next) - vty_out(vty, " grx-dns-add %s%s", inet_ntoa(server->addr.addr4), VTY_NEWLINE); -} - -static int config_write_gtphub(struct vty *vty) -{ - vty_out(vty, "gtphub%s", VTY_NEWLINE); - - write_addrs(vty, "bind-to-sgsns", - &g_cfg->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].bind, - &g_cfg->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].bind); - - write_addrs(vty, "bind-to-ggsns", - &g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].bind, - &g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].bind); - - if (g_cfg->sgsn_use_sender) { - vty_out(vty, "sgsn-use-sender%s", VTY_NEWLINE); - } - - if (g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].addr_str) { - write_addrs(vty, "sgsn-proxy", - &g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL], - &g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_USER]); - } - - if (g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str) { - write_addrs(vty, "ggsn-proxy", - &g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], - &g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER]); - } - - return CMD_SUCCESS; -} - -DEFUN(cfg_gtphub, cfg_gtphub_cmd, - "gtphub", - "Configure the GTP hub\n") -{ - vty->node = GTPHUB_NODE; - return CMD_SUCCESS; -} - -#define BIND_ARGS "ctrl ADDR <0-65535> user ADDR <0-65535>" -#define BIND_DOCS \ - "Set GTP-C bind\n" \ - "GTP-C local IP address (v4 or v6)\n" \ - "GTP-C local port\n" \ - "Set GTP-U bind\n" \ - "GTP-U local IP address (v4 or v6)\n" \ - "GTP-U local port\n" - - -DEFUN(cfg_gtphub_bind_to_sgsns_short, cfg_gtphub_bind_to_sgsns_short_cmd, - "bind-to-sgsns ADDR", - "GTP Hub Parameters\n" - "Set the local bind address to listen for SGSNs, for both GTP-C and GTP-U\n" - "Local IP address (v4 or v6)\n" - ) -{ - int i; - for_each_plane(i) - g_cfg->to_gsns[GTPH_SIDE_SGSN][i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT; - g_cfg->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT; - return CMD_SUCCESS; -} - -DEFUN(cfg_gtphub_bind_to_ggsns_short, cfg_gtphub_bind_to_ggsns_short_cmd, - "bind-to-ggsns ADDR", - "GTP Hub Parameters\n" - "Set the local bind address to listen for GGSNs, for both GTP-C and GTP-U\n" - "Local IP address (v4 or v6)\n" - ) -{ - int i; - for_each_plane(i) - g_cfg->to_gsns[GTPH_SIDE_GGSN][i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT; - g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT; - return CMD_SUCCESS; -} - - -static int handle_binds(struct gtphub_cfg_bind *b, const char **argv) -{ - b[GTPH_PLANE_CTRL].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - b[GTPH_PLANE_CTRL].bind.port = atoi(argv[1]); - b[GTPH_PLANE_USER].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[2]); - b[GTPH_PLANE_USER].bind.port = atoi(argv[3]); - return CMD_SUCCESS; -} - -DEFUN(cfg_gtphub_bind_to_sgsns, cfg_gtphub_bind_to_sgsns_cmd, - "bind-to-sgsns " BIND_ARGS, - "GTP Hub Parameters\n" - "Set the local bind addresses and ports to listen for SGSNs\n" - BIND_DOCS - ) -{ - return handle_binds(g_cfg->to_gsns[GTPH_SIDE_SGSN], argv); -} - -DEFUN(cfg_gtphub_bind_to_ggsns, cfg_gtphub_bind_to_ggsns_cmd, - "bind-to-ggsns " BIND_ARGS, - "GTP Hub Parameters\n" - "Set the local bind addresses and ports to listen for GGSNs\n" - BIND_DOCS - ) -{ - return handle_binds(g_cfg->to_gsns[GTPH_SIDE_GGSN], argv); -} - -DEFUN(cfg_gtphub_ggsn_proxy_short, cfg_gtphub_ggsn_proxy_short_cmd, - "ggsn-proxy ADDR", - "GTP Hub Parameters\n" - "Redirect all GGSN bound traffic to default ports on this address (another gtphub)\n" - "Remote IP address (v4 or v6)\n" - ) -{ - g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT; - g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT; - return CMD_SUCCESS; -} - -DEFUN(cfg_gtphub_ggsn_proxy, cfg_gtphub_ggsn_proxy_cmd, - "ggsn-proxy " BIND_ARGS, - "GTP Hub Parameters\n" - "Redirect all GGSN bound traffic to these addresses and ports (another gtphub)\n" - BIND_DOCS - ) -{ - g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].port = atoi(argv[1]); - g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]); - g_cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_USER].port = atoi(argv[3]); - return CMD_SUCCESS; -} - -DEFUN(cfg_gtphub_sgsn_proxy_short, cfg_gtphub_sgsn_proxy_short_cmd, - "sgsn-proxy ADDR", - "GTP Hub Parameters\n" - "Redirect all SGSN bound traffic to default ports on this address (another gtphub)\n" - "Remote IP address (v4 or v6)\n" - ) -{ - g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT; - g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT; - return CMD_SUCCESS; -} - -DEFUN(cfg_gtphub_sgsn_proxy, cfg_gtphub_sgsn_proxy_cmd, - "sgsn-proxy " BIND_ARGS, - "GTP Hub Parameters\n" - "Redirect all SGSN bound traffic to these addresses and ports (another gtphub)\n" - BIND_DOCS - ) -{ - g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); - g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].port = atoi(argv[1]); - g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]); - g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_USER].port = atoi(argv[3]); - return CMD_SUCCESS; -} - - -#define SGSN_USE_SENDER_STR \ - "Ignore SGSN's Address IEs, use sender address and port (useful over NAT)\n" - -DEFUN(cfg_gtphub_sgsn_use_sender, - cfg_gtphub_sgsn_use_sender_cmd, - "sgsn-use-sender", - SGSN_USE_SENDER_STR) -{ - g_cfg->sgsn_use_sender = 1; - return CMD_SUCCESS; -} - -DEFUN(cfg_gtphub_no_sgsn_use_sender, - cfg_gtphub_no_sgsn_use_sender_cmd, - "no sgsn-use-sender", - NO_STR SGSN_USE_SENDER_STR) -{ - g_cfg->sgsn_use_sender = 0; - return CMD_SUCCESS; -} - - -/* Copied from sgsn_vty.h */ -DEFUN(cfg_grx_ggsn, cfg_grx_ggsn_cmd, - "grx-dns-add A.B.C.D", - "Add DNS server\nIPv4 address\n") -{ - struct ares_addr_node *node = talloc_zero(tall_bsc_ctx, struct ares_addr_node); - node->family = AF_INET; - inet_aton(argv[0], &node->addr.addr4); - - node->next = sgsn->ares_servers; - sgsn->ares_servers = node; - return CMD_SUCCESS; -} - - -static void show_bind_stats_all(struct vty *vty) -{ - int plane_idx; - for_each_plane(plane_idx) { - vty_out(vty, "- %s Plane:%s", - gtphub_plane_idx_names[plane_idx], VTY_NEWLINE); - - int side_idx; - for_each_side(side_idx) { - struct gtphub_bind *b = &g_hub->to_gsns[side_idx][plane_idx]; - vty_out(vty, " - local addr to/from %ss: %s port %d%s", - gtphub_side_idx_names[side_idx], - gsn_addr_to_str(&b->local_addr), (int)b->local_port, - VTY_NEWLINE); - vty_out_rate_ctr_group(vty, " ", b->counters_io); - } - } -} - -static void show_tunnel_stats(struct vty *vty, struct gtphub_tunnel *tun) -{ - int plane_idx; - for_each_plane(plane_idx) { - vty_out(vty, "- %s Plane:%s", - gtphub_plane_idx_names[plane_idx], VTY_NEWLINE); - - int side_idx; - for_each_side(side_idx) { - struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][plane_idx]; - vty_out(vty, " - to/from %s:%s", - gtphub_side_idx_names[side_idx], - VTY_NEWLINE); - vty_out_rate_ctr_group(vty, " ", te->counters_io); - } - } -} - -static void show_peer_summary(struct vty *vty, const char *prefix, - int side_idx, int plane_idx, - struct gtphub_peer *p, int with_io_stats) -{ - struct gtphub_peer_addr *pa; - int p2l = strlen(prefix) + 4 + 1; - char prefix2[p2l]; - memset(prefix2, ' ', p2l - 1); - prefix2[p2l - 1] = '\0'; - - if (with_io_stats) { - llist_for_each_entry(pa, &p->addresses, entry) { - vty_out(vty, "%s- %s %s %s%s", prefix, - gtphub_side_idx_names[side_idx], - gtphub_plane_idx_names[plane_idx], - gsn_addr_to_str(&pa->addr), - VTY_NEWLINE); - - - struct gtphub_peer_port *pp; - llist_for_each_entry(pp, &pa->ports, entry) { - vty_out(vty, "%s Port %" PRIu16 "%s", prefix, pp->port, VTY_NEWLINE); - vty_out_rate_ctr_group(vty, prefix2, pp->counters_io); - } - } - } else { - llist_for_each_entry(pa, &p->addresses, entry) { - vty_out(vty, "%s- %s %s %s", prefix, - gtphub_side_idx_names[side_idx], - gtphub_plane_idx_names[plane_idx], - gsn_addr_to_str(&pa->addr)); - struct gtphub_peer_port *pp; - llist_for_each_entry(pp, &pa->ports, entry) { - vty_out(vty, ":%" PRIu16, pp->port); - } - vty_out(vty, VTY_NEWLINE); - } - } -} - -static void show_peers_summary(struct vty *vty) -{ - int side_idx; - int plane_idx; - - int count[GTPH_SIDE_N][GTPH_PLANE_N] = {{0}}; - - for_each_side(side_idx) { - for_each_plane(plane_idx) { - struct gtphub_peer *p; - llist_for_each_entry(p, &g_hub->to_gsns[side_idx][plane_idx].peers, entry) { - count[side_idx][plane_idx] ++; - } - } - } - - vty_out(vty, "Peers Count:%s", VTY_NEWLINE); - for_each_side_and_plane(side_idx, plane_idx) { - vty_out(vty, " %s %s peers: %d%s", - gtphub_side_idx_names[side_idx], - gtphub_plane_idx_names[plane_idx], - count[side_idx][plane_idx], - VTY_NEWLINE); - } -} - -static void show_peers_all(struct vty *vty, int with_io_stats) -{ - int side_idx; - int plane_idx; - - int count[GTPH_SIDE_N][GTPH_PLANE_N] = {{0}}; - - vty_out(vty, "All Peers%s%s", - with_io_stats? " with I/O stats" : "", - VTY_NEWLINE); - for_each_side(side_idx) { - vty_out(vty, "- %s%s", gtphub_side_idx_names[side_idx], VTY_NEWLINE); - for_each_plane(plane_idx) { - struct gtphub_peer *p; - llist_for_each_entry(p, &g_hub->to_gsns[side_idx][plane_idx].peers, entry) { - count[side_idx][plane_idx] ++; - show_peer_summary(vty, " ", side_idx, plane_idx, p, with_io_stats); - } - } - } - for_each_side_and_plane(side_idx, plane_idx) { - vty_out(vty, "%s %s peers: %d%s", - gtphub_side_idx_names[side_idx], - gtphub_plane_idx_names[plane_idx], - count[side_idx][plane_idx], - VTY_NEWLINE); - } -} - - -static void show_tunnels_summary(struct vty *vty) -{ - time_t now = gtphub_now(); - - const int w = 36; - int max_expiry = g_hub->expire_slowly.expiry_in_seconds; - float seconds_per_step = ((float)max_expiry) / w; - - /* Print TEI mapping expiry in an ASCII histogram, like: - TEI map summary - Legend: '_'=0 '.'<=1% ':'<=2% '|'<=10% '#'>10% (10.0 m/step) - CTRL: 30 mappings, valid for 360m[# :. | . : . ]1m - USER: 30 mappings, valid for 360m[# :. | . : . ]1m - 4 TEI mappings in total, last expiry in 359.4 min - */ - vty_out(vty, - "Tunnels summary%s" - " Legend: ' '=0 '.'<=1%% ':'<=2%% '|'<=10%% '#'>10%% (%.1f m/step)%s", - VTY_NEWLINE, - seconds_per_step / 60., - VTY_NEWLINE); - - int last_expiry = 0; - - unsigned int count = 0; - - int histogram[w]; - memset(histogram, 0, sizeof(histogram)); - - struct gtphub_tunnel *t; - llist_for_each_entry(t, &g_hub->tunnels, entry) { - count ++; - int expiry = t->expiry_entry.expiry - now; - last_expiry = (last_expiry > expiry) ? last_expiry : expiry; - - int hi = ((float)expiry) / seconds_per_step; - if (hi < 0) - hi = 0; - if (hi > (w - 1)) - hi = w - 1; - histogram[hi] ++; - } - - vty_out(vty, - " %u tunnels, valid for %dm[", - count, max_expiry / 60); - - int i; - for (i = w - 1; i >= 0; i--) { - char c; - int val = histogram[i]; - int percent = 100. * val / count; - if (!val) - c = ' '; - else if (percent <= 1) - c = '.'; - else if (percent <= 2) - c = ':'; - else if (percent <= 10) - c = '|'; - else c = '#'; - vty_out(vty, "%c", c); - } - vty_out(vty, "]1m%s", VTY_NEWLINE); - - vty_out(vty, " last expiry in %.1f min%s", - ((float)last_expiry) / 60., - VTY_NEWLINE); -} - -static void show_tunnels_all(struct vty *vty, int with_io_stats) -{ - time_t now = gtphub_now(); - - vty_out(vty, "All tunnels%s:%s" - "Legend: TEI=: SGSN <-> GGSN (expiry in minutes), with each:%s" - " [/] (TEI C= U=)%s", - with_io_stats? "with I/O stats" : "", - VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); - - unsigned int count = 0; - unsigned int incomplete = 0; - struct gtphub_tunnel *tun; - llist_for_each_entry(tun, &g_hub->tunnels, entry) { - vty_out(vty, - "%s (expiry in %dm)%s", - gtphub_tunnel_str(tun), - (int)((tun->expiry_entry.expiry - now) / 60), - VTY_NEWLINE); - count ++; - if (!gtphub_tunnel_complete(tun)) - incomplete ++; - if (with_io_stats) - show_tunnel_stats(vty, tun); - } - vty_out(vty, "Total: %u tunnels (of which %u incomplete)%s", - count, incomplete, VTY_NEWLINE); -} - -#define SHOW_GTPHUB_STRS SHOW_STR "Show info on running GTP hub\n" -#define SHOW_GTPHUB_PEERS_STRS SHOW_GTPHUB_STRS "Active peers\n" -#define SHOW_GTPHUB_TUNS_STRS SHOW_GTPHUB_STRS "Active tunnels\n" - -DEFUN(show_gtphub_peers_summary, show_gtphub_peers_summary_cmd, "show gtphub peers summary", - SHOW_GTPHUB_PEERS_STRS "Summary of all peers\n") -{ - show_peers_summary(vty); - return CMD_SUCCESS; -} - -DEFUN(show_gtphub_peers_list, show_gtphub_peers_list_cmd, "show gtphub peers list", - SHOW_GTPHUB_PEERS_STRS "List all peers\n") -{ - show_peers_all(vty, 0); - return CMD_SUCCESS; -} - -DEFUN(show_gtphub_peers_stats, show_gtphub_peers_stats_cmd, "show gtphub peers stats", - SHOW_GTPHUB_PEERS_STRS "List all peers with I/O stats\n") -{ - show_peers_all(vty, 1); - return CMD_SUCCESS; -} - -DEFUN(show_gtphub_tunnels_summary, show_gtphub_tunnels_summary_cmd, "show gtphub tunnels summary", - SHOW_GTPHUB_TUNS_STRS "Summary of all tunnels\n") -{ - show_tunnels_summary(vty); - return CMD_SUCCESS; -} - -DEFUN(show_gtphub_tunnels_list, show_gtphub_tunnels_list_cmd, "show gtphub tunnels list", - SHOW_GTPHUB_TUNS_STRS "List all tunnels\n") -{ - show_tunnels_all(vty, 0); - return CMD_SUCCESS; -} - -DEFUN(show_gtphub_tunnels_stats, show_gtphub_tunnels_stats_cmd, "show gtphub tunnels stats", - SHOW_GTPHUB_TUNS_STRS "List all tunnels with I/O stats\n") -{ - show_tunnels_all(vty, 1); - return CMD_SUCCESS; -} - -DEFUN(show_gtphub, show_gtphub_cmd, "show gtphub all", - SHOW_GTPHUB_STRS "Summarize everything about the GTP hub\n") -{ - show_bind_stats_all(vty); - show_peers_summary(vty); - show_tunnels_summary(vty); - return CMD_SUCCESS; -} - - -int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg) -{ - g_hub = global_hub; - g_cfg = global_cfg; - - install_element_ve(&show_gtphub_cmd); - install_element_ve(&show_gtphub_peers_summary_cmd); - install_element_ve(&show_gtphub_peers_list_cmd); - install_element_ve(&show_gtphub_peers_stats_cmd); - install_element_ve(&show_gtphub_tunnels_summary_cmd); - install_element_ve(&show_gtphub_tunnels_list_cmd); - install_element_ve(&show_gtphub_tunnels_stats_cmd); - - install_element(CONFIG_NODE, &cfg_gtphub_cmd); - install_node(>phub_node, config_write_gtphub); - vty_install_default(GTPHUB_NODE); - - install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_short_cmd); - install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_cmd); - install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_ggsns_short_cmd); - install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_ggsns_cmd); - install_element(GTPHUB_NODE, &cfg_gtphub_ggsn_proxy_short_cmd); - install_element(GTPHUB_NODE, &cfg_gtphub_ggsn_proxy_cmd); - install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_short_cmd); - install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_cmd); - install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_use_sender_cmd); - install_element(GTPHUB_NODE, &cfg_gtphub_no_sgsn_use_sender_cmd); - install_element(GTPHUB_NODE, &cfg_grx_ggsn_cmd); - - return 0; -} - -int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file) -{ - int rc; - - rc = vty_read_config_file(config_file, NULL); - if (rc < 0) { - fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file); - return rc; - } - - return 0; -} diff --git a/src/gprs/osmo_sgsn.cfg b/src/gprs/osmo_sgsn.cfg deleted file mode 100644 index c4c9ec1cf..000000000 --- a/src/gprs/osmo_sgsn.cfg +++ /dev/null @@ -1,23 +0,0 @@ -! -! Osmocom SGSN (0.9.0.474-0ede2) configuration saved from vty -!! -! -line vty - no login -! -sgsn - gtp local-ip 192.168.100.11 - ggsn 0 remote-ip 192.168.100.239 - ggsn 0 gtp-version 1 -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 - encapsulation udp local-ip 192.168.100.11 - encapsulation udp local-port 23000 - encapsulation framerelay-gre enabled 0 -bssgp diff --git a/src/gprs/sgsn_ares.c b/src/gprs/sgsn_ares.c deleted file mode 100644 index d94d184a3..000000000 --- a/src/gprs/sgsn_ares.c +++ /dev/null @@ -1,173 +0,0 @@ -/* C-ARES DNS resolver integration */ - -/* - * (C) 2015 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include - -#include - -struct cares_event_fd { - struct llist_head head; - struct osmo_fd fd; -}; - -struct cares_cb_data { - ares_host_callback cb; - void *data; -}; - -static void osmo_ares_reschedule(struct sgsn_instance *sgsn); -static void ares_cb(void *_arg, int status, int timeouts, struct hostent *hostent) -{ - struct cares_cb_data *arg = _arg; - - arg->cb(arg->data, status, timeouts, hostent); - osmo_ares_reschedule(sgsn); - talloc_free(arg); -} - -static int ares_osmo_fd_cb(struct osmo_fd *fd, unsigned int what) -{ - LOGP(DGPRS, LOGL_DEBUG, "C-ares fd(%d) ready(%d)\n", fd->fd, what); - - ares_process_fd(sgsn->ares_channel, - (what & BSC_FD_READ) ? fd->fd : ARES_SOCKET_BAD, - (what & BSC_FD_WRITE) ? fd->fd : ARES_SOCKET_BAD); - osmo_ares_reschedule(sgsn); - return 0; -} - -static void ares_timeout_cb(void *data) -{ - struct sgsn_instance *sgsn = data; - - LOGP(DGPRS, LOGL_DEBUG, "C-ares triggering timeout\n"); - ares_process_fd(sgsn->ares_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); - osmo_ares_reschedule(sgsn); -} - -static void osmo_ares_reschedule(struct sgsn_instance *sgsn) -{ - struct timeval *timeout, tv; - - osmo_timer_del(&sgsn->ares_timer); - timeout = ares_timeout(sgsn->ares_channel, NULL, &tv); - if (timeout) { - LOGP(DGPRS, LOGL_DEBUG, "C-ares scheduling timeout %llu.%llu\n", - (unsigned long long) tv.tv_sec, - (unsigned long long) tv.tv_usec); - osmo_timer_setup(&sgsn->ares_timer, ares_timeout_cb, sgsn); - osmo_timer_schedule(&sgsn->ares_timer, tv.tv_sec, tv.tv_usec); - } -} - -static void setup_ares_osmo_fd(void *data, int fd, int read, int write) -{ - struct cares_event_fd *ufd, *tmp; - - /* delete the entry */ - if (read == 0 && write == 0) { - llist_for_each_entry_safe(ufd, tmp, &sgsn->ares_fds, head) { - if (ufd->fd.fd != fd) - continue; - - LOGP(DGPRS, LOGL_DEBUG, - "Removing C-ares watched fd (%d)\n", fd); - osmo_fd_unregister(&ufd->fd); - llist_del(&ufd->head); - talloc_free(ufd); - return; - } - } - - /* Search for the fd or create a new one */ - llist_for_each_entry(ufd, &sgsn->ares_fds, head) { - if (ufd->fd.fd != fd) - continue; - - LOGP(DGPRS, LOGL_DEBUG, "Updating C-ares fd (%d)\n", fd); - goto update_fd; - } - - LOGP(DGPRS, LOGL_DEBUG, "Registering C-ares fd (%d)\n", fd); - ufd = talloc_zero(tall_bsc_ctx, struct cares_event_fd); - ufd->fd.fd = fd; - ufd->fd.cb = ares_osmo_fd_cb; - ufd->fd.data = data; - if (osmo_fd_register(&ufd->fd) != 0) - LOGP(DGPRS, LOGL_ERROR, "Failed to register C-ares fd (%d)\n", fd); - llist_add(&ufd->head, &sgsn->ares_fds); - -update_fd: - if (read) - ufd->fd.when |= BSC_FD_READ; - else - ufd->fd.when &= ~BSC_FD_READ; - - if (write) - ufd->fd.when |= BSC_FD_WRITE; - else - ufd->fd.when &= ~BSC_FD_WRITE; - - osmo_ares_reschedule(sgsn); -} - -int sgsn_ares_query(struct sgsn_instance *sgsn, const char *name, - ares_host_callback cb, void *data) -{ - struct cares_cb_data *cb_data; - - cb_data = talloc_zero(tall_bsc_ctx, struct cares_cb_data); - cb_data->cb = cb; - cb_data->data = data; - ares_gethostbyname(sgsn->ares_channel, name, AF_INET, ares_cb, cb_data); - osmo_ares_reschedule(sgsn); - return 0; -} - -int sgsn_ares_init(struct sgsn_instance *sgsn) -{ - struct ares_options options; - int optmask; - int rc; - - INIT_LLIST_HEAD(&sgsn->ares_fds); - memset(&options, 0, sizeof(options)); - options.sock_state_cb = setup_ares_osmo_fd; - options.sock_state_cb_data = sgsn; - - optmask = ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB | ARES_OPT_DOMAINS; - - if (sgsn->ares_servers) - optmask |= ARES_OPT_SERVERS; - - ares_library_init(ARES_LIB_INIT_ALL); - rc = ares_init_options(&sgsn->ares_channel, &options, optmask); - if (rc != ARES_SUCCESS) - return rc; - - if (sgsn->ares_servers) - rc = ares_set_servers(sgsn->ares_channel, sgsn->ares_servers); - - return rc; -} - -osmo_static_assert(ARES_SUCCESS == 0, ares_success_zero); diff --git a/src/gprs/sgsn_auth.c b/src/gprs/sgsn_auth.c deleted file mode 100644 index a64339c3e..000000000 --- a/src/gprs/sgsn_auth.c +++ /dev/null @@ -1,312 +0,0 @@ -/* MS authorization and subscriber data handling */ - -/* (C) 2009-2010 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include - -const struct value_string auth_state_names[] = { - { SGSN_AUTH_ACCEPTED, "accepted"}, - { SGSN_AUTH_REJECTED, "rejected"}, - { SGSN_AUTH_UNKNOWN, "unknown"}, - { SGSN_AUTH_AUTHENTICATE, "authenticate" }, - { SGSN_AUTH_UMTS_RESYNC, "UMTS-resync" }, - { 0, NULL } -}; - -const struct value_string *sgsn_auth_state_names = auth_state_names; - -void sgsn_auth_init(void) -{ - INIT_LLIST_HEAD(&sgsn->cfg.imsi_acl); -} - -/* temporary IMSI ACL hack */ -struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg) -{ - struct imsi_acl_entry *acl; - llist_for_each_entry(acl, &cfg->imsi_acl, list) { - if (!strcmp(imsi, acl->imsi)) - return acl; - } - return NULL; -} - -int sgsn_acl_add(const char *imsi, struct sgsn_config *cfg) -{ - struct imsi_acl_entry *acl; - - if (sgsn_acl_lookup(imsi, cfg)) - return -EEXIST; - - acl = talloc_zero(NULL, struct imsi_acl_entry); - if (!acl) - return -ENOMEM; - osmo_strlcpy(acl->imsi, imsi, sizeof(acl->imsi)); - - llist_add(&acl->list, &cfg->imsi_acl); - - return 0; -} - -int sgsn_acl_del(const char *imsi, struct sgsn_config *cfg) -{ - struct imsi_acl_entry *acl; - - acl = sgsn_acl_lookup(imsi, cfg); - if (!acl) - return -ENODEV; - - llist_del(&acl->list); - talloc_free(acl); - - return 0; -} - -enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx) -{ - char mccmnc[16]; - int check_net = 0; - int check_acl = 0; - - OSMO_ASSERT(mmctx); - - switch (sgsn->cfg.auth_policy) { - case SGSN_AUTH_POLICY_OPEN: - return SGSN_AUTH_ACCEPTED; - - case SGSN_AUTH_POLICY_CLOSED: - check_net = 1; - check_acl = 1; - break; - - case SGSN_AUTH_POLICY_ACL_ONLY: - check_acl = 1; - break; - - case SGSN_AUTH_POLICY_REMOTE: - if (!mmctx->subscr) - return mmctx->auth_state; - - if (mmctx->subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING_MASK) - return mmctx->auth_state; - - if (sgsn->cfg.require_authentication && - (!mmctx->is_authenticated || - mmctx->subscr->sgsn_data->auth_triplets_updated)) - return SGSN_AUTH_AUTHENTICATE; - - if (mmctx->subscr->authorized) - return SGSN_AUTH_ACCEPTED; - - return SGSN_AUTH_REJECTED; - } - - if (!strlen(mmctx->imsi)) { - LOGMMCTXP(LOGL_NOTICE, mmctx, - "Missing IMSI, authorization state not known\n"); - return SGSN_AUTH_UNKNOWN; - } - - if (check_net) { - /* We simply assume that the IMSI exists, as long as it is part - * of 'our' network */ - snprintf(mccmnc, sizeof(mccmnc), "%03d%02d", - mmctx->ra.mcc, mmctx->ra.mnc); - if (strncmp(mccmnc, mmctx->imsi, 5) == 0) - return SGSN_AUTH_ACCEPTED; - } - - if (check_acl && sgsn_acl_lookup(mmctx->imsi, &sgsn->cfg)) - return SGSN_AUTH_ACCEPTED; - - return SGSN_AUTH_REJECTED; -} - -/* - * This function is directly called by e.g. the GMM layer. It returns either - * after calling sgsn_auth_update directly or after triggering an asynchronous - * procedure which will call sgsn_auth_update later on. - */ -int sgsn_auth_request(struct sgsn_mm_ctx *mmctx) -{ - struct gprs_subscr *subscr; - struct gsm_auth_tuple *at; - int need_update_location; - int rc; - - LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting authorization\n"); - - if (sgsn->cfg.auth_policy != SGSN_AUTH_POLICY_REMOTE) { - sgsn_auth_update(mmctx); - return 0; - } - - need_update_location = sgsn->cfg.require_update_location && - (mmctx->subscr == NULL || - mmctx->pending_req == GSM48_MT_GMM_ATTACH_REQ); - - /* This has the side effect of registering the subscr with the mmctx */ - subscr = gprs_subscr_get_or_create_by_mmctx(mmctx); - gprs_subscr_put(subscr); - - OSMO_ASSERT(mmctx->subscr != NULL); - - if (sgsn->cfg.require_authentication && !mmctx->is_authenticated) { - /* Find next tuple */ - at = sgsn_auth_get_tuple(mmctx, mmctx->auth_triplet.key_seq); - - if (!at) { - /* No valid tuple found, request fresh ones */ - mmctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL; - LOGMMCTXP(LOGL_INFO, mmctx, - "Requesting authentication tuples\n"); - rc = gprs_subscr_request_auth_info(mmctx, NULL, NULL); - if (rc >= 0) - return 0; - - return rc; - } - - mmctx->auth_triplet = *at; - } else if (need_update_location) { - LOGMMCTXP(LOGL_INFO, mmctx, - "Missing information, requesting subscriber data\n"); - rc = gprs_subscr_request_update_location(mmctx); - if (rc >= 0) - return 0; - - return rc; - } - - sgsn_auth_update(mmctx); - return 0; -} - -void sgsn_auth_update(struct sgsn_mm_ctx *mmctx) -{ - enum sgsn_auth_state auth_state; - struct gprs_subscr *subscr = mmctx->subscr; - struct gsm_auth_tuple *at; - int gmm_cause; - - auth_state = sgsn_auth_state(mmctx); - - LOGMMCTXP(LOGL_DEBUG, mmctx, "Updating authorization (%s -> %s)\n", - get_value_string(sgsn_auth_state_names, mmctx->auth_state), - get_value_string(sgsn_auth_state_names, auth_state)); - - if (auth_state == SGSN_AUTH_UNKNOWN && subscr && - !(subscr->flags & GPRS_SUBSCRIBER_UPDATE_PENDING_MASK)) { - /* Reject requests if gprs_subscr_request_update_location fails */ - LOGMMCTXP(LOGL_ERROR, mmctx, - "Missing information, authorization not possible\n"); - auth_state = SGSN_AUTH_REJECTED; - } - - if (auth_state == SGSN_AUTH_AUTHENTICATE && - mmctx->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) { - /* The current tuple is not valid, but we are possibly called - * because new auth tuples have been received */ - at = sgsn_auth_get_tuple(mmctx, mmctx->auth_triplet.key_seq); - if (!at) { - LOGMMCTXP(LOGL_ERROR, mmctx, - "Missing auth tuples, authorization not possible\n"); - auth_state = SGSN_AUTH_REJECTED; - } else { - mmctx->auth_triplet = *at; - } - } - - if (mmctx->auth_state == auth_state) - return; - - LOGMMCTXP(LOGL_INFO, mmctx, "Got authorization update: state %s -> %s\n", - get_value_string(sgsn_auth_state_names, mmctx->auth_state), - get_value_string(sgsn_auth_state_names, auth_state)); - - mmctx->auth_state = auth_state; - - switch (auth_state) { - case SGSN_AUTH_AUTHENTICATE: - if (subscr) - subscr->sgsn_data->auth_triplets_updated = 0; - - gsm0408_gprs_authenticate(mmctx); - break; - case SGSN_AUTH_ACCEPTED: - gsm0408_gprs_access_granted(mmctx); - break; - case SGSN_AUTH_REJECTED: - gmm_cause = - subscr ? subscr->sgsn_data->error_cause : - SGSN_ERROR_CAUSE_NONE; - - if (subscr && (subscr->flags & GPRS_SUBSCRIBER_CANCELLED) != 0) - gsm0408_gprs_access_cancelled(mmctx, gmm_cause); - else - gsm0408_gprs_access_denied(mmctx, gmm_cause); - break; - default: - break; - } -} - -struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx, - unsigned key_seq) -{ - unsigned count; - unsigned idx; - struct gsm_auth_tuple *at = NULL; - - struct sgsn_subscriber_data *sdata; - - if (!mmctx->subscr) - return NULL; - - if (key_seq == GSM_KEY_SEQ_INVAL) - /* Start with 0 after increment module array size */ - idx = ARRAY_SIZE(sdata->auth_triplets) - 1; - else - idx = key_seq; - - sdata = mmctx->subscr->sgsn_data; - - /* Find next tuple */ - for (count = ARRAY_SIZE(sdata->auth_triplets); count > 0; count--) { - idx = (idx + 1) % ARRAY_SIZE(sdata->auth_triplets); - - if (sdata->auth_triplets[idx].key_seq == GSM_KEY_SEQ_INVAL) - continue; - - if (sdata->auth_triplets[idx].use_count == 0) { - at = &sdata->auth_triplets[idx]; - at->use_count = 1; - return at; - } - } - - return NULL; -} diff --git a/src/gprs/sgsn_cdr.c b/src/gprs/sgsn_cdr.c deleted file mode 100644 index 16ea9d47a..000000000 --- a/src/gprs/sgsn_cdr.c +++ /dev/null @@ -1,259 +0,0 @@ -/* GPRS SGSN CDR dumper */ - -/* (C) 2015 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include - -#include -#include - -/* TODO...avoid going through a global */ -extern struct sgsn_instance *sgsn; - -/** - * The CDR module will generate an entry like: - * - * IMSI, # Subscriber IMSI - * IMEI, # Subscriber IMEI - * MSISDN, # Subscriber MISDN - * Charging_Timestamp, # Event start Time - * Charging_UTC, # Time zone of event start time - * Duration, # Session DURATION - * Cell_Id, # CELL_ID - * Location_Area, # LAC - * GGSN_ADDR, # GGSN_ADDR - * SGSN_ADDR, # SGSN_ADDR - * APNI, # APNI - * PDP_ADDR, # PDP_ADDR - * VOL_IN, # VOL_IN in Bytes - * VOL_OUT, # VOL_OUT in Bytes - * CAUSE_FOR_TERM, # CAUSE_FOR_TERM - */ - - -static void maybe_print_header(FILE *cdr_file) -{ - if (ftell(cdr_file) != 0) - return; - - fprintf(cdr_file, "timestamp,imsi,imei,msisdn,cell_id,lac,hlr,event,pdp_duration,ggsn_addr,sgsn_addr,apni,eua_addr,vol_in,vol_out,charging_id\n"); -} - -static void cdr_log_mm(struct sgsn_instance *inst, const char *ev, - struct sgsn_mm_ctx *mmctx) -{ - FILE *cdr_file; - struct tm tm; - struct timeval tv; - - if (!inst->cfg.cdr.filename) - return; - - cdr_file = fopen(inst->cfg.cdr.filename, "a"); - if (!cdr_file) { - LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n", - inst->cfg.cdr.filename); - return; - } - - maybe_print_header(cdr_file); - gettimeofday(&tv, NULL); - gmtime_r(&tv.tv_sec, &tm); - fprintf(cdr_file, "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s,%s\n", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, - (int)(tv.tv_usec / 1000), - mmctx->imsi, - mmctx->imei, - mmctx->msisdn, - mmctx->gb.cell_id, - mmctx->ra.lac, - mmctx->hlr, - ev); - - fclose(cdr_file); -} - -static void extract_eua(struct ul66_t *eua, char *eua_addr) -{ - if (eua->l < 2) - return; - - /* there is no addr for ETSI/PPP */ - if ((eua->v[0] & 0x0F) != 1) { - strcpy(eua_addr, "ETSI"); - return; - } - - if (eua->v[1] == 0x21 && eua->l == 6) - inet_ntop(AF_INET, &eua->v[2], eua_addr, INET_ADDRSTRLEN); - else if (eua->v[1] == 0x57 && eua->l == 18) - inet_ntop(AF_INET6, &eua->v[2], eua_addr, INET6_ADDRSTRLEN); - else { - /* e.g. both IPv4 and IPv6 */ - strcpy(eua_addr, "Unknown address"); - } -} - -static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev, - struct sgsn_pdp_ctx *pdp) -{ - FILE *cdr_file; - char apni[(pdp->lib ? pdp->lib->apn_use.l : 0) + 1]; - char ggsn_addr[INET_ADDRSTRLEN + 1]; - char sgsn_addr[INET_ADDRSTRLEN + 1]; - char eua_addr[INET6_ADDRSTRLEN + 1]; - struct tm tm; - struct timeval tv; - time_t duration; - struct timespec tp; - - if (!inst->cfg.cdr.filename) - return; - - memset(apni, 0, sizeof(apni)); - memset(ggsn_addr, 0, sizeof(ggsn_addr)); - memset(eua_addr, 0, sizeof(eua_addr)); - - - if (pdp->lib) { - osmo_apn_to_str(apni, pdp->lib->apn_use.v, pdp->lib->apn_use.l); - inet_ntop(AF_INET, &pdp->lib->hisaddr0.s_addr, ggsn_addr, sizeof(ggsn_addr)); - extract_eua(&pdp->lib->eua, eua_addr); - } - - if (pdp->ggsn) - inet_ntop(AF_INET, &pdp->ggsn->gsn->gsnc.s_addr, sgsn_addr, sizeof(sgsn_addr)); - - cdr_file = fopen(inst->cfg.cdr.filename, "a"); - if (!cdr_file) { - LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n", - inst->cfg.cdr.filename); - return; - } - - maybe_print_header(cdr_file); - - clock_gettime(CLOCK_MONOTONIC, &tp); - gettimeofday(&tv, NULL); - - /* convert the timestamp to UTC */ - gmtime_r(&tv.tv_sec, &tm); - - /* Check the duration of the PDP context */ - duration = tp.tv_sec - pdp->cdr_start.tv_sec; - - fprintf(cdr_file, - "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s,%s,%ld,%s,%s,%s,%s,%" PRIu64 ",%" PRIu64 ",%u\n", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, - (int)(tv.tv_usec / 1000), - pdp->mm ? pdp->mm->imsi : "N/A", - pdp->mm ? pdp->mm->imei : "N/A", - pdp->mm ? pdp->mm->msisdn : "N/A", - pdp->mm ? pdp->mm->gb.cell_id : -1, - pdp->mm ? pdp->mm->ra.lac : -1, - pdp->mm ? pdp->mm->hlr : "N/A", - ev, - (unsigned long ) duration, - ggsn_addr, - sgsn_addr, - apni, - eua_addr, - pdp->cdr_bytes_in, - pdp->cdr_bytes_out, - pdp->cdr_charging_id); - fclose(cdr_file); -} - -static void cdr_pdp_timeout(void *_data) -{ - struct sgsn_pdp_ctx *pdp = _data; - cdr_log_pdp(sgsn, "pdp-periodic", pdp); - osmo_timer_schedule(&pdp->cdr_timer, sgsn->cfg.cdr.interval, 0); -} - -static int handle_sgsn_sig(unsigned int subsys, unsigned int signal, - void *handler_data, void *_signal_data) -{ - struct sgsn_signal_data *signal_data = _signal_data; - struct sgsn_instance *inst = handler_data; - - if (subsys != SS_SGSN) - return 0; - - switch (signal) { - case S_SGSN_ATTACH: - cdr_log_mm(inst, "attach", signal_data->mm); - break; - case S_SGSN_UPDATE: - cdr_log_mm(inst, "update", signal_data->mm); - break; - case S_SGSN_DETACH: - cdr_log_mm(inst, "detach", signal_data->mm); - break; - case S_SGSN_MM_FREE: - cdr_log_mm(inst, "free", signal_data->mm); - break; - case S_SGSN_PDP_ACT: - clock_gettime(CLOCK_MONOTONIC, &signal_data->pdp->cdr_start); - signal_data->pdp->cdr_charging_id = signal_data->pdp->lib->cid; - cdr_log_pdp(inst, "pdp-act", signal_data->pdp); - osmo_timer_setup(&signal_data->pdp->cdr_timer, cdr_pdp_timeout, - signal_data->pdp); - osmo_timer_schedule(&signal_data->pdp->cdr_timer, inst->cfg.cdr.interval, 0); - break; - case S_SGSN_PDP_DEACT: - cdr_log_pdp(inst, "pdp-deact", signal_data->pdp); - osmo_timer_del(&signal_data->pdp->cdr_timer); - break; - case S_SGSN_PDP_TERMINATE: - cdr_log_pdp(inst, "pdp-terminate", signal_data->pdp); - osmo_timer_del(&signal_data->pdp->cdr_timer); - break; - case S_SGSN_PDP_FREE: - cdr_log_pdp(inst, "pdp-free", signal_data->pdp); - osmo_timer_del(&signal_data->pdp->cdr_timer); - break; - } - - return 0; -} - -int sgsn_cdr_init(struct sgsn_instance *sgsn) -{ - /* register for CDR related events */ - sgsn->cfg.cdr.interval = 10 * 60; - osmo_signal_register_handler(SS_SGSN, handle_sgsn_sig, sgsn); - - return 0; -} diff --git a/src/gprs/sgsn_ctrl.c b/src/gprs/sgsn_ctrl.c deleted file mode 100644 index 31ac74f1f..000000000 --- a/src/gprs/sgsn_ctrl.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Control Interface Implementation for the SGSN */ -/* - * (C) 2014 by Holger Hans Peter Freyther - * (C) 2014 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include - -#include - -extern vector ctrl_node_vec; - -static int get_subscriber_list(struct ctrl_cmd *cmd, void *d) -{ - struct sgsn_mm_ctx *mm; - - cmd->reply = talloc_strdup(cmd, ""); - llist_for_each_entry(mm, &sgsn_mm_ctxts, list) { - char *addr = NULL; - struct sgsn_pdp_ctx *pdp; - - if (strlen(mm->imsi) == 0) - continue; - - llist_for_each_entry(pdp, &mm->pdp_list, list) - addr = gprs_pdpaddr2str(pdp->lib->eua.v, - pdp->lib->eua.l); - - cmd->reply = talloc_asprintf_append( - cmd->reply, - "%s,%s\n", mm->imsi, addr ? addr : ""); - } - - return CTRL_CMD_REPLY; -} -CTRL_CMD_DEFINE_RO(subscriber_list, "subscriber-list-active-v1"); - -int sgsn_ctrl_cmds_install(void) -{ - int rc = 0; - rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_list); - return rc; -} - -struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *net, - const char *bind_addr, uint16_t port) -{ - return ctrl_interface_setup_dynip(net, bind_addr, port, NULL); -} diff --git a/src/gprs/sgsn_libgtp.c b/src/gprs/sgsn_libgtp.c deleted file mode 100644 index 90b4d1636..000000000 --- a/src/gprs/sgsn_libgtp.c +++ /dev/null @@ -1,885 +0,0 @@ -/* GPRS SGSN integration with libgtp of OpenGGSN */ -/* libgtp implements the GPRS Tunelling Protocol GTP per TS 09.60 / 29.060 */ - -/* (C) 2010 by Harald Welte - * (C) 2010 by On-Waves - * (C) 2015 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bscconfig.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BUILD_IU -#include -#include -#endif - -#include -#include - -/* TS 23.003: The MSISDN shall take the dummy MSISDN value composed of - * 15 digits set to 0 (encoded as an E.164 international number) when - * the MSISDN is not available in messages in which the presence of the - * MSISDN parameter */ -static const uint8_t dummy_msisdn[] = - { 0x91, /* No extension, international, E.164 */ - 0, 0, 0, 0, 0, 0, 0, /* 14 digits of zeroes */ - 0xF0 /* 15th digit of zero + padding */ }; - -const struct value_string gtp_cause_strs[] = { - { GTPCAUSE_REQ_IMSI, "Request IMSI" }, - { GTPCAUSE_REQ_IMEI, "Request IMEI" }, - { GTPCAUSE_REQ_IMSI_IMEI, "Request IMSI and IMEI" }, - { GTPCAUSE_NO_ID_NEEDED, "No identity needed" }, - { GTPCAUSE_MS_REFUSES_X, "MS refuses" }, - { GTPCAUSE_MS_NOT_RESP_X, "MS is not GPRS responding" }, - { GTPCAUSE_ACC_REQ, "Request accepted" }, - { GTPCAUSE_NON_EXIST, "Non-existent" }, - { GTPCAUSE_INVALID_MESSAGE, "Invalid message format" }, - { GTPCAUSE_IMSI_NOT_KNOWN, "IMSI not known" }, - { GTPCAUSE_MS_DETACHED, "MS is GPRS detached" }, - { GTPCAUSE_MS_NOT_RESP, "MS is not GPRS responding" }, - { GTPCAUSE_MS_REFUSES, "MS refuses" }, - { GTPCAUSE_NO_RESOURCES, "No resources available" }, - { GTPCAUSE_NOT_SUPPORTED, "Service not supported" }, - { GTPCAUSE_MAN_IE_INCORRECT, "Mandatory IE incorrect" }, - { GTPCAUSE_MAN_IE_MISSING, "Mandatory IE missing" }, - { GTPCAUSE_OPT_IE_INCORRECT, "Optional IE incorrect" }, - { GTPCAUSE_SYS_FAIL, "System failure" }, - { GTPCAUSE_ROAMING_REST, "Roaming restrictions" }, - { GTPCAUSE_PTIMSI_MISMATCH, "P-TMSI Signature mismatch" }, - { GTPCAUSE_CONN_SUSP, "GPRS connection suspended" }, - { GTPCAUSE_AUTH_FAIL, "Authentication failure" }, - { GTPCAUSE_USER_AUTH_FAIL, "User authentication failed" }, - { GTPCAUSE_CONTEXT_NOT_FOUND, "Context not found" }, - { GTPCAUSE_ADDR_OCCUPIED, "All dynamic PDP addresses occupied" }, - { GTPCAUSE_NO_MEMORY, "No memory is available" }, - { GTPCAUSE_RELOC_FAIL, "Relocation failure" }, - { GTPCAUSE_UNKNOWN_MAN_EXTHEADER, "Unknown mandatory ext. header" }, - { GTPCAUSE_SEM_ERR_TFT, "Semantic error in TFT operation" }, - { GTPCAUSE_SYN_ERR_TFT, "Syntactic error in TFT operation" }, - { GTPCAUSE_SEM_ERR_FILTER, "Semantic errors in packet filter" }, - { GTPCAUSE_SYN_ERR_FILTER, "Syntactic errors in packet filter" }, - { GTPCAUSE_MISSING_APN, "Missing or unknown APN" }, - { GTPCAUSE_UNKNOWN_PDP, "Unknown PDP address or PDP type" }, - { 0, NULL } -}; - -/* Generate the GTP IMSI IE according to 09.60 Section 7.9.2 */ -static uint64_t imsi_str2gtp(char *str) -{ - uint64_t imsi64 = 0; - unsigned int n; - unsigned int imsi_len = strlen(str); - - if (imsi_len > 16) { - LOGP(DGPRS, LOGL_NOTICE, "IMSI length > 16 not supported!\n"); - return 0; - } - - for (n = 0; n < 16; n++) { - uint64_t val; - if (n < imsi_len) - val = (str[n]-'0') & 0xf; - else - val = 0xf; - imsi64 |= (val << (n*4)); - } - return imsi64; -} - -/* generate a PDP context based on the IE's from the 04.08 message, - * and send the GTP create pdp context request to the GGSN */ -struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, - struct sgsn_mm_ctx *mmctx, - uint16_t nsapi, - struct tlv_parsed *tp) -{ - struct gprs_ra_id raid; - struct sgsn_pdp_ctx *pctx; - struct pdp_t *pdp; - uint64_t imsi_ui64; - size_t qos_len; - const uint8_t *qos; - int rc; - - LOGP(DGPRS, LOGL_ERROR, "Create PDP Context\n"); - pctx = sgsn_pdp_ctx_alloc(mmctx, nsapi); - if (!pctx) { - LOGP(DGPRS, LOGL_ERROR, "Couldn't allocate PDP Ctx\n"); - return NULL; - } - - imsi_ui64 = imsi_str2gtp(mmctx->imsi); - - rc = pdp_newpdp(&pdp, imsi_ui64, nsapi, NULL); - if (rc) { - LOGP(DGPRS, LOGL_ERROR, "Out of libgtp PDP Contexts\n"); - return NULL; - } - pdp->priv = pctx; - pctx->lib = pdp; - pctx->ggsn = ggsn; - - //pdp->peer = /* sockaddr_in of GGSN (receive) */ - //pdp->ipif = /* not used by library */ - pdp->version = ggsn->gtp_version; - pdp->hisaddr0 = ggsn->remote_addr; - pdp->hisaddr1 = ggsn->remote_addr; - //pdp->cch_pdp = 512; /* Charging Flat Rate */ - - /* MS provided APN, subscription was verified by the caller */ - pdp->selmode = 0xFC | 0x00; - - /* IMSI, TEID/TEIC, FLLU/FLLC, TID, NSAPI set in pdp_newpdp */ - - /* Put the MSISDN in case we have it */ - if (mmctx->subscr && mmctx->subscr->sgsn_data->msisdn_len) { - pdp->msisdn.l = mmctx->subscr->sgsn_data->msisdn_len; - if (pdp->msisdn.l > sizeof(pdp->msisdn.v)) - pdp->msisdn.l = sizeof(pdp->msisdn.v); - memcpy(pdp->msisdn.v, mmctx->subscr->sgsn_data->msisdn, - pdp->msisdn.l); - } else { - /* use the dummy 15-digits-zero MSISDN value */ - pdp->msisdn.l = sizeof(dummy_msisdn); - memcpy(pdp->msisdn.v, dummy_msisdn, pdp->msisdn.l); - } - - /* End User Address from GMM requested PDP address */ - pdp->eua.l = TLVP_LEN(tp, OSMO_IE_GSM_REQ_PDP_ADDR); - if (pdp->eua.l > sizeof(pdp->eua.v)) - pdp->eua.l = sizeof(pdp->eua.v); - memcpy(pdp->eua.v, TLVP_VAL(tp, OSMO_IE_GSM_REQ_PDP_ADDR), - pdp->eua.l); - /* Highest 4 bits of first byte need to be set to 1, otherwise - * the IE is identical with the 04.08 PDP Address IE */ - pdp->eua.v[0] |= 0xf0; - - /* APN name from GMM */ - pdp->apn_use.l = TLVP_LEN(tp, GSM48_IE_GSM_APN); - if (pdp->apn_use.l > sizeof(pdp->apn_use.v)) - pdp->apn_use.l = sizeof(pdp->apn_use.v); - memcpy(pdp->apn_use.v, TLVP_VAL(tp, GSM48_IE_GSM_APN), - pdp->apn_use.l); - - /* Protocol Configuration Options from GMM */ - pdp->pco_req.l = TLVP_LEN(tp, GSM48_IE_GSM_PROTO_CONF_OPT); - if (pdp->pco_req.l > sizeof(pdp->pco_req.v)) - pdp->pco_req.l = sizeof(pdp->pco_req.v); - memcpy(pdp->pco_req.v, TLVP_VAL(tp, GSM48_IE_GSM_PROTO_CONF_OPT), - pdp->pco_req.l); - - /* QoS options from GMM or remote */ - if (TLVP_LEN(tp, OSMO_IE_GSM_SUB_QOS) > 0) { - qos_len = TLVP_LEN(tp, OSMO_IE_GSM_SUB_QOS); - qos = TLVP_VAL(tp, OSMO_IE_GSM_SUB_QOS); - } else { - qos_len = TLVP_LEN(tp, OSMO_IE_GSM_REQ_QOS); - qos = TLVP_VAL(tp, OSMO_IE_GSM_REQ_QOS); - } - - if (qos_len <= 3) { - pdp->qos_req.l = qos_len + 1; - if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) - pdp->qos_req.l = sizeof(pdp->qos_req.v); - pdp->qos_req.v[0] = 0; /* Allocation/Retention policy */ - memcpy(&pdp->qos_req.v[1], qos, pdp->qos_req.l - 1); - } else { - pdp->qos_req.l = qos_len; - if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) - pdp->qos_req.l = sizeof(pdp->qos_req.v); - memcpy(pdp->qos_req.v, qos, pdp->qos_req.l); - } - - /* charging characteristics if present */ - if (TLVP_LEN(tp, OSMO_IE_GSM_CHARG_CHAR) >= sizeof(pdp->cch_pdp)) - pdp->cch_pdp = tlvp_val16be(tp, OSMO_IE_GSM_CHARG_CHAR); - - /* SGSN address for control plane */ - pdp->gsnlc.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr); - memcpy(pdp->gsnlc.v, &sgsn->cfg.gtp_listenaddr.sin_addr, - sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); - - /* SGSN address for user plane - * Default to the control plane addr for now. If we are connected to a - * hnbgw via IuPS we'll need to send a PDP context update with the - * correct IP address after the RAB Assignment is complete */ - pdp->gsnlu.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr); - memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr, - sizeof(sgsn->cfg.gtp_listenaddr.sin_addr)); - - /* Encode RAT Type according to TS 29.060 7.7.50 */ - pdp->rattype.l = 1; - if (mmctx->ran_type == MM_CTX_T_UTRAN_Iu) - pdp->rattype.v[0] = 1; - else - pdp->rattype.v[0] = 2; - pdp->rattype_given = 1; - - /* Include RAI and ULI all the time */ - pdp->rai_given = 1; - pdp->rai.l = 6; - - /* Routing Area Identifier with LAC and RAC fixed values, as - * requested in 29.006 7.3.1 */ - raid = mmctx->ra; - raid.lac = 0xFFFE; - raid.rac = 0xFF; - gsm48_construct_ra(pdp->rai.v, &raid); - - /* Encode User Location Information accordint to TS 29.060 7.7.51 */ - pdp->userloc_given = 1; - pdp->userloc.l = 8; - switch (mmctx->ran_type) { - case MM_CTX_T_GERAN_Gb: - case MM_CTX_T_GERAN_Iu: - pdp->rattype.v[0] = 2; - /* User Location Information */ - pdp->userloc_given = 1; - pdp->userloc.l = 8; - pdp->userloc.v[0] = 0; /* CGI for GERAN */ - bssgp_create_cell_id(&pdp->userloc.v[1], &mmctx->ra, mmctx->gb.cell_id); - break; - case MM_CTX_T_UTRAN_Iu: - pdp->userloc.v[0] = 1; /* SAI for UTRAN */ - /* SAI is like CGI but with SAC instead of CID, so we can abuse this function */ - bssgp_create_cell_id(&pdp->userloc.v[1], &mmctx->ra, mmctx->iu.sac); - break; - } - - /* include the IMEI(SV) */ - pdp->imeisv_given = 1; - gsm48_encode_bcd_number(&pdp->imeisv.v[0], 8, 0, mmctx->imei); - pdp->imeisv.l = pdp->imeisv.v[0]; - memmove(&pdp->imeisv.v[0], &pdp->imeisv.v[1], 8); - - /* change pdp state to 'requested' */ - pctx->state = PDP_STATE_CR_REQ; - - rc = gtp_create_context_req(ggsn->gsn, pdp, pctx); - /* FIXME */ - - return pctx; -} - -/* SGSN wants to delete a PDP context */ -int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx) -{ - LOGPDPCTXP(LOGL_ERROR, pctx, "Delete PDP Context\n"); - - /* FIXME: decide if we need teardown or not ! */ - return gtp_delete_context_req(pctx->ggsn->gsn, pctx->lib, pctx, 1); -} - -struct cause_map { - uint8_t cause_in; - uint8_t cause_out; -}; - -static uint8_t cause_map(const struct cause_map *map, uint8_t in, uint8_t deflt) -{ - const struct cause_map *m; - - for (m = map; m->cause_in && m->cause_out; m++) { - if (m->cause_in == in) - return m->cause_out; - } - return deflt; -} - -/* how do we map from gtp cause to SM cause */ -static const struct cause_map gtp2sm_cause_map[] = { - { GTPCAUSE_NO_RESOURCES, GSM_CAUSE_INSUFF_RSRC }, - { GTPCAUSE_NOT_SUPPORTED, GSM_CAUSE_SERV_OPT_NOTSUPP }, - { GTPCAUSE_MAN_IE_INCORRECT, GSM_CAUSE_INV_MAND_INFO }, - { GTPCAUSE_MAN_IE_MISSING, GSM_CAUSE_INV_MAND_INFO }, - { GTPCAUSE_OPT_IE_INCORRECT, GSM_CAUSE_PROTO_ERR_UNSPEC }, - { GTPCAUSE_SYS_FAIL, GSM_CAUSE_NET_FAIL }, - { GTPCAUSE_ROAMING_REST, GSM_CAUSE_REQ_SERV_OPT_NOTSUB }, - { GTPCAUSE_PTIMSI_MISMATCH, GSM_CAUSE_PROTO_ERR_UNSPEC }, - { GTPCAUSE_CONN_SUSP, GSM_CAUSE_PROTO_ERR_UNSPEC }, - { GTPCAUSE_AUTH_FAIL, GSM_CAUSE_AUTH_FAILED }, - { GTPCAUSE_USER_AUTH_FAIL, GSM_CAUSE_ACT_REJ_GGSN }, - { GTPCAUSE_CONTEXT_NOT_FOUND, GSM_CAUSE_PROTO_ERR_UNSPEC }, - { GTPCAUSE_ADDR_OCCUPIED, GSM_CAUSE_INSUFF_RSRC }, - { GTPCAUSE_NO_MEMORY, GSM_CAUSE_INSUFF_RSRC }, - { GTPCAUSE_RELOC_FAIL, GSM_CAUSE_PROTO_ERR_UNSPEC }, - { GTPCAUSE_UNKNOWN_MAN_EXTHEADER, GSM_CAUSE_PROTO_ERR_UNSPEC }, - { GTPCAUSE_MISSING_APN, GSM_CAUSE_MISSING_APN }, - { GTPCAUSE_UNKNOWN_PDP, GSM_CAUSE_UNKNOWN_PDP }, - { 0, 0 } -}; - -static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx) -{ - struct sgsn_signal_data sig_data; - int rc; - struct gprs_llc_lle *lle; - - /* Inform others about it */ - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.pdp = pctx; - osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_ACT, &sig_data); - - /* Send PDP CTX ACT to MS */ - rc = gsm48_tx_gsm_act_pdp_acc(pctx); - if (rc < 0) - return rc; - - if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) { - /* Send SNDCP XID to MS */ - lle = &pctx->mm->gb.llme->lle[pctx->sapi]; - rc = sndcp_sn_xid_req(lle,pctx->nsapi); - if (rc < 0) - return rc; - } - - return 0; -} - -/* The GGSN has confirmed the creation of a PDP Context */ -static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause) -{ - struct sgsn_pdp_ctx *pctx = cbp; - uint8_t reject_cause; - - LOGPDPCTXP(LOGL_INFO, pctx, "Received CREATE PDP CTX CONF, cause=%d(%s)\n", - cause, get_value_string(gtp_cause_strs, cause)); - - if (!pctx->mm) { - LOGP(DGPRS, LOGL_INFO, - "No MM context, aborting CREATE PDP CTX CONF\n"); - return -EIO; - } - - /* Check for cause value if it was really successful */ - if (cause < 0) { - LOGP(DGPRS, LOGL_NOTICE, "Create PDP ctx req timed out\n"); - if (pdp && pdp->version == 1) { - pdp->version = 0; - gtp_create_context_req(sgsn->gsn, pdp, cbp); - return 0; - } else { - reject_cause = GSM_CAUSE_NET_FAIL; - goto reject; - } - } - - /* Check for cause value if it was really successful */ - if (cause != GTPCAUSE_ACC_REQ) { - reject_cause = cause_map(gtp2sm_cause_map, cause, - GSM_CAUSE_ACT_REJ_GGSN); - goto reject; - } - - if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) { - /* Activate the SNDCP layer */ - sndcp_sm_activate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi); - return send_act_pdp_cont_acc(pctx); - } else if (pctx->mm->ran_type == MM_CTX_T_UTRAN_Iu) { -#ifdef BUILD_IU - /* Activate a radio bearer */ - iu_rab_act_ps(pdp->nsapi, pctx); - return 0; -#else - return -ENOTSUP; -#endif - } - - LOGP(DGPRS, LOGL_ERROR, "Unknown ran_type %d\n", - pctx->mm->ran_type); - reject_cause = GSM_CAUSE_PROTO_ERR_UNSPEC; - -reject: - /* - * In case of a timeout pdp will be NULL but we have a valid pointer - * in pctx->lib. For other rejects pctx->lib and pdp might be the - * same. - */ - pctx->state = PDP_STATE_NONE; - if (pctx->lib && pctx->lib != pdp) - pdp_freepdp(pctx->lib); - pctx->lib = NULL; - - if (pdp) - pdp_freepdp(pdp); - /* Send PDP CTX ACT REJ to MS */ - gsm48_tx_gsm_act_pdp_rej(pctx->mm, pctx->ti, reject_cause, - 0, NULL); - sgsn_pdp_ctx_free(pctx); - - return EOF; -} - -void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen) -{ - pdp->lib->gsnlu.l = alen; - memcpy(pdp->lib->gsnlu.v, addr, alen); - gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0); -} - -#ifdef BUILD_IU -/* Callback for RAB assignment response */ -int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) -{ - uint8_t rab_id; - bool require_pdp_update = false; - struct sgsn_pdp_ctx *pdp = NULL; - RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem; - - rab_id = item->rAB_ID.buf[0]; - - pdp = sgsn_pdp_ctx_by_nsapi(ctx, rab_id); - if (!pdp) { - LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Response for unknown RAB/NSAPI=%u\n", rab_id); - return -1; - } - - if (item->transportLayerAddress) { - LOGPC(DRANAP, LOGL_INFO, " Setup: (%u/%s)", rab_id, osmo_hexdump(item->transportLayerAddress->buf, - item->transportLayerAddress->size)); - switch (item->transportLayerAddress->size) { - case 7: - /* It must be IPv4 inside a X213 NSAP */ - memcpy(pdp->lib->gsnlu.v, &item->transportLayerAddress->buf[3], 4); - break; - case 4: - /* It must be a raw IPv4 address */ - memcpy(pdp->lib->gsnlu.v, item->transportLayerAddress->buf, 4); - break; - case 16: - /* TODO: It must be a raw IPv6 address */ - case 19: - /* TODO: It must be IPv6 inside a X213 NSAP */ - default: - LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Resp: Unknown " - "transport layer address size %u\n", - item->transportLayerAddress->size); - return -1; - } - require_pdp_update = true; - } - - /* The TEI on the RNC side might have changed, too */ - if (item->iuTransportAssociation && - item->iuTransportAssociation->present == RANAP_IuTransportAssociation_PR_gTP_TEI && - item->iuTransportAssociation->choice.gTP_TEI.buf && - item->iuTransportAssociation->choice.gTP_TEI.size >= 4) { - uint32_t tei = osmo_load32be(item->iuTransportAssociation->choice.gTP_TEI.buf); - LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n", - pdp->lib->teid_own, tei); - pdp->lib->teid_own = tei; - require_pdp_update = true; - } - - if (require_pdp_update) - gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0); - - if (pdp->state != PDP_STATE_CR_CONF) { - send_act_pdp_cont_acc(pdp); - pdp->state = PDP_STATE_CR_CONF; - } - return 0; - -} -#endif - -/* Confirmation of a PDP Context Delete */ -static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause) -{ - struct sgsn_signal_data sig_data; - struct sgsn_pdp_ctx *pctx = cbp; - int rc = 0; - - LOGPDPCTXP(LOGL_INFO, pctx, "Received DELETE PDP CTX CONF, cause=%d(%s)\n", - cause, get_value_string(gtp_cause_strs, cause)); - - memset(&sig_data, 0, sizeof(sig_data)); - sig_data.pdp = pctx; - osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_DEACT, &sig_data); - - if (pctx->mm) { - if (pctx->mm->ran_type == MM_CTX_T_GERAN_Gb) { - /* Deactivate the SNDCP layer */ - sndcp_sm_deactivate_ind(&pctx->mm->gb.llme->lle[pctx->sapi], pctx->nsapi); - } else { -#ifdef BUILD_IU - /* Deactivate radio bearer */ - ranap_iu_rab_deact(pctx->mm->iu.ue_ctx, 1); -#else - return -ENOTSUP; -#endif - } - - /* Confirm deactivation of PDP context to MS */ - rc = gsm48_tx_gsm_deact_pdp_acc(pctx); - } else { - LOGPDPCTXP(LOGL_NOTICE, pctx, - "Not deactivating SNDCP layer since the MM context " - "is not available\n"); - } - - /* unlink the now non-existing library handle from the pdp - * context */ - pctx->lib = NULL; - - sgsn_pdp_ctx_free(pctx); - - return rc; -} - -/* Confirmation of an GTP ECHO request */ -static int echo_conf(struct pdp_t *pdp, void *cbp, int recovery) -{ - if (recovery < 0) { - LOGP(DGPRS, LOGL_NOTICE, "GTP Echo Request timed out\n"); - /* FIXME: if version == 1, retry with version 0 */ - } else { - DEBUGP(DGPRS, "GTP Rx Echo Response\n"); - } - return 0; -} - -/* Any message received by GGSN contains a recovery IE */ -static int cb_recovery(struct sockaddr_in *peer, uint8_t recovery) -{ - struct sgsn_ggsn_ctx *ggsn; - - ggsn = sgsn_ggsn_ctx_by_addr(&peer->sin_addr); - if (!ggsn) { - LOGP(DGPRS, LOGL_NOTICE, "Received Recovery IE for unknown GGSN\n"); - return -EINVAL; - } - - if (ggsn->remote_restart_ctr == -1) { - /* First received ECHO RESPONSE, note the restart ctr */ - ggsn->remote_restart_ctr = recovery; - } else if (ggsn->remote_restart_ctr != recovery) { - /* counter has changed (GGSN restart): release all PDP */ - LOGP(DGPRS, LOGL_NOTICE, "GGSN recovery (%u->%u), " - "releasing all PDP contexts\n", - ggsn->remote_restart_ctr, recovery); - ggsn->remote_restart_ctr = recovery; - drop_all_pdp_for_ggsn(ggsn); - } - return 0; -} - -/* libgtp callback for confirmations */ -static int cb_conf(int type, int cause, struct pdp_t *pdp, void *cbp) -{ - DEBUGP(DGPRS, "libgtp cb_conf(type=%d, cause=%d, pdp=%p, cbp=%p)\n", - type, cause, pdp, cbp); - - if (cause == EOF) - LOGP(DGPRS, LOGL_ERROR, "libgtp EOF (type=%u, pdp=%p, cbp=%p)\n", - type, pdp, cbp); - - switch (type) { - case GTP_ECHO_REQ: - /* libgtp hands us the RECOVERY number instead of a cause */ - return echo_conf(pdp, cbp, cause); - case GTP_CREATE_PDP_REQ: - return create_pdp_conf(pdp, cbp, cause); - case GTP_DELETE_PDP_REQ: - return delete_pdp_conf(pdp, cbp, cause); - default: - break; - } - return 0; -} - -/* Called whenever a PDP context is deleted for any reason */ -static int cb_delete_context(struct pdp_t *pdp) -{ - LOGP(DGPRS, LOGL_INFO, "PDP Context was deleted\n"); - return 0; -} - -/* Called when we receive a Version Not Supported message */ -static int cb_unsup_ind(struct sockaddr_in *peer) -{ - LOGP(DGPRS, LOGL_INFO, "GTP Version not supported Indication " - "from %s:%u\n", inet_ntoa(peer->sin_addr), - ntohs(peer->sin_port)); - return 0; -} - -/* Called when we receive a Supported Ext Headers Notification */ -static int cb_extheader_ind(struct sockaddr_in *peer) -{ - LOGP(DGPRS, LOGL_INFO, "GTP Supported Ext Headers Noficiation " - "from %s:%u\n", inet_ntoa(peer->sin_addr), - ntohs(peer->sin_port)); - return 0; -} - -/* Called whenever we recive a DATA packet */ -static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len) -{ - struct bssgp_paging_info pinfo; - struct sgsn_pdp_ctx *pdp; - struct sgsn_mm_ctx *mm; - struct msgb *msg; - uint8_t *ud; - - pdp = lib->priv; - if (!pdp) { - LOGP(DGPRS, LOGL_NOTICE, - "GTP DATA IND from GGSN for unknown PDP\n"); - return -EIO; - } - mm = pdp->mm; - if (!mm) { - LOGP(DGPRS, LOGL_ERROR, - "PDP context (address=%u) without MM context!\n", - pdp->address); - return -EIO; - } - - DEBUGP(DGPRS, "GTP DATA IND from GGSN for %s, length=%u\n", mm->imsi, - len); - - if (mm->ran_type == MM_CTX_T_UTRAN_Iu) { -#ifdef BUILD_IU - /* Ignore the packet for now and page the UE to get the RAB - * reestablished */ - ranap_iu_page_ps(mm->imsi, &mm->p_tmsi, mm->ra.lac, mm->ra.rac); - - return 0; -#else - return -ENOTSUP; -#endif - } - - msg = msgb_alloc_headroom(len+256, 128, "GTP->SNDCP"); - ud = msgb_put(msg, len); - memcpy(ud, packet, len); - - msgb_tlli(msg) = mm->gb.tlli; - msgb_bvci(msg) = mm->gb.bvci; - msgb_nsei(msg) = mm->gb.nsei; - - switch (mm->gmm_state) { - case GMM_REGISTERED_SUSPENDED: - /* initiate PS PAGING procedure */ - memset(&pinfo, 0, sizeof(pinfo)); - pinfo.mode = BSSGP_PAGING_PS; - pinfo.scope = BSSGP_PAGING_BVCI; - pinfo.bvci = mm->gb.bvci; - pinfo.imsi = mm->imsi; - pinfo.ptmsi = &mm->p_tmsi; - pinfo.drx_params = mm->drx_parms; - pinfo.qos[0] = 0; // FIXME - bssgp_tx_paging(mm->gb.nsei, 0, &pinfo); - rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PAGING_PS]); - /* FIXME: queue the packet we received from GTP */ - break; - case GMM_REGISTERED_NORMAL: - break; - default: - LOGP(DGPRS, LOGL_ERROR, "GTP DATA IND for TLLI %08X in state " - "%u\n", mm->gb.tlli, mm->gmm_state); - msgb_free(msg); - return -1; - } - - rate_ctr_inc(&pdp->ctrg->ctr[PDP_CTR_PKTS_UDATA_OUT]); - rate_ctr_add(&pdp->ctrg->ctr[PDP_CTR_BYTES_UDATA_OUT], len); - rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PKTS_UDATA_OUT]); - rate_ctr_add(&mm->ctrg->ctr[GMM_CTR_BYTES_UDATA_OUT], len); - - /* It is easier to have a global count */ - pdp->cdr_bytes_out += len; - - return sndcp_unitdata_req(msg, &mm->gb.llme->lle[pdp->sapi], - pdp->nsapi, mm); -} - -/* Called by SNDCP when it has received/re-assembled a N-PDU */ -int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi, - struct msgb *msg, uint32_t npdu_len, uint8_t *npdu) -{ - struct sgsn_mm_ctx *mmctx; - struct sgsn_pdp_ctx *pdp; - - /* look-up the MM context for this message */ - mmctx = sgsn_mm_ctx_by_tlli(tlli, ra_id); - if (!mmctx) { - LOGP(DGPRS, LOGL_ERROR, - "Cannot find MM CTX for TLLI %08x\n", tlli); - return -EIO; - } - /* look-up the PDP context for this message */ - pdp = sgsn_pdp_ctx_by_nsapi(mmctx, nsapi); - if (!pdp) { - LOGP(DGPRS, LOGL_ERROR, "Cannot find PDP CTX for " - "TLLI=%08x, NSAPI=%u\n", tlli, nsapi); - return -EIO; - } - if (!pdp->lib) { - LOGP(DGPRS, LOGL_ERROR, "PDP CTX without libgtp\n"); - return -EIO; - } - - rate_ctr_inc(&pdp->ctrg->ctr[PDP_CTR_PKTS_UDATA_IN]); - rate_ctr_add(&pdp->ctrg->ctr[PDP_CTR_BYTES_UDATA_IN], npdu_len); - rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_UDATA_IN]); - rate_ctr_add(&mmctx->ctrg->ctr[GMM_CTR_BYTES_UDATA_IN], npdu_len); - - /* It is easier to have a global count */ - pdp->cdr_bytes_in += npdu_len; - - return gtp_data_req(pdp->ggsn->gsn, pdp->lib, npdu, npdu_len); -} - -/* libgtp select loop integration */ -static int sgsn_gtp_fd_cb(struct osmo_fd *fd, unsigned int what) -{ - struct sgsn_instance *sgi = fd->data; - int rc; - - if (!(what & BSC_FD_READ)) - return 0; - - switch (fd->priv_nr) { - case 0: - rc = gtp_decaps0(sgi->gsn); - break; - case 1: - rc = gtp_decaps1c(sgi->gsn); - break; - case 2: - rc = gtp_decaps1u(sgi->gsn); - break; - default: - rc = -EINVAL; - break; - } - return rc; -} - -static void sgsn_gtp_tmr_start(struct sgsn_instance *sgi) -{ - struct timeval next; - - /* Retrieve next retransmission as struct timeval */ - gtp_retranstimeout(sgi->gsn, &next); - - /* re-schedule the timer */ - osmo_timer_schedule(&sgi->gtp_timer, next.tv_sec, next.tv_usec/1000); -} - -/* timer callback for libgtp retransmissions and ping */ -static void sgsn_gtp_tmr_cb(void *data) -{ - struct sgsn_instance *sgi = data; - - /* Do all the retransmissions as needed */ - gtp_retrans(sgi->gsn); - - sgsn_gtp_tmr_start(sgi); -} - -int sgsn_gtp_init(struct sgsn_instance *sgi) -{ - int rc; - struct gsn_t *gsn; - - rc = gtp_new(&sgi->gsn, sgi->cfg.gtp_statedir, - &sgi->cfg.gtp_listenaddr.sin_addr, GTP_MODE_SGSN); - if (rc) { - LOGP(DGPRS, LOGL_ERROR, "Failed to create GTP: %d\n", rc); - return rc; - } - gsn = sgi->gsn; - - sgi->gtp_fd0.fd = gsn->fd0; - sgi->gtp_fd0.priv_nr = 0; - sgi->gtp_fd0.data = sgi; - sgi->gtp_fd0.when = BSC_FD_READ; - sgi->gtp_fd0.cb = sgsn_gtp_fd_cb; - rc = osmo_fd_register(&sgi->gtp_fd0); - if (rc < 0) - return rc; - - sgi->gtp_fd1c.fd = gsn->fd1c; - sgi->gtp_fd1c.priv_nr = 1; - sgi->gtp_fd1c.data = sgi; - sgi->gtp_fd1c.when = BSC_FD_READ; - sgi->gtp_fd1c.cb = sgsn_gtp_fd_cb; - rc = osmo_fd_register(&sgi->gtp_fd1c); - if (rc < 0) { - osmo_fd_unregister(&sgi->gtp_fd0); - return rc; - } - - sgi->gtp_fd1u.fd = gsn->fd1u; - sgi->gtp_fd1u.priv_nr = 2; - sgi->gtp_fd1u.data = sgi; - sgi->gtp_fd1u.when = BSC_FD_READ; - sgi->gtp_fd1u.cb = sgsn_gtp_fd_cb; - rc = osmo_fd_register(&sgi->gtp_fd1u); - if (rc < 0) { - osmo_fd_unregister(&sgi->gtp_fd0); - osmo_fd_unregister(&sgi->gtp_fd1c); - return rc; - } - - /* Start GTP re-transmission timer */ - osmo_timer_setup(&sgi->gtp_timer, sgsn_gtp_tmr_cb, sgi); - sgsn_gtp_tmr_start(sgi); - - /* Register callbackcs with libgtp */ - gtp_set_cb_delete_context(gsn, cb_delete_context); - gtp_set_cb_conf(gsn, cb_conf); - gtp_set_cb_recovery(gsn, cb_recovery); - gtp_set_cb_data_ind(gsn, cb_data_ind); - gtp_set_cb_unsup_ind(gsn, cb_unsup_ind); - gtp_set_cb_extheader_ind(gsn, cb_extheader_ind); - - return 0; -} diff --git a/src/gprs/sgsn_main.c b/src/gprs/sgsn_main.c deleted file mode 100644 index 25ee632cc..000000000 --- a/src/gprs/sgsn_main.c +++ /dev/null @@ -1,476 +0,0 @@ -/* GPRS SGSN Implementation */ - -/* (C) 2010 by Harald Welte - * (C) 2010 by On-Waves - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#include "../../bscconfig.h" - -#if BUILD_IU -#include -#endif - -#define _GNU_SOURCE -#include - -void *tall_bsc_ctx; - -struct gprs_ns_inst *sgsn_nsi; -static int daemonize = 0; -const char *openbsc_copyright = - "Copyright (C) 2010 Harald Welte and On-Waves\r\n" - "License AGPLv3+: GNU AGPL version 3 or later \r\n" - "This is free software: you are free to change and redistribute it.\r\n" - "There is NO WARRANTY, to the extent permitted by law.\r\n"; - -static struct sgsn_instance sgsn_inst = { - .config_file = "osmo_sgsn.cfg", - .cfg = { - .gtp_statedir = "./", - .auth_policy = SGSN_AUTH_POLICY_CLOSED, - .gsup_server_port = OSMO_GSUP_PORT, - }, -}; -struct sgsn_instance *sgsn = &sgsn_inst; - -/* call-back function for the NS protocol */ -static int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, - struct msgb *msg, uint16_t bvci) -{ - int rc = 0; - - switch (event) { - case GPRS_NS_EVT_UNIT_DATA: - /* hand the message into the BSSGP implementation */ - rc = bssgp_rcvmsg(msg); - break; - default: - LOGP(DGPRS, LOGL_ERROR, "SGSN: Unknown event %u from NS\n", event); - if (msg) - msgb_free(msg); - rc = -EIO; - break; - } - return rc; -} - -/* call-back function for the BSSGP protocol */ -int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) -{ - struct osmo_bssgp_prim *bp; - bp = container_of(oph, struct osmo_bssgp_prim, oph); - - switch (oph->sap) { - case SAP_BSSGP_LL: - switch (oph->primitive) { - case PRIM_BSSGP_UL_UD: - return gprs_llc_rcvmsg(oph->msg, bp->tp); - } - break; - case SAP_BSSGP_GMM: - switch (oph->primitive) { - case PRIM_BSSGP_GMM_SUSPEND: - return gprs_gmm_rx_suspend(bp->ra_id, bp->tlli); - case PRIM_BSSGP_GMM_RESUME: - return gprs_gmm_rx_resume(bp->ra_id, bp->tlli, - bp->u.resume.suspend_ref); - } - break; - case SAP_BSSGP_NM: - break; - } - return 0; -} - -static void signal_handler(int signal) -{ - fprintf(stdout, "signal %u received\n", signal); - - switch (signal) { - case SIGINT: - case SIGTERM: - osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); - sleep(1); - exit(0); - break; - case SIGABRT: - /* in case of abort, we want to obtain a talloc report - * and then return to the caller, who will abort the process */ - case SIGUSR1: - talloc_report(tall_vty_ctx, stderr); - talloc_report_full(tall_bsc_ctx, stderr); - break; - case SIGUSR2: - talloc_report_full(tall_vty_ctx, stderr); - break; - default: - break; - } -} - -/* NSI that BSSGP uses when transmitting on NS */ -extern struct gprs_ns_inst *bssgp_nsi; - -extern int bsc_vty_go_parent(struct vty *vty); - -static struct vty_app_info vty_info = { - .name = "OsmoSGSN", - .version = PACKAGE_VERSION, - .go_parent_cb = bsc_vty_go_parent, - .is_config_node = bsc_vty_is_config_node, -}; - -static void print_help(void) -{ - printf("Some useful help...\n"); - printf(" -h --help\tthis text\n"); - printf(" -D --daemonize\tFork the process into a background daemon\n"); - printf(" -d option --debug\tenable Debugging\n"); - printf(" -s --disable-color\n"); - printf(" -c --config-file\tThe config file to use [%s]\n", sgsn->config_file); - printf(" -e --log-level number\tSet a global log level\n"); -} - -static void handle_options(int argc, char **argv) -{ - while (1) { - int option_index = 0, c; - static struct option long_options[] = { - {"help", 0, 0, 'h'}, - {"debug", 1, 0, 'd'}, - {"daemonize", 0, 0, 'D'}, - {"config-file", 1, 0, 'c'}, - {"disable-color", 0, 0, 's'}, - {"timestamp", 0, 0, 'T'}, - { "version", 0, 0, 'V' }, - {"log-level", 1, 0, 'e'}, - {NULL, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "hd:Dc:sTVe:", - long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - //print_usage(); - print_help(); - exit(0); - case 's': - log_set_use_color(osmo_stderr_target, 0); - break; - case 'd': - log_parse_category_mask(osmo_stderr_target, optarg); - break; - case 'D': - daemonize = 1; - break; - case 'c': - sgsn_inst.config_file = strdup(optarg); - break; - case 'T': - log_set_print_timestamp(osmo_stderr_target, 1); - break; - case 'V': - print_version(1); - exit(0); - break; - case 'e': - log_set_log_level(osmo_stderr_target, atoi(optarg)); - break; - default: - /* ignore */ - break; - } - } -} - -/* default categories */ -static struct log_info_cat gprs_categories[] = { - [DMM] = { - .name = "DMM", - .description = "Layer3 Mobility Management (MM)", - .color = "\033[1;33m", - .enabled = 1, .loglevel = LOGL_NOTICE, - }, - [DPAG] = { - .name = "DPAG", - .description = "Paging Subsystem", - .color = "\033[1;38m", - .enabled = 1, .loglevel = LOGL_NOTICE, - }, - [DMEAS] = { - .name = "DMEAS", - .description = "Radio Measurement Processing", - .enabled = 0, .loglevel = LOGL_NOTICE, - }, - [DREF] = { - .name = "DREF", - .description = "Reference Counting", - .enabled = 0, .loglevel = LOGL_NOTICE, - }, - [DGPRS] = { - .name = "DGPRS", - .description = "GPRS Packet Service", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DNS] = { - .name = "DNS", - .description = "GPRS Network Service (NS)", - .enabled = 1, .loglevel = LOGL_INFO, - }, - [DBSSGP] = { - .name = "DBSSGP", - .description = "GPRS BSS Gateway Protocol (BSSGP)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DLLC] = { - .name = "DLLC", - .description = "GPRS Logical Link Control Protocol (LLC)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DSNDCP] = { - .name = "DSNDCP", - .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DRANAP] = { - .name = "DRANAP", - .description = "RAN Application Part (RANAP)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DSUA] = { - .name = "DSUA", - .description = "SCCP User Adaptation (SUA)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DSLHC] = { - .name = "DSLHC", - .description = "RFC1144 TCP/IP Header compression (SLHC)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DV42BIS] = { - .name = "DV42BIS", - .description = "V.42bis data compression (SNDCP)", - .enabled = 1, .loglevel = LOGL_DEBUG, - } -}; - -static const struct log_info gprs_log_info = { - .filter_fn = gprs_log_filter_fn, - .cat = gprs_categories, - .num_cat = ARRAY_SIZE(gprs_categories), -}; - -int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum ranap_iu_event_type type, void *data); - -int main(int argc, char **argv) -{ - struct ctrl_handle *ctrl; - struct gsm_network dummy_network; - struct osmo_sccp_instance *sccp; - int rc; - - srand(time(NULL)); - tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn"); - msgb_talloc_ctx_init(tall_bsc_ctx, 0); - - signal(SIGINT, &signal_handler); - signal(SIGTERM, &signal_handler); - signal(SIGABRT, &signal_handler); - signal(SIGUSR1, &signal_handler); - signal(SIGUSR2, &signal_handler); - - osmo_init_ignore_signals(); - osmo_init_logging(&gprs_log_info); - osmo_stats_init(tall_bsc_ctx); - - vty_info.copyright = openbsc_copyright; - vty_init(&vty_info); - logging_vty_add_cmds(NULL); - osmo_stats_vty_add_cmds(&gprs_log_info); - sgsn_vty_init(&sgsn_inst.cfg); - ctrl_vty_init(tall_bsc_ctx); - osmo_ss7_init(); - - handle_options(argc, argv); - - rate_ctr_init(tall_bsc_ctx); - - gprs_ns_set_log_ss(DNS); - bssgp_set_log_ss(DBSSGP); - - sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb, tall_bsc_ctx); - if (!sgsn_nsi) { - LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n"); - exit(1); - } - bssgp_nsi = sgsn_inst.cfg.nsi = sgsn_nsi; - - gprs_llc_init("/usr/local/lib/osmocom/crypt/"); - sgsn_rate_ctr_init(); - sgsn_inst_init(); - - gprs_ns_vty_init(bssgp_nsi); - bssgp_vty_init(); - gprs_llc_vty_init(); - gprs_sndcp_vty_init(); - sgsn_auth_init(); - sgsn_cdr_init(&sgsn_inst); - /* FIXME: register signal handler for SS_L_NS */ - - rc = sgsn_parse_config(sgsn_inst.config_file); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Error in config file\n"); - exit(2); - } - - /* start telnet after reading config for vty_get_bind_addr() */ - rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network, - vty_get_bind_addr(), OSMO_VTY_PORT_SGSN); - if (rc < 0) - exit(1); - - /* start control interface after reading config for - * ctrl_vty_get_bind_addr() */ - ctrl = sgsn_controlif_setup(NULL, ctrl_vty_get_bind_addr(), - OSMO_CTRL_PORT_SGSN); - if (!ctrl) { - LOGP(DGPRS, LOGL_ERROR, "Failed to create CTRL interface.\n"); - exit(1); - } - - if (sgsn_ctrl_cmds_install() != 0) { - LOGP(DGPRS, LOGL_ERROR, "Failed to install CTRL commands.\n"); - exit(1); - } - - - rc = sgsn_gtp_init(&sgsn_inst); - if (rc) { - LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on GTP socket\n"); - exit(2); - } - - rc = gprs_subscr_init(&sgsn_inst); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Cannot set up subscriber management\n"); - exit(2); - } - - rc = gprs_ns_nsip_listen(sgsn_nsi); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on NSIP socket\n"); - exit(2); - } - - rc = gprs_ns_frgre_listen(sgsn_nsi); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen GRE " - "socket. Do you have CAP_NET_RAW?\n"); - exit(2); - } - - if (sgsn->cfg.dynamic_lookup) { - if (sgsn_ares_init(sgsn) != 0) { - LOGP(DGPRS, LOGL_FATAL, - "Failed to initialize c-ares(%d)\n", rc); - exit(4); - } - } - -#ifdef BUILD_IU - sccp = osmo_sccp_simple_client(tall_bsc_ctx, "OsmoSGSN", - 2 /* FIXME: configurable */, - OSMO_SS7_ASP_PROT_M3UA, 0, - "127.0.0.4" /* FIXME: configurable */, - M3UA_PORT, - "127.0.0.1" /* FIXME: configurable */); - if (!sccp) { - printf("Setting up SCCP client failed.\n"); - return 8; - } - - ranap_iu_init(tall_bsc_ctx, DRANAP, "OsmoSGSN-IuPS", sccp, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event); -#endif - - if (daemonize) { - rc = osmo_daemonize(); - if (rc < 0) { - perror("Error during daemonize"); - exit(1); - } - } - - while (1) { - rc = osmo_select_main(0); - if (rc < 0) - exit(3); - } - - /* not reached */ - exit(0); -} diff --git a/src/gprs/sgsn_vty.c b/src/gprs/sgsn_vty.c deleted file mode 100644 index 3a5b2ca64..000000000 --- a/src/gprs/sgsn_vty.c +++ /dev/null @@ -1,1329 +0,0 @@ -/* - * (C) 2010-2016 by Harald Welte - * (C) 2010 by On-Waves - * (C) 2015 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "../../bscconfig.h" - -#ifdef BUILD_IU -#include -#endif - -static struct sgsn_config *g_cfg = NULL; - -const struct value_string sgsn_auth_pol_strs[] = { - { SGSN_AUTH_POLICY_OPEN, "accept-all" }, - { SGSN_AUTH_POLICY_CLOSED, "closed" }, - { SGSN_AUTH_POLICY_ACL_ONLY, "acl-only" }, - { SGSN_AUTH_POLICY_REMOTE, "remote" }, - { 0, NULL } -}; - -/* Section 11.2.2 / Table 11.3a GPRS Mobility management timers – MS side */ -#define GSM0408_T3312_SECS (10*60) /* periodic RAU interval, default 54min */ - -/* Section 11.2.2 / Table 11.4 MM timers netwokr side */ -#define GSM0408_T3322_SECS 6 /* DETACH_REQ -> DETACH_ACC */ -#define GSM0408_T3350_SECS 6 /* waiting for ATT/RAU/TMSI COMPL */ -#define GSM0408_T3360_SECS 6 /* waiting for AUTH/CIPH RESP */ -#define GSM0408_T3370_SECS 6 /* waiting for ID RESP */ - -/* Section 11.2.2 / Table 11.4a MM timers network side */ -#define GSM0408_T3313_SECS 30 /* waiting for paging response */ -#define GSM0408_T3314_SECS 44 /* force to STBY on expiry, Ready timer */ -#define GSM0408_T3316_SECS 44 - -/* Section 11.3 / Table 11.2d Timers of Session Management - network side */ -#define GSM0408_T3385_SECS 8 /* wait for ACT PDP CTX REQ */ -#define GSM0408_T3386_SECS 8 /* wait for MODIFY PDP CTX ACK */ -#define GSM0408_T3395_SECS 8 /* wait for DEACT PDP CTX ACK */ -#define GSM0408_T3397_SECS 8 /* wait for DEACT AA PDP CTX ACK */ - -#define DECLARE_TIMER(number, doc) \ - DEFUN(cfg_sgsn_T##number, \ - cfg_sgsn_T##number##_cmd, \ - "timer t" #number " <0-65535>", \ - "Configure GPRS Timers\n" \ - doc "\nTimer Value in seconds\n") \ -{ \ - int value = atoi(argv[0]); \ - \ - if (value < 0 || value > 65535) { \ - vty_out(vty, "Timer value %s out of range.%s", \ - argv[0], VTY_NEWLINE); \ - return CMD_WARNING; \ - } \ - \ - g_cfg->timers.T##number = value; \ - return CMD_SUCCESS; \ -} - -DECLARE_TIMER(3312, "Periodic RA Update timer (s)") -DECLARE_TIMER(3322, "Detach request -> accept timer (s)") -DECLARE_TIMER(3350, "Waiting for ATT/RAU/TMSI_COMPL timer (s)") -DECLARE_TIMER(3360, "Waiting for AUTH/CIPH response timer (s)") -DECLARE_TIMER(3370, "Waiting for IDENTITY response timer (s)") - -DECLARE_TIMER(3313, "Waiting for paging response timer (s)") -DECLARE_TIMER(3314, "Force to STANDBY on expiry timer (s)") -DECLARE_TIMER(3316, "AA-Ready timer (s)") - -DECLARE_TIMER(3385, "Wait for ACT PDP CTX REQ timer (s)") -DECLARE_TIMER(3386, "Wait for MODIFY PDP CTX ACK timer (s)") -DECLARE_TIMER(3395, "Wait for DEACT PDP CTX ACK timer (s)") -DECLARE_TIMER(3397, "Wait for DEACT AA PDP CTX ACK timer (s)") - - -#define GSM48_MAX_APN_LEN 102 /* 10.5.6.1 */ -/** Copy apn to a static buffer, replacing the length octets in apn_enc with '.' - * and terminating with a '\0'. Return the static buffer. - * len: the length of the encoded APN (which has no terminating zero). - */ -static char *gprs_apn2str(uint8_t *apn, unsigned int len) -{ - static char apnbuf[GSM48_MAX_APN_LEN+1]; - - if (!apn) - return ""; - osmo_apn_to_str(apnbuf, apn, len); - - return apnbuf+1; -} - -char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len) -{ - static char str[INET6_ADDRSTRLEN + 10]; - - if (!pdpa || len < 2) - return "none"; - - switch (pdpa[0] & 0x0f) { - case PDP_TYPE_ORG_IETF: - switch (pdpa[1]) { - case PDP_TYPE_N_IETF_IPv4: - if (len < 2 + 4) - break; - strcpy(str, "IPv4 "); - inet_ntop(AF_INET, pdpa+2, str+5, sizeof(str)-5); - return str; - case PDP_TYPE_N_IETF_IPv6: - if (len < 2 + 8) - break; - strcpy(str, "IPv6 "); - inet_ntop(AF_INET6, pdpa+2, str+5, sizeof(str)-5); - return str; - default: - break; - } - break; - case PDP_TYPE_ORG_ETSI: - if (pdpa[1] == PDP_TYPE_N_ETSI_PPP) - return "PPP"; - break; - default: - break; - } - - return "invalid"; -} - -static struct cmd_node sgsn_node = { - SGSN_NODE, - "%s(config-sgsn)# ", - 1, -}; - -static int config_write_sgsn(struct vty *vty) -{ - struct sgsn_ggsn_ctx *gctx; - struct imsi_acl_entry *acl; - struct apn_ctx *actx; - struct ares_addr_node *server; - - vty_out(vty, "sgsn%s", VTY_NEWLINE); - - vty_out(vty, " gtp local-ip %s%s", - inet_ntoa(g_cfg->gtp_listenaddr.sin_addr), VTY_NEWLINE); - - llist_for_each_entry(gctx, &sgsn_ggsn_ctxts, list) { - if (gctx->id == UINT32_MAX) - continue; - - vty_out(vty, " ggsn %u remote-ip %s%s", gctx->id, - inet_ntoa(gctx->remote_addr), VTY_NEWLINE); - vty_out(vty, " ggsn %u gtp-version %u%s", gctx->id, - gctx->gtp_version, VTY_NEWLINE); - } - - if (sgsn->cfg.dynamic_lookup) - vty_out(vty, " ggsn dynamic%s", VTY_NEWLINE); - - for (server = sgsn->ares_servers; server; server = server->next) - vty_out(vty, " grx-dns-add %s%s", inet_ntoa(server->addr.addr4), VTY_NEWLINE); - - if (g_cfg->cipher != GPRS_ALGO_GEA0) - vty_out(vty, " encryption %s%s", - get_value_string(gprs_cipher_names, g_cfg->cipher), - VTY_NEWLINE); - if (g_cfg->gsup_server_addr.sin_addr.s_addr) - vty_out(vty, " gsup remote-ip %s%s", - inet_ntoa(g_cfg->gsup_server_addr.sin_addr), VTY_NEWLINE); - if (g_cfg->gsup_server_port) - vty_out(vty, " gsup remote-port %d%s", - g_cfg->gsup_server_port, VTY_NEWLINE); - vty_out(vty, " auth-policy %s%s", - get_value_string(sgsn_auth_pol_strs, g_cfg->auth_policy), - VTY_NEWLINE); - - vty_out(vty, " gsup oap-id %d%s", - (int)g_cfg->oap.client_id, VTY_NEWLINE); - if (g_cfg->oap.secret_k_present != 0) - vty_out(vty, " gsup oap-k %s%s", - osmo_hexdump_nospc(g_cfg->oap.secret_k, sizeof(g_cfg->oap.secret_k)), - VTY_NEWLINE); - if (g_cfg->oap.secret_opc_present != 0) - vty_out(vty, " gsup oap-opc %s%s", - osmo_hexdump_nospc(g_cfg->oap.secret_opc, sizeof(g_cfg->oap.secret_opc)), - VTY_NEWLINE); - - llist_for_each_entry(acl, &g_cfg->imsi_acl, list) - vty_out(vty, " imsi-acl add %s%s", acl->imsi, VTY_NEWLINE); - - if (llist_empty(&sgsn_apn_ctxts)) - vty_out(vty, " ! apn * ggsn 0%s", VTY_NEWLINE); - llist_for_each_entry(actx, &sgsn_apn_ctxts, list) { - if (strlen(actx->imsi_prefix) > 0) - vty_out(vty, " apn %s imsi-prefix %s ggsn %u%s", - actx->name, actx->imsi_prefix, actx->ggsn->id, - VTY_NEWLINE); - else - vty_out(vty, " apn %s ggsn %u%s", actx->name, - actx->ggsn->id, VTY_NEWLINE); - } - - if (g_cfg->cdr.filename) - vty_out(vty, " cdr filename %s%s", g_cfg->cdr.filename, VTY_NEWLINE); - else - vty_out(vty, " no cdr filename%s", VTY_NEWLINE); - vty_out(vty, " cdr interval %d%s", g_cfg->cdr.interval, VTY_NEWLINE); - - vty_out(vty, " timer t3312 %d%s", g_cfg->timers.T3312, VTY_NEWLINE); - vty_out(vty, " timer t3322 %d%s", g_cfg->timers.T3322, VTY_NEWLINE); - vty_out(vty, " timer t3350 %d%s", g_cfg->timers.T3350, VTY_NEWLINE); - vty_out(vty, " timer t3360 %d%s", g_cfg->timers.T3360, VTY_NEWLINE); - vty_out(vty, " timer t3370 %d%s", g_cfg->timers.T3370, VTY_NEWLINE); - vty_out(vty, " timer t3313 %d%s", g_cfg->timers.T3313, VTY_NEWLINE); - vty_out(vty, " timer t3314 %d%s", g_cfg->timers.T3314, VTY_NEWLINE); - vty_out(vty, " timer t3316 %d%s", g_cfg->timers.T3316, VTY_NEWLINE); - vty_out(vty, " timer t3385 %d%s", g_cfg->timers.T3385, VTY_NEWLINE); - vty_out(vty, " timer t3386 %d%s", g_cfg->timers.T3386, VTY_NEWLINE); - vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE); - vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE); - - if (g_cfg->pcomp_rfc1144.active) { - vty_out(vty, " compression rfc1144 active slots %d%s", - g_cfg->pcomp_rfc1144.s01 + 1, VTY_NEWLINE); - } else if (g_cfg->pcomp_rfc1144.passive) { - vty_out(vty, " compression rfc1144 passive%s", VTY_NEWLINE); - } else - vty_out(vty, " no compression rfc1144%s", VTY_NEWLINE); - - if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 1) { - vty_out(vty, - " compression v42bis active direction sgsn codewords %d strlen %d%s", - g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, - VTY_NEWLINE); - } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 2) { - vty_out(vty, - " compression v42bis active direction ms codewords %d strlen %d%s", - g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, - VTY_NEWLINE); - } else if (g_cfg->dcomp_v42bis.active && g_cfg->dcomp_v42bis.p0 == 3) { - vty_out(vty, - " compression v42bis active direction both codewords %d strlen %d%s", - g_cfg->dcomp_v42bis.p1, g_cfg->dcomp_v42bis.p2, - VTY_NEWLINE); - } else if (g_cfg->dcomp_v42bis.passive) { - vty_out(vty, " compression v42bis passive%s", VTY_NEWLINE); - } else - vty_out(vty, " no compression v42bis%s", VTY_NEWLINE); - -#ifdef BUILD_IU - ranap_iu_vty_config_write(vty, " "); -#endif - - return CMD_SUCCESS; -} - -#define SGSN_STR "Configure the SGSN\n" -#define GGSN_STR "Configure the GGSN information\n" - -DEFUN(cfg_sgsn, cfg_sgsn_cmd, - "sgsn", - SGSN_STR) -{ - vty->node = SGSN_NODE; - return CMD_SUCCESS; -} - -DEFUN(cfg_sgsn_bind_addr, cfg_sgsn_bind_addr_cmd, - "gtp local-ip A.B.C.D", - "GTP Parameters\n" - "Set the IP address for the local GTP bind\n" - "IPv4 Address\n") -{ - inet_aton(argv[0], &g_cfg->gtp_listenaddr.sin_addr); - - return CMD_SUCCESS; -} - -DEFUN(cfg_ggsn_remote_ip, cfg_ggsn_remote_ip_cmd, - "ggsn <0-255> remote-ip A.B.C.D", - GGSN_STR "GGSN Number\n" IP_STR "IPv4 Address\n") -{ - uint32_t id = atoi(argv[0]); - struct sgsn_ggsn_ctx *ggc = sgsn_ggsn_ctx_find_alloc(id); - - inet_aton(argv[1], &ggc->remote_addr); - - return CMD_SUCCESS; -} - -#if 0 -DEFUN(cfg_ggsn_remote_port, cfg_ggsn_remote_port_cmd, - "ggsn <0-255> remote-port <0-65535>", - "") -{ - uint32_t id = atoi(argv[0]); - struct sgsn_ggsn_ctx *ggc = sgsn_ggsn_ctx_find_alloc(id); - uint16_t port = atoi(argv[1]); - -} -#endif - -DEFUN(cfg_ggsn_gtp_version, cfg_ggsn_gtp_version_cmd, - "ggsn <0-255> gtp-version (0|1)", - GGSN_STR "GGSN Number\n" "GTP Version\n" - "Version 0\n" "Version 1\n") -{ - uint32_t id = atoi(argv[0]); - struct sgsn_ggsn_ctx *ggc = sgsn_ggsn_ctx_find_alloc(id); - - if (atoi(argv[1])) - ggc->gtp_version = 1; - else - ggc->gtp_version = 0; - - return CMD_SUCCESS; -} - -DEFUN(cfg_ggsn_dynamic_lookup, cfg_ggsn_dynamic_lookup_cmd, - "ggsn dynamic", - GGSN_STR "Enable dynamic GRX based look-up (requires restart)\n") -{ - sgsn->cfg.dynamic_lookup = 1; - return CMD_SUCCESS; -} - -DEFUN(cfg_grx_ggsn, cfg_grx_ggsn_cmd, - "grx-dns-add A.B.C.D", - "Add DNS server\nIPv4 address\n") -{ - struct ares_addr_node *node = talloc_zero(tall_bsc_ctx, struct ares_addr_node); - node->family = AF_INET; - inet_aton(argv[0], &node->addr.addr4); - - node->next = sgsn->ares_servers; - sgsn->ares_servers = node; - return CMD_SUCCESS; -} - -#define APN_STR "Configure the information per APN\n" -#define APN_GW_STR "The APN gateway name optionally prefixed by '*' (wildcard)\n" - -static int add_apn_ggsn_mapping(struct vty *vty, const char *apn_str, - const char *imsi_prefix, int ggsn_id) -{ - struct apn_ctx *actx; - struct sgsn_ggsn_ctx *ggsn; - - ggsn = sgsn_ggsn_ctx_by_id(ggsn_id); - if (ggsn == NULL) { - vty_out(vty, "%% a GGSN with id %d has not been defined%s", - ggsn_id, VTY_NEWLINE); - return CMD_WARNING; - } - - actx = sgsn_apn_ctx_find_alloc(apn_str, imsi_prefix); - if (!actx) { - vty_out(vty, "%% unable to create APN context for %s/%s%s", - apn_str, imsi_prefix, VTY_NEWLINE); - return CMD_WARNING; - } - - actx->ggsn = ggsn; - - return CMD_SUCCESS; -} - -DEFUN(cfg_apn_ggsn, cfg_apn_ggsn_cmd, - "apn APNAME ggsn <0-255>", - APN_STR APN_GW_STR - "Select the GGSN to use when the APN gateway prefix matches\n" - "The GGSN id") -{ - - return add_apn_ggsn_mapping(vty, argv[0], "", atoi(argv[1])); -} - -DEFUN(cfg_apn_imsi_ggsn, cfg_apn_imsi_ggsn_cmd, - "apn APNAME imsi-prefix IMSIPRE ggsn <0-255>", - APN_STR APN_GW_STR - "Restrict rule to a certain IMSI prefix\n" - "An IMSI prefix\n" - "Select the GGSN to use when APN gateway and IMSI prefix match\n" - "The GGSN id") -{ - - return add_apn_ggsn_mapping(vty, argv[0], argv[1], atoi(argv[2])); -} - -const struct value_string gprs_mm_st_strs[] = { - { GMM_DEREGISTERED, "DEREGISTERED" }, - { GMM_COMMON_PROC_INIT, "COMMON PROCEDURE (INIT)" }, - { GMM_REGISTERED_NORMAL, "REGISTERED (NORMAL)" }, - { GMM_REGISTERED_SUSPENDED, "REGISTERED (SUSPENDED)" }, - { GMM_DEREGISTERED_INIT, "DEREGISTERED (INIT)" }, - { 0, NULL } -}; - -static char *gtp_ntoa(struct ul16_t *ul) -{ - if (ul->l == 4) { - struct in_addr *ia = (struct in_addr *) ul; - return inet_ntoa(*ia); - } else { - return "UNKNOWN"; - } -} - -static void vty_dump_pdp(struct vty *vty, const char *pfx, - struct sgsn_pdp_ctx *pdp) -{ - const char *imsi = pdp->mm ? pdp->mm->imsi : "(detaching)"; - vty_out(vty, "%sPDP Context IMSI: %s, SAPI: %u, NSAPI: %u, TI: %u%s", - pfx, imsi, pdp->sapi, pdp->nsapi, pdp->ti, VTY_NEWLINE); - if (pdp->lib) { - vty_out(vty, "%s APN: %s%s", pfx, - gprs_apn2str(pdp->lib->apn_use.v, pdp->lib->apn_use.l), - VTY_NEWLINE); - vty_out(vty, "%s PDP Address: %s%s", pfx, - gprs_pdpaddr2str(pdp->lib->eua.v, pdp->lib->eua.l), - VTY_NEWLINE); - vty_out(vty, "%s GTP Local Control(%s / TEIC: 0x%08x) ", pfx, - gtp_ntoa(&pdp->lib->gsnlc), pdp->lib->teic_own); - vty_out(vty, "Data(%s / TEID: 0x%08x)%s", - gtp_ntoa(&pdp->lib->gsnlu), pdp->lib->teid_own, VTY_NEWLINE); - vty_out(vty, "%s GTP Remote Control(%s / TEIC: 0x%08x) ", pfx, - gtp_ntoa(&pdp->lib->gsnrc), pdp->lib->teic_gn); - vty_out(vty, "Data(%s / TEID: 0x%08x)%s", - gtp_ntoa(&pdp->lib->gsnru), pdp->lib->teid_gn, VTY_NEWLINE); - } - - vty_out_rate_ctr_group(vty, " ", pdp->ctrg); -} - -static void vty_dump_mmctx(struct vty *vty, const char *pfx, - struct sgsn_mm_ctx *mm, int pdp) -{ - vty_out(vty, "%sMM Context for IMSI %s, IMEI %s, P-TMSI %08x%s", - pfx, mm->imsi, mm->imei, mm->p_tmsi, VTY_NEWLINE); - vty_out(vty, "%s MSISDN: %s, TLLI: %08x%s HLR: %s", - pfx, mm->msisdn, mm->gb.tlli, mm->hlr, VTY_NEWLINE); - vty_out(vty, "%s MM State: %s, Routeing Area: %u-%u-%u-%u, " - "Cell ID: %u%s", pfx, - get_value_string(gprs_mm_st_strs, mm->gmm_state), - mm->ra.mcc, mm->ra.mnc, mm->ra.lac, mm->ra.rac, - mm->gb.cell_id, VTY_NEWLINE); - - vty_out_rate_ctr_group(vty, " ", mm->ctrg); - - if (pdp) { - struct sgsn_pdp_ctx *pdp; - - llist_for_each_entry(pdp, &mm->pdp_list, list) - vty_dump_pdp(vty, " ", pdp); - } -} - -DEFUN(show_sgsn, show_sgsn_cmd, "show sgsn", - SHOW_STR "Display information about the SGSN") -{ - if (sgsn->gsup_client) { - struct ipa_client_conn *link = sgsn->gsup_client->link; - vty_out(vty, - " Remote authorization: %sconnected to %s:%d via GSUP%s", - sgsn->gsup_client->is_connected ? "" : "not ", - link->addr, link->port, - VTY_NEWLINE); - } - /* FIXME: statistics */ - return CMD_SUCCESS; -} - -#define MMCTX_STR "MM Context\n" -#define INCLUDE_PDP_STR "Include PDP Context Information\n" - -#if 0 -DEFUN(show_mmctx_tlli, show_mmctx_tlli_cmd, - "show mm-context tlli HEX [pdp]", - SHOW_STR MMCTX_STR "Identify by TLLI\n" "TLLI\n" INCLUDE_PDP_STR) -{ - uint32_t tlli; - struct sgsn_mm_ctx *mm; - - tlli = strtoul(argv[0], NULL, 16); - mm = sgsn_mm_ctx_by_tlli(tlli); - if (!mm) { - vty_out(vty, "No MM context for TLLI %08x%s", - tlli, VTY_NEWLINE); - return CMD_WARNING; - } - vty_dump_mmctx(vty, "", mm, argv[1] ? 1 : 0); - return CMD_SUCCESS; -} -#endif - -DEFUN(swow_mmctx_imsi, show_mmctx_imsi_cmd, - "show mm-context imsi IMSI [pdp]", - SHOW_STR MMCTX_STR "Identify by IMSI\n" "IMSI of the MM Context\n" - INCLUDE_PDP_STR) -{ - struct sgsn_mm_ctx *mm; - - mm = sgsn_mm_ctx_by_imsi(argv[0]); - if (!mm) { - vty_out(vty, "No MM context for IMSI %s%s", - argv[0], VTY_NEWLINE); - return CMD_WARNING; - } - vty_dump_mmctx(vty, "", mm, argv[1] ? 1 : 0); - return CMD_SUCCESS; -} - -DEFUN(swow_mmctx_all, show_mmctx_all_cmd, - "show mm-context all [pdp]", - SHOW_STR MMCTX_STR "All MM Contexts\n" INCLUDE_PDP_STR) -{ - struct sgsn_mm_ctx *mm; - - llist_for_each_entry(mm, &sgsn_mm_ctxts, list) - vty_dump_mmctx(vty, "", mm, argv[0] ? 1 : 0); - - return CMD_SUCCESS; -} - -DEFUN(show_pdpctx_all, show_pdpctx_all_cmd, - "show pdp-context all", - SHOW_STR "Display information on PDP Context\n" "Show everything\n") -{ - struct sgsn_pdp_ctx *pdp; - - llist_for_each_entry(pdp, &sgsn_pdp_ctxts, g_list) - vty_dump_pdp(vty, "", pdp); - - return CMD_SUCCESS; -} - - -DEFUN(imsi_acl, cfg_imsi_acl_cmd, - "imsi-acl (add|del) IMSI", - "Access Control List of foreign IMSIs\n" - "Add IMSI to ACL\n" - "Remove IMSI from ACL\n" - "IMSI of subscriber\n") -{ - char imsi_sanitized[GSM23003_IMSI_MAX_DIGITS+1]; - const char *op = argv[0]; - const char *imsi = imsi_sanitized; - int rc; - - /* Sanitize IMSI */ - if (strlen(argv[1]) > GSM23003_IMSI_MAX_DIGITS) { - vty_out(vty, "%% IMSI (%s) too long -- ignored!%s", - argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - memset(imsi_sanitized, '0', sizeof(imsi_sanitized)); - strcpy(imsi_sanitized+GSM23003_IMSI_MAX_DIGITS-strlen(argv[1]),argv[1]); - - if (!strcmp(op, "add")) - rc = sgsn_acl_add(imsi, g_cfg); - else - rc = sgsn_acl_del(imsi, g_cfg); - - if (rc < 0) { - vty_out(vty, "%% unable to %s ACL%s", op, VTY_NEWLINE); - return CMD_WARNING; - } - - return CMD_SUCCESS; -} - -DEFUN(cfg_encrypt, cfg_encrypt_cmd, - "encryption (GEA0|GEA1|GEA2|GEA3|GEA4)", - "Set encryption algorithm for SGSN\n" - "Use GEA0 (no encryption)\n" - "Use GEA1\nUse GEA2\nUse GEA3\nUse GEA4\n") -{ - enum gprs_ciph_algo c = get_string_value(gprs_cipher_names, argv[0]); - if (c != GPRS_ALGO_GEA0) { - if (!gprs_cipher_supported(c)) { - vty_out(vty, "%% cipher %s is unsupported in current version%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; - } - - if (!g_cfg->require_authentication) { - vty_out(vty, "%% unable to use encryption %s without authentication: please adjust auth-policy%s", - argv[0], VTY_NEWLINE); - return CMD_WARNING; - } - } - - g_cfg->cipher = c; - - return CMD_SUCCESS; -} - -DEFUN(cfg_auth_policy, cfg_auth_policy_cmd, - "auth-policy (accept-all|closed|acl-only|remote)", - "Autorization Policy of SGSN\n" - "Accept all IMSIs (DANGEROUS)\n" - "Accept only home network subscribers or those in the ACL\n" - "Accept only subscribers in the ACL\n" - "Use remote subscription data only (HLR)\n") -{ - int val = get_string_value(sgsn_auth_pol_strs, argv[0]); - OSMO_ASSERT(val >= SGSN_AUTH_POLICY_OPEN && val <= SGSN_AUTH_POLICY_REMOTE); - g_cfg->auth_policy = val; - g_cfg->require_authentication = (val == SGSN_AUTH_POLICY_REMOTE); - g_cfg->require_update_location = (val == SGSN_AUTH_POLICY_REMOTE); - - return CMD_SUCCESS; -} - -/* Subscriber */ -#include - -static void subscr_dump_full_vty(struct vty *vty, struct gprs_subscr *gsub, int pending) -{ -#if 0 - char expire_time[200]; -#endif - struct gsm_auth_tuple *at; - int at_idx; - struct sgsn_subscriber_pdp_data *pdp; - - vty_out(vty, " Authorized: %d%s", - gsub->authorized, VTY_NEWLINE); - vty_out(vty, " LAC: %d/0x%x%s", - gsub->lac, gsub->lac, VTY_NEWLINE); - vty_out(vty, " IMSI: %s%s", gsub->imsi, VTY_NEWLINE); - if (gsub->tmsi != GSM_RESERVED_TMSI) - vty_out(vty, " TMSI: %08X%s", gsub->tmsi, - VTY_NEWLINE); - if (gsub->sgsn_data->msisdn_len > 0) - vty_out(vty, " MSISDN (BCD): %s%s", - osmo_hexdump(gsub->sgsn_data->msisdn, - gsub->sgsn_data->msisdn_len), - VTY_NEWLINE); - - if (strlen(gsub->imei) > 0) - vty_out(vty, " IMEI: %s%s", gsub->imei, VTY_NEWLINE); - - for (at_idx = 0; at_idx < ARRAY_SIZE(gsub->sgsn_data->auth_triplets); - at_idx++) { - at = &gsub->sgsn_data->auth_triplets[at_idx]; - if (at->key_seq == GSM_KEY_SEQ_INVAL) - continue; - - vty_out(vty, " A3A8 tuple (used %d times): ", - at->use_count); - vty_out(vty, " CKSN: %d, ", - at->key_seq); - if (at->vec.auth_types & OSMO_AUTH_TYPE_GSM) { - vty_out(vty, "RAND: %s, ", - osmo_hexdump(at->vec.rand, - sizeof(at->vec.rand))); - vty_out(vty, "SRES: %s, ", - osmo_hexdump(at->vec.sres, - sizeof(at->vec.sres))); - vty_out(vty, "Kc: %s%s", - osmo_hexdump(at->vec.kc, - sizeof(at->vec.kc)), VTY_NEWLINE); - } - if (at->vec.auth_types & OSMO_AUTH_TYPE_UMTS) { - vty_out(vty, " AUTN: %s, ", - osmo_hexdump(at->vec.autn, - sizeof(at->vec.autn))); - vty_out(vty, "RES: %s, ", - osmo_hexdump(at->vec.res, at->vec.res_len)); - vty_out(vty, "IK: %s, ", - osmo_hexdump(at->vec.ik, sizeof(at->vec.ik))); - vty_out(vty, "CK: %s, ", - osmo_hexdump(at->vec.ck, sizeof(at->vec.ck))); - } - } - - llist_for_each_entry(pdp, &gsub->sgsn_data->pdp_list, list) { - vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s' QoS: %s%s", - pdp->context_id, pdp->pdp_type, pdp->apn_str, - osmo_hexdump(pdp->qos_subscribed, pdp->qos_subscribed_len), - VTY_NEWLINE); - } - -#if 0 - /* print the expiration time of a subscriber */ - if (gsub->expire_lu) { - strftime(expire_time, sizeof(expire_time), - "%a, %d %b %Y %T %z", localtime(&gsub->expire_lu)); - expire_time[sizeof(expire_time) - 1] = '\0'; - vty_out(vty, " Expiration Time: %s%s", expire_time, VTY_NEWLINE); - } -#endif - - if (gsub->flags) - vty_out(vty, " Flags: %s%s%s%s%s%s", - gsub->flags & GPRS_SUBSCRIBER_FIRST_CONTACT ? - "FIRST_CONTACT " : "", - gsub->flags & GPRS_SUBSCRIBER_CANCELLED ? - "CANCELLED " : "", - gsub->flags & GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING ? - "UPDATE_LOCATION_PENDING " : "", - gsub->flags & GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING ? - "AUTH_INFO_PENDING " : "", - gsub->flags & GPRS_SUBSCRIBER_ENABLE_PURGE ? - "ENABLE_PURGE " : "", - VTY_NEWLINE); - - vty_out(vty, " Use count: %u%s", gsub->use_count, VTY_NEWLINE); -} - -DEFUN(show_subscr_cache, - show_subscr_cache_cmd, - "show subscriber cache", - SHOW_STR "Show information about subscribers\n" - "Display contents of subscriber cache\n") -{ - struct gprs_subscr *subscr; - - llist_for_each_entry(subscr, gprs_subscribers, entry) { - vty_out(vty, " Subscriber:%s", VTY_NEWLINE); - subscr_dump_full_vty(vty, subscr, 0); - } - - return CMD_SUCCESS; -} - -#define UPDATE_SUBSCR_STR "update-subscriber imsi IMSI " -#define UPDATE_SUBSCR_HELP "Update subscriber list\n" \ - "Use the IMSI to select the subscriber\n" \ - "The IMSI\n" - -#define UPDATE_SUBSCR_INSERT_HELP "Insert data into the subscriber record\n" - -DEFUN(update_subscr_insert_auth_triplet, update_subscr_insert_auth_triplet_cmd, - UPDATE_SUBSCR_STR "insert auth-triplet <1-5> sres SRES rand RAND kc KC", - UPDATE_SUBSCR_HELP - UPDATE_SUBSCR_INSERT_HELP - "Update authentication triplet\n" - "Triplet index\n" - "Set SRES value\nSRES value (4 byte) in hex\n" - "Set RAND value\nRAND value (16 byte) in hex\n" - "Set Kc value\nKc value (8 byte) in hex\n") -{ - const char *imsi = argv[0]; - const int cksn = atoi(argv[1]) - 1; - const char *sres_str = argv[2]; - const char *rand_str = argv[3]; - const char *kc_str = argv[4]; - struct gsm_auth_tuple at = {0,}; - - struct gprs_subscr *subscr; - - subscr = gprs_subscr_get_by_imsi(imsi); - if (!subscr) { - vty_out(vty, "%% unable get subscriber record for %s%s", - imsi, VTY_NEWLINE); - return CMD_WARNING; - } - - OSMO_ASSERT(subscr->sgsn_data); - - if (osmo_hexparse(sres_str, &at.vec.sres[0], sizeof(at.vec.sres)) < 0) { - vty_out(vty, "%% invalid SRES value '%s'%s", - sres_str, VTY_NEWLINE); - goto failed; - } - if (osmo_hexparse(rand_str, &at.vec.rand[0], sizeof(at.vec.rand)) < 0) { - vty_out(vty, "%% invalid RAND value '%s'%s", - rand_str, VTY_NEWLINE); - goto failed; - } - if (osmo_hexparse(kc_str, &at.vec.kc[0], sizeof(at.vec.kc)) < 0) { - vty_out(vty, "%% invalid Kc value '%s'%s", - kc_str, VTY_NEWLINE); - goto failed; - } - at.key_seq = cksn; - - subscr->sgsn_data->auth_triplets[cksn] = at; - subscr->sgsn_data->auth_triplets_updated = 1; - - gprs_subscr_put(subscr); - - return CMD_SUCCESS; - -failed: - gprs_subscr_put(subscr); - return CMD_SUCCESS; -} - -DEFUN(update_subscr_cancel, update_subscr_cancel_cmd, - UPDATE_SUBSCR_STR "cancel (update-procedure|subscription-withdraw)", - UPDATE_SUBSCR_HELP - "Cancel (remove) subscriber record\n" - "The MS moved to another SGSN\n" - "The subscription is no longer valid\n") -{ - const char *imsi = argv[0]; - const char *cancel_type = argv[1]; - - struct gprs_subscr *subscr; - - subscr = gprs_subscr_get_by_imsi(imsi); - if (!subscr) { - vty_out(vty, "%% no subscriber record for %s%s", - imsi, VTY_NEWLINE); - return CMD_WARNING; - } - - if (strcmp(cancel_type, "update-procedure") == 0) - subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE; - else - subscr->sgsn_data->error_cause = GMM_CAUSE_IMPL_DETACHED; - - gprs_subscr_cancel(subscr); - gprs_subscr_put(subscr); - - return CMD_SUCCESS; -} - -DEFUN(update_subscr_create, update_subscr_create_cmd, - UPDATE_SUBSCR_STR "create", - UPDATE_SUBSCR_HELP - "Create a subscriber entry\n") -{ - const char *imsi = argv[0]; - - struct gprs_subscr *subscr; - - subscr = gprs_subscr_get_by_imsi(imsi); - if (subscr) { - vty_out(vty, "%% subscriber record already exists for %s%s", - imsi, VTY_NEWLINE); - return CMD_WARNING; - } - - subscr = gprs_subscr_get_or_create(imsi); - subscr->keep_in_ram = 1; - gprs_subscr_put(subscr); - - return CMD_SUCCESS; -} - -DEFUN(update_subscr_destroy, update_subscr_destroy_cmd, - UPDATE_SUBSCR_STR "destroy", - UPDATE_SUBSCR_HELP - "Destroy a subscriber entry\n") -{ - const char *imsi = argv[0]; - - struct gprs_subscr *subscr; - - subscr = gprs_subscr_get_by_imsi(imsi); - if (!subscr) { - vty_out(vty, "%% subscriber record does not exist for %s%s", - imsi, VTY_NEWLINE); - return CMD_WARNING; - } - - subscr->keep_in_ram = 0; - subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE; - gprs_subscr_cancel(subscr); - if (subscr->use_count > 1) - vty_out(vty, "%% subscriber is still in use%s", - VTY_NEWLINE); - gprs_subscr_put(subscr); - - return CMD_SUCCESS; -} - -#define UL_ERR_STR "system-failure|data-missing|unexpected-data-value|" \ - "unknown-subscriber|roaming-not-allowed" - -#define UL_ERR_HELP \ - "Force error code SystemFailure\n" \ - "Force error code DataMissing\n" \ - "Force error code UnexpectedDataValue\n" \ - "Force error code UnknownSubscriber\n" \ - "Force error code RoamingNotAllowed\n" - -DEFUN(update_subscr_update_location_result, update_subscr_update_location_result_cmd, - UPDATE_SUBSCR_STR "update-location-result (ok|" UL_ERR_STR ")", - UPDATE_SUBSCR_HELP - "Complete the update location procedure\n" - "The update location request succeeded\n" - UL_ERR_HELP) -{ - const char *imsi = argv[0]; - const char *ret_code_str = argv[1]; - - struct gprs_subscr *subscr; - - const struct value_string cause_mapping[] = { - { GMM_CAUSE_NET_FAIL, "system-failure" }, - { GMM_CAUSE_INV_MAND_INFO, "data-missing" }, - { GMM_CAUSE_PROTO_ERR_UNSPEC, "unexpected-data-value" }, - { GMM_CAUSE_IMSI_UNKNOWN, "unknown-subscriber" }, - { GMM_CAUSE_GPRS_NOTALLOWED, "roaming-not-allowed" }, - { 0, NULL } - }; - - subscr = gprs_subscr_get_by_imsi(imsi); - if (!subscr) { - vty_out(vty, "%% unable to get subscriber record for %s%s", - imsi, VTY_NEWLINE); - return CMD_WARNING; - } - - if (strcmp(ret_code_str, "ok") == 0) { - subscr->sgsn_data->error_cause = SGSN_ERROR_CAUSE_NONE; - subscr->authorized = 1; - } else { - subscr->sgsn_data->error_cause = - get_string_value(cause_mapping, ret_code_str); - subscr->authorized = 0; - } - - gprs_subscr_update(subscr); - - gprs_subscr_put(subscr); - - return CMD_SUCCESS; -} - -DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd, - UPDATE_SUBSCR_STR "update-auth-info", - UPDATE_SUBSCR_HELP - "Complete the send authentication info procedure\n") -{ - const char *imsi = argv[0]; - - struct gprs_subscr *subscr; - - subscr = gprs_subscr_get_by_imsi(imsi); - if (!subscr) { - vty_out(vty, "%% unable to get subscriber record for %s%s", - imsi, VTY_NEWLINE); - return CMD_WARNING; - } - - gprs_subscr_update_auth_info(subscr); - - gprs_subscr_put(subscr); - - return CMD_SUCCESS; -} - -DEFUN(cfg_gsup_remote_ip, cfg_gsup_remote_ip_cmd, - "gsup remote-ip A.B.C.D", - "GSUP Parameters\n" - "Set the IP address of the remote GSUP server\n" - "IPv4 Address\n") -{ - inet_aton(argv[0], &g_cfg->gsup_server_addr.sin_addr); - - return CMD_SUCCESS; -} - -DEFUN(cfg_gsup_remote_port, cfg_gsup_remote_port_cmd, - "gsup remote-port <0-65535>", - "GSUP Parameters\n" - "Set the TCP port of the remote GSUP server\n" - "Remote TCP port\n") -{ - g_cfg->gsup_server_port = atoi(argv[0]); - - return CMD_SUCCESS; -} - -DEFUN(cfg_gsup_oap_id, cfg_gsup_oap_id_cmd, - "gsup oap-id <0-65535>", - "GSUP Parameters\n" - "Set the SGSN's OAP client ID\nOAP client ID (0 == disabled)\n") -{ - /* VTY ensures range */ - g_cfg->oap.client_id = (uint16_t)atoi(argv[0]); - return CMD_SUCCESS; -} - -DEFUN(cfg_gsup_oap_k, cfg_gsup_oap_k_cmd, - "gsup oap-k K", - "GSUP Parameters\n" - "Set the OAP shared secret K\nK value (16 byte) hex\n") -{ - const char *k = argv[0]; - - g_cfg->oap.secret_k_present = 0; - - if ((!k) || (strlen(k) == 0)) - goto disable; - - int k_len = osmo_hexparse(k, - g_cfg->oap.secret_k, - sizeof(g_cfg->oap.secret_k)); - if (k_len != 16) { - vty_out(vty, "%% need exactly 16 octets for oap-k, got %d.%s", - k_len, VTY_NEWLINE); - goto disable; - } - - g_cfg->oap.secret_k_present = 1; - return CMD_SUCCESS; - -disable: - if (g_cfg->oap.client_id > 0) { - vty_out(vty, "%% OAP client ID set, but invalid oap-k value disables OAP.%s", - VTY_NEWLINE); - return CMD_WARNING; - } - return CMD_SUCCESS; -} - -DEFUN(cfg_gsup_oap_opc, cfg_gsup_oap_opc_cmd, - "gsup oap-opc OPC", - "GSUP Parameters\n" - "Set the OAP shared secret OPC\nOPC value (16 byte) hex\n") -{ - const char *opc = argv[0]; - - g_cfg->oap.secret_opc_present = 0; - - if ((!opc) || (strlen(opc) == 0)) - goto disable; - - int opc_len = osmo_hexparse(opc, - g_cfg->oap.secret_opc, - sizeof(g_cfg->oap.secret_opc)); - if (opc_len != 16) { - vty_out(vty, "%% need exactly 16 octets for oap-opc, got %d.%s", - opc_len, VTY_NEWLINE); - goto disable; - } - - g_cfg->oap.secret_opc_present = 1; - return CMD_SUCCESS; - -disable: - if (g_cfg->oap.client_id > 0) { - vty_out(vty, "%% OAP client ID set, but invalid oap-opc value disables OAP.%s", - VTY_NEWLINE); - return CMD_WARNING; - } - return CMD_SUCCESS; -} - -DEFUN(cfg_apn_name, cfg_apn_name_cmd, - "access-point-name NAME", - "Configure a global list of allowed APNs\n" - "Add this NAME to the list\n") -{ - return add_apn_ggsn_mapping(vty, argv[0], "", 0); -} - -DEFUN(cfg_no_apn_name, cfg_no_apn_name_cmd, - "no access-point-name NAME", - NO_STR "Configure a global list of allowed APNs\n" - "Remove entry with NAME\n") -{ - struct apn_ctx *apn_ctx = sgsn_apn_ctx_by_name(argv[0], ""); - if (!apn_ctx) - return CMD_SUCCESS; - - sgsn_apn_ctx_free(apn_ctx); - return CMD_SUCCESS; -} - -DEFUN(cfg_cdr_filename, cfg_cdr_filename_cmd, - "cdr filename NAME", - "CDR\nSet filename\nname\n") -{ - talloc_free(g_cfg->cdr.filename); - g_cfg->cdr.filename = talloc_strdup(tall_vty_ctx, argv[0]); - return CMD_SUCCESS; -} - -DEFUN(cfg_no_cdr_filename, cfg_no_cdr_filename_cmd, - "no cdr filename", - NO_STR "CDR\nDisable CDR generation\n") -{ - talloc_free(g_cfg->cdr.filename); - g_cfg->cdr.filename = NULL; - return CMD_SUCCESS; -} - -DEFUN(cfg_cdr_interval, cfg_cdr_interval_cmd, - "cdr interval <1-2147483647>", - "CDR\nPDP periodic log interval\nSeconds\n") -{ - g_cfg->cdr.interval = atoi(argv[0]); - return CMD_SUCCESS; -} - -#define COMPRESSION_STR "Configure compression\n" -DEFUN(cfg_no_comp_rfc1144, cfg_no_comp_rfc1144_cmd, - "no compression rfc1144", - NO_STR COMPRESSION_STR "disable rfc1144 TCP/IP header compression\n") -{ - g_cfg->pcomp_rfc1144.active = 0; - g_cfg->pcomp_rfc1144.passive = 0; - return CMD_SUCCESS; -} - -DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd, - "compression rfc1144 active slots <1-256>", - COMPRESSION_STR - "RFC1144 Header compresion scheme\n" - "Compression is actively proposed\n" - "Number of compression state slots\n" - "Number of compression state slots\n") -{ - g_cfg->pcomp_rfc1144.active = 1; - g_cfg->pcomp_rfc1144.passive = 1; - g_cfg->pcomp_rfc1144.s01 = atoi(argv[0]) - 1; - return CMD_SUCCESS; -} - -DEFUN(cfg_comp_rfc1144p, cfg_comp_rfc1144p_cmd, - "compression rfc1144 passive", - COMPRESSION_STR - "RFC1144 Header compresion scheme\n" - "Compression is available on request\n") -{ - g_cfg->pcomp_rfc1144.active = 0; - g_cfg->pcomp_rfc1144.passive = 1; - return CMD_SUCCESS; -} - -DEFUN(cfg_no_comp_v42bis, cfg_no_comp_v42bis_cmd, - "no compression v42bis", - NO_STR COMPRESSION_STR "disable V.42bis data compression\n") -{ - g_cfg->dcomp_v42bis.active = 0; - g_cfg->dcomp_v42bis.passive = 0; - return CMD_SUCCESS; -} - -DEFUN(cfg_comp_v42bis, cfg_comp_v42bis_cmd, - "compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>", - COMPRESSION_STR - "V.42bis data compresion scheme\n" - "Compression is actively proposed\n" - "Direction in which the compression shall be active (p0)\n" - "Compress ms->sgsn direction only\n" - "Compress sgsn->ms direction only\n" - "Both directions\n" - "Number of codewords (p1)\n" - "Number of codewords\n" - "Maximum string length (p2)\n" "Maximum string length\n") -{ - g_cfg->dcomp_v42bis.active = 1; - g_cfg->dcomp_v42bis.passive = 1; - - switch (argv[0][0]) { - case 'm': - g_cfg->dcomp_v42bis.p0 = 1; - break; - case 's': - g_cfg->dcomp_v42bis.p0 = 2; - break; - case 'b': - g_cfg->dcomp_v42bis.p0 = 3; - break; - } - - g_cfg->dcomp_v42bis.p1 = atoi(argv[1]); - g_cfg->dcomp_v42bis.p2 = atoi(argv[2]); - return CMD_SUCCESS; -} - -DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd, - "compression v42bis passive", - COMPRESSION_STR - "V.42bis data compresion scheme\n" - "Compression is available on request\n") -{ - g_cfg->dcomp_v42bis.active = 0; - g_cfg->dcomp_v42bis.passive = 1; - return CMD_SUCCESS; -} - -int sgsn_vty_init(struct sgsn_config *cfg) -{ - g_cfg = cfg; - - install_element_ve(&show_sgsn_cmd); - //install_element_ve(&show_mmctx_tlli_cmd); - install_element_ve(&show_mmctx_imsi_cmd); - install_element_ve(&show_mmctx_all_cmd); - install_element_ve(&show_pdpctx_all_cmd); - install_element_ve(&show_subscr_cache_cmd); - - install_element(ENABLE_NODE, &update_subscr_insert_auth_triplet_cmd); - install_element(ENABLE_NODE, &update_subscr_create_cmd); - install_element(ENABLE_NODE, &update_subscr_destroy_cmd); - install_element(ENABLE_NODE, &update_subscr_cancel_cmd); - install_element(ENABLE_NODE, &update_subscr_update_location_result_cmd); - install_element(ENABLE_NODE, &update_subscr_update_auth_info_cmd); - - install_element(CONFIG_NODE, &cfg_sgsn_cmd); - install_node(&sgsn_node, config_write_sgsn); - vty_install_default(SGSN_NODE); - install_element(SGSN_NODE, &cfg_sgsn_bind_addr_cmd); - install_element(SGSN_NODE, &cfg_ggsn_remote_ip_cmd); - //install_element(SGSN_NODE, &cfg_ggsn_remote_port_cmd); - install_element(SGSN_NODE, &cfg_ggsn_gtp_version_cmd); - install_element(SGSN_NODE, &cfg_imsi_acl_cmd); - install_element(SGSN_NODE, &cfg_auth_policy_cmd); - install_element(SGSN_NODE, &cfg_encrypt_cmd); - install_element(SGSN_NODE, &cfg_gsup_remote_ip_cmd); - install_element(SGSN_NODE, &cfg_gsup_remote_port_cmd); - install_element(SGSN_NODE, &cfg_gsup_oap_id_cmd); - install_element(SGSN_NODE, &cfg_gsup_oap_k_cmd); - install_element(SGSN_NODE, &cfg_gsup_oap_opc_cmd); - install_element(SGSN_NODE, &cfg_apn_ggsn_cmd); - install_element(SGSN_NODE, &cfg_apn_imsi_ggsn_cmd); - install_element(SGSN_NODE, &cfg_apn_name_cmd); - install_element(SGSN_NODE, &cfg_no_apn_name_cmd); - install_element(SGSN_NODE, &cfg_cdr_filename_cmd); - install_element(SGSN_NODE, &cfg_no_cdr_filename_cmd); - install_element(SGSN_NODE, &cfg_cdr_interval_cmd); - install_element(SGSN_NODE, &cfg_ggsn_dynamic_lookup_cmd); - install_element(SGSN_NODE, &cfg_grx_ggsn_cmd); - - install_element(SGSN_NODE, &cfg_sgsn_T3312_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3322_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3350_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3360_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3370_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3313_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3314_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3316_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3385_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3386_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd); - install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd); - - install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd); - install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd); - install_element(SGSN_NODE, &cfg_comp_rfc1144p_cmd); - install_element(SGSN_NODE, &cfg_no_comp_v42bis_cmd); - install_element(SGSN_NODE, &cfg_comp_v42bis_cmd); - install_element(SGSN_NODE, &cfg_comp_v42bisp_cmd); - -#ifdef BUILD_IU - ranap_iu_vty_init(SGSN_NODE, &g_cfg->iu.rab_assign_addr_enc); -#endif - return 0; -} - -int sgsn_parse_config(const char *config_file) -{ - int rc; - - /* make sure sgsn_vty_init() was called before this */ - OSMO_ASSERT(g_cfg); - - g_cfg->timers.T3312 = GSM0408_T3312_SECS; - g_cfg->timers.T3322 = GSM0408_T3322_SECS; - g_cfg->timers.T3350 = GSM0408_T3350_SECS; - g_cfg->timers.T3360 = GSM0408_T3360_SECS; - g_cfg->timers.T3370 = GSM0408_T3370_SECS; - g_cfg->timers.T3313 = GSM0408_T3313_SECS; - g_cfg->timers.T3314 = GSM0408_T3314_SECS; - g_cfg->timers.T3316 = GSM0408_T3316_SECS; - g_cfg->timers.T3385 = GSM0408_T3385_SECS; - g_cfg->timers.T3386 = GSM0408_T3386_SECS; - g_cfg->timers.T3395 = GSM0408_T3395_SECS; - g_cfg->timers.T3397 = GSM0408_T3397_SECS; - - rc = vty_read_config_file(config_file, NULL); - if (rc < 0) { - fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file); - return rc; - } - - if (g_cfg->auth_policy == SGSN_AUTH_POLICY_REMOTE - && !(g_cfg->gsup_server_addr.sin_addr.s_addr - && g_cfg->gsup_server_port)) { - fprintf(stderr, "Configuration error:" - " 'auth-policy remote' requires both" - " 'gsup remote-ip' and 'gsup remote-port'\n"); - return -EINVAL; - } - - return 0; -} diff --git a/src/gprs/slhc.c b/src/gprs/slhc.c deleted file mode 100644 index cbdf8dbd8..000000000 --- a/src/gprs/slhc.c +++ /dev/null @@ -1,813 +0,0 @@ -/* - * Routines to compress and uncompress tcp packets (for transmission - * over low speed serial lines). - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - * - * - * modified for KA9Q Internet Software Package by - * Katie Stevens (dkstevens@ucdavis.edu) - * University of California, Davis - * Computing Services - * - 01-31-90 initial adaptation (from 1.19) - * PPP.05 02-15-90 [ks] - * PPP.08 05-02-90 [ks] use PPP protocol field to signal compression - * PPP.15 09-90 [ks] improve mbuf handling - * PPP.16 11-02 [karn] substantially rewritten to use NOS facilities - * - * - Feb 1991 Bill_Simpson@um.cc.umich.edu - * variable number of conversation slots - * allow zero or one slots - * separate routines - * status display - * - Jul 1994 Dmitry Gorodchanin - * Fixes for memory leaks. - * - Oct 1994 Dmitry Gorodchanin - * Modularization. - * - Jan 1995 Bjorn Ekwall - * Use ip_fast_csum from ip.h - * - July 1995 Christos A. Polyzols - * Spotted bug in tcp option checking - * - * - * This module is a difficult issue. It's clearly inet code but it's also clearly - * driver code belonging close to PPP and SLIP - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ERR_PTR(x) x - - -static unsigned char *encode(unsigned char *cp, unsigned short n); -static long decode(unsigned char **cpp); -static unsigned char * put16(unsigned char *cp, unsigned short x); -static unsigned short pull16(unsigned char **cpp); - -/* Replacement for kernel space function ip_fast_csum() */ -static uint16_t ip_fast_csum(uint8_t *iph, int ihl) -{ - int i; - uint16_t temp; - uint32_t accumulator = 0xFFFF; - - for(i=0;i0xFFFF) - { - accumulator++; - accumulator&=0xFFFF; - } - } - - return (uint16_t)(htons(~accumulator)&0xFFFF); -} - -/* Replacement for kernel space function put_unaligned() */ -static void put_unaligned(uint16_t val, void *ptr) -{ - memcpy(ptr,&val,sizeof(val)); -} - - -/* Allocate compression data structure - * slots must be in range 0 to 255 (zero meaning no compression) - * Returns pointer to structure or ERR_PTR() on error. - */ -struct slcompress * -slhc_init(const void *ctx, int rslots, int tslots) -{ - register short i; - register struct cstate *ts; - struct slcompress *comp; - - if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255) - return NULL; - - comp = (struct slcompress *)talloc_zero_size(ctx,sizeof(struct slcompress)); - if (! comp) - goto out_fail; - - if (rslots > 0) { - size_t rsize = rslots * sizeof(struct cstate); - comp->rstate = (struct cstate *) talloc_zero_size(ctx, rsize); - if (! comp->rstate) - goto out_free; - comp->rslot_limit = rslots - 1; - } - - if (tslots > 0) { - size_t tsize = tslots * sizeof(struct cstate); - comp->tstate = (struct cstate *) talloc_zero_size(ctx, tsize); - if (! comp->tstate) - goto out_free2; - comp->tslot_limit = tslots - 1; - } - - comp->xmit_oldest = 0; - comp->xmit_current = 255; - comp->recv_current = 255; - /* - * don't accept any packets with implicit index until we get - * one with an explicit index. Otherwise the uncompress code - * will try to use connection 255, which is almost certainly - * out of range - */ - comp->flags |= SLF_TOSS; - - if ( tslots > 0 ) { - ts = comp->tstate; - for(i = comp->tslot_limit; i > 0; --i){ - ts[i].cs_this = i; - ts[i].next = &(ts[i - 1]); - } - ts[0].next = &(ts[comp->tslot_limit]); - ts[0].cs_this = 0; - } - return comp; - -out_free2: - talloc_free(comp->rstate); -out_free: - talloc_free(comp); -out_fail: - return NULL; -} - - -/* Free a compression data structure */ -void -slhc_free(struct slcompress *comp) -{ - DEBUGP(DSLHC, "slhc_free(): Freeing compression states...\n"); - - if ( comp == NULLSLCOMPR ) - return; - - if ( comp->tstate != NULLSLSTATE ) - talloc_free(comp->tstate ); - - if ( comp->rstate != NULLSLSTATE ) - talloc_free( comp->rstate ); - - talloc_free( comp ); -} - - -/* Put a short in host order into a char array in network order */ -static inline unsigned char * -put16(unsigned char *cp, unsigned short x) -{ - *cp++ = x >> 8; - *cp++ = x; - - return cp; -} - - -/* Encode a number */ -static unsigned char * -encode(unsigned char *cp, unsigned short n) -{ - if(n >= 256 || n == 0){ - *cp++ = 0; - cp = put16(cp,n); - } else { - *cp++ = n; - } - - DEBUGP(DSLHC, "encode(): n=%04x\n",n); - return cp; -} - -/* Pull a 16-bit integer in host order from buffer in network byte order */ -static unsigned short -pull16(unsigned char **cpp) -{ - short rval; - - rval = *(*cpp)++; - rval <<= 8; - rval |= *(*cpp)++; - return rval; -} - -/* Decode a number */ -static long -decode(unsigned char **cpp) -{ - register int x; - - x = *(*cpp)++; - if(x == 0){ - return pull16(cpp) & 0xffff; /* pull16 returns -1 on error */ - } else { - return x & 0xff; /* -1 if PULLCHAR returned error */ - } -} - -/* - * icp and isize are the original packet. - * ocp is a place to put a copy if necessary. - * cpp is initially a pointer to icp. If the copy is used, - * change it to ocp. - */ - -int -slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, - unsigned char *ocp, unsigned char **cpp, int compress_cid) -{ - register struct cstate *ocs = &(comp->tstate[comp->xmit_oldest]); - register struct cstate *lcs = ocs; - register struct cstate *cs = lcs->next; - register unsigned long deltaS, deltaA; - register short changes = 0; - int hlen; - unsigned char new_seq[16]; - register unsigned char *cp = new_seq; - struct iphdr *ip; - struct tcphdr *th, *oth; - __sum16 csum; - - - /* - * Don't play with runt packets. - */ - - if(isizeprotocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) { - /* Send as regular IP */ - if(ip->protocol != IPPROTO_TCP) - comp->sls_o_nontcp++; - else - comp->sls_o_tcp++; - DEBUGP(DSLHC, "slhc_compress(): Not a TCP packat, will not touch...\n"); - return isize; - } - /* Extract TCP header */ - - th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); - hlen = ip->ihl*4 + th->doff*4; - - /* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or - * some other control bit is set). Also uncompressible if - * it's a runt. - */ - if(hlen > isize || th->syn || th->fin || th->rst || - ! (th->ack)){ - /* TCP connection stuff; send as regular IP */ - comp->sls_o_tcp++; - DEBUGP(DSLHC, "slhc_compress(): Packet is part of a TCP connection, will not touch...\n"); - return isize; - } - /* - * Packet is compressible -- we're going to send either a - * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way, - * we need to locate (or create) the connection state. - * - * States are kept in a circularly linked list with - * xmit_oldest pointing to the end of the list. The - * list is kept in lru order by moving a state to the - * head of the list whenever it is referenced. Since - * the list is short and, empirically, the connection - * we want is almost always near the front, we locate - * states via linear search. If we don't find a state - * for the datagram, the oldest state is (re-)used. - */ - - DEBUGP(DSLHC, "slhc_compress(): Compressible packet detected!\n"); - - for ( ; ; ) { - if( ip->saddr == cs->cs_ip.saddr - && ip->daddr == cs->cs_ip.daddr - && th->source == cs->cs_tcp.source - && th->dest == cs->cs_tcp.dest) - goto found; - - /* if current equal oldest, at end of list */ - if ( cs == ocs ) - break; - lcs = cs; - cs = cs->next; - comp->sls_o_searches++; - } - /* - * Didn't find it -- re-use oldest cstate. Send an - * uncompressed packet that tells the other side what - * connection number we're using for this conversation. - * - * Note that since the state list is circular, the oldest - * state points to the newest and we only need to set - * xmit_oldest to update the lru linkage. - */ - - DEBUGP(DSLHC, "slhc_compress(): Header not yet seen, will memorize header for the next turn...\n"); - comp->sls_o_misses++; - comp->xmit_oldest = lcs->cs_this; - goto uncompressed; - -found: - DEBUGP(DSLHC, "slhc_compress(): Header already seen, trying to compress...\n"); - /* - * Found it -- move to the front on the connection list. - */ - if(lcs == ocs) { - /* found at most recently used */ - } else if (cs == ocs) { - /* found at least recently used */ - comp->xmit_oldest = lcs->cs_this; - } else { - /* more than 2 elements */ - lcs->next = cs->next; - cs->next = ocs->next; - ocs->next = cs; - } - - /* - * Make sure that only what we expect to change changed. - * Check the following: - * IP protocol version, header length & type of service. - * The "Don't fragment" bit. - * The time-to-live field. - * The TCP header length. - * IP options, if any. - * TCP options, if any. - * If any of these things are different between the previous & - * current datagram, we send the current datagram `uncompressed'. - */ - oth = &cs->cs_tcp; - - /* Display a little more debug information about which of the - * header fields changed unexpectedly */ - if(ip->version != cs->cs_ip.version) - DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->version != cs->cs_ip.version\n"); - if(ip->ihl != cs->cs_ip.ihl) - DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ihl != cs->cs_ip.ihl\n"); - if(ip->tos != cs->cs_ip.tos) - DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->tos != cs->cs_ip.tos\n"); - if((ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))) - DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))\n"); - if(ip->ttl != cs->cs_ip.ttl) - DEBUGP(DSLHC, "slhc_compress(): Unexpected change: ip->ttl != cs->cs_ip.ttl\n"); - if(th->doff != cs->cs_tcp.doff) - DEBUGP(DSLHC, "slhc_compress(): Unexpected change: th->doff != cs->cs_tcp.doff\n"); - if(ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) { - DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0)\n"); - DEBUGP(DSLHC, "slhc_compress(): ip->ihl = %i\n", ip->ihl); - DEBUGP(DSLHC, "slhc_compress(): ip+1 = %s\n", - osmo_hexdump_nospc((uint8_t*)(ip+1),((ip->ihl)-5)*4)); - DEBUGP(DSLHC, "slhc_compress(): Unexpected change: cs->cs_ipopt = %s\n", - osmo_hexdump_nospc((uint8_t*)(cs->cs_ipopt),((ip->ihl)-5)*4)); - } - if(th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0) { - DEBUGP(DSLHC, "slhc_compress(): Unexpected change: (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)\n"); - DEBUGP(DSLHC, "slhc_compress(): th->doff = %i\n", th->doff); - DEBUGP(DSLHC, "slhc_compress(): th+1 = %s\n", - osmo_hexdump_nospc((uint8_t*)(th+1),((th->doff)-5)*4)); - DEBUGP(DSLHC, "slhc_compress(): cs->cs_tcpopt = %s\n", - osmo_hexdump_nospc((uint8_t*)cs->cs_tcpopt, - ((th->doff)-5)*4)); - } - - - if(ip->version != cs->cs_ip.version || ip->ihl != cs->cs_ip.ihl - || ip->tos != cs->cs_ip.tos - || (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000)) - || ip->ttl != cs->cs_ip.ttl - || th->doff != cs->cs_tcp.doff - || (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0) - || (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)){ - DEBUGP(DSLHC, "slhc_compress(): The header contains unexpected changes, can't compress...\n"); - goto uncompressed; - } - - /* - * Figure out which of the changing fields changed. The - * receiver expects changes in the order: urgent, window, - * ack, seq (the order minimizes the number of temporaries - * needed in this section of code). - */ - if(th->urg){ - deltaS = ntohs(th->urg_ptr); - DEBUGP(DSLHC, "slhc_compress(): flag: Urgent Pointer (U) = 1\n"); - cp = encode(cp,deltaS); - changes |= NEW_U; - } else if(th->urg_ptr != oth->urg_ptr){ - /* argh! URG not set but urp changed -- a sensible - * implementation should never do this but RFC793 - * doesn't prohibit the change so we have to deal - * with it. */ - DEBUGP(DSLHC, "slhc_compress(): URG not set but urp changed, can't compress...\n"); - goto uncompressed; - } - if((deltaS = ntohs(th->window) - ntohs(oth->window)) != 0){ - DEBUGP(DSLHC, "slhc_compress(): flag: Delta Window (W) = 1\n"); - cp = encode(cp,deltaS); - changes |= NEW_W; - } - if((deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L){ - if(deltaA > 0x0000ffff) { - DEBUGP(DSLHC, "slhc_compress(): (deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L, can't compress...\n"); - goto uncompressed; - } - DEBUGP(DSLHC, "slhc_compress(): flag: Delta Ack (A) = 1\n"); - cp = encode(cp,deltaA); - changes |= NEW_A; - } - if((deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L){ - if(deltaS > 0x0000ffff) { - DEBUGP(DSLHC, "slhc_compress(): (deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L, can't compress...\n"); - goto uncompressed; - } - DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1\n"); - cp = encode(cp,deltaS); - changes |= NEW_S; - } - - switch(changes){ - case 0: /* Nothing changed. If this packet contains data and the - * last one didn't, this is probably a data packet following - * an ack (normal on an interactive connection) and we send - * it compressed. Otherwise it's probably a retransmit, - * retransmitted ack or window probe. Send it uncompressed - * in case the other side missed the compressed version. - */ - if(ip->tot_len != cs->cs_ip.tot_len && - ntohs(cs->cs_ip.tot_len) == hlen) - break; - DEBUGP(DSLHC, "slhc_compress(): Retransmitted packet detected, can't compress...\n"); - goto uncompressed; - case SPECIAL_I: - case SPECIAL_D: - /* actual changes match one of our special case encodings -- - * send packet uncompressed. - */ - DEBUGP(DSLHC, "slhc_compress(): Special case detected, can't compress...\n"); - goto uncompressed; - case NEW_S|NEW_A: - if(deltaS == deltaA && - deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ - /* special case for echoed terminal traffic */ - DEBUGP(DSLHC, "slhc_compress(): Special case for echoed terminal traffic detected...\n"); - DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); - changes = SPECIAL_I; - cp = new_seq; - } - break; - case NEW_S: - if(deltaS == ntohs(cs->cs_ip.tot_len) - hlen){ - /* special case for data xfer */ - DEBUGP(DSLHC, "slhc_compress(): Special case for data xfer detected...\n"); - DEBUGP(DSLHC, "slhc_compress(): flag: Delta Sequence (S) = 1, Delta Ack (A) = 1, Delta Window (W) = 1, Urgent Pointer (U) = 1\n"); - changes = SPECIAL_D; - cp = new_seq; - } - break; - } - deltaS = ntohs(ip->id) - ntohs(cs->cs_ip.id); - if(deltaS != 1){ - DEBUGP(DSLHC, "slhc_compress(): flag: Delta IP ID (I) = 1\n"); - cp = encode(cp,deltaS); - changes |= NEW_I; - } - if(th->psh) { - DEBUGP(DSLHC, "slhc_compress(): flag: Push (P) = 1\n"); - changes |= TCP_PUSH_BIT; - } - /* Grab the cksum before we overwrite it below. Then update our - * state with this packet's header. - */ - csum = th->check; - memcpy(&cs->cs_ip,ip,20); - memcpy(&cs->cs_tcp,th,20); - /* We want to use the original packet as our compressed packet. - * (cp - new_seq) is the number of bytes we need for compressed - * sequence numbers. In addition we need one byte for the change - * mask, one for the connection id and two for the tcp checksum. - * So, (cp - new_seq) + 4 bytes of header are needed. - */ - deltaS = cp - new_seq; - if(compress_cid == 0 || comp->xmit_current != cs->cs_this){ - cp = ocp; - *cpp = ocp; - DEBUGP(DSLHC, "slhc_compress(): flag: Connection number (C) = 1\n"); - *cp++ = changes | NEW_C; - *cp++ = cs->cs_this; - comp->xmit_current = cs->cs_this; - } else { - cp = ocp; - *cpp = ocp; - *cp++ = changes; - } - *(__sum16 *)cp = csum; - cp += 2; -/* deltaS is now the size of the change section of the compressed header */ - - DEBUGP(DSLHC, "slhc_compress(): Delta-list length (deltaS) = %li\n",deltaS); - DEBUGP(DSLHC, "slhc_compress(): Original header len (hlen) = %i\n",hlen); - - memcpy(cp,new_seq,deltaS); /* Write list of deltas */ - memcpy(cp+deltaS,icp+hlen,isize-hlen); - comp->sls_o_compressed++; - ocp[0] |= SL_TYPE_COMPRESSED_TCP; - return isize - hlen + deltaS + (cp - ocp); - - /* Update connection state cs & send uncompressed packet (i.e., - * a regular ip/tcp packet but with the 'conversation id' we hope - * to use on future compressed packets in the protocol field). - */ -uncompressed: - DEBUGP(DSLHC, "slhc_compress(): Packet will be sent uncompressed...\n"); - memcpy(&cs->cs_ip,ip,20); - memcpy(&cs->cs_tcp,th,20); - if (ip->ihl > 5) - memcpy(cs->cs_ipopt, ip+1, ((ip->ihl) - 5) * 4); - if (th->doff > 5) - memcpy(cs->cs_tcpopt, th+1, ((th->doff) - 5) * 4); - comp->xmit_current = cs->cs_this; - comp->sls_o_uncompressed++; - memcpy(ocp, icp, isize); - *cpp = ocp; - ocp[9] = cs->cs_this; - ocp[0] |= SL_TYPE_UNCOMPRESSED_TCP; - return isize; -} - - -int -slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) -{ - register int changes; - long x; - register struct tcphdr *thp; - register struct iphdr *ip; - register struct cstate *cs; - int len, hdrlen; - unsigned char *cp = icp; - - /* We've got a compressed packet; read the change byte */ - comp->sls_i_compressed++; - if(isize < 3){ - comp->sls_i_error++; - return 0; - } - changes = *cp++; - if(changes & NEW_C){ - /* Make sure the state index is in range, then grab the state. - * If we have a good state index, clear the 'discard' flag. - */ - x = *cp++; /* Read conn index */ - if(x < 0 || x > comp->rslot_limit) - goto bad; - - comp->flags &=~ SLF_TOSS; - comp->recv_current = x; - } else { - /* this packet has an implicit state index. If we've - * had a line error since the last time we got an - * explicit state index, we have to toss the packet. */ - if(comp->flags & SLF_TOSS){ - comp->sls_i_tossed++; - return 0; - } - } - cs = &comp->rstate[comp->recv_current]; - thp = &cs->cs_tcp; - ip = &cs->cs_ip; - - thp->check = *(__sum16 *)cp; - cp += 2; - - thp->psh = (changes & TCP_PUSH_BIT) ? 1 : 0; -/* - * we can use the same number for the length of the saved header and - * the current one, because the packet wouldn't have been sent - * as compressed unless the options were the same as the previous one - */ - - hdrlen = ip->ihl * 4 + thp->doff * 4; - - switch(changes & SPECIALS_MASK){ - case SPECIAL_I: /* Echoed terminal traffic */ - DEBUGP(DSLHC, "slhc_uncompress(): Echoed terminal traffic detected\n"); - - { - register short i; - i = ntohs(ip->tot_len) - hdrlen; - thp->ack_seq = htonl( ntohl(thp->ack_seq) + i); - thp->seq = htonl( ntohl(thp->seq) + i); - } - break; - - case SPECIAL_D: /* Unidirectional data */ - DEBUGP(DSLHC, "slhc_uncompress(): Unidirectional data detected\n"); - thp->seq = htonl( ntohl(thp->seq) + - ntohs(ip->tot_len) - hdrlen); - break; - - default: - DEBUGP(DSLHC, "slhc_uncompress(): default packet type detected\n"); - if(changes & NEW_U){ - thp->urg = 1; - if((x = decode(&cp)) == -1) { - goto bad; - } - thp->urg_ptr = htons(x); - } else - thp->urg = 0; - if(changes & NEW_W){ - if((x = decode(&cp)) == -1) { - goto bad; - } - thp->window = htons( ntohs(thp->window) + x); - } - if(changes & NEW_A){ - if((x = decode(&cp)) == -1) { - goto bad; - } - thp->ack_seq = htonl( ntohl(thp->ack_seq) + x); - } - if(changes & NEW_S){ - if((x = decode(&cp)) == -1) { - goto bad; - } - thp->seq = htonl( ntohl(thp->seq) + x); - } - break; - } - if(changes & NEW_I){ - if((x = decode(&cp)) == -1) { - goto bad; - } - ip->id = htons (ntohs (ip->id) + x); - } else - ip->id = htons (ntohs (ip->id) + 1); - - /* - * At this point, cp points to the first byte of data in the - * packet. Put the reconstructed TCP and IP headers back on the - * packet. Recalculate IP checksum (but not TCP checksum). - */ - - len = isize - (cp - icp); - if (len < 0) - goto bad; - len += hdrlen; - ip->tot_len = htons(len); - ip->check = 0; - - DEBUGP(DSLHC, "slhc_uncompress(): making space for the reconstructed header...\n"); - memmove(icp + hdrlen, cp, len - hdrlen); - - cp = icp; - memcpy(cp, ip, 20); - cp += 20; - - if (ip->ihl > 5) { - memcpy(cp, cs->cs_ipopt, (ip->ihl - 5) * 4); - cp += (ip->ihl - 5) * 4; - } - - put_unaligned(ip_fast_csum(icp, ip->ihl), - &((struct iphdr *)icp)->check); - - memcpy(cp, thp, 20); - cp += 20; - - if (thp->doff > 5) { - memcpy(cp, cs->cs_tcpopt, ((thp->doff) - 5) * 4); - cp += ((thp->doff) - 5) * 4; - } - - return len; -bad: - DEBUGP(DSLHC, "slhc_uncompress(): bad packet detected!\n"); - comp->sls_i_error++; - return slhc_toss( comp ); -} - - -int -slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) -{ - register struct cstate *cs; - unsigned ihl; - - unsigned char index; - - if(isize < 20) { - /* The packet is shorter than a legal IP header */ - comp->sls_i_runt++; - DEBUGP(DSLHC, "slhc_remember(): The packet is shorter than a legal IP header ==> slhc_toss()\n"); - return slhc_toss( comp ); - } - /* Peek at the IP header's IHL field to find its length */ - ihl = icp[0] & 0xf; - if(ihl < 20 / 4){ - /* The IP header length field is too small */ - comp->sls_i_runt++; - DEBUGP(DSLHC, "slhc_remember(): The IP header length field is too small ==> slhc_toss()\n"); - return slhc_toss( comp ); - } - index = icp[9]; - icp[9] = IPPROTO_TCP; - - if (ip_fast_csum(icp, ihl)) { - /* Bad IP header checksum; discard */ - comp->sls_i_badcheck++; - DEBUGP(DSLHC, "slhc_remember(): Bad IP header checksum; discard ==> slhc_toss()\n"); - return slhc_toss( comp ); - } - if(index > comp->rslot_limit) { - comp->sls_i_error++; - DEBUGP(DSLHC, "slhc_remember(): index > comp->rslot_limit ==> slhc_toss()\n"); - return slhc_toss(comp); - } - - /* Update local state */ - cs = &comp->rstate[comp->recv_current = index]; - comp->flags &=~ SLF_TOSS; - memcpy(&cs->cs_ip,icp,20); - memcpy(&cs->cs_tcp,icp + ihl*4,20); - if (ihl > 5) - memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4); - if (cs->cs_tcp.doff > 5) - memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); - cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; - /* Put headers back on packet - * Neither header checksum is recalculated - */ - comp->sls_i_uncompressed++; - return isize; -} - -int -slhc_toss(struct slcompress *comp) -{ - DEBUGP(DSLHC, "slhc_toss(): Reset compression state...\n"); - if ( comp == NULLSLCOMPR ) - return 0; - - comp->flags |= SLF_TOSS; - return 0; -} - -void slhc_i_status(struct slcompress *comp) -{ - if (comp != NULLSLCOMPR) { - DEBUGP(DSLHC, "slhc_i_status(): %d Cmp, %d Uncmp, %d Bad, %d Tossed\n", - comp->sls_i_compressed, - comp->sls_i_uncompressed, - comp->sls_i_error, - comp->sls_i_tossed); - } -} - -void slhc_o_status(struct slcompress *comp) -{ - if (comp != NULLSLCOMPR) { - DEBUGP(DSLHC, "slhc_o_status(): %d Cmp, %d Uncmp, %d AsIs, %d NotTCP %d Searches, %d Misses\n", - comp->sls_o_compressed, - comp->sls_o_uncompressed, - comp->sls_o_tcp, - comp->sls_o_nontcp, - comp->sls_o_searches, - comp->sls_o_misses); - } -} - diff --git a/src/gprs/v42bis.c b/src/gprs/v42bis.c deleted file mode 100644 index a04b0af5c..000000000 --- a/src/gprs/v42bis.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * v42bis.c - * - * Written by Steve Underwood - * - * Copyright (C) 2005, 2011 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1, - * as published by the Free Software Foundation. - * - * 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED. - Currently it performs the core compression and decompression functions OK. - However, a number of the bells and whistles in V.42bis are incomplete. */ - -/*! \file */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -#define span_log(x,y,msg, ...) DEBUGP(DV42BIS,msg, ##__VA_ARGS__) -#define span_log_init(x,y,z) -#define span_log_set_protocol(x,y) - - -#define FALSE 0 -#define TRUE 1 - -/* Fixed parameters from the spec. */ -/* Character size (bits) */ -#define V42BIS_N3 8 -/* Number of characters in the alphabet */ -#define V42BIS_N4 256 -/* Index number of first dictionary entry used to store a string */ -#define V42BIS_N5 (V42BIS_N4 + V42BIS_N6) -/* Number of control codewords */ -#define V42BIS_N6 3 -/* V.42bis/9.2 */ -#define V42BIS_ESC_STEP 51 - -/* Compreeibility monitoring parameters for assessing automated switches between - transparent and compressed mode */ -#define COMPRESSIBILITY_MONITOR (256*V42BIS_N3) -#define COMPRESSIBILITY_MONITOR_HYSTERESIS 11 - -/* Control code words in compressed mode */ -enum -{ - V42BIS_ETM = 0, /* Enter transparent mode */ - V42BIS_FLUSH = 1, /* Flush data */ - V42BIS_STEPUP = 2 /* Step up codeword size */ -}; - -/* Command codes in transparent mode */ -enum -{ - V42BIS_ECM = 0, /* Enter compression mode */ - V42BIS_EID = 1, /* Escape character in data */ - V42BIS_RESET = 2 /* Force reinitialisation */ -}; - -static __inline__ void push_octet(v42bis_comp_state_t *s, int octet) -{ - s->output_buf[s->output_octet_count++] = (uint8_t) octet; - if (s->output_octet_count >= s->max_output_len) - { - s->handler(s->user_data, s->output_buf, s->output_octet_count); - s->output_octet_count = 0; - } -} -/*- End of function --------------------------------------------------------*/ - -static __inline__ void push_octets(v42bis_comp_state_t *s, const uint8_t buf[], int len) -{ - int i; - int chunk; - - i = 0; - while ((s->output_octet_count + len - i) >= s->max_output_len) - { - chunk = s->max_output_len - s->output_octet_count; - memcpy(&s->output_buf[s->output_octet_count], &buf[i], chunk); - s->handler(s->user_data, s->output_buf, s->max_output_len); - s->output_octet_count = 0; - i += chunk; - } - chunk = len - i; - if (chunk > 0) - { - memcpy(&s->output_buf[s->output_octet_count], &buf[i], chunk); - s->output_octet_count += chunk; - } -} -/*- End of function --------------------------------------------------------*/ - -static __inline__ void push_compressed_code(v42bis_comp_state_t *s, int code) -{ - s->bit_buffer |= code << s->bit_count; - s->bit_count += s->v42bis_parm_c2; - while (s->bit_count >= 8) - { - push_octet(s, s->bit_buffer & 0xFF); - s->bit_buffer >>= 8; - s->bit_count -= 8; - } -} -/*- End of function --------------------------------------------------------*/ - -static __inline__ void push_octet_alignment(v42bis_comp_state_t *s) -{ - if ((s->bit_count & 7)) - { - s->bit_count += (8 - (s->bit_count & 7)); - while (s->bit_count >= 8) - { - push_octet(s, s->bit_buffer & 0xFF); - s->bit_buffer >>= 8; - s->bit_count -= 8; - } - } -} -/*- End of function --------------------------------------------------------*/ - -static __inline__ void flush_octets(v42bis_comp_state_t *s) -{ - if (s->output_octet_count > 0) - { - s->handler(s->user_data, s->output_buf, s->output_octet_count); - s->output_octet_count = 0; - } -} -/*- End of function --------------------------------------------------------*/ - -static void dictionary_init(v42bis_comp_state_t *s) -{ - int i; - - memset(s->dict, 0, sizeof(s->dict)); - for (i = 0; i < V42BIS_N4; i++) - s->dict[i + V42BIS_N6].node_octet = i; - s->v42bis_parm_c1 = V42BIS_N5; - s->v42bis_parm_c2 = V42BIS_N3 + 1; - s->v42bis_parm_c3 = V42BIS_N4 << 1; - s->last_matched = 0; - s->update_at = 0; - s->last_added = 0; - s->bit_buffer = 0; - s->bit_count = 0; - s->flushed_length = 0; - s->string_length = 0; - s->escape_code = 0; - s->transparent = TRUE; - s->escaped = FALSE; - s->compression_performance = COMPRESSIBILITY_MONITOR; -} -/*- End of function --------------------------------------------------------*/ - -static uint16_t match_octet(v42bis_comp_state_t *s, uint16_t at, uint8_t octet) -{ - uint16_t e; - - if (at == 0) - return octet + V42BIS_N6; - e = s->dict[at].child; - while (e) - { - if (s->dict[e].node_octet == octet) - return e; - e = s->dict[e].next; - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -static uint16_t add_octet_to_dictionary(v42bis_comp_state_t *s, uint16_t at, uint8_t octet) -{ - uint16_t newx; - uint16_t next; - uint16_t e; - - newx = s->v42bis_parm_c1; - s->dict[newx].node_octet = octet; - s->dict[newx].parent = at; - s->dict[newx].child = 0; - s->dict[newx].next = s->dict[at].child; - s->dict[at].child = newx; - next = newx; - /* 6.5 Recovering a dictionary entry to use next */ - do - { - /* 6.5(a) and (b) */ - if (++next == s->v42bis_parm_n2) - next = V42BIS_N5; - } - while (s->dict[next].child); - /* 6.5(c) We need to reuse a leaf node */ - if (s->dict[next].parent) - { - /* 6.5(d) Detach the leaf node from its parent, and re-use it */ - e = s->dict[next].parent; - if (s->dict[e].child == next) - { - s->dict[e].child = s->dict[next].next; - } - else - { - e = s->dict[e].child; - while (s->dict[e].next != next) - e = s->dict[e].next; - s->dict[e].next = s->dict[next].next; - } - } - s->v42bis_parm_c1 = next; - return newx; -} -/*- End of function --------------------------------------------------------*/ - -static void send_string(v42bis_comp_state_t *s) -{ - push_octets(s, s->string, s->string_length); - s->string_length = 0; - s->flushed_length = 0; -} -/*- End of function --------------------------------------------------------*/ - -static void expand_codeword_to_string(v42bis_comp_state_t *s, uint16_t code) -{ - int i; - uint16_t p; - - /* Work out the length */ - for (i = 0, p = code; p; i++) - p = s->dict[p].parent; - s->string_length += i; - /* Now expand the known length of string */ - i = s->string_length - 1; - for (p = code; p; ) - { - s->string[i--] = s->dict[p].node_octet; - p = s->dict[p].parent; - } -} -/*- End of function --------------------------------------------------------*/ - -static void send_encoded_data(v42bis_comp_state_t *s, uint16_t code) -{ - int i; - - /* Update compressibility metric */ - /* Integrate at the compressed bit rate, and leak at the pre-compression bit rate */ - s->compression_performance += (s->v42bis_parm_c2 - s->compression_performance*s->string_length*V42BIS_N3/COMPRESSIBILITY_MONITOR); - if (s->transparent) - { - for (i = 0; i < s->string_length; i++) - { - push_octet(s, s->string[i]); - if (s->string[i] == s->escape_code) - { - push_octet(s, V42BIS_EID); - s->escape_code += V42BIS_ESC_STEP; - } - } - } - else - { - /* Allow for any escape octets in the string */ - for (i = 0; i < s->string_length; i++) - { - if (s->string[i] == s->escape_code) - s->escape_code += V42BIS_ESC_STEP; - } - /* 7.4 Encoding - we now have the longest matchable string, and will need to output the code for it. */ - while (code >= s->v42bis_parm_c3) - { - /* We need to increase the codeword size */ - /* 7.4(a) */ - push_compressed_code(s, V42BIS_STEPUP); - /* 7.4(b) */ - s->v42bis_parm_c2++; - /* 7.4(c) */ - s->v42bis_parm_c3 <<= 1; - /* 7.4(d) this might need to be repeated, so we loop */ - } - /* 7.5 Transfer - output the last state of the string */ - push_compressed_code(s, code); - } - s->string_length = 0; - s->flushed_length = 0; -} -/*- End of function --------------------------------------------------------*/ - -static void go_compressed(v42bis_state_t *ss) -{ - v42bis_comp_state_t *s; - - s = &ss->compress; - if (!s->transparent) - return; - span_log(&ss->logging, SPAN_LOG_FLOW, "Changing to compressed mode\n"); - /* Switch out of transparent now, between codes. We need to send the octet which did not - match, just before switching. */ - if (s->last_matched) - { - s->update_at = s->last_matched; - send_encoded_data(s, s->last_matched); - s->last_matched = 0; - } - push_octet(s, s->escape_code); - push_octet(s, V42BIS_ECM); - s->bit_buffer = 0; - s->transparent = FALSE; -} -/*- End of function --------------------------------------------------------*/ - -static void go_transparent(v42bis_state_t *ss) -{ - v42bis_comp_state_t *s; - - s = &ss->compress; - if (s->transparent) - return; - span_log(&ss->logging, SPAN_LOG_FLOW, "Changing to transparent mode\n"); - /* Switch into transparent now, between codes, and the unmatched octet should - go out in transparent mode, just below */ - if (s->last_matched) - { - s->update_at = s->last_matched; - send_encoded_data(s, s->last_matched); - s->last_matched = 0; - } - s->last_added = 0; - push_compressed_code(s, V42BIS_ETM); - push_octet_alignment(s); - s->transparent = TRUE; -} -/*- End of function --------------------------------------------------------*/ - -static void monitor_for_mode_change(v42bis_state_t *ss) -{ - v42bis_comp_state_t *s; - - s = &ss->compress; - switch (s->compression_mode) - { - case V42BIS_COMPRESSION_MODE_DYNAMIC: - /* 7.8 Data compressibility test */ - if (s->transparent) - { - if (s->compression_performance < COMPRESSIBILITY_MONITOR - COMPRESSIBILITY_MONITOR_HYSTERESIS) - { - /* 7.8.1 Transition to compressed mode */ - go_compressed(ss); - } - } - else - { - if (s->compression_performance > COMPRESSIBILITY_MONITOR) - { - /* 7.8.2 Transition to transparent mode */ - go_transparent(ss); - } - } - /* 7.8.3 Reset function - TODO */ - break; - case V42BIS_COMPRESSION_MODE_ALWAYS: - if (s->transparent) - go_compressed(ss); - break; - case V42BIS_COMPRESSION_MODE_NEVER: - if (!s->transparent) - go_transparent(ss); - break; - } -} -/*- End of function --------------------------------------------------------*/ - -static int v42bis_comp_init(v42bis_comp_state_t *s, - int p1, - int p2, - put_msg_func_t handler, - void *user_data, - int max_output_len) -{ - memset(s, 0, sizeof(*s)); - s->v42bis_parm_n2 = p1; - s->v42bis_parm_n7 = p2; - s->handler = handler; - s->user_data = user_data; - s->max_output_len = (max_output_len < V42BIS_MAX_OUTPUT_LENGTH) ? max_output_len : V42BIS_MAX_OUTPUT_LENGTH; - s->output_octet_count = 0; - dictionary_init(s); - return 0; -} -/*- End of function --------------------------------------------------------*/ - -static int comp_exit(v42bis_comp_state_t *s) -{ - s->v42bis_parm_n2 = 0; - return 0; -} -/*- End of function --------------------------------------------------------*/ - -SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *ss, const uint8_t buf[], int len) -{ - v42bis_comp_state_t *s; - int i; - uint16_t code; - - s = &ss->compress; - if (!s->v42bis_parm_p0) - { - /* Compression is off - just push the incoming data out */ - push_octets(s, buf, len); - return 0; - } - for (i = 0; i < len; ) - { - /* 6.4 Add the string to the dictionary */ - if (s->update_at) - { - if (match_octet(s, s->update_at, buf[i]) == 0) - s->last_added = add_octet_to_dictionary(s, s->update_at, buf[i]); - s->update_at = 0; - } - /* Match string */ - while (i < len) - { - code = match_octet(s, s->last_matched, buf[i]); - if (code == 0) - { - s->update_at = s->last_matched; - send_encoded_data(s, s->last_matched); - s->last_matched = 0; - break; - } - if (code == s->last_added) - { - s->last_added = 0; - send_encoded_data(s, s->last_matched); - s->last_matched = 0; - break; - } - s->last_matched = code; - /* 6.3(b) If the string matches a dictionary entry, and the entry is not that entry - created by the last invocation of the string matching procedure, then the - next character shall be read and appended to the string and this step - repeated. */ - s->string[s->string_length++] = buf[i++]; - /* 6.4(a) The string must not exceed N7 in length */ - if (s->string_length + s->flushed_length == s->v42bis_parm_n7) - { - send_encoded_data(s, s->last_matched); - s->last_matched = 0; - break; - } - } - monitor_for_mode_change(ss); - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *ss) -{ - v42bis_comp_state_t *s; - int len; - - s = &ss->compress; - if (s->update_at) - return 0; - if (s->last_matched) - { - len = s->string_length; - send_encoded_data(s, s->last_matched); - s->flushed_length += len; - } - if (!s->transparent) - { - s->update_at = s->last_matched; - s->last_matched = 0; - s->flushed_length = 0; - push_compressed_code(s, V42BIS_FLUSH); - push_octet_alignment(s); - } - flush_octets(s); - return 0; -} -/*- End of function --------------------------------------------------------*/ - -SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *ss, const uint8_t buf[], int len) -{ - v42bis_comp_state_t *s; - int i; - int j; - int yyy; - uint16_t code; - uint16_t p; - uint8_t ch; - uint8_t in; - - s = &ss->decompress; - if (!s->v42bis_parm_p0) - { - /* Compression is off - just push the incoming data out */ - push_octets(s, buf, len); - return 0; - } - for (i = 0; i < len; ) - { - if (s->transparent) - { - in = buf[i]; - if (s->escaped) - { - /* Command */ - s->escaped = FALSE; - switch (in) - { - case V42BIS_ECM: - /* Enter compressed mode */ - span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_ECM\n"); - send_string(s); - s->transparent = FALSE; - s->update_at = s->last_matched; - s->last_matched = 0; - i++; - continue; - case V42BIS_EID: - /* Escape symbol */ - span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_EID\n"); - in = s->escape_code; - s->escape_code += V42BIS_ESC_STEP; - break; - case V42BIS_RESET: - /* Reset dictionary */ - span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_RESET\n"); - /* TODO: */ - send_string(s); - dictionary_init(s); - i++; - continue; - default: - span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_???? - %" PRIu32 "\n", in); - return -1; - } - } - else if (in == s->escape_code) - { - s->escaped = TRUE; - i++; - continue; - } - - yyy = TRUE; - for (j = 0; j < 2 && yyy; j++) - { - if (s->update_at) - { - if (match_octet(s, s->update_at, in) == 0) - s->last_added = add_octet_to_dictionary(s, s->update_at, in); - s->update_at = 0; - } - - code = match_octet(s, s->last_matched, in); - if (code == 0) - { - s->update_at = s->last_matched; - send_string(s); - s->last_matched = 0; - } - else if (code == s->last_added) - { - s->last_added = 0; - send_string(s); - s->last_matched = 0; - } - else - { - s->last_matched = code; - s->string[s->string_length++] = in; - if (s->string_length + s->flushed_length == s->v42bis_parm_n7) - { - send_string(s); - s->last_matched = 0; - } - i++; - yyy = FALSE; - } - } - } - else - { - /* Get code from input */ - while (s->bit_count < s->v42bis_parm_c2 && i < len) - { - s->bit_buffer |= buf[i++] << s->bit_count; - s->bit_count += 8; - } - if (s->bit_count < s->v42bis_parm_c2) - continue; - code = s->bit_buffer & ((1 << s->v42bis_parm_c2) - 1); - s->bit_buffer >>= s->v42bis_parm_c2; - s->bit_count -= s->v42bis_parm_c2; - - if (code < V42BIS_N6) - { - /* We have a control code. */ - switch (code) - { - case V42BIS_ETM: - /* Enter transparent mode */ - span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_ETM\n"); - s->bit_count = 0; - s->transparent = TRUE; - s->last_matched = 0; - s->last_added = 0; - break; - case V42BIS_FLUSH: - /* Flush signal */ - span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_FLUSH\n"); - s->bit_count = 0; - break; - case V42BIS_STEPUP: - /* Increase code word size */ - span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_STEPUP\n"); - s->v42bis_parm_c2++; - s->v42bis_parm_c3 <<= 1; - if (s->v42bis_parm_c2 > (s->v42bis_parm_n2 >> 3)) - return -1; - break; - } - continue; - } - /* Regular codeword */ - if (code == s->v42bis_parm_c1) - return -1; - expand_codeword_to_string(s, code); - if (s->update_at) - { - ch = s->string[0]; - if ((p = match_octet(s, s->update_at, ch)) == 0) - { - s->last_added = add_octet_to_dictionary(s, s->update_at, ch); - if (code == s->v42bis_parm_c1) - return -1; - } - else if (p == s->last_added) - { - s->last_added = 0; - } - } - s->update_at = ((s->string_length + s->flushed_length) == s->v42bis_parm_n7) ? 0 : code; - /* Allow for any escapes which may be in this string */ - for (j = 0; j < s->string_length; j++) - { - if (s->string[j] == s->escape_code) - s->escape_code += V42BIS_ESC_STEP; - } - send_string(s); - } - } - return 0; -} -/*- End of function --------------------------------------------------------*/ - -SPAN_DECLARE(int) v42bis_decompress_flush(v42bis_state_t *ss) -{ - v42bis_comp_state_t *s; - int len; - - s = &ss->decompress; - len = s->string_length; - send_string(s); - s->flushed_length += len; - flush_octets(s); - return 0; -} -/*- End of function --------------------------------------------------------*/ - -SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode) -{ - s->compress.compression_mode = mode; -} -/*- End of function --------------------------------------------------------*/ - -SPAN_DECLARE(v42bis_state_t *) v42bis_init(const void *ctx, - v42bis_state_t *s, - int negotiated_p0, - int negotiated_p1, - int negotiated_p2, - put_msg_func_t encode_handler, - void *encode_user_data, - int max_encode_len, - put_msg_func_t decode_handler, - void *decode_user_data, - int max_decode_len) -{ - int ret; - - if (negotiated_p1 < V42BIS_MIN_DICTIONARY_SIZE || negotiated_p1 > 65535) - return NULL; - if (negotiated_p2 < V42BIS_MIN_STRING_SIZE || negotiated_p2 > V42BIS_MAX_STRING_SIZE) - return NULL; - if (s == NULL) - { - if ((s = (v42bis_state_t *) talloc_zero_size(ctx,sizeof(*s))) == NULL) - return NULL; - } - memset(s, 0, sizeof(*s)); - span_log_init(&s->logging, SPAN_LOG_NONE, NULL); - span_log_set_protocol(&s->logging, "V.42bis"); - - if ((ret = v42bis_comp_init(&s->compress, negotiated_p1, negotiated_p2, encode_handler, encode_user_data, max_encode_len))) - return NULL; - if ((ret = v42bis_comp_init(&s->decompress, negotiated_p1, negotiated_p2, decode_handler, decode_user_data, max_decode_len))) - { - comp_exit(&s->compress); - return NULL; - } - s->compress.v42bis_parm_p0 = negotiated_p0 & 2; - s->decompress.v42bis_parm_p0 = negotiated_p0 & 1; - - return s; -} -/*- End of function --------------------------------------------------------*/ - -SPAN_DECLARE(int) v42bis_release(v42bis_state_t *s) -{ - return 0; -} -/*- End of function --------------------------------------------------------*/ - -SPAN_DECLARE(int) v42bis_free(v42bis_state_t *s) -{ - comp_exit(&s->compress); - comp_exit(&s->decompress); - talloc_free(s); - return 0; -} -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ diff --git a/src/libbsc/abis_rsl.c b/src/libbsc/abis_rsl.c index 66cda8200..75229a55f 100644 --- a/src/libbsc/abis_rsl.c +++ b/src/libbsc/abis_rsl.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include @@ -46,6 +46,7 @@ #include #include #include +#include #define RSL_ALLOC_SIZE 1024 #define RSL_ALLOC_HEADROOM 128 diff --git a/src/libbsc/bsc_api.c b/src/libbsc/bsc_api.c index c60f8182a..a0ba69a91 100644 --- a/src/libbsc/bsc_api.c +++ b/src/libbsc/bsc_api.c @@ -30,9 +30,8 @@ #include #include #include -#include #include -#include +#include #include #include diff --git a/src/libbsc/bsc_init.c b/src/libbsc/bsc_init.c index 78ca2ab4d..a99eea27f 100644 --- a/src/libbsc/bsc_init.c +++ b/src/libbsc/bsc_init.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include diff --git a/src/libbsc/bsc_vty.c b/src/libbsc/bsc_vty.c index d55c6eb30..abfff0cd5 100644 --- a/src/libbsc/bsc_vty.c +++ b/src/libbsc/bsc_vty.c @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -44,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -56,8 +56,8 @@ #include #include #include -#include #include +#include #include @@ -1021,26 +1021,6 @@ DEFUN(show_ts, return CMD_SUCCESS; } -static void subscr_dump_vty(struct vty *vty, struct vlr_subscr *vsub) -{ - OSMO_ASSERT(vsub); - if (strlen(vsub->name)) - vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE); - if (strlen(vsub->msisdn)) - vty_out(vty, " Extension: %s%s", vsub->msisdn, - VTY_NEWLINE); - if (strlen(vsub->imsi)) - vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE); - if (vsub->tmsi != GSM_RESERVED_TMSI) - vty_out(vty, " TMSI: %08X%s", vsub->tmsi, - VTY_NEWLINE); - if (vsub->tmsi_new != GSM_RESERVED_TMSI) - vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new, - VTY_NEWLINE); - - vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE); -} - static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub) { if (strlen(bsub->imsi)) @@ -1166,9 +1146,9 @@ static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan) vty_out(vty, " Channel Mode / Codec: %s%s", get_value_string(gsm48_cmode_names, lchan->tch_mode), VTY_NEWLINE); - if (lchan->conn && lchan->conn->vsub) { + if (lchan->conn && lchan->conn->bsub) { vty_out(vty, " Subscriber:%s", VTY_NEWLINE); - subscr_dump_vty(vty, lchan->conn->vsub); + bsc_subscr_dump_vty(vty, lchan->conn->bsub); } else vty_out(vty, " No Subscriber%s", VTY_NEWLINE); if (is_ipaccess_bts(lchan->ts->trx->bts)) { diff --git a/src/libbsc/chan_alloc.c b/src/libbsc/chan_alloc.c index 33b79a0b2..4192d65f7 100644 --- a/src/libbsc/chan_alloc.c +++ b/src/libbsc/chan_alloc.c @@ -32,6 +32,7 @@ #include #include #include +#include #include diff --git a/src/libbsc/gsm_04_08_utils.c b/src/libbsc/gsm_04_08_utils.c index 7c5e0e97a..109beda49 100644 --- a/src/libbsc/gsm_04_08_utils.c +++ b/src/libbsc/gsm_04_08_utils.c @@ -32,11 +32,11 @@ #include #include -#include #include #include #include #include +#include /* should ip.access BTS use direct RTP streams between each other (1), * or should OpenBSC always act as RTP relay/proxy in between (0) ? */ diff --git a/src/libbsc/handover_logic.c b/src/libbsc/handover_logic.c index 14566cfa1..8ced74fd5 100644 --- a/src/libbsc/handover_logic.c +++ b/src/libbsc/handover_logic.c @@ -33,14 +33,14 @@ #include #include #include -#include #include #include #include #include #include #include -#include +#include +#include struct bsc_handover { struct llist_head list; @@ -262,7 +262,7 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan) net = new_lchan->ts->trx->bts->network; LOGP(DHO, LOGL_INFO, "Subscriber %s HO from BTS %u->%u on ARFCN " - "%u->%u\n", vlr_subscr_name(ho->old_lchan->conn->vsub), + "%u->%u\n", bsc_subscr_name(ho->old_lchan->conn->bsub), ho->old_lchan->ts->trx->bts->nr, new_lchan->ts->trx->bts->nr, ho->old_lchan->ts->trx->arfcn, new_lchan->ts->trx->arfcn); diff --git a/src/libbsc/net_init.c b/src/libbsc/net_init.c index 9d5431964..0dd37534e 100644 --- a/src/libbsc/net_init.c +++ b/src/libbsc/net_init.c @@ -20,6 +20,7 @@ #include #include #include +#include struct gsm_network *bsc_network_init(void *ctx, uint16_t country_code, diff --git a/src/libbsc/paging.c b/src/libbsc/paging.c index e19c2d1c4..02212a352 100644 --- a/src/libbsc/paging.c +++ b/src/libbsc/paging.c @@ -50,7 +50,6 @@ #include #include #include -#include void *tall_paging_ctx; diff --git a/src/libbsc/system_information.c b/src/libbsc/system_information.c index dcabbbdd1..fe0b23d02 100644 --- a/src/libbsc/system_information.c +++ b/src/libbsc/system_information.c @@ -30,13 +30,15 @@ #include #include #include +#include +#include #include -#include #include #include #include #include +#include /* * DCS1800 and PCS1900 have overlapping ARFCNs. We would need to set the diff --git a/src/libcommon-cs/common_cs.c b/src/libcommon-cs/common_cs.c index d6dff95df..fbcfa1d66 100644 --- a/src/libcommon-cs/common_cs.c +++ b/src/libcommon-cs/common_cs.c @@ -23,12 +23,13 @@ #include #include +#include #include #include #include #include -#include +#include /* Warning: if bsc_network_init() is not called, some of the members of * gsm_network are not initialized properly and must not be used! (In diff --git a/src/libcommon/Makefile.am b/src/libcommon/Makefile.am index 0b258c08a..6cfebc2da 100644 --- a/src/libcommon/Makefile.am +++ b/src/libcommon/Makefile.am @@ -23,25 +23,7 @@ libcommon_a_SOURCES = \ debug.c \ gsm_data.c \ gsm_data_shared.c \ - gsup_client.c \ - oap_client.c \ socket.c \ talloc_ctx.c \ gsm_subscriber_base.c \ $(NULL) - -noinst_PROGRAMS = \ - gsup_test_client \ - $(NULL) - -gsup_test_client_SOURCES = \ - gsup_test_client.c \ - $(NULL) -gsup_test_client_LDADD = \ - libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) \ - -lrt \ - $(NULL) diff --git a/src/libcommon/gsm_data.c b/src/libcommon/gsm_data.c index 7be224082..077029a9f 100644 --- a/src/libcommon/gsm_data.c +++ b/src/libcommon/gsm_data.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/src/libcommon/gsm_subscriber_base.c b/src/libcommon/gsm_subscriber_base.c index 018ed210c..a2f6b2d1f 100644 --- a/src/libcommon/gsm_subscriber_base.c +++ b/src/libcommon/gsm_subscriber_base.c @@ -31,34 +31,7 @@ #include #include #include -#include LLIST_HEAD(active_subscribers); void *tall_subscr_ctx; -/* return static buffer with printable name of VLR subscriber */ -const char *vlr_subscr_name(struct vlr_subscr *vsub) -{ - static char buf[32]; - if (!vsub) - return "unknown"; - if (vsub->msisdn[0]) - snprintf(buf, sizeof(buf), "MSISDN:%s", vsub->msisdn); - else if (vsub->imsi[0]) - snprintf(buf, sizeof(buf), "IMSI:%s", vsub->imsi); - else if (vsub->tmsi != GSM_RESERVED_TMSI) - snprintf(buf, sizeof(buf), "TMSI:0x%08x", vsub->tmsi); - else if (vsub->tmsi_new != GSM_RESERVED_TMSI) - snprintf(buf, sizeof(buf), "TMSI(new):0x%08x", vsub->tmsi_new); - else - return "unknown"; - buf[sizeof(buf)-1] = '\0'; - return buf; -} - -const char *vlr_subscr_msisdn_or_name(struct vlr_subscr *vsub) -{ - if (!vsub || !vsub->msisdn[0]) - return vlr_subscr_name(vsub); - return vsub->msisdn; -} diff --git a/src/libcommon/gsup_client.c b/src/libcommon/gsup_client.c deleted file mode 100644 index fd65e7b0b..000000000 --- a/src/libcommon/gsup_client.c +++ /dev/null @@ -1,347 +0,0 @@ -/* Generic Subscriber Update Protocol client */ - -/* (C) 2014-2016 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Jacob Erlbeck - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include - -#include -#include -#include -#include - -#include - -#include -#include - -extern void *tall_bsc_ctx; - -static void start_test_procedure(struct gsup_client *gsupc); - -static void gsup_client_send_ping(struct gsup_client *gsupc) -{ - struct msgb *msg = gsup_client_msgb_alloc(); - - msg->l2h = msgb_put(msg, 1); - msg->l2h[0] = IPAC_MSGT_PING; - ipa_msg_push_header(msg, IPAC_PROTO_IPACCESS); - ipa_client_conn_send(gsupc->link, msg); -} - -static int gsup_client_connect(struct gsup_client *gsupc) -{ - int rc; - - if (gsupc->is_connected) - return 0; - - if (osmo_timer_pending(&gsupc->connect_timer)) { - LOGP(DLGSUP, LOGL_DEBUG, - "GSUP connect: connect timer already running\n"); - osmo_timer_del(&gsupc->connect_timer); - } - - if (osmo_timer_pending(&gsupc->ping_timer)) { - LOGP(DLGSUP, LOGL_DEBUG, - "GSUP connect: ping timer already running\n"); - osmo_timer_del(&gsupc->ping_timer); - } - - if (ipa_client_conn_clear_queue(gsupc->link) > 0) - LOGP(DLGSUP, LOGL_DEBUG, "GSUP connect: discarded stored messages\n"); - - rc = ipa_client_conn_open(gsupc->link); - - if (rc >= 0) { - LOGP(DLGSUP, LOGL_NOTICE, "GSUP connecting to %s:%d\n", - gsupc->link->addr, gsupc->link->port); - return 0; - } - - LOGP(DLGSUP, LOGL_ERROR, "GSUP failed to connect to %s:%d: %s\n", - gsupc->link->addr, gsupc->link->port, strerror(-rc)); - - if (rc == -EBADF || rc == -ENOTSOCK || rc == -EAFNOSUPPORT || - rc == -EINVAL) - return rc; - - osmo_timer_schedule(&gsupc->connect_timer, - GSUP_CLIENT_RECONNECT_INTERVAL, 0); - - LOGP(DLGSUP, LOGL_INFO, "Scheduled timer to retry GSUP connect to %s:%d\n", - gsupc->link->addr, gsupc->link->port); - - return 0; -} - -static void connect_timer_cb(void *gsupc_) -{ - struct gsup_client *gsupc = gsupc_; - - if (gsupc->is_connected) - return; - - gsup_client_connect(gsupc); -} - -static void client_send(struct gsup_client *gsupc, int proto_ext, - struct msgb *msg_tx) -{ - ipa_prepend_header_ext(msg_tx, proto_ext); - ipa_msg_push_header(msg_tx, IPAC_PROTO_OSMO); - ipa_client_conn_send(gsupc->link, msg_tx); - /* msg_tx is now queued and will be freed. */ -} - -static void gsup_client_oap_register(struct gsup_client *gsupc) -{ - struct msgb *msg_tx; - int rc; - rc = oap_client_register(&gsupc->oap_state, &msg_tx); - - if ((rc < 0) || (!msg_tx)) { - LOGP(DLGSUP, LOGL_ERROR, "GSUP OAP set up, but cannot register.\n"); - return; - } - - client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx); -} - -static void gsup_client_updown_cb(struct ipa_client_conn *link, int up) -{ - struct gsup_client *gsupc = link->data; - - LOGP(DLGSUP, LOGL_INFO, "GSUP link to %s:%d %s\n", - link->addr, link->port, up ? "UP" : "DOWN"); - - gsupc->is_connected = up; - - if (up) { - start_test_procedure(gsupc); - - if (gsupc->oap_state.state == OAP_INITIALIZED) - gsup_client_oap_register(gsupc); - - osmo_timer_del(&gsupc->connect_timer); - } else { - osmo_timer_del(&gsupc->ping_timer); - - osmo_timer_schedule(&gsupc->connect_timer, - GSUP_CLIENT_RECONNECT_INTERVAL, 0); - } -} - -static int gsup_client_oap_handle(struct gsup_client *gsupc, struct msgb *msg_rx) -{ - int rc; - struct msgb *msg_tx; - - /* If the oap_state is disabled, this will reject the messages. */ - rc = oap_client_handle(&gsupc->oap_state, msg_rx, &msg_tx); - msgb_free(msg_rx); - if (rc < 0) - return rc; - - if (msg_tx) - client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx); - - return 0; -} - -static int gsup_client_read_cb(struct ipa_client_conn *link, struct msgb *msg) -{ - struct ipaccess_head *hh = (struct ipaccess_head *) msg->data; - struct ipaccess_head_ext *he = (struct ipaccess_head_ext *) msgb_l2(msg); - struct gsup_client *gsupc = (struct gsup_client *)link->data; - int rc; - struct ipaccess_unit ipa_dev = { - /* see gsup_client_create() on const vs non-const */ - .unit_name = (char*)gsupc->unit_name, - }; - - OSMO_ASSERT(ipa_dev.unit_name); - - msg->l2h = &hh->data[0]; - - rc = ipaccess_bts_handle_ccm(link, &ipa_dev, msg); - - if (rc < 0) { - LOGP(DLGSUP, LOGL_NOTICE, - "GSUP received an invalid IPA/CCM message from %s:%d\n", - link->addr, link->port); - /* Link has been closed */ - gsupc->is_connected = 0; - msgb_free(msg); - return -1; - } - - if (rc == 1) { - uint8_t msg_type = *(msg->l2h); - /* CCM message */ - if (msg_type == IPAC_MSGT_PONG) { - LOGP(DLGSUP, LOGL_DEBUG, "GSUP receiving PONG\n"); - gsupc->got_ipa_pong = 1; - } - - msgb_free(msg); - return 0; - } - - if (hh->proto != IPAC_PROTO_OSMO) - goto invalid; - - if (!he || msgb_l2len(msg) < sizeof(*he)) - goto invalid; - - msg->l2h = &he->data[0]; - - if (he->proto == IPAC_PROTO_EXT_GSUP) { - OSMO_ASSERT(gsupc->read_cb != NULL); - gsupc->read_cb(gsupc, msg); - /* expecting read_cb() to free msg */ - } else if (he->proto == IPAC_PROTO_EXT_OAP) { - return gsup_client_oap_handle(gsupc, msg); - /* gsup_client_oap_handle frees msg */ - } else - goto invalid; - - return 0; - -invalid: - LOGP(DLGSUP, LOGL_NOTICE, - "GSUP received an invalid IPA message from %s:%d, size = %d\n", - link->addr, link->port, msgb_length(msg)); - - msgb_free(msg); - return -1; -} - -static void ping_timer_cb(void *gsupc_) -{ - struct gsup_client *gsupc = gsupc_; - - LOGP(DLGSUP, LOGL_INFO, "GSUP ping callback (%s, %s PONG)\n", - gsupc->is_connected ? "connected" : "not connected", - gsupc->got_ipa_pong ? "got" : "didn't get"); - - if (gsupc->got_ipa_pong) { - start_test_procedure(gsupc); - return; - } - - LOGP(DLGSUP, LOGL_NOTICE, "GSUP ping timed out, reconnecting\n"); - ipa_client_conn_close(gsupc->link); - gsupc->is_connected = 0; - - gsup_client_connect(gsupc); -} - -static void start_test_procedure(struct gsup_client *gsupc) -{ - osmo_timer_setup(&gsupc->ping_timer, ping_timer_cb, gsupc); - - gsupc->got_ipa_pong = 0; - osmo_timer_schedule(&gsupc->ping_timer, GSUP_CLIENT_PING_INTERVAL, 0); - LOGP(DLGSUP, LOGL_DEBUG, "GSUP sending PING\n"); - gsup_client_send_ping(gsupc); -} - -struct gsup_client *gsup_client_create(const char *unit_name, - const char *ip_addr, - unsigned int tcp_port, - gsup_client_read_cb_t read_cb, - struct oap_client_config *oapc_config) -{ - struct gsup_client *gsupc; - int rc; - - gsupc = talloc_zero(tall_bsc_ctx, struct gsup_client); - OSMO_ASSERT(gsupc); - - /* struct ipaccess_unit has a non-const unit_name, so let's copy to be - * able to have a non-const unit_name here as well. To not taint the - * public gsup_client API, let's store it in a const char* anyway. */ - gsupc->unit_name = talloc_strdup(gsupc, unit_name); - OSMO_ASSERT(gsupc->unit_name); - - /* a NULL oapc_config will mark oap_state disabled. */ - rc = oap_client_init(oapc_config, &gsupc->oap_state); - if (rc != 0) - goto failed; - - gsupc->link = ipa_client_conn_create(gsupc, - /* no e1inp */ NULL, - 0, - ip_addr, tcp_port, - gsup_client_updown_cb, - gsup_client_read_cb, - /* default write_cb */ NULL, - gsupc); - if (!gsupc->link) - goto failed; - - osmo_timer_setup(&gsupc->connect_timer, connect_timer_cb, gsupc); - - rc = gsup_client_connect(gsupc); - - if (rc < 0) - goto failed; - - gsupc->read_cb = read_cb; - - return gsupc; - -failed: - gsup_client_destroy(gsupc); - return NULL; -} - -void gsup_client_destroy(struct gsup_client *gsupc) -{ - osmo_timer_del(&gsupc->connect_timer); - osmo_timer_del(&gsupc->ping_timer); - - if (gsupc->link) { - ipa_client_conn_close(gsupc->link); - ipa_client_conn_destroy(gsupc->link); - gsupc->link = NULL; - } - talloc_free(gsupc); -} - -int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg) -{ - if (!gsupc || !gsupc->is_connected) { - LOGP(DGPRS, LOGL_ERROR, "GSUP not connected, unable to send %s\n", msgb_hexdump(msg)); - msgb_free(msg); - return -ENOTCONN; - } - - client_send(gsupc, IPAC_PROTO_EXT_GSUP, msg); - - return 0; -} - -struct msgb *gsup_client_msgb_alloc(void) -{ - return msgb_alloc_headroom(4000, 64, __func__); -} diff --git a/src/libcommon/gsup_test_client.c b/src/libcommon/gsup_test_client.c deleted file mode 100644 index b6a8d6b7d..000000000 --- a/src/libcommon/gsup_test_client.c +++ /dev/null @@ -1,298 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -static struct gsup_client *g_gc; - - -/*********************************************************************** - * IMSI Operation - ***********************************************************************/ -static LLIST_HEAD(g_imsi_ops); - -struct imsi_op_stats { - uint32_t num_alloc; - uint32_t num_released; - uint32_t num_rx_success; - uint32_t num_rx_error; - uint32_t num_timeout; -}; - -enum imsi_op_type { - IMSI_OP_SAI, - IMSI_OP_LU, - IMSI_OP_ISD, - _NUM_IMSI_OP -}; - -static const struct value_string imsi_op_names[] = { - { IMSI_OP_SAI, "SAI" }, - { IMSI_OP_LU, "LU" }, - { IMSI_OP_ISD, "ISD" }, - { 0, NULL } -}; - -static struct imsi_op_stats imsi_op_stats[_NUM_IMSI_OP]; - -struct imsi_op { - struct llist_head list; - char imsi[17]; - enum imsi_op_type type; - struct osmo_timer_list timer; -}; - -static struct imsi_op *imsi_op_find(const char *imsi, - enum imsi_op_type type) -{ - struct imsi_op *io; - - llist_for_each_entry(io, &g_imsi_ops, list) { - if (!strcmp(io->imsi, imsi) && io->type == type) - return io; - } - return NULL; -} - -static void imsi_op_timer_cb(void *data); - -static struct imsi_op *imsi_op_alloc(void *ctx, const char *imsi, - enum imsi_op_type type) -{ - struct imsi_op *io; - - if (imsi_op_find(imsi, type)) - return NULL; - - io = talloc_zero(ctx, struct imsi_op); - osmo_strlcpy(io->imsi, imsi, sizeof(io->imsi)); - io->type = type; - osmo_timer_setup(&io->timer, imsi_op_timer_cb, io); - llist_add(&io->list, &g_imsi_ops); - imsi_op_stats[type].num_alloc++; - - return io; -} - -static void imsi_op_release(struct imsi_op *io) -{ - osmo_timer_del(&io->timer); - llist_del(&io->list); - imsi_op_stats[io->type].num_released++; - talloc_free(io); -} - -static void imsi_op_timer_cb(void *data) -{ - struct imsi_op *io = data; - printf("%s: Timer expiration\n", io->imsi); - imsi_op_stats[io->type].num_timeout++; - imsi_op_release(io); -} - -/* allocate + generate + send Send-Auth-Info */ -int req_auth_info(const char *imsi) -{ - struct imsi_op *io = imsi_op_alloc(g_gc, imsi, IMSI_OP_SAI); - struct osmo_gsup_message gsup = {0}; - struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__); - - osmo_strlcpy(gsup.imsi, io->imsi, sizeof(gsup.imsi)); - gsup.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST; - - osmo_gsup_encode(msg, &gsup); - - return gsup_client_send(g_gc, msg); -} - -/* allocate + generate + send Send-Auth-Info */ -int req_loc_upd(const char *imsi) -{ - struct imsi_op *io = imsi_op_alloc(g_gc, imsi, IMSI_OP_LU); - struct osmo_gsup_message gsup = {0}; - struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__); - - osmo_strlcpy(gsup.imsi, io->imsi, sizeof(gsup.imsi)); - gsup.message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST; - - osmo_gsup_encode(msg, &gsup); - - return gsup_client_send(g_gc, msg); -} - -int resp_isd(struct imsi_op *io) -{ - struct osmo_gsup_message gsup = {0}; - struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__); - - osmo_strlcpy(gsup.imsi, io->imsi, sizeof(gsup.imsi)); - gsup.message_type = OSMO_GSUP_MSGT_INSERT_DATA_RESULT; - - osmo_gsup_encode(msg, &gsup); - - imsi_op_release(io); - - return gsup_client_send(g_gc, msg); -} - -/* receive an incoming GSUP message */ -static void imsi_op_rx_gsup(struct imsi_op *io, const struct osmo_gsup_message *gsup) -{ - int is_error = 0; - - if (OSMO_GSUP_IS_MSGT_ERROR(gsup->message_type)) { - imsi_op_stats[io->type].num_rx_error++; - is_error = 1; - } else - imsi_op_stats[io->type].num_rx_success++; - - switch (io->type) { - case IMSI_OP_SAI: - printf("%s; SAI Response%s\n", io->imsi, is_error ? ": ERROR" : ""); - /* now that we have auth tuples, request LU */ - req_loc_upd(io->imsi); - imsi_op_release(io); - break; - case IMSI_OP_LU: - printf("%s; LU Response%s\n", io->imsi, is_error ? ": ERROR" : ""); - imsi_op_release(io); - break; - case IMSI_OP_ISD: - printf("%s; ISD Request%s\n", io->imsi, is_error ? ": ERROR" : ""); - resp_isd(io); - break; - default: - printf("%s: Unknown\n", io->imsi); - imsi_op_release(io); - break; - } -} - -static int op_type_by_gsup_msgt(enum osmo_gsup_message_type msg_type) -{ - switch (msg_type) { - case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: - case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: - return IMSI_OP_SAI; - case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: - case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: - return IMSI_OP_LU; - case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: - return IMSI_OP_ISD; - default: - printf("Unknown GSUP msg_type %u\n", msg_type); - return -1; - } -} - -static int gsupc_read_cb(struct gsup_client *gsupc, struct msgb *msg) -{ - struct osmo_gsup_message gsup_msg = {0}; - struct imsi_op *io; - int rc; - - DEBUGP(DGPRS, "Rx GSUP %s\n", osmo_hexdump(msgb_l2(msg), msgb_l2len(msg))); - - rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup_msg); - if (rc < 0) - return rc; - - if (!gsup_msg.imsi[0]) - return -1; - - rc = op_type_by_gsup_msgt(gsup_msg.message_type); - if (rc < 0) - return rc; - - switch (rc) { - case IMSI_OP_SAI: - case IMSI_OP_LU: - io = imsi_op_find(gsup_msg.imsi, rc); - if (!io) - return -1; - break; - case IMSI_OP_ISD: - /* ISD is an inbound transaction */ - io = imsi_op_alloc(g_gc, gsup_msg.imsi, IMSI_OP_ISD); - break; - } - - imsi_op_rx_gsup(io, &gsup_msg); - msgb_free(msg); - - return 0; -} - -static void print_report(void) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(imsi_op_stats); i++) { - struct imsi_op_stats *st = &imsi_op_stats[i]; - const char *name = get_value_string(imsi_op_names, i); - printf("%s: %u alloc, %u released, %u success, %u error , %u tout\n", - name, st->num_alloc, st->num_released, st->num_rx_success, - st->num_rx_error, st->num_timeout); - } -} - -static void sig_cb(int sig) -{ - switch (sig) { - case SIGINT: - print_report(); - exit(0); - break; - } -} - -void *tall_bsc_ctx = NULL; - -/* default categories */ -static struct log_info_cat default_categories[] = { -}; - -static const struct log_info gsup_test_client_log_info = { - .cat = default_categories, - .num_cat = ARRAY_SIZE(default_categories), -}; - -int main(int argc, char **argv) -{ - unsigned long long i; - char *server_host = "127.0.0.1"; - uint16_t server_port = OSMO_GSUP_PORT; - - osmo_init_logging(&gsup_test_client_log_info); - - g_gc = gsup_client_create("GSUPTEST", server_host, server_port, - gsupc_read_cb, NULL); - - - signal(SIGINT, sig_cb); - - for (i = 0; i < 10000; i++) { - unsigned long long imsi = 901790000000000 + i; - char imsi_buf[17]; - snprintf(imsi_buf, sizeof(imsi_buf), "%015llu", imsi); - req_auth_info(imsi_buf); - osmo_select_main(0); - } - - while (1) { - osmo_select_main(0); - } - - print_report(); - exit(0); -} diff --git a/src/libfilter/bsc_msg_filter.c b/src/libfilter/bsc_msg_filter.c index 115d376cb..338db7298 100644 --- a/src/libfilter/bsc_msg_filter.c +++ b/src/libfilter/bsc_msg_filter.c @@ -28,12 +28,14 @@ #include #include #include +#include #include #include #include #include +#include int bsc_filter_barr_find(struct rb_root *root, const char *imsi, int *cm, int *lu) { diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am deleted file mode 100644 index c9b8bb4cc..000000000 --- a/src/libmsc/Makefile.am +++ /dev/null @@ -1,75 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - -I$(top_builddir) \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(COVERAGE_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) \ - $(LIBSMPP34_CFLAGS) \ - $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) \ - $(NULL) - -noinst_HEADERS = \ - meas_feed.h \ - $(NULL) - -noinst_LIBRARIES = \ - libmsc.a \ - $(NULL) - -libmsc_a_SOURCES = \ - a_iface.c \ - a_iface_bssap.c \ - auth.c \ - msc_vty.c \ - db.c \ - gsm_04_08.c \ - gsm_04_11.c \ - gsm_04_14.c \ - gsm_04_80.c \ - gsm_subscriber.c \ - mncc.c \ - mncc_builtin.c \ - mncc_sock.c \ - msc_ifaces.c \ - rrlp.c \ - silent_call.c \ - sms_queue.c \ - ussd.c \ - vty_interface_layer3.c \ - transaction.c \ - osmo_msc.c \ - ctrl_commands.c \ - meas_feed.c \ - subscr_conn.c \ - $(NULL) -if BUILD_IU -libmsc_a_SOURCES += \ - iucs.c \ - iucs_ranap.c \ - $(NULL) -else -libmsc_a_SOURCES += \ - iu_dummy.c \ - $(NULL) -endif - -if BUILD_SMPP -noinst_HEADERS += \ - smpp_smsc.h \ - $(NULL) - -libmsc_a_SOURCES += \ - smpp_smsc.c \ - smpp_openbsc.c \ - smpp_vty.c \ - smpp_utils.c \ - $(NULL) -endif diff --git a/src/libmsc/a_iface.c b/src/libmsc/a_iface.c deleted file mode 100644 index e473b7526..000000000 --- a/src/libmsc/a_iface.c +++ /dev/null @@ -1,591 +0,0 @@ -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* A pointer to the GSM network we work with. By the current paradigm, - * there can only be one gsm_network per MSC. The pointer is set once - * when calling a_init() */ -static struct gsm_network *gsm_network = NULL; - -/* A struct to track currently active connections. We need that information - * to handle failure sitautions. In case of a problem, we must know which - * connections are currently open and which BSC is responsible. We also need - * the data to perform our connection checks (a_reset). All other logic will - * look at the connection ids and addresses that are supplied by the - * primitives */ -struct bsc_conn { - struct llist_head list; - uint32_t conn_id; /* Connection identifier */ -}; - -/* Internal list with connections we currently maintain. This - * list is of type struct bsc_conn (see above) */ -static LLIST_HEAD(active_connections); - -/* Record info of a new active connection in the active connection list */ -static void record_bsc_con(const void *ctx, uint32_t conn_id) -{ - struct bsc_conn *conn; - - conn = talloc_zero(ctx, struct bsc_conn); - OSMO_ASSERT(conn); - - conn->conn_id = conn_id; - - llist_add_tail(&conn->list, &active_connections); -} - -/* Delete info of a closed connection from the active connection list */ -void a_delete_bsc_con(uint32_t conn_id) -{ - struct bsc_conn *conn; - struct bsc_conn *conn_temp; - - LOGP(DMSC, LOGL_DEBUG, - "Removing connection from active sccp-connection list (conn_id=%i)\n", - conn_id); - - llist_for_each_entry_safe(conn, conn_temp, &active_connections, list) { - if (conn->conn_id == conn_id) { - llist_del(&conn->list); - talloc_free(conn); - } - } -} - -/* Check if a specified connection id has an active SCCP connection */ -static bool check_connection_active(uint32_t conn_id) -{ - struct bsc_conn *conn; - - /* Find the address for the current connection id */ - llist_for_each_entry(conn, &active_connections, list) { - if (conn->conn_id == conn_id) { - return true; - } - } - - return false; -} - -/* Get the reset context for a specifiec calling (BSC) address */ -static struct a_reset_ctx *get_reset_ctx_by_sccp_addr(const struct osmo_sccp_addr *addr) -{ - struct bsc_context *bsc_ctx; - struct osmo_ss7_instance *ss7; - - if (!addr) - return NULL; - - llist_for_each_entry(bsc_ctx, &gsm_network->a.bscs, list) { - if (memcmp(&bsc_ctx->bsc_addr, addr, sizeof(*addr)) == 0) - return bsc_ctx->reset; - } - - ss7 = osmo_ss7_instance_find(gsm_network->a.cs7_instance); - OSMO_ASSERT(ss7); - LOGP(DMSC, LOGL_ERROR, "The calling BSC (%s) is unknown to this MSC ...\n", - osmo_sccp_addr_name(ss7, addr)); - return NULL; -} - -/* Send DTAP message via A-interface */ -int a_iface_tx_dtap(struct msgb *msg) -{ - struct gsm_subscriber_connection *conn; - struct msgb *msg_resp; - - /* FIXME: Set this to some meaninful value! */ - uint8_t link_id = 0x00; - OSMO_ASSERT(msg); - conn = (struct gsm_subscriber_connection *)msg->dst; - OSMO_ASSERT(conn); - OSMO_ASSERT(conn->a.scu); - - LOGP(DMSC, LOGL_DEBUG, "Passing DTAP message from MSC to BSC (conn_id=%i)\n", conn->a.conn_id); - - msg->l3h = msg->data; - msg_resp = gsm0808_create_dtap(msg, link_id); - if (!msg_resp) { - LOGP(DMSC, LOGL_ERROR, "Unable to generate BSSMAP DTAP message!\n"); - return -EINVAL; - } else - LOGP(DMSC, LOGL_DEBUG, "Massage will be sent as BSSMAP DTAP message!\n"); - - LOGP(DMSC, LOGL_DEBUG, "N-DATA.req(%u, %s)\n", conn->a.conn_id, osmo_hexdump(msg_resp->data, msg_resp->len)); - return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg_resp); -} - -/* Send Cipher mode command via A-interface */ -int a_iface_tx_cipher_mode(const struct gsm_subscriber_connection *conn, - int cipher, const const uint8_t *key, int len, int include_imeisv) -{ - /* TODO generalize for A- and Iu interfaces, don't name after 08.08 */ - struct msgb *msg_resp; - struct gsm0808_encrypt_info ei; - - OSMO_ASSERT(conn); - - LOGP(DMSC, LOGL_DEBUG, "Passing Cipher mode command message from MSC to BSC (conn_id=%i)\n", conn->a.conn_id); - uint8_t crm = 0x01; - uint8_t *crm_ptr = NULL; - - /* Setup encryption information */ - if (len > ENCRY_INFO_KEY_MAXLEN || !key) { - LOGP(DMSC, LOGL_ERROR, - "Cipher mode command message could not be generated due to invalid key! (conn_id=%i)\n", - conn->a.conn_id); - return -EINVAL; - } else { - memcpy(&ei.key, key, len); - ei.key_len = len; - } - - if (include_imeisv) - crm_ptr = &crm; - - ei.perm_algo[0] = (uint8_t) (1 << cipher); - ei.perm_algo_len = 1; - - msg_resp = gsm0808_create_cipher(&ei, crm_ptr); - LOGP(DMSC, LOGL_DEBUG, "N-DATA.req(%u, %s)\n", conn->a.conn_id, osmo_hexdump(msg_resp->data, msg_resp->len)); - - return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg_resp); -} - -/* Page a subscriber via A-interface */ -int a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac) -{ - struct bsc_context *bsc_ctx; - struct gsm0808_cell_id_list cil; - struct msgb *msg; - int page_count = 0; - struct osmo_ss7_instance *ss7; - - OSMO_ASSERT(imsi); - - cil.id_discr = CELL_IDENT_LAC; - cil.id_list_lac[0] = lac; - cil.id_list_len = 1; - - ss7 = osmo_ss7_instance_find(gsm_network->a.cs7_instance); - OSMO_ASSERT(ss7); - - /* Deliver paging request to all known BSCs */ - llist_for_each_entry(bsc_ctx, &gsm_network->a.bscs, list) { - if (a_reset_conn_ready(bsc_ctx->reset)) { - LOGP(DMSC, LOGL_DEBUG, - "Passing paging message from MSC %s to BSC %s (imsi=%s, tmsi=0x%08x, lac=%u)\n", - osmo_sccp_addr_name(ss7, &bsc_ctx->msc_addr), - osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), imsi, tmsi, lac); - msg = gsm0808_create_paging(imsi, &tmsi, &cil, NULL); - osmo_sccp_tx_unitdata_msg(bsc_ctx->sccp_user, - &bsc_ctx->msc_addr, &bsc_ctx->bsc_addr, msg); - page_count++; - } else { - LOGP(DMSC, LOGL_DEBUG, - "Connection down, dropping paging from MSC %s to BSC %s (imsi=%s, tmsi=0x%08x, lac=%u)\n", - osmo_sccp_addr_name(ss7, &bsc_ctx->msc_addr), - osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), imsi, tmsi, lac); - } - } - - if (page_count <= 0) - LOGP(DMSC, LOGL_ERROR, "Could not deliver paging because none of the associated BSCs is available!\n"); - - return page_count; -} - -/* Convert speech version field */ -static uint8_t convert_Abis_sv_to_A_sv(int speech_ver) -{ - /* The speech versions that are transmitted in the Bearer capability - * information element, that is transmitted on the Abis interfece - * use a different encoding than the permitted speech version - * identifier, that is signalled in the channel type element on the A - * interface. (See also 3GPP TS 48.008, 3.2.2.1 and 3GPP TS 24.008, - * 10.5.103 */ - - switch (speech_ver) { - case GSM48_BCAP_SV_FR: - return GSM0808_PERM_FR1; - break; - case GSM48_BCAP_SV_HR: - return GSM0808_PERM_HR1; - break; - case GSM48_BCAP_SV_EFR: - return GSM0808_PERM_FR2; - break; - case GSM48_BCAP_SV_AMR_F: - return GSM0808_PERM_FR3; - break; - case GSM48_BCAP_SV_AMR_H: - return GSM0808_PERM_HR3; - break; - case GSM48_BCAP_SV_AMR_OFW: - return GSM0808_PERM_FR4; - break; - case GSM48_BCAP_SV_AMR_OHW: - return GSM0808_PERM_HR4; - break; - case GSM48_BCAP_SV_AMR_FW: - return GSM0808_PERM_FR5; - break; - case GSM48_BCAP_SV_AMR_OH: - return GSM0808_PERM_HR6; - break; - } - - /* If nothing matches, tag the result as invalid */ - LOGP(DMSC, LOGL_ERROR, "Invalid permitted speech version / rate detected, discarding.\n"); - return 0xFF; -} - -/* Convert speech preference field */ -static uint8_t convert_Abis_prev_to_A_pref(int radio) -{ - /* The Radio channel requirement field that is transmitted in the - * Bearer capability information element, that is transmitted on the - * Abis interfece uses a different encoding than the Channel rate and - * type field that is signalled in the channel type element on the A - * interface. (See also 3GPP TS 48.008, 3.2.2.1 and 3GPP TS 24.008, - * 10.5.102 */ - - switch (radio) { - case GSM48_BCAP_RRQ_FR_ONLY: - return GSM0808_SPEECH_FULL_BM; - case GSM48_BCAP_RRQ_DUAL_FR: - return GSM0808_SPEECH_FULL_PREF; - case GSM48_BCAP_RRQ_DUAL_HR: - return GSM0808_SPEECH_HALF_PREF; - } - - LOGP(DMSC, LOGL_ERROR, "Invalid speech version / rate combination preference, defaulting to full rate.\n"); - return GSM0808_SPEECH_FULL_BM; -} - -/* Assemble the channel type field */ -static int enc_channel_type(struct gsm0808_channel_type *ct, const struct gsm_mncc_bearer_cap *bc) -{ - unsigned int i; - uint8_t sv; - unsigned int count = 0; - bool only_gsm_hr = true; - - OSMO_ASSERT(ct); - OSMO_ASSERT(bc); - - ct->ch_indctr = GSM0808_CHAN_SPEECH; - - for (i = 0; i < ARRAY_SIZE(bc->speech_ver); i++) { - if (bc->speech_ver[i] == -1) - break; - sv = convert_Abis_sv_to_A_sv(bc->speech_ver[i]); - if (sv != 0xFF) { - /* Detect if something else than - * GSM HR V1 is supported */ - if (sv == GSM0808_PERM_HR2 || - sv == GSM0808_PERM_HR3 || sv == GSM0808_PERM_HR4 || sv == GSM0808_PERM_HR6) - only_gsm_hr = false; - - ct->perm_spch[count] = sv; - count++; - } - } - ct->perm_spch_len = count; - - if (only_gsm_hr) - /* Note: We must avoid the usage of GSM HR1 as this - * codec only offers very poor audio quality. If the - * MS only supports GSM HR1 (and full rate), and has - * a preference for half rate. Then we will ignore the - * preference and assume a preference for full rate. */ - ct->ch_rate_type = GSM0808_SPEECH_FULL_BM; - else - ct->ch_rate_type = convert_Abis_prev_to_A_pref(bc->radio); - - if (count) - return 0; - else - return -EINVAL; -} - -/* Assemble the speech codec field */ -static int enc_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct gsm0808_channel_type *ct) -{ - unsigned int i; - int rc; - - memset(scl, 0, sizeof(*scl)); - for (i = 0; i < ct->perm_spch_len; i++) { - rc = gsm0808_speech_codec_from_chan_type(&scl->codec[i], ct->perm_spch[i]); - if (rc != 0) - return -EINVAL; - } - scl->len = i; - - return 0; -} - -/* Send assignment request via A-interface */ -int a_iface_tx_assignment(const struct gsm_trans *trans) -{ - struct gsm_subscriber_connection *conn; - struct gsm0808_channel_type ct; - struct gsm0808_speech_codec_list scl; - uint32_t *ci_ptr = NULL; - struct msgb *msg; - struct sockaddr_storage rtp_addr; - struct sockaddr_in rtp_addr_in; - int rc; - - OSMO_ASSERT(trans); - conn = trans->conn; - OSMO_ASSERT(conn); - - LOGP(DMSC, LOGL_ERROR, "Sending assignment command to BSC (conn_id %u)\n", conn->a.conn_id); - - /* Channel type */ - rc = enc_channel_type(&ct, &trans->bearer_cap); - if (rc < 0) { - LOGP(DMSC, LOGL_ERROR, "Faild to generate channel type -- assignment not sent!\n"); - return -EINVAL; - } - - /* Speech codec list */ - rc = enc_speech_codec_list(&scl, &ct); - if (rc < 0) { - LOGP(DMSC, LOGL_ERROR, "Faild to generate Speech codec list -- assignment not sent!\n"); - return -EINVAL; - } - - /* Package RTP-Address data */ - memset(&rtp_addr_in, 0, sizeof(rtp_addr_in)); - rtp_addr_in.sin_family = AF_INET; - rtp_addr_in.sin_port = osmo_htons(conn->rtp.port_subscr); - rtp_addr_in.sin_addr.s_addr = osmo_htonl(mgcpgw_client_remote_addr_n(gsm_network->mgcpgw.client)); - - memset(&rtp_addr, 0, sizeof(rtp_addr)); - memcpy(&rtp_addr, &rtp_addr_in, sizeof(rtp_addr_in)); - - msg = gsm0808_create_ass(&ct, NULL, &rtp_addr, &scl, ci_ptr); - - LOGP(DMSC, LOGL_DEBUG, "N-DATA.req(%u, %s)\n", conn->a.conn_id, osmo_hexdump(msg->data, msg->len)); - return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg); -} - -/* Send clear command via A-interface */ -int a_iface_tx_clear_cmd(struct gsm_subscriber_connection *conn) -{ - struct msgb *msg; - - LOGP(DMSC, LOGL_NOTICE, "Sending clear command to BSC (conn_id=%u)\n", conn->a.conn_id); - - msg = gsm0808_create_clear_command(GSM0808_CAUSE_CALL_CONTROL); - return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg); -} - -/* Callback function: Close all open connections */ -static void a_reset_cb(const void *priv) -{ - struct msgb *msg; - struct bsc_context *bsc_ctx = (struct bsc_context*) priv; - struct osmo_ss7_instance *ss7; - - /* Skip if the A interface is not properly initalized yet */ - if (!gsm_network) - return; - - /* Clear all now orphaned subscriber connections */ - a_clear_all(bsc_ctx->sccp_user, &bsc_ctx->bsc_addr); - - /* Send reset to the remote BSC */ - ss7 = osmo_ss7_instance_find(gsm_network->a.cs7_instance); - OSMO_ASSERT(ss7); - LOGP(DMSC, LOGL_NOTICE, "Sending RESET to BSC %s\n", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr)); - msg = gsm0808_create_reset(); - osmo_sccp_tx_unitdata_msg(bsc_ctx->sccp_user, &bsc_ctx->msc_addr, - &bsc_ctx->bsc_addr, msg); -} - -/* Add a new BSC connection to our internal list with known BSCs */ -static void add_bsc(const struct osmo_sccp_addr *msc_addr, const struct osmo_sccp_addr *bsc_addr, - struct osmo_sccp_user *scu) -{ - struct bsc_context *bsc_ctx; - struct osmo_ss7_instance *ss7; - - OSMO_ASSERT(bsc_addr); - OSMO_ASSERT(msc_addr); - OSMO_ASSERT(scu); - - /* Check if we already know this BSC, if yes, skip adding it. */ - if (get_reset_ctx_by_sccp_addr(bsc_addr)) - return; - - ss7 = osmo_ss7_instance_find(gsm_network->a.cs7_instance); - OSMO_ASSERT(ss7); - LOGP(DMSC, LOGL_NOTICE, "Adding new BSC connection for BSC %s...\n", osmo_sccp_addr_name(ss7, bsc_addr)); - - /* Generate and fill up a new bsc context */ - bsc_ctx = talloc_zero(gsm_network, struct bsc_context); - OSMO_ASSERT(bsc_ctx); - memcpy(&bsc_ctx->bsc_addr, bsc_addr, sizeof(*bsc_addr)); - memcpy(&bsc_ctx->msc_addr, msc_addr, sizeof(*msc_addr)); - bsc_ctx->sccp_user = scu; - llist_add_tail(&bsc_ctx->list, &gsm_network->a.bscs); - - /* Start reset procedure to make the new connection active */ - bsc_ctx->reset = a_reset_alloc(bsc_ctx, osmo_sccp_addr_name(ss7, bsc_addr), a_reset_cb, bsc_ctx); -} - -/* Callback function, called by the SSCP stack when data arrives */ -static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu) -{ - struct osmo_sccp_user *scu = _scu; - struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *)oph; - int rc = 0; - struct a_conn_info a_conn_info; - memset(&a_conn_info, 0, sizeof(a_conn_info)); - a_conn_info.network = gsm_network; - a_conn_info.reset = NULL; - - switch (OSMO_PRIM_HDR(&scu_prim->oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): - /* Handle inbound connection indication */ - add_bsc(&scu_prim->u.connect.called_addr, &scu_prim->u.connect.calling_addr, scu); - a_conn_info.conn_id = scu_prim->u.connect.conn_id; - a_conn_info.msc_addr = &scu_prim->u.connect.called_addr; - a_conn_info.bsc_addr = &scu_prim->u.connect.calling_addr; - a_conn_info.reset = get_reset_ctx_by_sccp_addr(&scu_prim->u.unitdata.calling_addr); - - if (a_reset_conn_ready(a_conn_info.reset) == false) { - rc = osmo_sccp_tx_disconn(scu, a_conn_info.conn_id, a_conn_info.msc_addr, - SCCP_RETURN_CAUSE_UNQUALIFIED); - break; - } - - osmo_sccp_tx_conn_resp(scu, scu_prim->u.connect.conn_id, &scu_prim->u.connect.called_addr, NULL, 0); - if (msgb_l2len(oph->msg) > 0) { - LOGP(DMSC, LOGL_DEBUG, "N-CONNECT.ind(%u, %s)\n", - scu_prim->u.connect.conn_id, osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - rc = sccp_rx_dt(scu, &a_conn_info, oph->msg); - } else - LOGP(DMSC, LOGL_DEBUG, "N-CONNECT.ind(%u)\n", scu_prim->u.connect.conn_id); - - record_bsc_con(scu, scu_prim->u.connect.conn_id); - break; - - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): - /* Handle incoming connection oriented data */ - a_conn_info.conn_id = scu_prim->u.data.conn_id; - LOGP(DMSC, LOGL_DEBUG, "N-DATA.ind(%u, %s)\n", - scu_prim->u.data.conn_id, osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - sccp_rx_dt(scu, &a_conn_info, oph->msg); - break; - - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): - /* Handle inbound UNITDATA */ - add_bsc(&scu_prim->u.unitdata.called_addr, &scu_prim->u.unitdata.calling_addr, scu); - a_conn_info.msc_addr = &scu_prim->u.unitdata.called_addr; - a_conn_info.bsc_addr = &scu_prim->u.unitdata.calling_addr; - a_conn_info.reset = get_reset_ctx_by_sccp_addr(&scu_prim->u.unitdata.calling_addr); - DEBUGP(DMSC, "N-UNITDATA.ind(%s)\n", osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - sccp_rx_udt(scu, &a_conn_info, oph->msg); - break; - - default: - LOGP(DMSC, LOGL_ERROR, "Unhandled SIGTRAN primitive: %u:%u\n", oph->primitive, oph->operation); - break; - } - - return rc; -} - -/* Clear all subscriber connections on a specified BSC */ -void a_clear_all(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *bsc_addr) -{ - struct gsm_subscriber_connection *conn; - struct gsm_subscriber_connection *conn_temp; - struct gsm_network *network = gsm_network; - - OSMO_ASSERT(scu); - OSMO_ASSERT(bsc_addr); - - llist_for_each_entry_safe(conn, conn_temp, &network->subscr_conns, entry) { - /* Clear only A connections and connections that actually - * belong to the specified BSC */ - if (conn->via_ran == RAN_GERAN_A && memcmp(bsc_addr, &conn->a.bsc_addr, sizeof(conn->a.bsc_addr)) == 0) { - LOGP(DMSC, LOGL_NOTICE, "Dropping orphaned subscriber connection (conn_id %i)\n", - conn->a.conn_id); - msc_clear_request(conn, GSM48_CC_CAUSE_SWITCH_CONG); - - /* If there is still an SCCP connection active, remove it now */ - if (check_connection_active(conn->a.conn_id)) { - osmo_sccp_tx_disconn(scu, conn->a.conn_id, bsc_addr, - SCCP_RELEASE_CAUSE_END_USER_ORIGINATED); - a_delete_bsc_con(conn->a.conn_id); - } - } - } -} - -/* Initalize A interface connection between to MSC and BSC */ -int a_init(struct osmo_sccp_instance *sccp, struct gsm_network *network) -{ - OSMO_ASSERT(sccp); - OSMO_ASSERT(network); - - /* FIXME: Remove hardcoded parameters, use parameters in parameter list */ - LOGP(DMSC, LOGL_NOTICE, "Initalizing SCCP connection to stp...\n"); - - /* Set GSM network variable, there can only be - * one network by design */ - if (gsm_network != NULL) { - OSMO_ASSERT(gsm_network == network); - } else - gsm_network = network; - - /* SCCP Protocol stack */ - osmo_sccp_user_bind(sccp, "OsmoMSC-A", sccp_sap_up, SCCP_SSN_BSSAP); - - return 0; -} diff --git a/src/libmsc/a_iface_bssap.c b/src/libmsc/a_iface_bssap.c deleted file mode 100644 index e8a229374..000000000 --- a/src/libmsc/a_iface_bssap.c +++ /dev/null @@ -1,716 +0,0 @@ -/* (C) 2017 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IP_V4_ADDR_LEN 4 - -/* - * Helper functions to lookup and allocate subscribers - */ - -/* Allocate a new subscriber connection */ -static struct gsm_subscriber_connection *subscr_conn_allocate_a(const struct a_conn_info *a_conn_info, - struct gsm_network *network, - uint16_t lac, struct osmo_sccp_user *scu, int conn_id) -{ - struct gsm_subscriber_connection *conn; - - LOGP(DMSC, LOGL_NOTICE, "Allocating A-Interface subscriber conn: lac %i, conn_id %i\n", lac, conn_id); - - conn = talloc_zero(network, struct gsm_subscriber_connection); - if (!conn) - return NULL; - - conn->network = network; - conn->via_ran = RAN_GERAN_A; - conn->lac = lac; - - conn->a.conn_id = conn_id; - conn->a.scu = scu; - - /* Also backup the calling address of the BSC, this allows us to - * identify later which BSC is responsible for this subscriber connection */ - memcpy(&conn->a.bsc_addr, a_conn_info->bsc_addr, sizeof(conn->a.bsc_addr)); - - llist_add_tail(&conn->entry, &network->subscr_conns); - LOGP(DMSC, LOGL_NOTICE, "A-Interface subscriber connection successfully allocated!\n"); - return conn; -} - -/* Return an existing A subscriber connection record for the given - * connection IDs, or return NULL if not found. */ -static struct gsm_subscriber_connection *subscr_conn_lookup_a(const struct gsm_network *network, int conn_id) -{ - struct gsm_subscriber_connection *conn; - - OSMO_ASSERT(network); - - DEBUGP(DMSC, "Looking for A subscriber: conn_id %i\n", conn_id); - - /* FIXME: log_subscribers() is defined in iucs.c as static inline, if - * maybe this function should be public to reach it from here? */ - /* log_subscribers(network); */ - - llist_for_each_entry(conn, &network->subscr_conns, entry) { - if (conn->via_ran == RAN_GERAN_A && conn->a.conn_id == conn_id) { - DEBUGP(DIUCS, "Found A subscriber for conn_id %i\n", conn_id); - return conn; - } - } - DEBUGP(DMSC, "No A subscriber found for conn_id %i\n", conn_id); - return NULL; -} - -/* - * BSSMAP handling for UNITDATA - */ - -/* Endpoint to handle BSSMAP reset */ -static void bssmap_rx_reset(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - struct gsm_network *network = a_conn_info->network; - struct osmo_ss7_instance *ss7; - - ss7 = osmo_ss7_instance_find(network->a.cs7_instance); - OSMO_ASSERT(ss7); - - LOGP(DMSC, LOGL_NOTICE, "Rx RESET from BSC %s, sending RESET ACK\n", - osmo_sccp_addr_name(ss7, a_conn_info->bsc_addr)); - osmo_sccp_tx_unitdata_msg(scu, a_conn_info->msc_addr, a_conn_info->bsc_addr, gsm0808_create_reset_ack()); - - /* Make sure all orphand subscriber connections will be cleard */ - a_clear_all(scu, a_conn_info->bsc_addr); - - msgb_free(msg); -} - -/* Endpoint to handle BSSMAP reset acknowlegement */ -static void bssmap_rx_reset_ack(const struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, - struct msgb *msg) -{ - - struct gsm_network *network = a_conn_info->network; - struct osmo_ss7_instance *ss7; - - ss7 = osmo_ss7_instance_find(network->a.cs7_instance); - OSMO_ASSERT(ss7); - - if (a_conn_info->reset == NULL) { - LOGP(DMSC, LOGL_ERROR, "Received RESET ACK from an unknown BSC %s, ignoring...\n", - osmo_sccp_addr_name(ss7, a_conn_info->bsc_addr)); - goto fail; - } - - LOGP(DMSC, LOGL_NOTICE, "Received RESET ACK from BSC %s\n", osmo_sccp_addr_name(ss7, a_conn_info->bsc_addr)); - - /* Confirm that we managed to get the reset ack message - * towards the connection reset logic */ - a_reset_ack_confirm(a_conn_info->reset); - -fail: - msgb_free(msg); -} - -/* Handle UNITDATA BSSMAP messages */ -static void bssmap_rcvmsg_udt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - /* Note: When in the MSC role, RESET ACK is the only valid message that - * can be received via UNITDATA */ - - if (msgb_l3len(msg) < 1) { - LOGP(DMSC, LOGL_NOTICE, "Error: No data received -- discarding message!\n"); - return; - } - - LOGP(DMSC, LOGL_NOTICE, "Rx BSC UDT BSSMAP %s\n", gsm0808_bssmap_name(msg->l3h[0])); - - switch (msg->l3h[0]) { - case BSS_MAP_MSG_RESET: - bssmap_rx_reset(scu, a_conn_info, msg); - break; - case BSS_MAP_MSG_RESET_ACKNOWLEDGE: - bssmap_rx_reset_ack(scu, a_conn_info, msg); - break; - default: - LOGP(DMSC, LOGL_NOTICE, "Unimplemented message format: %s -- message discarded!\n", - gsm0808_bssmap_name(msg->l3h[0])); - msgb_free(msg); - } -} - -/* Receive incoming connection less data messages via sccp */ -void sccp_rx_udt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - /* Note: The only valid message type that can be received - * via UNITDATA are BSS Management messages */ - struct bssmap_header *bs; - - OSMO_ASSERT(scu); - OSMO_ASSERT(a_conn_info); - OSMO_ASSERT(msg); - - LOGP(DMSC, LOGL_NOTICE, "Rx BSC UDT: %s\n", osmo_hexdump(msgb_l2(msg), msgb_l2len(msg))); - - if (msgb_l2len(msg) < sizeof(*bs)) { - LOGP(DMSC, LOGL_ERROR, "Error: Header is too short -- discarding message!\n"); - msgb_free(msg); - return; - } - - bs = (struct bssmap_header *)msgb_l2(msg); - if (bs->length < msgb_l2len(msg) - sizeof(*bs)) { - LOGP(DMSC, LOGL_ERROR, "Error: Message is too short -- discarding message!\n"); - msgb_free(msg); - return; - } - - switch (bs->type) { - case BSSAP_MSG_BSS_MANAGEMENT: - msg->l3h = &msg->l2h[sizeof(struct bssmap_header)]; - bssmap_rcvmsg_udt(scu, a_conn_info, msg); - break; - default: - LOGP(DMSC, LOGL_ERROR, - "Error: Unimplemented message type: %s -- message discarded!\n", gsm0808_bssmap_name(bs->type)); - msgb_free(msg); - } -} - -/* - * BSSMAP handling for connection oriented data - */ - -/* Endpoint to handle BSSMAP clear request */ -static int bssmap_rx_clear_rqst(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - struct gsm_network *network = a_conn_info->network; - struct tlv_parsed tp; - int rc; - struct msgb *msg_resp; - uint8_t cause; - struct gsm_subscriber_connection *conn; - - LOGP(DMSC, LOGL_NOTICE, "BSC requested to clear connection (conn_id=%i)\n", a_conn_info->conn_id); - - tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - if (!TLVP_PRESENT(&tp, GSM0808_IE_CAUSE)) { - LOGP(DMSC, LOGL_ERROR, "Cause code is missing -- discarding message!\n"); - goto fail; - } - cause = TLVP_VAL(&tp, GSM0808_IE_CAUSE)[0]; - - /* Respond with clear command */ - msg_resp = gsm0808_create_clear_command(GSM0808_CAUSE_CALL_CONTROL); - rc = osmo_sccp_tx_data_msg(scu, a_conn_info->conn_id, msg_resp); - - /* If possible, inform the MSC about the clear request */ - conn = subscr_conn_lookup_a(network, a_conn_info->conn_id); - if (!conn) - goto fail; - msc_clear_request(conn, cause); - - msgb_free(msg); - return rc; - -fail: - msgb_free(msg); - return -EINVAL; -} - -/* Endpoint to handle BSSMAP clear complete */ -static int bssmap_rx_clear_complete(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - int rc; - - LOGP(DMSC, LOGL_NOTICE, "Releasing connection (conn_id=%i)\n", a_conn_info->conn_id); - rc = osmo_sccp_tx_disconn(scu, a_conn_info->conn_id, - a_conn_info->msc_addr, SCCP_RELEASE_CAUSE_END_USER_ORIGINATED); - - /* Remove the record from the list with active connections. */ - a_delete_bsc_con(a_conn_info->conn_id); - - msgb_free(msg); - return rc; -} - -/* Endpoint to handle layer 3 complete messages */ -static int bssmap_rx_l3_compl(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - struct tlv_parsed tp; - struct { - uint8_t ident; - struct gsm48_loc_area_id lai; - uint16_t ci; - } __attribute__ ((packed)) lai_ci; - uint16_t mcc; - uint16_t mnc; - uint16_t lac; - uint8_t data_length; - const uint8_t *data; - int rc; - - struct gsm_network *network = a_conn_info->network; - struct gsm_subscriber_connection *conn; - - LOGP(DMSC, LOGL_NOTICE, "BSC has completed layer 3 connection (conn_id=%i)\n", a_conn_info->conn_id); - - tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - if (!TLVP_PRESENT(&tp, GSM0808_IE_CELL_IDENTIFIER)) { - LOGP(DMSC, LOGL_ERROR, "Mandatory CELL IDENTIFIER not present -- discarding message!\n"); - goto fail; - } - if (!TLVP_PRESENT(&tp, GSM0808_IE_LAYER_3_INFORMATION)) { - LOGP(DMSC, LOGL_ERROR, "Mandatory LAYER 3 INFORMATION not present -- discarding message!\n"); - goto fail; - } - - /* Parse Cell ID element */ - /* FIXME: Encapsulate this in a parser/generator function inside - * libosmocore, add support for all specified cell identification - * discriminators (see 3GPP ts 3.2.2.17 Cell Identifier) */ - data_length = TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER); - data = TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER); - if (sizeof(lai_ci) != data_length) { - LOGP(DMSC, LOGL_ERROR, - "Unable to parse element CELL IDENTIFIER (wrong field length) -- discarding message!\n"); - goto fail; - } - memcpy(&lai_ci, data, sizeof(lai_ci)); - if (lai_ci.ident != CELL_IDENT_WHOLE_GLOBAL) { - LOGP(DMSC, LOGL_ERROR, - "Unable to parse element CELL IDENTIFIER (wrong cell identification discriminator) -- discarding message!\n"); - goto fail; - } - if (gsm48_decode_lai(&lai_ci.lai, &mcc, &mnc, &lac) != 0) { - LOGP(DMSC, LOGL_ERROR, - "Unable to parse element CELL IDENTIFIER (lai decoding failed) -- discarding message!\n"); - goto fail; - } - - /* Parse Layer 3 Information element */ - /* FIXME: This is probably to hackish, compiler also complains "assignment discards ‘const’ qualifier..." */ - msg->l3h = TLVP_VAL(&tp, GSM0808_IE_LAYER_3_INFORMATION); - msg->tail = msg->l3h + TLVP_LEN(&tp, GSM0808_IE_LAYER_3_INFORMATION); - - /* Create new subscriber context */ - conn = subscr_conn_allocate_a(a_conn_info, network, lac, scu, a_conn_info->conn_id); - - /* Handover location update to the MSC code */ - /* msc_compl_l3() takes ownership of dtap_msg - * message buffer */ - rc = msc_compl_l3(conn, msg, 0); - if (rc == MSC_CONN_ACCEPT) { - LOGP(DMSC, LOGL_NOTICE, "User has been accepted by MSC.\n"); - return 0; - } else if (rc == MSC_CONN_REJECT) - LOGP(DMSC, LOGL_NOTICE, "User has been rejected by MSC.\n"); - else - LOGP(DMSC, LOGL_NOTICE, "User has been rejected by MSC (unknown error)\n"); - - return -EINVAL; - -fail: - msgb_free(msg); - return -EINVAL; -} - -/* Endpoint to handle BSSMAP classmark update */ -static int bssmap_rx_classmark_upd(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - struct gsm_network *network = a_conn_info->network; - struct gsm_subscriber_connection *conn; - struct tlv_parsed tp; - const uint8_t *cm2 = NULL; - const uint8_t *cm3 = NULL; - uint8_t cm2_len = 0; - uint8_t cm3_len = 0; - - conn = subscr_conn_lookup_a(network, a_conn_info->conn_id); - if (!conn) - goto fail; - - LOGP(DMSC, LOGL_NOTICE, "BSC sends clasmark update (conn_id=%i)\n", conn->a.conn_id); - - tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - if (!TLVP_PRESENT(&tp, GSM0808_IE_CLASSMARK_INFORMATION_T2)) { - LOGP(DMSC, LOGL_ERROR, "Mandatory Classmark Information Type 2 not present -- discarding message!\n"); - goto fail; - } - - cm2 = TLVP_VAL(&tp, GSM0808_IE_CLASSMARK_INFORMATION_T2); - cm2_len = TLVP_LEN(&tp, GSM0808_IE_CLASSMARK_INFORMATION_T2); - - if (TLVP_PRESENT(&tp, GSM0808_IE_CLASSMARK_INFORMATION_T3)) { - cm3 = TLVP_VAL(&tp, GSM0808_IE_CLASSMARK_INFORMATION_T3); - cm3_len = TLVP_LEN(&tp, GSM0808_IE_CLASSMARK_INFORMATION_T3); - } - - /* Inform MSC about the classmark change */ - msc_classmark_chg(conn, cm2, cm2_len, cm3, cm3_len); - - msgb_free(msg); - return 0; - -fail: - msgb_free(msg); - return -EINVAL; -} - -/* Endpoint to handle BSSMAP cipher mode complete */ -static int bssmap_rx_ciph_compl(const struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, - struct msgb *msg) -{ - /* FIXME: The field GSM0808_IE_LAYER_3_MESSAGE_CONTENTS is optional by - * means of the specification. So there can be messages without L3 info. - * In this case, the code will crash becrause msc_cipher_mode_compl() - * is not able to deal with msg = NULL and apperently - * msc_cipher_mode_compl() was never meant to be used without L3 data. - * This needs to be discussed further! */ - - struct gsm_network *network = a_conn_info->network; - struct gsm_subscriber_connection *conn; - struct tlv_parsed tp; - uint8_t alg_id = 1; - - conn = subscr_conn_lookup_a(network, a_conn_info->conn_id); - if (!conn) - goto fail; - - LOGP(DMSC, LOGL_NOTICE, "BSC sends cipher mode complete (conn_id=%i)\n", conn->a.conn_id); - - tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - - if (TLVP_PRESENT(&tp, GSM0808_IE_CHOSEN_ENCR_ALG)) { - alg_id = TLVP_VAL(&tp, GSM0808_IE_CHOSEN_ENCR_ALG)[0] - 1; - } - - if (TLVP_PRESENT(&tp, GSM0808_IE_LAYER_3_MESSAGE_CONTENTS)) { - msg->l3h = TLVP_VAL(&tp, GSM0808_IE_LAYER_3_MESSAGE_CONTENTS); - msg->tail = msg->l3h + TLVP_LEN(&tp, GSM0808_IE_LAYER_3_MESSAGE_CONTENTS); - } else { - msgb_free(msg); - msg = NULL; - } - - /* Hand over cipher mode complete message to the MSC, - * msc_cipher_mode_compl() takes ownership for msg */ - msc_cipher_mode_compl(conn, msg, alg_id); - - return 0; -fail: - msgb_free(msg); - return -EINVAL; -} - -/* Endpoint to handle BSSMAP cipher mode reject */ -static int bssmap_rx_ciph_rej(const struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - struct gsm_network *network = a_conn_info->network; - struct gsm_subscriber_connection *conn; - struct tlv_parsed tp; - uint8_t cause; - - conn = subscr_conn_lookup_a(network, a_conn_info->conn_id); - if (!conn) - goto fail; - - LOGP(DMSC, LOGL_NOTICE, "BSC sends cipher mode reject (conn_id=%i)\n", conn->a.conn_id); - - tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - if (!TLVP_PRESENT(&tp, BSS_MAP_MSG_CIPHER_MODE_REJECT)) { - LOGP(DMSC, LOGL_ERROR, "Cause code is missing -- discarding message!\n"); - goto fail; - } - - cause = TLVP_VAL(&tp, BSS_MAP_MSG_CIPHER_MODE_REJECT)[0]; - LOGP(DMSC, LOGL_NOTICE, "Cipher mode rejection cause: %i\n", cause); - - /* FIXME: Can we do something meaningful here? e.g. report to the - * msc code somehow that the cipher mode command has failed. */ - - msgb_free(msg); - return 0; -fail: - msgb_free(msg); - return -EINVAL; -} - -/* Endpoint to handle BSSMAP assignment failure */ -static int bssmap_rx_ass_fail(const struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - struct gsm_network *network = a_conn_info->network; - struct gsm_subscriber_connection *conn; - struct tlv_parsed tp; - uint8_t cause; - uint8_t *rr_cause_ptr = NULL; - uint8_t rr_cause; - - conn = subscr_conn_lookup_a(network, a_conn_info->conn_id); - if (!conn) - goto fail; - - LOGP(DMSC, LOGL_NOTICE, "BSC sends assignment failure message (conn_id=%i)\n", conn->a.conn_id); - - tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - if (!TLVP_PRESENT(&tp, GSM0808_IE_CAUSE)) { - LOGP(DMSC, LOGL_ERROR, "Cause code is missing -- discarding message!\n"); - goto fail; - } - cause = TLVP_VAL(&tp, GSM0808_IE_CAUSE)[0]; - - if (TLVP_PRESENT(&tp, GSM0808_IE_RR_CAUSE)) { - rr_cause = TLVP_VAL(&tp, GSM0808_IE_RR_CAUSE)[0]; - rr_cause_ptr = &rr_cause; - } - - /* FIXME: In AoIP, the Assignment failure will carry also an optional - * Codec List (BSS Supported) element. It has to be discussed if we - * can ignore this element. If not, The msc_assign_fail() function - * call has to change. However msc_assign_fail() does nothing in the - * end. So probably we can just leave it as it is. Even for AoIP */ - - /* Inform the MSC about the assignment failure event */ - msc_assign_fail(conn, cause, rr_cause_ptr); - - msgb_free(msg); - return 0; -fail: - msgb_free(msg); - return -EINVAL; -} - -/* Endpoint to handle sapi "n" reject */ -static int bssmap_rx_sapi_n_rej(const struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, - struct msgb *msg) -{ - struct gsm_network *network = a_conn_info->network; - struct gsm_subscriber_connection *conn; - struct tlv_parsed tp; - uint8_t dlci; - - conn = subscr_conn_lookup_a(network, a_conn_info->conn_id); - if (!conn) - goto fail; - - LOGP(DMSC, LOGL_NOTICE, "BSC sends sapi \"n\" reject message (conn_id=%i)\n", conn->a.conn_id); - - /* Note: The MSC code seems not to care about the cause code, but by - * the specification it is mandatory, so we check its presence. See - * also 3GPP TS 48.008 3.2.1.34 SAPI "n" REJECT */ - tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - if (!TLVP_PRESENT(&tp, GSM0808_IE_CAUSE)) { - LOGP(DMSC, LOGL_ERROR, "Cause code is missing -- discarding message!\n"); - goto fail; - } - - tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - if (!TLVP_PRESENT(&tp, GSM0808_IE_DLCI)) { - LOGP(DMSC, LOGL_ERROR, "DLCI is missing -- discarding message!\n"); - goto fail; - } - dlci = TLVP_VAL(&tp, GSM0808_IE_DLCI)[0]; - - /* Inform the MSC about the sapi "n" reject event */ - msc_sapi_n_reject(conn, dlci); - - msgb_free(msg); - return 0; -fail: - msgb_free(msg); - return -EINVAL; -} - -/* Endpoint to handle assignment complete */ -static int bssmap_rx_ass_compl(const struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, - struct msgb *msg) -{ - struct gsm_network *network = a_conn_info->network; - struct gsm_subscriber_connection *conn; - struct mgcpgw_client *mgcp; - struct tlv_parsed tp; - struct sockaddr_storage rtp_addr; - struct sockaddr_in *rtp_addr_in; - int rc; - - conn = subscr_conn_lookup_a(network, a_conn_info->conn_id); - if (!conn) - goto fail; - - mgcp = conn->network->mgcpgw.client; - OSMO_ASSERT(mgcp); - - LOGP(DMSC, LOGL_NOTICE, "BSC sends assignment complete message (conn_id=%i)\n", conn->a.conn_id); - - tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - - if (!TLVP_PRESENT(&tp, GSM0808_IE_AOIP_TRASP_ADDR)) { - LOGP(DMSC, LOGL_ERROR, "AoIP transport identifier missing -- discarding message!\n"); - goto fail; - } - - /* Decode AoIP transport address element */ - rc = gsm0808_dec_aoip_trasp_addr(&rtp_addr, TLVP_VAL(&tp, GSM0808_IE_AOIP_TRASP_ADDR), - TLVP_LEN(&tp, GSM0808_IE_AOIP_TRASP_ADDR)); - if (rc < 0) { - LOGP(DMSC, LOGL_ERROR, "Unable to decode aoip transport address.\n"); - goto fail; - } - - /* use address / port supplied with the AoIP - * transport address element */ - if (rtp_addr.ss_family == AF_INET) { - rtp_addr_in = (struct sockaddr_in *)&rtp_addr; - conn->rtp.port_subscr = osmo_ntohs(rtp_addr_in->sin_port); - /* FIXME: We also get the IP-Address of the remote (e.g. BTS) - * end with the response. Currently we just ignore that address. - * Instead we expect that our local MGCP gateway and the code - * controlling it, magically knows the IP of the remote end. */ - } else { - LOGP(DMSC, LOGL_ERROR, "Unsopported addressing scheme. (supports only IPV4)\n"); - goto fail; - } - - /* FIXME: Seems to be related to authentication or, - encryption. Is this really in the right place? */ - msc_rx_sec_mode_compl(conn); - - msgb_free(msg); - return 0; -fail: - msgb_free(msg); - return -EINVAL; -} - -/* Handle incoming connection oriented BSSMAP messages */ -static int rx_bssmap(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - if (msgb_l3len(msg) < 1) { - LOGP(DMSC, LOGL_NOTICE, "Error: No data received -- discarding message!\n"); - msgb_free(msg); - return -1; - } - - LOGP(DMSC, LOGL_NOTICE, "Rx MSC DT1 BSSMAP %s\n", gsm0808_bssmap_name(msg->l3h[0])); - - switch (msg->l3h[0]) { - case BSS_MAP_MSG_CLEAR_RQST: - return bssmap_rx_clear_rqst(scu, a_conn_info, msg); - break; - case BSS_MAP_MSG_CLEAR_COMPLETE: - return bssmap_rx_clear_complete(scu, a_conn_info, msg); - break; - case BSS_MAP_MSG_COMPLETE_LAYER_3: - return bssmap_rx_l3_compl(scu, a_conn_info, msg); - break; - case BSS_MAP_MSG_CLASSMARK_UPDATE: - return bssmap_rx_classmark_upd(scu, a_conn_info, msg); - break; - case BSS_MAP_MSG_CIPHER_MODE_COMPLETE: - return bssmap_rx_ciph_compl(scu, a_conn_info, msg); - break; - case BSS_MAP_MSG_CIPHER_MODE_REJECT: - return bssmap_rx_ciph_rej(scu, a_conn_info, msg); - break; - case BSS_MAP_MSG_ASSIGMENT_FAILURE: - return bssmap_rx_ass_fail(scu, a_conn_info, msg); - break; - case BSS_MAP_MSG_SAPI_N_REJECT: - return bssmap_rx_sapi_n_rej(scu, a_conn_info, msg); - break; - case BSS_MAP_MSG_ASSIGMENT_COMPLETE: - return bssmap_rx_ass_compl(scu, a_conn_info, msg); - break; - default: - LOGP(DMSC, LOGL_ERROR, "Unimplemented msg type: %s\n", gsm0808_bssmap_name(msg->l3h[0])); - msgb_free(msg); - return -EINVAL; - } - - return -EINVAL; -} - -/* Endpoint to handle regular BSSAP DTAP messages */ -static int rx_dtap(const struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - struct gsm_network *network = a_conn_info->network; - struct gsm_subscriber_connection *conn; - - conn = subscr_conn_lookup_a(network, a_conn_info->conn_id); - if (!conn) { - msgb_free(msg); - return -EINVAL; - } - - LOGP(DMSC, LOGL_NOTICE, "BSC sends layer 3 dtap (conn_id=%i)\n", conn->a.conn_id); - - /* msc_dtap expects the dtap payload in l3h */ - msg->l3h = msg->l2h + 3; - - /* Forward dtap payload into the msc, - * msc_dtap() takes ownership for msg */ - msc_dtap(conn, conn->a.conn_id, msg); - - return 0; -} - -/* Handle incoming connection oriented messages */ -int sccp_rx_dt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg) -{ - OSMO_ASSERT(scu); - OSMO_ASSERT(a_conn_info); - OSMO_ASSERT(msg); - - LOGP(DMSC, LOGL_NOTICE, "Rx BSC DT: %s\n", osmo_hexdump(msgb_l2(msg), msgb_l2len(msg))); - - if (msgb_l2len(msg) < sizeof(struct bssmap_header)) { - LOGP(DMSC, LOGL_NOTICE, "The header is too short -- discarding message!\n"); - msgb_free(msg); - } - - switch (msg->l2h[0]) { - case BSSAP_MSG_BSS_MANAGEMENT: - msg->l3h = &msg->l2h[sizeof(struct bssmap_header)]; - return rx_bssmap(scu, a_conn_info, msg); - break; - case BSSAP_MSG_DTAP: - return rx_dtap(scu, a_conn_info, msg); - break; - default: - LOGP(DMSC, LOGL_ERROR, "Unimplemented BSSAP msg type: %s\n", gsm0808_bssap_name(msg->l2h[0])); - msgb_free(msg); - return -EINVAL; - } - - return -EINVAL; -} diff --git a/src/libmsc/auth.c b/src/libmsc/auth.c deleted file mode 100644 index 9064ce6c4..000000000 --- a/src/libmsc/auth.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Authentication related functions */ - -/* - * (C) 2010 by Sylvain Munaut - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include - -#include -#include - -#include - -#include - -const struct value_string auth_action_names[] = { - OSMO_VALUE_STRING(AUTH_ERROR), - OSMO_VALUE_STRING(AUTH_NOT_AVAIL), - OSMO_VALUE_STRING(AUTH_DO_AUTH_THEN_CIPH), - OSMO_VALUE_STRING(AUTH_DO_CIPH), - OSMO_VALUE_STRING(AUTH_DO_AUTH), - { 0, NULL } -}; diff --git a/src/libmsc/ctrl_commands.c b/src/libmsc/ctrl_commands.c deleted file mode 100644 index 9d1f0d4fa..000000000 --- a/src/libmsc/ctrl_commands.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * (C) 2014 by Holger Hans Peter Freyther - * (C) 2014 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -static struct gsm_network *msc_ctrl_net = NULL; - -static int verify_subscriber_modify(struct ctrl_cmd *cmd, const char *value, void *d) -{ - return 0; -} - -static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data) -{ - cmd->reply = "Command moved to osmo-hlr, no longer available here"; - return CTRL_CMD_ERROR; -} - -CTRL_CMD_DEFINE_WO(subscriber_modify, "subscriber-modify-v1"); - -static int set_subscriber_delete(struct ctrl_cmd *cmd, void *data) -{ - cmd->reply = "Command moved to osmo-hlr, no longer available here"; - return CTRL_CMD_ERROR; -} -CTRL_CMD_DEFINE_WO_NOVRF(subscriber_delete, "subscriber-delete-v1"); - -static int get_subscriber_list(struct ctrl_cmd *cmd, void *d) -{ - struct vlr_subscr *vsub; - - if (!msc_ctrl_net) { - cmd->reply = "MSC CTRL commands not initialized"; - return CTRL_CMD_ERROR; - } - - if (!msc_ctrl_net->vlr) { - cmd->reply = "VLR not initialized"; - return CTRL_CMD_ERROR; - } - - cmd->reply = talloc_strdup(cmd, ""); - - llist_for_each_entry(vsub, &msc_ctrl_net->vlr->subscribers, list) { - cmd->reply = talloc_asprintf_append(cmd->reply, "%s,%s\n", - vsub->imsi, vsub->msisdn); - } - printf("%s\n", cmd->reply); /* <-- what? */ - return CTRL_CMD_REPLY; -} -CTRL_CMD_DEFINE_RO(subscriber_list, "subscriber-list-active-v1"); - -int msc_ctrl_cmds_install(struct gsm_network *net) -{ - int rc = 0; - msc_ctrl_net = net; - - rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_modify); - rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_delete); - rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_list); - return rc; -} diff --git a/src/libmsc/db.c b/src/libmsc/db.c deleted file mode 100644 index ae7e2876b..000000000 --- a/src/libmsc/db.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* Simple HLR/VLR database backend using dbi */ -/* (C) 2008 by Jan Luebbe - * (C) 2009 by Holger Hans Peter Freyther - * (C) 2009 by Harald Welte - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -static char *db_basename = NULL; -static char *db_dirname = NULL; -static dbi_conn conn; - -#define SCHEMA_REVISION "5" - -enum { - SCHEMA_META, - INSERT_META, - SCHEMA_SUBSCRIBER, - SCHEMA_AUTH, - SCHEMA_EQUIPMENT, - SCHEMA_EQUIPMENT_WATCH, - SCHEMA_SMS, - SCHEMA_VLR, - SCHEMA_APDU, - SCHEMA_COUNTERS, - SCHEMA_RATE, - SCHEMA_AUTHKEY, - SCHEMA_AUTHLAST, -}; - -static const char *create_stmts[] = { - [SCHEMA_META] = "CREATE TABLE IF NOT EXISTS Meta (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "key TEXT UNIQUE NOT NULL, " - "value TEXT NOT NULL" - ")", - [INSERT_META] = "INSERT OR IGNORE INTO Meta " - "(key, value) " - "VALUES " - "('revision', " SCHEMA_REVISION ")", - [SCHEMA_SUBSCRIBER] = "CREATE TABLE IF NOT EXISTS Subscriber (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "created TIMESTAMP NOT NULL, " - "updated TIMESTAMP NOT NULL, " - "imsi NUMERIC UNIQUE NOT NULL, " - "name TEXT, " - "extension TEXT UNIQUE, " - "authorized INTEGER NOT NULL DEFAULT 0, " - "tmsi TEXT UNIQUE, " - "lac INTEGER NOT NULL DEFAULT 0, " - "expire_lu TIMESTAMP DEFAULT NULL" - ")", - [SCHEMA_AUTH] = "CREATE TABLE IF NOT EXISTS AuthToken (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "subscriber_id INTEGER UNIQUE NOT NULL, " - "created TIMESTAMP NOT NULL, " - "token TEXT UNIQUE NOT NULL" - ")", - [SCHEMA_EQUIPMENT] = "CREATE TABLE IF NOT EXISTS Equipment (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "created TIMESTAMP NOT NULL, " - "updated TIMESTAMP NOT NULL, " - "name TEXT, " - "classmark1 NUMERIC, " - "classmark2 BLOB, " - "classmark3 BLOB, " - "imei NUMERIC UNIQUE NOT NULL" - ")", - [SCHEMA_EQUIPMENT_WATCH] = "CREATE TABLE IF NOT EXISTS EquipmentWatch (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "created TIMESTAMP NOT NULL, " - "updated TIMESTAMP NOT NULL, " - "subscriber_id NUMERIC NOT NULL, " - "equipment_id NUMERIC NOT NULL, " - "UNIQUE (subscriber_id, equipment_id) " - ")", - [SCHEMA_SMS] = "CREATE TABLE IF NOT EXISTS SMS (" - /* metadata, not part of sms */ - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "created TIMESTAMP NOT NULL, " - "sent TIMESTAMP, " - "deliver_attempts INTEGER NOT NULL DEFAULT 0, " - /* data directly copied/derived from SMS */ - "valid_until TIMESTAMP, " - "reply_path_req INTEGER NOT NULL, " - "status_rep_req INTEGER NOT NULL, " - "is_report INTEGER NOT NULL, " - "msg_ref INTEGER NOT NULL, " - "protocol_id INTEGER NOT NULL, " - "data_coding_scheme INTEGER NOT NULL, " - "ud_hdr_ind INTEGER NOT NULL, " - "src_addr TEXT NOT NULL, " - "src_ton INTEGER NOT NULL, " - "src_npi INTEGER NOT NULL, " - "dest_addr TEXT NOT NULL, " - "dest_ton INTEGER NOT NULL, " - "dest_npi INTEGER NOT NULL, " - "user_data BLOB, " /* TP-UD */ - /* additional data, interpreted from SMS */ - "header BLOB, " /* UD Header */ - "text TEXT " /* decoded UD after UDH */ - ")", - [SCHEMA_VLR] = "CREATE TABLE IF NOT EXISTS VLR (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "created TIMESTAMP NOT NULL, " - "updated TIMESTAMP NOT NULL, " - "subscriber_id NUMERIC UNIQUE NOT NULL, " - "last_bts NUMERIC NOT NULL " - ")", - [SCHEMA_APDU] = "CREATE TABLE IF NOT EXISTS ApduBlobs (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "created TIMESTAMP NOT NULL, " - "apdu_id_flags INTEGER NOT NULL, " - "subscriber_id INTEGER NOT NULL, " - "apdu BLOB " - ")", - [SCHEMA_COUNTERS] = "CREATE TABLE IF NOT EXISTS Counters (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "timestamp TIMESTAMP NOT NULL, " - "value INTEGER NOT NULL, " - "name TEXT NOT NULL " - ")", - [SCHEMA_RATE] = "CREATE TABLE IF NOT EXISTS RateCounters (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "timestamp TIMESTAMP NOT NULL, " - "value INTEGER NOT NULL, " - "name TEXT NOT NULL, " - "idx INTEGER NOT NULL " - ")", - [SCHEMA_AUTHKEY] = "CREATE TABLE IF NOT EXISTS AuthKeys (" - "subscriber_id INTEGER PRIMARY KEY, " - "algorithm_id INTEGER NOT NULL, " - "a3a8_ki BLOB " - ")", - [SCHEMA_AUTHLAST] = "CREATE TABLE IF NOT EXISTS AuthLastTuples (" - "subscriber_id INTEGER PRIMARY KEY, " - "issued TIMESTAMP NOT NULL, " - "use_count INTEGER NOT NULL DEFAULT 0, " - "key_seq INTEGER NOT NULL, " - "rand BLOB NOT NULL, " - "sres BLOB NOT NULL, " - "kc BLOB NOT NULL " - ")", -}; - -void db_error_func(dbi_conn conn, void *data) -{ - const char *msg; - dbi_conn_error(conn, &msg); - LOGP(DDB, LOGL_ERROR, "DBI: %s\n", msg); - osmo_log_backtrace(DDB, LOGL_ERROR); -} - -static int update_db_revision_2(void) -{ - dbi_result result; - - result = dbi_conn_query(conn, - "ALTER TABLE Subscriber " - "ADD COLUMN expire_lu " - "TIMESTAMP DEFAULT NULL"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to alter table Subscriber (upgrade from rev 2).\n"); - return -EINVAL; - } - dbi_result_free(result); - - result = dbi_conn_query(conn, - "UPDATE Meta " - "SET value = '3' " - "WHERE key = 'revision'"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to update DB schema revision (upgrade from rev 2).\n"); - return -EINVAL; - } - dbi_result_free(result); - - return 0; -} - -/** - * Copied from the normal sms_from_result_v3 to avoid having - * to make sure that the real routine will remain backward - * compatible. - */ -static struct gsm_sms *sms_from_result_v3(dbi_result result) -{ - struct gsm_sms *sms = sms_alloc(); - long long unsigned int sender_id; - const char *text, *daddr; - const unsigned char *user_data; - char buf[32]; - char *quoted; - dbi_result result2; - const char *extension; - - if (!sms) - return NULL; - - sms->id = dbi_result_get_ulonglong(result, "id"); - - /* find extension by id, assuming that the subscriber still exists in - * the db */ - sender_id = dbi_result_get_ulonglong(result, "sender_id"); - snprintf(buf, sizeof(buf), "%llu", sender_id); - - dbi_conn_quote_string_copy(conn, buf, "ed); - result2 = dbi_conn_queryf(conn, - "SELECT extension FROM Subscriber " - "WHERE id = %s ", quoted); - free(quoted); - extension = dbi_result_get_string(result2, "extension"); - if (extension) - osmo_strlcpy(sms->src.addr, extension, sizeof(sms->src.addr)); - dbi_result_free(result2); - /* got the extension */ - - sms->reply_path_req = dbi_result_get_ulonglong(result, "reply_path_req"); - sms->status_rep_req = dbi_result_get_ulonglong(result, "status_rep_req"); - sms->ud_hdr_ind = dbi_result_get_ulonglong(result, "ud_hdr_ind"); - sms->protocol_id = dbi_result_get_ulonglong(result, "protocol_id"); - sms->data_coding_scheme = dbi_result_get_ulonglong(result, - "data_coding_scheme"); - - daddr = dbi_result_get_string(result, "dest_addr"); - if (daddr) - osmo_strlcpy(sms->dst.addr, daddr, sizeof(sms->dst.addr)); - - sms->user_data_len = dbi_result_get_field_length(result, "user_data"); - user_data = dbi_result_get_binary(result, "user_data"); - if (sms->user_data_len > sizeof(sms->user_data)) - sms->user_data_len = (uint8_t) sizeof(sms->user_data); - memcpy(sms->user_data, user_data, sms->user_data_len); - - text = dbi_result_get_string(result, "text"); - if (text) - osmo_strlcpy(sms->text, text, sizeof(sms->text)); - return sms; -} - -static int update_db_revision_3(void) -{ - dbi_result result; - struct gsm_sms *sms; - - LOGP(DDB, LOGL_NOTICE, "Going to migrate from revision 3\n"); - - result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to begin transaction (upgrade from rev 3)\n"); - return -EINVAL; - } - dbi_result_free(result); - - /* Rename old SMS table to be able create a new one */ - result = dbi_conn_query(conn, "ALTER TABLE SMS RENAME TO SMS_3"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to rename the old SMS table (upgrade from rev 3).\n"); - goto rollback; - } - dbi_result_free(result); - - /* Create new SMS table with all the bells and whistles! */ - result = dbi_conn_query(conn, create_stmts[SCHEMA_SMS]); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to create a new SMS table (upgrade from rev 3).\n"); - goto rollback; - } - dbi_result_free(result); - - /* Cycle through old messages and convert them to the new format */ - result = dbi_conn_query(conn, "SELECT * FROM SMS_3"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed fetch messages from the old SMS table (upgrade from rev 3).\n"); - goto rollback; - } - while (dbi_result_next_row(result)) { - sms = sms_from_result_v3(result); - if (db_sms_store(sms) != 0) { - LOGP(DDB, LOGL_ERROR, "Failed to store message to the new SMS table(upgrade from rev 3).\n"); - sms_free(sms); - dbi_result_free(result); - goto rollback; - } - sms_free(sms); - } - dbi_result_free(result); - - /* Remove the temporary table */ - result = dbi_conn_query(conn, "DROP TABLE SMS_3"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to drop the old SMS table (upgrade from rev 3).\n"); - goto rollback; - } - dbi_result_free(result); - - /* We're done. Bump DB Meta revision to 4 */ - result = dbi_conn_query(conn, - "UPDATE Meta " - "SET value = '4' " - "WHERE key = 'revision'"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to update DB schema revision (upgrade from rev 3).\n"); - goto rollback; - } - dbi_result_free(result); - - result = dbi_conn_query(conn, "COMMIT TRANSACTION"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to commit the transaction (upgrade from rev 3)\n"); - return -EINVAL; - } else { - dbi_result_free(result); - } - - /* Shrink DB file size by actually wiping out SMS_3 table data */ - result = dbi_conn_query(conn, "VACUUM"); - if (!result) - LOGP(DDB, LOGL_ERROR, - "VACUUM failed. Ignoring it (upgrade from rev 3).\n"); - else - dbi_result_free(result); - - return 0; - -rollback: - result = dbi_conn_query(conn, "ROLLBACK TRANSACTION"); - if (!result) - LOGP(DDB, LOGL_ERROR, - "Rollback failed (upgrade from rev 3).\n"); - else - dbi_result_free(result); - return -EINVAL; -} - -/* Just like v3, but there is a new message reference field for status reports, - * that is set to zero for existing entries since there is no way we can infer - * this. - */ -static struct gsm_sms *sms_from_result_v4(dbi_result result) -{ - struct gsm_sms *sms = sms_alloc(); - const unsigned char *user_data; - const char *text, *addr; - - if (!sms) - return NULL; - - sms->id = dbi_result_get_ulonglong(result, "id"); - - sms->reply_path_req = dbi_result_get_ulonglong(result, "reply_path_req"); - sms->status_rep_req = dbi_result_get_ulonglong(result, "status_rep_req"); - sms->ud_hdr_ind = dbi_result_get_ulonglong(result, "ud_hdr_ind"); - sms->protocol_id = dbi_result_get_ulonglong(result, "protocol_id"); - sms->data_coding_scheme = dbi_result_get_ulonglong(result, - "data_coding_scheme"); - - addr = dbi_result_get_string(result, "src_addr"); - osmo_strlcpy(sms->src.addr, addr, sizeof(sms->src.addr)); - sms->src.ton = dbi_result_get_ulonglong(result, "src_ton"); - sms->src.npi = dbi_result_get_ulonglong(result, "src_npi"); - - addr = dbi_result_get_string(result, "dest_addr"); - osmo_strlcpy(sms->dst.addr, addr, sizeof(sms->dst.addr)); - sms->dst.ton = dbi_result_get_ulonglong(result, "dest_ton"); - sms->dst.npi = dbi_result_get_ulonglong(result, "dest_npi"); - - sms->user_data_len = dbi_result_get_field_length(result, "user_data"); - user_data = dbi_result_get_binary(result, "user_data"); - if (sms->user_data_len > sizeof(sms->user_data)) - sms->user_data_len = (uint8_t) sizeof(sms->user_data); - memcpy(sms->user_data, user_data, sms->user_data_len); - - text = dbi_result_get_string(result, "text"); - if (text) - osmo_strlcpy(sms->text, text, sizeof(sms->text)); - return sms; -} - -static int update_db_revision_4(void) -{ - dbi_result result; - struct gsm_sms *sms; - - LOGP(DDB, LOGL_NOTICE, "Going to migrate from revision 4\n"); - - result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to begin transaction (upgrade from rev 4)\n"); - return -EINVAL; - } - dbi_result_free(result); - - /* Rename old SMS table to be able create a new one */ - result = dbi_conn_query(conn, "ALTER TABLE SMS RENAME TO SMS_4"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to rename the old SMS table (upgrade from rev 4).\n"); - goto rollback; - } - dbi_result_free(result); - - /* Create new SMS table with all the bells and whistles! */ - result = dbi_conn_query(conn, create_stmts[SCHEMA_SMS]); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to create a new SMS table (upgrade from rev 4).\n"); - goto rollback; - } - dbi_result_free(result); - - /* Cycle through old messages and convert them to the new format */ - result = dbi_conn_query(conn, "SELECT * FROM SMS_4"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed fetch messages from the old SMS table (upgrade from rev 4).\n"); - goto rollback; - } - while (dbi_result_next_row(result)) { - sms = sms_from_result_v4(result); - if (db_sms_store(sms) != 0) { - LOGP(DDB, LOGL_ERROR, "Failed to store message to the new SMS table(upgrade from rev 4).\n"); - sms_free(sms); - dbi_result_free(result); - goto rollback; - } - sms_free(sms); - } - dbi_result_free(result); - - /* Remove the temporary table */ - result = dbi_conn_query(conn, "DROP TABLE SMS_4"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to drop the old SMS table (upgrade from rev 4).\n"); - goto rollback; - } - dbi_result_free(result); - - /* We're done. Bump DB Meta revision to 4 */ - result = dbi_conn_query(conn, - "UPDATE Meta " - "SET value = '5' " - "WHERE key = 'revision'"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to update DB schema revision (upgrade from rev 4).\n"); - goto rollback; - } - dbi_result_free(result); - - result = dbi_conn_query(conn, "COMMIT TRANSACTION"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to commit the transaction (upgrade from rev 4)\n"); - return -EINVAL; - } else { - dbi_result_free(result); - } - - /* Shrink DB file size by actually wiping out SMS_4 table data */ - result = dbi_conn_query(conn, "VACUUM"); - if (!result) - LOGP(DDB, LOGL_ERROR, - "VACUUM failed. Ignoring it (upgrade from rev 4).\n"); - else - dbi_result_free(result); - - return 0; - -rollback: - result = dbi_conn_query(conn, "ROLLBACK TRANSACTION"); - if (!result) - LOGP(DDB, LOGL_ERROR, - "Rollback failed (upgrade from rev 4).\n"); - else - dbi_result_free(result); - return -EINVAL; -} - -static int check_db_revision(void) -{ - dbi_result result; - const char *rev_s; - int db_rev = 0; - - /* Make a query */ - result = dbi_conn_query(conn, - "SELECT value FROM Meta " - "WHERE key = 'revision'"); - - if (!result) - return -EINVAL; - - if (!dbi_result_next_row(result)) { - dbi_result_free(result); - return -EINVAL; - } - - /* Fetch the DB schema revision */ - rev_s = dbi_result_get_string(result, "value"); - if (!rev_s) { - dbi_result_free(result); - return -EINVAL; - } - - if (!strcmp(rev_s, SCHEMA_REVISION)) { - /* Everything is fine */ - dbi_result_free(result); - return 0; - } - - db_rev = atoi(rev_s); - dbi_result_free(result); - - /* Incremental migration waterfall */ - switch (db_rev) { - case 2: - if (update_db_revision_2()) - goto error; - case 3: - if (update_db_revision_3()) - goto error; - case 4: - if (update_db_revision_4()) - goto error; - - /* The end of waterfall */ - break; - default: - LOGP(DDB, LOGL_FATAL, - "Invalid database schema revision '%d'.\n", db_rev); - return -EINVAL; - } - - return 0; - -error: - LOGP(DDB, LOGL_FATAL, "Failed to update database " - "from schema revision '%d'.\n", db_rev); - return -EINVAL; -} - -static int db_configure(void) -{ - dbi_result result; - - result = dbi_conn_query(conn, - "PRAGMA synchronous = FULL"); - if (!result) - return -EINVAL; - - dbi_result_free(result); - return 0; -} - -int db_init(const char *name) -{ - dbi_initialize(NULL); - - conn = dbi_conn_new("sqlite3"); - if (conn == NULL) { - LOGP(DDB, LOGL_FATAL, "Failed to create connection.\n"); - return 1; - } - - dbi_conn_error_handler( conn, db_error_func, NULL ); - - /* MySQL - dbi_conn_set_option(conn, "host", "localhost"); - dbi_conn_set_option(conn, "username", "your_name"); - dbi_conn_set_option(conn, "password", "your_password"); - dbi_conn_set_option(conn, "dbname", "your_dbname"); - dbi_conn_set_option(conn, "encoding", "UTF-8"); - */ - - /* SqLite 3 */ - db_basename = strdup(name); - db_dirname = strdup(name); - dbi_conn_set_option(conn, "sqlite3_dbdir", dirname(db_dirname)); - dbi_conn_set_option(conn, "dbname", basename(db_basename)); - - if (dbi_conn_connect(conn) < 0) - goto out_err; - - return 0; - -out_err: - free(db_dirname); - free(db_basename); - db_dirname = db_basename = NULL; - return -1; -} - - -int db_prepare(void) -{ - dbi_result result; - int i; - - for (i = 0; i < ARRAY_SIZE(create_stmts); i++) { - result = dbi_conn_query(conn, create_stmts[i]); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to create some table.\n"); - return 1; - } - dbi_result_free(result); - } - - if (check_db_revision() < 0) { - LOGP(DDB, LOGL_FATAL, "Database schema revision invalid, " - "please update your database schema\n"); - return -1; - } - - db_configure(); - - return 0; -} - -int db_fini(void) -{ - dbi_conn_close(conn); - dbi_shutdown(); - - free(db_dirname); - free(db_basename); - return 0; -} - -/* store an [unsent] SMS to the database */ -int db_sms_store(struct gsm_sms *sms) -{ - dbi_result result; - char *q_text, *q_daddr, *q_saddr; - unsigned char *q_udata; - char *validity_timestamp = "2222-2-2"; - - /* FIXME: generate validity timestamp based on validity_minutes */ - - dbi_conn_quote_string_copy(conn, (char *)sms->text, &q_text); - dbi_conn_quote_string_copy(conn, (char *)sms->dst.addr, &q_daddr); - dbi_conn_quote_string_copy(conn, (char *)sms->src.addr, &q_saddr); - dbi_conn_quote_binary_copy(conn, sms->user_data, sms->user_data_len, - &q_udata); - - /* FIXME: correct validity period */ - result = dbi_conn_queryf(conn, - "INSERT INTO SMS " - "(created, valid_until, " - "reply_path_req, status_rep_req, is_report, " - "msg_ref, protocol_id, data_coding_scheme, " - "ud_hdr_ind, " - "user_data, text, " - "dest_addr, dest_ton, dest_npi, " - "src_addr, src_ton, src_npi) VALUES " - "(datetime('now'), %u, " - "%u, %u, %u, " - "%u, %u, %u, " - "%u, " - "%s, %s, " - "%s, %u, %u, " - "%s, %u, %u)", - validity_timestamp, - sms->reply_path_req, sms->status_rep_req, sms->is_report, - sms->msg_ref, sms->protocol_id, sms->data_coding_scheme, - sms->ud_hdr_ind, - q_udata, q_text, - q_daddr, sms->dst.ton, sms->dst.npi, - q_saddr, sms->src.ton, sms->src.npi); - free(q_text); - free(q_udata); - free(q_daddr); - free(q_saddr); - - if (!result) - return -EIO; - - dbi_result_free(result); - return 0; -} - -static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result result) -{ - struct gsm_sms *sms = sms_alloc(); - const char *text, *daddr, *saddr; - const unsigned char *user_data; - - if (!sms) - return NULL; - - sms->id = dbi_result_get_ulonglong(result, "id"); - - /* FIXME: validity */ - /* FIXME: those should all be get_uchar, but sqlite3 is braindead */ - sms->created = dbi_result_get_datetime(result, "created"); - sms->reply_path_req = dbi_result_get_ulonglong(result, "reply_path_req"); - sms->status_rep_req = dbi_result_get_ulonglong(result, "status_rep_req"); - sms->is_report = dbi_result_get_ulonglong(result, "is_report"); - sms->msg_ref = dbi_result_get_ulonglong(result, "msg_ref"); - sms->ud_hdr_ind = dbi_result_get_ulonglong(result, "ud_hdr_ind"); - sms->protocol_id = dbi_result_get_ulonglong(result, "protocol_id"); - sms->data_coding_scheme = dbi_result_get_ulonglong(result, - "data_coding_scheme"); - - sms->dst.npi = dbi_result_get_ulonglong(result, "dest_npi"); - sms->dst.ton = dbi_result_get_ulonglong(result, "dest_ton"); - daddr = dbi_result_get_string(result, "dest_addr"); - if (daddr) - osmo_strlcpy(sms->dst.addr, daddr, sizeof(sms->dst.addr)); - sms->receiver = vlr_subscr_find_by_msisdn(net->vlr, sms->dst.addr); - - sms->src.npi = dbi_result_get_ulonglong(result, "src_npi"); - sms->src.ton = dbi_result_get_ulonglong(result, "src_ton"); - saddr = dbi_result_get_string(result, "src_addr"); - if (saddr) - osmo_strlcpy(sms->src.addr, saddr, sizeof(sms->src.addr)); - - sms->user_data_len = dbi_result_get_field_length(result, "user_data"); - user_data = dbi_result_get_binary(result, "user_data"); - if (sms->user_data_len > sizeof(sms->user_data)) - sms->user_data_len = (uint8_t) sizeof(sms->user_data); - memcpy(sms->user_data, user_data, sms->user_data_len); - - text = dbi_result_get_string(result, "text"); - if (text) - osmo_strlcpy(sms->text, text, sizeof(sms->text)); - return sms; -} - -struct gsm_sms *db_sms_get(struct gsm_network *net, unsigned long long id) -{ - dbi_result result; - struct gsm_sms *sms; - - result = dbi_conn_queryf(conn, - "SELECT * FROM SMS WHERE SMS.id = %llu", id); - if (!result) - return NULL; - - if (!dbi_result_next_row(result)) { - dbi_result_free(result); - return NULL; - } - - sms = sms_from_result(net, result); - - dbi_result_free(result); - - return sms; -} - -struct gsm_sms *db_sms_get_next_unsent(struct gsm_network *net, - unsigned long long min_sms_id, - unsigned int max_failed) -{ - dbi_result result; - struct gsm_sms *sms; - - result = dbi_conn_queryf(conn, - "SELECT * FROM SMS" - " WHERE sent IS NULL" - " AND id >= %llu" - " AND deliver_attempts <= %u" - " ORDER BY id LIMIT 1", - min_sms_id, max_failed); - - if (!result) - return NULL; - - if (!dbi_result_next_row(result)) { - dbi_result_free(result); - return NULL; - } - - sms = sms_from_result(net, result); - - dbi_result_free(result); - - return sms; -} - -/* retrieve the next unsent SMS for a given subscriber */ -struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub, - unsigned int max_failed) -{ - struct gsm_network *net = vsub->vlr->user_ctx; - dbi_result result; - struct gsm_sms *sms; - - if (!vsub->lu_complete) - return NULL; - - result = dbi_conn_queryf(conn, - "SELECT * FROM SMS" - " WHERE sent IS NULL" - " AND dest_addr=%s" - " AND deliver_attempts <= %u" - " ORDER BY id LIMIT 1", - vsub->msisdn, max_failed); - if (!result) - return NULL; - - if (!dbi_result_next_row(result)) { - dbi_result_free(result); - return NULL; - } - - sms = sms_from_result(net, result); - - dbi_result_free(result); - - return sms; -} - -struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net, - const char *last_msisdn, - unsigned int max_failed) -{ - dbi_result result; - struct gsm_sms *sms; - - result = dbi_conn_queryf(conn, - "SELECT * FROM SMS" - " WHERE sent IS NULL" - " AND dest_addr > '%s'" - " AND deliver_attempts <= %u" - " ORDER BY dest_addr, id LIMIT 1", - last_msisdn, max_failed); - if (!result) - return NULL; - - if (!dbi_result_next_row(result)) { - dbi_result_free(result); - return NULL; - } - - sms = sms_from_result(net, result); - - dbi_result_free(result); - - return sms; -} - -/* mark a given SMS as delivered */ -int db_sms_mark_delivered(struct gsm_sms *sms) -{ - dbi_result result; - - result = dbi_conn_queryf(conn, - "UPDATE SMS " - "SET sent = datetime('now') " - "WHERE id = %llu", sms->id); - if (!result) { - LOGP(DDB, LOGL_ERROR, "Failed to mark SMS %llu as sent.\n", sms->id); - return 1; - } - - dbi_result_free(result); - return 0; -} - -/* increase the number of attempted deliveries */ -int db_sms_inc_deliver_attempts(struct gsm_sms *sms) -{ - dbi_result result; - - result = dbi_conn_queryf(conn, - "UPDATE SMS " - "SET deliver_attempts = deliver_attempts + 1 " - "WHERE id = %llu", sms->id); - if (!result) { - LOGP(DDB, LOGL_ERROR, "Failed to inc deliver attempts for " - "SMS %llu.\n", sms->id); - return 1; - } - - dbi_result_free(result); - return 0; -} - -/* Drop all pending SMS to or from the given extension */ -int db_sms_delete_by_msisdn(const char *msisdn) -{ - dbi_result result; - if (!msisdn || !*msisdn) - return 0; - result = dbi_conn_queryf(conn, - "DELETE FROM SMS WHERE src_addr=%s OR dest_addr=%s", - msisdn, msisdn); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to delete SMS for %s\n", msisdn); - return -1; - } - dbi_result_free(result); - return 0; -} - -int db_store_counter(struct osmo_counter *ctr) -{ - dbi_result result; - char *q_name; - - dbi_conn_quote_string_copy(conn, ctr->name, &q_name); - - result = dbi_conn_queryf(conn, - "INSERT INTO Counters " - "(timestamp,name,value) VALUES " - "(datetime('now'),%s,%lu)", q_name, ctr->value); - - free(q_name); - - if (!result) - return -EIO; - - dbi_result_free(result); - return 0; -} - -static int db_store_rate_ctr(struct rate_ctr_group *ctrg, unsigned int num, - char *q_prefix) -{ - dbi_result result; - char *q_name; - - dbi_conn_quote_string_copy(conn, ctrg->desc->ctr_desc[num].name, - &q_name); - - result = dbi_conn_queryf(conn, - "Insert INTO RateCounters " - "(timestamp,name,idx,value) VALUES " - "(datetime('now'),%s.%s,%u,%"PRIu64")", - q_prefix, q_name, ctrg->idx, ctrg->ctr[num].current); - - free(q_name); - - if (!result) - return -EIO; - - dbi_result_free(result); - return 0; -} - -int db_store_rate_ctr_group(struct rate_ctr_group *ctrg) -{ - unsigned int i; - char *q_prefix; - - dbi_conn_quote_string_copy(conn, ctrg->desc->group_name_prefix, &q_prefix); - - for (i = 0; i < ctrg->desc->num_ctr; i++) - db_store_rate_ctr(ctrg, i, q_prefix); - - free(q_prefix); - - return 0; -} diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c deleted file mode 100644 index 21bc2b83b..000000000 --- a/src/libmsc/gsm_04_08.c +++ /dev/null @@ -1,3493 +0,0 @@ -/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface - * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */ - -/* (C) 2008-2016 by Harald Welte - * (C) 2008-2012 by Holger Hans Peter Freyther - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bscconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef BUILD_IU -#include -#endif - -#include -#include - -#include - - -void *tall_locop_ctx; -void *tall_authciphop_ctx; - -static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, - uint32_t send_tmsi); -static int gsm48_tx_simple(struct gsm_subscriber_connection *conn, - uint8_t pdisc, uint8_t msg_type); - -struct gsm_lai { - uint16_t mcc; - uint16_t mnc; - uint16_t lac; -}; - -static uint32_t new_callref = 0x80000001; - -void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg) -{ - net->mncc_recv(net, msg); -} - -static int gsm48_conn_sendmsg(struct msgb *msg, struct gsm_subscriber_connection *conn, - struct gsm_trans *trans) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msg->data; - - /* if we get passed a transaction reference, do some common - * work that the caller no longer has to do */ - if (trans) { - gh->proto_discr = trans->protocol | (trans->transaction_id << 4); - } - - return msc_tx_dtap(conn, msg); -} - -int gsm48_cc_tx_notify_ss(struct gsm_trans *trans, const char *message) -{ - struct gsm48_hdr *gh; - struct msgb *ss_notify; - - ss_notify = gsm0480_create_notifySS(message); - if (!ss_notify) - return -1; - - gsm0480_wrap_invoke(ss_notify, GSM0480_OP_CODE_NOTIFY_SS, 0); - uint8_t *data = msgb_push(ss_notify, 1); - data[0] = ss_notify->len - 1; - gh = (struct gsm48_hdr *) msgb_push(ss_notify, sizeof(*gh)); - gh->msg_type = GSM48_MT_CC_FACILITY; - return gsm48_conn_sendmsg(ss_notify, trans->conn, trans); -} - -/* clear all transactions globally; used in case of MNCC socket disconnect */ -void gsm0408_clear_all_trans(struct gsm_network *net, int protocol) -{ - struct gsm_trans *trans, *temp; - - LOGP(DCC, LOGL_NOTICE, "Clearing all currently active transactions!!!\n"); - - llist_for_each_entry_safe(trans, temp, &net->trans_list, entry) { - if (trans->protocol == protocol) { - trans->callref = 0; - trans_free(trans); - } - } -} - -/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */ -static int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause) -{ - struct msgb *msg; - - msg = gsm48_create_loc_upd_rej(cause); - if (!msg) { - LOGP(DMM, LOGL_ERROR, "Failed to create msg for LOCATION UPDATING REJECT.\n"); - return -1; - } - - LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT\n", - vlr_subscr_name(conn->vsub)); - - return gsm48_conn_sendmsg(msg, conn, NULL); -} - -/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */ -static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, - uint32_t send_tmsi) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD ACC"); - struct gsm48_hdr *gh; - struct gsm48_loc_area_id *lai; - uint8_t *mid; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_MM; - gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT; - - lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai)); - gsm48_generate_lai(lai, conn->network->country_code, - conn->network->network_code, - conn->lac); - - if (send_tmsi == GSM_RESERVED_TMSI) { - /* we did not allocate a TMSI to the MS, so we need to - * include the IMSI in order for the MS to delete any - * old TMSI that might still be allocated */ - uint8_t mi[10]; - int len; - len = gsm48_generate_mid_from_imsi(mi, conn->vsub->imsi); - mid = msgb_put(msg, len); - memcpy(mid, mi, len); - DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT\n", - vlr_subscr_name(conn->vsub)); - } else { - /* Include the TMSI, which means that the MS will send a - * TMSI REALLOCATION COMPLETE, and we should wait for - * that until T3250 expiration */ - mid = msgb_put(msg, GSM48_MID_TMSI_LEN); - gsm48_generate_mid_from_tmsi(mid, send_tmsi); - DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT (TMSI = 0x%08x)\n", - vlr_subscr_name(conn->vsub), - send_tmsi); - } - /* TODO: Follow-on proceed */ - /* TODO: CTS permission */ - /* TODO: Equivalent PLMNs */ - /* TODO: Emergency Number List */ - /* TODO: Per-MS T3312 */ - - - return gsm48_conn_sendmsg(msg, conn, NULL); -} - -/* Transmit Chapter 9.2.10 Identity Request */ -static int mm_tx_identity_req(struct gsm_subscriber_connection *conn, uint8_t id_type) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ"); - struct gsm48_hdr *gh; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM; - gh->msg_type = GSM48_MT_MM_ID_REQ; - gh->data[0] = id_type; - - return gsm48_conn_sendmsg(msg, conn, NULL); -} - -/* Parse Chapter 9.2.11 Identity Response */ -static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK; - char mi_string[GSM48_MI_SIZE]; - - if (!conn->vsub) { - LOGP(DMM, LOGL_ERROR, - "Rx MM Identity Response: invalid: no subscriber\n"); - return -EINVAL; - } - - gsm48_mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]); - DEBUGP(DMM, "IDENTITY RESPONSE: MI(%s)=%s\n", - gsm48_mi_type_name(mi_type), mi_string); - - osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, gh->data); - - return vlr_subscr_rx_id_resp(conn->vsub, gh->data+1, gh->data[0]); -} - -/* FIXME: to libosmogsm */ -static const struct value_string lupd_names[] = { - { GSM48_LUPD_NORMAL, "NORMAL" }, - { GSM48_LUPD_PERIODIC, "PERIODIC" }, - { GSM48_LUPD_IMSI_ATT, "IMSI ATTACH" }, - { 0, NULL } -}; - -/* Chapter 9.2.15: Receive Location Updating Request. - * Keep this function non-static for direct invocation by unit tests. */ -int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - static const enum subscr_conn_from conn_from_lu = SUBSCR_CONN_FROM_LU; - struct gsm_network *net = conn->network; - struct gsm48_hdr *gh = msgb_l3(msg); - struct gsm48_loc_upd_req *lu; - uint8_t mi_type; - char mi_string[GSM48_MI_SIZE]; - enum vlr_lu_type vlr_lu_type = VLR_LU_TYPE_REGULAR; - uint32_t tmsi; - char *imsi; - struct osmo_location_area_id old_lai, new_lai; - struct osmo_fsm_inst *lu_fsm; - bool is_utran; - int rc; - - lu = (struct gsm48_loc_upd_req *) gh->data; - - mi_type = lu->mi[0] & GSM_MI_TYPE_MASK; - - gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len); - - rc = msc_create_conn_fsm(conn, mi_string); - if (rc) - /* logging already happened in msc_create_conn_fsm() */ - return rc; - - conn->classmark.classmark1 = lu->classmark1; - conn->classmark.classmark1_set = true; - - DEBUGP(DMM, "LOCATION UPDATING REQUEST: MI(%s)=%s type=%s\n", - gsm48_mi_type_name(mi_type), mi_string, - get_value_string(lupd_names, lu->type)); - - osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, &lu->mi_len); - - switch (lu->type) { - case GSM48_LUPD_NORMAL: - rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL]); - vlr_lu_type = VLR_LU_TYPE_REGULAR; - break; - case GSM48_LUPD_IMSI_ATT: - rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH]); - vlr_lu_type = VLR_LU_TYPE_IMSI_ATTACH; - break; - case GSM48_LUPD_PERIODIC: - rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC]); - vlr_lu_type = VLR_LU_TYPE_PERIODIC; - break; - } - - /* TODO: 10.5.1.6 MS Classmark for UMTS / Classmark 2 */ - /* TODO: 10.5.3.14 Aditional update parameters (CS fallback calls) */ - /* TODO: 10.5.7.8 Device properties */ - /* TODO: 10.5.1.15 MS network feature support */ - - switch (mi_type) { - case GSM_MI_TYPE_IMSI: - tmsi = GSM_RESERVED_TMSI; - imsi = mi_string; - break; - case GSM_MI_TYPE_TMSI: - tmsi = tmsi_from_string(mi_string); - imsi = NULL; - break; - default: - DEBUGPC(DMM, "unknown mobile identity type\n"); - tmsi = GSM_RESERVED_TMSI; - imsi = NULL; - break; - } - - gsm48_decode_lai(&lu->lai, &old_lai.plmn.mcc, - &old_lai.plmn.mnc, &old_lai.lac); - new_lai.plmn.mcc = conn->network->country_code; - new_lai.plmn.mnc = conn->network->network_code; - new_lai.lac = conn->lac; - DEBUGP(DMM, "LU/new-LAC: %u/%u\n", old_lai.lac, new_lai.lac); - - is_utran = (conn->via_ran == RAN_UTRAN_IU); - lu_fsm = vlr_loc_update(conn->conn_fsm, - SUBSCR_CONN_E_ACCEPTED, - SUBSCR_CONN_E_CN_CLOSE, - (void*)&conn_from_lu, - net->vlr, conn, vlr_lu_type, tmsi, imsi, - &old_lai, &new_lai, - is_utran || conn->network->authentication_required, - is_utran? VLR_CIPH_A5_3 - : conn->network->a5_encryption, - classmark_is_r99(&conn->classmark), - is_utran, - net->vlr->cfg.assign_tmsi); - if (!lu_fsm) { - DEBUGP(DRR, "%s: Can't start LU FSM\n", mi_string); - return 0; - } - - /* From vlr_loc_update() we expect an implicit dispatch of - * VLR_ULA_E_UPDATE_LA, and thus we expect msc_vlr_subscr_assoc() to - * already have been called and completed. Has an error occured? */ - - if (!conn->vsub || conn->vsub->lu_fsm != lu_fsm) { - LOGP(DRR, LOGL_ERROR, - "%s: internal error during Location Updating attempt\n", - mi_string); - return -EIO; - } - - return 0; -} - -/* Turn int into semi-octet representation: 98 => 0x89 */ -/* FIXME: libosmocore/libosmogsm */ -static uint8_t bcdify(uint8_t value) -{ - uint8_t ret; - - ret = value / 10; - ret |= (value % 10) << 4; - - return ret; -} - - -/* Section 9.2.15a */ -int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 MM INF"); - struct gsm48_hdr *gh; - struct gsm_network *net = conn->network; - uint8_t *ptr8; - int name_len, name_pad; - - time_t cur_t; - struct tm* gmt_time; - struct tm* local_time; - int tzunits; - int dst = 0; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_MM; - gh->msg_type = GSM48_MT_MM_INFO; - - if (net->name_long) { -#if 0 - name_len = strlen(net->name_long); - /* 10.5.3.5a */ - ptr8 = msgb_put(msg, 3); - ptr8[0] = GSM48_IE_NAME_LONG; - ptr8[1] = name_len*2 +1; - ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */ - - ptr16 = (uint16_t *) msgb_put(msg, name_len*2); - for (i = 0; i < name_len; i++) - ptr16[i] = htons(net->name_long[i]); - - /* FIXME: Use Cell Broadcast, not UCS-2, since - * UCS-2 is only supported by later revisions of the spec */ -#endif - name_len = (strlen(net->name_long)*7)/8; - name_pad = (8 - strlen(net->name_long)*7)%8; - if (name_pad > 0) - name_len++; - /* 10.5.3.5a */ - ptr8 = msgb_put(msg, 3); - ptr8[0] = GSM48_IE_NAME_LONG; - ptr8[1] = name_len +1; - ptr8[2] = 0x80 | name_pad; /* Cell Broadcast DCS, no CI */ - - ptr8 = msgb_put(msg, name_len); - gsm_7bit_encode_n(ptr8, name_len, net->name_long, NULL); - - } - - if (net->name_short) { -#if 0 - name_len = strlen(net->name_short); - /* 10.5.3.5a */ - ptr8 = (uint8_t *) msgb_put(msg, 3); - ptr8[0] = GSM48_IE_NAME_SHORT; - ptr8[1] = name_len*2 + 1; - ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */ - - ptr16 = (uint16_t *) msgb_put(msg, name_len*2); - for (i = 0; i < name_len; i++) - ptr16[i] = htons(net->name_short[i]); -#endif - name_len = (strlen(net->name_short)*7)/8; - name_pad = (8 - strlen(net->name_short)*7)%8; - if (name_pad > 0) - name_len++; - /* 10.5.3.5a */ - ptr8 = (uint8_t *) msgb_put(msg, 3); - ptr8[0] = GSM48_IE_NAME_SHORT; - ptr8[1] = name_len +1; - ptr8[2] = 0x80 | name_pad; /* Cell Broadcast DCS, no CI */ - - ptr8 = msgb_put(msg, name_len); - gsm_7bit_encode_n(ptr8, name_len, net->name_short, NULL); - - } - - /* Section 10.5.3.9 */ - cur_t = time(NULL); - gmt_time = gmtime(&cur_t); - - ptr8 = msgb_put(msg, 8); - ptr8[0] = GSM48_IE_NET_TIME_TZ; - ptr8[1] = bcdify(gmt_time->tm_year % 100); - ptr8[2] = bcdify(gmt_time->tm_mon + 1); - ptr8[3] = bcdify(gmt_time->tm_mday); - ptr8[4] = bcdify(gmt_time->tm_hour); - ptr8[5] = bcdify(gmt_time->tm_min); - ptr8[6] = bcdify(gmt_time->tm_sec); - - if (net->tz.override) { - /* Convert tz.hr and tz.mn to units */ - if (net->tz.hr < 0) { - tzunits = ((net->tz.hr/-1)*4); - tzunits = tzunits + (net->tz.mn/15); - ptr8[7] = bcdify(tzunits); - /* Set negative time */ - ptr8[7] |= 0x08; - } - else { - tzunits = net->tz.hr*4; - tzunits = tzunits + (net->tz.mn/15); - ptr8[7] = bcdify(tzunits); - } - /* Convert DST value */ - if (net->tz.dst >= 0 && net->tz.dst <= 2) - dst = net->tz.dst; - } - else { - /* Need to get GSM offset and convert into 15 min units */ - /* This probably breaks if gmtoff returns a value not evenly divisible by 15? */ -#ifdef HAVE_TM_GMTOFF_IN_TM - local_time = localtime(&cur_t); - tzunits = (local_time->tm_gmtoff/60)/15; -#else - /* find timezone offset */ - time_t utc; - double offsetFromUTC; - utc = mktime(gmt_time); - local_time = localtime(&cur_t); - offsetFromUTC = difftime(cur_t, utc); - if (local_time->tm_isdst) - offsetFromUTC += 3600.0; - tzunits = ((int)offsetFromUTC) / 60 / 15; -#endif - if (tzunits < 0) { - tzunits = tzunits/-1; - ptr8[7] = bcdify(tzunits); - /* Flip it to negative */ - ptr8[7] |= 0x08; - } - else - ptr8[7] = bcdify(tzunits); - - /* Does not support DST +2 */ - if (local_time->tm_isdst) - dst = 1; - } - - if (dst) { - ptr8 = msgb_put(msg, 3); - ptr8[0] = GSM48_IE_NET_DST; - ptr8[1] = 1; - ptr8[2] = dst; - } - - DEBUGP(DMM, "-> MM INFO\n"); - - return gsm48_conn_sendmsg(msg, conn, NULL); -} - -/*! Send an Authentication Request to MS on the given subscriber connection - * according to 3GPP/ETSI TS 24.008, Section 9.2.2. - * \param[in] conn Subscriber connection to send on. - * \param[in] rand Random challenge token to send, must be 16 bytes long. - * \param[in] autn r99: In case of UMTS mutual authentication, AUTN token to - * send; must be 16 bytes long, or pass NULL for plain GSM auth. - * \param[in] key_seq auth tuple's sequence number. - */ -int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand, - uint8_t *autn, int key_seq) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH REQ"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - struct gsm48_auth_req *ar = (struct gsm48_auth_req *) msgb_put(msg, sizeof(*ar)); - - DEBUGP(DMM, "-> AUTH REQ (rand = %s)\n", osmo_hexdump_nospc(rand, 16)); - if (autn) - DEBUGP(DMM, " AUTH REQ (autn = %s)\n", osmo_hexdump_nospc(autn, 16)); - - gh->proto_discr = GSM48_PDISC_MM; - gh->msg_type = GSM48_MT_MM_AUTH_REQ; - - ar->key_seq = key_seq; - - /* 16 bytes RAND parameters */ - osmo_static_assert(sizeof(ar->rand) == 16, sizeof_auth_req_r99_rand); - if (rand) - memcpy(ar->rand, rand, 16); - - - /* 16 bytes AUTN */ - if (autn) - msgb_tlv_put(msg, GSM48_IE_AUTN, 16, autn); - - return gsm48_conn_sendmsg(msg, conn, NULL); -} - -/* Section 9.2.1 */ -int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn) -{ - DEBUGP(DMM, "-> AUTH REJECT\n"); - return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_AUTH_REJ); -} - -static int msc_vlr_tx_cm_serv_acc(void *msc_conn_ref); -static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum vlr_proc_arq_result result); - -static int cm_serv_reuse_conn(struct gsm_subscriber_connection *conn, const uint8_t *mi_lv) -{ - uint8_t mi_type; - char mi_string[GSM48_MI_SIZE]; - uint32_t tmsi; - - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, mi_lv[0]); - mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; - - switch (mi_type) { - case GSM_MI_TYPE_IMSI: - if (vlr_subscr_matches_imsi(conn->vsub, mi_string)) - goto accept_reuse; - break; - case GSM_MI_TYPE_TMSI: - tmsi = osmo_load32be(mi_lv+2); - if (vlr_subscr_matches_tmsi(conn->vsub, tmsi)) - goto accept_reuse; - break; - case GSM_MI_TYPE_IMEI: - if (vlr_subscr_matches_imei(conn->vsub, mi_string)) - goto accept_reuse; - break; - default: - break; - } - - LOGP(DMM, LOGL_ERROR, "%s: CM Service Request with mismatching mobile identity: %s %s\n", - vlr_subscr_name(conn->vsub), gsm48_mi_type_name(mi_type), mi_string); - msc_vlr_tx_cm_serv_rej(conn, VLR_PR_ARQ_RES_ILLEGAL_SUBSCR); - return -EINVAL; - -accept_reuse: - DEBUGP(DMM, "%s: re-using already accepted connection\n", - vlr_subscr_name(conn->vsub)); - conn->received_cm_service_request = true; - return conn->network->vlr->ops.tx_cm_serv_acc(conn); -} - -/* - * Handle CM Service Requests - * a) Verify that the packet is long enough to contain the information - * we require otherwsie reject with INCORRECT_MESSAGE - * b) Try to parse the TMSI. If we do not have one reject - * c) Check that we know the subscriber with the TMSI otherwise reject - * with a HLR cause - * d) Set the subscriber on the conn and accept - * - * Keep this function non-static for direct invocation by unit tests. - */ -int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - static const enum subscr_conn_from conn_from_cm_service_req = - SUBSCR_CONN_FROM_CM_SERVICE_REQ; - struct gsm_network *net = conn->network; - uint8_t mi_type; - char mi_string[GSM48_MI_SIZE]; - - struct gsm48_hdr *gh = msgb_l3(msg); - struct gsm48_service_request *req = - (struct gsm48_service_request *)gh->data; - /* unfortunately in Phase1 the classmark2 length is variable */ - uint8_t classmark2_len = gh->data[1]; - uint8_t *classmark2 = gh->data+2; - uint8_t mi_len = *(classmark2 + classmark2_len); - uint8_t *mi = (classmark2 + classmark2_len + 1); - struct osmo_location_area_id lai; - bool is_utran; - int rc; - - lai.plmn.mcc = conn->network->country_code; - lai.plmn.mnc = conn->network->network_code; - lai.lac = conn->lac; - - DEBUGP(DMM, "<- CM SERVICE REQUEST "); - if (msg->data_len < sizeof(struct gsm48_service_request*)) { - DEBUGPC(DMM, "wrong sized message\n"); - return msc_gsm48_tx_mm_serv_rej(conn, - GSM48_REJECT_INCORRECT_MESSAGE); - } - - if (msg->data_len < req->mi_len + 6) { - DEBUGPC(DMM, "does not fit in packet\n"); - return msc_gsm48_tx_mm_serv_rej(conn, - GSM48_REJECT_INCORRECT_MESSAGE); - } - - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); - mi_type = mi[0] & GSM_MI_TYPE_MASK; - - if (mi_type == GSM_MI_TYPE_IMSI) { - DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n", - req->cm_service_type, gsm48_mi_type_name(mi_type), - mi_string); - } else if (mi_type == GSM_MI_TYPE_TMSI) { - DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n", - req->cm_service_type, gsm48_mi_type_name(mi_type), - mi_string); - } else { - DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type); - return msc_gsm48_tx_mm_serv_rej(conn, - GSM48_REJECT_INCORRECT_MESSAGE); - } - - osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len)); - memcpy(conn->classmark.classmark2, classmark2, classmark2_len); - conn->classmark.classmark2_len = classmark2_len; - - if (conn->conn_fsm) { - if (msc_subscr_conn_is_accepted(conn)) - return cm_serv_reuse_conn(conn, mi-1); - LOGP(DMM, LOGL_ERROR, "%s: connection already in use\n", - vlr_subscr_name(conn->vsub)); - msc_vlr_tx_cm_serv_rej(conn, VLR_PR_ARQ_RES_UNKNOWN_ERROR); - return -EINVAL; - } - - rc = msc_create_conn_fsm(conn, mi_string); - if (rc) { - msc_vlr_tx_cm_serv_rej(conn, VLR_PR_ARQ_RES_UNKNOWN_ERROR); - /* logging already happened in msc_create_conn_fsm() */ - return rc; - } - - is_utran = (conn->via_ran == RAN_UTRAN_IU); - vlr_proc_acc_req(conn->conn_fsm, - SUBSCR_CONN_E_ACCEPTED, - SUBSCR_CONN_E_CN_CLOSE, - (void*)&conn_from_cm_service_req, - net->vlr, conn, - VLR_PR_ARQ_T_CM_SERV_REQ, mi-1, &lai, - is_utran || conn->network->authentication_required, - is_utran? VLR_CIPH_A5_3 - : conn->network->a5_encryption, - classmark_is_r99(&conn->classmark), - is_utran); - - return 0; -} - -static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm_network *network = conn->network; - struct gsm48_hdr *gh = msgb_l3(msg); - struct gsm48_imsi_detach_ind *idi = - (struct gsm48_imsi_detach_ind *) gh->data; - uint8_t mi_type = idi->mi[0] & GSM_MI_TYPE_MASK; - char mi_string[GSM48_MI_SIZE]; - struct vlr_subscr *vsub = NULL; - - gsm48_mi_to_string(mi_string, sizeof(mi_string), idi->mi, idi->mi_len); - DEBUGP(DMM, "IMSI DETACH INDICATION: MI(%s)=%s\n", - gsm48_mi_type_name(mi_type), mi_string); - - rate_ctr_inc(&network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH]); - - switch (mi_type) { - case GSM_MI_TYPE_TMSI: - vsub = vlr_subscr_find_by_tmsi(network->vlr, - tmsi_from_string(mi_string)); - break; - case GSM_MI_TYPE_IMSI: - vsub = vlr_subscr_find_by_imsi(network->vlr, mi_string); - break; - case GSM_MI_TYPE_IMEI: - case GSM_MI_TYPE_IMEISV: - /* no sim card... FIXME: what to do ? */ - LOGP(DMM, LOGL_ERROR, "MI(%s)=%s: unimplemented mobile identity type\n", - gsm48_mi_type_name(mi_type), mi_string); - break; - default: - LOGP(DMM, LOGL_ERROR, "MI(%s)=%s: unknown mobile identity type\n", - gsm48_mi_type_name(mi_type), mi_string); - break; - } - - /* TODO? We used to remember the subscriber's classmark1 here and - * stored it in the old sqlite db, but now we store it in a conn that - * will be discarded anyway: */ - conn->classmark.classmark1 = idi->classmark1; - - if (!vsub) { - LOGP(DMM, LOGL_ERROR, "IMSI DETACH for unknown subscriber MI(%s)=%s\n", - gsm48_mi_type_name(mi_type), mi_string); - } else { - LOGP(DMM, LOGL_INFO, "IMSI DETACH for %s\n", vlr_subscr_name(vsub)); - vlr_subscr_rx_imsi_detach(vsub); - osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_DETACHED, vsub); - vlr_subscr_put(vsub); - } - - msc_subscr_conn_close(conn, 0); - return 0; -} - -static int gsm48_rx_mm_status(struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - - DEBUGP(DMM, "MM STATUS (reject cause 0x%02x)\n", gh->data[0]); - - return 0; -} - -static int parse_gsm_auth_resp(uint8_t *res, uint8_t *res_len, - struct gsm_subscriber_connection *conn, - struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - struct gsm48_auth_resp *ar = (struct gsm48_auth_resp*) gh->data; - - if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*ar)) { - LOGP(DMM, LOGL_ERROR, - "%s: MM AUTHENTICATION RESPONSE:" - " l3 length invalid: %u\n", - vlr_subscr_name(conn->vsub), msgb_l3len(msg)); - return -EINVAL; - } - - *res_len = sizeof(ar->sres); - memcpy(res, ar->sres, sizeof(ar->sres)); - return 0; -} - -static int parse_umts_auth_resp(uint8_t *res, uint8_t *res_len, - struct gsm_subscriber_connection *conn, - struct msgb *msg) -{ - struct gsm48_hdr *gh; - uint8_t *data; - uint8_t iei; - uint8_t ie_len; - unsigned int data_len; - - /* First parse the GSM part */ - if (parse_gsm_auth_resp(res, res_len, conn, msg)) - return -EINVAL; - OSMO_ASSERT(*res_len == 4); - - /* Then add the extended res part */ - gh = msgb_l3(msg); - data = gh->data + sizeof(struct gsm48_auth_resp); - data_len = msgb_l3len(msg) - (data - (uint8_t*)msgb_l3(msg)); - - if (data_len < 3) { - LOGP(DMM, LOGL_ERROR, - "%s: MM AUTHENTICATION RESPONSE:" - " l3 length invalid: %u\n", - vlr_subscr_name(conn->vsub), msgb_l3len(msg)); - return -EINVAL; - } - - iei = data[0]; - ie_len = data[1]; - if (iei != GSM48_IE_AUTH_RES_EXT) { - LOGP(DMM, LOGL_ERROR, - "%s: MM R99 AUTHENTICATION RESPONSE:" - " expected IEI 0x%02x, got 0x%02x\n", - vlr_subscr_name(conn->vsub), - GSM48_IE_AUTH_RES_EXT, iei); - return -EINVAL; - } - - if (ie_len > 12) { - LOGP(DMM, LOGL_ERROR, - "%s: MM R99 AUTHENTICATION RESPONSE:" - " extended Auth Resp IE 0x%02x is too large: %u bytes\n", - vlr_subscr_name(conn->vsub), GSM48_IE_AUTH_RES_EXT, ie_len); - return -EINVAL; - } - - *res_len += ie_len; - memcpy(res + 4, &data[2], ie_len); - return 0; -} - -/* Chapter 9.2.3: Authentication Response */ -static int gsm48_rx_mm_auth_resp(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - uint8_t res[16]; - uint8_t res_len; - int rc; - bool is_r99; - - if (!conn->vsub) { - LOGP(DMM, LOGL_ERROR, - "MM AUTHENTICATION RESPONSE: invalid: no subscriber\n"); - msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED); - return -EINVAL; - } - - if (msgb_l3len(msg) > - sizeof(struct gsm48_hdr) + sizeof(struct gsm48_auth_resp)) { - rc = parse_umts_auth_resp(res, &res_len, conn, msg); - is_r99 = true; - } else { - rc = parse_gsm_auth_resp(res, &res_len, conn, msg); - is_r99 = false; - } - - if (rc) { - msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED); - return -EINVAL; - } - - DEBUGP(DMM, "%s: MM %s AUTHENTICATION RESPONSE (%s = %s)\n", - vlr_subscr_name(conn->vsub), - is_r99 ? "R99" : "GSM", is_r99 ? "res" : "sres", - osmo_hexdump_nospc(res, res_len)); - - return vlr_subscr_rx_auth_resp(conn->vsub, is_r99, - conn->via_ran == RAN_UTRAN_IU, - res, res_len); -} - -static int gsm48_rx_mm_auth_fail(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t cause; - uint8_t auts_tag; - uint8_t auts_len; - uint8_t *auts; - - if (!conn->vsub) { - LOGP(DMM, LOGL_ERROR, - "MM R99 AUTHENTICATION FAILURE: invalid: no subscriber\n"); - msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED); - return -EINVAL; - } - - if (msgb_l3len(msg) < sizeof(*gh) + 1) { - LOGP(DMM, LOGL_ERROR, - "%s: MM R99 AUTHENTICATION FAILURE:" - " l3 length invalid: %u\n", - vlr_subscr_name(conn->vsub), msgb_l3len(msg)); - msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED); - return -EINVAL; - } - - cause = gh->data[0]; - - if (cause != GSM48_REJECT_SYNCH_FAILURE) { - LOGP(DMM, LOGL_INFO, - "%s: MM R99 AUTHENTICATION FAILURE: cause 0x%0x\n", - vlr_subscr_name(conn->vsub), cause); - vlr_subscr_rx_auth_fail(conn->vsub, NULL); - return 0; - } - - /* This is a Synch Failure procedure, which should pass an AUTS to - * resynchronize the sequence nr with the HLR. Expecting exactly one - * TLV with 14 bytes of AUTS. */ - - if (msgb_l3len(msg) < sizeof(*gh) + 1 + 2) { - LOGP(DMM, LOGL_INFO, - "%s: MM R99 AUTHENTICATION FAILURE:" - " invalid Synch Failure: missing AUTS IE\n", - vlr_subscr_name(conn->vsub)); - msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED); - return -EINVAL; - } - - auts_tag = gh->data[1]; - auts_len = gh->data[2]; - auts = &gh->data[3]; - - if (auts_tag != GSM48_IE_AUTS - || auts_len != 14) { - LOGP(DMM, LOGL_INFO, - "%s: MM R99 AUTHENTICATION FAILURE:" - " invalid Synch Failure:" - " expected AUTS IE 0x%02x of 14 bytes," - " got IE 0x%02x of %u bytes\n", - vlr_subscr_name(conn->vsub), - GSM48_IE_AUTS, auts_tag, auts_len); - msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED); - return -EINVAL; - } - - if (msgb_l3len(msg) < sizeof(*gh) + 1 + 2 + auts_len) { - LOGP(DMM, LOGL_INFO, - "%s: MM R99 AUTHENTICATION FAILURE:" - " invalid Synch Failure msg: message truncated (%u)\n", - vlr_subscr_name(conn->vsub), msgb_l3len(msg)); - msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED); - return -EINVAL; - } - - /* We have an AUTS IE with exactly 14 bytes of AUTS and the msgb is - * large enough. */ - - DEBUGP(DMM, "%s: MM R99 AUTHENTICATION SYNCH (AUTS = %s)\n", - vlr_subscr_name(conn->vsub), osmo_hexdump_nospc(auts, 14)); - - return vlr_subscr_rx_auth_fail(conn->vsub, auts); -} - -static int gsm48_rx_mm_tmsi_reall_compl(struct gsm_subscriber_connection *conn) -{ - DEBUGP(DMM, "TMSI Reallocation Completed. Subscriber: %s\n", - vlr_subscr_name(conn->vsub)); - if (!conn->vsub) { - LOGP(DMM, LOGL_ERROR, - "Rx MM TMSI Reallocation Complete: invalid: no subscriber\n"); - return -EINVAL; - } - return vlr_subscr_rx_tmsi_reall_compl(conn->vsub); -} - -/* Receive a GSM 04.08 Mobility Management (MM) message */ -static int gsm0408_rcv_mm(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - int rc = 0; - - switch (gsm48_hdr_msg_type(gh)) { - case GSM48_MT_MM_LOC_UPD_REQUEST: - rc = mm_rx_loc_upd_req(conn, msg); - break; - case GSM48_MT_MM_ID_RESP: - rc = mm_rx_id_resp(conn, msg); - break; - case GSM48_MT_MM_CM_SERV_REQ: - rc = gsm48_rx_mm_serv_req(conn, msg); - break; - case GSM48_MT_MM_STATUS: - rc = gsm48_rx_mm_status(msg); - break; - case GSM48_MT_MM_TMSI_REALL_COMPL: - rc = gsm48_rx_mm_tmsi_reall_compl(conn); - break; - case GSM48_MT_MM_IMSI_DETACH_IND: - rc = gsm48_rx_mm_imsi_detach_ind(conn, msg); - break; - case GSM48_MT_MM_CM_REEST_REQ: - DEBUGP(DMM, "CM REESTABLISH REQUEST: Not implemented\n"); - break; - case GSM48_MT_MM_AUTH_RESP: - rc = gsm48_rx_mm_auth_resp(conn, msg); - break; - case GSM48_MT_MM_AUTH_FAIL: - rc = gsm48_rx_mm_auth_fail(conn, msg); - break; - default: - LOGP(DMM, LOGL_NOTICE, "Unknown GSM 04.08 MM msg type 0x%02x\n", - gh->msg_type); - break; - } - - return rc; -} - -static uint8_t *gsm48_cm2_get_mi(uint8_t *classmark2_lv, unsigned int tot_len) -{ - /* Check the size for the classmark */ - if (tot_len < 1 + *classmark2_lv) - return NULL; - - uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1; - if (tot_len < 2 + *classmark2_lv + mi_lv[0]) - return NULL; - - return mi_lv; -} - -/* Receive a PAGING RESPONSE message from the MS */ -static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - static const enum subscr_conn_from conn_from_paging_resp = - SUBSCR_CONN_FROM_PAGING_RESP; - struct gsm_network *net = conn->network; - struct gsm48_hdr *gh = msgb_l3(msg); - struct gsm48_pag_resp *resp; - uint8_t *classmark2_lv = gh->data + 1; - uint8_t *mi_lv; - uint8_t mi_type; - char mi_string[GSM48_MI_SIZE]; - int rc = 0; - struct osmo_location_area_id lai; - bool is_utran; - - lai.plmn.mcc = conn->network->country_code; - lai.plmn.mnc = conn->network->network_code; - lai.lac = conn->lac; - - resp = (struct gsm48_pag_resp *) &gh->data[0]; - gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*gh), - mi_string, &mi_type); - DEBUGP(DRR, "PAGING RESPONSE: MI(%s)=%s\n", - gsm48_mi_type_name(mi_type), mi_string); - - mi_lv = gsm48_cm2_get_mi(classmark2_lv, msgb_l3len(msg) - sizeof(*gh)); - if (!mi_lv) { - /* FIXME */ - return -1; - } - - rc = msc_create_conn_fsm(conn, mi_string); - if (rc) - /* logging already happened in msc_create_conn_fsm() */ - return rc; - - memcpy(conn->classmark.classmark2, classmark2_lv+1, *classmark2_lv); - conn->classmark.classmark2_len = *classmark2_lv; - - is_utran = (conn->via_ran == RAN_UTRAN_IU); - vlr_proc_acc_req(conn->conn_fsm, - SUBSCR_CONN_E_ACCEPTED, - SUBSCR_CONN_E_CN_CLOSE, - (void*)&conn_from_paging_resp, - net->vlr, conn, - VLR_PR_ARQ_T_PAGING_RESP, mi_lv, &lai, - is_utran || conn->network->authentication_required, - is_utran? VLR_CIPH_A5_3 - : conn->network->a5_encryption, - classmark_is_r99(&conn->classmark), - is_utran); - - return 0; -} - -static int gsm48_rx_rr_app_info(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t apdu_id_flags; - uint8_t apdu_len; - uint8_t *apdu_data; - - apdu_id_flags = gh->data[0]; - apdu_len = gh->data[1]; - apdu_data = gh->data+2; - - DEBUGP(DRR, "RX APPLICATION INFO id/flags=0x%02x apdu_len=%u apdu=%s\n", - apdu_id_flags, apdu_len, osmo_hexdump(apdu_data, apdu_len)); - - /* we're not using the app info blob anywhere, so ignore. */ -#if 0 - return db_apdu_blob_store(conn->subscr, apdu_id_flags, apdu_len, apdu_data); -#else - return 0; -#endif -} - -/* Receive a GSM 04.08 Radio Resource (RR) message */ -static int gsm0408_rcv_rr(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - int rc = 0; - - switch (gh->msg_type) { - case GSM48_MT_RR_PAG_RESP: - rc = gsm48_rx_rr_pag_resp(conn, msg); - break; - case GSM48_MT_RR_APP_INFO: - rc = gsm48_rx_rr_app_info(conn, msg); - break; - default: - LOGP(DRR, LOGL_NOTICE, "MSC: Unimplemented %s GSM 04.08 RR " - "message\n", gsm48_rr_msg_name(gh->msg_type)); - break; - } - - return rc; -} - -int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_id, - uint8_t apdu_len, const uint8_t *apdu) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 APP INF"); - struct gsm48_hdr *gh; - - DEBUGP(DRR, "TX APPLICATION INFO id=0x%02x, len=%u\n", - apdu_id, apdu_len); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 2 + apdu_len); - gh->proto_discr = GSM48_PDISC_RR; - gh->msg_type = GSM48_MT_RR_APP_INFO; - gh->data[0] = apdu_id; - gh->data[1] = apdu_len; - memcpy(gh->data+2, apdu, apdu_len); - - return gsm48_conn_sendmsg(msg, conn, NULL); -} - -/* FIXME: this count_statistics is a state machine behaviour. we should convert - * the complete call control into a state machine. Afterwards we can move this - * code into state transitions. - */ -static void count_statistics(struct gsm_trans *trans, int new_state) -{ - int old_state = trans->cc.state; - struct rate_ctr_group *msc = trans->net->msc_ctrs; - - if (old_state == new_state) - return; - - /* state incoming */ - switch (new_state) { - case GSM_CSTATE_ACTIVE: - osmo_counter_inc(trans->net->active_calls); - rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_ACTIVE]); - break; - } - - /* state outgoing */ - switch (old_state) { - case GSM_CSTATE_ACTIVE: - osmo_counter_dec(trans->net->active_calls); - if (new_state == GSM_CSTATE_DISCONNECT_REQ || - new_state == GSM_CSTATE_DISCONNECT_IND) - rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_COMPLETE]); - else - rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_INCOMPLETE]); - break; - } -} - -/* Call Control */ - -/* The entire call control code is written in accordance with Figure 7.10c - * for 'very early assignment', i.e. we allocate a TCH/F during IMMEDIATE - * ASSIGN, then first use that TCH/F for signalling and later MODE MODIFY - * it for voice */ - -static void new_cc_state(struct gsm_trans *trans, int state) -{ - if (state > 31 || state < 0) - return; - - DEBUGP(DCC, "new state %s -> %s\n", - gsm48_cc_state_name(trans->cc.state), - gsm48_cc_state_name(state)); - - count_statistics(trans, state); - trans->cc.state = state; -} - -static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC STATUS"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - uint8_t *cause, *call_state; - - gh->msg_type = GSM48_MT_CC_STATUS; - - cause = msgb_put(msg, 3); - cause[0] = 2; - cause[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_USER; - cause[2] = 0x80 | 30; /* response to status inquiry */ - - call_state = msgb_put(msg, 1); - call_state[0] = 0xc0 | 0x00; - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_tx_simple(struct gsm_subscriber_connection *conn, - uint8_t pdisc, uint8_t msg_type) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 TX SIMPLE"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->proto_discr = pdisc; - gh->msg_type = msg_type; - - return gsm48_conn_sendmsg(msg, conn, NULL); -} - -static void gsm48_stop_cc_timer(struct gsm_trans *trans) -{ - if (osmo_timer_pending(&trans->cc.timer)) { - DEBUGP(DCC, "stopping pending timer T%x\n", trans->cc.Tcurrent); - osmo_timer_del(&trans->cc.timer); - trans->cc.Tcurrent = 0; - } -} - -static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans, - int msg_type, struct gsm_mncc *mncc) -{ - struct msgb *msg; - unsigned char *data; - - DEBUGP(DMNCC, "transmit message %s\n", get_mncc_name(msg_type)); - -#if BEFORE_MSCSPLIT - /* Re-enable this log output once we can obtain this information via - * A-interface, see OS#2391. */ - if (trans) - if (trans->conn && trans->conn->lchan) - DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) " - "Sending '%s' to MNCC.\n", - trans->conn->lchan->ts->trx->bts->nr, - trans->conn->lchan->ts->trx->nr, - trans->conn->lchan->ts->nr, trans->transaction_id, - vlr_subscr_msisdn_or_name(trans->vsub), - get_mncc_name(msg_type)); - else - DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) " - "Sending '%s' to MNCC.\n", - vlr_subscr_msisdn_or_name(trans->vsub), - get_mncc_name(msg_type)); - else - DEBUGP(DCC, "(bts - trx - ts - ti -- sub -) " - "Sending '%s' to MNCC.\n", get_mncc_name(msg_type)); -#else - DEBUGP(DCC, "Sending '%s' to MNCC.\n", get_mncc_name(msg_type)); -#endif - - mncc->msg_type = msg_type; - - msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC"); - if (!msg) - return -ENOMEM; - - data = msgb_put(msg, sizeof(struct gsm_mncc)); - memcpy(data, mncc, sizeof(struct gsm_mncc)); - - cc_tx_to_mncc(net, msg); - - return 0; -} - -int mncc_release_ind(struct gsm_network *net, struct gsm_trans *trans, - uint32_t callref, int location, int value) -{ - struct gsm_mncc rel; - - memset(&rel, 0, sizeof(rel)); - rel.callref = callref; - mncc_set_cause(&rel, location, value); - if (trans && trans->cc.state == GSM_CSTATE_RELEASE_REQ) - return mncc_recvmsg(net, trans, MNCC_REL_CNF, &rel); - return mncc_recvmsg(net, trans, MNCC_REL_IND, &rel); -} - -/* Call Control Specific transaction release. - * gets called by trans_free, DO NOT CALL YOURSELF! */ -void _gsm48_cc_trans_free(struct gsm_trans *trans) -{ - gsm48_stop_cc_timer(trans); - - /* Make sure call also gets released on the mgcp side */ - msc_call_release(trans); - - /* send release to L4, if callref still exists */ - if (trans->callref) { - /* Ressource unavailable */ - mncc_release_ind(trans->net, trans, trans->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_RESOURCE_UNAVAIL); - } - if (trans->cc.state != GSM_CSTATE_NULL) - new_cc_state(trans, GSM_CSTATE_NULL); -} - -static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg); - -/* call-back from paging the B-end of the connection */ -static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event, - struct msgb *msg, void *_conn, void *_transt) -{ - struct gsm_subscriber_connection *conn = _conn; - struct gsm_trans *transt = _transt; - - OSMO_ASSERT(!transt->conn); - - switch (event) { - case GSM_PAGING_SUCCEEDED: - DEBUGP(DCC, "Paging subscr %s succeeded!\n", - vlr_subscr_msisdn_or_name(transt->vsub)); - OSMO_ASSERT(conn); - /* Assign conn */ - transt->conn = conn; - /* send SETUP request to called party */ - gsm48_cc_tx_setup(transt, &transt->cc.msg); - break; - case GSM_PAGING_EXPIRED: - case GSM_PAGING_BUSY: - DEBUGP(DCC, "Paging subscr %s expired!\n", - vlr_subscr_msisdn_or_name(transt->vsub)); - /* Temporarily out of order */ - mncc_release_ind(transt->net, transt, - transt->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_DEST_OOO); - transt->callref = 0; - transt->paging_request = NULL; - trans_free(transt); - break; - default: - LOGP(DCC, LOGL_ERROR, "Unknown paging event %d\n", event); - break; - } - - transt->paging_request = NULL; - return 0; -} - -/* bridge channels of two transactions */ -static int tch_bridge(struct gsm_network *net, struct gsm_mncc_bridge *bridge) -{ - struct gsm_trans *trans1 = trans_find_by_callref(net, bridge->callref[0]); - struct gsm_trans *trans2 = trans_find_by_callref(net, bridge->callref[1]); - - if (!trans1 || !trans2) - return -EIO; - - if (!trans1->conn || !trans2->conn) - return -EIO; - - /* Which subscriber do we want to track trans1 or trans2? */ - log_set_context(LOG_CTX_VLR_SUBSCR, trans1->vsub); - - return msc_call_bridge(trans1, trans2); -} - -static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg) -{ - DEBUGP(DCC, "-> STATUS ENQ\n"); - return gsm48_cc_tx_status(trans, msg); -} - -static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg); -static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg); - -static void gsm48_cc_timeout(void *arg) -{ - struct gsm_trans *trans = arg; - int disconnect = 0, release = 0; - int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER; - int mo_location = GSM48_CAUSE_LOC_USER; - int l4_cause = GSM48_CC_CAUSE_NORMAL_UNSPEC; - int l4_location = GSM48_CAUSE_LOC_PRN_S_LU; - struct gsm_mncc mo_rel, l4_rel; - - memset(&mo_rel, 0, sizeof(struct gsm_mncc)); - mo_rel.callref = trans->callref; - memset(&l4_rel, 0, sizeof(struct gsm_mncc)); - l4_rel.callref = trans->callref; - - switch(trans->cc.Tcurrent) { - case 0x303: - release = 1; - l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND; - break; - case 0x310: - disconnect = 1; - l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND; - break; - case 0x313: - disconnect = 1; - /* unknown, did not find it in the specs */ - break; - case 0x301: - disconnect = 1; - l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND; - break; - case 0x308: - if (!trans->cc.T308_second) { - /* restart T308 a second time */ - gsm48_cc_tx_release(trans, &trans->cc.msg); - trans->cc.T308_second = 1; - break; /* stay in release state */ - } - trans_free(trans); - return; -// release = 1; -// l4_cause = 14; -// break; - case 0x306: - release = 1; - mo_cause = trans->cc.msg.cause.value; - mo_location = trans->cc.msg.cause.location; - break; - case 0x323: - disconnect = 1; - break; - default: - release = 1; - } - - if (release && trans->callref) { - /* process release towards layer 4 */ - mncc_release_ind(trans->net, trans, trans->callref, - l4_location, l4_cause); - trans->callref = 0; - } - - if (disconnect && trans->callref) { - /* process disconnect towards layer 4 */ - mncc_set_cause(&l4_rel, l4_location, l4_cause); - mncc_recvmsg(trans->net, trans, MNCC_DISC_IND, &l4_rel); - } - - /* process disconnect towards mobile station */ - if (disconnect || release) { - mncc_set_cause(&mo_rel, mo_location, mo_cause); - mo_rel.cause.diag[0] = ((trans->cc.Tcurrent & 0xf00) >> 8) + '0'; - mo_rel.cause.diag[1] = ((trans->cc.Tcurrent & 0x0f0) >> 4) + '0'; - mo_rel.cause.diag[2] = (trans->cc.Tcurrent & 0x00f) + '0'; - mo_rel.cause.diag_len = 3; - - if (disconnect) - gsm48_cc_tx_disconnect(trans, &mo_rel); - if (release) - gsm48_cc_tx_release(trans, &mo_rel); - } - -} - -/* disconnect both calls from the bridge */ -static inline void disconnect_bridge(struct gsm_network *net, - struct gsm_mncc_bridge *bridge, int err) -{ - struct gsm_trans *trans0 = trans_find_by_callref(net, bridge->callref[0]); - struct gsm_trans *trans1 = trans_find_by_callref(net, bridge->callref[1]); - struct gsm_mncc mx_rel; - if (!trans0 || !trans1) - return; - - DEBUGP(DCC, "Failed to bridge TCH for calls %x <-> %x :: %s \n", - trans0->callref, trans1->callref, strerror(err)); - - memset(&mx_rel, 0, sizeof(struct gsm_mncc)); - mncc_set_cause(&mx_rel, GSM48_CAUSE_LOC_INN_NET, - GSM48_CC_CAUSE_CHAN_UNACCEPT); - - mx_rel.callref = trans0->callref; - gsm48_cc_tx_disconnect(trans0, &mx_rel); - - mx_rel.callref = trans1->callref; - gsm48_cc_tx_disconnect(trans1, &mx_rel); -} - -static void gsm48_start_cc_timer(struct gsm_trans *trans, int current, - int sec, int micro) -{ - DEBUGP(DCC, "starting timer T%x with %d seconds\n", current, sec); - osmo_timer_setup(&trans->cc.timer, gsm48_cc_timeout, trans); - osmo_timer_schedule(&trans->cc.timer, sec, micro); - trans->cc.Tcurrent = current; -} - -static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t msg_type = gsm48_hdr_msg_type(gh); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc setup; - - memset(&setup, 0, sizeof(struct gsm_mncc)); - setup.callref = trans->callref; - - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); - /* emergency setup is identified by msg_type */ - if (msg_type == GSM48_MT_CC_EMERG_SETUP) - setup.emergency = 1; - - /* use subscriber as calling party number */ - setup.fields |= MNCC_F_CALLING; - osmo_strlcpy(setup.calling.number, trans->vsub->msisdn, sizeof(setup.calling.number)); - osmo_strlcpy(setup.imsi, trans->vsub->imsi, sizeof(setup.imsi)); - - /* bearer capability */ - if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) { - setup.fields |= MNCC_F_BEARER_CAP; - gsm48_decode_bearer_cap(&setup.bearer_cap, - TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1); - - /* Create a copy of the bearer capability - * in the transaction struct, so we can use - * this information later */ - memcpy(&trans->bearer_cap,&setup.bearer_cap, - sizeof(trans->bearer_cap)); - } - /* facility */ - if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { - setup.fields |= MNCC_F_FACILITY; - gsm48_decode_facility(&setup.facility, - TLVP_VAL(&tp, GSM48_IE_FACILITY)-1); - } - /* called party bcd number */ - if (TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD)) { - setup.fields |= MNCC_F_CALLED; - gsm48_decode_called(&setup.called, - TLVP_VAL(&tp, GSM48_IE_CALLED_BCD)-1); - } - /* user-user */ - if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) { - setup.fields |= MNCC_F_USERUSER; - gsm48_decode_useruser(&setup.useruser, - TLVP_VAL(&tp, GSM48_IE_USER_USER)-1); - } - /* ss-version */ - if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) { - setup.fields |= MNCC_F_SSVERSION; - gsm48_decode_ssversion(&setup.ssversion, - TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); - } - /* CLIR suppression */ - if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_SUPP)) - setup.clir.sup = 1; - /* CLIR invocation */ - if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_INVOC)) - setup.clir.inv = 1; - /* cc cap */ - if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) { - setup.fields |= MNCC_F_CCCAP; - gsm48_decode_cccap(&setup.cccap, - TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1); - } - - new_cc_state(trans, GSM_CSTATE_INITIATED); - - LOGP(DCC, LOGL_INFO, "Subscriber %s (%s) sends SETUP to %s\n", - vlr_subscr_name(trans->vsub), trans->vsub->msisdn, - setup.called.number); - - rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP]); - - /* indicate setup to MNCC */ - mncc_recvmsg(trans->net, trans, MNCC_SETUP_IND, &setup); - - /* MNCC code will modify the channel asynchronously, we should - * ipaccess-bind only after the modification has been made to the - * lchan->tch_mode */ - return 0; -} - -static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC STUP"); - struct gsm48_hdr *gh; - struct gsm_mncc *setup = arg; - int rc, trans_id; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - /* transaction id must not be assigned */ - if (trans->transaction_id != 0xff) { /* unasssigned */ - DEBUGP(DCC, "TX Setup with assigned transaction. " - "This is not allowed!\n"); - /* Temporarily out of order */ - rc = mncc_release_ind(trans->net, trans, trans->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_RESOURCE_UNAVAIL); - trans->callref = 0; - trans_free(trans); - return rc; - } - - /* Get free transaction_id */ - trans_id = trans_assign_trans_id(trans->net, trans->vsub, - GSM48_PDISC_CC, 0); - if (trans_id < 0) { - /* no free transaction ID */ - rc = mncc_release_ind(trans->net, trans, trans->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_RESOURCE_UNAVAIL); - trans->callref = 0; - trans_free(trans); - return rc; - } - trans->transaction_id = trans_id; - - gh->msg_type = GSM48_MT_CC_SETUP; - - gsm48_start_cc_timer(trans, 0x303, GSM48_T303); - - /* bearer capability */ - if (setup->fields & MNCC_F_BEARER_CAP) - gsm48_encode_bearer_cap(msg, 0, &setup->bearer_cap); - /* facility */ - if (setup->fields & MNCC_F_FACILITY) - gsm48_encode_facility(msg, 0, &setup->facility); - /* progress */ - if (setup->fields & MNCC_F_PROGRESS) - gsm48_encode_progress(msg, 0, &setup->progress); - /* calling party BCD number */ - if (setup->fields & MNCC_F_CALLING) - gsm48_encode_calling(msg, &setup->calling); - /* called party BCD number */ - if (setup->fields & MNCC_F_CALLED) - gsm48_encode_called(msg, &setup->called); - /* user-user */ - if (setup->fields & MNCC_F_USERUSER) - gsm48_encode_useruser(msg, 0, &setup->useruser); - /* redirecting party BCD number */ - if (setup->fields & MNCC_F_REDIRECTING) - gsm48_encode_redirecting(msg, &setup->redirecting); - /* signal */ - if (setup->fields & MNCC_F_SIGNAL) - gsm48_encode_signal(msg, setup->signal); - - new_cc_state(trans, GSM_CSTATE_CALL_PRESENT); - - rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP]); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc call_conf; - int rc; - - gsm48_stop_cc_timer(trans); - gsm48_start_cc_timer(trans, 0x310, GSM48_T310); - - memset(&call_conf, 0, sizeof(struct gsm_mncc)); - call_conf.callref = trans->callref; - - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); -#if 0 - /* repeat */ - if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_CIR)) - call_conf.repeat = 1; - if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_SEQ)) - call_conf.repeat = 2; -#endif - /* bearer capability */ - if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) { - call_conf.fields |= MNCC_F_BEARER_CAP; - gsm48_decode_bearer_cap(&call_conf.bearer_cap, - TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1); - - /* Create a copy of the bearer capability - * in the transaction struct, so we can use - * this information later */ - memcpy(&trans->bearer_cap,&call_conf.bearer_cap, - sizeof(trans->bearer_cap)); - } - /* cause */ - if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { - call_conf.fields |= MNCC_F_CAUSE; - gsm48_decode_cause(&call_conf.cause, - TLVP_VAL(&tp, GSM48_IE_CAUSE)-1); - } - /* cc cap */ - if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) { - call_conf.fields |= MNCC_F_CCCAP; - gsm48_decode_cccap(&call_conf.cccap, - TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1); - } - - /* IMSI of called subscriber */ - osmo_strlcpy(call_conf.imsi, trans->vsub->imsi, sizeof(call_conf.imsi)); - - new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF); - - /* Assign call (if not done yet) */ - if (trans->assignment_done == false) { - rc = msc_call_assignment(trans); - trans->assignment_done = true; - } - else - rc = 0; - - /* don't continue, if there were problems with - * the call assignment. */ - if (rc) - return rc; - - return mncc_recvmsg(trans->net, trans, MNCC_CALL_CONF_IND, - &call_conf); -} - -static int gsm48_cc_tx_call_proc_and_assign(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *proceeding = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC PROC"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - int rc; - - gh->msg_type = GSM48_MT_CC_CALL_PROC; - - new_cc_state(trans, GSM_CSTATE_MO_CALL_PROC); - - /* bearer capability */ - if (proceeding->fields & MNCC_F_BEARER_CAP) - gsm48_encode_bearer_cap(msg, 0, &proceeding->bearer_cap); - /* facility */ - if (proceeding->fields & MNCC_F_FACILITY) - gsm48_encode_facility(msg, 0, &proceeding->facility); - /* progress */ - if (proceeding->fields & MNCC_F_PROGRESS) - gsm48_encode_progress(msg, 0, &proceeding->progress); - - rc = gsm48_conn_sendmsg(msg, trans->conn, trans); - if (rc) - return rc; - - /* Assign call (if not done yet) */ - if (trans->assignment_done == false) { - rc = msc_call_assignment(trans); - trans->assignment_done = true; - } - else - rc = 0; - - return rc; -} - -static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc alerting; - - gsm48_stop_cc_timer(trans); - gsm48_start_cc_timer(trans, 0x301, GSM48_T301); - - memset(&alerting, 0, sizeof(struct gsm_mncc)); - alerting.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); - /* facility */ - if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { - alerting.fields |= MNCC_F_FACILITY; - gsm48_decode_facility(&alerting.facility, - TLVP_VAL(&tp, GSM48_IE_FACILITY)-1); - } - - /* progress */ - if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) { - alerting.fields |= MNCC_F_PROGRESS; - gsm48_decode_progress(&alerting.progress, - TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1); - } - /* ss-version */ - if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) { - alerting.fields |= MNCC_F_SSVERSION; - gsm48_decode_ssversion(&alerting.ssversion, - TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); - } - - new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED); - - return mncc_recvmsg(trans->net, trans, MNCC_ALERT_IND, - &alerting); -} - -static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *alerting = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC ALERT"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_ALERTING; - - /* facility */ - if (alerting->fields & MNCC_F_FACILITY) - gsm48_encode_facility(msg, 0, &alerting->facility); - /* progress */ - if (alerting->fields & MNCC_F_PROGRESS) - gsm48_encode_progress(msg, 0, &alerting->progress); - /* user-user */ - if (alerting->fields & MNCC_F_USERUSER) - gsm48_encode_useruser(msg, 0, &alerting->useruser); - - new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *progress = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC PROGRESS"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_PROGRESS; - - /* progress */ - gsm48_encode_progress(msg, 1, &progress->progress); - /* user-user */ - if (progress->fields & MNCC_F_USERUSER) - gsm48_encode_useruser(msg, 0, &progress->useruser); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *connect = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSN 04.08 CC CON"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_CONNECT; - - gsm48_stop_cc_timer(trans); - gsm48_start_cc_timer(trans, 0x313, GSM48_T313); - - /* facility */ - if (connect->fields & MNCC_F_FACILITY) - gsm48_encode_facility(msg, 0, &connect->facility); - /* progress */ - if (connect->fields & MNCC_F_PROGRESS) - gsm48_encode_progress(msg, 0, &connect->progress); - /* connected number */ - if (connect->fields & MNCC_F_CONNECTED) - gsm48_encode_connected(msg, &connect->connected); - /* user-user */ - if (connect->fields & MNCC_F_USERUSER) - gsm48_encode_useruser(msg, 0, &connect->useruser); - - new_cc_state(trans, GSM_CSTATE_CONNECT_IND); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc connect; - - gsm48_stop_cc_timer(trans); - - memset(&connect, 0, sizeof(struct gsm_mncc)); - connect.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); - /* use subscriber as connected party number */ - connect.fields |= MNCC_F_CONNECTED; - osmo_strlcpy(connect.connected.number, trans->vsub->msisdn, sizeof(connect.connected.number)); - osmo_strlcpy(connect.imsi, trans->vsub->imsi, sizeof(connect.imsi)); - - /* facility */ - if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { - connect.fields |= MNCC_F_FACILITY; - gsm48_decode_facility(&connect.facility, - TLVP_VAL(&tp, GSM48_IE_FACILITY)-1); - } - /* user-user */ - if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) { - connect.fields |= MNCC_F_USERUSER; - gsm48_decode_useruser(&connect.useruser, - TLVP_VAL(&tp, GSM48_IE_USER_USER)-1); - } - /* ss-version */ - if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) { - connect.fields |= MNCC_F_SSVERSION; - gsm48_decode_ssversion(&connect.ssversion, - TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); - } - - new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST); - rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT]); - - return mncc_recvmsg(trans->net, trans, MNCC_SETUP_CNF, &connect); -} - - -static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm_mncc connect_ack; - - gsm48_stop_cc_timer(trans); - - new_cc_state(trans, GSM_CSTATE_ACTIVE); - rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK]); - - memset(&connect_ack, 0, sizeof(struct gsm_mncc)); - connect_ack.callref = trans->callref; - - return mncc_recvmsg(trans->net, trans, MNCC_SETUP_COMPL_IND, - &connect_ack); -} - -static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC CON ACK"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_CONNECT_ACK; - - new_cc_state(trans, GSM_CSTATE_ACTIVE); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc disc; - - gsm48_stop_cc_timer(trans); - - new_cc_state(trans, GSM_CSTATE_DISCONNECT_REQ); - - memset(&disc, 0, sizeof(struct gsm_mncc)); - disc.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_CAUSE, 0); - /* cause */ - if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { - disc.fields |= MNCC_F_CAUSE; - gsm48_decode_cause(&disc.cause, - TLVP_VAL(&tp, GSM48_IE_CAUSE)-1); - } - /* facility */ - if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { - disc.fields |= MNCC_F_FACILITY; - gsm48_decode_facility(&disc.facility, - TLVP_VAL(&tp, GSM48_IE_FACILITY)-1); - } - /* user-user */ - if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) { - disc.fields |= MNCC_F_USERUSER; - gsm48_decode_useruser(&disc.useruser, - TLVP_VAL(&tp, GSM48_IE_USER_USER)-1); - } - /* ss-version */ - if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) { - disc.fields |= MNCC_F_SSVERSION; - gsm48_decode_ssversion(&disc.ssversion, - TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); - } - - return mncc_recvmsg(trans->net, trans, MNCC_DISC_IND, &disc); - -} - -static struct gsm_mncc_cause default_cause = { - .location = GSM48_CAUSE_LOC_PRN_S_LU, - .coding = 0, - .rec = 0, - .rec_val = 0, - .value = GSM48_CC_CAUSE_NORMAL_UNSPEC, - .diag_len = 0, - .diag = { 0 }, -}; - -static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *disc = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC DISC"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_DISCONNECT; - - gsm48_stop_cc_timer(trans); - gsm48_start_cc_timer(trans, 0x306, GSM48_T306); - - /* cause */ - if (disc->fields & MNCC_F_CAUSE) - gsm48_encode_cause(msg, 1, &disc->cause); - else - gsm48_encode_cause(msg, 1, &default_cause); - - /* facility */ - if (disc->fields & MNCC_F_FACILITY) - gsm48_encode_facility(msg, 0, &disc->facility); - /* progress */ - if (disc->fields & MNCC_F_PROGRESS) - gsm48_encode_progress(msg, 0, &disc->progress); - /* user-user */ - if (disc->fields & MNCC_F_USERUSER) - gsm48_encode_useruser(msg, 0, &disc->useruser); - - /* store disconnect cause for T306 expiry */ - memcpy(&trans->cc.msg, disc, sizeof(struct gsm_mncc)); - - new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc rel; - int rc; - - gsm48_stop_cc_timer(trans); - - memset(&rel, 0, sizeof(struct gsm_mncc)); - rel.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); - /* cause */ - if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { - rel.fields |= MNCC_F_CAUSE; - gsm48_decode_cause(&rel.cause, - TLVP_VAL(&tp, GSM48_IE_CAUSE)-1); - } - /* facility */ - if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { - rel.fields |= MNCC_F_FACILITY; - gsm48_decode_facility(&rel.facility, - TLVP_VAL(&tp, GSM48_IE_FACILITY)-1); - } - /* user-user */ - if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) { - rel.fields |= MNCC_F_USERUSER; - gsm48_decode_useruser(&rel.useruser, - TLVP_VAL(&tp, GSM48_IE_USER_USER)-1); - } - /* ss-version */ - if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) { - rel.fields |= MNCC_F_SSVERSION; - gsm48_decode_ssversion(&rel.ssversion, - TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); - } - - if (trans->cc.state == GSM_CSTATE_RELEASE_REQ) { - /* release collision 5.4.5 */ - rc = mncc_recvmsg(trans->net, trans, MNCC_REL_CNF, &rel); - } else { - rc = gsm48_tx_simple(trans->conn, - GSM48_PDISC_CC | (trans->transaction_id << 4), - GSM48_MT_CC_RELEASE_COMPL); - rc = mncc_recvmsg(trans->net, trans, MNCC_REL_IND, &rel); - } - - new_cc_state(trans, GSM_CSTATE_NULL); - - trans->callref = 0; - trans_free(trans); - - return rc; -} - -static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *rel = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_RELEASE; - - gsm48_stop_cc_timer(trans); - gsm48_start_cc_timer(trans, 0x308, GSM48_T308); - - /* cause */ - if (rel->fields & MNCC_F_CAUSE) - gsm48_encode_cause(msg, 0, &rel->cause); - /* facility */ - if (rel->fields & MNCC_F_FACILITY) - gsm48_encode_facility(msg, 0, &rel->facility); - /* user-user */ - if (rel->fields & MNCC_F_USERUSER) - gsm48_encode_useruser(msg, 0, &rel->useruser); - - trans->cc.T308_second = 0; - memcpy(&trans->cc.msg, rel, sizeof(struct gsm_mncc)); - - if (trans->cc.state != GSM_CSTATE_RELEASE_REQ) - new_cc_state(trans, GSM_CSTATE_RELEASE_REQ); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc rel; - int rc = 0; - - gsm48_stop_cc_timer(trans); - - memset(&rel, 0, sizeof(struct gsm_mncc)); - rel.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); - /* cause */ - if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { - rel.fields |= MNCC_F_CAUSE; - gsm48_decode_cause(&rel.cause, - TLVP_VAL(&tp, GSM48_IE_CAUSE)-1); - } - /* facility */ - if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { - rel.fields |= MNCC_F_FACILITY; - gsm48_decode_facility(&rel.facility, - TLVP_VAL(&tp, GSM48_IE_FACILITY)-1); - } - /* user-user */ - if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) { - rel.fields |= MNCC_F_USERUSER; - gsm48_decode_useruser(&rel.useruser, - TLVP_VAL(&tp, GSM48_IE_USER_USER)-1); - } - /* ss-version */ - if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) { - rel.fields |= MNCC_F_SSVERSION; - gsm48_decode_ssversion(&rel.ssversion, - TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); - } - - if (trans->callref) { - switch (trans->cc.state) { - case GSM_CSTATE_CALL_PRESENT: - rc = mncc_recvmsg(trans->net, trans, - MNCC_REJ_IND, &rel); - break; - case GSM_CSTATE_RELEASE_REQ: - rc = mncc_recvmsg(trans->net, trans, - MNCC_REL_CNF, &rel); - break; - default: - rc = mncc_recvmsg(trans->net, trans, - MNCC_REL_IND, &rel); - } - } - - trans->callref = 0; - trans_free(trans); - - return rc; -} - -static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *rel = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL COMPL"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - int ret; - - gh->msg_type = GSM48_MT_CC_RELEASE_COMPL; - - trans->callref = 0; - - gsm48_stop_cc_timer(trans); - - /* cause */ - if (rel->fields & MNCC_F_CAUSE) - gsm48_encode_cause(msg, 0, &rel->cause); - /* facility */ - if (rel->fields & MNCC_F_FACILITY) - gsm48_encode_facility(msg, 0, &rel->facility); - /* user-user */ - if (rel->fields & MNCC_F_USERUSER) - gsm48_encode_useruser(msg, 0, &rel->useruser); - - ret = gsm48_conn_sendmsg(msg, trans->conn, trans); - - trans_free(trans); - - return ret; -} - -static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc fac; - - memset(&fac, 0, sizeof(struct gsm_mncc)); - fac.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_FACILITY, 0); - /* facility */ - if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { - fac.fields |= MNCC_F_FACILITY; - gsm48_decode_facility(&fac.facility, - TLVP_VAL(&tp, GSM48_IE_FACILITY)-1); - } - /* ss-version */ - if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) { - fac.fields |= MNCC_F_SSVERSION; - gsm48_decode_ssversion(&fac.ssversion, - TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); - } - - return mncc_recvmsg(trans->net, trans, MNCC_FACILITY_IND, &fac); -} - -static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *fac = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC FAC"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_FACILITY; - - /* facility */ - gsm48_encode_facility(msg, 1, &fac->facility); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_hold(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm_mncc hold; - - memset(&hold, 0, sizeof(struct gsm_mncc)); - hold.callref = trans->callref; - return mncc_recvmsg(trans->net, trans, MNCC_HOLD_IND, &hold); -} - -static int gsm48_cc_tx_hold_ack(struct gsm_trans *trans, void *arg) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC HLD ACK"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_HOLD_ACK; - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_tx_hold_rej(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *hold_rej = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC HLD REJ"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_HOLD_REJ; - - /* cause */ - if (hold_rej->fields & MNCC_F_CAUSE) - gsm48_encode_cause(msg, 1, &hold_rej->cause); - else - gsm48_encode_cause(msg, 1, &default_cause); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_retrieve(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm_mncc retrieve; - - memset(&retrieve, 0, sizeof(struct gsm_mncc)); - retrieve.callref = trans->callref; - return mncc_recvmsg(trans->net, trans, MNCC_RETRIEVE_IND, - &retrieve); -} - -static int gsm48_cc_tx_retrieve_ack(struct gsm_trans *trans, void *arg) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC RETR ACK"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_RETR_ACK; - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_tx_retrieve_rej(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *retrieve_rej = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC RETR REJ"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_RETR_REJ; - - /* cause */ - if (retrieve_rej->fields & MNCC_F_CAUSE) - gsm48_encode_cause(msg, 1, &retrieve_rej->cause); - else - gsm48_encode_cause(msg, 1, &default_cause); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_start_dtmf(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc dtmf; - - memset(&dtmf, 0, sizeof(struct gsm_mncc)); - dtmf.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); - /* keypad facility */ - if (TLVP_PRESENT(&tp, GSM48_IE_KPD_FACILITY)) { - dtmf.fields |= MNCC_F_KEYPAD; - gsm48_decode_keypad(&dtmf.keypad, - TLVP_VAL(&tp, GSM48_IE_KPD_FACILITY)-1); - } - - return mncc_recvmsg(trans->net, trans, MNCC_START_DTMF_IND, &dtmf); -} - -static int gsm48_cc_tx_start_dtmf_ack(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *dtmf = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF ACK"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_START_DTMF_ACK; - - /* keypad */ - if (dtmf->fields & MNCC_F_KEYPAD) - gsm48_encode_keypad(msg, dtmf->keypad); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *dtmf = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF REJ"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_START_DTMF_REJ; - - /* cause */ - if (dtmf->fields & MNCC_F_CAUSE) - gsm48_encode_cause(msg, 1, &dtmf->cause); - else - gsm48_encode_cause(msg, 1, &default_cause); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_tx_stop_dtmf_ack(struct gsm_trans *trans, void *arg) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF STP ACK"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_STOP_DTMF_ACK; - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_stop_dtmf(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm_mncc dtmf; - - memset(&dtmf, 0, sizeof(struct gsm_mncc)); - dtmf.callref = trans->callref; - - return mncc_recvmsg(trans->net, trans, MNCC_STOP_DTMF_IND, &dtmf); -} - -static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc modify; - - memset(&modify, 0, sizeof(struct gsm_mncc)); - modify.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0); - /* bearer capability */ - if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) { - modify.fields |= MNCC_F_BEARER_CAP; - gsm48_decode_bearer_cap(&modify.bearer_cap, - TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1); - - /* Create a copy of the bearer capability - * in the transaction struct, so we can use - * this information later */ - memcpy(&trans->bearer_cap,&modify.bearer_cap, - sizeof(trans->bearer_cap)); - } - - new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY); - - return mncc_recvmsg(trans->net, trans, MNCC_MODIFY_IND, &modify); -} - -static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *modify = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_MODIFY; - - gsm48_start_cc_timer(trans, 0x323, GSM48_T323); - - /* bearer capability */ - gsm48_encode_bearer_cap(msg, 1, &modify->bearer_cap); - - new_cc_state(trans, GSM_CSTATE_MO_TERM_MODIFY); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc modify; - - gsm48_stop_cc_timer(trans); - - memset(&modify, 0, sizeof(struct gsm_mncc)); - modify.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0); - /* bearer capability */ - if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) { - modify.fields |= MNCC_F_BEARER_CAP; - gsm48_decode_bearer_cap(&modify.bearer_cap, - TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1); - - /* Create a copy of the bearer capability - * in the transaction struct, so we can use - * this information later */ - memcpy(&trans->bearer_cap,&modify.bearer_cap, - sizeof(trans->bearer_cap)); - } - - new_cc_state(trans, GSM_CSTATE_ACTIVE); - - return mncc_recvmsg(trans->net, trans, MNCC_MODIFY_CNF, &modify); -} - -static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *modify = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD COMPL"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_MODIFY_COMPL; - - /* bearer capability */ - gsm48_encode_bearer_cap(msg, 1, &modify->bearer_cap); - - new_cc_state(trans, GSM_CSTATE_ACTIVE); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc modify; - - gsm48_stop_cc_timer(trans); - - memset(&modify, 0, sizeof(struct gsm_mncc)); - modify.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, GSM48_IE_CAUSE); - /* bearer capability */ - if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) { - modify.fields |= GSM48_IE_BEARER_CAP; - gsm48_decode_bearer_cap(&modify.bearer_cap, - TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1); - - /* Create a copy of the bearer capability - * in the transaction struct, so we can use - * this information later */ - memcpy(&trans->bearer_cap,&modify.bearer_cap, - sizeof(trans->bearer_cap)); - } - /* cause */ - if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { - modify.fields |= MNCC_F_CAUSE; - gsm48_decode_cause(&modify.cause, - TLVP_VAL(&tp, GSM48_IE_CAUSE)-1); - } - - new_cc_state(trans, GSM_CSTATE_ACTIVE); - - return mncc_recvmsg(trans->net, trans, MNCC_MODIFY_REJ, &modify); -} - -static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *modify = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD REJ"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_MODIFY_REJECT; - - /* bearer capability */ - gsm48_encode_bearer_cap(msg, 1, &modify->bearer_cap); - /* cause */ - gsm48_encode_cause(msg, 1, &modify->cause); - - new_cc_state(trans, GSM_CSTATE_ACTIVE); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *notify = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC NOT"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_NOTIFY; - - /* notify */ - gsm48_encode_notify(msg, notify->notify); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); -// struct tlv_parsed tp; - struct gsm_mncc notify; - - memset(¬ify, 0, sizeof(struct gsm_mncc)); - notify.callref = trans->callref; -// tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len); - if (payload_len >= 1) - gsm48_decode_notify(¬ify.notify, gh->data); - - return mncc_recvmsg(trans->net, trans, MNCC_NOTIFY_IND, ¬ify); -} - -static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *user = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USR INFO"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - - gh->msg_type = GSM48_MT_CC_USER_INFO; - - /* user-user */ - if (user->fields & MNCC_F_USERUSER) - gsm48_encode_useruser(msg, 1, &user->useruser); - /* more data */ - if (user->more) - gsm48_encode_more(msg); - - return gsm48_conn_sendmsg(msg, trans->conn, trans); -} - -static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - struct gsm_mncc user; - - memset(&user, 0, sizeof(struct gsm_mncc)); - user.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_USER_USER, 0); - /* user-user */ - if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) { - user.fields |= MNCC_F_USERUSER; - gsm48_decode_useruser(&user.useruser, - TLVP_VAL(&tp, GSM48_IE_USER_USER)-1); - } - /* more data */ - if (TLVP_PRESENT(&tp, GSM48_IE_MORE_DATA)) - user.more = 1; - - return mncc_recvmsg(trans->net, trans, MNCC_USERINFO_IND, &user); -} - -static void mncc_recv_rtp(struct gsm_network *net, uint32_t callref, - int cmd, uint32_t addr, uint16_t port, uint32_t payload_type, - uint32_t payload_msg_type) -{ - uint8_t data[sizeof(struct gsm_mncc)]; - struct gsm_mncc_rtp *rtp; - - memset(&data, 0, sizeof(data)); - rtp = (struct gsm_mncc_rtp *) &data[0]; - - rtp->callref = callref; - rtp->msg_type = cmd; - rtp->ip = addr; - rtp->port = port; - rtp->payload_type = payload_type; - rtp->payload_msg_type = payload_msg_type; - mncc_recvmsg(net, NULL, cmd, (struct gsm_mncc *)data); -} - -static void mncc_recv_rtp_sock(struct gsm_network *net, struct gsm_trans *trans, int cmd) -{ - int msg_type; - - /* FIXME This has to be set to some meaningful value. - * Possible options are: - * GSM_TCHF_FRAME, GSM_TCHF_FRAME_EFR, - * GSM_TCHH_FRAME, GSM_TCH_FRAME_AMR - * (0 if unknown) */ - msg_type = GSM_TCHF_FRAME; - - uint32_t addr = mgcpgw_client_remote_addr_n(net->mgcpgw.client); - uint16_t port = trans->conn->rtp.port_cn; - - /* FIXME: This has to be set to some meaningful value, - * before the MSC-Split, this value was pulled from - * lchan->abis_ip.rtp_payload */ - uint32_t payload_type = 0; - - return mncc_recv_rtp(net, trans->callref, cmd, - addr, - port, - payload_type, - msg_type); -} - -static void mncc_recv_rtp_err(struct gsm_network *net, uint32_t callref, int cmd) -{ - return mncc_recv_rtp(net, callref, cmd, 0, 0, 0, 0); -} - -static int tch_rtp_create(struct gsm_network *net, uint32_t callref) -{ - struct gsm_trans *trans; - int rc; - - /* Find callref */ - trans = trans_find_by_callref(net, callref); - if (!trans) { - LOGP(DMNCC, LOGL_ERROR, "RTP create for non-existing trans\n"); - mncc_recv_rtp_err(net, callref, MNCC_RTP_CREATE); - return -EIO; - } - log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub); - if (!trans->conn) { - LOGP(DMNCC, LOGL_NOTICE, "RTP create for trans without conn\n"); - mncc_recv_rtp_err(net, callref, MNCC_RTP_CREATE); - return 0; - } - - trans->conn->mncc_rtp_bridge = 1; - - /* When we call msc_call_assignment() we will trigger, depending - * on the RAN type the call assignment on the A or Iu interface. - * msc_call_assignment() also takes care about sending the CRCX - * command to the MGCP-GW. The CRCX will return the port number, - * where the PBX (e.g. Asterisk) will send its RTP stream to. We - * have to return this port number back to the MNCC by sending - * it back with the TCH_RTP_CREATE message. To make sure that - * this message is sent AFTER the response to CRCX from the - * MGCP-GW has arrived, we need will instruct msc_call_assignment() - * to take care of this by setting trans->tch_rtp_create to true. - * This will make sure that gsm48_tch_rtp_create() (below) is - * called as soon as the local port number has become known. */ - trans->tch_rtp_create = true; - - /* Assign call (if not done yet) */ - if (trans->assignment_done == false) { - rc = msc_call_assignment(trans); - trans->assignment_done = true; - } - else - rc = 0; - - return rc; -} - -/* Trigger TCH_RTP_CREATE acknowledgement */ -int gsm48_tch_rtp_create(struct gsm_trans *trans) -{ - /* This function is called as soon as the port, on which the - * mgcp-gw expects the incoming RTP stream from the remote - * end (e.g. Asterisk) is known. */ - - struct gsm_subscriber_connection *conn = trans->conn; - struct gsm_network *network = conn->network; - - mncc_recv_rtp_sock(network, trans, MNCC_RTP_CREATE); - return 0; -} - -static int tch_rtp_connect(struct gsm_network *net, void *arg) -{ - struct gsm_trans *trans; - struct gsm_mncc_rtp *rtp = arg; - - /* Find callref */ - trans = trans_find_by_callref(net, rtp->callref); - if (!trans) { - LOGP(DMNCC, LOGL_ERROR, "RTP connect for non-existing trans\n"); - mncc_recv_rtp_err(net, rtp->callref, MNCC_RTP_CONNECT); - return -EIO; - } - log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub); - if (!trans->conn) { - LOGP(DMNCC, LOGL_ERROR, "RTP connect for trans without conn\n"); - mncc_recv_rtp_err(net, rtp->callref, MNCC_RTP_CONNECT); - return 0; - } - - msc_call_connect(trans,rtp->port,rtp->ip); - return 0; -} - -static struct downstate { - uint32_t states; - int type; - int (*rout) (struct gsm_trans *trans, void *arg); -} downstatelist[] = { - /* mobile originating call establishment */ - {SBIT(GSM_CSTATE_INITIATED), /* 5.2.1.2 */ - MNCC_CALL_PROC_REQ, gsm48_cc_tx_call_proc_and_assign}, - {SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.2 | 5.2.1.5 */ - MNCC_ALERT_REQ, gsm48_cc_tx_alerting}, - {SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) | SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.2 | 5.2.1.6 | 5.2.1.6 */ - MNCC_SETUP_RSP, gsm48_cc_tx_connect}, - {SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.4.2 */ - MNCC_PROGRESS_REQ, gsm48_cc_tx_progress}, - /* mobile terminating call establishment */ - {SBIT(GSM_CSTATE_NULL), /* 5.2.2.1 */ - MNCC_SETUP_REQ, gsm48_cc_tx_setup}, - {SBIT(GSM_CSTATE_CONNECT_REQUEST), - MNCC_SETUP_COMPL_REQ, gsm48_cc_tx_connect_ack}, - /* signalling during call */ - {SBIT(GSM_CSTATE_ACTIVE), - MNCC_NOTIFY_REQ, gsm48_cc_tx_notify}, - {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), - MNCC_FACILITY_REQ, gsm48_cc_tx_facility}, - {ALL_STATES, - MNCC_START_DTMF_RSP, gsm48_cc_tx_start_dtmf_ack}, - {ALL_STATES, - MNCC_START_DTMF_REJ, gsm48_cc_tx_start_dtmf_rej}, - {ALL_STATES, - MNCC_STOP_DTMF_RSP, gsm48_cc_tx_stop_dtmf_ack}, - {SBIT(GSM_CSTATE_ACTIVE), - MNCC_HOLD_CNF, gsm48_cc_tx_hold_ack}, - {SBIT(GSM_CSTATE_ACTIVE), - MNCC_HOLD_REJ, gsm48_cc_tx_hold_rej}, - {SBIT(GSM_CSTATE_ACTIVE), - MNCC_RETRIEVE_CNF, gsm48_cc_tx_retrieve_ack}, - {SBIT(GSM_CSTATE_ACTIVE), - MNCC_RETRIEVE_REJ, gsm48_cc_tx_retrieve_rej}, - {SBIT(GSM_CSTATE_ACTIVE), - MNCC_MODIFY_REQ, gsm48_cc_tx_modify}, - {SBIT(GSM_CSTATE_MO_ORIG_MODIFY), - MNCC_MODIFY_RSP, gsm48_cc_tx_modify_complete}, - {SBIT(GSM_CSTATE_MO_ORIG_MODIFY), - MNCC_MODIFY_REJ, gsm48_cc_tx_modify_reject}, - {SBIT(GSM_CSTATE_ACTIVE), - MNCC_USERINFO_REQ, gsm48_cc_tx_userinfo}, - /* clearing */ - {SBIT(GSM_CSTATE_INITIATED), - MNCC_REJ_REQ, gsm48_cc_tx_release_compl}, - {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_DISCONNECT_IND) - SBIT(GSM_CSTATE_RELEASE_REQ) - SBIT(GSM_CSTATE_DISCONNECT_REQ), /* 5.4.4 */ - MNCC_DISC_REQ, gsm48_cc_tx_disconnect}, - {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */ - MNCC_REL_REQ, gsm48_cc_tx_release}, -}; - -#define DOWNSLLEN \ - (sizeof(downstatelist) / sizeof(struct downstate)) - - -int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) -{ - int i, rc = 0; - struct gsm_trans *trans = NULL, *transt; - struct gsm_subscriber_connection *conn = NULL; - struct gsm_mncc *data = arg, rel; - - DEBUGP(DMNCC, "receive message %s\n", get_mncc_name(msg_type)); - - /* handle special messages */ - switch(msg_type) { - case MNCC_BRIDGE: - rc = tch_bridge(net, arg); - if (rc < 0) - disconnect_bridge(net, arg, -rc); - return rc; - case MNCC_RTP_CREATE: - return tch_rtp_create(net, data->callref); - case MNCC_RTP_CONNECT: - return tch_rtp_connect(net, arg); - case MNCC_RTP_FREE: - /* unused right now */ - return -EIO; - - case MNCC_FRAME_DROP: - case MNCC_FRAME_RECV: - case GSM_TCHF_FRAME: - case GSM_TCHF_FRAME_EFR: - case GSM_TCHH_FRAME: - case GSM_TCH_FRAME_AMR: - LOGP(DMNCC, LOGL_ERROR, "RTP streams must be handled externally; %s not supported.\n", - get_mncc_name(msg_type)); - return -ENOTSUP; - } - - memset(&rel, 0, sizeof(struct gsm_mncc)); - rel.callref = data->callref; - - /* Find callref */ - trans = trans_find_by_callref(net, data->callref); - - /* Callref unknown */ - if (!trans) { - struct vlr_subscr *vsub; - - if (msg_type != MNCC_SETUP_REQ) { - DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) " - "Received '%s' from MNCC with " - "unknown callref %d\n", data->called.number, - get_mncc_name(msg_type), data->callref); - /* Invalid call reference */ - return mncc_release_ind(net, NULL, data->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_INVAL_TRANS_ID); - } - if (!data->called.number[0] && !data->imsi[0]) { - DEBUGP(DCC, "(bts - trx - ts - ti) " - "Received '%s' from MNCC with " - "no number or IMSI\n", get_mncc_name(msg_type)); - /* Invalid number */ - return mncc_release_ind(net, NULL, data->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_INV_NR_FORMAT); - } - /* New transaction due to setup, find subscriber */ - if (data->called.number[0]) - vsub = vlr_subscr_find_by_msisdn(net->vlr, - data->called.number); - else - vsub = vlr_subscr_find_by_imsi(net->vlr, data->imsi); - - /* update the subscriber we deal with */ - log_set_context(LOG_CTX_VLR_SUBSCR, vsub); - - /* If subscriber is not found */ - if (!vsub) { - DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) " - "Received '%s' from MNCC with " - "unknown subscriber %s\n", data->called.number, - get_mncc_name(msg_type), data->called.number); - /* Unknown subscriber */ - return mncc_release_ind(net, NULL, data->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_UNASSIGNED_NR); - } - /* If subscriber is not "attached" */ - if (!vsub->lac) { - DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) " - "Received '%s' from MNCC with " - "detached subscriber %s\n", data->called.number, - get_mncc_name(msg_type), data->called.number); - vlr_subscr_put(vsub); - /* Temporarily out of order */ - return mncc_release_ind(net, NULL, data->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_DEST_OOO); - } - /* Create transaction */ - trans = trans_alloc(net, vsub, GSM48_PDISC_CC, 0xff, data->callref); - if (!trans) { - DEBUGP(DCC, "No memory for trans.\n"); - vlr_subscr_put(vsub); - /* Ressource unavailable */ - mncc_release_ind(net, NULL, data->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_RESOURCE_UNAVAIL); - return -ENOMEM; - } - - /* Find conn */ - conn = connection_for_subscr(vsub); - - /* If subscriber has no conn */ - if (!conn) { - /* find transaction with this subscriber already paging */ - llist_for_each_entry(transt, &net->trans_list, entry) { - /* Transaction of our conn? */ - if (transt == trans || - transt->vsub != vsub) - continue; - DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) " - "Received '%s' from MNCC with " - "unallocated channel, paging already " - "started for lac %d.\n", - data->called.number, - get_mncc_name(msg_type), vsub->lac); - vlr_subscr_put(vsub); - trans_free(trans); - return 0; - } - /* store setup information until paging succeeds */ - memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc)); - - /* Request a channel */ - trans->paging_request = subscr_request_conn( - vsub, - setup_trig_pag_evt, - trans, - "MNCC: establish call"); - if (!trans->paging_request) { - LOGP(DCC, LOGL_ERROR, "Failed to allocate paging token.\n"); - vlr_subscr_put(vsub); - trans_free(trans); - return 0; - } - vlr_subscr_put(vsub); - return 0; - } - - /* Assign conn */ - trans->conn = msc_subscr_conn_get(conn); - vlr_subscr_put(vsub); - } else { - /* update the subscriber we deal with */ - log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub); - } - - if (trans->conn) - conn = trans->conn; - - /* if paging did not respond yet */ - if (!conn) { - DEBUGP(DCC, "(sub %s) " - "Received '%s' from MNCC in paging state\n", - vlr_subscr_msisdn_or_name(trans->vsub), - get_mncc_name(msg_type)); - mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_NORM_CALL_CLEAR); - if (msg_type == MNCC_REL_REQ) - rc = mncc_recvmsg(net, trans, MNCC_REL_CNF, &rel); - else - rc = mncc_recvmsg(net, trans, MNCC_REL_IND, &rel); - trans->callref = 0; - trans_free(trans); - return rc; - } - - DEBUGP(DCC, "(ti %02x sub %s) " - "Received '%s' from MNCC in state %d (%s)\n", - trans->transaction_id, - vlr_subscr_msisdn_or_name(trans->conn->vsub), - get_mncc_name(msg_type), trans->cc.state, - gsm48_cc_state_name(trans->cc.state)); - - /* Find function for current state and message */ - for (i = 0; i < DOWNSLLEN; i++) - if ((msg_type == downstatelist[i].type) - && ((1 << trans->cc.state) & downstatelist[i].states)) - break; - if (i == DOWNSLLEN) { - DEBUGP(DCC, "Message unhandled at this state.\n"); - return 0; - } - - rc = downstatelist[i].rout(trans, arg); - - return rc; -} - - -static struct datastate { - uint32_t states; - int type; - int (*rout) (struct gsm_trans *trans, struct msgb *msg); -} datastatelist[] = { - /* mobile originating call establishment */ - {SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */ - GSM48_MT_CC_SETUP, gsm48_cc_rx_setup}, - {SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */ - GSM48_MT_CC_EMERG_SETUP, gsm48_cc_rx_setup}, - {SBIT(GSM_CSTATE_CONNECT_IND), /* 5.2.1.2 */ - GSM48_MT_CC_CONNECT_ACK, gsm48_cc_rx_connect_ack}, - /* mobile terminating call establishment */ - {SBIT(GSM_CSTATE_CALL_PRESENT), /* 5.2.2.3.2 */ - GSM48_MT_CC_CALL_CONF, gsm48_cc_rx_call_conf}, - {SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF), /* ???? | 5.2.2.3.2 */ - GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting}, - {SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF) | SBIT(GSM_CSTATE_CALL_RECEIVED), /* (5.2.2.6) | 5.2.2.6 | 5.2.2.6 */ - GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect}, - /* signalling during call */ - {ALL_STATES - SBIT(GSM_CSTATE_NULL), - GSM48_MT_CC_FACILITY, gsm48_cc_rx_facility}, - {SBIT(GSM_CSTATE_ACTIVE), - GSM48_MT_CC_NOTIFY, gsm48_cc_rx_notify}, - {ALL_STATES, - GSM48_MT_CC_START_DTMF, gsm48_cc_rx_start_dtmf}, - {ALL_STATES, - GSM48_MT_CC_STOP_DTMF, gsm48_cc_rx_stop_dtmf}, - {ALL_STATES, - GSM48_MT_CC_STATUS_ENQ, gsm48_cc_rx_status_enq}, - {SBIT(GSM_CSTATE_ACTIVE), - GSM48_MT_CC_HOLD, gsm48_cc_rx_hold}, - {SBIT(GSM_CSTATE_ACTIVE), - GSM48_MT_CC_RETR, gsm48_cc_rx_retrieve}, - {SBIT(GSM_CSTATE_ACTIVE), - GSM48_MT_CC_MODIFY, gsm48_cc_rx_modify}, - {SBIT(GSM_CSTATE_MO_TERM_MODIFY), - GSM48_MT_CC_MODIFY_COMPL, gsm48_cc_rx_modify_complete}, - {SBIT(GSM_CSTATE_MO_TERM_MODIFY), - GSM48_MT_CC_MODIFY_REJECT, gsm48_cc_rx_modify_reject}, - {SBIT(GSM_CSTATE_ACTIVE), - GSM48_MT_CC_USER_INFO, gsm48_cc_rx_userinfo}, - /* clearing */ - {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */ - GSM48_MT_CC_DISCONNECT, gsm48_cc_rx_disconnect}, - {ALL_STATES - SBIT(GSM_CSTATE_NULL), /* 5.4.4.1.2.2 */ - GSM48_MT_CC_RELEASE, gsm48_cc_rx_release}, - {ALL_STATES, /* 5.4.3.4 */ - GSM48_MT_CC_RELEASE_COMPL, gsm48_cc_rx_release_compl}, -}; - -#define DATASLLEN \ - (sizeof(datastatelist) / sizeof(struct datastate)) - -static int gsm0408_rcv_cc(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t msg_type = gsm48_hdr_msg_type(gh); - uint8_t transaction_id = gsm48_hdr_trans_id_flip_ti(gh); - struct gsm_trans *trans = NULL; - int i, rc = 0; - - if (msg_type & 0x80) { - DEBUGP(DCC, "MSG 0x%2x not defined for PD error\n", msg_type); - return -EINVAL; - } - - if (!conn->vsub) { - LOGP(DCC, LOGL_ERROR, "Invalid conn: no subscriber\n"); - return -EINVAL; - } - - /* Find transaction */ - trans = trans_find_by_id(conn, GSM48_PDISC_CC, transaction_id); - -#if BEFORE_MSCSPLIT - /* Re-enable this log output once we can obtain this information via - * A-interface, see OS#2391. */ - DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) " - "Received '%s' from MS in state %d (%s)\n", - conn->bts->nr, conn->lchan->ts->trx->nr, conn->lchan->ts->nr, - transaction_id, vlr_subscr_msisdn_or_name(conn->vsub), - gsm48_cc_msg_name(msg_type), trans?(trans->cc.state):0, - gsm48_cc_state_name(trans?(trans->cc.state):0)); -#endif - - /* Create transaction */ - if (!trans) { - DEBUGP(DCC, "Unknown transaction ID %x, " - "creating new trans.\n", transaction_id); - /* Create transaction */ - trans = trans_alloc(conn->network, conn->vsub, - GSM48_PDISC_CC, - transaction_id, new_callref++); - if (!trans) { - DEBUGP(DCC, "No memory for trans.\n"); - rc = gsm48_tx_simple(conn, - GSM48_PDISC_CC | (transaction_id << 4), - GSM48_MT_CC_RELEASE_COMPL); - return -ENOMEM; - } - /* Assign transaction */ - trans->conn = msc_subscr_conn_get(conn); - cm_service_request_concludes(conn, msg); - } - - /* find function for current state and message */ - for (i = 0; i < DATASLLEN; i++) - if ((msg_type == datastatelist[i].type) - && ((1 << trans->cc.state) & datastatelist[i].states)) - break; - if (i == DATASLLEN) { - DEBUGP(DCC, "Message unhandled at this state.\n"); - return 0; - } - - assert(trans->vsub); - - rc = datastatelist[i].rout(trans, msg); - - msc_subscr_conn_communicating(conn); - return rc; -} - -static bool msg_is_initially_permitted(const struct gsm48_hdr *hdr) -{ - uint8_t pdisc = gsm48_hdr_pdisc(hdr); - uint8_t msg_type = gsm48_hdr_msg_type(hdr); - - switch (pdisc) { - case GSM48_PDISC_MM: - switch (msg_type) { - case GSM48_MT_MM_LOC_UPD_REQUEST: - case GSM48_MT_MM_CM_SERV_REQ: - case GSM48_MT_MM_AUTH_RESP: - case GSM48_MT_MM_AUTH_FAIL: - case GSM48_MT_MM_ID_RESP: - case GSM48_MT_MM_TMSI_REALL_COMPL: - case GSM48_MT_MM_IMSI_DETACH_IND: - return true; - default: - break; - } - break; - case GSM48_PDISC_RR: - switch (msg_type) { - case GSM48_MT_RR_CIPH_M_COMPL: - case GSM48_MT_RR_PAG_RESP: - return true; - default: - break; - } - break; - default: - break; - } - - return false; -} - -void cm_service_request_concludes(struct gsm_subscriber_connection *conn, - struct msgb *msg) -{ - - /* If a CM Service Request was received before, this is the request the - * conn was opened for. No need to wait for further messages. */ - - if (!conn->received_cm_service_request) - return; - - if (log_check_level(DMM, LOGL_DEBUG)) { - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t pdisc = gsm48_hdr_pdisc(gh); - uint8_t msg_type = gsm48_hdr_msg_type(gh); - - DEBUGP(DMM, "%s: rx msg %s:" - " received_cm_service_request changes to false\n", - vlr_subscr_name(conn->vsub), - gsm48_pdisc_msgtype_name(pdisc, msg_type)); - } - conn->received_cm_service_request = false; -} - - -/* Main entry point for GSM 04.08/44.008 Layer 3 data (e.g. from the BSC). */ -int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t pdisc = gsm48_hdr_pdisc(gh); - int rc = 0; - - OSMO_ASSERT(conn); - OSMO_ASSERT(msg); - - LOGP(DRLL, LOGL_DEBUG, "Dispatching 04.08 message %s (0x%x:0x%x)\n", - gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)), - pdisc, gsm48_hdr_msg_type(gh)); - - if (!msc_subscr_conn_is_accepted(conn) - && !msg_is_initially_permitted(gh)) { - LOGP(DRLL, LOGL_ERROR, - "subscr %s: Message not permitted for initial conn: %s\n", - vlr_subscr_name(conn->vsub), - gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh))); - return -EACCES; - } - - if (conn->vsub && conn->vsub->cs.attached_via_ran != conn->via_ran) { - LOGP(DMM, LOGL_ERROR, - "%s: Illegal situation: RAN type mismatch:" - " attached via %s, received message via %s\n", - vlr_subscr_name(conn->vsub), - ran_type_name(conn->vsub->cs.attached_via_ran), - ran_type_name(conn->via_ran)); - return -EACCES; - } - -#if 0 - if (silent_call_reroute(conn, msg)) - return silent_call_rx(conn, msg); -#endif - - switch (pdisc) { - case GSM48_PDISC_CC: - rc = gsm0408_rcv_cc(conn, msg); - break; - case GSM48_PDISC_MM: - rc = gsm0408_rcv_mm(conn, msg); - break; - case GSM48_PDISC_RR: - rc = gsm0408_rcv_rr(conn, msg); - break; - case GSM48_PDISC_SMS: - rc = gsm0411_rcv_sms(conn, msg); - break; - case GSM48_PDISC_MM_GPRS: - case GSM48_PDISC_SM_GPRS: - LOGP(DRLL, LOGL_NOTICE, "Unimplemented " - "GSM 04.08 discriminator 0x%02x\n", pdisc); - rc = -ENOTSUP; - break; - case GSM48_PDISC_NC_SS: - rc = handle_rcv_ussd(conn, msg); - break; - case GSM48_PDISC_TEST: - rc = gsm0414_rcv_test(conn, msg); - break; - default: - LOGP(DRLL, LOGL_NOTICE, "Unknown " - "GSM 04.08 discriminator 0x%02x\n", pdisc); - rc = -EINVAL; - break; - } - - return rc; -} - -/*********************************************************************** - * VLR integration - ***********************************************************************/ - -/* VLR asks us to send an authentication request */ -static int msc_vlr_tx_auth_req(void *msc_conn_ref, struct gsm_auth_tuple *at, - bool send_autn) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - return gsm48_tx_mm_auth_req(conn, at->vec.rand, - send_autn? at->vec.autn : NULL, - at->key_seq); -} - -/* VLR asks us to send an authentication reject */ -static int msc_vlr_tx_auth_rej(void *msc_conn_ref) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - return gsm48_tx_mm_auth_rej(conn); -} - -/* VLR asks us to transmit an Identity Request of given type */ -static int msc_vlr_tx_id_req(void *msc_conn_ref, uint8_t mi_type) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - return mm_tx_identity_req(conn, mi_type); -} - -/* VLR asks us to transmit a Location Update Accept */ -static int msc_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - return gsm0408_loc_upd_acc(conn, send_tmsi); -} - -/* VLR asks us to transmit a Location Update Reject */ -static int msc_vlr_tx_lu_rej(void *msc_conn_ref, uint8_t cause) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - return gsm0408_loc_upd_rej(conn, cause); -} - -/* VLR asks us to transmit a CM Service Accept */ -static int msc_vlr_tx_cm_serv_acc(void *msc_conn_ref) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - return msc_gsm48_tx_mm_serv_ack(conn); -} - -static int msc_vlr_tx_common_id(void *msc_conn_ref) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - return msc_tx_common_id(conn); -} - -/* VLR asks us to transmit a CM Service Reject */ -static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum vlr_proc_arq_result result) -{ - uint8_t cause; - struct gsm_subscriber_connection *conn = msc_conn_ref; - conn->received_cm_service_request = false; - - switch (result) { - default: - case VLR_PR_ARQ_RES_NONE: - case VLR_PR_ARQ_RES_SYSTEM_FAILURE: - case VLR_PR_ARQ_RES_UNKNOWN_ERROR: - cause = GSM48_REJECT_NETWORK_FAILURE; - break; - case VLR_PR_ARQ_RES_ILLEGAL_SUBSCR: - cause = GSM48_REJECT_LOC_NOT_ALLOWED; - break; - case VLR_PR_ARQ_RES_UNIDENT_SUBSCR: - cause = GSM48_REJECT_INVALID_MANDANTORY_INF; - break; - case VLR_PR_ARQ_RES_ROAMING_NOTALLOWED: - cause = GSM48_REJECT_ROAMING_NOT_ALLOWED; - break; - case VLR_PR_ARQ_RES_ILLEGAL_EQUIP: - cause = GSM48_REJECT_ILLEGAL_MS; - break; - case VLR_PR_ARQ_RES_TIMEOUT: - cause = GSM48_REJECT_CONGESTION; - break; - }; - - return msc_gsm48_tx_mm_serv_rej(conn, cause); -} - -/* VLR asks us to start using ciphering */ -static int msc_vlr_set_ciph_mode(void *msc_conn_ref, - enum vlr_ciph ciph, - bool retrieve_imeisv) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - struct vlr_subscr *vsub; - struct gsm_auth_tuple *tuple; - - if (!conn || !conn->vsub) { - LOGP(DMM, LOGL_ERROR, "Cannot send Ciphering Mode Command to" - " NULL conn/subscriber"); - return -EINVAL; - } - - vsub = conn->vsub; - tuple = vsub->last_tuple; - - if (!tuple) { - LOGP(DMM, LOGL_ERROR, "subscr %s: Cannot send Ciphering Mode" - " Command: no auth tuple available\n", - vlr_subscr_name(vsub)); - return -EINVAL; - } - - switch (conn->via_ran) { - case RAN_GERAN_A: - DEBUGP(DMM, "-> CIPHER MODE COMMAND %s\n", - vlr_subscr_name(conn->vsub)); - return a_iface_tx_cipher_mode(conn, ciph, tuple->vec.kc, 8, - retrieve_imeisv); - case RAN_UTRAN_IU: -#ifdef BUILD_IU - DEBUGP(DMM, "-> SECURITY MODE CONTROL %s\n", - vlr_subscr_name(conn->vsub)); - return ranap_iu_tx_sec_mode_cmd(conn->iu.ue_ctx, &tuple->vec, 0, 1); -#else - LOGP(DMM, LOGL_ERROR, "Cannot send Security Mode Control over RAN_UTRAN_IU," - " built without Iu support\n"); - return -ENOTSUP; -#endif - - default: - break; - } - LOGP(DMM, LOGL_ERROR, - "%s: cannot start ciphering, unknown RAN type %d\n", - vlr_subscr_name(conn->vsub), conn->via_ran); - return -ENOTSUP; -} - -void msc_rx_sec_mode_compl(struct gsm_subscriber_connection *conn) -{ - struct vlr_ciph_result vlr_res = {}; - - if (!conn || !conn->vsub) { - LOGP(DMM, LOGL_ERROR, - "Rx Security Mode Complete for invalid conn\n"); - return; - } - - DEBUGP(DMM, "<- SECURITY MODE COMPLETE %s\n", - vlr_subscr_name(conn->vsub)); - - vlr_res.cause = VLR_CIPH_COMPL; - vlr_subscr_rx_ciph_res(conn->vsub, &vlr_res); -} - -/* VLR informs us that the subscriber data has somehow been modified */ -static void msc_vlr_subscr_update(struct vlr_subscr *subscr) -{ - /* FIXME */ -} - -/* VLR informs us that the subscriber has been associated with a conn */ -static void msc_vlr_subscr_assoc(void *msc_conn_ref, - struct vlr_subscr *vsub) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - OSMO_ASSERT(!conn->vsub); - conn->vsub = vlr_subscr_get(vsub); - conn->vsub->cs.attached_via_ran = conn->via_ran; -} - -/* operations that we need to implement for libvlr */ -static const struct vlr_ops msc_vlr_ops = { - .tx_auth_req = msc_vlr_tx_auth_req, - .tx_auth_rej = msc_vlr_tx_auth_rej, - .tx_id_req = msc_vlr_tx_id_req, - .tx_lu_acc = msc_vlr_tx_lu_acc, - .tx_lu_rej = msc_vlr_tx_lu_rej, - .tx_cm_serv_acc = msc_vlr_tx_cm_serv_acc, - .tx_cm_serv_rej = msc_vlr_tx_cm_serv_rej, - .set_ciph_mode = msc_vlr_set_ciph_mode, - .tx_common_id = msc_vlr_tx_common_id, - .subscr_update = msc_vlr_subscr_update, - .subscr_assoc = msc_vlr_subscr_assoc, -}; - -/* Allocate net->vlr so that the VTY may configure the VLR's data structures */ -int msc_vlr_alloc(struct gsm_network *net) -{ - net->vlr = vlr_alloc(net, &msc_vlr_ops); - if (!net->vlr) - return -ENOMEM; - net->vlr->user_ctx = net; - return 0; -} - -/* Launch the VLR, i.e. its GSUP connection */ -int msc_vlr_start(struct gsm_network *net) -{ - OSMO_ASSERT(net->vlr); - return vlr_start("MSC", net->vlr, net->gsup_server_addr_str, - net->gsup_server_port); -} diff --git a/src/libmsc/gsm_04_11.c b/src/libmsc/gsm_04_11.c deleted file mode 100644 index 574fe281d..000000000 --- a/src/libmsc/gsm_04_11.c +++ /dev/null @@ -1,1189 +0,0 @@ -/* Point-to-Point (PP) Short Message Service (SMS) - * Support on Mobile Radio Interface - * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */ - -/* (C) 2008 by Daniel Willmann - * (C) 2009 by Harald Welte - * (C) 2010-2012 by Holger Hans Peter Freyther - * (C) 2010 by On-Waves - * (C) 2011 by Andreas Eversberg - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - - -#include -#include -#include -#include -#include -#include - -#include "bscconfig.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BUILD_SMPP -#include "smpp_smsc.h" -#endif - -void *tall_gsms_ctx; -static uint32_t new_callref = 0x40000001; - - -struct gsm_sms *sms_alloc(void) -{ - return talloc_zero(tall_gsms_ctx, struct gsm_sms); -} - -void sms_free(struct gsm_sms *sms) -{ - /* drop references to subscriber structure */ - if (sms->receiver) - vlr_subscr_put(sms->receiver); -#ifdef BUILD_SMPP - if (sms->smpp.esme) - smpp_esme_put(sms->smpp.esme); -#endif - - talloc_free(sms); -} - -struct gsm_sms *sms_from_text(struct vlr_subscr *receiver, - struct vlr_subscr *sender, - int dcs, const char *text) -{ - struct gsm_sms *sms = sms_alloc(); - - if (!sms) - return NULL; - - sms->receiver = vlr_subscr_get(receiver); - osmo_strlcpy(sms->text, text, sizeof(sms->text)); - - osmo_strlcpy(sms->src.addr, sender->msisdn, sizeof(sms->src.addr)); - sms->reply_path_req = 0; - sms->status_rep_req = 0; - sms->ud_hdr_ind = 0; - sms->protocol_id = 0; /* implicit */ - sms->data_coding_scheme = dcs; - osmo_strlcpy(sms->dst.addr, receiver->msisdn, sizeof(sms->dst.addr)); - /* Generate user_data */ - sms->user_data_len = gsm_7bit_encode_n(sms->user_data, sizeof(sms->user_data), - sms->text, NULL); - - return sms; -} - - -static void send_signal(int sig_no, - struct gsm_trans *trans, - struct gsm_sms *sms, - int paging_result) -{ - struct sms_signal_data sig; - sig.trans = trans; - sig.sms = sms; - sig.paging_result = paging_result; - osmo_signal_dispatch(SS_SMS, sig_no, &sig); -} - -static int gsm411_sendmsg(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - DEBUGP(DLSMS, "GSM4.11 TX %s\n", osmo_hexdump(msg->data, msg->len)); - msg->l3h = msg->data; - return msc_tx_dtap(conn, msg); -} - -/* Prefix msg with a 04.08/04.11 CP header */ -static int gsm411_cp_sendmsg(struct msgb *msg, struct gsm_trans *trans, - uint8_t msg_type) -{ - struct gsm48_hdr *gh; - - gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh)); - /* Outgoing needs the highest bit set */ - gh->proto_discr = trans->protocol | (trans->transaction_id<<4); - gh->msg_type = msg_type; - - DEBUGP(DLSMS, "sending CP message (trans=%x)\n", trans->transaction_id); - - return gsm411_sendmsg(trans->conn, msg); -} - -/* mm_send: receive MMCCSMS sap message from SMC */ -static int gsm411_mm_send(struct gsm411_smc_inst *inst, int msg_type, - struct msgb *msg, int cp_msg_type) -{ - struct gsm_trans *trans = - container_of(inst, struct gsm_trans, sms.smc_inst); - int rc = 0; - - switch (msg_type) { - case GSM411_MMSMS_EST_REQ: - /* recycle msg */ - rc = gsm411_smc_recv(inst, GSM411_MMSMS_EST_CNF, msg, 0); - msgb_free(msg); /* upper layer does not free msg */ - break; - case GSM411_MMSMS_DATA_REQ: - rc = gsm411_cp_sendmsg(msg, trans, cp_msg_type); - break; - case GSM411_MMSMS_REL_REQ: - DEBUGP(DLSMS, "Got MMSMS_REL_REQ, destroying transaction.\n"); - msgb_free(msg); - trans_free(trans); - break; - default: - LOGP(DLSMS, LOGL_NOTICE, "Unhandled MMCCSMS msg 0x%x\n", msg_type); - msgb_free(msg); - rc = -EINVAL; - } - - return rc; -} - -/* mm_send: receive MNCCSMS sap message from SMR */ -int gsm411_mn_send(struct gsm411_smr_inst *inst, int msg_type, - struct msgb *msg) -{ - struct gsm_trans *trans = - container_of(inst, struct gsm_trans, sms.smr_inst); - - /* forward to SMC */ - return gsm411_smc_send(&trans->sms.smc_inst, msg_type, msg); -} - -static int gsm340_rx_sms_submit(struct gsm_sms *gsms) -{ - if (db_sms_store(gsms) != 0) { - LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n"); - return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER; - } - /* dispatch a signal to tell higher level about it */ - send_signal(S_SMS_SUBMITTED, NULL, gsms, 0); - - return 0; -} - -/* generate a TPDU address field compliant with 03.40 sec. 9.1.2.5 */ -static int gsm340_gen_oa_sub(uint8_t *oa, unsigned int oa_len, - const struct gsm_sms_addr *src) -{ - /* network specific, private numbering plan */ - return gsm340_gen_oa(oa, oa_len, src->ton, src->npi, src->addr); -} - -/* generate a msgb containing an 03.40 9.2.2.1 SMS-DELIVER TPDU derived from - * struct gsm_sms, returns total size of TPDU */ -static int gsm340_gen_sms_deliver_tpdu(struct msgb *msg, struct gsm_sms *sms) -{ - uint8_t *smsp; - uint8_t oa[12]; /* max len per 03.40 */ - uint8_t octet_len; - unsigned int old_msg_len = msg->len; - int oa_len; - - /* generate first octet with masked bits */ - smsp = msgb_put(msg, 1); - /* TP-MTI (message type indicator) */ - *smsp = GSM340_SMS_DELIVER_SC2MS; - /* TP-MMS (more messages to send) */ - if (0 /* FIXME */) - *smsp |= 0x04; - /* TP-SRI(deliver)/SRR(submit) */ - if (sms->status_rep_req) - *smsp |= 0x20; - /* TP-UDHI (indicating TP-UD contains a header) */ - if (sms->ud_hdr_ind) - *smsp |= 0x40; - - /* generate originator address */ - oa_len = gsm340_gen_oa_sub(oa, sizeof(oa), &sms->src); - if (oa_len < 0) - return -ENOSPC; - - smsp = msgb_put(msg, oa_len); - memcpy(smsp, oa, oa_len); - - /* generate TP-PID */ - smsp = msgb_put(msg, 1); - *smsp = sms->protocol_id; - - /* generate TP-DCS */ - smsp = msgb_put(msg, 1); - *smsp = sms->data_coding_scheme; - - /* generate TP-SCTS */ - smsp = msgb_put(msg, 7); - gsm340_gen_scts(smsp, time(NULL)); - - /* generate TP-UDL */ - smsp = msgb_put(msg, 1); - *smsp = sms->user_data_len; - - /* generate TP-UD */ - switch (gsm338_get_sms_alphabet(sms->data_coding_scheme)) { - case DCS_7BIT_DEFAULT: - octet_len = sms->user_data_len*7/8; - if (sms->user_data_len*7%8 != 0) - octet_len++; - /* Warning, user_data_len indicates the amount of septets - * (characters), we need amount of octets occupied */ - smsp = msgb_put(msg, octet_len); - memcpy(smsp, sms->user_data, octet_len); - break; - case DCS_UCS2: - case DCS_8BIT_DATA: - smsp = msgb_put(msg, sms->user_data_len); - memcpy(smsp, sms->user_data, sms->user_data_len); - break; - default: - LOGP(DLSMS, LOGL_NOTICE, "Unhandled Data Coding Scheme: 0x%02X\n", - sms->data_coding_scheme); - break; - } - - return msg->len - old_msg_len; -} - -/* As defined by GSM 03.40, Section 9.2.2.3. */ -static int gsm340_gen_sms_status_report_tpdu(struct msgb *msg, - struct gsm_sms *sms) -{ - unsigned int old_msg_len = msg->len; - uint8_t oa[12]; /* max len per 03.40 */ - uint8_t *smsp; - int oa_len; - - /* generate first octet with masked bits */ - smsp = msgb_put(msg, 1); - /* TP-MTI (message type indicator) */ - *smsp = GSM340_SMS_STATUS_REP_SC2MS; - /* TP-MMS (more messages to send) */ - if (0 /* FIXME */) - *smsp |= 0x04; - /* TP-MR (message reference) */ - smsp = msgb_put(msg, 1); - *smsp = sms->msg_ref; - - /* generate recipient address */ - oa_len = gsm340_gen_oa_sub(oa, sizeof(oa), &sms->src); - if (oa_len < 0) - return -ENOSPC; - - smsp = msgb_put(msg, oa_len); - memcpy(smsp, oa, oa_len); - - /* generate TP-SCTS (Service centre timestamp) */ - smsp = msgb_put(msg, 7); - gsm340_gen_scts(smsp, sms->created); - - /* generate TP-DT (Discharge time, in TP-SCTS format). */ - smsp = msgb_put(msg, 7); - gsm340_gen_scts(smsp, sms->created); - - /* TP-ST (status) */ - smsp = msgb_put(msg, 1); - /* From GSM 03.40, Section 9.2.3.15, 0x00 means OK. */ - *smsp = 0x00; - - LOGP(DLSMS, LOGL_INFO, "sending status report for SMS reference %x\n", - sms->msg_ref); - - return msg->len - old_msg_len; -} - -static int sms_route_mt_sms(struct gsm_subscriber_connection *conn, - struct gsm_sms *gsms) -{ - int rc; - -#ifdef BUILD_SMPP - int smpp_first = smpp_route_smpp_first(gsms, conn); - - /* - * Route through SMPP first before going to the local database. In case - * of a unroutable message and no local subscriber, SMPP will be tried - * twice. In case of an unknown subscriber continue with the normal - * delivery of the SMS. - */ - if (smpp_first) { - rc = smpp_try_deliver(gsms, conn); - if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) - /* unknown subscriber, try local */ - goto try_local; - if (rc < 0) { - LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", - vlr_subscr_name(conn->vsub), rc); - rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; - /* rc will be logged by gsm411_send_rp_error() */ - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[ - MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); - } - return rc; - } - -try_local: -#endif - - /* determine gsms->receiver based on dialled number */ - gsms->receiver = vlr_subscr_find_by_msisdn(conn->network->vlr, - gsms->dst.addr); - if (!gsms->receiver) { -#ifdef BUILD_SMPP - /* Avoid a second look-up */ - if (smpp_first) { - rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); - return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; - } - - rc = smpp_try_deliver(gsms, conn); - if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) { - rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); - } else if (rc < 0) { - LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.", - vlr_subscr_name(conn->vsub), rc); - rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; - /* rc will be logged by gsm411_send_rp_error() */ - rate_ctr_inc(&conn->bts->network->msc_ctrs->ctr[ - MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); - } -#else - rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; - rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); -#endif - } - - return rc; -} - - -/* process an incoming TPDU (called from RP-DATA) - * return value > 0: RP CAUSE for ERROR; < 0: silent error; 0 = success */ -static int gsm340_rx_tpdu(struct gsm_trans *trans, struct msgb *msg, - uint32_t gsm411_msg_ref) -{ - struct gsm_subscriber_connection *conn = trans->conn; - uint8_t *smsp = msgb_sms(msg); - struct gsm_sms *gsms; - unsigned int sms_alphabet; - uint8_t sms_mti, sms_vpf; - uint8_t *sms_vp; - uint8_t da_len_bytes; - uint8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */ - int rc = 0; - - rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED]); - - gsms = sms_alloc(); - if (!gsms) - return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER; - - /* invert those fields where 0 means active/present */ - sms_mti = *smsp & 0x03; - sms_vpf = (*smsp & 0x18) >> 3; - gsms->status_rep_req = (*smsp & 0x20) >> 5; - gsms->ud_hdr_ind = (*smsp & 0x40); - /* - * Not evaluating MMS (More Messages to Send) because the - * lchan stays open anyway. - * Not evaluating RP (Reply Path) because we're not aware of its - * benefits. - */ - - smsp++; - gsms->msg_ref = *smsp++; - - gsms->gsm411.transaction_id = trans->transaction_id; - gsms->gsm411.msg_ref = gsm411_msg_ref; - - /* length in bytes of the destination address */ - da_len_bytes = 2 + *smsp/2 + *smsp%2; - if (da_len_bytes > 12) { - LOGP(DLSMS, LOGL_ERROR, "Destination Address > 12 bytes ?!?\n"); - rc = GSM411_RP_CAUSE_SEMANT_INC_MSG; - goto out; - } else if (da_len_bytes < 4) { - LOGP(DLSMS, LOGL_ERROR, "Destination Address < 4 bytes ?!?\n"); - rc = GSM411_RP_CAUSE_SEMANT_INC_MSG; - goto out; - } - memset(address_lv, 0, sizeof(address_lv)); - memcpy(address_lv, smsp, da_len_bytes); - /* mangle first byte to reflect length in bytes, not digits */ - address_lv[0] = da_len_bytes - 1; - - gsms->dst.ton = (address_lv[1] >> 4) & 7; - gsms->dst.npi = address_lv[1] & 0xF; - /* convert to real number */ - gsm48_decode_bcd_number(gsms->dst.addr, - sizeof(gsms->dst.addr), address_lv, 1); - smsp += da_len_bytes; - - gsms->protocol_id = *smsp++; - gsms->data_coding_scheme = *smsp++; - - sms_alphabet = gsm338_get_sms_alphabet(gsms->data_coding_scheme); - if (sms_alphabet == 0xffffffff) { - rc = GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER; - goto out; - } - - switch (sms_vpf) { - case GSM340_TP_VPF_RELATIVE: - sms_vp = smsp++; - break; - case GSM340_TP_VPF_ABSOLUTE: - case GSM340_TP_VPF_ENHANCED: - sms_vp = smsp; - /* the additional functionality indicator... */ - if (sms_vpf == GSM340_TP_VPF_ENHANCED && *smsp & (1<<7)) - smsp++; - smsp += 7; - break; - case GSM340_TP_VPF_NONE: - sms_vp = 0; - break; - default: - LOGP(DLSMS, LOGL_NOTICE, - "SMS Validity period not implemented: 0x%02x\n", sms_vpf); - rc = GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER; - goto out; - } - gsms->user_data_len = *smsp++; - if (gsms->user_data_len) { - memcpy(gsms->user_data, smsp, gsms->user_data_len); - - switch (sms_alphabet) { - case DCS_7BIT_DEFAULT: - gsm_7bit_decode_n(gsms->text, sizeof(gsms->text), smsp, - gsms->user_data_len); - break; - case DCS_8BIT_DATA: - case DCS_UCS2: - case DCS_NONE: - break; - } - } - - osmo_strlcpy(gsms->src.addr, conn->vsub->msisdn, sizeof(gsms->src.addr)); - - LOGP(DLSMS, LOGL_INFO, "RX SMS: Sender: %s, MTI: 0x%02x, VPF: 0x%02x, " - "MR: 0x%02x PID: 0x%02x, DCS: 0x%02x, DA: %s, " - "UserDataLength: 0x%02x, UserData: \"%s\"\n", - vlr_subscr_name(conn->vsub), sms_mti, sms_vpf, gsms->msg_ref, - gsms->protocol_id, gsms->data_coding_scheme, gsms->dst.addr, - gsms->user_data_len, - sms_alphabet == DCS_7BIT_DEFAULT ? gsms->text : - osmo_hexdump(gsms->user_data, gsms->user_data_len)); - - gsms->validity_minutes = gsm340_validity_period(sms_vpf, sms_vp); - - /* FIXME: This looks very wrong */ - send_signal(0, NULL, gsms, 0); - - rc = sms_route_mt_sms(conn, gsms); - - /* This SMS got routed through SMPP or no receiver exists. */ - if (!gsms->receiver) - return rc; - - switch (sms_mti) { - case GSM340_SMS_SUBMIT_MS2SC: - /* MS is submitting a SMS */ - rc = gsm340_rx_sms_submit(gsms); - break; - case GSM340_SMS_COMMAND_MS2SC: - case GSM340_SMS_DELIVER_REP_MS2SC: - LOGP(DLSMS, LOGL_NOTICE, "Unimplemented MTI 0x%02x\n", sms_mti); - rc = GSM411_RP_CAUSE_IE_NOTEXIST; - break; - default: - LOGP(DLSMS, LOGL_NOTICE, "Undefined MTI 0x%02x\n", sms_mti); - rc = GSM411_RP_CAUSE_IE_NOTEXIST; - break; - } -out: - sms_free(gsms); - - return rc; -} - -/* Prefix msg with a RP-DATA header and send as SMR DATA */ -static int gsm411_rp_sendmsg(struct gsm411_smr_inst *inst, struct msgb *msg, - uint8_t rp_msg_type, uint8_t rp_msg_ref, - int rl_msg_type) -{ - struct gsm411_rp_hdr *rp; - uint8_t len = msg->len; - - /* GSM 04.11 RP-DATA header */ - rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp)); - rp->len = len + 2; - rp->msg_type = rp_msg_type; - rp->msg_ref = rp_msg_ref; - - return gsm411_smr_send(inst, rl_msg_type, msg); -} - -int gsm411_send_rp_ack(struct gsm_trans *trans, uint8_t msg_ref) -{ - struct msgb *msg = gsm411_msgb_alloc(); - - DEBUGP(DLSMS, "TX: SMS RP ACK\n"); - - return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg, GSM411_MT_RP_ACK_MT, - msg_ref, GSM411_SM_RL_REPORT_REQ); -} - -int gsm411_send_rp_error(struct gsm_trans *trans, uint8_t msg_ref, - uint8_t cause) -{ - struct msgb *msg = gsm411_msgb_alloc(); - - msgb_tv_put(msg, 1, cause); - - LOGP(DLSMS, LOGL_NOTICE, "TX: SMS RP ERROR, cause %d (%s)\n", cause, - get_value_string(gsm411_rp_cause_strs, cause)); - - return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg, - GSM411_MT_RP_ERROR_MT, msg_ref, GSM411_SM_RL_REPORT_REQ); -} - -/* Receive a 04.11 TPDU inside RP-DATA / user data */ -static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans, - struct gsm411_rp_hdr *rph, - uint8_t src_len, uint8_t *src, - uint8_t dst_len, uint8_t *dst, - uint8_t tpdu_len, uint8_t *tpdu) -{ - int rc = 0; - - if (src_len && src) - LOGP(DLSMS, LOGL_ERROR, "RP-DATA (MO) with SRC ?!?\n"); - - if (!dst_len || !dst || !tpdu_len || !tpdu) { - LOGP(DLSMS, LOGL_ERROR, - "RP-DATA (MO) without DST or TPDU ?!?\n"); - gsm411_send_rp_error(trans, rph->msg_ref, - GSM411_RP_CAUSE_INV_MAND_INF); - return -EIO; - } - msg->l4h = tpdu; - - DEBUGP(DLSMS, "DST(%u,%s)\n", dst_len, osmo_hexdump(dst, dst_len)); - - rc = gsm340_rx_tpdu(trans, msg, rph->msg_ref); - if (rc == 0) - return gsm411_send_rp_ack(trans, rph->msg_ref); - else if (rc > 0) - return gsm411_send_rp_error(trans, rph->msg_ref, rc); - else - return rc; -} - -/* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */ -static int gsm411_rx_rp_data(struct msgb *msg, struct gsm_trans *trans, - struct gsm411_rp_hdr *rph) -{ - uint8_t src_len, dst_len, rpud_len; - uint8_t *src = NULL, *dst = NULL , *rp_ud = NULL; - - /* in the MO case, this should always be zero length */ - src_len = rph->data[0]; - if (src_len) - src = &rph->data[1]; - - dst_len = rph->data[1+src_len]; - if (dst_len) - dst = &rph->data[1+src_len+1]; - - rpud_len = rph->data[1+src_len+1+dst_len]; - if (rpud_len) - rp_ud = &rph->data[1+src_len+1+dst_len+1]; - - DEBUGP(DLSMS, "RX_RP-DATA: src_len=%u, dst_len=%u ud_len=%u\n", - src_len, dst_len, rpud_len); - return gsm411_rx_rp_ud(msg, trans, rph, src_len, src, dst_len, dst, - rpud_len, rp_ud); -} - -static struct gsm_sms *sms_report_alloc(struct gsm_sms *sms) -{ - struct gsm_sms *sms_report; - int len; - - sms_report = sms_alloc(); - OSMO_ASSERT(sms_report); - - sms_report->msg_ref = sms->msg_ref; - sms_report->protocol_id = sms->protocol_id; - sms_report->data_coding_scheme = GSM338_DCS_1111_8BIT_DATA; - - /* Invert address to send status report back to origin. */ - sms_report->src = sms->dst; - sms_report->dst = sms->src; - - /* As specified by Appendix B. Delivery Receipt Format. - * TODO: Many fields in this string are just set with dummy values, - * revisit this. - */ - len = snprintf((char *)sms_report->user_data, - sizeof(sms_report->user_data), - "id:%.08llu sub:000 dlvrd:000 submit date:YYMMDDhhmm done date:YYMMDDhhmm stat:DELIVRD err:000 text:%.20s", - sms->id, sms->text); - sms_report->user_data_len = len; - LOGP(DLSMS, LOGL_NOTICE, "%s\n", sms_report->user_data); - - /* This represents a sms report. */ - sms_report->is_report = true; - - return sms_report; -} - -static void sms_status_report(struct gsm_sms *gsms, - struct gsm_subscriber_connection *conn) -{ - struct gsm_sms *sms_report; - int rc; - - sms_report = sms_report_alloc(gsms); - - rc = sms_route_mt_sms(conn, sms_report); - if (rc < 0) { - LOGP(DLSMS, LOGL_ERROR, - "Failed to send status report! err=%d\n", rc); - } - - /* No route via SMPP, send the GSM 03.40 status-report now. */ - if (gsms->receiver) - gsm340_rx_sms_submit(sms_report); - - LOGP(DLSMS, LOGL_NOTICE, "Status report has been sent\n"); - - sms_free(sms_report); -} - -/* Receive a 04.11 RP-ACK message (response to RP-DATA from us) */ -static int gsm411_rx_rp_ack(struct msgb *msg, struct gsm_trans *trans, - struct gsm411_rp_hdr *rph) -{ - struct gsm_sms *sms = trans->sms.sms; - - /* Acnkowledgement to MT RP_DATA, i.e. the MS confirms it - * successfully received a SMS. We can now safely mark it as - * transmitted */ - - if (!sms) { - LOGP(DLSMS, LOGL_ERROR, "RX RP-ACK but no sms in transaction?!?\n"); - return gsm411_send_rp_error(trans, rph->msg_ref, - GSM411_RP_CAUSE_PROTOCOL_ERR); - } - - /* mark this SMS as sent in database */ - db_sms_mark_delivered(sms); - - send_signal(S_SMS_DELIVERED, trans, sms, 0); - - if (sms->status_rep_req) - sms_status_report(sms, trans->conn); - - sms_free(sms); - trans->sms.sms = NULL; - - return 0; -} - -static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans, - struct gsm411_rp_hdr *rph) -{ - struct gsm_network *net = trans->conn->network; - struct gsm_sms *sms = trans->sms.sms; - uint8_t cause_len = rph->data[0]; - uint8_t cause = rph->data[1]; - - /* Error in response to MT RP_DATA, i.e. the MS did not - * successfully receive the SMS. We need to investigate - * the cause and take action depending on it */ - - LOGP(DLSMS, LOGL_NOTICE, "%s: RX SMS RP-ERROR, cause %d:%d (%s)\n", - vlr_subscr_name(trans->conn->vsub), cause_len, cause, - get_value_string(gsm411_rp_cause_strs, cause)); - - if (!sms) { - LOGP(DLSMS, LOGL_ERROR, - "RX RP-ERR, but no sms in transaction?!?\n"); - return -EINVAL; -#if 0 - return gsm411_send_rp_error(trans, rph->msg_ref, - GSM411_RP_CAUSE_PROTOCOL_ERR); -#endif - } - - if (cause == GSM411_RP_CAUSE_MT_MEM_EXCEEDED) { - /* MS has not enough memory to store the message. We need - * to store this in our database and wait for a SMMA message */ - /* FIXME */ - send_signal(S_SMS_MEM_EXCEEDED, trans, sms, 0); - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM]); - } else { - send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0); - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER]); - } - - sms_free(sms); - trans->sms.sms = NULL; - - return 0; -} - -static int gsm411_rx_rp_smma(struct msgb *msg, struct gsm_trans *trans, - struct gsm411_rp_hdr *rph) -{ - int rc; - - rc = gsm411_send_rp_ack(trans, rph->msg_ref); - - /* MS tells us that it has memory for more SMS, we need - * to check if we have any pending messages for it and then - * transfer those */ - send_signal(S_SMS_SMMA, trans, NULL, 0); - - return rc; -} - -/* receive RL DATA */ -static int gsm411_rx_rl_data(struct msgb *msg, struct gsm48_hdr *gh, - struct gsm_trans *trans) -{ - struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data; - uint8_t msg_type = rp_data->msg_type & 0x07; - int rc = 0; - - switch (msg_type) { - case GSM411_MT_RP_DATA_MO: - DEBUGP(DLSMS, "RX SMS RP-DATA (MO)\n"); - rc = gsm411_rx_rp_data(msg, trans, rp_data); - break; - case GSM411_MT_RP_SMMA_MO: - DEBUGP(DLSMS, "RX SMS RP-SMMA\n"); - rc = gsm411_rx_rp_smma(msg, trans, rp_data); - break; - default: - LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type); - rc = -EINVAL; - break; - } - - return rc; -} - -/* receive RL REPORT */ -static int gsm411_rx_rl_report(struct msgb *msg, struct gsm48_hdr *gh, - struct gsm_trans *trans) -{ - struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data; - uint8_t msg_type = rp_data->msg_type & 0x07; - int rc = 0; - - switch (msg_type) { - case GSM411_MT_RP_ACK_MO: - DEBUGP(DLSMS, "RX SMS RP-ACK (MO)\n"); - rc = gsm411_rx_rp_ack(msg, trans, rp_data); - break; - case GSM411_MT_RP_ERROR_MO: - DEBUGP(DLSMS, "RX SMS RP-ERROR (MO)\n"); - rc = gsm411_rx_rp_error(msg, trans, rp_data); - break; - default: - LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type); - rc = -EINVAL; - break; - } - - return rc; -} - -/* receive SM-RL sap message from SMR - * NOTE: Message is freed by sender - */ -int gsm411_rl_recv(struct gsm411_smr_inst *inst, int msg_type, - struct msgb *msg) -{ - struct gsm_trans *trans = - container_of(inst, struct gsm_trans, sms.smr_inst); - struct gsm48_hdr *gh = msgb_l3(msg); - int rc = 0; - - switch (msg_type) { - case GSM411_SM_RL_DATA_IND: - rc = gsm411_rx_rl_data(msg, gh, trans); - break; - case GSM411_SM_RL_REPORT_IND: - if (gh) - rc = gsm411_rx_rl_report(msg, gh, trans); - break; - default: - LOGP(DLSMS, LOGL_NOTICE, "Unhandled SM-RL message 0x%x\n", msg_type); - rc = -EINVAL; - } - - return rc; -} - -/* receive MNCCSMS sap message from SMC - * NOTE: Message is freed by sender - */ -static int gsm411_mn_recv(struct gsm411_smc_inst *inst, int msg_type, - struct msgb *msg) -{ - struct gsm_trans *trans = - container_of(inst, struct gsm_trans, sms.smc_inst); - struct gsm48_hdr *gh = msgb_l3(msg); - int rc = 0; - - switch (msg_type) { - case GSM411_MNSMS_EST_IND: - case GSM411_MNSMS_DATA_IND: - DEBUGP(DLSMS, "MNSMS-DATA/EST-IND\n"); - rc = gsm411_smr_recv(&trans->sms.smr_inst, msg_type, msg); - break; - case GSM411_MNSMS_ERROR_IND: - if (gh) - DEBUGP(DLSMS, "MNSMS-ERROR-IND, cause %d (%s)\n", - gh->data[0], - get_value_string(gsm411_cp_cause_strs, - gh->data[0])); - else - DEBUGP(DLSMS, "MNSMS-ERROR-IND, no cause\n"); - rc = gsm411_smr_recv(&trans->sms.smr_inst, msg_type, msg); - break; - default: - LOGP(DLSMS, LOGL_NOTICE, "Unhandled MNCCSMS msg 0x%x\n", msg_type); - rc = -EINVAL; - } - - return rc; -} - -/* Entry point for incoming GSM48_PDISC_SMS from abis_rsl.c */ -int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, - struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t msg_type = gh->msg_type; - uint8_t transaction_id = gsm48_hdr_trans_id_flip_ti(gh); - struct gsm_trans *trans; - int new_trans = 0; - int rc = 0; - - if (!conn->vsub) - return -EIO; - /* FIXME: send some error message */ - - DEBUGP(DLSMS, "receiving data (trans_id=%x, msg_type=%s)\n", transaction_id, - gsm48_pdisc_msgtype_name(gsm48_hdr_pdisc(gh), gsm48_hdr_msg_type(gh))); - - trans = trans_find_by_id(conn, GSM48_PDISC_SMS, transaction_id); - - /* - * A transaction we created but don't know about? - */ - if (!trans && (transaction_id & 0x8) == 0) { - LOGP(DLSMS, LOGL_ERROR, "trans_id=%x allocated by us but known " - "to us anymore. We are ignoring it, maybe a CP-ERROR " - "from a MS?\n", - transaction_id); - return -EINVAL; - } - - if (!trans) { - DEBUGP(DLSMS, " -> (new transaction)\n"); - trans = trans_alloc(conn->network, conn->vsub, - GSM48_PDISC_SMS, - transaction_id, new_callref++); - if (!trans) { - DEBUGP(DLSMS, " -> No memory for trans\n"); - /* FIXME: send some error message */ - return -ENOMEM; - } - gsm411_smc_init(&trans->sms.smc_inst, 0, 1, - gsm411_mn_recv, gsm411_mm_send); - gsm411_smr_init(&trans->sms.smr_inst, 0, 1, - gsm411_rl_recv, gsm411_mn_send); - - trans->conn = msc_subscr_conn_get(conn); - - new_trans = 1; - cm_service_request_concludes(conn, msg); - } - - /* 5.4: For MO, if a CP-DATA is received for a new - * transaction, equals reception of an implicit - * last CP-ACK for previous transaction */ - if (trans->sms.smc_inst.cp_state == GSM411_CPS_IDLE - && msg_type == GSM411_MT_CP_DATA) { - int i; - struct gsm_trans *ptrans; - - /* Scan through all remote initiated transactions */ - for (i=8; i<15; i++) { - if (i == transaction_id) - continue; - - ptrans = trans_find_by_id(conn, GSM48_PDISC_SMS, i); - if (!ptrans) - continue; - - DEBUGP(DLSMS, "Implicit CP-ACK for trans_id=%x\n", i); - - /* Finish it for good */ - trans_free(ptrans); - } - } - - msc_subscr_conn_communicating(conn); - - gsm411_smc_recv(&trans->sms.smc_inst, - (new_trans) ? GSM411_MMSMS_EST_IND : GSM411_MMSMS_DATA_IND, - msg, msg_type); - - return rc; -} - -/* Take a SMS in gsm_sms structure and send it through an already - * existing conn. We also assume that the caller ensured this conn already - * has a SAPI3 RLL connection! */ -int gsm411_send_sms(struct gsm_subscriber_connection *conn, struct gsm_sms *sms) -{ - struct msgb *msg = gsm411_msgb_alloc(); - struct gsm_trans *trans; - uint8_t *data, *rp_ud_len; - uint8_t msg_ref = sms_next_rp_msg_ref(&conn->next_rp_ref); - int transaction_id; - int rc; - - transaction_id = - trans_assign_trans_id(conn->network, conn->vsub, - GSM48_PDISC_SMS, 0); - if (transaction_id == -1) { - LOGP(DLSMS, LOGL_ERROR, "No available transaction ids\n"); - send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, 0); - sms_free(sms); - msgb_free(msg); - return -EBUSY; - } - - DEBUGP(DLSMS, "%s()\n", __func__); - - /* FIXME: allocate transaction with message reference */ - trans = trans_alloc(conn->network, conn->vsub, - GSM48_PDISC_SMS, - transaction_id, new_callref++); - if (!trans) { - LOGP(DLSMS, LOGL_ERROR, "No memory for trans\n"); - send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, 0); - sms_free(sms); - msgb_free(msg); - /* FIXME: send some error message */ - return -ENOMEM; - } - gsm411_smc_init(&trans->sms.smc_inst, sms->id, 1, - gsm411_mn_recv, gsm411_mm_send); - gsm411_smr_init(&trans->sms.smr_inst, sms->id, 1, - gsm411_rl_recv, gsm411_mn_send); - trans->sms.sms = sms; - - trans->conn = msc_subscr_conn_get(conn); - - /* Hardcode SMSC Originating Address for now */ - data = (uint8_t *)msgb_put(msg, 8); - data[0] = 0x07; /* originator length == 7 */ - data[1] = 0x91; /* type of number: international, ISDN */ - data[2] = 0x44; /* 447785016005 */ - data[3] = 0x77; - data[4] = 0x58; - data[5] = 0x10; - data[6] = 0x06; - data[7] = 0x50; - - /* Hardcoded Destination Address */ - data = (uint8_t *)msgb_put(msg, 1); - data[0] = 0; /* destination length == 0 */ - - /* obtain a pointer for the rp_ud_len, so we can fill it later */ - rp_ud_len = (uint8_t *)msgb_put(msg, 1); - - if (sms->is_report) { - /* generate the 03.40 SMS-STATUS-REPORT TPDU */ - rc = gsm340_gen_sms_status_report_tpdu(msg, sms); - } else { - /* generate the 03.40 SMS-DELIVER TPDU */ - rc = gsm340_gen_sms_deliver_tpdu(msg, sms); - } - if (rc < 0) { - send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0); - sms_free(sms); - trans->sms.sms = NULL; - trans_free(trans); - msgb_free(msg); - return rc; - } - - *rp_ud_len = rc; - - DEBUGP(DLSMS, "TX: SMS DELIVER\n"); - - rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]); - db_sms_inc_deliver_attempts(trans->sms.sms); - - return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg, - GSM411_MT_RP_DATA_MT, msg_ref, GSM411_SM_RL_DATA_REQ); -} - -/* paging callback. Here we get called if paging a subscriber has - * succeeded or failed. */ -static int paging_cb_send_sms(unsigned int hooknum, unsigned int event, - struct msgb *msg, void *_conn, void *_sms) -{ - struct gsm_subscriber_connection *conn = _conn; - struct gsm_sms *sms = _sms; - int rc = 0; - - DEBUGP(DLSMS, "paging_cb_send_sms(hooknum=%u, event=%u, msg=%p," - "conn=%p, sms=%p/id: %llu)\n", hooknum, event, msg, conn, sms, sms->id); - - if (hooknum != GSM_HOOK_RR_PAGING) - return -EINVAL; - - switch (event) { - case GSM_PAGING_SUCCEEDED: - gsm411_send_sms(conn, sms); - break; - case GSM_PAGING_EXPIRED: - case GSM_PAGING_OOM: - case GSM_PAGING_BUSY: - send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, event); - sms_free(sms); - rc = -ETIMEDOUT; - break; - default: - LOGP(DLSMS, LOGL_ERROR, "Unhandled paging event: %d\n", event); - } - - return rc; -} - -/* high-level function to send a SMS to a given subscriber. The function - * will take care of paging the subscriber, establishing the RLL SAPI3 - * connection, etc. */ -int gsm411_send_sms_subscr(struct vlr_subscr *vsub, - struct gsm_sms *sms) -{ - struct gsm_subscriber_connection *conn; - void *res; - - /* check if we already have an open conn to the subscriber. - * if yes, send the SMS this way */ - conn = connection_for_subscr(vsub); - if (conn) { - LOGP(DLSMS, LOGL_DEBUG, "Sending SMS via already open connection %p to %s\n", - conn, vlr_subscr_name(vsub)); - return gsm411_send_sms(conn, sms); - } - - /* if not, we have to start paging */ - LOGP(DLSMS, LOGL_DEBUG, "Sending SMS: no connection open, start paging %s\n", - vlr_subscr_name(vsub)); - res = subscr_request_conn(vsub, paging_cb_send_sms, sms, "send SMS"); - if (!res) { - send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, GSM_PAGING_BUSY); - sms_free(sms); - } - return 0; -} - -void _gsm411_sms_trans_free(struct gsm_trans *trans) -{ - /* cleanup SMS instance */ - gsm411_smr_clear(&trans->sms.smr_inst); - trans->sms.smr_inst.rl_recv = NULL; - trans->sms.smr_inst.mn_send = NULL; - - gsm411_smc_clear(&trans->sms.smc_inst); - trans->sms.smc_inst.mn_recv = NULL; - trans->sms.smc_inst.mm_send = NULL; - - if (trans->sms.sms) { - LOGP(DLSMS, LOGL_ERROR, "Transaction contains SMS.\n"); - send_signal(S_SMS_UNKNOWN_ERROR, trans, trans->sms.sms, 0); - sms_free(trans->sms.sms); - trans->sms.sms = NULL; - } -} - -/* Process incoming SAPI N-REJECT from BSC */ -void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn) -{ - struct gsm_network *net; - struct gsm_trans *trans, *tmp; - - net = conn->network; - - llist_for_each_entry_safe(trans, tmp, &net->trans_list, entry) { - struct gsm_sms *sms; - - if (trans->conn != conn) - continue; - if (trans->protocol != GSM48_PDISC_SMS) - continue; - - sms = trans->sms.sms; - if (!sms) { - LOGP(DLSMS, LOGL_ERROR, "SAPI Reject but no SMS.\n"); - continue; - } - - send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0); - sms_free(sms); - trans->sms.sms = NULL; - trans_free(trans); - } -} - diff --git a/src/libmsc/gsm_04_80.c b/src/libmsc/gsm_04_80.c deleted file mode 100644 index bec1d26f4..000000000 --- a/src/libmsc/gsm_04_80.c +++ /dev/null @@ -1,155 +0,0 @@ -/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface - * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */ - -/* (C) 2008-2009 by Harald Welte - * (C) 2008, 2009, 2010 by Holger Hans Peter Freyther - * (C) 2009 by Mike Haben - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static inline unsigned char *msgb_wrap_with_TL(struct msgb *msgb, uint8_t tag) -{ - uint8_t *data = msgb_push(msgb, 2); - - data[0] = tag; - data[1] = msgb->len - 2; - return data; -} - -static inline unsigned char *msgb_push_TLV1(struct msgb *msgb, uint8_t tag, - uint8_t value) -{ - uint8_t *data = msgb_push(msgb, 3); - - data[0] = tag; - data[1] = 1; - data[2] = value; - return data; -} - - -/* Send response to a mobile-originated ProcessUnstructuredSS-Request */ -int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn, - const struct msgb *in_msg, const char *response_text, - const struct ss_request *req) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USSD RSP"); - struct gsm48_hdr *gh; - uint8_t *ptr8; - int response_len; - - /* First put the payload text into the message */ - ptr8 = msgb_put(msg, 0); - gsm_7bit_encode_n_ussd(ptr8, msgb_tailroom(msg), response_text, &response_len); - msgb_put(msg, response_len); - - /* Then wrap it as an Octet String */ - msgb_wrap_with_TL(msg, ASN1_OCTET_STRING_TAG); - - /* Pre-pend the DCS octet string */ - msgb_push_TLV1(msg, ASN1_OCTET_STRING_TAG, 0x0F); - - /* Then wrap these as a Sequence */ - msgb_wrap_with_TL(msg, GSM_0480_SEQUENCE_TAG); - - /* Pre-pend the operation code */ - msgb_push_TLV1(msg, GSM0480_OPERATION_CODE, - GSM0480_OP_CODE_PROCESS_USS_REQ); - - /* Wrap the operation code and IA5 string as a sequence */ - msgb_wrap_with_TL(msg, GSM_0480_SEQUENCE_TAG); - - /* Pre-pend the invoke ID */ - msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id); - - /* Wrap this up as a Return Result component */ - msgb_wrap_with_TL(msg, GSM0480_CTYPE_RETURN_RESULT); - - /* Wrap the component in a Facility message */ - msgb_wrap_with_TL(msg, GSM0480_IE_FACILITY); - - /* And finally pre-pend the L3 header */ - gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_NC_SS | req->transaction_id - | (1<<7); /* TI direction = 1 */ - gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE; - - return msc_tx_dtap(conn, msg); -} - -int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn, - const struct msgb *in_msg, - const struct ss_request *req) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USSD REJ"); - struct gsm48_hdr *gh; - - /* First insert the problem code */ - msgb_push_TLV1(msg, GSM_0480_PROBLEM_CODE_TAG_GENERAL, - GSM_0480_GEN_PROB_CODE_UNRECOGNISED); - - /* Before it insert the invoke ID */ - msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id); - - /* Wrap this up as a Reject component */ - msgb_wrap_with_TL(msg, GSM0480_CTYPE_REJECT); - - /* Wrap the component in a Facility message */ - msgb_wrap_with_TL(msg, GSM0480_IE_FACILITY); - - /* And finally pre-pend the L3 header */ - gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_NC_SS; - gh->proto_discr |= req->transaction_id | (1<<7); /* TI direction = 1 */ - gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE; - - return msc_tx_dtap(conn, msg); -} - -int msc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level, const char *text) -{ - struct msgb *msg = gsm0480_create_ussd_notify(level, text); - if (!msg) - return -1; - return msc_tx_dtap(conn, msg); -} - -int msc_send_ussd_release_complete(struct gsm_subscriber_connection *conn) -{ - struct msgb *msg = gsm0480_create_ussd_release_complete(); - if (!msg) - return -1; - return msc_tx_dtap(conn, msg); -} diff --git a/src/libmsc/gsm_subscriber.c b/src/libmsc/gsm_subscriber.c deleted file mode 100644 index 09540c16c..000000000 --- a/src/libmsc/gsm_subscriber.c +++ /dev/null @@ -1,190 +0,0 @@ -/* The concept of a subscriber for the MSC, roughly HLR/VLR functionality */ - -/* (C) 2008 by Harald Welte - * (C) 2009,2013 by Holger Hans Peter Freyther - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include "../../bscconfig.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#ifdef BUILD_IU -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, - struct msgb *msg, void *data, void *param) -{ - struct subscr_request *request, *tmp; - struct gsm_subscriber_connection *conn = data; - struct vlr_subscr *vsub = param; - struct paging_signal_data sig_data; - - OSMO_ASSERT(vsub); - OSMO_ASSERT(hooknum == GSM_HOOK_RR_PAGING); - OSMO_ASSERT(!(conn && (conn->vsub != vsub))); - OSMO_ASSERT(!((event == GSM_PAGING_SUCCEEDED) && !conn)); - - LOGP(DPAG, LOGL_DEBUG, "Paging %s for %s (event=%d)\n", - event == GSM_PAGING_SUCCEEDED ? "success" : "failure", - vlr_subscr_name(vsub), event); - - if (!vsub->cs.is_paging) { - LOGP(DPAG, LOGL_ERROR, - "Paging Response received for subscriber" - " that is not paging.\n"); - return -EINVAL; - } - - if (event == GSM_PAGING_SUCCEEDED) - msc_stop_paging(vsub); - - /* Inform parts of the system we don't know */ - sig_data.vsub = vsub; - sig_data.conn = conn; - sig_data.paging_result = event; - osmo_signal_dispatch(SS_PAGING, - event == GSM_PAGING_SUCCEEDED ? - S_PAGING_SUCCEEDED : S_PAGING_EXPIRED, - &sig_data); - - llist_for_each_entry_safe(request, tmp, &vsub->cs.requests, entry) { - llist_del(&request->entry); - if (request->cbfn) { - LOGP(DPAG, LOGL_DEBUG, "Calling paging cbfn.\n"); - request->cbfn(hooknum, event, msg, data, request->param); - } else - LOGP(DPAG, LOGL_DEBUG, "Paging without action.\n"); - talloc_free(request); - } - - /* balanced with the moment we start paging */ - vsub->cs.is_paging = false; - vlr_subscr_put(vsub); - return 0; -} - -int msc_paging_request(struct vlr_subscr *vsub) -{ - /* The subscriber was last seen in subscr->lac. Find out which - * BSCs/RNCs are responsible and send them a paging request via open - * SCCP connections (if any). */ - /* TODO Implementing only RNC paging, since this is code on the iu branch. - * Need to add BSC paging at some point. */ - switch (vsub->cs.attached_via_ran) { - case RAN_GERAN_A: - return a_iface_tx_paging(vsub->imsi, vsub->tmsi, vsub->lac); - case RAN_UTRAN_IU: - return ranap_iu_page_cs(vsub->imsi, - vsub->tmsi == GSM_RESERVED_TMSI? - NULL : &vsub->tmsi, - vsub->lac); - default: - break; - } - - LOGP(DPAG, LOGL_ERROR, "%s: Cannot page, subscriber not attached\n", - vlr_subscr_name(vsub)); - return -EINVAL; -} - -/*! \brief Start a paging request for vsub, call cbfn(param) when done. - * \param vsub subscriber to page. - * \param cbfn function to call when the conn is established. - * \param param caller defined param to pass to cbfn(). - * \param label human readable label of the request kind used for logging. - */ -struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub, - gsm_cbfn *cbfn, void *param, - const char *label) -{ - int rc; - struct subscr_request *request; - - /* Start paging.. we know it is async so we can do it before */ - if (!vsub->cs.is_paging) { - LOGP(DMM, LOGL_DEBUG, "Subscriber %s not paged yet, start paging.\n", - vlr_subscr_name(vsub)); - rc = msc_paging_request(vsub); - if (rc <= 0) { - LOGP(DMM, LOGL_ERROR, "Subscriber %s paging failed: %d\n", - vlr_subscr_name(vsub), rc); - return NULL; - } - /* reduced on the first paging callback */ - vlr_subscr_get(vsub); - vsub->cs.is_paging = true; - } else { - LOGP(DMM, LOGL_DEBUG, "Subscriber %s already paged.\n", - vlr_subscr_name(vsub)); - } - - /* TODO: Stop paging in case of memory allocation failure */ - request = talloc_zero(vsub, struct subscr_request); - if (!request) - return NULL; - - request->cbfn = cbfn; - request->param = param; - llist_add_tail(&request->entry, &vsub->cs.requests); - return request; -} - -void subscr_remove_request(struct subscr_request *request) -{ - llist_del(&request->entry); - talloc_free(request); -} - -struct gsm_subscriber_connection *connection_for_subscr(struct vlr_subscr *vsub) -{ - struct gsm_network *net = vsub->vlr->user_ctx; - struct gsm_subscriber_connection *conn; - - llist_for_each_entry(conn, &net->subscr_conns, entry) { - if (conn->vsub == vsub) - return conn; - } - - return NULL; -} diff --git a/src/libmsc/iu_dummy.c b/src/libmsc/iu_dummy.c deleted file mode 100644 index e9d335e2e..000000000 --- a/src/libmsc/iu_dummy.c +++ /dev/null @@ -1,93 +0,0 @@ -/* Trivial switch-off of external Iu dependencies, - * allowing to run full unit tests even when built without Iu support. */ - -/* - * (C) 2016,2017 by sysmocom s.f.m.c. GmbH - * - * Author: Neels Hofmeyr - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include "../../bscconfig.h" -#ifndef BUILD_IU - -#include - -#include -#include -#include - -struct msgb; -struct ranap_ue_conn_ctx; -struct gsm_auth_tuple; -struct RANAP_Cause; -struct osmo_auth_vector; - -int ranap_iu_tx(struct msgb *msg, uint8_t sapi) -{ - LOGP(DLGLOBAL, LOGL_INFO, "iu_tx() dummy called, NOT transmitting %d bytes: %s\n", - msg->len, osmo_hexdump(msg->data, msg->len)); - return 0; -} - -int ranap_iu_tx_sec_mode_cmd(struct ranap_ue_conn_ctx *uectx, struct osmo_auth_vector *vec, - int send_ck) -{ - LOGP(DLGLOBAL, LOGL_INFO, "iu_tx_sec_mode_cmd() dummy called, NOT transmitting Security Mode Command\n"); - return 0; -} - -int ranap_iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac) -{ - LOGP(DLGLOBAL, LOGL_INFO, "iu_page_cs() dummy called, NOT paging\n"); - return 23; -} - -int ranap_iu_page_ps(const char *imsi, const uint32_t *ptmsi, uint16_t lac, uint8_t rac) -{ - LOGP(DLGLOBAL, LOGL_INFO, "iu_page_ps() dummy called, NOT paging\n"); - return 0; -} - -struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, - uint16_t rtp_port, - bool use_x213_nsap) -{ - LOGP(DLGLOBAL, LOGL_INFO, "ranap_new_msg_rab_assign_voice() dummy called, NOT composing RAB Assignment\n"); - return NULL; -} - -int ranap_iu_rab_act(struct ranap_ue_conn_ctx *ue_ctx, struct msgb *msg) -{ - LOGP(DLGLOBAL, LOGL_INFO, "iu_rab_act() dummy called, NOT activating RAB\n"); - return 0; -} - -int ranap_iu_tx_common_id(struct ranap_ue_conn_ctx *uectx, const char *imsi) -{ - LOGP(DLGLOBAL, LOGL_INFO, "iu_tx_common_id() dummy called, NOT sending CommonID\n"); - return 0; -} - -int ranap_iu_tx_release(struct ranap_ue_conn_ctx *ctx, const struct RANAP_Cause *cause) -{ - LOGP(DLGLOBAL, LOGL_INFO, "iu_tx_release() dummy called, NOT sending Release\n"); - return 0; -} - -#endif diff --git a/src/libmsc/iucs.c b/src/libmsc/iucs.c deleted file mode 100644 index 04b9ece7d..000000000 --- a/src/libmsc/iucs.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Code to manage MSC subscriber connections over IuCS interface */ - -/* - * (C) 2016,2017 by sysmocom s.f.m.c. GmbH - * - * Author: Neels Hofmeyr - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include - -/* For A-interface see libbsc/bsc_api.c subscr_con_allocate() */ -static struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *network, - struct ranap_ue_conn_ctx *ue, - uint16_t lac) -{ - struct gsm_subscriber_connection *conn; - - DEBUGP(DIUCS, "Allocating IuCS subscriber conn: lac %d, conn_id %" PRIx32 "\n", - lac, ue->conn_id); - - conn = talloc_zero(network, struct gsm_subscriber_connection); - if (!conn) - return NULL; - - conn->network = network; - conn->via_ran = RAN_UTRAN_IU; - conn->iu.ue_ctx = ue; - conn->iu.ue_ctx->rab_assign_addr_enc = network->iu.rab_assign_addr_enc; - conn->lac = lac; - - llist_add_tail(&conn->entry, &network->subscr_conns); - return conn; -} - -static int same_ue_conn(struct ranap_ue_conn_ctx *a, struct ranap_ue_conn_ctx *b) -{ - if (a == b) - return 1; - return (a->conn_id == b->conn_id); -} - -static inline void log_subscribers(struct gsm_network *network) -{ - if (!log_check_level(DIUCS, LOGL_DEBUG)) - return; - - struct gsm_subscriber_connection *conn; - int i = 0; - llist_for_each_entry(conn, &network->subscr_conns, entry) { - DEBUGP(DIUCS, "%3d: %s", i, vlr_subscr_name(conn->vsub)); - switch (conn->via_ran) { - case RAN_UTRAN_IU: - DEBUGPC(DIUCS, " Iu"); - if (conn->iu.ue_ctx) { - DEBUGPC(DIUCS, " conn_id %d", - conn->iu.ue_ctx->conn_id - ); - } - break; - case RAN_GERAN_A: - DEBUGPC(DIUCS, " A"); - /* TODO log A-interface connection details */ - break; - case RAN_UNKNOWN: - DEBUGPC(DIUCS, " ?"); - break; - default: - DEBUGPC(DIUCS, " invalid"); - break; - } - DEBUGPC(DIUCS, "\n"); - i++; - } - DEBUGP(DIUCS, "subscribers registered: %d\n", i); -} - -/* Return an existing IuCS subscriber connection record for the given - * connection IDs, or return NULL if not found. */ -struct gsm_subscriber_connection *subscr_conn_lookup_iu( - struct gsm_network *network, - struct ranap_ue_conn_ctx *ue) -{ - struct gsm_subscriber_connection *conn; - - DEBUGP(DIUCS, "Looking for IuCS subscriber: conn_id %" PRIx32 "\n", - ue->conn_id); - log_subscribers(network); - - llist_for_each_entry(conn, &network->subscr_conns, entry) { - if (conn->via_ran != RAN_UTRAN_IU) - continue; - if (!same_ue_conn(conn->iu.ue_ctx, ue)) - continue; - DEBUGP(DIUCS, "Found IuCS subscriber for conn_id %" PRIx32 "\n", - ue->conn_id); - return conn; - } - DEBUGP(DIUCS, "No IuCS subscriber found for conn_id %" PRIx32 "\n", - ue->conn_id); - return NULL; -} - -/* Receive MM/CC/... message from IuCS (SCCP user SAP). - * msg->dst must reference a struct ranap_ue_conn_ctx, which identifies the peer that - * sent the msg. - * - * For A-interface see libbsc/bsc_api.c gsm0408_rcvmsg(). */ -int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg, - uint16_t *lac) -{ - int rc; - struct ranap_ue_conn_ctx *ue_ctx; - struct gsm_subscriber_connection *conn; - - ue_ctx = (struct ranap_ue_conn_ctx*)msg->dst; - - /* TODO: are there message types that could allow us to skip this - * search? */ - conn = subscr_conn_lookup_iu(network, ue_ctx); - - if (conn && lac && (conn->lac != *lac)) { - LOGP(DIUCS, LOGL_ERROR, "IuCS subscriber has changed LAC" - " within the same connection, discarding connection:" - " %s from LAC %d to %d\n", - vlr_subscr_name(conn->vsub), conn->lac, *lac); - /* Deallocate conn with previous LAC */ - msc_subscr_conn_close(conn, GSM_CAUSE_INV_MAND_INFO); - /* At this point we could be tolerant and allocate a new - * connection, but changing the LAC within the same connection - * is shifty. Rather cancel everything. */ - return -1; - } - - if (conn) { - /* Make sure we don't receive RR over IuCS; otherwise all - * messages handled by gsm0408_dispatch() are of interest (CC, - * MM, SMS, NS_SS, maybe even MM_GPRS and SM_GPRS). */ - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t pdisc = gh->proto_discr & 0x0f; - OSMO_ASSERT(pdisc != GSM48_PDISC_RR); - - msc_dtap(conn, ue_ctx->conn_id, msg); - rc = 0; - } else { - /* allocate a new connection */ - - if (!lac) { - LOGP(DIUCS, LOGL_ERROR, "New IuCS subscriber" - " but no LAC available. Expecting an InitialUE" - " message containing a LAI IE." - " Dropping connection.\n"); - return -1; - } - - conn = subscr_conn_allocate_iu(network, ue_ctx, *lac); - if (!conn) - abort(); - - /* ownership of conn hereby goes to the MSC: */ - rc = msc_compl_l3(conn, msg, 0); - } - - return rc; -} diff --git a/src/libmsc/iucs_ranap.c b/src/libmsc/iucs_ranap.c deleted file mode 100644 index 45de1caca..000000000 --- a/src/libmsc/iucs_ranap.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Implementation of RANAP messages to/from an MSC via an Iu-CS interface. - * This keeps direct RANAP dependencies out of libmsc. */ - -/* (C) 2016 by sysmocom s.m.f.c. GmbH - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include "../../bscconfig.h" - -#ifdef BUILD_IU - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* To continue authorization after a Security Mode Complete */ -int gsm0408_authorize(struct gsm_subscriber_connection *conn); - -static int iucs_rx_rab_assign(struct gsm_subscriber_connection *conn, - RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) -{ - uint8_t rab_id; - RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem; - - rab_id = item->rAB_ID.buf[0]; - - LOGP(DIUCS, LOGL_NOTICE, - "Received RAB assignment event for %s rab_id=%hhd\n", - vlr_subscr_name(conn->vsub), rab_id); - - return 0; -} - -int iucs_rx_sec_mode_compl(struct gsm_subscriber_connection *conn, - RANAP_SecurityModeCompleteIEs_t *ies) -{ - OSMO_ASSERT(conn->via_ran == RAN_UTRAN_IU); - - /* TODO evalute ies */ - - msc_rx_sec_mode_compl(conn); - return 0; -} - -int iucs_rx_ranap_event(struct gsm_network *network, - struct ranap_ue_conn_ctx *ue_ctx, int type, void *data) -{ - struct gsm_subscriber_connection *conn; - - conn = subscr_conn_lookup_iu(network, ue_ctx); - - if (!conn) { - LOGP(DRANAP, LOGL_ERROR, "Cannot find subscriber for IU event %u\n", type); - return -1; - } - - switch (type) { - case RANAP_IU_EVENT_IU_RELEASE: - case RANAP_IU_EVENT_LINK_INVALIDATED: - LOGP(DIUCS, LOGL_INFO, "IuCS release for %s\n", - vlr_subscr_name(conn->vsub)); - msc_subscr_conn_close(conn, 0); - return 0; - - case RANAP_IU_EVENT_SECURITY_MODE_COMPLETE: - LOGP(DIUCS, LOGL_INFO, "IuCS security mode complete for %s\n", - vlr_subscr_name(conn->vsub)); - return iucs_rx_sec_mode_compl(conn, - (RANAP_SecurityModeCompleteIEs_t*)data); - case RANAP_IU_EVENT_RAB_ASSIGN: - return iucs_rx_rab_assign(conn, - (RANAP_RAB_SetupOrModifiedItemIEs_t*)data); - default: - LOGP(DIUCS, LOGL_NOTICE, "Unknown message received:" - " RANAP event: %i\n", type); - return -1; - } -} - -#endif /* BUILD_IU */ diff --git a/src/libmsc/meas_feed.c b/src/libmsc/meas_feed.c deleted file mode 100644 index 1e7b4cd51..000000000 --- a/src/libmsc/meas_feed.c +++ /dev/null @@ -1,168 +0,0 @@ -/* UDP-Feed of measurement reports */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "meas_feed.h" - -struct meas_feed_state { - struct osmo_wqueue wqueue; - char scenario[31+1]; - char *dst_host; - uint16_t dst_port; -}; - - -static struct meas_feed_state g_mfs; - -static int process_meas_rep(struct gsm_meas_rep *mr) -{ - struct msgb *msg; - struct meas_feed_meas *mfm; - struct vlr_subscr *vsub; - - /* ignore measurements as long as we don't know who it is */ - if (!mr->lchan || !mr->lchan->conn || !mr->lchan->conn->vsub) - return 0; - - vsub = mr->lchan->conn->vsub; - - msg = msgb_alloc(sizeof(struct meas_feed_meas), "Meas. Feed"); - if (!msg) - return 0; - - /* fill in the header */ - mfm = (struct meas_feed_meas *) msgb_put(msg, sizeof(*mfm)); - mfm->hdr.msg_type = MEAS_FEED_MEAS; - mfm->hdr.version = MEAS_FEED_VERSION; - - /* fill in MEAS_FEED_MEAS specific header */ - osmo_strlcpy(mfm->imsi, vsub->imsi, sizeof(mfm->imsi)); - osmo_strlcpy(mfm->name, vsub->name, sizeof(mfm->name)); - osmo_strlcpy(mfm->scenario, g_mfs.scenario, sizeof(mfm->scenario)); - - /* copy the entire measurement report */ - memcpy(&mfm->mr, mr, sizeof(mfm->mr)); - - /* copy channel information */ - /* we assume that the measurement report always belong to some timeslot */ - mfm->lchan_type = (uint8_t)mr->lchan->type; - mfm->pchan_type = (uint8_t)mr->lchan->ts->pchan; - mfm->bts_nr = mr->lchan->ts->trx->bts->nr; - mfm->trx_nr = mr->lchan->ts->trx->nr; - mfm->ts_nr = mr->lchan->ts->nr; - mfm->ss_nr = mr->lchan->nr; - - /* and send it to the socket */ - if (osmo_wqueue_enqueue(&g_mfs.wqueue, msg) != 0) - msgb_free(msg); - - return 0; -} - -static int meas_feed_sig_cb(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct lchan_signal_data *sdata = signal_data; - - if (subsys != SS_LCHAN) - return 0; - - if (signal == S_LCHAN_MEAS_REP) - process_meas_rep(sdata->mr); - - return 0; -} - -static int feed_write_cb(struct osmo_fd *ofd, struct msgb *msg) -{ - return write(ofd->fd, msgb_data(msg), msgb_length(msg)); -} - -static int feed_read_cb(struct osmo_fd *ofd) -{ - int rc; - char buf[256]; - - rc = read(ofd->fd, buf, sizeof(buf)); - ofd->fd &= ~BSC_FD_READ; - - return rc; -} - -int meas_feed_cfg_set(const char *dst_host, uint16_t dst_port) -{ - int rc; - int already_initialized = 0; - - if (g_mfs.wqueue.bfd.fd) - already_initialized = 1; - - - if (already_initialized && - !strcmp(dst_host, g_mfs.dst_host) && - dst_port == g_mfs.dst_port) - return 0; - - if (!already_initialized) { - osmo_wqueue_init(&g_mfs.wqueue, 10); - g_mfs.wqueue.write_cb = feed_write_cb; - g_mfs.wqueue.read_cb = feed_read_cb; - osmo_signal_register_handler(SS_LCHAN, meas_feed_sig_cb, NULL); - } - - if (already_initialized) { - osmo_wqueue_clear(&g_mfs.wqueue); - osmo_fd_unregister(&g_mfs.wqueue.bfd); - close(g_mfs.wqueue.bfd.fd); - /* don't set to zero, as that would mean 'not yet initialized' */ - g_mfs.wqueue.bfd.fd = -1; - } - rc = osmo_sock_init_ofd(&g_mfs.wqueue.bfd, AF_UNSPEC, SOCK_DGRAM, - IPPROTO_UDP, dst_host, dst_port, - OSMO_SOCK_F_CONNECT); - if (rc < 0) - return rc; - - g_mfs.wqueue.bfd.when &= ~BSC_FD_READ; - - if (g_mfs.dst_host) - talloc_free(g_mfs.dst_host); - g_mfs.dst_host = talloc_strdup(NULL, dst_host); - g_mfs.dst_port = dst_port; - - return 0; -} - -void meas_feed_cfg_get(char **host, uint16_t *port) -{ - *port = g_mfs.dst_port; - *host = g_mfs.dst_host; -} - -void meas_feed_scenario_set(const char *name) -{ - osmo_strlcpy(g_mfs.scenario, name, sizeof(g_mfs.scenario)); -} - -const char *meas_feed_scenario_get(void) -{ - return g_mfs.scenario; -} diff --git a/src/libmsc/meas_feed.h b/src/libmsc/meas_feed.h deleted file mode 100644 index 782a9616c..000000000 --- a/src/libmsc/meas_feed.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _INT_MEAS_FEED_H -#define _INT_MEAS_FEED_H - -#include - -int meas_feed_cfg_set(const char *dst_host, uint16_t dst_port); -void meas_feed_cfg_get(char **host, uint16_t *port); - -void meas_feed_scenario_set(const char *name); -const char *meas_feed_scenario_get(void); - -#endif /* _INT_MEAS_FEED_H */ diff --git a/src/libmsc/mncc.c b/src/libmsc/mncc.c deleted file mode 100644 index 8110eadca..000000000 --- a/src/libmsc/mncc.c +++ /dev/null @@ -1,107 +0,0 @@ -/* mncc.c - utility routines for the MNCC API between the 04.08 - * message parsing and the actual Call Control logic */ - -/* (C) 2008-2009 by Harald Welte - * (C) 2009 by Andreas Eversberg - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - - -static const struct value_string mncc_names[] = { - { MNCC_SETUP_REQ, "MNCC_SETUP_REQ" }, - { MNCC_SETUP_IND, "MNCC_SETUP_IND" }, - { MNCC_SETUP_RSP, "MNCC_SETUP_RSP" }, - { MNCC_SETUP_CNF, "MNCC_SETUP_CNF" }, - { MNCC_SETUP_COMPL_REQ, "MNCC_SETUP_COMPL_REQ" }, - { MNCC_SETUP_COMPL_IND, "MNCC_SETUP_COMPL_IND" }, - { MNCC_CALL_CONF_IND, "MNCC_CALL_CONF_IND" }, - { MNCC_CALL_PROC_REQ, "MNCC_CALL_PROC_REQ" }, - { MNCC_PROGRESS_REQ, "MNCC_PROGRESS_REQ" }, - { MNCC_ALERT_REQ, "MNCC_ALERT_REQ" }, - { MNCC_ALERT_IND, "MNCC_ALERT_IND" }, - { MNCC_NOTIFY_REQ, "MNCC_NOTIFY_REQ" }, - { MNCC_NOTIFY_IND, "MNCC_NOTIFY_IND" }, - { MNCC_DISC_REQ, "MNCC_DISC_REQ" }, - { MNCC_DISC_IND, "MNCC_DISC_IND" }, - { MNCC_REL_REQ, "MNCC_REL_REQ" }, - { MNCC_REL_IND, "MNCC_REL_IND" }, - { MNCC_REL_CNF, "MNCC_REL_CNF" }, - { MNCC_FACILITY_REQ, "MNCC_FACILITY_REQ" }, - { MNCC_FACILITY_IND, "MNCC_FACILITY_IND" }, - { MNCC_START_DTMF_IND, "MNCC_START_DTMF_IND" }, - { MNCC_START_DTMF_RSP, "MNCC_START_DTMF_RSP" }, - { MNCC_START_DTMF_REJ, "MNCC_START_DTMF_REJ" }, - { MNCC_STOP_DTMF_IND, "MNCC_STOP_DTMF_IND" }, - { MNCC_STOP_DTMF_RSP, "MNCC_STOP_DTMF_RSP" }, - { MNCC_MODIFY_REQ, "MNCC_MODIFY_REQ" }, - { MNCC_MODIFY_IND, "MNCC_MODIFY_IND" }, - { MNCC_MODIFY_RSP, "MNCC_MODIFY_RSP" }, - { MNCC_MODIFY_CNF, "MNCC_MODIFY_CNF" }, - { MNCC_MODIFY_REJ, "MNCC_MODIFY_REJ" }, - { MNCC_HOLD_IND, "MNCC_HOLD_IND" }, - { MNCC_HOLD_CNF, "MNCC_HOLD_CNF" }, - { MNCC_HOLD_REJ, "MNCC_HOLD_REJ" }, - { MNCC_RETRIEVE_IND, "MNCC_RETRIEVE_IND" }, - { MNCC_RETRIEVE_CNF, "MNCC_RETRIEVE_CNF" }, - { MNCC_RETRIEVE_REJ, "MNCC_RETRIEVE_REJ" }, - { MNCC_USERINFO_REQ, "MNCC_USERINFO_REQ" }, - { MNCC_USERINFO_IND, "MNCC_USERINFO_IND" }, - { MNCC_REJ_REQ, "MNCC_REJ_REQ" }, - { MNCC_REJ_IND, "MNCC_REJ_IND" }, - { MNCC_BRIDGE, "MNCC_BRIDGE" }, - { MNCC_FRAME_RECV, "MNCC_FRAME_RECV" }, - { MNCC_FRAME_DROP, "MNCC_FRAME_DROP" }, - { MNCC_LCHAN_MODIFY, "MNCC_LCHAN_MODIFY" }, - { MNCC_RTP_CREATE, "MNCC_RTP_CREATE" }, - { MNCC_RTP_CONNECT, "MNCC_RTP_CONNECT" }, - { MNCC_RTP_FREE, "MNCC_RTP_FREE" }, - { GSM_TCHF_FRAME, "GSM_TCHF_FRAME" }, - { GSM_TCHF_FRAME_EFR, "GSM_TCHF_FRAME_EFR" }, - { GSM_TCHH_FRAME, "GSM_TCHH_FRAME" }, - { GSM_TCH_FRAME_AMR, "GSM_TCH_FRAME_AMR" }, - { GSM_BAD_FRAME, "GSM_BAD_FRAME" }, - { 0, NULL }, -}; - -const char *get_mncc_name(int value) -{ - return get_value_string(mncc_names, value); -} - -void mncc_set_cause(struct gsm_mncc *data, int loc, int val) -{ - data->fields |= MNCC_F_CAUSE; - data->cause.location = loc; - data->cause.value = val; -} - diff --git a/src/libmsc/mncc_builtin.c b/src/libmsc/mncc_builtin.c deleted file mode 100644 index ac6e7345d..000000000 --- a/src/libmsc/mncc_builtin.c +++ /dev/null @@ -1,383 +0,0 @@ -/* mncc_builtin.c - default, minimal built-in MNCC Application for - * standalone bsc_hack (network-in-the-box mode) */ - -/* (C) 2008-2010 by Harald Welte - * (C) 2009 by Andreas Eversberg - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -void *tall_call_ctx; - -static LLIST_HEAD(call_list); - -static uint32_t new_callref = 0x00000001; - -struct mncc_int mncc_int = { - .def_codec = { GSM48_CMODE_SPEECH_V1, GSM48_CMODE_SPEECH_V1 }, -}; - -static void free_call(struct gsm_call *call) -{ - llist_del(&call->entry); - DEBUGP(DMNCC, "(call %x) Call removed.\n", call->callref); - talloc_free(call); -} - - -static struct gsm_call *get_call_ref(uint32_t callref) -{ - struct gsm_call *callt; - - llist_for_each_entry(callt, &call_list, entry) { - if (callt->callref == callref) - return callt; - } - return NULL; -} - -/* on incoming call, look up database and send setup to remote subscr. */ -static int mncc_setup_ind(struct gsm_call *call, int msg_type, - struct gsm_mncc *setup) -{ - struct gsm_mncc mncc; - struct gsm_call *remote; - - memset(&mncc, 0, sizeof(struct gsm_mncc)); - mncc.callref = call->callref; - - /* already have remote call */ - if (call->remote_ref) - return 0; - - /* transfer mode 1 would be packet mode, which was never specified */ - if (setup->bearer_cap.mode != 0) { - LOGP(DMNCC, LOGL_NOTICE, "(call %x) We don't support " - "packet mode\n", call->callref); - mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_BEARER_CA_UNAVAIL); - goto out_reject; - } - - /* we currently only do speech */ - if (setup->bearer_cap.transfer != GSM_MNCC_BCAP_SPEECH) { - LOGP(DMNCC, LOGL_NOTICE, "(call %x) We only support " - "voice calls\n", call->callref); - mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_BEARER_CA_UNAVAIL); - goto out_reject; - } - - /* create remote call */ - if (!(remote = talloc_zero(tall_call_ctx, struct gsm_call))) { - mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_RESOURCE_UNAVAIL); - goto out_reject; - } - llist_add_tail(&remote->entry, &call_list); - remote->net = call->net; - remote->callref = new_callref++; - DEBUGP(DMNCC, "(call %x) Creating new remote instance %x.\n", - call->callref, remote->callref); - - /* link remote call */ - call->remote_ref = remote->callref; - remote->remote_ref = call->callref; - - /* send call proceeding */ - memset(&mncc, 0, sizeof(struct gsm_mncc)); - mncc.callref = call->callref; - DEBUGP(DMNCC, "(call %x) Accepting call.\n", call->callref); - mncc_tx_to_cc(call->net, MNCC_CALL_PROC_REQ, &mncc); - - /* modify mode */ - memset(&mncc, 0, sizeof(struct gsm_mncc)); - mncc.callref = call->callref; - DEBUGP(DMNCC, "(call %x) Modify channel mode\n", call->callref); - mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, &mncc); - - /* send setup to remote */ -// setup->fields |= MNCC_F_SIGNAL; -// setup->signal = GSM48_SIGNAL_DIALTONE; - setup->callref = remote->callref; - DEBUGP(DMNCC, "(call %x) Forwarding SETUP to remote.\n", call->callref); - return mncc_tx_to_cc(remote->net, MNCC_SETUP_REQ, setup); - -out_reject: - mncc_tx_to_cc(call->net, MNCC_REJ_REQ, &mncc); - free_call(call); - return 0; -} - -static int mncc_alert_ind(struct gsm_call *call, int msg_type, - struct gsm_mncc *alert) -{ - struct gsm_call *remote; - - /* send alerting to remote */ - if (!(remote = get_call_ref(call->remote_ref))) - return 0; - alert->callref = remote->callref; - DEBUGP(DMNCC, "(call %x) Forwarding ALERT to remote.\n", call->callref); - return mncc_tx_to_cc(remote->net, MNCC_ALERT_REQ, alert); -} - -static int mncc_notify_ind(struct gsm_call *call, int msg_type, - struct gsm_mncc *notify) -{ - struct gsm_call *remote; - - /* send notify to remote */ - if (!(remote = get_call_ref(call->remote_ref))) - return 0; - notify->callref = remote->callref; - DEBUGP(DMNCC, "(call %x) Forwarding NOTIF to remote.\n", call->callref); - return mncc_tx_to_cc(remote->net, MNCC_NOTIFY_REQ, notify); -} - -static int mncc_setup_cnf(struct gsm_call *call, int msg_type, - struct gsm_mncc *connect) -{ - struct gsm_mncc connect_ack, frame_recv; - struct gsm_network *net = call->net; - struct gsm_call *remote; - struct gsm_mncc_bridge bridge = { .msg_type = MNCC_BRIDGE }; - - /* acknowledge connect */ - memset(&connect_ack, 0, sizeof(struct gsm_mncc)); - connect_ack.callref = call->callref; - DEBUGP(DMNCC, "(call %x) Acknowledge SETUP.\n", call->callref); - mncc_tx_to_cc(call->net, MNCC_SETUP_COMPL_REQ, &connect_ack); - - /* send connect message to remote */ - if (!(remote = get_call_ref(call->remote_ref))) - return 0; - connect->callref = remote->callref; - DEBUGP(DMNCC, "(call %x) Sending CONNECT to remote.\n", call->callref); - mncc_tx_to_cc(remote->net, MNCC_SETUP_RSP, connect); - - /* bridge tch */ - bridge.callref[0] = call->callref; - bridge.callref[1] = call->remote_ref; - DEBUGP(DMNCC, "(call %x) Bridging with remote.\n", call->callref); - - /* proxy mode */ - if (!net->handover.active) { - /* in the no-handover case, we can bridge, i.e. use - * the old RTP proxy code */ - return mncc_tx_to_cc(call->net, MNCC_BRIDGE, &bridge); - } else { - /* in case of handover, we need to re-write the RTP - * SSRC, sequence and timestamp values and thus - * need to enable RTP receive for both directions */ - memset(&frame_recv, 0, sizeof(struct gsm_mncc)); - frame_recv.callref = call->callref; - mncc_tx_to_cc(call->net, MNCC_FRAME_RECV, &frame_recv); - frame_recv.callref = call->remote_ref; - return mncc_tx_to_cc(call->net, MNCC_FRAME_RECV, &frame_recv); - } -} - -static int mncc_disc_ind(struct gsm_call *call, int msg_type, - struct gsm_mncc *disc) -{ - struct gsm_call *remote; - - /* send release */ - DEBUGP(DMNCC, "(call %x) Releasing call with cause %d\n", - call->callref, disc->cause.value); - mncc_tx_to_cc(call->net, MNCC_REL_REQ, disc); - - /* send disc to remote */ - if (!(remote = get_call_ref(call->remote_ref))) { - return 0; - } - disc->callref = remote->callref; - DEBUGP(DMNCC, "(call %x) Disconnecting remote with cause %d\n", - remote->callref, disc->cause.value); - return mncc_tx_to_cc(remote->net, MNCC_DISC_REQ, disc); -} - -static int mncc_rel_ind(struct gsm_call *call, int msg_type, struct gsm_mncc *rel) -{ - struct gsm_call *remote; - - /* send release to remote */ - if (!(remote = get_call_ref(call->remote_ref))) { - free_call(call); - return 0; - } - - rel->callref = remote->callref; - DEBUGP(DMNCC, "(call %x) Releasing remote with cause %d\n", - call->callref, rel->cause.value); - - /* - * Release this side of the call right now. Otherwise we end up - * in this method for the other call and will also try to release - * it and then we will end up with a double free and a crash - */ - free_call(call); - mncc_tx_to_cc(remote->net, MNCC_REL_REQ, rel); - - return 0; -} - -static int mncc_rel_cnf(struct gsm_call *call, int msg_type, struct gsm_mncc *rel) -{ - free_call(call); - return 0; -} - -/* Internal MNCC handler input function (from CC -> MNCC -> here) */ -int int_mncc_recv(struct gsm_network *net, struct msgb *msg) -{ - void *arg = msgb_data(msg); - struct gsm_mncc *data = arg; - int msg_type = data->msg_type; - int callref; - struct gsm_call *call = NULL, *callt; - int rc = 0; - - /* Special messages */ - switch(msg_type) { - } - - /* find callref */ - callref = data->callref; - llist_for_each_entry(callt, &call_list, entry) { - if (callt->callref == callref) { - call = callt; - break; - } - } - - /* create callref, if setup is received */ - if (!call) { - if (msg_type != MNCC_SETUP_IND) - goto out_free; /* drop */ - /* create call */ - if (!(call = talloc_zero(tall_call_ctx, struct gsm_call))) { - struct gsm_mncc rel; - - memset(&rel, 0, sizeof(struct gsm_mncc)); - rel.callref = callref; - mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_RESOURCE_UNAVAIL); - mncc_tx_to_cc(net, MNCC_REL_REQ, &rel); - goto out_free; - } - llist_add_tail(&call->entry, &call_list); - call->net = net; - call->callref = callref; - DEBUGP(DMNCC, "(call %x) Call created.\n", call->callref); - } - - if (mncc_is_data_frame(msg_type)) { - LOGP(DMNCC, LOGL_ERROR, "(call %x) Received data frame, which is not supported.\n", - call->callref); - goto out_free; - } - - DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref, - get_mncc_name(msg_type)); - - switch(msg_type) { - case MNCC_SETUP_IND: - rc = mncc_setup_ind(call, msg_type, arg); - break; - case MNCC_SETUP_CNF: - rc = mncc_setup_cnf(call, msg_type, arg); - break; - case MNCC_SETUP_COMPL_IND: - break; - case MNCC_CALL_CONF_IND: - /* we now need to MODIFY the channel */ - mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, data); - break; - case MNCC_ALERT_IND: - rc = mncc_alert_ind(call, msg_type, arg); - break; - case MNCC_NOTIFY_IND: - rc = mncc_notify_ind(call, msg_type, arg); - break; - case MNCC_DISC_IND: - rc = mncc_disc_ind(call, msg_type, arg); - break; - case MNCC_REL_IND: - case MNCC_REJ_IND: - rc = mncc_rel_ind(call, msg_type, arg); - break; - case MNCC_REL_CNF: - rc = mncc_rel_cnf(call, msg_type, arg); - break; - case MNCC_FACILITY_IND: - break; - case MNCC_START_DTMF_IND: - rc = mncc_tx_to_cc(net, MNCC_START_DTMF_REJ, data); - break; - case MNCC_STOP_DTMF_IND: - rc = mncc_tx_to_cc(net, MNCC_STOP_DTMF_RSP, data); - break; - case MNCC_MODIFY_IND: - mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_SERV_OPT_UNIMPL); - DEBUGP(DMNCC, "(call %x) Rejecting MODIFY with cause %d\n", - call->callref, data->cause.value); - rc = mncc_tx_to_cc(net, MNCC_MODIFY_REJ, data); - break; - case MNCC_MODIFY_CNF: - break; - case MNCC_HOLD_IND: - mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_SERV_OPT_UNIMPL); - DEBUGP(DMNCC, "(call %x) Rejecting HOLD with cause %d\n", - call->callref, data->cause.value); - rc = mncc_tx_to_cc(net, MNCC_HOLD_REJ, data); - break; - case MNCC_RETRIEVE_IND: - mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_SERV_OPT_UNIMPL); - DEBUGP(DMNCC, "(call %x) Rejecting RETRIEVE with cause %d\n", - call->callref, data->cause.value); - rc = mncc_tx_to_cc(net, MNCC_RETRIEVE_REJ, data); - break; - default: - LOGP(DMNCC, LOGL_NOTICE, "(call %x) Message unhandled\n", callref); - break; - } - -out_free: - msgb_free(msg); - - return rc; -} diff --git a/src/libmsc/mncc_sock.c b/src/libmsc/mncc_sock.c deleted file mode 100644 index 0c696f2d9..000000000 --- a/src/libmsc/mncc_sock.c +++ /dev/null @@ -1,317 +0,0 @@ -/* mncc_sock.c: Tie the MNCC interface to a unix domain socket */ - -/* (C) 2008-2010 by Harald Welte - * (C) 2009 by Andreas Eversberg - * (C) 2012 by Holger Hans Peter Freyther - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -struct mncc_sock_state { - struct gsm_network *net; - struct osmo_fd listen_bfd; /* fd for listen socket */ - struct osmo_fd conn_bfd; /* fd for connection to lcr */ -}; - -/* input from CC code into mncc_sock */ -int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg) -{ - struct gsm_mncc *mncc_in = (struct gsm_mncc *) msgb_data(msg); - int msg_type = mncc_in->msg_type; - - /* Check if we currently have a MNCC handler connected */ - if (net->mncc_state->conn_bfd.fd < 0) { - LOGP(DMNCC, LOGL_ERROR, "mncc_sock receives %s for external CC app " - "but socket is gone\n", get_mncc_name(msg_type)); - if (!mncc_is_data_frame(msg_type)) { - /* release the request */ - struct gsm_mncc mncc_out; - memset(&mncc_out, 0, sizeof(mncc_out)); - mncc_out.callref = mncc_in->callref; - mncc_set_cause(&mncc_out, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_TEMP_FAILURE); - mncc_tx_to_cc(net, MNCC_REL_REQ, &mncc_out); - } - /* free the original message */ - msgb_free(msg); - return -1; - } - - /* FIXME: check for some maximum queue depth? */ - - /* Actually enqueue the message and mark socket write need */ - msgb_enqueue(&net->upqueue, msg); - net->mncc_state->conn_bfd.when |= BSC_FD_WRITE; - return 0; -} - -static void mncc_sock_close(struct mncc_sock_state *state) -{ - struct osmo_fd *bfd = &state->conn_bfd; - - LOGP(DMNCC, LOGL_NOTICE, "MNCC Socket has LOST connection\n"); - - close(bfd->fd); - bfd->fd = -1; - osmo_fd_unregister(bfd); - - /* re-enable the generation of ACCEPT for new connections */ - state->listen_bfd.when |= BSC_FD_READ; - - /* release all exisitng calls */ - gsm0408_clear_all_trans(state->net, GSM48_PDISC_CC); - - /* flush the queue */ - while (!llist_empty(&state->net->upqueue)) { - struct msgb *msg = msgb_dequeue(&state->net->upqueue); - msgb_free(msg); - } -} - -static int mncc_sock_read(struct osmo_fd *bfd) -{ - struct mncc_sock_state *state = (struct mncc_sock_state *)bfd->data; - struct gsm_mncc *mncc_prim; - struct msgb *msg; - int rc; - - msg = msgb_alloc(sizeof(*mncc_prim)+256, "mncc_sock_rx"); - if (!msg) - return -ENOMEM; - - mncc_prim = (struct gsm_mncc *) msg->tail; - - rc = recv(bfd->fd, msg->tail, msgb_tailroom(msg), 0); - if (rc == 0) - goto close; - - if (rc < 0) { - if (errno == EAGAIN) - return 0; - goto close; - } - - rc = mncc_tx_to_cc(state->net, mncc_prim->msg_type, mncc_prim); - - /* as we always synchronously process the message in mncc_send() and - * its callbacks, we can free the message here. */ - msgb_free(msg); - - return rc; - -close: - msgb_free(msg); - mncc_sock_close(state); - return -1; -} - -static int mncc_sock_write(struct osmo_fd *bfd) -{ - struct mncc_sock_state *state = bfd->data; - struct gsm_network *net = state->net; - int rc; - - while (!llist_empty(&net->upqueue)) { - struct msgb *msg, *msg2; - struct gsm_mncc *mncc_prim; - - /* peek at the beginning of the queue */ - msg = llist_entry(net->upqueue.next, struct msgb, list); - mncc_prim = (struct gsm_mncc *)msg->data; - - bfd->when &= ~BSC_FD_WRITE; - - /* bug hunter 8-): maybe someone forgot msgb_put(...) ? */ - if (!msgb_length(msg)) { - LOGP(DMNCC, LOGL_ERROR, "message type (%d) with ZERO " - "bytes!\n", mncc_prim->msg_type); - goto dontsend; - } - - /* try to send it over the socket */ - rc = write(bfd->fd, msgb_data(msg), msgb_length(msg)); - if (rc == 0) - goto close; - if (rc < 0) { - if (errno == EAGAIN) { - bfd->when |= BSC_FD_WRITE; - break; - } - goto close; - } - -dontsend: - /* _after_ we send it, we can deueue */ - msg2 = msgb_dequeue(&net->upqueue); - assert(msg == msg2); - msgb_free(msg); - } - return 0; - -close: - mncc_sock_close(state); - - return -1; -} - -static int mncc_sock_cb(struct osmo_fd *bfd, unsigned int flags) -{ - int rc = 0; - - if (flags & BSC_FD_READ) - rc = mncc_sock_read(bfd); - if (rc < 0) - return rc; - - if (flags & BSC_FD_WRITE) - rc = mncc_sock_write(bfd); - - return rc; -} - -/** - * Send a version indication to the remote. - */ -static void queue_hello(struct mncc_sock_state *mncc) -{ - struct gsm_mncc_hello *hello; - struct msgb *msg; - - msg = msgb_alloc(512, "mncc hello"); - if (!msg) { - LOGP(DMNCC, LOGL_ERROR, "Failed to allocate hello.\n"); - mncc_sock_close(mncc); - return; - } - - hello = (struct gsm_mncc_hello *) msgb_put(msg, sizeof(*hello)); - hello->msg_type = MNCC_SOCKET_HELLO; - hello->version = MNCC_SOCK_VERSION; - hello->mncc_size = sizeof(struct gsm_mncc); - hello->data_frame_size = sizeof(struct gsm_data_frame); - hello->called_offset = offsetof(struct gsm_mncc, called); - hello->signal_offset = offsetof(struct gsm_mncc, signal); - hello->emergency_offset = offsetof(struct gsm_mncc, emergency); - - msgb_enqueue(&mncc->net->upqueue, msg); - mncc->conn_bfd.when |= BSC_FD_WRITE; -} - -/* accept a new connection */ -static int mncc_sock_accept(struct osmo_fd *bfd, unsigned int flags) -{ - struct mncc_sock_state *state = (struct mncc_sock_state *)bfd->data; - struct osmo_fd *conn_bfd = &state->conn_bfd; - struct sockaddr_un un_addr; - socklen_t len; - int rc; - - len = sizeof(un_addr); - rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len); - if (rc < 0) { - LOGP(DMNCC, LOGL_ERROR, "Failed to accept a new connection\n"); - return -1; - } - - if (conn_bfd->fd >= 0) { - LOGP(DMNCC, LOGL_NOTICE, "MNCC app connects but we already have " - "another active connection ?!?\n"); - /* We already have one MNCC app connected, this is all we support */ - state->listen_bfd.when &= ~BSC_FD_READ; - close(rc); - return 0; - } - - conn_bfd->fd = rc; - conn_bfd->when = BSC_FD_READ; - conn_bfd->cb = mncc_sock_cb; - conn_bfd->data = state; - - if (osmo_fd_register(conn_bfd) != 0) { - LOGP(DMNCC, LOGL_ERROR, "Failed to register new connection fd\n"); - close(conn_bfd->fd); - conn_bfd->fd = -1; - return -1; - } - - LOGP(DMNCC, LOGL_NOTICE, "MNCC Socket has connection with external " - "call control application\n"); - - queue_hello(state); - return 0; -} - - -int mncc_sock_init(struct gsm_network *net, const char *sock_path) -{ - struct mncc_sock_state *state; - struct osmo_fd *bfd; - int rc; - - state = talloc_zero(tall_bsc_ctx, struct mncc_sock_state); - if (!state) - return -ENOMEM; - - state->net = net; - state->conn_bfd.fd = -1; - - bfd = &state->listen_bfd; - - bfd->fd = osmo_sock_unix_init(SOCK_SEQPACKET, 0, sock_path, - OSMO_SOCK_F_BIND); - if (bfd->fd < 0) { - LOGP(DMNCC, LOGL_ERROR, "Could not create unix socket: %s: %s\n", - sock_path, strerror(errno)); - talloc_free(state); - return -1; - } - - bfd->when = BSC_FD_READ; - bfd->cb = mncc_sock_accept; - bfd->data = state; - - rc = osmo_fd_register(bfd); - if (rc < 0) { - LOGP(DMNCC, LOGL_ERROR, "Could not register listen fd: %d\n", rc); - close(bfd->fd); - talloc_free(state); - return rc; - } - - net->mncc_state = state; - - LOGP(DMNCC, LOGL_NOTICE, "MNCC socket at %s\n", sock_path); - return 0; -} diff --git a/src/libmsc/msc_ifaces.c b/src/libmsc/msc_ifaces.c deleted file mode 100644 index 161a10019..000000000 --- a/src/libmsc/msc_ifaces.c +++ /dev/null @@ -1,423 +0,0 @@ -/* Implementation for MSC decisions which interface to send messages out on. */ - -/* (C) 2016 by sysmocom s.m.f.c GmbH - * - * All Rights Reserved - * - * 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 Affero 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 . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../bscconfig.h" - -#ifdef BUILD_IU -#include -extern struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, - uint32_t rtp_ip, - uint16_t rtp_port, - bool use_x213_nsap); -#else -#include -#endif /* BUILD_IU */ - -static int msc_tx(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - if (!conn) - return -EINVAL; - if (!msg) - return -EINVAL; - - DEBUGP(DMSC, "msc_tx %u bytes to %s via %s\n", - msg->len, vlr_subscr_name(conn->vsub), - ran_type_name(conn->via_ran)); - switch (conn->via_ran) { - case RAN_GERAN_A: - msg->dst = conn; - return a_iface_tx_dtap(msg); - - case RAN_UTRAN_IU: - msg->dst = conn->iu.ue_ctx; - return ranap_iu_tx(msg, 0); - - default: - LOGP(DMSC, LOGL_ERROR, - "msc_tx(): conn->via_ran invalid (%d)\n", - conn->via_ran); - return -1; - } -} - - -int msc_tx_dtap(struct gsm_subscriber_connection *conn, - struct msgb *msg) -{ - return msc_tx(conn, msg); -} - - -/* 9.2.5 CM service accept */ -int msc_gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) -{ - struct msgb *msg; - struct gsm48_hdr *gh; - - if (!conn) - return -EINVAL; - - msg = gsm48_msgb_alloc_name("GSM 04.08 SERV ACC"); - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_MM; - gh->msg_type = GSM48_MT_MM_CM_SERV_ACC; - - DEBUGP(DMM, "-> CM SERVICE ACCEPT %s\n", - vlr_subscr_name(conn->vsub)); - - return msc_tx_dtap(conn, msg); -} - -/* 9.2.6 CM service reject */ -int msc_gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, - enum gsm48_reject_value value) -{ - struct msgb *msg; - - if (!conn) - return -EINVAL; - - conn->received_cm_service_request = false; - - msg = gsm48_create_mm_serv_rej(value); - if (!msg) { - LOGP(DMM, LOGL_ERROR, "Failed to allocate CM Service Reject.\n"); - return -1; - } - - DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value); - - return msc_tx_dtap(conn, msg); -} - -int msc_tx_common_id(struct gsm_subscriber_connection *conn) -{ - if (!conn) - return -EINVAL; - - /* Common ID is only sent over IuCS */ - if (conn->via_ran != RAN_UTRAN_IU) { - LOGP(DMM, LOGL_INFO, - "%s: Asked to transmit Common ID, but skipping" - " because this is not on UTRAN\n", - vlr_subscr_name(conn->vsub)); - return 0; - } - - DEBUGP(DIUCS, "%s: tx CommonID %s\n", - vlr_subscr_name(conn->vsub), conn->vsub->imsi); - return ranap_iu_tx_common_id(conn->iu.ue_ctx, conn->vsub->imsi); -} - -static int iu_rab_act_cs(struct ranap_ue_conn_ctx *uectx, uint8_t rab_id, - uint32_t rtp_ip, uint16_t rtp_port) -{ -#ifdef BUILD_IU - struct msgb *msg; - bool use_x213_nsap; - uint32_t conn_id = uectx->conn_id; - - use_x213_nsap = (uectx->rab_assign_addr_enc == RANAP_NSAP_ADDR_ENC_X213); - - LOGP(DIUCS, LOGL_DEBUG, "Assigning RAB: conn_id=%u, rab_id=%d," - " rtp=%x:%u, use_x213_nsap=%d\n", conn_id, rab_id, rtp_ip, - rtp_port, use_x213_nsap); - - msg = ranap_new_msg_rab_assign_voice(rab_id, rtp_ip, rtp_port, - use_x213_nsap); - msg->l2h = msg->data; - - if (ranap_iu_rab_act(uectx, msg)) - LOGP(DIUCS, LOGL_ERROR, "Failed to send RAB Assignment:" - " conn_id=%d rab_id=%d rtp=%x:%u\n", - conn_id, rab_id, rtp_ip, rtp_port); - return 0; -#else - LOGP(DMSC, LOGL_ERROR, "Cannot send Iu RAB Assignment: built without Iu support\n"); - return -ENOTSUP; -#endif -} - -static void mgcp_response_rab_act_cs_crcx(struct mgcp_response *r, void *priv) -{ - struct gsm_trans *trans = priv; - struct gsm_subscriber_connection *conn = trans->conn; - uint32_t rtp_ip; - int rc; - - if (r->head.response_code != 200) { - LOGP(DMGCP, LOGL_ERROR, - "MGCPGW response yields error: %d %s\n", - r->head.response_code, r->head.comment); - goto rab_act_cs_error; - } - - rc = mgcp_response_parse_params(r); - if (rc) { - LOGP(DMGCP, LOGL_ERROR, - "Cannot parse MGCP response, for %s\n", - vlr_subscr_name(trans->vsub)); - goto rab_act_cs_error; - } - - conn->rtp.port_cn = r->audio_port; - - rtp_ip = mgcpgw_client_remote_addr_n(conn->network->mgcpgw.client); - - if (trans->conn->via_ran == RAN_UTRAN_IU) { - /* Assign a voice channel via RANAP on 3G */ - if (iu_rab_act_cs(conn->iu.ue_ctx, conn->iu.rab_id, rtp_ip, conn->rtp.port_subscr)) - goto rab_act_cs_error; - } else if (trans->conn->via_ran == RAN_GERAN_A) { - /* Assign a voice channel via A on 2G */ - if (a_iface_tx_assignment(trans)) - goto rab_act_cs_error; - } else - goto rab_act_cs_error; - - /* Respond back to MNCC (if requested) */ - if (trans->tch_rtp_create) { - if (gsm48_tch_rtp_create(trans)) - goto rab_act_cs_error; - } - return; - -rab_act_cs_error: - /* FIXME abort call, invalidate conn, ... */ - LOGP(DMSC, LOGL_ERROR, "%s: failure during assignment\n", - vlr_subscr_name(trans->vsub)); - return; -} - -int msc_call_assignment(struct gsm_trans *trans) -{ - struct gsm_subscriber_connection *conn; - struct mgcpgw_client *mgcp; - struct msgb *msg; - uint16_t bts_base; - - if (!trans) - return -EINVAL; - if (!trans->conn) - return -EINVAL; - - conn = trans->conn; - mgcp = conn->network->mgcpgw.client; - -#ifdef BUILD_IU - /* FIXME: HACK. where to scope the RAB Id? At the conn / subscriber / ranap_ue_conn_ctx? */ - static uint8_t next_iu_rab_id = 1; - if (conn->via_ran == RAN_UTRAN_IU) - conn->iu.rab_id = next_iu_rab_id ++; -#endif - - conn->rtp.mgcp_rtp_endpoint = - mgcpgw_client_next_endpoint(conn->network->mgcpgw.client); - - /* This will calculate the port we assign to the BTS via AoIP - * assignment command (or rab-assignment on 3G) The BTS will send - * its RTP traffic to that port on the MGCPGW side. The MGCPGW only - * gets the endpoint ID via the CRCX. It will do the same calculation - * on his side too to get knowledge of the rtp port. */ - bts_base = mgcpgw_client_conf_actual(mgcp)->bts_base; - conn->rtp.port_subscr = bts_base + 2 * conn->rtp.mgcp_rtp_endpoint; - - /* Establish the RTP stream first as looping back to the originator. - * The MDCX will patch through to the counterpart. TODO: play a ring - * tone instead. */ - msg = mgcp_msg_crcx(mgcp, conn->rtp.mgcp_rtp_endpoint, - conn->rtp.mgcp_rtp_endpoint, MGCP_CONN_LOOPBACK); - return mgcpgw_client_tx(mgcp, msg, mgcp_response_rab_act_cs_crcx, trans); -} - -static void mgcp_response_bridge_mdcx(struct mgcp_response *r, void *priv); - -static void mgcp_bridge(struct gsm_trans *from, struct gsm_trans *to, - enum bridge_state state, - enum mgcp_connection_mode mode) -{ - struct gsm_subscriber_connection *conn1 = from->conn; - struct gsm_subscriber_connection *conn2 = to->conn; - struct mgcpgw_client *mgcp = conn1->network->mgcpgw.client; - const char *ip; - struct msgb *msg; - - OSMO_ASSERT(mgcp); - - from->bridge.peer = to; - from->bridge.state = state; - - /* Loop back to the same MGCP GW */ - ip = mgcpgw_client_remote_addr_str(mgcp); - - msg = mgcp_msg_mdcx(mgcp, - conn1->rtp.mgcp_rtp_endpoint, - ip, conn2->rtp.port_cn, - mode); - if (mgcpgw_client_tx(mgcp, msg, mgcp_response_bridge_mdcx, from)) - LOGP(DMGCP, LOGL_ERROR, - "Failed to send MDCX message for %s\n", - vlr_subscr_name(from->vsub)); -} - -static void mgcp_response_bridge_mdcx(struct mgcp_response *r, void *priv) -{ - struct gsm_trans *trans = priv; - struct gsm_trans *peer = trans->bridge.peer; - - switch (trans->bridge.state) { - case BRIDGE_STATE_LOOPBACK_PENDING: - trans->bridge.state = BRIDGE_STATE_LOOPBACK_ESTABLISHED; - - switch (peer->bridge.state) { - case BRIDGE_STATE_LOOPBACK_PENDING: - /* Wait until the other is done as well. */ - return; - case BRIDGE_STATE_LOOPBACK_ESTABLISHED: - /* Now that both are in loopback, switch both to - * forwarding. */ - mgcp_bridge(trans, peer, BRIDGE_STATE_BRIDGE_PENDING, - MGCP_CONN_RECV_SEND); - mgcp_bridge(peer, trans, BRIDGE_STATE_BRIDGE_PENDING, - MGCP_CONN_RECV_SEND); - break; - default: - LOGP(DMGCP, LOGL_ERROR, - "Unexpected bridge state: %d for %s\n", - trans->bridge.state, vlr_subscr_name(trans->vsub)); - break; - } - break; - - case BRIDGE_STATE_BRIDGE_PENDING: - trans->bridge.state = BRIDGE_STATE_BRIDGE_ESTABLISHED; - break; - - default: - LOGP(DMGCP, LOGL_ERROR, - "Unexpected bridge state: %d for %s\n", - trans->bridge.state, vlr_subscr_name(trans->vsub)); - break; - } -} - -int msc_call_connect(struct gsm_trans *trans, uint16_t port, uint32_t ip) -{ - /* With this function we inform the MGCP-GW where (ip/port) it - * has to send its outgoing voic traffic. The receiving end will - * usually be a PBX (e.g. Asterisk). The IP-Address we tell, will - * not only be used to direct the traffic, it will also be used - * as a filter to make sure only RTP packets from the right - * remote end will reach the BSS. This is also the reason why - * inbound audio will not work until this step is performed */ - - /* NOTE: This function is used when msc_call_bridge(), is not - * applicable. This is usually the case when an external MNCC - * is in use */ - - struct gsm_subscriber_connection *conn; - struct mgcpgw_client *mgcp; - struct msgb *msg; - - if (!trans) - return -EINVAL; - if (!trans->conn) - return -EINVAL; - if (!trans->conn->network) - return -EINVAL; - if (!trans->conn->network->mgcpgw.client) - return -EINVAL; - - mgcp = trans->conn->network->mgcpgw.client; - - struct in_addr ip_addr; - ip_addr.s_addr = ntohl(ip); - - conn = trans->conn; - - msg = mgcp_msg_mdcx(mgcp, - conn->rtp.mgcp_rtp_endpoint, - inet_ntoa(ip_addr), port, MGCP_CONN_RECV_SEND); - if (mgcpgw_client_tx(mgcp, msg, NULL, trans)) - LOGP(DMGCP, LOGL_ERROR, - "Failed to send MDCX message for %s\n", - vlr_subscr_name(trans->vsub)); - - return 0; -} - -int msc_call_bridge(struct gsm_trans *trans1, struct gsm_trans *trans2) -{ - if (!trans1) - return -EINVAL; - if (!trans2) - return -EINVAL; - - /* First setup as loopback and configure the counterparts' endpoints, - * so that when transmission starts the originating addresses are - * already known to be valid. The mgcp callback will continue. */ - mgcp_bridge(trans1, trans2, BRIDGE_STATE_LOOPBACK_PENDING, - MGCP_CONN_LOOPBACK); - mgcp_bridge(trans2, trans1, BRIDGE_STATE_LOOPBACK_PENDING, - MGCP_CONN_LOOPBACK); - - return 0; -} - -void msc_call_release(struct gsm_trans *trans) -{ - struct msgb *msg; - struct gsm_subscriber_connection *conn; - struct mgcpgw_client *mgcp; - - if (!trans) - return; - if (!trans->conn) - return; - if (!trans->conn->network) - return; - - conn = trans->conn; - mgcp = conn->network->mgcpgw.client; - - /* Send DLCX */ - msg = mgcp_msg_dlcx(mgcp, conn->rtp.mgcp_rtp_endpoint, - conn->rtp.mgcp_rtp_endpoint); - if (mgcpgw_client_tx(mgcp, msg, NULL, NULL)) - LOGP(DMGCP, LOGL_ERROR, - "Failed to send DLCX message for %s\n", - vlr_subscr_name(trans->vsub)); - - /* Release endpoint id */ - mgcpgw_client_release_endpoint(conn->rtp.mgcp_rtp_endpoint, mgcp); -} diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c deleted file mode 100644 index 50679aa01..000000000 --- a/src/libmsc/msc_vty.c +++ /dev/null @@ -1,162 +0,0 @@ -/* MSC interface to quagga VTY */ -/* (C) 2016 by sysmocom s.m.f.c. GmbH - * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c) - * (C) 2009 by Harald Welte - * (C) 2009-2011 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -/* NOTE: I would have liked to call this the MSC_NODE instead of the MSC_NODE, - * but MSC_NODE already exists to configure a remote MSC for osmo-bsc. */ - -#include "../../bscconfig.h" - -#include - -#include -#ifdef BUILD_IU -#include -#endif - -#include -#include -#include -#include - -static struct cmd_node msc_node = { - MSC_NODE, - "%s(config-msc)# ", - 1, -}; - -DEFUN(cfg_msc, cfg_msc_cmd, - "msc", "Configure MSC options") -{ - vty->node = MSC_NODE; - return CMD_SUCCESS; -} - -DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd, - "assign-tmsi", - "Assign TMSI during Location Updating.\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - gsmnet->vlr->cfg.assign_tmsi = true; - return CMD_SUCCESS; -} - -DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd, - "no assign-tmsi", - NO_STR "Assign TMSI during Location Updating.\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - gsmnet->vlr->cfg.assign_tmsi = false; - return CMD_SUCCESS; -} - -DEFUN(cfg_msc_cs7_instance_a, - cfg_msc_cs7_instance_a_cmd, - "cs7-instance-a <0-15>", - "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - gsmnet->a.cs7_instance = atoi(argv[0]); - return CMD_SUCCESS; -} - -DEFUN(cfg_msc_cs7_instance_iu, - cfg_msc_cs7_instance_iu_cmd, - "cs7-instance-iu <0-15>", - "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - gsmnet->iu.cs7_instance = atoi(argv[0]); - return CMD_SUCCESS; -} - -static int config_write_msc(struct vty *vty) -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - - vty_out(vty, "msc%s", VTY_NEWLINE); - vty_out(vty, " %sassign-tmsi%s", - gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE); - - vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance, - VTY_NEWLINE); - vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance, - VTY_NEWLINE); - - mgcpgw_client_config_write(vty, " "); -#ifdef BUILD_IU - ranap_iu_vty_config_write(vty, " "); -#endif - - return CMD_SUCCESS; -} - -static int config_write_net(struct vty *vty) -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - - vty_out(vty, "network%s", VTY_NEWLINE); - vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE); - vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE); - vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE); - vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE); - vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE); - vty_out(vty, " location updating reject cause %u%s", - gsmnet->reject_cause, VTY_NEWLINE); - vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE); - vty_out(vty, " rrlp mode %s%s", rrlp_mode_name(gsmnet->rrlp.mode), - VTY_NEWLINE); - vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE); - if (gsmnet->tz.override != 0) { - if (gsmnet->tz.dst) - vty_out(vty, " timezone %d %d %d%s", - gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst, - VTY_NEWLINE); - else - vty_out(vty, " timezone %d %d%s", - gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE); - } - if (gsmnet->t3212 == 0) - vty_out(vty, " no periodic location update%s", VTY_NEWLINE); - else - vty_out(vty, " periodic location update %u%s", - gsmnet->t3212 * 6, VTY_NEWLINE); - - return CMD_SUCCESS; -} - -void msc_vty_init(struct gsm_network *msc_network) -{ - common_cs_vty_init(msc_network, config_write_net); - - install_element(CONFIG_NODE, &cfg_msc_cmd); - install_node(&msc_node, config_write_msc); - vty_install_default(MSC_NODE); - install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd); - install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd); - install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd); - install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd); - - mgcpgw_client_vty_init(msc_network, MSC_NODE, &msc_network->mgcpgw.conf); -#ifdef BUILD_IU - ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc); -#endif -} diff --git a/src/libmsc/osmo_msc.c b/src/libmsc/osmo_msc.c deleted file mode 100644 index 4d24f22a6..000000000 --- a/src/libmsc/osmo_msc.c +++ /dev/null @@ -1,387 +0,0 @@ -/* main MSC management code... */ - -/* - * (C) 2010,2013 by Holger Hans Peter Freyther - * (C) 2010 by On-Waves - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../../bscconfig.h" -#ifdef BUILD_IU -#include -#else -#include -#endif - -/* Receive a SAPI-N-REJECT from BSC */ -void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci) -{ - int sapi = dlci & 0x7; - - if (sapi == UM_SAPI_SMS) - gsm411_sapi_n_reject(conn); -} - -static void subscr_conn_bump(struct gsm_subscriber_connection *conn) -{ - if (!conn) - return; - if (!conn->conn_fsm) - return; - if (!(conn->conn_fsm->state == SUBSCR_CONN_S_ACCEPTED - || conn->conn_fsm->state == SUBSCR_CONN_S_COMMUNICATING)) { - DEBUGP(DMM, "%s: bump: conn still being established (%s)\n", - vlr_subscr_name(conn->vsub), - osmo_fsm_inst_state_name(conn->conn_fsm)); - return; - } - osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_BUMP, NULL); -} - -/* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or - * MSC_CONN_REJECT */ -int msc_compl_l3(struct gsm_subscriber_connection *conn, - struct msgb *msg, uint16_t chosen_channel) -{ - msc_subscr_conn_get(conn); - gsm0408_dispatch(conn, msg); - - /* Bump whether the conn wants to be closed */ - subscr_conn_bump(conn); - - /* If this should be kept, the conn->conn_fsm has placed a use_count */ - msc_subscr_conn_put(conn); - - /* Always return acceptance, because even if the conn was not accepted, - * we assumed ownership of it and the caller shall not interfere with - * that. We may even already have discarded the conn. */ - return MSC_CONN_ACCEPT; - -#if 0 - /* - * If this is a silent call we want the channel to remain open as long as - * possible and this is why we accept this connection regardless of any - * pending transaction or ongoing operation. - */ - if (conn->silent_call) - return MSC_CONN_ACCEPT; - if (conn->loc_operation || conn->sec_operation || conn->anch_operation) - return MSC_CONN_ACCEPT; - if (trans_has_conn(conn)) - return MSC_CONN_ACCEPT; - - LOGP(DRR, LOGL_INFO, "MSC Complete L3: Rejecting connection.\n"); - return MSC_CONN_REJECT; -#endif -} - -/* Receive a DTAP message from BSC */ -void msc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) -{ - msc_subscr_conn_get(conn); - gsm0408_dispatch(conn, msg); - - /* Bump whether the conn wants to be closed */ - subscr_conn_bump(conn); - msc_subscr_conn_put(conn); -} - -/* Receive an ASSIGNMENT COMPLETE from BSC */ -void msc_assign_compl(struct gsm_subscriber_connection *conn, - uint8_t rr_cause, uint8_t chosen_channel, - uint8_t encr_alg_id, uint8_t speec) -{ - LOGP(DRR, LOGL_DEBUG, "MSC assign complete (do nothing).\n"); -} - -/* Receive an ASSIGNMENT FAILURE from BSC */ -void msc_assign_fail(struct gsm_subscriber_connection *conn, - uint8_t cause, uint8_t *rr_cause) -{ - LOGP(DRR, LOGL_DEBUG, "MSC assign failure (do nothing).\n"); -} - -/* Receive a CLASSMARK CHANGE from BSC */ -void msc_classmark_chg(struct gsm_subscriber_connection *conn, - const uint8_t *cm2, uint8_t cm2_len, - const uint8_t *cm3, uint8_t cm3_len) -{ - if (cm2 && cm2_len) { - if (cm2_len > sizeof(conn->classmark.classmark2)) { - LOGP(DRR, LOGL_NOTICE, "%s: classmark2 is %u bytes, truncating at %zu bytes\n", - vlr_subscr_name(conn->vsub), cm2_len, sizeof(conn->classmark.classmark2)); - cm2_len = sizeof(conn->classmark.classmark2); - } - conn->classmark.classmark2_len = cm2_len; - memcpy(conn->classmark.classmark2, cm2, cm2_len); - } - if (cm3 && cm3_len) { - if (cm3_len > sizeof(conn->classmark.classmark3)) { - LOGP(DRR, LOGL_NOTICE, "%s: classmark3 is %u bytes, truncating at %zu bytes\n", - vlr_subscr_name(conn->vsub), cm3_len, sizeof(conn->classmark.classmark3)); - cm3_len = sizeof(conn->classmark.classmark3); - } - conn->classmark.classmark3_len = cm3_len; - memcpy(conn->classmark.classmark3, cm3, cm3_len); - } -} - -/* Receive a CIPHERING MODE COMPLETE from BSC */ -void msc_cipher_mode_compl(struct gsm_subscriber_connection *conn, - struct msgb *msg, uint8_t alg_id) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - struct tlv_parsed tp; - uint8_t mi_type; - char imeisv[GSM48_MI_SIZE] = ""; - struct vlr_ciph_result ciph_res = { .cause = VLR_CIPH_REJECT }; - - if (!gh) { - LOGP(DRR, LOGL_ERROR, "invalid: msgb without l3 header\n"); - return; - } - - if (!conn) { - LOGP(DRR, LOGL_ERROR, - "invalid: rx Ciphering Mode Complete on NULL conn\n"); - return; - } - if (!conn->vsub) { - LOGP(DRR, LOGL_ERROR, - "invalid: rx Ciphering Mode Complete for NULL subscr\n"); - return; - } - - DEBUGP(DRR, "%s: CIPHERING MODE COMPLETE\n", - vlr_subscr_name(conn->vsub)); - - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); - - /* bearer capability */ - if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) { - mi_type = TLVP_VAL(&tp, GSM48_IE_MOBILE_ID)[0] & GSM_MI_TYPE_MASK; - if (mi_type == GSM_MI_TYPE_IMEISV - && TLVP_LEN(&tp, GSM48_IE_MOBILE_ID) > 0) { - gsm48_mi_to_string(imeisv, sizeof(imeisv), - TLVP_VAL(&tp, GSM48_IE_MOBILE_ID), - TLVP_LEN(&tp, GSM48_IE_MOBILE_ID)); - ciph_res.imeisv = imeisv; - } - } - - ciph_res.cause = VLR_CIPH_COMPL; - vlr_subscr_rx_ciph_res(conn->vsub, &ciph_res); -} - -struct gsm_subscriber_connection *msc_subscr_con_allocate(struct gsm_network *network) -{ - struct gsm_subscriber_connection *conn; - - conn = talloc_zero(network, struct gsm_subscriber_connection); - if (!conn) - return NULL; - - conn->network = network; - llist_add_tail(&conn->entry, &network->subscr_conns); - return conn; -} - -void msc_subscr_cleanup(struct vlr_subscr *vsub) -{ - if (!vsub) - return; - vsub->lu_fsm = NULL; -} - -void msc_subscr_con_cleanup(struct gsm_subscriber_connection *conn) -{ - if (!conn) - return; - - if (conn->vsub) { - DEBUGP(DRLL, "subscr %s: Freeing subscriber connection\n", - vlr_subscr_name(conn->vsub)); - msc_subscr_cleanup(conn->vsub); - vlr_subscr_put(conn->vsub); - conn->vsub = NULL; - } else - DEBUGP(DRLL, "Freeing subscriber connection" - " with NULL subscriber\n"); - - if (!conn->conn_fsm) - return; - - osmo_fsm_inst_term(conn->conn_fsm, - (conn->conn_fsm->state == SUBSCR_CONN_S_RELEASED) - ? OSMO_FSM_TERM_REGULAR - : OSMO_FSM_TERM_ERROR, - NULL); -} - -void msc_subscr_con_free(struct gsm_subscriber_connection *conn) -{ - if (!conn) - return; - - msc_subscr_con_cleanup(conn); - - llist_del(&conn->entry); - talloc_free(conn); -} - -/* Receive a CLEAR REQUEST from BSC */ -int msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause) -{ - msc_subscr_conn_close(conn, cause); - return 1; -} - -/* MSC-level operations to be called by libbsc in NITB */ -static struct bsc_api msc_handler = { - .sapi_n_reject = msc_sapi_n_reject, - .compl_l3 = msc_compl_l3, - .dtap = msc_dtap, - .clear_request = msc_clear_request, - .assign_compl = msc_assign_compl, - .assign_fail = msc_assign_fail, - .classmark_chg = msc_classmark_chg, - .cipher_mode_compl = msc_cipher_mode_compl, - .conn_cleanup = msc_subscr_con_cleanup, -}; - -struct bsc_api *msc_bsc_api() { - return &msc_handler; -} - -static void msc_subscr_conn_release_all(struct gsm_subscriber_connection *conn, uint32_t cause) -{ - if (conn->in_release) - return; - conn->in_release = true; - - /* If we're closing in a middle of a trans, we need to clean up */ - trans_conn_closed(conn); - - switch (conn->via_ran) { - case RAN_UTRAN_IU: - ranap_iu_tx_release(conn->iu.ue_ctx, NULL); - /* FIXME: keep the conn until the Iu Release Outcome is - * received from the UE, or a timeout expires. For now, the log - * says "unknown UE" for each release outcome. */ - break; - case RAN_GERAN_A: - a_iface_tx_clear_cmd(conn); - break; - default: - LOGP(DMM, LOGL_ERROR, "%s: Unknown RAN type, cannot tx release/clear\n", - vlr_subscr_name(conn->vsub)); - break; - } -} - -/* If the conn->conn_fsm is still present, dispatch SUBSCR_CONN_E_CN_CLOSE - * event to gracefully terminate the connection. If the conn_fsm is already - * cleared, call msc_subscr_conn_release_all() to take release actions. - * \param cause a GSM_CAUSE_* constant, e.g. GSM_CAUSE_AUTH_FAILED. - */ -void msc_subscr_conn_close(struct gsm_subscriber_connection *conn, - uint32_t cause) -{ - if (!conn) - return; - if (conn->in_release) { - DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u):" - " already dispatching release, ignore.\n", - vlr_subscr_name(conn->vsub), cause); - return; - } - if (!conn->conn_fsm) { - DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u): no conn fsm," - " releasing directly without release event.\n", - vlr_subscr_name(conn->vsub), cause); - /* In case of an IMSI Detach, we don't have conn_fsm. Release - * anyway to ensure a timely Iu Release / BSSMAP Clear. */ - msc_subscr_conn_release_all(conn, cause); - return; - } - if (conn->conn_fsm->state == SUBSCR_CONN_S_RELEASED) { - DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u):" - " conn fsm already releasing, ignore.\n", - vlr_subscr_name(conn->vsub), cause); - return; - } - osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_CN_CLOSE, &cause); -} - -/* increment the ref-count. Needs to be called by every user */ -struct gsm_subscriber_connection * -_msc_subscr_conn_get(struct gsm_subscriber_connection *conn, - const char *file, int line) -{ - OSMO_ASSERT(conn); - - if (conn->in_release) - return NULL; - - conn->use_count++; - LOGPSRC(DREF, LOGL_DEBUG, file, line, - "%s: MSC conn use + 1 == %u\n", - vlr_subscr_name(conn->vsub), conn->use_count); - - return conn; -} - -/* decrement the ref-count. Once it reaches zero, we release */ -void _msc_subscr_conn_put(struct gsm_subscriber_connection *conn, - const char *file, int line) -{ - OSMO_ASSERT(conn); - - if (conn->use_count == 0) { - LOGPSRC(DREF, LOGL_ERROR, file, line, - "%s: MSC conn use - 1 failed: is already 0\n", - vlr_subscr_name(conn->vsub)); - return; - } - - conn->use_count--; - LOGPSRC(DREF, LOGL_DEBUG, file, line, - "%s: MSC conn use - 1 == %u\n", - vlr_subscr_name(conn->vsub), conn->use_count); - - if (conn->use_count == 0) - msc_subscr_con_free(conn); -} - -void msc_stop_paging(struct vlr_subscr *vsub) -{ - DEBUGP(DPAG, "Paging can stop for %s\n", vlr_subscr_name(vsub)); - /* tell BSCs and RNCs to stop paging? How? */ -} diff --git a/src/libmsc/rrlp.c b/src/libmsc/rrlp.c deleted file mode 100644 index cd3da066b..000000000 --- a/src/libmsc/rrlp.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Radio Resource LCS (Location) Protocol, GMS TS 04.31 */ - -/* (C) 2009 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - - - -#include -#include -#include -#include - -/* RRLP msPositionReq, nsBased, - * Accuracy=60, Method=gps, ResponseTime=2, oneSet */ -static const uint8_t ms_based_pos_req[] = { 0x40, 0x01, 0x78, 0xa8 }; - -/* RRLP msPositionReq, msBasedPref, - Accuracy=60, Method=gpsOrEOTD, ResponseTime=5, multipleSets */ -static const uint8_t ms_pref_pos_req[] = { 0x40, 0x02, 0x79, 0x50 }; - -/* RRLP msPositionReq, msAssistedPref, - Accuracy=60, Method=gpsOrEOTD, ResponseTime=5, multipleSets */ -static const uint8_t ass_pref_pos_req[] = { 0x40, 0x03, 0x79, 0x50 }; - -static int send_rrlp_req(struct gsm_subscriber_connection *conn) -{ - struct gsm_network *net = conn->network; - const uint8_t *req; - - switch (net->rrlp.mode) { - case RRLP_MODE_MS_BASED: - req = ms_based_pos_req; - break; - case RRLP_MODE_MS_PREF: - req = ms_pref_pos_req; - break; - case RRLP_MODE_ASS_PREF: - req = ass_pref_pos_req; - break; - case RRLP_MODE_NONE: - default: - return 0; - } - - return gsm48_send_rr_app_info(conn, 0x00, - sizeof(ms_based_pos_req), req); -} - -static int subscr_sig_cb(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct vlr_subscr *vsub; - struct gsm_subscriber_connection *conn; - - switch (signal) { - case S_SUBSCR_ATTACHED: - /* A subscriber has attached. */ - vsub = signal_data; - conn = connection_for_subscr(vsub); - if (!conn) - break; - send_rrlp_req(conn); - break; - } - return 0; -} - -static int paging_sig_cb(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct paging_signal_data *psig_data = signal_data; - - switch (signal) { - case S_PAGING_SUCCEEDED: - /* A subscriber has attached. */ - send_rrlp_req(psig_data->conn); - break; - case S_PAGING_EXPIRED: - break; - } - return 0; -} - -void on_dso_load_rrlp(void) -{ - osmo_signal_register_handler(SS_SUBSCR, subscr_sig_cb, NULL); - osmo_signal_register_handler(SS_PAGING, paging_sig_cb, NULL); -} diff --git a/src/libmsc/silent_call.c b/src/libmsc/silent_call.c deleted file mode 100644 index 7af7a8055..000000000 --- a/src/libmsc/silent_call.c +++ /dev/null @@ -1,165 +0,0 @@ -/* GSM silent call feature */ - -/* - * (C) 2009 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* paging of the requested subscriber has completed */ -static int paging_cb_silent(unsigned int hooknum, unsigned int event, - struct msgb *msg, void *_conn, void *_data) -{ - struct gsm_subscriber_connection *conn = _conn; - struct scall_signal_data sigdata; - int rc = 0; - - if (hooknum != GSM_HOOK_RR_PAGING) - return -EINVAL; - - DEBUGP(DLSMS, "paging_cb_silent: "); - - sigdata.conn = conn; - sigdata.data = _data; - - switch (event) { - case GSM_PAGING_SUCCEEDED: -#if BEFORE_MSCSPLIT - /* Re-enable this log output once we can obtain this information via - * A-interface, see OS#2391. */ - DEBUGPC(DLSMS, "success, using Timeslot %u on ARFCN %u\n", - conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn); -#endif - conn->silent_call = 1; - msc_subscr_conn_get(conn); - /* increment lchan reference count */ - osmo_signal_dispatch(SS_SCALL, S_SCALL_SUCCESS, &sigdata); - break; - case GSM_PAGING_EXPIRED: - case GSM_PAGING_BUSY: - case GSM_PAGING_OOM: - DEBUGP(DLSMS, "expired\n"); - osmo_signal_dispatch(SS_SCALL, S_SCALL_EXPIRED, &sigdata); - break; - default: - rc = -EINVAL; - break; - } - - return rc; -} - -#if 0 -/* receive a layer 3 message from a silent call */ -int silent_call_rx(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - /* FIXME: do something like sending it through a UDP port */ - LOGP(DLSMS, LOGL_NOTICE, "Discarding L3 message from a silent call.\n"); - return 0; -} -#endif - -struct msg_match { - uint8_t pdisc; - uint8_t msg_type; -}; - -/* list of messages that are handled inside OpenBSC, even in a silent call */ -static const struct msg_match silent_call_accept[] = { - { GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST }, - { GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_REQ }, -}; - -#if 0 -/* decide if we need to reroute a message as part of a silent call */ -int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t pdisc = gsm48_hdr_pdisc(gh); - uint8_t msg_type = gsm48_hdr_msg_type(gh); - int i; - - /* if we're not part of a silent call, never reroute */ - if (!conn->silent_call) - return 0; - - /* check if we are a special message that is handled in openbsc */ - for (i = 0; i < ARRAY_SIZE(silent_call_accept); i++) { - if (silent_call_accept[i].pdisc == pdisc && - silent_call_accept[i].msg_type == msg_type) - return 0; - } - - /* otherwise, reroute */ - LOGP(DLSMS, LOGL_INFO, "Rerouting L3 message from a silent call.\n"); - return 1; -} -#endif - - -/* initiate a silent call with a given subscriber */ -int gsm_silent_call_start(struct vlr_subscr *vsub, void *data, int type) -{ - struct subscr_request *req; - - /* FIXME the VTY command allows selecting a silent call channel type. - * This doesn't apply to the situation after MSCSPLIT with an - * A-interface. */ - req = subscr_request_conn(vsub, paging_cb_silent, data, - "establish silent call"); - return req != NULL; -} - -/* end a silent call with a given subscriber */ -int gsm_silent_call_stop(struct vlr_subscr *vsub) -{ - struct gsm_subscriber_connection *conn; - - conn = connection_for_subscr(vsub); - if (!conn) - return -EINVAL; - - /* did we actually establish a silent call for this guy? */ - if (!conn->silent_call) - return -EINVAL; - -#if BEFORE_MSCSPLIT - /* Re-enable this log output once we can obtain this information via - * A-interface, see OS#2391. */ - DEBUGPC(DLSMS, "Stopping silent call using Timeslot %u on ARFCN %u\n", - conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn); -#endif - - conn->silent_call = 0; - msc_subscr_conn_put(conn); - - return 0; -} diff --git a/src/libmsc/smpp_openbsc.c b/src/libmsc/smpp_openbsc.c deleted file mode 100644 index 431cb4dfd..000000000 --- a/src/libmsc/smpp_openbsc.c +++ /dev/null @@ -1,794 +0,0 @@ -/* OpenBSC SMPP 3.4 interface, SMSC-side implementation */ - -/* (C) 2012-2013 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - */ - - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "smpp_smsc.h" - -/*! \brief find vlr_subscr for a given SMPP NPI/TON/Address */ -static struct vlr_subscr *subscr_by_dst(struct gsm_network *net, - uint8_t npi, uint8_t ton, - const char *addr) -{ - struct vlr_subscr *vsub = NULL; - - switch (npi) { - case NPI_Land_Mobile_E212: - vsub = vlr_subscr_find_by_imsi(net->vlr, addr); - break; - case NPI_ISDN_E163_E164: - case NPI_Private: - vsub = vlr_subscr_find_by_msisdn(net->vlr, addr); - break; - default: - LOGP(DSMPP, LOGL_NOTICE, "Unsupported NPI: %u\n", npi); - break; - } - - log_set_context(LOG_CTX_VLR_SUBSCR, vsub); - return vsub; -} - -static int smpp34_submit_tlv_msg_payload(const struct tlv_t *t, - const struct submit_sm_t *submit, - const uint8_t **sms_msg, - unsigned int *sms_msg_len) -{ - if (submit->sm_length) { - LOGP(DLSMS, LOGL_ERROR, - "SMPP cannot have payload in TLV _and_ in the header\n"); - return -1; - } - *sms_msg = t->value.octet; - *sms_msg_len = t->length; - - return 0; -} - -/*! \brief convert from submit_sm_t to gsm_sms */ -static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, - const struct submit_sm_t *submit) -{ - const uint8_t *sms_msg = NULL; - unsigned int sms_msg_len = 0; - struct vlr_subscr *dest; - uint16_t msg_ref = 0; - struct gsm_sms *sms; - struct tlv_t *t; - int mode; - - dest = subscr_by_dst(net, submit->dest_addr_npi, - submit->dest_addr_ton, - (const char *)submit->destination_addr); - if (!dest) { - LOGP(DLSMS, LOGL_NOTICE, "SMPP SUBMIT-SM for unknown subscriber: " - "%s (NPI=%u)\n", submit->destination_addr, - submit->dest_addr_npi); - return ESME_RINVDSTADR; - } - - smpp34_tlv_for_each(t, submit->tlv) { - switch (t->tag) { - case TLVID_message_payload: - if (smpp34_submit_tlv_msg_payload(t, submit, &sms_msg, - &sms_msg_len) < 0) { - vlr_subscr_put(dest); - return ESME_ROPTPARNOTALLWD; - } - break; - case TLVID_user_message_reference: - msg_ref = t->value.val16; - break; - default: - break; - } - } - - if (!sms_msg) { - if (submit->sm_length > 0 && submit->sm_length < 255) { - sms_msg = submit->short_message; - sms_msg_len = submit->sm_length; - } else { - LOGP(DLSMS, LOGL_ERROR, - "SMPP neither message payload nor valid sm_length.\n"); - vlr_subscr_put(dest); - return ESME_RINVPARLEN; - } - } - - sms = sms_alloc(); - sms->source = SMS_SOURCE_SMPP; - sms->smpp.sequence_nr = submit->sequence_number; - sms->status_rep_req = submit->registered_delivery; - sms->msg_ref = msg_ref; - - /* fill in the destination address */ - sms->receiver = dest; - sms->dst.ton = submit->dest_addr_ton; - sms->dst.npi = submit->dest_addr_npi; - osmo_strlcpy(sms->dst.addr, dest->msisdn, sizeof(sms->dst.addr)); - - /* fill in the source address */ - sms->src.ton = submit->source_addr_ton; - sms->src.npi = submit->source_addr_npi; - osmo_strlcpy(sms->src.addr, (char *)submit->source_addr, - sizeof(sms->src.addr)); - - if (submit->esm_class == SMPP34_DELIVERY_ACK) - sms->is_report = true; - - if (submit->esm_class & SMPP34_UDHI_IND) - sms->ud_hdr_ind = 1; - - if (submit->esm_class & SMPP34_REPLY_PATH) { - sms->reply_path_req = 1; -#warning Implement reply path - } - - if (submit->data_coding == 0x00 || /* SMSC default */ - submit->data_coding == 0x01) { /* GSM default alphabet */ - sms->data_coding_scheme = GSM338_DCS_1111_7BIT; - mode = MODE_7BIT; - } else if ((submit->data_coding & 0xFC) == 0xF0) { /* 03.38 DCS default */ - /* pass DCS 1:1 through from SMPP to GSM */ - sms->data_coding_scheme = submit->data_coding; - mode = MODE_7BIT; - } else if (submit->data_coding == 0x02 || - submit->data_coding == 0x04) { - /* 8-bit binary */ - sms->data_coding_scheme = GSM338_DCS_1111_8BIT_DATA; - mode = MODE_8BIT; - } else if ((submit->data_coding & 0xFC) == 0xF4) { /* 03.38 DCS 8bit */ - /* pass DCS 1:1 through from SMPP to GSM */ - sms->data_coding_scheme = submit->data_coding; - mode = MODE_8BIT; - } else if (submit->data_coding == 0x08) { - /* UCS-2 */ - sms->data_coding_scheme = (2 << 2); - mode = MODE_8BIT; - } else { - sms_free(sms); - LOGP(DLSMS, LOGL_ERROR, "SMPP Unknown Data Coding 0x%02x\n", - submit->data_coding); - return ESME_RUNKNOWNERR; - } - - if (mode == MODE_7BIT) { - uint8_t ud_len = 0, padbits = 0; - sms->data_coding_scheme = GSM338_DCS_1111_7BIT; - if (sms->ud_hdr_ind) { - ud_len = *sms_msg + 1; - printf("copying %u bytes user data...\n", ud_len); - memcpy(sms->user_data, sms_msg, - OSMO_MIN(ud_len, sizeof(sms->user_data))); - sms_msg += ud_len; - sms_msg_len -= ud_len; - padbits = 7 - (ud_len % 7); - } - gsm_septets2octets(sms->user_data+ud_len, sms_msg, - sms_msg_len, padbits); - sms->user_data_len = (ud_len*8 + padbits)/7 + sms_msg_len;/* SEPTETS */ - /* FIXME: sms->text */ - } else { - memcpy(sms->user_data, sms_msg, sms_msg_len); - sms->user_data_len = sms_msg_len; - } - - *psms = sms; - return ESME_ROK; -} - -/*! \brief handle incoming libsmpp34 ssubmit_sm_t from remote ESME */ -int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit, - struct submit_sm_resp_t *submit_r) -{ - struct gsm_sms *sms; - struct gsm_network *net = esme->smsc->priv; - struct sms_signal_data sig; - int rc = -1; - - rc = submit_to_sms(&sms, net, submit); - if (rc != ESME_ROK) { - submit_r->command_status = rc; - return 0; - } - smpp_esme_get(esme); - sms->smpp.esme = esme; - sms->protocol_id = submit->protocol_id; - - switch (submit->esm_class & SMPP34_MSG_MODE_MASK) { - case 0: /* default */ - case 1: /* datagram */ - case 3: /* store-and-forward */ - rc = db_sms_store(sms); - sms_free(sms); - sms = NULL; - if (rc < 0) { - LOGP(DLSMS, LOGL_ERROR, "SMPP SUBMIT-SM: Unable to " - "store SMS in database\n"); - submit_r->command_status = ESME_RSYSERR; - return 0; - } - strcpy((char *)submit_r->message_id, "msg_id_not_implemented"); - LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Stored in DB\n"); - - memset(&sig, 0, sizeof(sig)); - osmo_signal_dispatch(SS_SMS, S_SMS_SUBMITTED, &sig); - rc = 0; - break; - case 2: /* forward (i.e. transaction) mode */ - LOGP(DLSMS, LOGL_DEBUG, "SMPP SUBMIT-SM: Forwarding in " - "real time (Transaction/Forward mode)\n"); - sms->smpp.transaction_mode = 1; - gsm411_send_sms_subscr(sms->receiver, sms); - rc = 1; /* don't send any response yet */ - break; - } - return rc; -} - -static void alert_all_esme(struct smsc *smsc, struct vlr_subscr *vsub, - uint8_t smpp_avail_status) -{ - struct osmo_esme *esme; - - llist_for_each_entry(esme, &smsc->esme_list, list) { - /* we currently send an alert notification to each ESME that is - * connected, and do not require a (non-existant) delivery - * pending flag to be set before, FIXME: make this VTY - * configurable */ - if (esme->acl && esme->acl->deliver_src_imsi) { - smpp_tx_alert(esme, TON_Subscriber_Number, - NPI_Land_Mobile_E212, - vsub->imsi, smpp_avail_status); - } else { - smpp_tx_alert(esme, TON_Network_Specific, - NPI_ISDN_E163_E164, - vsub->msisdn, smpp_avail_status); - } - } -} - - -/*! \brief signal handler for status of attempted SMS deliveries */ -static int smpp_sms_cb(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct sms_signal_data *sig_sms = signal_data; - struct gsm_sms *sms = sig_sms->sms; - struct smsc *smsc = handler_data; - int rc = 0; - - if (!sms) - return 0; - - if (sms->source != SMS_SOURCE_SMPP) - return 0; - - switch (signal) { - case S_SMS_MEM_EXCEEDED: - /* fall-through: There is no ESME_Rxxx result code to - * indicate a MEMORY EXCEEDED in transaction mode back - * to the ESME */ - case S_SMS_UNKNOWN_ERROR: - if (sms->smpp.transaction_mode) { - /* Send back the SUBMIT-SM response with apropriate error */ - LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Error\n"); - rc = smpp_tx_submit_r(sms->smpp.esme, - sms->smpp.sequence_nr, - ESME_RDELIVERYFAILURE, - sms->smpp.msg_id); - } - break; - case S_SMS_DELIVERED: - /* SMS layer tells us the delivery has been completed */ - if (sms->smpp.transaction_mode) { - /* Send back the SUBMIT-SM response */ - LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Success\n"); - rc = smpp_tx_submit_r(sms->smpp.esme, - sms->smpp.sequence_nr, - ESME_ROK, sms->smpp.msg_id); - } - break; - case S_SMS_SMMA: - if (!sig_sms->trans || !sig_sms->trans->vsub) { - /* SMMA without a subscriber? strange... */ - LOGP(DLSMS, LOGL_NOTICE, "SMMA without subscriber?\n"); - break; - } - - /* There's no real 1:1 match for SMMA in SMPP. However, - * an ALERT NOTIFICATION seems to be the most logical - * choice */ - alert_all_esme(smsc, sig_sms->trans->vsub, 0); - break; - } - - return rc; -} - -/*! \brief signal handler for subscriber related signals */ -static int smpp_subscr_cb(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct vlr_subscr *vsub = signal_data; - struct smsc *smsc = handler_data; - uint8_t smpp_avail_status; - - /* determine the smpp_avail_status depending on attach/detach */ - switch (signal) { - case S_SUBSCR_ATTACHED: - smpp_avail_status = 0; - break; - case S_SUBSCR_DETACHED: - smpp_avail_status = 2; - break; - default: - return 0; - } - - alert_all_esme(smsc, vsub, smpp_avail_status); - - return 0; -} - -/* GSM 03.38 6.2.1 Character expanding (no decode!) */ -static int gsm_7bit_expand(char *text, const uint8_t *user_data, uint8_t septet_l, uint8_t ud_hdr_ind) -{ - int i = 0; - int shift = 0; - uint8_t c; - - /* skip the user data header */ - if (ud_hdr_ind) { - /* get user data header length + 1 (for the 'user data header length'-field) */ - shift = ((user_data[0] + 1) * 8) / 7; - if ((((user_data[0] + 1) * 8) % 7) != 0) - shift++; - septet_l = septet_l - shift; - } - - for (i = 0; i < septet_l; i++) { - c = - ((user_data[((i + shift) * 7 + 7) >> 3] << - (7 - (((i + shift) * 7 + 7) & 7))) | - (user_data[((i + shift) * 7) >> 3] >> - (((i + shift) * 7) & 7))) & 0x7f; - - *(text++) = c; - } - - *text = '\0'; - - return i; -} - - -/* FIXME: libsmpp34 helpers, they should be part of libsmpp34! */ -void append_tlv(tlv_t **req_tlv, uint16_t tag, - const uint8_t *data, uint16_t len) -{ - tlv_t tlv; - - memset(&tlv, 0, sizeof(tlv)); - tlv.tag = tag; - tlv.length = len; - memcpy(tlv.value.octet, data, tlv.length); - build_tlv(req_tlv, &tlv); -} -void append_tlv_u8(tlv_t **req_tlv, uint16_t tag, uint8_t val) -{ - tlv_t tlv; - - memset(&tlv, 0, sizeof(tlv)); - tlv.tag = tag; - tlv.length = 1; - tlv.value.val08 = val; - build_tlv(req_tlv, &tlv); -} -void append_tlv_u16(tlv_t **req_tlv, uint16_t tag, uint16_t val) -{ - tlv_t tlv; - - memset(&tlv, 0, sizeof(tlv)); - tlv.tag = tag; - tlv.length = 2; - tlv.value.val16 = val; - build_tlv(req_tlv, &tlv); -} - -#if BEFORE_MSCSPLIT -/* We currently have no lchan information. Re-add after A-interface, see OS#2390. */ -/* Append the Osmocom vendor-specific additional TLVs to a SMPP msg */ -static void append_osmo_tlvs(tlv_t **req_tlv, const struct gsm_lchan *lchan) -{ - int idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep), - lchan->meas_rep_idx, 1); - const struct gsm_meas_rep *mr = &lchan->meas_rep[idx]; - const struct gsm_meas_rep_unidir *ul_meas = &mr->ul; - const struct gsm_meas_rep_unidir *dl_meas = &mr->dl; - - /* Osmocom vendor-specific SMPP34 extensions */ - append_tlv_u16(req_tlv, TLVID_osmo_arfcn, lchan->ts->trx->arfcn); - if (mr->flags & MEAS_REP_F_MS_L1) { - uint8_t ms_dbm; - append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_l1.ta); - ms_dbm = ms_pwr_dbm(lchan->ts->trx->bts->band, mr->ms_l1.pwr); - append_tlv_u8(req_tlv, TLVID_osmo_ms_l1_txpwr, ms_dbm); - } else if (mr->flags & MEAS_REP_F_MS_TO) /* Save Timing Offset field = MS Timing Offset + 63 */ - append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset + 63); - - append_tlv_u16(req_tlv, TLVID_osmo_rxlev_ul, - rxlev2dbm(ul_meas->full.rx_lev)); - append_tlv_u8(req_tlv, TLVID_osmo_rxqual_ul, ul_meas->full.rx_qual); - - if (mr->flags & MEAS_REP_F_DL_VALID) { - append_tlv_u16(req_tlv, TLVID_osmo_rxlev_dl, - rxlev2dbm(dl_meas->full.rx_lev)); - append_tlv_u8(req_tlv, TLVID_osmo_rxqual_dl, - dl_meas->full.rx_qual); - } - - if (lchan->conn && lchan->conn->vsub) { - struct vlr_subscr *vsub = lchan->conn->vsub; - size_t imei_len = strlen(vsub->imei); - if (imei_len) - append_tlv(req_tlv, TLVID_osmo_imei, - (uint8_t *)vsub->imei, imei_len+1); - } -} -#endif - -struct { - uint32_t smpp_status_code; - uint8_t gsm411_cause; -} smpp_to_gsm411_err_array[] = { - - /* Seems like most phones don't care about the failure cause, - * although some will display a different notification for - * GSM411_RP_CAUSE_MO_NUM_UNASSIGNED - * Some provoke a display of "Try again later" - * while others a more definitive "Message sending failed" - */ - - { ESME_RSYSERR, GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER }, - { ESME_RINVDSTADR, GSM411_RP_CAUSE_MO_NUM_UNASSIGNED }, - { ESME_RMSGQFUL, GSM411_RP_CAUSE_MO_CONGESTION }, - { ESME_RINVSRCADR, GSM411_RP_CAUSE_MO_SMS_REJECTED }, - { ESME_RINVMSGID, GSM411_RP_CAUSE_INV_TRANS_REF } -}; - -static int smpp_to_gsm411_err(uint32_t smpp_status_code, int *gsm411_cause) -{ - int i; - for (i = 0; i < ARRAY_SIZE(smpp_to_gsm411_err_array); i++) { - if (smpp_to_gsm411_err_array[i].smpp_status_code != smpp_status_code) - continue; - *gsm411_cause = smpp_to_gsm411_err_array[i].gsm411_cause; - return 0; - } - return -1; -} - -static void smpp_cmd_free(struct osmo_smpp_cmd *cmd) -{ - osmo_timer_del(&cmd->response_timer); - llist_del(&cmd->list); - vlr_subscr_put(cmd->vsub); - talloc_free(cmd); -} - -void smpp_cmd_flush_pending(struct osmo_esme *esme) -{ - struct osmo_smpp_cmd *cmd, *next; - - llist_for_each_entry_safe(cmd, next, &esme->smpp_cmd_list, list) - smpp_cmd_free(cmd); -} - -void smpp_cmd_ack(struct osmo_smpp_cmd *cmd) -{ - struct gsm_subscriber_connection *conn; - struct gsm_trans *trans; - - if (cmd->is_report) - goto out; - - conn = connection_for_subscr(cmd->vsub); - if (!conn) { - LOGP(DSMPP, LOGL_ERROR, "No connection to subscriber anymore\n"); - goto out; - } - - trans = trans_find_by_id(conn, GSM48_PDISC_SMS, cmd->gsm411_trans_id); - if (!trans) { - LOGP(DSMPP, LOGL_ERROR, "GSM transaction %u is gone\n", - cmd->gsm411_trans_id); - goto out; - } - - gsm411_send_rp_ack(trans, cmd->gsm411_msg_ref); -out: - smpp_cmd_free(cmd); -} - -void smpp_cmd_err(struct osmo_smpp_cmd *cmd, uint32_t status) -{ - struct gsm_subscriber_connection *conn; - struct gsm_trans *trans; - int gsm411_cause; - - if (cmd->is_report) - goto out; - - conn = connection_for_subscr(cmd->vsub); - if (!conn) { - LOGP(DSMPP, LOGL_ERROR, "No connection to subscriber anymore\n"); - goto out; - } - - trans = trans_find_by_id(conn, GSM48_PDISC_SMS, cmd->gsm411_trans_id); - if (!trans) { - LOGP(DSMPP, LOGL_ERROR, "GSM transaction %u is gone\n", - cmd->gsm411_trans_id); - goto out; - } - - if (smpp_to_gsm411_err(status, &gsm411_cause) < 0) - gsm411_cause = GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER; - - gsm411_send_rp_error(trans, cmd->gsm411_msg_ref, gsm411_cause); -out: - smpp_cmd_free(cmd); -} - -static void smpp_deliver_sm_cb(void *data) -{ - smpp_cmd_err(data, ESME_RSYSERR); -} - -static int smpp_cmd_enqueue(struct osmo_esme *esme, - struct vlr_subscr *vsub, struct gsm_sms *sms, - uint32_t sequence_number) -{ - struct osmo_smpp_cmd *cmd; - - cmd = talloc_zero(esme, struct osmo_smpp_cmd); - if (!cmd) - return -1; - - cmd->sequence_nr = sequence_number; - cmd->is_report = sms->is_report; - cmd->gsm411_msg_ref = sms->gsm411.msg_ref; - cmd->gsm411_trans_id = sms->gsm411.transaction_id; - cmd->vsub = vlr_subscr_get(vsub); - - /* FIXME: No predefined value for this response_timer as specified by - * SMPP 3.4 specs, section 7.2. Make this configurable? Don't forget - * lchan keeps busy until we get a reply to this SMPP command. Too high - * value may exhaust resources. - */ - osmo_timer_setup(&cmd->response_timer, smpp_deliver_sm_cb, cmd); - osmo_timer_schedule(&cmd->response_timer, 5, 0); - llist_add_tail(&cmd->list, &esme->smpp_cmd_list); - - return 0; -} - -struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme, - uint32_t sequence_nr) -{ - struct osmo_smpp_cmd *cmd; - - llist_for_each_entry(cmd, &esme->smpp_cmd_list, list) { - if (cmd->sequence_nr == sequence_nr) - return cmd; - } - return NULL; -} - -static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms, - struct gsm_subscriber_connection *conn) -{ - struct deliver_sm_t deliver; - int mode, ret; - uint8_t dcs; - - memset(&deliver, 0, sizeof(deliver)); - deliver.command_length = 0; - deliver.command_id = DELIVER_SM; - deliver.command_status = ESME_ROK; - - strcpy((char *)deliver.service_type, "CMT"); - if (esme->acl && esme->acl->deliver_src_imsi) { - deliver.source_addr_ton = TON_Subscriber_Number; - deliver.source_addr_npi = NPI_Land_Mobile_E212; - snprintf((char *)deliver.source_addr, - sizeof(deliver.source_addr), "%s", - conn->vsub->imsi); - } else { - deliver.source_addr_ton = TON_Network_Specific; - deliver.source_addr_npi = NPI_ISDN_E163_E164; - snprintf((char *)deliver.source_addr, - sizeof(deliver.source_addr), "%s", - conn->vsub->msisdn); - } - - deliver.dest_addr_ton = sms->dst.ton; - deliver.dest_addr_npi = sms->dst.npi; - memcpy(deliver.destination_addr, sms->dst.addr, - sizeof(deliver.destination_addr)); - - if (sms->is_report) - deliver.esm_class = SMPP34_DELIVERY_RECEIPT; - else - deliver.esm_class = SMPP34_DATAGRAM_MODE; - - if (sms->ud_hdr_ind) - deliver.esm_class |= SMPP34_UDHI_IND; - if (sms->reply_path_req) - deliver.esm_class |= SMPP34_REPLY_PATH; - - deliver.protocol_id = sms->protocol_id; - deliver.priority_flag = 0; - if (sms->status_rep_req) - deliver.registered_delivery = SMPP34_DELIVERY_RECEIPT_ON; - - /* Figure out SMPP DCS from TP-DCS */ - dcs = sms->data_coding_scheme; - if (smpp_determine_scheme(dcs, &deliver.data_coding, &mode) == -1) - return -1; - - /* Transparently pass on DCS via SMPP if requested */ - if (esme->acl && esme->acl->dcs_transparent) - deliver.data_coding = dcs; - - if (mode == MODE_7BIT) { - uint8_t *dst = deliver.short_message; - - /* SMPP has this strange notion of putting 7bit SMS in - * an octet-aligned mode */ - if (sms->ud_hdr_ind) { - /* length (bytes) of UDH inside UD */ - uint8_t udh_len = sms->user_data[0] + 1; - - /* copy over the UDH */ - memcpy(dst, sms->user_data, udh_len); - dst += udh_len; - deliver.sm_length = udh_len; - } - /* add decoded text */ - deliver.sm_length += gsm_7bit_expand((char *)dst, sms->user_data, sms->user_data_len, sms->ud_hdr_ind); - } else { - deliver.sm_length = sms->user_data_len; - memcpy(deliver.short_message, sms->user_data, deliver.sm_length); - } - -#if BEFORE_MSCSPLIT - /* We currently have no lchan information. Re-add after A-interface, see OS#2390. */ - if (esme->acl && esme->acl->osmocom_ext && conn->lchan) - append_osmo_tlvs(&deliver.tlv, conn->lchan); -#endif - - append_tlv_u16(&deliver.tlv, TLVID_user_message_reference, - sms->msg_ref); - - ret = smpp_tx_deliver(esme, &deliver); - if (ret < 0) - return ret; - - return smpp_cmd_enqueue(esme, conn->vsub, sms, - deliver.sequence_number); -} - -static struct smsc *g_smsc; - -int smpp_route_smpp_first(struct gsm_sms *sms, struct gsm_subscriber_connection *conn) -{ - return g_smsc->smpp_first; -} - -int smpp_try_deliver(struct gsm_sms *sms, - struct gsm_subscriber_connection *conn) -{ - struct osmo_esme *esme; - struct osmo_smpp_addr dst; - int rc; - - memset(&dst, 0, sizeof(dst)); - dst.ton = sms->dst.ton; - dst.npi = sms->dst.npi; - memcpy(dst.addr, sms->dst.addr, sizeof(dst.addr)); - - rc = smpp_route(g_smsc, &dst, &esme); - if (!rc) - rc = deliver_to_esme(esme, sms, conn); - - return rc; -} - -struct smsc *smsc_from_vty(struct vty *v) -{ - /* FIXME: this is ugly */ - return g_smsc; -} - -/*! \brief Allocate the OpenBSC SMPP interface struct and init VTY. */ -int smpp_openbsc_alloc_init(void *ctx) -{ - g_smsc = smpp_smsc_alloc_init(ctx); - if (!g_smsc) { - LOGP(DSMPP, LOGL_FATAL, "Cannot allocate smsc struct\n"); - return -1; - } - return smpp_vty_init(); -} - -/*! \brief Launch the OpenBSC SMPP interface with the parameters set from VTY. - */ -int smpp_openbsc_start(struct gsm_network *net) -{ - int rc; - g_smsc->priv = net; - - /* If a VTY configuration has taken place, the values have been stored - * in the smsc struct. Otherwise, use the defaults (NULL -> any, 0 -> - * default SMPP port, see smpp_smsc_bind()). */ - rc = smpp_smsc_start(g_smsc, g_smsc->bind_addr, g_smsc->listen_port); - if (rc < 0) - return rc; - - rc = osmo_signal_register_handler(SS_SMS, smpp_sms_cb, g_smsc); - if (rc < 0) - return rc; - rc = osmo_signal_register_handler(SS_SUBSCR, smpp_subscr_cb, g_smsc); - if (rc < 0) - return rc; - - return 0; -} - diff --git a/src/libmsc/smpp_smsc.c b/src/libmsc/smpp_smsc.c deleted file mode 100644 index 04afc49bb..000000000 --- a/src/libmsc/smpp_smsc.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* SMPP 3.4 interface, SMSC-side implementation */ -/* (C) 2012 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - */ - - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "smpp_smsc.h" - -#include -#include - -/*! \brief Ugly wrapper. libsmpp34 should do this itself! */ -#define SMPP34_UNPACK(rc, type, str, data, len) \ - memset(str, 0, sizeof(*str)); \ - rc = smpp34_unpack(type, str, data, len) - -enum emse_bind { - ESME_BIND_RX = 0x01, - ESME_BIND_TX = 0x02, -}; - -const struct value_string smpp_status_strs[] = { - { ESME_ROK, "No Error" }, - { ESME_RINVMSGLEN, "Message Length is invalid" }, - { ESME_RINVCMDLEN, "Command Length is invalid" }, - { ESME_RINVCMDID, "Invalid Command ID" }, - { ESME_RINVBNDSTS, "Incorrect BIND Status for given command" }, - { ESME_RALYBND, "ESME Already in Bound State" }, - { ESME_RINVPRTFLG, "Invalid Priority Flag" }, - { ESME_RINVREGDLVFLG, "Invalid Registered Delivery Flag" }, - { ESME_RSYSERR, "System Error" }, - { ESME_RINVSRCADR, "Invalid Source Address" }, - { ESME_RINVDSTADR, "Invalid Destination Address" }, - { ESME_RINVMSGID, "Message ID is invalid" }, - { ESME_RBINDFAIL, "Bind failed" }, - { ESME_RINVPASWD, "Invalid Password" }, - { ESME_RINVSYSID, "Invalid System ID" }, - { ESME_RCANCELFAIL, "Cancel SM Failed" }, - { ESME_RREPLACEFAIL, "Replace SM Failed" }, - { ESME_RMSGQFUL, "Message Queue Full" }, - { ESME_RINVSERTYP, "Invalid Service Type" }, - { ESME_RINVNUMDESTS, "Invalid number of destinations" }, - { ESME_RINVDLNAME, "Invalid Distribution List name" }, - { ESME_RINVDESTFLAG, "Destination flag is invalid" }, - { ESME_RINVSUBREP, "Invalid submit with replace request" }, - { ESME_RINVESMCLASS, "Invalid esm_class field data" }, - { ESME_RCNTSUBDL, "Cannot Submit to Distribution List" }, - { ESME_RSUBMITFAIL, "submit_sm or submit_multi failed" }, - { ESME_RINVSRCTON, "Invalid Source address TON" }, - { ESME_RINVSRCNPI, "Invalid Sourec address NPI" }, - { ESME_RINVDSTTON, "Invalid Destination address TON" }, - { ESME_RINVDSTNPI, "Invalid Desetination address NPI" }, - { ESME_RINVSYSTYP, "Invalid system_type field" }, - { ESME_RINVREPFLAG, "Invalid replace_if_present field" }, - { ESME_RINVNUMMSGS, "Invalid number of messages" }, - { ESME_RTHROTTLED, "Throttling error (ESME has exceeded message limits)" }, - { ESME_RINVSCHED, "Invalid Scheduled Delivery Time" }, - { ESME_RINVEXPIRY, "Invalid message validity period (Expiry time)" }, - { ESME_RINVDFTMSGID, "Predefined Message Invalid or Not Found" }, - { ESME_RX_T_APPN, "ESME Receiver Temporary App Error Code" }, - { ESME_RX_P_APPN, "ESME Receiver Permanent App Error Code" }, - { ESME_RX_R_APPN, "ESME Receiver Reject Message Error Code" }, - { ESME_RQUERYFAIL, "query_sm request failed" }, - { ESME_RINVOPTPARSTREAM,"Error in the optional part of the PDU Body" }, - { ESME_ROPTPARNOTALLWD, "Optional Parameter not allowed" }, - { ESME_RINVPARLEN, "Invalid Parameter Length" }, - { ESME_RMISSINGOPTPARAM,"Expected Optional Parameter missing" }, - { ESME_RINVOPTPARAMVAL, "Invalid Optional Parameter Value" }, - { ESME_RDELIVERYFAILURE,"Delivery Failure (used for data_sm_resp)" }, - { ESME_RUNKNOWNERR, "Unknown Error" }, - { 0, NULL } -}; - -/*! \brief compare if two SMPP addresses are equal */ -int smpp_addr_eq(const struct osmo_smpp_addr *a, - const struct osmo_smpp_addr *b) -{ - if (a->ton == b->ton && - a->npi == b->npi && - !strcmp(a->addr, b->addr)) - return 1; - - return 0; -} - - -struct osmo_smpp_acl *smpp_acl_by_system_id(struct smsc *smsc, - const char *sys_id) -{ - struct osmo_smpp_acl *acl; - - llist_for_each_entry(acl, &smsc->acl_list, list) { - if (!strcmp(acl->system_id, sys_id)) - return acl; - } - - return NULL; -} - -struct osmo_smpp_acl *smpp_acl_alloc(struct smsc *smsc, const char *sys_id) -{ - struct osmo_smpp_acl *acl; - - if (strlen(sys_id) > SMPP_SYS_ID_LEN) - return NULL; - - if (smpp_acl_by_system_id(smsc, sys_id)) - return NULL; - - acl = talloc_zero(smsc, struct osmo_smpp_acl); - if (!acl) - return NULL; - - acl->smsc = smsc; - strcpy(acl->system_id, sys_id); - INIT_LLIST_HEAD(&acl->route_list); - - llist_add_tail(&acl->list, &smsc->acl_list); - - return acl; -} - -void smpp_acl_delete(struct osmo_smpp_acl *acl) -{ - struct osmo_smpp_route *r, *r2; - - llist_del(&acl->list); - - /* kill any active ESMEs */ - if (acl->esme) { - struct osmo_esme *esme = acl->esme; - osmo_fd_unregister(&esme->wqueue.bfd); - close(esme->wqueue.bfd.fd); - esme->wqueue.bfd.fd = -1; - esme->acl = NULL; - smpp_esme_put(esme); - } - - /* delete all routes for this ACL */ - llist_for_each_entry_safe(r, r2, &acl->route_list, list) { - llist_del(&r->list); - llist_del(&r->global_list); - talloc_free(r); - } - - talloc_free(acl); -} - -static struct osmo_smpp_route *route_alloc(struct osmo_smpp_acl *acl) -{ - struct osmo_smpp_route *r; - - r = talloc_zero(acl, struct osmo_smpp_route); - if (!r) - return NULL; - - llist_add_tail(&r->list, &acl->route_list); - llist_add_tail(&r->global_list, &acl->smsc->route_list); - - return r; -} - -int smpp_route_pfx_add(struct osmo_smpp_acl *acl, - const struct osmo_smpp_addr *pfx) -{ - struct osmo_smpp_route *r; - - llist_for_each_entry(r, &acl->route_list, list) { - if (r->type == SMPP_ROUTE_PREFIX && - smpp_addr_eq(&r->u.prefix, pfx)) - return -EEXIST; - } - - r = route_alloc(acl); - if (!r) - return -ENOMEM; - r->type = SMPP_ROUTE_PREFIX; - r->acl = acl; - memcpy(&r->u.prefix, pfx, sizeof(r->u.prefix)); - - return 0; -} - -int smpp_route_pfx_del(struct osmo_smpp_acl *acl, - const struct osmo_smpp_addr *pfx) -{ - struct osmo_smpp_route *r, *r2; - - llist_for_each_entry_safe(r, r2, &acl->route_list, list) { - if (r->type == SMPP_ROUTE_PREFIX && - smpp_addr_eq(&r->u.prefix, pfx)) { - llist_del(&r->list); - talloc_free(r); - return 0; - } - } - - return -ENODEV; -} - - -/*! \brief increaes the use/reference count */ -void smpp_esme_get(struct osmo_esme *esme) -{ - esme->use++; -} - -static void esme_destroy(struct osmo_esme *esme) -{ - osmo_wqueue_clear(&esme->wqueue); - if (esme->wqueue.bfd.fd >= 0) { - osmo_fd_unregister(&esme->wqueue.bfd); - close(esme->wqueue.bfd.fd); - } - smpp_cmd_flush_pending(esme); - llist_del(&esme->list); - talloc_free(esme); -} - -static uint32_t esme_inc_seq_nr(struct osmo_esme *esme) -{ - esme->own_seq_nr++; - if (esme->own_seq_nr > 0x7fffffff) - esme->own_seq_nr = 1; - - return esme->own_seq_nr; -} - -/*! \brief decrease the use/reference count, free if it is 0 */ -void smpp_esme_put(struct osmo_esme *esme) -{ - esme->use--; - if (esme->use <= 0) - esme_destroy(esme); -} - -/*! \brief try to find a SMPP route (ESME) for given destination */ -int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct osmo_esme **pesme) -{ - struct osmo_smpp_route *r; - struct osmo_smpp_acl *acl = NULL; - - DEBUGP(DSMPP, "Looking up route for (%u/%u/%s)\n", - dest->ton, dest->npi, dest->addr); - - /* search for a specific route */ - llist_for_each_entry(r, &smsc->route_list, global_list) { - switch (r->type) { - case SMPP_ROUTE_PREFIX: - DEBUGP(DSMPP, "Checking prefix route (%u/%u/%s)->%s\n", - r->u.prefix.ton, r->u.prefix.npi, r->u.prefix.addr, - r->acl->system_id); - if (r->u.prefix.ton == dest->ton && - r->u.prefix.npi == dest->npi && - !strncmp(r->u.prefix.addr, dest->addr, - strlen(r->u.prefix.addr))) { - DEBUGP(DSMPP, "Found prefix route ACL\n"); - acl = r->acl; - } - break; - default: - break; - } - - if (acl) - break; - } - - if (!acl) { - /* check for default route */ - if (smsc->def_route) { - DEBUGP(DSMPP, "Using existing default route\n"); - acl = smsc->def_route; - } - } - - if (acl && acl->esme) { - struct osmo_esme *esme; - DEBUGP(DSMPP, "ACL even has ESME, we can route to it!\n"); - esme = acl->esme; - if (esme->bind_flags & ESME_BIND_RX) { - *pesme = esme; - return 0; - } else - LOGP(DSMPP, LOGL_NOTICE, "[%s] is matching route, " - "but not bound for Rx, discarding MO SMS\n", - esme->system_id); - } - - *pesme = NULL; - if (acl) - return GSM48_CC_CAUSE_NETWORK_OOO; - else - return GSM48_CC_CAUSE_UNASSIGNED_NR; -} - - -/*! \brief initialize the libsmpp34 data structure for a response */ -#define INIT_RESP(type, resp, req) { \ - memset((resp), 0, sizeof(*(resp))); \ - (resp)->command_length = 0; \ - (resp)->command_id = type; \ - (resp)->command_status = ESME_ROK; \ - (resp)->sequence_number = (req)->sequence_number; \ -} - -/*! \brief pack a libsmpp34 data strcutrure and send it to the ESME */ -#define PACK_AND_SEND(esme, ptr) pack_and_send(esme, (ptr)->command_id, ptr) -static int pack_and_send(struct osmo_esme *esme, uint32_t type, void *ptr) -{ - struct msgb *msg = msgb_alloc(4096, "SMPP_Tx"); - int rc, rlen; - if (!msg) - return -ENOMEM; - - rc = smpp34_pack(type, msg->tail, msgb_tailroom(msg), &rlen, ptr); - if (rc != 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error during smpp34_pack(): %s\n", - esme->system_id, smpp34_strerror); - msgb_free(msg); - return -EINVAL; - } - msgb_put(msg, rlen); - - if (osmo_wqueue_enqueue(&esme->wqueue, msg) != 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Write queue full. Dropping message\n", - esme->system_id); - msgb_free(msg); - return -EAGAIN; - } - return 0; -} - -/*! \brief transmit a generic NACK to a remote ESME */ -static int smpp_tx_gen_nack(struct osmo_esme *esme, uint32_t seq, uint32_t status) -{ - struct generic_nack_t nack; - char buf[SMALL_BUFF]; - - nack.command_length = 0; - nack.command_id = GENERIC_NACK; - nack.sequence_number = seq; - nack.command_status = status; - - LOGP(DSMPP, LOGL_ERROR, "[%s] Tx GENERIC NACK: %s\n", - esme->system_id, str_command_status(status, buf)); - - return PACK_AND_SEND(esme, &nack); -} - -/*! \brief retrieve SMPP command ID from a msgb */ -static inline uint32_t smpp_msgb_cmdid(struct msgb *msg) -{ - uint8_t *tmp = msgb_data(msg) + 4; - return ntohl(*(uint32_t *)tmp); -} - -/*! \brief retrieve SMPP sequence number from a msgb */ -static inline uint32_t smpp_msgb_seq(struct msgb *msg) -{ - uint8_t *tmp = msgb_data(msg); - return ntohl(*(uint32_t *)tmp); -} - -/*! \brief handle an incoming SMPP generic NACK */ -static int smpp_handle_gen_nack(struct osmo_esme *esme, struct msgb *msg) -{ - struct generic_nack_t nack; - char buf[SMALL_BUFF]; - int rc; - - SMPP34_UNPACK(rc, GENERIC_NACK, &nack, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); - return rc; - } - - LOGP(DSMPP, LOGL_ERROR, "[%s] Rx GENERIC NACK: %s\n", - esme->system_id, str_command_status(nack.command_status, buf)); - - return 0; -} - -static int _process_bind(struct osmo_esme *esme, uint8_t if_version, - uint32_t bind_flags, const char *sys_id, - const char *passwd) -{ - struct osmo_smpp_acl *acl; - - if (if_version != SMPP_VERSION) - return ESME_RSYSERR; - - if (esme->bind_flags) - return ESME_RALYBND; - - esme->smpp_version = if_version; - snprintf(esme->system_id, sizeof(esme->system_id), "%s", sys_id); - - acl = smpp_acl_by_system_id(esme->smsc, esme->system_id); - if (!esme->smsc->accept_all) { - if (!acl) { - /* This system is unknown */ - return ESME_RINVSYSID; - } else { - if (strlen(acl->passwd) && - strcmp(acl->passwd, passwd)) { - return ESME_RINVPASWD; - } - } - } - if (acl) { - esme->acl = acl; - acl->esme = esme; - } - - esme->bind_flags = bind_flags; - - return ESME_ROK; -} - - -/*! \brief handle an incoming SMPP BIND RECEIVER */ -static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg) -{ - struct bind_receiver_t bind; - struct bind_receiver_resp_t bind_r; - int rc; - - SMPP34_UNPACK(rc, BIND_RECEIVER, &bind, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); - return rc; - } - - INIT_RESP(BIND_TRANSMITTER_RESP, &bind_r, &bind); - - LOGP(DSMPP, LOGL_INFO, "[%s] Rx BIND Rx from (Version %02x)\n", - bind.system_id, bind.interface_version); - - rc = _process_bind(esme, bind.interface_version, ESME_BIND_RX, - (const char *)bind.system_id, (const char *)bind.password); - bind_r.command_status = rc; - - return PACK_AND_SEND(esme, &bind_r); -} - -/*! \brief handle an incoming SMPP BIND TRANSMITTER */ -static int smpp_handle_bind_tx(struct osmo_esme *esme, struct msgb *msg) -{ - struct bind_transmitter_t bind; - struct bind_transmitter_resp_t bind_r; - struct tlv_t tlv; - int rc; - - SMPP34_UNPACK(rc, BIND_TRANSMITTER, &bind, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); - return rc; - } - - INIT_RESP(BIND_TRANSMITTER_RESP, &bind_r, &bind); - - LOGP(DSMPP, LOGL_INFO, "[%s] Rx BIND Tx (Version %02x)\n", - bind.system_id, bind.interface_version); - - rc = _process_bind(esme, bind.interface_version, ESME_BIND_TX, - (const char *)bind.system_id, (const char *)bind.password); - bind_r.command_status = rc; - - /* build response */ - snprintf((char *)bind_r.system_id, sizeof(bind_r.system_id), "%s", - esme->smsc->system_id); - - /* add interface version TLV */ - tlv.tag = TLVID_sc_interface_version; - tlv.length = sizeof(uint8_t); - tlv.value.val16 = esme->smpp_version; - build_tlv(&bind_r.tlv, &tlv); - - return PACK_AND_SEND(esme, &bind_r); -} - -/*! \brief handle an incoming SMPP BIND TRANSCEIVER */ -static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg) -{ - struct bind_transceiver_t bind; - struct bind_transceiver_resp_t bind_r; - int rc; - - SMPP34_UNPACK(rc, BIND_TRANSCEIVER, &bind, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); - return rc; - } - - INIT_RESP(BIND_TRANSCEIVER_RESP, &bind_r, &bind); - - LOGP(DSMPP, LOGL_INFO, "[%s] Rx BIND Trx (Version %02x)\n", - bind.system_id, bind.interface_version); - - rc = _process_bind(esme, bind.interface_version, ESME_BIND_RX|ESME_BIND_TX, - (const char *)bind.system_id, (const char *)bind.password); - bind_r.command_status = rc; - - return PACK_AND_SEND(esme, &bind_r); -} - -/*! \brief handle an incoming SMPP UNBIND */ -static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg) -{ - struct unbind_t unbind; - struct unbind_resp_t unbind_r; - int rc; - - SMPP34_UNPACK(rc, UNBIND, &unbind, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); - return rc; - } - - INIT_RESP(UNBIND_RESP, &unbind_r, &unbind); - - LOGP(DSMPP, LOGL_INFO, "[%s] Rx UNBIND\n", esme->system_id); - - if (esme->bind_flags == 0) { - unbind_r.command_status = ESME_RINVBNDSTS; - goto err; - } - - esme->bind_flags = 0; -err: - return PACK_AND_SEND(esme, &unbind_r); -} - -/*! \brief handle an incoming SMPP ENQUIRE LINK */ -static int smpp_handle_enq_link(struct osmo_esme *esme, struct msgb *msg) -{ - struct enquire_link_t enq; - struct enquire_link_resp_t enq_r; - int rc; - - SMPP34_UNPACK(rc, ENQUIRE_LINK, &enq, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); - return rc; - } - - LOGP(DSMPP, LOGL_DEBUG, "[%s] Rx Enquire Link\n", esme->system_id); - - INIT_RESP(ENQUIRE_LINK_RESP, &enq_r, &enq); - - LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx Enquire Link Response\n", esme->system_id); - - return PACK_AND_SEND(esme, &enq_r); -} - -/*! \brief send a SUBMIT-SM RESPONSE to a remote ESME */ -int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr, - uint32_t command_status, char *msg_id) -{ - struct submit_sm_resp_t submit_r; - - memset(&submit_r, 0, sizeof(submit_r)); - submit_r.command_length = 0; - submit_r.command_id = SUBMIT_SM_RESP; - submit_r.command_status = command_status; - submit_r.sequence_number= sequence_nr; - snprintf((char *) submit_r.message_id, sizeof(submit_r.message_id), "%s", msg_id); - - return PACK_AND_SEND(esme, &submit_r); -} - -static const struct value_string smpp_avail_strs[] = { - { 0, "Available" }, - { 1, "Denied" }, - { 2, "Unavailable" }, - { 0, NULL } -}; - -/*! \brief send an ALERT_NOTIFICATION to a remote ESME */ -int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi, - const char *addr, uint8_t avail_status) -{ - struct alert_notification_t alert; - struct tlv_t tlv; - - memset(&alert, 0, sizeof(alert)); - alert.command_length = 0; - alert.command_id = ALERT_NOTIFICATION; - alert.command_status = ESME_ROK; - alert.sequence_number = esme_inc_seq_nr(esme); - alert.source_addr_ton = ton; - alert.source_addr_npi = npi; - snprintf((char *)alert.source_addr, sizeof(alert.source_addr), "%s", addr); - - tlv.tag = TLVID_ms_availability_status; - tlv.length = sizeof(uint8_t); - tlv.value.val08 = avail_status; - build_tlv(&alert.tlv, &tlv); - - LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx ALERT_NOTIFICATION (%s/%u/%u): %s\n", - esme->system_id, alert.source_addr, alert.source_addr_ton, - alert.source_addr_npi, - get_value_string(smpp_avail_strs, avail_status)); - - return PACK_AND_SEND(esme, &alert); -} - -/* \brief send a DELIVER-SM message to given ESME */ -int smpp_tx_deliver(struct osmo_esme *esme, struct deliver_sm_t *deliver) -{ - deliver->sequence_number = esme_inc_seq_nr(esme); - - LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx DELIVER-SM (from %s)\n", - esme->system_id, deliver->source_addr); - - return PACK_AND_SEND(esme, deliver); -} - -/*! \brief handle an incoming SMPP DELIVER-SM RESPONSE */ -static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg) -{ - struct deliver_sm_resp_t deliver_r; - struct osmo_smpp_cmd *cmd; - int rc; - - memset(&deliver_r, 0, sizeof(deliver_r)); - SMPP34_UNPACK(rc, DELIVER_SM_RESP, &deliver_r, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); - return rc; - } - - cmd = smpp_cmd_find_by_seqnum(esme, deliver_r.sequence_number); - if (!cmd) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Rx DELIVER-SM RESP !? (%s)\n", - esme->system_id, get_value_string(smpp_status_strs, - deliver_r.command_status)); - return -1; - } - - if (deliver_r.command_status == ESME_ROK) - smpp_cmd_ack(cmd); - else - smpp_cmd_err(cmd, deliver_r.command_status); - - LOGP(DSMPP, LOGL_INFO, "[%s] Rx DELIVER-SM RESP (%s)\n", - esme->system_id, get_value_string(smpp_status_strs, - deliver_r.command_status)); - - return 0; -} - -/*! \brief handle an incoming SMPP SUBMIT-SM */ -static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg) -{ - struct submit_sm_t submit; - struct submit_sm_resp_t submit_r; - int rc; - - memset(&submit, 0, sizeof(submit)); - SMPP34_UNPACK(rc, SUBMIT_SM, &submit, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); - return rc; - } - - INIT_RESP(SUBMIT_SM_RESP, &submit_r, &submit); - - if (!(esme->bind_flags & ESME_BIND_TX)) { - submit_r.command_status = ESME_RINVBNDSTS; - return PACK_AND_SEND(esme, &submit_r); - } - - LOGP(DSMPP, LOGL_INFO, "[%s] Rx SUBMIT-SM (%s/%u/%u)\n", - esme->system_id, submit.destination_addr, - submit.dest_addr_ton, submit.dest_addr_npi); - - INIT_RESP(SUBMIT_SM_RESP, &submit_r, &submit); - - rc = handle_smpp_submit(esme, &submit, &submit_r); - if (rc == 0) - return PACK_AND_SEND(esme, &submit_r); - - return rc; -} - -/*! \brief one complete SMPP PDU from the ESME has been received */ -static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses) -{ - uint32_t cmd_id = smpp_msgb_cmdid(msg); - int rc = 0; - - LOGP(DSMPP, LOGL_DEBUG, "[%s] smpp_pdu_rx(%s)\n", esme->system_id, - osmo_hexdump(msgb_data(msg), msgb_length(msg))); - - switch (cmd_id) { - case GENERIC_NACK: - rc = smpp_handle_gen_nack(esme, msg); - break; - case BIND_RECEIVER: - rc = smpp_handle_bind_rx(esme, msg); - break; - case BIND_TRANSMITTER: - rc = smpp_handle_bind_tx(esme, msg); - break; - case BIND_TRANSCEIVER: - rc = smpp_handle_bind_trx(esme, msg); - break; - case UNBIND: - rc = smpp_handle_unbind(esme, msg); - break; - case ENQUIRE_LINK: - rc = smpp_handle_enq_link(esme, msg); - break; - case SUBMIT_SM: - rc = smpp_handle_submit(esme, msg); - break; - case DELIVER_SM_RESP: - rc = smpp_handle_deliver_resp(esme, msg); - break; - case DELIVER_SM: - break; - case DATA_SM: - break; - case CANCEL_SM: - case QUERY_SM: - case REPLACE_SM: - case SUBMIT_MULTI: - LOGP(DSMPP, LOGL_NOTICE, "[%s] Unimplemented PDU Command " - "0x%08x\n", esme->system_id, cmd_id); - break; - default: - LOGP(DSMPP, LOGL_ERROR, "[%s] Unknown PDU Command 0x%08x\n", - esme->system_id, cmd_id); - rc = smpp_tx_gen_nack(esme, smpp_msgb_seq(msg), ESME_RINVCMDID); - break; - } - - return rc; -} - -/* This macro should be called after a call to read() in the read_cb of an - * osmo_fd to properly check for errors. - * rc is the return value of read, err_label is the label to jump to in case of - * an error. The code there should handle closing the connection. - * FIXME: This code should go in libosmocore utils.h so it can be used by other - * projects as well. - * */ -#define OSMO_FD_CHECK_READ(rc, err_label) \ - if (rc < 0) { \ - /* EINTR is a non-fatal error, just try again */ \ - if (errno == EINTR) \ - return 0; \ - goto err_label; \ - } else if (rc == 0) { \ - goto err_label; \ - } - -/* !\brief call-back when per-ESME TCP socket has some data to be read */ -static int esme_link_read_cb(struct osmo_fd *ofd) -{ - struct osmo_esme *esme = ofd->data; - uint32_t len; - uint8_t *lenptr = (uint8_t *) &len; - uint8_t *cur; - struct msgb *msg; - ssize_t rdlen, rc; - - switch (esme->read_state) { - case READ_ST_IN_LEN: - rdlen = sizeof(uint32_t) - esme->read_idx; - rc = read(ofd->fd, lenptr + esme->read_idx, rdlen); - if (rc < 0) - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n", - esme->system_id, rc, strerror(errno)); - OSMO_FD_CHECK_READ(rc, dead_socket); - - esme->read_idx += rc; - - if (esme->read_idx >= sizeof(uint32_t)) { - esme->read_len = ntohl(len); - if (esme->read_len < 8 || esme->read_len > UINT16_MAX) { - LOGP(DSMPP, LOGL_ERROR, "[%s] length invalid %u\n", - esme->system_id, esme->read_len); - goto dead_socket; - } - - msg = msgb_alloc(esme->read_len, "SMPP Rx"); - if (!msg) - return -ENOMEM; - esme->read_msg = msg; - cur = msgb_put(msg, sizeof(uint32_t)); - memcpy(cur, lenptr, sizeof(uint32_t)); - esme->read_state = READ_ST_IN_MSG; - esme->read_idx = sizeof(uint32_t); - } - break; - case READ_ST_IN_MSG: - msg = esme->read_msg; - rdlen = esme->read_len - esme->read_idx; - rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg))); - if (rc < 0) - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n", - esme->system_id, rc, strerror(errno)); - OSMO_FD_CHECK_READ(rc, dead_socket); - - esme->read_idx += rc; - msgb_put(msg, rc); - - if (esme->read_idx >= esme->read_len) { - rc = smpp_pdu_rx(esme, esme->read_msg); - msgb_free(esme->read_msg); - esme->read_msg = NULL; - esme->read_idx = 0; - esme->read_len = 0; - esme->read_state = READ_ST_IN_LEN; - } - break; - } - - return 0; -dead_socket: - msgb_free(esme->read_msg); - osmo_fd_unregister(&esme->wqueue.bfd); - close(esme->wqueue.bfd.fd); - esme->wqueue.bfd.fd = -1; - smpp_esme_put(esme); - - return 0; -} - -/* call-back of write queue once it wishes to write a message to the socket */ -static int esme_link_write_cb(struct osmo_fd *ofd, struct msgb *msg) -{ - struct osmo_esme *esme = ofd->data; - int rc; - - rc = write(ofd->fd, msgb_data(msg), msgb_length(msg)); - if (rc == 0) { - osmo_fd_unregister(&esme->wqueue.bfd); - close(esme->wqueue.bfd.fd); - esme->wqueue.bfd.fd = -1; - smpp_esme_put(esme); - } else if (rc < msgb_length(msg)) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Short write\n", esme->system_id); - return -1; - } - - return 0; -} - -/* callback for already-accepted new TCP socket */ -static int link_accept_cb(struct smsc *smsc, int fd, - struct sockaddr_storage *s, socklen_t s_len) -{ - struct osmo_esme *esme = talloc_zero(smsc, struct osmo_esme); - if (!esme) { - close(fd); - return -ENOMEM; - } - - INIT_LLIST_HEAD(&esme->smpp_cmd_list); - smpp_esme_get(esme); - esme->own_seq_nr = rand(); - esme_inc_seq_nr(esme); - esme->smsc = smsc; - osmo_wqueue_init(&esme->wqueue, 10); - esme->wqueue.bfd.fd = fd; - esme->wqueue.bfd.data = esme; - esme->wqueue.bfd.when = BSC_FD_READ; - - if (osmo_fd_register(&esme->wqueue.bfd) != 0) { - close(fd); - talloc_free(esme); - return -EIO; - } - - esme->wqueue.read_cb = esme_link_read_cb; - esme->wqueue.write_cb = esme_link_write_cb; - - esme->sa_len = OSMO_MIN(sizeof(esme->sa), s_len); - memcpy(&esme->sa, s, esme->sa_len); - - llist_add_tail(&esme->list, &smsc->esme_list); - - return 0; -} - -/* callback of listening TCP socket */ -static int smsc_fd_cb(struct osmo_fd *ofd, unsigned int what) -{ - int rc; - struct sockaddr_storage sa; - socklen_t sa_len = sizeof(sa); - - rc = accept(ofd->fd, (struct sockaddr *)&sa, &sa_len); - if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "Accept returns %d (%s)\n", - rc, strerror(errno)); - return rc; - } - return link_accept_cb(ofd->data, rc, &sa, sa_len); -} - -/*! \brief allocate and initialize an smsc struct from talloc context ctx. */ -struct smsc *smpp_smsc_alloc_init(void *ctx) -{ - struct smsc *smsc = talloc_zero(ctx, struct smsc); - - INIT_LLIST_HEAD(&smsc->esme_list); - INIT_LLIST_HEAD(&smsc->acl_list); - INIT_LLIST_HEAD(&smsc->route_list); - - smsc->listen_ofd.data = smsc; - smsc->listen_ofd.cb = smsc_fd_cb; - - return smsc; -} - -/*! \brief Set the SMPP address and port without binding. */ -int smpp_smsc_conf(struct smsc *smsc, const char *bind_addr, uint16_t port) -{ - talloc_free((void*)smsc->bind_addr); - smsc->bind_addr = NULL; - if (bind_addr) { - smsc->bind_addr = talloc_strdup(smsc, bind_addr); - if (!smsc->bind_addr) - return -ENOMEM; - } - smsc->listen_port = port; - return 0; -} - -/*! \brief Bind to given address and port and accept connections. - * \param[in] bind_addr Local IP address, may be NULL for any. - * \param[in] port TCP port number, may be 0 for default SMPP (2775). - */ -int smpp_smsc_start(struct smsc *smsc, const char *bind_addr, uint16_t port) -{ - int rc; - - /* default port for SMPP */ - if (!port) - port = 2775; - - smpp_smsc_stop(smsc); - - LOGP(DSMPP, LOGL_NOTICE, "SMPP at %s %d\n", - bind_addr? bind_addr : "0.0.0.0", port); - - rc = osmo_sock_init_ofd(&smsc->listen_ofd, AF_UNSPEC, SOCK_STREAM, - IPPROTO_TCP, bind_addr, port, - OSMO_SOCK_F_BIND); - if (rc < 0) - return rc; - - /* store new address and port */ - rc = smpp_smsc_conf(smsc, bind_addr, port); - if (rc) - smpp_smsc_stop(smsc); - return rc; -} - -/*! \brief Change a running connection to a different address/port, and upon - * error switch back to the running configuration. */ -int smpp_smsc_restart(struct smsc *smsc, const char *bind_addr, uint16_t port) -{ - int rc; - - rc = smpp_smsc_start(smsc, bind_addr, port); - if (rc) - /* if there is an error, try to re-bind to the old port */ - return smpp_smsc_start(smsc, smsc->bind_addr, smsc->listen_port); - return 0; -} - -/*! /brief Close SMPP connection. */ -void smpp_smsc_stop(struct smsc *smsc) -{ - if (smsc->listen_ofd.fd > 0) { - close(smsc->listen_ofd.fd); - smsc->listen_ofd.fd = 0; - osmo_fd_unregister(&smsc->listen_ofd); - } -} diff --git a/src/libmsc/smpp_smsc.h b/src/libmsc/smpp_smsc.h deleted file mode 100644 index 755e68577..000000000 --- a/src/libmsc/smpp_smsc.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef _SMPP_SMSC_H -#define _SMPP_SMSC_H - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#define SMPP_SYS_ID_LEN 16 -#define SMPP_PASSWD_LEN 16 - -#define MODE_7BIT 7 -#define MODE_8BIT 8 - -enum esme_read_state { - READ_ST_IN_LEN = 0, - READ_ST_IN_MSG = 1, -}; - -struct osmo_smpp_acl; - -struct osmo_smpp_addr { - uint8_t ton; - uint8_t npi; - char addr[21+1]; -}; - -struct osmo_esme { - struct llist_head list; - struct smsc *smsc; - struct osmo_smpp_acl *acl; - int use; - - struct llist_head smpp_cmd_list; - - uint32_t own_seq_nr; - - struct osmo_wqueue wqueue; - struct sockaddr_storage sa; - socklen_t sa_len; - - enum esme_read_state read_state; - uint32_t read_len; - uint32_t read_idx; - struct msgb *read_msg; - - uint8_t smpp_version; - char system_id[SMPP_SYS_ID_LEN+1]; - - uint8_t bind_flags; -}; - -struct osmo_smpp_acl { - struct llist_head list; - struct smsc *smsc; - struct osmo_esme *esme; - char *description; - char system_id[SMPP_SYS_ID_LEN+1]; - char passwd[SMPP_PASSWD_LEN+1]; - int default_route; - int deliver_src_imsi; - int osmocom_ext; - int dcs_transparent; - struct llist_head route_list; -}; - -enum osmo_smpp_rtype { - SMPP_ROUTE_NONE, - SMPP_ROUTE_PREFIX, -}; - -struct osmo_smpp_route { - struct llist_head list; /*!< in acl.route_list */ - struct llist_head global_list; /*!< in smsc->route_list */ - struct osmo_smpp_acl *acl; - enum osmo_smpp_rtype type; - union { - struct osmo_smpp_addr prefix; - } u; -}; - -struct osmo_smpp_cmd { - struct llist_head list; - struct vlr_subscr *vsub; - uint32_t sequence_nr; - uint32_t gsm411_msg_ref; - uint8_t gsm411_trans_id; - bool is_report; - struct osmo_timer_list response_timer; -}; - -struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme, - uint32_t sequence_number); -void smpp_cmd_ack(struct osmo_smpp_cmd *cmd); -void smpp_cmd_err(struct osmo_smpp_cmd *cmd, uint32_t status); -void smpp_cmd_flush_pending(struct osmo_esme *esme); - -struct smsc { - struct osmo_fd listen_ofd; - struct llist_head esme_list; - struct llist_head acl_list; - struct llist_head route_list; - const char *bind_addr; - uint16_t listen_port; - char system_id[SMPP_SYS_ID_LEN+1]; - int accept_all; - int smpp_first; - struct osmo_smpp_acl *def_route; - void *priv; -}; - -int smpp_addr_eq(const struct osmo_smpp_addr *a, - const struct osmo_smpp_addr *b); - -struct smsc *smpp_smsc_alloc_init(void *ctx); -int smpp_smsc_conf(struct smsc *smsc, const char *bind_addr, uint16_t port); -int smpp_smsc_start(struct smsc *smsc, const char *bind_addr, uint16_t port); -int smpp_smsc_restart(struct smsc *smsc, const char *bind_addr, uint16_t port); -void smpp_smsc_stop(struct smsc *smsc); - -void smpp_esme_get(struct osmo_esme *esme); -void smpp_esme_put(struct osmo_esme *esme); - -int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct osmo_esme **emse); - -struct osmo_smpp_acl *smpp_acl_alloc(struct smsc *smsc, const char *sys_id); -struct osmo_smpp_acl *smpp_acl_by_system_id(struct smsc *smsc, - const char *sys_id); -void smpp_acl_delete(struct osmo_smpp_acl *acl); - -int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr, - uint32_t command_status, char *msg_id); - -int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi, - const char *addr, uint8_t avail_status); - -int smpp_tx_deliver(struct osmo_esme *esme, struct deliver_sm_t *deliver); - -int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit, - struct submit_sm_resp_t *submit_r); - -int smpp_route_pfx_add(struct osmo_smpp_acl *acl, - const struct osmo_smpp_addr *pfx); -int smpp_route_pfx_del(struct osmo_smpp_acl *acl, - const struct osmo_smpp_addr *pfx); - -int smpp_vty_init(void); - -int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode); - - - -struct gsm_sms; -struct gsm_subscriber_connection; - -int smpp_route_smpp_first(struct gsm_sms *sms, - struct gsm_subscriber_connection *conn); -int smpp_try_deliver(struct gsm_sms *sms, - struct gsm_subscriber_connection *conn); -#endif diff --git a/src/libmsc/smpp_utils.c b/src/libmsc/smpp_utils.c deleted file mode 100644 index d0850d8c1..000000000 --- a/src/libmsc/smpp_utils.c +++ /dev/null @@ -1,62 +0,0 @@ - -/* (C) 2012-2013 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - */ - - -#include "smpp_smsc.h" -#include - - -int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode) -{ - if ((dcs & 0xF0) == 0xF0) { - if (dcs & 0x04) { - /* bit 2 == 1: 8bit data */ - *data_coding = 0x02; - *mode = MODE_8BIT; - } else { - /* bit 2 == 0: default alphabet */ - *data_coding = 0x01; - *mode = MODE_7BIT; - } - } else if ((dcs & 0xE0) == 0) { - switch (dcs & 0xC) { - case 0: - *data_coding = 0x01; - *mode = MODE_7BIT; - break; - case 4: - *data_coding = 0x02; - *mode = MODE_8BIT; - break; - case 8: - *data_coding = 0x08; /* UCS-2 */ - *mode = MODE_8BIT; - break; - default: - goto unknown_mo; - } - } else { -unknown_mo: - LOGP(DLSMS, LOGL_ERROR, "SMPP MO Unknown Data Coding 0x%02x\n", dcs); - return -1; - } - - return 0; - -} diff --git a/src/libmsc/smpp_vty.c b/src/libmsc/smpp_vty.c deleted file mode 100644 index 13467f182..000000000 --- a/src/libmsc/smpp_vty.c +++ /dev/null @@ -1,612 +0,0 @@ -/* SMPP vty interface */ - -/* (C) 2012 by Harald Welte - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include "smpp_smsc.h" - -struct smsc *smsc_from_vty(struct vty *v); - -static struct cmd_node smpp_node = { - SMPP_NODE, - "%s(config-smpp)# ", - 1, -}; - -static struct cmd_node esme_node = { - SMPP_ESME_NODE, - "%s(config-smpp-esme)# ", - 1, -}; - -DEFUN(cfg_smpp, cfg_smpp_cmd, - "smpp", "Configure SMPP SMS Interface") -{ - vty->node = SMPP_NODE; - - return CMD_SUCCESS; -} - -DEFUN(cfg_smpp_first, cfg_smpp_first_cmd, - "smpp-first", - "Try SMPP routes before the subscriber DB\n") -{ - struct smsc *smsc = smsc_from_vty(vty); - smsc->smpp_first = 1; - return CMD_SUCCESS; -} - -DEFUN(cfg_no_smpp_first, cfg_no_smpp_first_cmd, - "no smpp-first", - NO_STR "Try SMPP before routes before the subscriber DB\n") -{ - struct smsc *smsc = smsc_from_vty(vty); - smsc->smpp_first = 0; - return CMD_SUCCESS; -} - -static int smpp_local_tcp(struct vty *vty, - const char *bind_addr, uint16_t port) -{ - struct smsc *smsc = smsc_from_vty(vty); - int is_running = smsc->listen_ofd.fd > 0; - int same_bind_addr; - int rc; - - /* If it is not up yet, don't rebind, just set values. */ - if (!is_running) { - rc = smpp_smsc_conf(smsc, bind_addr, port); - if (rc < 0) { - vty_out(vty, "%% Cannot configure new address:port%s", - VTY_NEWLINE); - return CMD_WARNING; - } - return CMD_SUCCESS; - } - - rc = smpp_smsc_restart(smsc, bind_addr, port); - if (rc < 0) { - vty_out(vty, "%% Cannot bind to new port %s:%u nor to" - " old port %s:%u%s", - bind_addr? bind_addr : "0.0.0.0", - port, - smsc->bind_addr? smsc->bind_addr : "0.0.0.0", - smsc->listen_port, - VTY_NEWLINE); - return CMD_WARNING; - } - - same_bind_addr = (bind_addr == smsc->bind_addr) - || (bind_addr && smsc->bind_addr - && (strcmp(bind_addr, smsc->bind_addr) == 0)); - - if (!same_bind_addr || port != smsc->listen_port) { - vty_out(vty, "%% Cannot bind to new port %s:%u, staying on" - " old port %s:%u%s", - bind_addr? bind_addr : "0.0.0.0", - port, - smsc->bind_addr? smsc->bind_addr : "0.0.0.0", - smsc->listen_port, - VTY_NEWLINE); - return CMD_WARNING; - } - - return CMD_SUCCESS; -} - -DEFUN(cfg_smpp_port, cfg_smpp_port_cmd, - "local-tcp-port <1-65535>", - "Set the local TCP port on which we listen for SMPP\n" - "TCP port number") -{ - struct smsc *smsc = smsc_from_vty(vty); - uint16_t port = atoi(argv[0]); - return smpp_local_tcp(vty, smsc->bind_addr, port); -} - -DEFUN(cfg_smpp_addr_port, cfg_smpp_addr_port_cmd, - "local-tcp-ip A.B.C.D <1-65535>", - "Set the local IP address and TCP port on which we listen for SMPP\n" - "Local IP address\n" - "TCP port number") -{ - const char *bind_addr = argv[0]; - uint16_t port = atoi(argv[1]); - return smpp_local_tcp(vty, bind_addr, port); -} - -DEFUN(cfg_smpp_sys_id, cfg_smpp_sys_id_cmd, - "system-id ID", - "Set the System ID of this SMSC\n" - "Alphanumeric SMSC System ID\n") -{ - struct smsc *smsc = smsc_from_vty(vty); - - if (strlen(argv[0])+1 > sizeof(smsc->system_id)) - return CMD_WARNING; - - strcpy(smsc->system_id, argv[0]); - - return CMD_SUCCESS; -} - -DEFUN(cfg_smpp_policy, cfg_smpp_policy_cmd, - "policy (accept-all|closed)", - "Set the authentication policy of this SMSC\n" - "Accept all SMPP connections independeint of system ID / passwd\n" - "Accept only SMPP connections from ESMEs explicitly configured") -{ - struct smsc *smsc = smsc_from_vty(vty); - - if (!strcmp(argv[0], "accept-all")) - smsc->accept_all = 1; - else - smsc->accept_all = 0; - - return CMD_SUCCESS; -} - - -static int config_write_smpp(struct vty *vty) -{ - struct smsc *smsc = smsc_from_vty(vty); - - vty_out(vty, "smpp%s", VTY_NEWLINE); - if (smsc->bind_addr) - vty_out(vty, " local-tcp-ip %s %u%s", smsc->bind_addr, - smsc->listen_port, VTY_NEWLINE); - else - vty_out(vty, " local-tcp-port %u%s", smsc->listen_port, - VTY_NEWLINE); - if (strlen(smsc->system_id) > 0) - vty_out(vty, " system-id %s%s", smsc->system_id, VTY_NEWLINE); - vty_out(vty, " policy %s%s", - smsc->accept_all ? "accept-all" : "closed", VTY_NEWLINE); - vty_out(vty, " %ssmpp-first%s", - smsc->smpp_first ? "" : "no ", VTY_NEWLINE); - - return CMD_SUCCESS; -} - -DEFUN(cfg_esme, cfg_esme_cmd, - "esme NAME", - "Configure a particular ESME\n" - "Alphanumeric System ID of the ESME to be configured\n") -{ - struct smsc *smsc = smsc_from_vty(vty); - struct osmo_smpp_acl *acl; - const char *id = argv[0]; - - if (strlen(id) > 16) { - vty_out(vty, "%% System ID cannot be more than 16 " - "characters long%s", VTY_NEWLINE); - return CMD_WARNING; - } - acl = smpp_acl_by_system_id(smsc, id); - if (!acl) { - acl = smpp_acl_alloc(smsc, id); - if (!acl) - return CMD_WARNING; - } - - vty->index = acl; - vty->index_sub = &acl->description; - vty->node = SMPP_ESME_NODE; - - return CMD_SUCCESS; -} - -DEFUN(cfg_no_esme, cfg_no_esme_cmd, - "no esme NAME", - NO_STR "Remove ESME configuration\n" - "Alphanumeric System ID of the ESME to be removed\n") -{ - struct smsc *smsc = smsc_from_vty(vty); - struct osmo_smpp_acl *acl; - const char *id = argv[0]; - - acl = smpp_acl_by_system_id(smsc, id); - if (!acl) { - vty_out(vty, "%% ESME with system id '%s' unknown%s", - id, VTY_NEWLINE); - return CMD_WARNING; - } - - /* FIXME: close the connection, free data structure, etc. */ - - smpp_acl_delete(acl); - - return CMD_SUCCESS; -} - - -DEFUN(cfg_esme_passwd, cfg_esme_passwd_cmd, - "password PASSWORD", - "Set the password for this ESME\n" - "Alphanumeric password string\n") -{ - struct osmo_smpp_acl *acl = vty->index; - - if (strlen(argv[0])+1 > sizeof(acl->passwd)) - return CMD_WARNING; - - strcpy(acl->passwd, argv[0]); - - return CMD_SUCCESS; -} - -DEFUN(cfg_esme_no_passwd, cfg_esme_no_passwd_cmd, - "no password", - NO_STR "Remove the password for this ESME\n") -{ - struct osmo_smpp_acl *acl = vty->index; - - memset(acl->passwd, 0, sizeof(acl->passwd)); - - return CMD_SUCCESS; -} - -static int osmo_is_digits(const char *str) -{ - int i; - for (i = 0; i < strlen(str); i++) { - if (!isdigit(str[i])) - return 0; - } - return 1; -} - -static const struct value_string route_errstr[] = { - { -EEXIST, "Route already exists" }, - { -ENODEV, "Route does not exist" }, - { -ENOMEM, "No memory" }, - { -EINVAL, "Invalid" }, - { 0, NULL } -}; - -static const struct value_string smpp_ton_str_short[] = { - { TON_Unknown, "unknown" }, - { TON_International, "international" }, - { TON_National, "national" }, - { TON_Network_Specific, "network" }, - { TON_Subscriber_Number,"subscriber" }, - { TON_Alphanumeric, "alpha" }, - { TON_Abbreviated, "abbrev" }, - { 0, NULL } -}; - -static const struct value_string smpp_npi_str_short[] = { - { NPI_Unknown, "unknown" }, - { NPI_ISDN_E163_E164, "isdn" }, - { NPI_Data_X121, "x121" }, - { NPI_Telex_F69, "f69" }, - { NPI_Land_Mobile_E212, "e212" }, - { NPI_National, "national" }, - { NPI_Private, "private" }, - { NPI_ERMES, "ermes" }, - { NPI_Internet_IP, "ip" }, - { NPI_WAP_Client_Id, "wap" }, - { 0, NULL } -}; - - -#define SMPP_ROUTE_STR "Configure a route for MO-SMS to be sent to this ESME\n" -#define SMPP_ROUTE_P_STR SMPP_ROUTE_STR "Prefix-match route\n" -#define SMPP_PREFIX_STR "Destination number prefix\n" - -#define TON_CMD "(unknown|international|national|network|subscriber|alpha|abbrev)" -#define NPI_CMD "(unknown|isdn|x121|f69|e212|national|private|ermes|ip|wap)" -#define TON_STR "Unknown type-of-number\n" \ - "International type-of-number\n" \ - "National type-of-number\n" \ - "Network specific type-of-number\n" \ - "Subscriber type-of-number\n" \ - "Alphanumeric type-of-number\n" \ - "Abbreviated type-of-number\n" -#define NPI_STR "Unknown numbering plan\n" \ - "ISDN (E.164) numbering plan\n" \ - "X.121 numbering plan\n" \ - "F.69 numbering plan\n" \ - "E.212 numbering plan\n" \ - "National numbering plan\n" \ - "Private numbering plan\n" \ - "ERMES numbering plan\n" \ - "IP numbering plan\n" \ - "WAP numbeing plan\n" - -DEFUN(cfg_esme_route_pfx, cfg_esme_route_pfx_cmd, - "route prefix " TON_CMD " " NPI_CMD " PREFIX", - SMPP_ROUTE_P_STR TON_STR NPI_STR SMPP_PREFIX_STR) -{ - struct osmo_smpp_acl *acl = vty->index; - struct osmo_smpp_addr pfx; - int rc; - - /* check if DESTINATION is all-digits */ - if (!osmo_is_digits(argv[2])) { - vty_out(vty, "%% PREFIX has to be numeric%s", VTY_NEWLINE); - return CMD_WARNING; - } - - pfx.ton = get_string_value(smpp_ton_str_short, argv[0]); - pfx.npi = get_string_value(smpp_npi_str_short, argv[1]); - snprintf(pfx.addr, sizeof(pfx.addr), "%s", argv[2]); - - rc = smpp_route_pfx_add(acl, &pfx); - if (rc < 0) { - vty_out(vty, "%% error adding prefix route: %s%s", - get_value_string(route_errstr, rc), VTY_NEWLINE); - return CMD_WARNING; - } - - return CMD_SUCCESS; -} - -DEFUN(cfg_esme_no_route_pfx, cfg_esme_no_route_pfx_cmd, - "no route prefix " TON_CMD " " NPI_CMD " PREFIX", - NO_STR SMPP_ROUTE_P_STR TON_STR NPI_STR SMPP_PREFIX_STR) -{ - struct osmo_smpp_acl *acl = vty->index; - struct osmo_smpp_addr pfx; - int rc; - - /* check if DESTINATION is all-digits */ - if (!osmo_is_digits(argv[2])) { - vty_out(vty, "%% PREFIX has to be numeric%s", VTY_NEWLINE); - return CMD_WARNING; - } - - pfx.ton = get_string_value(smpp_ton_str_short, argv[0]); - pfx.npi = get_string_value(smpp_npi_str_short, argv[1]); - snprintf(pfx.addr, sizeof(pfx.addr), "%s", argv[2]); - - rc = smpp_route_pfx_del(acl, &pfx); - if (rc < 0) { - vty_out(vty, "%% error removing prefix route: %s%s", - get_value_string(route_errstr, rc), VTY_NEWLINE); - return CMD_WARNING; - } - - return CMD_SUCCESS; - -} - - -DEFUN(cfg_esme_defaultroute, cfg_esme_defaultroute_cmd, - "default-route", - "Set this ESME as default-route for all SMS to unknown destinations") -{ - struct osmo_smpp_acl *acl = vty->index; - - acl->default_route = 1; - - if (!acl->smsc->def_route) - acl->smsc->def_route = acl; - - return CMD_SUCCESS; -} - -DEFUN(cfg_no_esme_defaultroute, cfg_esme_no_defaultroute_cmd, - "no default-route", NO_STR - "Remove this ESME as default-route for all SMS to unknown destinations") -{ - struct osmo_smpp_acl *acl = vty->index; - - acl->default_route = 0; - - /* remove currently active default route, if it was created by - * this ACL */ - if (acl->smsc->def_route && acl->smsc->def_route == acl) - acl->smsc->def_route = NULL; - - return CMD_SUCCESS; -} - -DEFUN(cfg_esme_del_src_imsi, cfg_esme_del_src_imsi_cmd, - "deliver-src-imsi", - "Enable the use of IMSI as source address in DELIVER") -{ - struct osmo_smpp_acl *acl = vty->index; - - acl->deliver_src_imsi = 1; - - return CMD_SUCCESS; -} - -DEFUN(cfg_esme_no_del_src_imsi, cfg_esme_no_del_src_imsi_cmd, - "no deliver-src-imsi", NO_STR - "Disable the use of IMSI as source address in DELIVER") -{ - struct osmo_smpp_acl *acl = vty->index; - - acl->deliver_src_imsi = 0; - - return CMD_SUCCESS; -} - -DEFUN(cfg_esme_osmo_ext, cfg_esme_osmo_ext_cmd, - "osmocom-extensions", - "Enable the use of Osmocom SMPP Extensions for this ESME") -{ - struct osmo_smpp_acl *acl = vty->index; - - acl->osmocom_ext = 1; - - return CMD_SUCCESS; -} - -DEFUN(cfg_esme_no_osmo_ext, cfg_esme_no_osmo_ext_cmd, - "no osmocom-extensions", NO_STR - "Disable the use of Osmocom SMPP Extensions for this ESME") -{ - struct osmo_smpp_acl *acl = vty->index; - - acl->osmocom_ext = 0; - - return CMD_SUCCESS; -} - -DEFUN(cfg_esme_dcs_transp, cfg_esme_dcs_transp_cmd, - "dcs-transparent", - "Enable the transparent pass-through of TP-DCS to SMPP DataCoding") -{ - struct osmo_smpp_acl *acl = vty->index; - - acl->dcs_transparent = 1; - - return CMD_SUCCESS; -} - -DEFUN(cfg_esme_no_dcs_transp, cfg_esme_no_dcs_transp_cmd, - "no dcs-transparent", NO_STR - "Disable the transparent pass-through of TP-DCS to SMPP DataCoding") -{ - struct osmo_smpp_acl *acl = vty->index; - - acl->dcs_transparent = 0; - - return CMD_SUCCESS; -} - - -static void dump_one_esme(struct vty *vty, struct osmo_esme *esme) -{ - char host[128], serv[128]; - - host[0] = 0; - serv[0] = 0; - getnameinfo((const struct sockaddr *) &esme->sa, esme->sa_len, - host, sizeof(host), serv, sizeof(serv), NI_NUMERICSERV); - - vty_out(vty, "ESME System ID: %s, Password: %s, SMPP Version %02x%s", - esme->system_id, esme->acl ? esme->acl->passwd : "", - esme->smpp_version, VTY_NEWLINE); - vty_out(vty, " Connected from: %s:%s%s", host, serv, VTY_NEWLINE); - if (esme->smsc->def_route == esme->acl) - vty_out(vty, " Is current default route%s", VTY_NEWLINE); -} - -DEFUN(show_esme, show_esme_cmd, - "show smpp esme", - SHOW_STR "SMPP Interface\n" "SMPP Extrenal SMS Entity\n") -{ - struct smsc *smsc = smsc_from_vty(vty); - struct osmo_esme *esme; - - llist_for_each_entry(esme, &smsc->esme_list, list) - dump_one_esme(vty, esme); - - return CMD_SUCCESS; -} - -static void write_esme_route_single(struct vty *vty, struct osmo_smpp_route *r) -{ - switch (r->type) { - case SMPP_ROUTE_PREFIX: - vty_out(vty, " route prefix %s ", - get_value_string(smpp_ton_str_short, r->u.prefix.ton)); - vty_out(vty, "%s %s%s", - get_value_string(smpp_npi_str_short, r->u.prefix.npi), - r->u.prefix.addr, VTY_NEWLINE); - break; - case SMPP_ROUTE_NONE: - break; - } -} - -static void config_write_esme_single(struct vty *vty, struct osmo_smpp_acl *acl) -{ - struct osmo_smpp_route *r; - - vty_out(vty, " esme %s%s", acl->system_id, VTY_NEWLINE); - if (strlen(acl->passwd)) - vty_out(vty, " password %s%s", acl->passwd, VTY_NEWLINE); - if (acl->default_route) - vty_out(vty, " default-route%s", VTY_NEWLINE); - if (acl->deliver_src_imsi) - vty_out(vty, " deliver-src-imsi%s", VTY_NEWLINE); - if (acl->osmocom_ext) - vty_out(vty, " osmocom-extensions%s", VTY_NEWLINE); - if (acl->dcs_transparent) - vty_out(vty, " dcs-transparent%s", VTY_NEWLINE); - - llist_for_each_entry(r, &acl->route_list, list) - write_esme_route_single(vty, r); -} - -static int config_write_esme(struct vty *v) -{ - struct smsc *smsc = smsc_from_vty(v); - struct osmo_smpp_acl *acl; - - llist_for_each_entry(acl, &smsc->acl_list, list) - config_write_esme_single(v, acl); - - return CMD_SUCCESS; -} - -int smpp_vty_init(void) -{ - install_node(&smpp_node, config_write_smpp); - vty_install_default(SMPP_NODE); - install_element(CONFIG_NODE, &cfg_smpp_cmd); - - install_element(SMPP_NODE, &cfg_smpp_first_cmd); - install_element(SMPP_NODE, &cfg_no_smpp_first_cmd); - install_element(SMPP_NODE, &cfg_smpp_port_cmd); - install_element(SMPP_NODE, &cfg_smpp_addr_port_cmd); - install_element(SMPP_NODE, &cfg_smpp_sys_id_cmd); - install_element(SMPP_NODE, &cfg_smpp_policy_cmd); - install_element(SMPP_NODE, &cfg_esme_cmd); - install_element(SMPP_NODE, &cfg_no_esme_cmd); - - install_node(&esme_node, config_write_esme); - vty_install_default(SMPP_ESME_NODE); - install_element(SMPP_ESME_NODE, &cfg_esme_passwd_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_no_passwd_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_route_pfx_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_no_route_pfx_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_defaultroute_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_no_defaultroute_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_del_src_imsi_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_no_del_src_imsi_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_osmo_ext_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_no_osmo_ext_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_dcs_transp_cmd); - install_element(SMPP_ESME_NODE, &cfg_esme_no_dcs_transp_cmd); - - install_element_ve(&show_esme_cmd); - - return 0; -} diff --git a/src/libmsc/sms_queue.c b/src/libmsc/sms_queue.c deleted file mode 100644 index fe7a608be..000000000 --- a/src/libmsc/sms_queue.c +++ /dev/null @@ -1,578 +0,0 @@ -/* SMS queue to continously attempt to deliver SMS */ -/* - * (C) 2010 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -/** - * The difficulty of such a queue is to send a lot of SMS without - * overloading the paging subsystem and the database and other users - * of the MSC. To make the best use we would need to know the number - * of pending paging requests, then throttle the number of SMS we - * want to send and such. - * We will start with a very simple SMS Queue and then try to speed - * things up by collecting data from other parts of the system. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -/* - * One pending SMS that we wait for. - */ -struct gsm_sms_pending { - struct llist_head entry; - - struct vlr_subscr *vsub; - unsigned long long sms_id; - int failed_attempts; - int resend; -}; - -struct gsm_sms_queue { - struct osmo_timer_list resend_pending; - struct osmo_timer_list push_queue; - struct gsm_network *network; - int max_fail; - int max_pending; - int pending; - - struct llist_head pending_sms; - - char last_msisdn[GSM_EXTENSION_LENGTH+1]; -}; - -static int sms_subscr_cb(unsigned int, unsigned int, void *, void *); -static int sms_sms_cb(unsigned int, unsigned int, void *, void *); - -static struct gsm_sms_pending *sms_find_pending(struct gsm_sms_queue *smsq, - struct gsm_sms *sms) -{ - struct gsm_sms_pending *pending; - - llist_for_each_entry(pending, &smsq->pending_sms, entry) { - if (pending->sms_id == sms->id) - return pending; - } - - return NULL; -} - -static int sms_is_in_pending(struct gsm_sms_queue *smsq, struct gsm_sms *sms) -{ - return sms_find_pending(smsq, sms) != NULL; -} - -static struct gsm_sms_pending *sms_subscriber_find_pending( - struct gsm_sms_queue *smsq, - struct vlr_subscr *vsub) -{ - struct gsm_sms_pending *pending; - - llist_for_each_entry(pending, &smsq->pending_sms, entry) { - if (pending->vsub == vsub) - return pending; - } - - return NULL; -} - -static int sms_subscriber_is_pending(struct gsm_sms_queue *smsq, - struct vlr_subscr *vsub) -{ - return sms_subscriber_find_pending(smsq, vsub) != NULL; -} - -static struct gsm_sms_pending *sms_pending_from(struct gsm_sms_queue *smsq, - struct gsm_sms *sms) -{ - struct gsm_sms_pending *pending; - - pending = talloc_zero(smsq, struct gsm_sms_pending); - if (!pending) - return NULL; - - pending->vsub = vlr_subscr_get(sms->receiver); - pending->sms_id = sms->id; - return pending; -} - -static void sms_pending_free(struct gsm_sms_pending *pending) -{ - vlr_subscr_put(pending->vsub); - llist_del(&pending->entry); - talloc_free(pending); -} - -static void sms_pending_resend(struct gsm_sms_pending *pending) -{ - struct gsm_network *net = pending->vsub->vlr->user_ctx; - struct gsm_sms_queue *smsq; - LOGP(DLSMS, LOGL_DEBUG, - "Scheduling resend of SMS %llu.\n", pending->sms_id); - - pending->resend = 1; - - smsq = net->sms_queue; - if (osmo_timer_pending(&smsq->resend_pending)) - return; - - osmo_timer_schedule(&smsq->resend_pending, 1, 0); -} - -static void sms_pending_failed(struct gsm_sms_pending *pending, int paging_error) -{ - struct gsm_network *net = pending->vsub->vlr->user_ctx; - struct gsm_sms_queue *smsq; - - LOGP(DLSMS, LOGL_NOTICE, "Sending SMS %llu failed %d times.\n", - pending->sms_id, pending->failed_attempts); - - smsq = net->sms_queue; - if (++pending->failed_attempts < smsq->max_fail) - return sms_pending_resend(pending); - - sms_pending_free(pending); - smsq->pending -= 1; - sms_queue_trigger(smsq); -} - -/* - * Resend all SMS that are scheduled for a resend. This is done to - * avoid an immediate failure. - */ -static void sms_resend_pending(void *_data) -{ - struct gsm_sms_pending *pending, *tmp; - struct gsm_sms_queue *smsq = _data; - - llist_for_each_entry_safe(pending, tmp, &smsq->pending_sms, entry) { - struct gsm_sms *sms; - if (!pending->resend) - continue; - - sms = db_sms_get(smsq->network, pending->sms_id); - - /* the sms is gone? Move to the next */ - if (!sms) { - sms_pending_free(pending); - smsq->pending -= 1; - sms_queue_trigger(smsq); - } else { - pending->resend = 0; - gsm411_send_sms_subscr(sms->receiver, sms); - } - } -} - -/* Find the next pending SMS by cycling through the recipients. We could also - * cycle through the pending SMS, but that might cause us to keep trying to - * send SMS to the same few subscribers repeatedly while not servicing other - * subscribers for a long time. By walking the list of recipient MSISDNs, we - * ensure that all subscribers get their fair time to receive SMS. */ -struct gsm_sms *smsq_take_next_sms(struct gsm_network *net, - char *last_msisdn, - size_t last_msisdn_buflen) -{ - struct gsm_sms *sms; - int wrapped = 0; - int sanity = 100; - char started_with_msisdn[last_msisdn_buflen]; - - osmo_strlcpy(started_with_msisdn, last_msisdn, - sizeof(started_with_msisdn)); - - while (wrapped < 2 && (--sanity)) { - /* If we wrapped around and passed the first msisdn, we're - * through the entire SMS DB; end it. */ - if (wrapped && strcmp(last_msisdn, started_with_msisdn) >= 0) - break; - - sms = db_sms_get_next_unsent_rr_msisdn(net, last_msisdn, 9); - if (!sms) { - last_msisdn[0] = '\0'; - wrapped ++; - continue; - } - - /* Whatever happens, next time around service another recipient - */ - osmo_strlcpy(last_msisdn, sms->dst.addr, last_msisdn_buflen); - - /* Is the subscriber attached? If not, go to next SMS */ - if (!sms->receiver || !sms->receiver->lu_complete) - continue; - - return sms; - } - - DEBUGP(DLSMS, "SMS queue: no SMS to be sent\n"); - return NULL; -} - -/** - * I will submit up to max_pending - pending SMS to the - * subsystem. - */ -static void sms_submit_pending(void *_data) -{ - struct gsm_sms_queue *smsq = _data; - int attempts = smsq->max_pending - smsq->pending; - int initialized = 0; - unsigned long long first_sub = 0; - int attempted = 0, rounds = 0; - - LOGP(DLSMS, LOGL_DEBUG, "Attempting to send %d SMS\n", attempts); - - do { - struct gsm_sms_pending *pending; - struct gsm_sms *sms; - - - sms = smsq_take_next_sms(smsq->network, smsq->last_msisdn, - sizeof(smsq->last_msisdn)); - if (!sms) { - LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (%d attempted)\n", - attempted); - break; - } - - rounds += 1; - LOGP(DLSMS, LOGL_DEBUG, "Sending SMS round %d\n", rounds); - - /* - * This code needs to detect a loop. It assumes that no SMS - * will vanish during the time this is executed. We will remember - * the id of the first GSM subscriber we see and then will - * compare this. The Database code should make sure that we will - * see all other subscribers first before seeing this one again. - * - * It is always scary to have an infinite loop like this. - */ - if (!initialized) { - first_sub = sms->receiver->id; - initialized = 1; - } else if (first_sub == sms->receiver->id) { - LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (loop) (%d attempted)\n", - attempted); - sms_free(sms); - break; - } - - /* no need to send a pending sms */ - if (sms_is_in_pending(smsq, sms)) { - LOGP(DLSMS, LOGL_DEBUG, - "SMSqueue with pending sms: %llu. Skipping\n", sms->id); - sms_free(sms); - continue; - } - - /* no need to send a SMS with the same receiver */ - if (sms_subscriber_is_pending(smsq, sms->receiver)) { - LOGP(DLSMS, LOGL_DEBUG, - "SMSqueue with pending sub: %llu. Skipping\n", sms->receiver->id); - sms_free(sms); - continue; - } - - pending = sms_pending_from(smsq, sms); - if (!pending) { - LOGP(DLSMS, LOGL_ERROR, - "Failed to create pending SMS entry.\n"); - sms_free(sms); - continue; - } - - attempted += 1; - smsq->pending += 1; - llist_add_tail(&pending->entry, &smsq->pending_sms); - gsm411_send_sms_subscr(sms->receiver, sms); - } while (attempted < attempts && rounds < 1000); - - LOGP(DLSMS, LOGL_DEBUG, "SMSqueue added %d messages in %d rounds\n", attempted, rounds); -} - -/** - * Send the next SMS or trigger the queue - */ -static void sms_send_next(struct vlr_subscr *vsub) -{ - struct gsm_network *net = vsub->vlr->user_ctx; - struct gsm_sms_queue *smsq = net->sms_queue; - struct gsm_sms_pending *pending; - struct gsm_sms *sms; - - /* the subscriber should not be in the queue */ - OSMO_ASSERT(!sms_subscriber_is_pending(smsq, vsub)); - - /* check for more messages for this subscriber */ - sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX); - if (!sms) - goto no_pending_sms; - - /* The sms should not be scheduled right now */ - OSMO_ASSERT(!sms_is_in_pending(smsq, sms)); - - /* Remember that we deliver this SMS and send it */ - pending = sms_pending_from(smsq, sms); - if (!pending) { - LOGP(DLSMS, LOGL_ERROR, - "Failed to create pending SMS entry.\n"); - sms_free(sms); - goto no_pending_sms; - } - - smsq->pending += 1; - llist_add_tail(&pending->entry, &smsq->pending_sms); - gsm411_send_sms_subscr(sms->receiver, sms); - return; - -no_pending_sms: - /* Try to send the SMS to avoid the queue being stuck */ - sms_submit_pending(net->sms_queue); -} - -/* - * Kick off the queue again. - */ -int sms_queue_trigger(struct gsm_sms_queue *smsq) -{ - LOGP(DLSMS, LOGL_DEBUG, "Triggering SMS queue\n"); - if (osmo_timer_pending(&smsq->push_queue)) - return 0; - - osmo_timer_schedule(&smsq->push_queue, 1, 0); - return 0; -} - -int sms_queue_start(struct gsm_network *network, int max_pending) -{ - struct gsm_sms_queue *sms = talloc_zero(network, struct gsm_sms_queue); - if (!sms) { - LOGP(DMSC, LOGL_ERROR, "Failed to create the SMS queue.\n"); - return -1; - } - - osmo_signal_register_handler(SS_SUBSCR, sms_subscr_cb, network); - osmo_signal_register_handler(SS_SMS, sms_sms_cb, network); - - network->sms_queue = sms; - INIT_LLIST_HEAD(&sms->pending_sms); - sms->max_fail = 1; - sms->network = network; - sms->max_pending = max_pending; - osmo_timer_setup(&sms->push_queue, sms_submit_pending, sms); - osmo_timer_setup(&sms->resend_pending, sms_resend_pending, sms); - - sms_submit_pending(sms); - - return 0; -} - -static int sub_ready_for_sm(struct gsm_network *net, struct vlr_subscr *vsub) -{ - struct gsm_sms *sms; - struct gsm_sms_pending *pending; - struct gsm_subscriber_connection *conn; - - /* - * The code used to be very clever and tried to submit - * a SMS during the Location Updating Request. This has - * two issues: - * 1.) The Phone might not be ready yet, e.g. the C155 - * will not respond to the Submit when it is booting. - * 2.) The queue is already trying to submit SMS to the - * user and by not responding to the paging request - * we will set the LAC back to 0. We would have to - * stop the paging and move things over. - * - * We need to be careful in what we try here. - */ - - /* check if we have pending requests */ - pending = sms_subscriber_find_pending(net->sms_queue, vsub); - if (pending) { - LOGP(DMSC, LOGL_NOTICE, - "Pending paging while subscriber %llu attached.\n", - vsub->id); - return 0; - } - - conn = connection_for_subscr(vsub); - if (!conn) - return -1; - - /* Now try to deliver any pending SMS to this sub */ - sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX); - if (!sms) - return -1; - gsm411_send_sms(conn, sms); - return 0; -} - -static int sms_subscr_cb(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct vlr_subscr *vsub = signal_data; - - if (signal != S_SUBSCR_ATTACHED) - return 0; - - /* this is readyForSM */ - return sub_ready_for_sm(handler_data, vsub); -} - -static int sms_sms_cb(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct gsm_network *network = handler_data; - struct sms_signal_data *sig_sms = signal_data; - struct gsm_sms_pending *pending; - struct vlr_subscr *vsub; - - /* We got a new SMS and maybe should launch the queue again. */ - if (signal == S_SMS_SUBMITTED || signal == S_SMS_SMMA) { - /* TODO: For SMMA we might want to re-use the radio connection. */ - sms_queue_trigger(network->sms_queue); - return 0; - } - - if (!sig_sms->sms) - return -1; - - - /* - * Find the entry of our queue. The SMS subsystem will submit - * sms that are not in our control as we just have a channel - * open anyway. - */ - pending = sms_find_pending(network->sms_queue, sig_sms->sms); - if (!pending) - return 0; - - switch (signal) { - case S_SMS_DELIVERED: - /* Remember the subscriber and clear the pending entry */ - network->sms_queue->pending -= 1; - vsub = vlr_subscr_get(pending->vsub); - sms_pending_free(pending); - /* Attempt to send another SMS to this subscriber */ - sms_send_next(vsub); - vlr_subscr_put(vsub); - break; - case S_SMS_MEM_EXCEEDED: - network->sms_queue->pending -= 1; - sms_pending_free(pending); - sms_queue_trigger(network->sms_queue); - break; - case S_SMS_UNKNOWN_ERROR: - /* - * There can be many reasons for this failure. E.g. the paging - * timed out, the subscriber was not paged at all, or there was - * a protocol error. The current strategy is to try sending the - * next SMS for busy/oom and to retransmit when we have paged. - * - * When the paging expires three times we will disable the - * subscriber. If we have some kind of other transmit error we - * should flag the SMS as bad. - */ - switch (sig_sms->paging_result) { - case 0: - /* BAD SMS? */ - db_sms_inc_deliver_attempts(sig_sms->sms); - sms_pending_failed(pending, 0); - break; - case GSM_PAGING_EXPIRED: - sms_pending_failed(pending, 1); - break; - - case GSM_PAGING_OOM: - case GSM_PAGING_BUSY: - network->sms_queue->pending -= 1; - sms_pending_free(pending); - sms_queue_trigger(network->sms_queue); - break; - default: - LOGP(DLSMS, LOGL_ERROR, "Unhandled result: %d\n", - sig_sms->paging_result); - } - break; - default: - LOGP(DLSMS, LOGL_ERROR, "Unhandled result: %d\n", - sig_sms->paging_result); - } - - return 0; -} - -/* VTY helper functions */ -int sms_queue_stats(struct gsm_sms_queue *smsq, struct vty *vty) -{ - struct gsm_sms_pending *pending; - - vty_out(vty, "SMSqueue with max_pending: %d pending: %d%s", - smsq->max_pending, smsq->pending, VTY_NEWLINE); - - llist_for_each_entry(pending, &smsq->pending_sms, entry) - vty_out(vty, " SMS Pending for Subscriber: %llu SMS: %llu Failed: %d.%s", - pending->vsub->id, pending->sms_id, - pending->failed_attempts, VTY_NEWLINE); - return 0; -} - -int sms_queue_set_max_pending(struct gsm_sms_queue *smsq, int max_pending) -{ - LOGP(DLSMS, LOGL_NOTICE, "SMSqueue old max: %d new: %d\n", - smsq->max_pending, max_pending); - smsq->max_pending = max_pending; - return 0; -} - -int sms_queue_set_max_failure(struct gsm_sms_queue *smsq, int max_fail) -{ - LOGP(DLSMS, LOGL_NOTICE, "SMSqueue max failure old: %d new: %d\n", - smsq->max_fail, max_fail); - smsq->max_fail = max_fail; - return 0; -} - -int sms_queue_clear(struct gsm_sms_queue *smsq) -{ - struct gsm_sms_pending *pending, *tmp; - - llist_for_each_entry_safe(pending, tmp, &smsq->pending_sms, entry) { - LOGP(DLSMS, LOGL_NOTICE, - "SMSqueue clearing for sub %llu\n", pending->vsub->id); - sms_pending_free(pending); - } - - smsq->pending = 0; - return 0; -} diff --git a/src/libmsc/subscr_conn.c b/src/libmsc/subscr_conn.c deleted file mode 100644 index bcab8e48c..000000000 --- a/src/libmsc/subscr_conn.c +++ /dev/null @@ -1,359 +0,0 @@ -/* MSC subscriber connection implementation */ - -/* - * (C) 2016 by sysmocom s.m.f.c. - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define SUBSCR_CONN_TIMEOUT 5 /* seconds */ - -static const struct value_string subscr_conn_fsm_event_names[] = { - OSMO_VALUE_STRING(SUBSCR_CONN_E_INVALID), - OSMO_VALUE_STRING(SUBSCR_CONN_E_START), - OSMO_VALUE_STRING(SUBSCR_CONN_E_ACCEPTED), - OSMO_VALUE_STRING(SUBSCR_CONN_E_COMMUNICATING), - OSMO_VALUE_STRING(SUBSCR_CONN_E_BUMP), - OSMO_VALUE_STRING(SUBSCR_CONN_E_MO_CLOSE), - OSMO_VALUE_STRING(SUBSCR_CONN_E_CN_CLOSE), - { 0, NULL } -}; - -const struct value_string subscr_conn_from_names[] = { - OSMO_VALUE_STRING(SUBSCR_CONN_FROM_INVALID), - OSMO_VALUE_STRING(SUBSCR_CONN_FROM_LU), - OSMO_VALUE_STRING(SUBSCR_CONN_FROM_CM_SERVICE_REQ), - OSMO_VALUE_STRING(SUBSCR_CONN_FROM_PAGING_RESP), - { 0, NULL } -}; - -static void paging_event(struct gsm_subscriber_connection *conn, - enum gsm_paging_event pe) -{ - subscr_paging_dispatch(GSM_HOOK_RR_PAGING, pe, NULL, conn, conn->vsub); -} - -void subscr_conn_fsm_init(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - OSMO_ASSERT(event == SUBSCR_CONN_E_START); - osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_NEW, - SUBSCR_CONN_TIMEOUT, 0); -} - -void subscr_conn_fsm_new(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct gsm_subscriber_connection *conn = fi->priv; - enum subscr_conn_from from = SUBSCR_CONN_FROM_INVALID; - bool success; - - if (data) { - from = *(enum subscr_conn_from*)data; - LOGPFSM(fi, "%s\n", subscr_conn_from_name(from)); - } - - /* If accepted, transition the state, all other cases mean failure. */ - switch (event) { - case SUBSCR_CONN_E_ACCEPTED: - osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_ACCEPTED, - SUBSCR_CONN_TIMEOUT, 0); - break; - - case SUBSCR_CONN_E_MO_CLOSE: - case SUBSCR_CONN_E_CN_CLOSE: - if (data) - LOGPFSM(fi, "Close event, cause %u\n", - *(uint32_t*)data); - /* will release further below, see - * 'if (fi->state != SUBSCR_CONN_S_ACCEPTED)' */ - break; - - default: - LOGPFSML(fi, LOGL_ERROR, - "Unexpected event: %d %s\n", event, - osmo_fsm_event_name(fi->fsm, event)); - break; - } - - success = (fi->state == SUBSCR_CONN_S_ACCEPTED); - - if (from == SUBSCR_CONN_FROM_LU) - rate_ctr_inc(&conn->network->msc_ctrs->ctr[ - success ? MSC_CTR_LOC_UPDATE_COMPLETED - : MSC_CTR_LOC_UPDATE_FAILED]); - - /* signal paging success or failure in case this was a paging */ - if (from == SUBSCR_CONN_FROM_PAGING_RESP) - paging_event(conn, - success ? GSM_PAGING_SUCCEEDED - : GSM_PAGING_EXPIRED); - - /* FIXME rate counters */ - /*rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED]);*/ - - /* On failure, discard the conn */ - if (!success) { - /* TODO: on MO_CLOSE or CN_CLOSE, first go to RELEASING and - * await BSC/RNC confirmation? */ - osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASED, 0, 0); - return; - } - - if (from == SUBSCR_CONN_FROM_CM_SERVICE_REQ) { - conn->received_cm_service_request = true; - LOGPFSML(fi, LOGL_DEBUG, "received_cm_service_request = true\n"); - } - - osmo_fsm_inst_dispatch(fi, SUBSCR_CONN_E_BUMP, data); -} - -static void subscr_conn_fsm_bump(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct gsm_subscriber_connection *conn = fi->priv; - struct gsm_trans *trans; - - if (conn->silent_call) { - LOGPFSML(fi, LOGL_DEBUG, "bump: silent call still active\n"); - return; - } - - if (conn->received_cm_service_request) { - LOGPFSML(fi, LOGL_DEBUG, "bump: still awaiting first request after a CM Service Request\n"); - return; - } - - if (conn->vsub && !llist_empty(&conn->vsub->cs.requests)) { - struct subscr_request *sr; - if (!log_check_level(fi->fsm->log_subsys, LOGL_DEBUG)) { - llist_for_each_entry(sr, &conn->vsub->cs.requests, entry) { - LOGPFSML(fi, LOGL_DEBUG, "bump: still active: %s\n", - sr->label); - } - } - return; - } - - if ((trans = trans_has_conn(conn))) { - LOGPFSML(fi, LOGL_DEBUG, - "bump: connection still has active transaction: %s\n", - gsm48_pdisc_name(trans->protocol)); - return; - } - - LOGPFSML(fi, LOGL_DEBUG, "bump: releasing conn\n"); - osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASED, 0, 0); -} - -static void subscr_conn_fsm_accepted_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) -{ - struct gsm_subscriber_connection *conn = fi->priv; - osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_ATTACHED, conn->vsub); -} - -static void subscr_conn_fsm_accepted(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - switch (event) { - case SUBSCR_CONN_E_COMMUNICATING: - osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_COMMUNICATING, 0, 0); - return; - - case SUBSCR_CONN_E_BUMP: - subscr_conn_fsm_bump(fi, event, data); - return; - - default: - break; - } - /* Whatever unexpected happens in the accepted state, it means release. - * Even if an unexpected event is passed, the safest thing to do is - * discard the conn. We don't expect another SUBSCR_CONN_E_ACCEPTED. */ - osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASED, 0, 0); -} - -static void subscr_conn_fsm_communicating(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - switch (event) { - case SUBSCR_CONN_E_COMMUNICATING: - /* no-op */ - return; - - case SUBSCR_CONN_E_BUMP: - subscr_conn_fsm_bump(fi, event, data); - return; - - default: - break; - } - /* Whatever unexpected happens in the accepted state, it means release. - * Even if an unexpected event is passed, the safest thing to do is - * discard the conn. We don't expect another SUBSCR_CONN_E_ACCEPTED. */ - osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASED, 0, 0); -} - -static void subscr_conn_fsm_cleanup(struct osmo_fsm_inst *fi, - enum osmo_fsm_term_cause cause) -{ - struct gsm_subscriber_connection *conn = fi->priv; - fi->priv = NULL; - - if (!conn) - return; - conn->conn_fsm = NULL; - msc_subscr_conn_close(conn, cause); - msc_subscr_conn_put(conn); -} - -int subscr_conn_fsm_timeout(struct osmo_fsm_inst *fi) -{ - struct gsm_subscriber_connection *conn = fi->priv; - if (conn) - vlr_subscr_conn_timeout(conn->vsub); - osmo_fsm_inst_dispatch(fi, SUBSCR_CONN_E_CN_CLOSE, NULL); - return 0; -} - -static void subscr_conn_fsm_release(struct osmo_fsm_inst *fi, uint32_t prev_state) -{ - osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL); -} - -#define S(x) (1 << (x)) - -static const struct osmo_fsm_state subscr_conn_fsm_states[] = { - [SUBSCR_CONN_S_INIT] = { - .name = OSMO_STRINGIFY(SUBSCR_CONN_S_INIT), - .in_event_mask = S(SUBSCR_CONN_E_START), - .out_state_mask = S(SUBSCR_CONN_S_NEW), - .action = subscr_conn_fsm_init, - }, - [SUBSCR_CONN_S_NEW] = { - .name = OSMO_STRINGIFY(SUBSCR_CONN_S_NEW), - .in_event_mask = S(SUBSCR_CONN_E_ACCEPTED) | - S(SUBSCR_CONN_E_MO_CLOSE) | - S(SUBSCR_CONN_E_CN_CLOSE), - .out_state_mask = S(SUBSCR_CONN_S_ACCEPTED) | - S(SUBSCR_CONN_S_RELEASED), - .action = subscr_conn_fsm_new, - }, - [SUBSCR_CONN_S_ACCEPTED] = { - .name = OSMO_STRINGIFY(SUBSCR_CONN_S_ACCEPTED), - /* allow everything to release for any odd behavior */ - .in_event_mask = S(SUBSCR_CONN_E_COMMUNICATING) | - S(SUBSCR_CONN_E_BUMP) | - S(SUBSCR_CONN_E_ACCEPTED) | - S(SUBSCR_CONN_E_MO_CLOSE) | - S(SUBSCR_CONN_E_CN_CLOSE), - .out_state_mask = S(SUBSCR_CONN_S_RELEASED) | - S(SUBSCR_CONN_S_COMMUNICATING), - .onenter = subscr_conn_fsm_accepted_enter, - .action = subscr_conn_fsm_accepted, - }, - [SUBSCR_CONN_S_COMMUNICATING] = { - .name = OSMO_STRINGIFY(SUBSCR_CONN_S_COMMUNICATING), - /* allow everything to release for any odd behavior */ - .in_event_mask = S(SUBSCR_CONN_E_BUMP) | - S(SUBSCR_CONN_E_ACCEPTED) | - S(SUBSCR_CONN_E_COMMUNICATING) | - S(SUBSCR_CONN_E_MO_CLOSE) | - S(SUBSCR_CONN_E_CN_CLOSE), - .out_state_mask = S(SUBSCR_CONN_S_RELEASED), - .action = subscr_conn_fsm_communicating, - }, - [SUBSCR_CONN_S_RELEASED] = { - .name = OSMO_STRINGIFY(SUBSCR_CONN_S_RELEASED), - .onenter = subscr_conn_fsm_release, - }, -}; - -static struct osmo_fsm subscr_conn_fsm = { - .name = "Subscr_Conn", - .states = subscr_conn_fsm_states, - .num_states = ARRAY_SIZE(subscr_conn_fsm_states), - .allstate_event_mask = 0, - .allstate_action = NULL, - .log_subsys = DMM, - .event_names = subscr_conn_fsm_event_names, - .cleanup = subscr_conn_fsm_cleanup, - .timer_cb = subscr_conn_fsm_timeout, -}; - -int msc_create_conn_fsm(struct gsm_subscriber_connection *conn, const char *id) -{ - struct osmo_fsm_inst *fi; - OSMO_ASSERT(conn); - - if (conn->conn_fsm) { - LOGP(DMM, LOGL_ERROR, - "%s: Error: connection already in use\n", id); - return -EINVAL; - } - - /* Allocate the FSM not with the subscr_conn. Semantically it would - * make sense, but in subscr_conn_fsm_cleanup(), we want to discard the - * subscriber connection. If the FSM is freed along with the subscriber - * connection, then in _osmo_fsm_inst_term() the osmo_fsm_inst_free() - * that follows the cleanup() call would run into a double free. */ - fi = osmo_fsm_inst_alloc(&subscr_conn_fsm, conn->network, - msc_subscr_conn_get(conn), - LOGL_DEBUG, id); - - if (!fi) { - LOGP(DMM, LOGL_ERROR, - "%s: Failed to allocate subscr conn master FSM\n", id); - return -ENOMEM; - } - conn->conn_fsm = fi; - osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_START, NULL); - return 0; -} - -bool msc_subscr_conn_is_accepted(struct gsm_subscriber_connection *conn) -{ - if (!conn) - return false; - if (!conn->vsub) - return false; - if (!conn->conn_fsm) - return false; - if (!(conn->conn_fsm->state == SUBSCR_CONN_S_ACCEPTED - || conn->conn_fsm->state == SUBSCR_CONN_S_COMMUNICATING)) - return false; - return true; -} - -void msc_subscr_conn_communicating(struct gsm_subscriber_connection *conn) -{ - OSMO_ASSERT(conn); - osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_COMMUNICATING, - NULL); -} - -void msc_subscr_conn_init(void) -{ - osmo_fsm_register(&subscr_conn_fsm); -} diff --git a/src/libmsc/transaction.c b/src/libmsc/transaction.c deleted file mode 100644 index 28e0914a8..000000000 --- a/src/libmsc/transaction.c +++ /dev/null @@ -1,221 +0,0 @@ -/* GSM 04.07 Transaction handling */ - -/* (C) 2009 by Harald Welte - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void *tall_trans_ctx; - -void _gsm48_cc_trans_free(struct gsm_trans *trans); - -/*! Find a transaction in connection for given protocol + transaction ID - * \param[in] conn Connection in whihc we want to find transaction - * \param[in] proto Protocol of transaction - * \param[in] trans_id Transaction ID of transaction - * \returns Matching transaction, if any - */ -struct gsm_trans *trans_find_by_id(struct gsm_subscriber_connection *conn, - uint8_t proto, uint8_t trans_id) -{ - struct gsm_trans *trans; - struct gsm_network *net = conn->network; - struct vlr_subscr *vsub = conn->vsub; - - llist_for_each_entry(trans, &net->trans_list, entry) { - if (trans->vsub == vsub && - trans->protocol == proto && - trans->transaction_id == trans_id) - return trans; - } - return NULL; -} - -/*! Find a transaction by call reference - * \param[in] net Network in which we should search - * \param[in] callref Call Reference of transaction - * \returns Matching transaction, if any - */ -struct gsm_trans *trans_find_by_callref(struct gsm_network *net, - uint32_t callref) -{ - struct gsm_trans *trans; - - llist_for_each_entry(trans, &net->trans_list, entry) { - if (trans->callref == callref) - return trans; - } - return NULL; -} - -/*! Allocate a new transaction and add it to network list - * \param[in] net Netwokr in which we allocate transaction - * \param[in] subscr Subscriber for which we allocate transaction - * \param[in] protocol Protocol (CC/SMS/...) - * \param[in] callref Call Reference - * \returns Transaction - */ -struct gsm_trans *trans_alloc(struct gsm_network *net, - struct vlr_subscr *vsub, - uint8_t protocol, uint8_t trans_id, - uint32_t callref) -{ - struct gsm_trans *trans; - - DEBUGP(DCC, "subscr=%p, net=%p\n", vsub, net); - - /* a valid subscriber is indispensable */ - if (vsub == NULL) { - LOGP(DCC, LOGL_NOTICE, - "unable to alloc transaction, invalid subscriber (NULL)\n"); - return NULL; - } - - trans = talloc_zero(tall_trans_ctx, struct gsm_trans); - if (!trans) - return NULL; - - trans->vsub = vlr_subscr_get(vsub); - - trans->protocol = protocol; - trans->transaction_id = trans_id; - trans->callref = callref; - - trans->net = net; - llist_add_tail(&trans->entry, &net->trans_list); - - return trans; -} - -/*! Release a transaction - * \param[in] trans Transaction to be released - */ -void trans_free(struct gsm_trans *trans) -{ - switch (trans->protocol) { - case GSM48_PDISC_CC: - _gsm48_cc_trans_free(trans); - break; - case GSM48_PDISC_SMS: - _gsm411_sms_trans_free(trans); - break; - } - - if (trans->paging_request) { - subscr_remove_request(trans->paging_request); - trans->paging_request = NULL; - } - - if (trans->vsub) { - vlr_subscr_put(trans->vsub); - trans->vsub = NULL; - } - - llist_del(&trans->entry); - - if (trans->conn) - msc_subscr_conn_put(trans->conn); - - trans->conn = NULL; - talloc_free(trans); -} - -/*! allocate an unused transaction ID for the given subscriber - * in the given protocol using the ti_flag specified - * \param[in] net GSM network - * \param[in] subscr Subscriber for which to find ID - * \param[in] protocol Protocol for whihc to find ID - * \param[in] ti_flag FIXME - */ -int trans_assign_trans_id(struct gsm_network *net, struct vlr_subscr *vsub, - uint8_t protocol, uint8_t ti_flag) -{ - struct gsm_trans *trans; - unsigned int used_tid_bitmask = 0; - int i, j, h; - - if (ti_flag) - ti_flag = 0x8; - - /* generate bitmask of already-used TIDs for this (subscr,proto) */ - llist_for_each_entry(trans, &net->trans_list, entry) { - if (trans->vsub != vsub || - trans->protocol != protocol || - trans->transaction_id == 0xff) - continue; - used_tid_bitmask |= (1 << trans->transaction_id); - } - - /* find a new one, trying to go in a 'circular' pattern */ - for (h = 6; h > 0; h--) - if (used_tid_bitmask & (1 << (h | ti_flag))) - break; - for (i = 0; i < 7; i++) { - j = ((h + i) % 7) | ti_flag; - if ((used_tid_bitmask & (1 << j)) == 0) - return j; - } - - return -1; -} - -/*! Check if we have any transaction for given connection - * \param[in] conn Connection to check - * \returns 1 in case there is a transaction, 0 otherwise - */ -struct gsm_trans *trans_has_conn(const struct gsm_subscriber_connection *conn) -{ - struct gsm_trans *trans; - - llist_for_each_entry(trans, &conn->network->trans_list, entry) - if (trans->conn == conn) - return trans; - - return NULL; -} - -/*! Free all transactions associated with a connection, presumably when the - * conn is being closed. The transaction code will inform the CC or SMS - * facilities, which will then send the necessary release indications. - * \param[in] conn Connection that is going to be closed. - */ -void trans_conn_closed(struct gsm_subscriber_connection *conn) -{ - struct gsm_trans *trans; - - /* As part of the CC REL_IND the remote leg might be released and this - * will trigger another call to trans_free. This is something the llist - * macro can not handle and we need to re-iterate the list every time. - */ -restart: - llist_for_each_entry(trans, &conn->network->trans_list, entry) { - if (trans->conn == conn) { - trans_free(trans); - goto restart; - } - } -} diff --git a/src/libmsc/ussd.c b/src/libmsc/ussd.c deleted file mode 100644 index 81a356690..000000000 --- a/src/libmsc/ussd.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Network-specific handling of mobile-originated USSDs. */ - -/* (C) 2008-2009 by Harald Welte - * (C) 2008, 2009 by Holger Hans Peter Freyther - * (C) 2009 by Mike Haben - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -/* This module defines the network-specific handling of mobile-originated - USSD messages. */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* Declarations of USSD strings to be recognised */ -const char USSD_TEXT_OWN_NUMBER[] = "*#100#"; - -/* Forward declarations of network-specific handler functions */ -static int send_own_number(struct gsm_subscriber_connection *conn, const struct msgb *msg, const struct ss_request *req); - - -/* Entrypoint - handler function common to all mobile-originated USSDs */ -int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - int rc; - struct ss_request req; - struct gsm48_hdr *gh; - - /* TODO: Use subscriber_connection ref-counting if we ever want - * to keep the connection alive due ot ongoing USSD exchange. - * As we answer everytying synchronously so far, there's no need - * yet */ - - cm_service_request_concludes(conn, msg); - - memset(&req, 0, sizeof(req)); - gh = msgb_l3(msg); - rc = gsm0480_decode_ss_request(gh, msgb_l3len(msg), &req); - if (!rc) { - DEBUGP(DMM, "Unhandled SS\n"); - rc = gsm0480_send_ussd_reject(conn, msg, &req); - return rc; - } - - /* Interrogation or releaseComplete? */ - if (req.ussd_text[0] == '\0' || req.ussd_text[0] == 0xFF) { - if (req.ss_code > 0) { - /* Assume interrogateSS or modification of it and reject */ - rc = gsm0480_send_ussd_reject(conn, msg, &req); - return rc; - } - /* Still assuming a Release-Complete and returning */ - return 0; - } - - msc_subscr_conn_communicating(conn); - if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req.ussd_text)) { - DEBUGP(DMM, "USSD: Own number requested\n"); - rc = send_own_number(conn, msg, &req); - } else { - DEBUGP(DMM, "Unhandled USSD %s\n", req.ussd_text); - rc = gsm0480_send_ussd_reject(conn, msg, &req); - } - - return rc; -} - -/* A network-specific handler function */ -static int send_own_number(struct gsm_subscriber_connection *conn, const struct msgb *msg, const struct ss_request *req) -{ - char *own_number = conn->vsub->msisdn; - char response_string[GSM_EXTENSION_LENGTH + 20]; - - DEBUGP(DMM, "%s: MSISDN = %s\n", vlr_subscr_name(conn->vsub), - own_number); - - /* Need trailing CR as EOT character */ - snprintf(response_string, sizeof(response_string), "Your extension is %s\r", own_number); - return gsm0480_send_ussd_response(conn, msg, response_string, req); -} diff --git a/src/libmsc/vty_interface_layer3.c b/src/libmsc/vty_interface_layer3.c deleted file mode 100644 index 864597d6c..000000000 --- a/src/libmsc/vty_interface_layer3.c +++ /dev/null @@ -1,979 +0,0 @@ -/* OpenBSC interface to quagga VTY */ -/* (C) 2009 by Harald Welte - * (C) 2009-2011 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "meas_feed.h" - -extern struct gsm_network *gsmnet_from_vty(struct vty *v); - -static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub) -{ - int reqs; - struct llist_head *entry; - char expire_time[200]; - - if (strlen(vsub->name)) - vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE); - if (strlen(vsub->msisdn)) - vty_out(vty, " Extension: %s%s", vsub->msisdn, - VTY_NEWLINE); - vty_out(vty, " LAC: %d/0x%x%s", - vsub->lac, vsub->lac, VTY_NEWLINE); - vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE); - if (vsub->tmsi != GSM_RESERVED_TMSI) - vty_out(vty, " TMSI: %08X%s", vsub->tmsi, - VTY_NEWLINE); - if (vsub->tmsi_new != GSM_RESERVED_TMSI) - vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new, - VTY_NEWLINE); - -#if 0 - /* TODO: add this to vlr_subscr? */ - if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) { - struct gsm_auth_info *i = &vsub->auth_info; - vty_out(vty, " A3A8 algorithm id: %d%s", - i->auth_algo, VTY_NEWLINE); - vty_out(vty, " A3A8 Ki: %s%s", - osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len), - VTY_NEWLINE); - } -#endif - - if (vsub->last_tuple) { - struct gsm_auth_tuple *t = vsub->last_tuple; - vty_out(vty, " A3A8 last tuple (used %d times):%s", - t->use_count, VTY_NEWLINE); - vty_out(vty, " seq # : %d%s", - t->key_seq, VTY_NEWLINE); - vty_out(vty, " RAND : %s%s", - osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)), - VTY_NEWLINE); - vty_out(vty, " SRES : %s%s", - osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)), - VTY_NEWLINE); - vty_out(vty, " Kc : %s%s", - osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)), - VTY_NEWLINE); - } - - /* print the expiration time of a subscriber */ - strftime(expire_time, sizeof(expire_time), - "%a, %d %b %Y %T %z", localtime(&vsub->expire_lu)); - expire_time[sizeof(expire_time) - 1] = '\0'; - vty_out(vty, " Expiration Time: %s%s", expire_time, VTY_NEWLINE); - - reqs = 0; - llist_for_each(entry, &vsub->cs.requests) - reqs += 1; - vty_out(vty, " Paging: %s paging for %d requests%s", - vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE); - vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE); -} - - -/* Subscriber */ -DEFUN(show_subscr_cache, - show_subscr_cache_cmd, - "show subscriber cache", - SHOW_STR "Show information about subscribers\n" - "Display contents of subscriber cache\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub; - int count = 0; - - llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) { - if (++count > 100) { - vty_out(vty, "%% More than %d subscribers in cache," - " stopping here.%s", count-1, VTY_NEWLINE); - break; - } - vty_out(vty, " Subscriber:%s", VTY_NEWLINE); - subscr_dump_full_vty(vty, vsub); - } - - return CMD_SUCCESS; -} - -DEFUN(sms_send_pend, - sms_send_pend_cmd, - "sms send pending", - "SMS related commands\n" "SMS Sending related commands\n" - "Send all pending SMS") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct gsm_sms *sms; - unsigned long long sms_id = 0; - - while (1) { - sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX); - if (!sms) - break; - - if (sms->receiver) - gsm411_send_sms_subscr(sms->receiver, sms); - - sms_id = sms->id + 1; - } - - return CMD_SUCCESS; -} - -static int _send_sms_str(struct vlr_subscr *receiver, - struct vlr_subscr *sender, - char *str, uint8_t tp_pid) -{ - struct gsm_network *net = receiver->vlr->user_ctx; - struct gsm_sms *sms; - - sms = sms_from_text(receiver, sender, 0, str); - sms->protocol_id = tp_pid; - - /* store in database for the queue */ - if (db_sms_store(sms) != 0) { - LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n"); - sms_free(sms); - return CMD_WARNING; - } - LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n"); - - sms_free(sms); - sms_queue_trigger(net->sms_queue); - return CMD_SUCCESS; -} - -static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet, - const char *type, - const char *id) -{ - if (!strcmp(type, "extension") || !strcmp(type, "msisdn")) - return vlr_subscr_find_by_msisdn(gsmnet->vlr, id); - else if (!strcmp(type, "imsi") || !strcmp(type, "id")) - return vlr_subscr_find_by_imsi(gsmnet->vlr, id); - else if (!strcmp(type, "tmsi")) - return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id)); - - return NULL; -} -#define SUBSCR_TYPES "(extension|imsi|tmsi|id)" -#define SUBSCR_HELP "Operations on a Subscriber\n" \ - "Identify subscriber by extension (phone number)\n" \ - "Identify subscriber by IMSI\n" \ - "Identify subscriber by TMSI\n" \ - "Identify subscriber by database ID\n" \ - "Identifier for the subscriber\n" - -DEFUN(show_subscr, - show_subscr_cmd, - "show subscriber " SUBSCR_TYPES " ID", - SHOW_STR SUBSCR_HELP) -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], - argv[1]); - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - subscr_dump_full_vty(vty, vsub); - - vlr_subscr_put(vsub); - - return CMD_SUCCESS; -} - -DEFUN(subscriber_create, - subscriber_create_cmd, - "subscriber create imsi ID", - "Operations on a Subscriber\n" \ - "Create new subscriber\n" \ - "Identify the subscriber by his IMSI\n" \ - "Identifier for the subscriber\n") -{ - vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s", - VTY_NEWLINE); - return CMD_WARNING; -} - -DEFUN(subscriber_send_pending_sms, - subscriber_send_pending_sms_cmd, - "subscriber " SUBSCR_TYPES " ID sms pending-send", - SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub; - struct gsm_sms *sms; - - vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX); - if (sms) - gsm411_send_sms_subscr(sms->receiver, sms); - - vlr_subscr_put(vsub); - - return CMD_SUCCESS; -} - -DEFUN(subscriber_send_sms, - subscriber_send_sms_cmd, - "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE", - SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); - struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]); - char *str; - int rc; - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - rc = CMD_WARNING; - goto err; - } - - if (!sender) { - vty_out(vty, "%% No sender found for %s %s%s", - argv[2], argv[3], VTY_NEWLINE); - rc = CMD_WARNING; - goto err; - } - - str = argv_concat(argv, argc, 4); - rc = _send_sms_str(vsub, sender, str, 0); - talloc_free(str); - -err: - if (sender) - vlr_subscr_put(sender); - - if (vsub) - vlr_subscr_put(vsub); - - return rc; -} - -DEFUN(subscriber_silent_sms, - subscriber_silent_sms_cmd, - - "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE", - SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); - struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]); - char *str; - int rc; - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - rc = CMD_WARNING; - goto err; - } - - if (!sender) { - vty_out(vty, "%% No sender found for %s %s%s", - argv[2], argv[3], VTY_NEWLINE); - rc = CMD_WARNING; - goto err; - } - - str = argv_concat(argv, argc, 4); - rc = _send_sms_str(vsub, sender, str, 64); - talloc_free(str); - -err: - if (sender) - vlr_subscr_put(sender); - - if (vsub) - vlr_subscr_put(vsub); - - return rc; -} - -#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)" -#define CHAN_TYPE_HELP \ - "Any channel\n" \ - "TCH/F channel\n" \ - "Any TCH channel\n" \ - "SDCCH channel\n" - -DEFUN(subscriber_silent_call_start, - subscriber_silent_call_start_cmd, - "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)", - SUBSCR_HELP "Silent call operation\n" "Start silent call\n" - CHAN_TYPE_HELP) -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); - int rc, type; - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - if (!strcmp(argv[2], "tch/f")) - type = RSL_CHANNEED_TCH_F; - else if (!strcmp(argv[2], "tch/any")) - type = RSL_CHANNEED_TCH_ForH; - else if (!strcmp(argv[2], "sdcch")) - type = RSL_CHANNEED_SDCCH; - else - type = RSL_CHANNEED_ANY; /* Defaults to ANY */ - - rc = gsm_silent_call_start(vsub, vty, type); - if (rc <= 0) { - vty_out(vty, "%% Subscriber not attached%s", - VTY_NEWLINE); - vlr_subscr_put(vsub); - return CMD_WARNING; - } - - vlr_subscr_put(vsub); - - return CMD_SUCCESS; -} - -DEFUN(subscriber_silent_call_stop, - subscriber_silent_call_stop_cmd, - "subscriber " SUBSCR_TYPES " ID silent-call stop", - SUBSCR_HELP "Silent call operation\n" "Stop silent call\n" - CHAN_TYPE_HELP) -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); - int rc; - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - rc = gsm_silent_call_stop(vsub); - if (rc < 0) { - vlr_subscr_put(vsub); - return CMD_WARNING; - } - - vlr_subscr_put(vsub); - - return CMD_SUCCESS; -} - -DEFUN(subscriber_ussd_notify, - subscriber_ussd_notify_cmd, - "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT", - SUBSCR_HELP "Send a USSD notify to the subscriber\n" - "Alerting Level 0\n" - "Alerting Level 1\n" - "Alerting Level 2\n" - "Text of USSD message to send\n") -{ - char *text; - struct gsm_subscriber_connection *conn; - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); - int level; - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - level = atoi(argv[2]); - text = argv_concat(argv, argc, 3); - if (!text) { - vlr_subscr_put(vsub); - return CMD_WARNING; - } - - conn = connection_for_subscr(vsub); - if (!conn) { - vty_out(vty, "%% An active connection is required for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - vlr_subscr_put(vsub); - talloc_free(text); - return CMD_WARNING; - } - - msc_send_ussd_notify(conn, level, text); - msc_send_ussd_release_complete(conn); - - vlr_subscr_put(vsub); - talloc_free(text); - return CMD_SUCCESS; -} - -static int loop_by_char(uint8_t ch) -{ - switch (ch) { - case 'a': - return GSM414_LOOP_A; - case 'b': - return GSM414_LOOP_B; - case 'c': - return GSM414_LOOP_C; - case 'd': - return GSM414_LOOP_D; - case 'e': - return GSM414_LOOP_E; - case 'f': - return GSM414_LOOP_F; - case 'i': - return GSM414_LOOP_I; - } - return -1; -} - -DEFUN(subscriber_mstest_close, - subscriber_mstest_close_cmd, - "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)", - SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n" - "Close a TCH Loop inside the MS\n" - "Loop Type A\n" - "Loop Type B\n" - "Loop Type C\n" - "Loop Type D\n" - "Loop Type E\n" - "Loop Type F\n" - "Loop Type I\n") -{ - struct gsm_subscriber_connection *conn; - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); - const char *loop_str; - int loop_mode; - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - loop_str = argv[2]; - loop_mode = loop_by_char(loop_str[0]); - - conn = connection_for_subscr(vsub); - if (!conn) { - vty_out(vty, "%% An active connection is required for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - vlr_subscr_put(vsub); - return CMD_WARNING; - } - - gsm0414_tx_close_tch_loop_cmd(conn, loop_mode); - - return CMD_SUCCESS; -} - -DEFUN(subscriber_mstest_open, - subscriber_mstest_open_cmd, - "subscriber " SUBSCR_TYPES " ID ms-test open-loop", - SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n" - "Open a TCH Loop inside the MS\n") -{ - struct gsm_subscriber_connection *conn; - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - conn = connection_for_subscr(vsub); - if (!conn) { - vty_out(vty, "%% An active connection is required for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - vlr_subscr_put(vsub); - return CMD_WARNING; - } - - gsm0414_tx_open_loop_cmd(conn); - - return CMD_SUCCESS; -} - -DEFUN(ena_subscr_expire, - ena_subscr_expire_cmd, - "subscriber " SUBSCR_TYPES " ID expire", - SUBSCR_HELP "Expire the subscriber Now\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], - argv[1]); - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - if (vsub->lu_complete) { - vsub->lu_complete = false; - vlr_subscr_put(vsub); - vty_out(vty, "%% VLR released subscriber %s%s", - vlr_subscr_name(vsub), VTY_NEWLINE); - } - - if (vsub->use_count > 1) - vty_out(vty, "%% Subscriber %s is still in use," - " should be released soon%s", - vlr_subscr_name(vsub), VTY_NEWLINE); - - vlr_subscr_put(vsub); - return CMD_SUCCESS; -} - -#define A3A8_ALG_TYPES "(none|xor|comp128v1)" -#define A3A8_ALG_HELP \ - "Use No A3A8 algorithm\n" \ - "Use XOR algorithm\n" \ - "Use COMP128v1 algorithm\n" - -DEFUN(ena_subscr_a3a8, - ena_subscr_a3a8_cmd, - "subscriber " SUBSCR_TYPES " ID a3a8 " A3A8_ALG_TYPES " [KI]", - SUBSCR_HELP "Set a3a8 parameters for the subscriber\n" - A3A8_ALG_HELP "Encryption Key Ki\n") -{ - vty_out(vty, "%% 'subscriber a3a8' is no longer supported.%s" - "%% This is now up to osmo-hlr.%s", - VTY_NEWLINE, VTY_NEWLINE); - return CMD_WARNING; -} - -DEFUN(subscriber_update, - subscriber_update_cmd, - "subscriber " SUBSCR_TYPES " ID update", - SUBSCR_HELP "Update the subscriber data from the dabase.\n") -{ - vty_out(vty, "%% 'subscriber update' is no longer supported.%s", - VTY_NEWLINE); - return CMD_WARNING; -} - -static int scall_cbfn(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct scall_signal_data *sigdata = signal_data; - struct vty *vty = sigdata->data; - - switch (signal) { - case S_SCALL_SUCCESS: - vty_out(vty, "%% silent call success%s", VTY_NEWLINE); - break; - case S_SCALL_EXPIRED: - vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE); - break; - } - return 0; -} - -DEFUN(show_stats, - show_stats_cmd, - "show statistics", - SHOW_STR "Display network statistics\n") -{ - struct gsm_network *net = gsmnet_from_vty(vty); - - vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s", - net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current, - net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current, - net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current, - VTY_NEWLINE); - vty_out(vty, "IMSI Detach Indications : %lu%s", - net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current, - VTY_NEWLINE); - vty_out(vty, "Location Updating Results: %lu completed, %lu failed%s", - net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current, - net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current, - VTY_NEWLINE); - vty_out(vty, "Handover : %lu attempted, %lu no_channel, %lu timeout, " - "%lu completed, %lu failed%s", - net->bsc_ctrs->ctr[BSC_CTR_HANDOVER_ATTEMPTED].current, - net->bsc_ctrs->ctr[BSC_CTR_HANDOVER_NO_CHANNEL].current, - net->bsc_ctrs->ctr[BSC_CTR_HANDOVER_TIMEOUT].current, - net->bsc_ctrs->ctr[BSC_CTR_HANDOVER_COMPLETED].current, - net->bsc_ctrs->ctr[BSC_CTR_HANDOVER_FAILED].current, - VTY_NEWLINE); - vty_out(vty, "SMS MO : %lu submitted, %lu no receiver%s", - net->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current, - net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current, - VTY_NEWLINE); - vty_out(vty, "SMS MT : %lu delivered, %lu no memory, %lu other error%s", - net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current, - net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current, - net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current, - VTY_NEWLINE); - vty_out(vty, "MO Calls : %lu setup, %lu connect ack%s", - net->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current, - net->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current, - VTY_NEWLINE); - vty_out(vty, "MT Calls : %lu setup, %lu connect%s", - net->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current, - net->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current, - VTY_NEWLINE); - return CMD_SUCCESS; -} - -DEFUN(show_smsqueue, - show_smsqueue_cmd, - "show sms-queue", - SHOW_STR "Display SMSqueue statistics\n") -{ - struct gsm_network *net = gsmnet_from_vty(vty); - - sms_queue_stats(net->sms_queue, vty); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_trigger, - smsqueue_trigger_cmd, - "sms-queue trigger", - "SMS Queue\n" "Trigger sending messages\n") -{ - struct gsm_network *net = gsmnet_from_vty(vty); - - sms_queue_trigger(net->sms_queue); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_max, - smsqueue_max_cmd, - "sms-queue max-pending <1-500>", - "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n") -{ - struct gsm_network *net = gsmnet_from_vty(vty); - - sms_queue_set_max_pending(net->sms_queue, atoi(argv[0])); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_clear, - smsqueue_clear_cmd, - "sms-queue clear", - "SMS Queue\n" "Clear the queue of pending SMS\n") -{ - struct gsm_network *net = gsmnet_from_vty(vty); - - sms_queue_clear(net->sms_queue); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_fail, - smsqueue_fail_cmd, - "sms-queue max-failure <1-500>", - "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n") -{ - struct gsm_network *net = gsmnet_from_vty(vty); - - sms_queue_set_max_failure(net->sms_queue, atoi(argv[0])); - return CMD_SUCCESS; -} - - -DEFUN(cfg_mncc_int, cfg_mncc_int_cmd, - "mncc-int", "Configure internal MNCC handler") -{ - vty->node = MNCC_INT_NODE; - - return CMD_SUCCESS; -} - -static struct cmd_node mncc_int_node = { - MNCC_INT_NODE, - "%s(config-mncc-int)# ", - 1, -}; - -static const struct value_string tchf_codec_names[] = { - { GSM48_CMODE_SPEECH_V1, "fr" }, - { GSM48_CMODE_SPEECH_EFR, "efr" }, - { GSM48_CMODE_SPEECH_AMR, "amr" }, - { 0, NULL } -}; - -static const struct value_string tchh_codec_names[] = { - { GSM48_CMODE_SPEECH_V1, "hr" }, - { GSM48_CMODE_SPEECH_AMR, "amr" }, - { 0, NULL } -}; - -static int config_write_mncc_int(struct vty *vty) -{ - uint16_t meas_port; - char *meas_host; - const char *meas_scenario; - - meas_feed_cfg_get(&meas_host, &meas_port); - meas_scenario = meas_feed_scenario_get(); - - vty_out(vty, "mncc-int%s", VTY_NEWLINE); - vty_out(vty, " default-codec tch-f %s%s", - get_value_string(tchf_codec_names, mncc_int.def_codec[0]), - VTY_NEWLINE); - vty_out(vty, " default-codec tch-h %s%s", - get_value_string(tchh_codec_names, mncc_int.def_codec[1]), - VTY_NEWLINE); - if (meas_port) - vty_out(vty, " meas-feed destination %s %u%s", - meas_host, meas_port, VTY_NEWLINE); - if (strlen(meas_scenario) > 0) - vty_out(vty, " meas-feed scenario %s%s", - meas_scenario, VTY_NEWLINE); - - - return CMD_SUCCESS; -} - -DEFUN(mnccint_def_codec_f, - mnccint_def_codec_f_cmd, - "default-codec tch-f (fr|efr|amr)", - "Set default codec\n" "Codec for TCH/F\n" - "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n") -{ - mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]); - - return CMD_SUCCESS; -} - -DEFUN(mnccint_def_codec_h, - mnccint_def_codec_h_cmd, - "default-codec tch-h (hr|amr)", - "Set default codec\n" "Codec for TCH/H\n" - "Half-Rate\n" "Adaptive Multi-Rate\n") -{ - mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]); - - return CMD_SUCCESS; -} - -#define OBSOLETE_MSG "Obsolete\n" -/* this is just for backwards compatibility as the sms code moved into - * libosmocore and old config files no longer parse... */ -DEFUN_DEPRECATED(log_level_sms, log_level_sms_cmd, - "logging level sms (everything|debug|info|notice|error|fatal)", - ".HIDDEN\n" OBSOLETE_MSG OBSOLETE_MSG OBSOLETE_MSG OBSOLETE_MSG - OBSOLETE_MSG OBSOLETE_MSG OBSOLETE_MSG OBSOLETE_MSG) -{ - vty_out(vty, "%% 'logging level sms' is now called 'logging level " - "lsms', please update your config %s", VTY_NEWLINE); - - return CMD_SUCCESS; -} - -#define MEAS_STR "Measurement export related\n" -DEFUN(mnccint_meas_feed, mnccint_meas_feed_cmd, - "meas-feed destination ADDR <0-65535>", - MEAS_STR "destination\n" "address or hostname\n" "port number\n") -{ - int rc; - - rc = meas_feed_cfg_set(argv[0], atoi(argv[1])); - if (rc < 0) - return CMD_WARNING; - - return CMD_SUCCESS; -} - -DEFUN(meas_feed_scenario, meas_feed_scenario_cmd, - "meas-feed scenario NAME", - MEAS_STR "scenario\n" "Name up to 31 characters included in report\n") -{ - meas_feed_scenario_set(argv[0]); - - return CMD_SUCCESS; -} - - -DEFUN(logging_fltr_imsi, - logging_fltr_imsi_cmd, - "logging filter imsi IMSI", - LOGGING_STR FILTER_STR - "Filter log messages by IMSI\n" "IMSI to be used as filter\n") -{ - struct vlr_subscr *vlr_subscr; - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct log_target *tgt = osmo_log_vty2tgt(vty); - const char *imsi = argv[0]; - - if (!tgt) - return CMD_WARNING; - - vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi); - - if (!vlr_subscr) { - vty_out(vty, "%%no subscriber with IMSI(%s)%s", - argv[0], VTY_NEWLINE); - return CMD_WARNING; - } - - log_set_filter_vlr_subscr(tgt, vlr_subscr); - return CMD_SUCCESS; -} - -static struct cmd_node hlr_node = { - HLR_NODE, - "%s(config-hlr)# ", - 1, -}; - -DEFUN(cfg_hlr, cfg_hlr_cmd, - "hlr", "Configure connection to the HLR") -{ - vty->node = HLR_NODE; - return CMD_SUCCESS; -} - -DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D", - "Remote GSUP address of the HLR\n" - "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - talloc_free((void*)gsmnet->gsup_server_addr_str); - gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]); - return CMD_SUCCESS; -} - -DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>", - "Remote GSUP port of the HLR\n" - "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - gsmnet->gsup_server_port = atoi(argv[0]); - return CMD_SUCCESS; -} - -static int config_write_hlr(struct vty *vty) -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - - vty_out(vty, "hlr%s", VTY_NEWLINE); - vty_out(vty, " remote-ip %s%s", - gsmnet->gsup_server_addr_str, VTY_NEWLINE); - vty_out(vty, " remote-port %u%s", - gsmnet->gsup_server_port, VTY_NEWLINE); - return CMD_SUCCESS; -} - -int bsc_vty_init_extra(void) -{ - osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL); - - install_element_ve(&show_subscr_cmd); - install_element_ve(&show_subscr_cache_cmd); - - install_element_ve(&sms_send_pend_cmd); - - install_element_ve(&subscriber_create_cmd); - install_element_ve(&subscriber_send_sms_cmd); - install_element_ve(&subscriber_silent_sms_cmd); - install_element_ve(&subscriber_silent_call_start_cmd); - install_element_ve(&subscriber_silent_call_stop_cmd); - install_element_ve(&subscriber_ussd_notify_cmd); - install_element_ve(&subscriber_mstest_close_cmd); - install_element_ve(&subscriber_mstest_open_cmd); - install_element_ve(&subscriber_update_cmd); - install_element_ve(&show_stats_cmd); - install_element_ve(&show_smsqueue_cmd); - install_element_ve(&logging_fltr_imsi_cmd); - - install_element(ENABLE_NODE, &ena_subscr_expire_cmd); - install_element(ENABLE_NODE, &ena_subscr_a3a8_cmd); - install_element(ENABLE_NODE, &smsqueue_trigger_cmd); - install_element(ENABLE_NODE, &smsqueue_max_cmd); - install_element(ENABLE_NODE, &smsqueue_clear_cmd); - install_element(ENABLE_NODE, &smsqueue_fail_cmd); - install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd); - install_element(ENABLE_NODE, &meas_feed_scenario_cmd); - - install_element(CONFIG_NODE, &cfg_mncc_int_cmd); - install_node(&mncc_int_node, config_write_mncc_int); - vty_install_default(MNCC_INT_NODE); - install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd); - install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd); - install_element(MNCC_INT_NODE, &mnccint_meas_feed_cmd); - install_element(MNCC_INT_NODE, &meas_feed_scenario_cmd); - - install_element(CFG_LOG_NODE, &log_level_sms_cmd); - install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd); - - install_element(CONFIG_NODE, &cfg_hlr_cmd); - install_node(&hlr_node, config_write_hlr); - install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd); - install_element(HLR_NODE, &cfg_hlr_remote_port_cmd); - - return 0; -} diff --git a/src/libvlr/Makefile.am b/src/libvlr/Makefile.am deleted file mode 100644 index 17ad4111f..000000000 --- a/src/libvlr/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ - $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) - -noinst_HEADERS = \ - vlr_access_req_fsm.h \ - vlr_auth_fsm.h \ - vlr_core.h \ - vlr_lu_fsm.h \ - $(NULL) - -noinst_LIBRARIES = libvlr.a - -libvlr_a_SOURCES = \ - vlr.c \ - vlr_access_req_fsm.c \ - vlr_auth_fsm.c \ - vlr_lu_fsm.c \ - $(NULL) diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c deleted file mode 100644 index d95d1b7ec..000000000 --- a/src/libvlr/vlr.c +++ /dev/null @@ -1,1112 +0,0 @@ -/* Osmocom Visitor Location Register (VLR) code base */ - -/* (C) 2016 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "vlr_core.h" -#include "vlr_auth_fsm.h" -#include "vlr_lu_fsm.h" -#include "vlr_access_req_fsm.h" - -#define SGSN_SUBSCR_MAX_RETRIES 3 -#define SGSN_SUBSCR_RETRY_INTERVAL 10 - -/*********************************************************************** - * Convenience functions - ***********************************************************************/ - -const struct value_string vlr_ciph_names[] = { - OSMO_VALUE_STRING(VLR_CIPH_NONE), - OSMO_VALUE_STRING(VLR_CIPH_A5_1), - OSMO_VALUE_STRING(VLR_CIPH_A5_2), - OSMO_VALUE_STRING(VLR_CIPH_A5_3), - { 0, NULL } -}; - -uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer) -{ - uint32_t tidx = 0xffffffff; - - switch (timer) { - case 3270: - tidx = VLR_T_3270; - break; - case 3260: - tidx = VLR_T_3260; - break; - case 3250: - tidx = VLR_T_3250; - break; - } - - OSMO_ASSERT(tidx < sizeof(vlr->cfg.timer)); - return vlr->cfg.timer[tidx]; -} - -struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr, - const char *imsi, - const char *file, int line) -{ - struct vlr_subscr *vsub; - - if (!imsi || !*imsi) - return NULL; - - llist_for_each_entry(vsub, &vlr->subscribers, list) { - if (vlr_subscr_matches_imsi(vsub, imsi)) - return _vlr_subscr_get(vsub, file, line); - } - return NULL; -} - -struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr, - uint32_t tmsi, - const char *file, int line) -{ - struct vlr_subscr *vsub; - - if (tmsi == GSM_RESERVED_TMSI) - return NULL; - - llist_for_each_entry(vsub, &vlr->subscribers, list) { - if (vlr_subscr_matches_tmsi(vsub, tmsi)) - return _vlr_subscr_get(vsub, file, line); - } - return NULL; -} - -struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr, - const char *msisdn, - const char *file, int line) -{ - struct vlr_subscr *vsub; - - if (!msisdn || !*msisdn) - return NULL; - - llist_for_each_entry(vsub, &vlr->subscribers, list) { - if (vlr_subscr_matches_msisdn(vsub, msisdn)) - return _vlr_subscr_get(vsub, file, line); - } - return NULL; -} - -/* Transmit GSUP message to HLR */ -static int vlr_tx_gsup_message(struct vlr_instance *vlr, - struct osmo_gsup_message *gsup_msg) -{ - struct msgb *msg = gsup_client_msgb_alloc(); - - osmo_gsup_encode(msg, gsup_msg); - - if (!vlr->gsup_client) { - LOGP(DVLR, LOGL_NOTICE, "GSUP link is down, cannot " - "send GSUP: %s\n", msgb_hexdump(msg)); - msgb_free(msg); - return -ENOTSUP; - } - - LOGP(DVLR, LOGL_DEBUG, "GSUP tx: %s\n", - osmo_hexdump_nospc(msg->data, msg->len)); - - return gsup_client_send(vlr->gsup_client, msg); -} - -/* Transmit GSUP message for subscriber to HLR, using IMSI from subscriber */ -static int vlr_subscr_tx_gsup_message(struct vlr_subscr *vsub, - struct osmo_gsup_message *gsup_msg) -{ - struct vlr_instance *vlr = vsub->vlr; - - if (strlen(gsup_msg->imsi) == 0) - osmo_strlcpy(gsup_msg->imsi, vsub->imsi, sizeof(gsup_msg->imsi)); - - return vlr_tx_gsup_message(vlr, gsup_msg); -} - -/* Transmit GSUP error in response to original message */ -static int vlr_tx_gsup_error_reply(struct vlr_instance *vlr, - struct osmo_gsup_message *gsup_orig, - enum gsm48_gmm_cause cause) -{ - struct osmo_gsup_message gsup_reply = {0}; - - osmo_strlcpy(gsup_reply.imsi, gsup_orig->imsi, sizeof(gsup_reply.imsi)); - gsup_reply.cause = cause; - gsup_reply.message_type = - OSMO_GSUP_TO_MSGT_ERROR(gsup_orig->message_type); - - return vlr_tx_gsup_message(vlr, &gsup_reply); -} - -struct vlr_subscr *_vlr_subscr_get(struct vlr_subscr *sub, const char *file, int line) -{ - if (!sub) - return NULL; - OSMO_ASSERT(sub->use_count < INT_MAX); - sub->use_count++; - LOGPSRC(DREF, LOGL_DEBUG, file, line, - "VLR subscr %s usage increases to: %d\n", - vlr_subscr_name(sub), sub->use_count); - return sub; -} - -struct vlr_subscr *_vlr_subscr_put(struct vlr_subscr *sub, const char *file, int line) -{ - if (!sub) - return NULL; - sub->use_count--; - LOGPSRC(DREF, sub->use_count >= 0? LOGL_DEBUG : LOGL_ERROR, - file, line, - "VLR subscr %s usage decreases to: %d\n", - vlr_subscr_name(sub), sub->use_count); - if (sub->use_count <= 0) - vlr_subscr_free(sub); - return NULL; -} - -/* Allocate a new subscriber and insert it into list */ -static struct vlr_subscr *_vlr_subscr_alloc(struct vlr_instance *vlr) -{ - struct vlr_subscr *vsub; - int i; - - vsub = talloc_zero(vlr, struct vlr_subscr); - vsub->vlr = vlr; - vsub->tmsi = GSM_RESERVED_TMSI; - vsub->tmsi_new = GSM_RESERVED_TMSI; - - for (i = 0; i < ARRAY_SIZE(vsub->auth_tuples); i++) - vsub->auth_tuples[i].key_seq = GSM_KEY_SEQ_INVAL; - - INIT_LLIST_HEAD(&vsub->cs.requests); - INIT_LLIST_HEAD(&vsub->ps.pdp_list); - - llist_add_tail(&vsub->list, &vlr->subscribers); - return vsub; -} - -struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr) -{ - return vlr_subscr_get(_vlr_subscr_alloc(vlr)); -} - -/* Send a GSUP Purge MS request. - * TODO: this should be sent to the *previous* VLR when this VLR is "taking" - * this subscriber, not to the HLR? */ -int vlr_subscr_purge(struct vlr_subscr *vsub) -{ - struct osmo_gsup_message gsup_msg = {0}; - - gsup_msg.message_type = OSMO_GSUP_MSGT_PURGE_MS_REQUEST; - - /* provide HLR number in case we know it */ - gsup_msg.hlr_enc_len = vsub->hlr.len; - gsup_msg.hlr_enc = vsub->hlr.buf; - - return vlr_subscr_tx_gsup_message(vsub, &gsup_msg); -} - -void vlr_subscr_cancel(struct vlr_subscr *vsub, enum gsm48_gmm_cause cause) -{ - if (!vsub) - return; - - if (vsub->lu_fsm) { - if (vsub->lu_fsm->state == VLR_ULA_S_WAIT_HLR_UPD) - osmo_fsm_inst_dispatch(vsub->lu_fsm, - VLR_ULA_E_HLR_LU_RES, - (void*)&cause); - else - osmo_fsm_inst_term(vsub->lu_fsm, OSMO_FSM_TERM_ERROR, - 0); - } - - if (vsub->proc_arq_fsm) - osmo_fsm_inst_term(vsub->proc_arq_fsm, OSMO_FSM_TERM_ERROR, 0); -} - -/* Call vlr_subscr_cancel(), then completely drop the entry from the VLR */ -void vlr_subscr_free(struct vlr_subscr *vsub) -{ - llist_del(&vsub->list); - DEBUGP(DREF, "freeing VLR subscr %s\n", vlr_subscr_name(vsub)); - talloc_free(vsub); -} - -/* Generate a new TMSI and store in vsub->tmsi_new. - * Search all known subscribers to ensure that the TMSI is unique. */ -int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub) -{ - struct vlr_instance *vlr = vsub->vlr; - uint32_t tmsi; - int tried; - - for (tried = 0; tried < 100; tried++) { - if (RAND_bytes((uint8_t *) &tmsi, sizeof(tmsi)) != 1) { - LOGP(DVLR, LOGL_ERROR, "RAND_bytes failed\n"); - return -1; - } - /* throw the dice again, if the TSMI doesn't fit */ - if (tmsi == GSM_RESERVED_TMSI) - continue; - - /* Section 2.4 of 23.003: MSC has two MSB 00/01/10, SGSN 11 */ - if (vlr->cfg.is_ps) { - /* SGSN */ - tmsi |= 0xC000000; - } else { - /* MSC */ - if ((tmsi & 0xC0000000) == 0xC0000000) - tmsi &= ~0xC0000000; - } - - /* If this TMSI is already in use, try another one. */ - if (vlr_subscr_find_by_tmsi(vlr, tmsi)) - continue; - - vsub->tmsi_new = tmsi; - return 0; - } - - LOGP(DVLR, LOGL_ERROR, "subscr %s: unable to generate valid TMSI" - " after %d tries\n", vlr_subscr_name(vsub), tried); - return -1; -} - -/* Find subscriber by IMSI, or create new subscriber if not found. - * \param[in] vlr VLR instace. - * \param[in] imsi IMSI string. - * \param[out] created if non-NULL, returns whether a new entry was created. */ -struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr, - const char *imsi, - bool *created, - const char *file, - int line) -{ - struct vlr_subscr *vsub; - vsub = _vlr_subscr_find_by_imsi(vlr, imsi, file, line); - if (vsub) { - if (created) - *created = false; - return vsub; - } - - vsub = _vlr_subscr_get(_vlr_subscr_alloc(vlr), file, line); - if (!vsub) - return NULL; - vlr_subscr_set_imsi(vsub, imsi); - LOGP(DVLR, LOGL_INFO, "New subscr, IMSI: %s\n", vsub->imsi); - if (created) - *created = true; - return vsub; -} - -/* Find subscriber by TMSI, or create new subscriber if not found. - * \param[in] vlr VLR instace. - * \param[in] tmsi TMSI. - * \param[out] created if non-NULL, returns whether a new entry was created. */ -struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr, - uint32_t tmsi, - bool *created, - const char *file, - int line) -{ - struct vlr_subscr *vsub; - vsub = _vlr_subscr_find_by_tmsi(vlr, tmsi, file, line); - if (vsub) { - if (created) - *created = false; - return vsub; - } - - vsub = _vlr_subscr_get(_vlr_subscr_alloc(vlr), file, line); - if (!vsub) - return NULL; - vsub->tmsi = tmsi; - LOGP(DVLR, LOGL_INFO, "New subscr, TMSI: 0x%08x\n", vsub->tmsi); - if (created) - *created = true; - return vsub; -} - -void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi) -{ - if (!vsub) - return; - osmo_strlcpy(vsub->imsi, imsi, sizeof(vsub->imsi)); - vsub->id = atoll(vsub->imsi); - DEBUGP(DVLR, "set IMSI on subscriber; IMSI=%s id=%llu\n", - vsub->imsi, vsub->id); -} - -void vlr_subscr_set_imei(struct vlr_subscr *vsub, const char *imei) -{ - if (!vsub) - return; - osmo_strlcpy(vsub->imei, imei, sizeof(vsub->imei)); - DEBUGP(DVLR, "set IMEI on subscriber; IMSI=%s IMEI=%s\n", - vsub->imsi, vsub->imei); -} - -void vlr_subscr_set_imeisv(struct vlr_subscr *vsub, const char *imeisv) -{ - if (!vsub) - return; - osmo_strlcpy(vsub->imeisv, imeisv, sizeof(vsub->imeisv)); - DEBUGP(DVLR, "set IMEISV on subscriber; IMSI=%s IMEISV=%s\n", - vsub->imsi, vsub->imeisv); -} - -/* Safely copy the given MSISDN string to vsub->msisdn */ -void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn) -{ - if (!vsub) - return; - osmo_strlcpy(vsub->msisdn, msisdn, sizeof(vsub->msisdn)); - DEBUGP(DVLR, "set MSISDN on subscriber; IMSI=%s MSISDN=%s\n", - vsub->imsi, vsub->msisdn); -} - -bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi) -{ - return vsub && imsi && vsub->imsi[0] && !strcmp(vsub->imsi, imsi); -} - -bool vlr_subscr_matches_tmsi(struct vlr_subscr *vsub, uint32_t tmsi) -{ - return vsub && tmsi != GSM_RESERVED_TMSI - && (vsub->tmsi == tmsi || vsub->tmsi_new == tmsi); -} - -bool vlr_subscr_matches_msisdn(struct vlr_subscr *vsub, const char *msisdn) -{ - return vsub && msisdn && vsub->msisdn[0] - && !strcmp(vsub->msisdn, msisdn); -} - -bool vlr_subscr_matches_imei(struct vlr_subscr *vsub, const char *imei) -{ - return vsub && imei && vsub->imei[0] - && !strcmp(vsub->imei, imei); -} - -/* Send updated subscriber information to HLR */ -int vlr_subscr_changed(struct vlr_subscr *vsub) -{ - /* FIXME */ - LOGP(DVLR, LOGL_ERROR, "Not implemented: %s\n", __func__); - return 0; -} - -/*********************************************************************** - * PDP context data - ***********************************************************************/ - -struct sgsn_subscriber_pdp_data * -vlr_subscr_pdp_data_alloc(struct vlr_subscr *vsub) -{ - struct sgsn_subscriber_pdp_data* pdata; - - pdata = talloc_zero(vsub, struct sgsn_subscriber_pdp_data); - - llist_add_tail(&pdata->list, &vsub->ps.pdp_list); - - return pdata; -} - -static int vlr_subscr_pdp_data_clear(struct vlr_subscr *vsub) -{ - struct sgsn_subscriber_pdp_data *pdp, *pdp2; - int count = 0; - - llist_for_each_entry_safe(pdp, pdp2, &vsub->ps.pdp_list, list) { - llist_del(&pdp->list); - talloc_free(pdp); - count += 1; - } - - return count; -} - -static struct sgsn_subscriber_pdp_data * -vlr_subscr_pdp_data_get_by_id(struct vlr_subscr *vsub, unsigned context_id) -{ - struct sgsn_subscriber_pdp_data *pdp; - - llist_for_each_entry(pdp, &vsub->ps.pdp_list, list) { - if (pdp->context_id == context_id) - return pdp; - } - - return NULL; -} - -/*********************************************************************** - * Actual Implementation - ***********************************************************************/ - -static int vlr_rx_gsup_unknown_imsi(struct vlr_instance *vlr, - struct osmo_gsup_message *gsup_msg) -{ - if (OSMO_GSUP_IS_MSGT_REQUEST(gsup_msg->message_type)) { - vlr_tx_gsup_error_reply(vlr, gsup_msg, - GMM_CAUSE_IMSI_UNKNOWN); - LOGP(DVLR, LOGL_NOTICE, - "Unknown IMSI %s, discarding GSUP request " - "of type 0x%02x\n", - gsup_msg->imsi, gsup_msg->message_type); - } else if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) { - LOGP(DVLR, LOGL_NOTICE, - "Unknown IMSI %s, discarding GSUP error " - "of type 0x%02x, cause '%s' (%d)\n", - gsup_msg->imsi, gsup_msg->message_type, - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - } else { - LOGP(DVLR, LOGL_NOTICE, - "Unknown IMSI %s, discarding GSUP response " - "of type 0x%02x\n", - gsup_msg->imsi, gsup_msg->message_type); - } - - return -GMM_CAUSE_IMSI_UNKNOWN; -} - -static int vlr_rx_gsup_purge_no_subscr(struct vlr_instance *vlr, - struct osmo_gsup_message *gsup_msg) -{ - if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) { - LOGGSUPP(LOGL_NOTICE, gsup_msg, - "Purge MS has failed with cause '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), - gsup_msg->cause); - return -gsup_msg->cause; - } - LOGGSUPP(LOGL_INFO, gsup_msg, "Completing purge MS\n"); - return 0; -} - -/* VLR internal call to request UpdateLocation from HLR */ -int vlr_subscr_req_lu(struct vlr_subscr *vsub, bool is_ps) -{ - struct osmo_gsup_message gsup_msg = {0}; - int rc; - - gsup_msg.message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST; - rc = vlr_subscr_tx_gsup_message(vsub, &gsup_msg); - - return rc; -} - -/* VLR internal call to request tuples from HLR */ -int vlr_subscr_req_sai(struct vlr_subscr *vsub, - const uint8_t *auts, const uint8_t *auts_rand) -{ - struct osmo_gsup_message gsup_msg = {0}; - - gsup_msg.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST; - gsup_msg.auts = auts; - gsup_msg.rand = auts_rand; - - return vlr_subscr_tx_gsup_message(vsub, &gsup_msg); -} - -/* Tell HLR that authentication failure occurred */ -int vlr_subscr_tx_auth_fail_rep(struct vlr_subscr *vsub) -{ - struct osmo_gsup_message gsup_msg = {0}; - - gsup_msg.message_type = OSMO_GSUP_MSGT_AUTH_FAIL_REPORT; - osmo_strlcpy(gsup_msg.imsi, vsub->imsi, sizeof(gsup_msg.imsi)); - return vlr_tx_gsup_message(vsub->vlr, &gsup_msg); -} - -/* Update the subscriber with GSUP-received auth tuples */ -void vlr_subscr_update_tuples(struct vlr_subscr *vsub, - const struct osmo_gsup_message *gsup) -{ - unsigned int i; - unsigned int got_tuples; - - if (gsup->num_auth_vectors) { - memset(&vsub->auth_tuples, 0, sizeof(vsub->auth_tuples)); - for (i = 0; i < ARRAY_SIZE(vsub->auth_tuples); i++) - vsub->auth_tuples[i].key_seq = GSM_KEY_SEQ_INVAL; - } - - got_tuples = 0; - for (i = 0; i < gsup->num_auth_vectors; i++) { - size_t key_seq = i; - - if (key_seq >= ARRAY_SIZE(vsub->auth_tuples)) { - LOGVSUBP(LOGL_NOTICE, vsub, - "Skipping auth tuple wih invalid cksn %zu\n", - key_seq); - continue; - } - vsub->auth_tuples[i].vec = gsup->auth_vectors[i]; - vsub->auth_tuples[i].key_seq = key_seq; - got_tuples ++; - } - - LOGVSUBP(LOGL_DEBUG, vsub, "Received %u auth tuples\n", got_tuples); - - if (!got_tuples) { - /* FIXME what now? */ - // vlr_subscr_cancel(vsub, GMM_CAUSE_GSM_AUTH_UNACCEPT); ? - } - - /* New tuples means last_tuple becomes invalid */ - vsub->last_tuple = NULL; -} - -/* Handle SendAuthInfo Result/Error from HLR */ -static int vlr_subscr_handle_sai_res(struct vlr_subscr *vsub, - const struct osmo_gsup_message *gsup) -{ - struct osmo_fsm_inst *auth_fi = vsub->auth_fsm; - void *data = (void *) gsup; - - switch (gsup->message_type) { - case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: - osmo_fsm_inst_dispatch(auth_fi, VLR_AUTH_E_HLR_SAI_ACK, data); - break; - case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: - osmo_fsm_inst_dispatch(auth_fi, VLR_AUTH_E_HLR_SAI_NACK, data); - break; - default: - return -1; - } - - return 0; -} - -static int decode_bcd_number_safe(char *output, int output_len, - const uint8_t *bcd_lv, int input_len, - int h_len) -{ - uint8_t len; - OSMO_ASSERT(output_len >= 1); - *output = '\0'; - if (input_len < 1) - return -EIO; - len = bcd_lv[0]; - if (input_len < len) - return -EIO; - return gsm48_decode_bcd_number(output, output_len, bcd_lv, h_len); -} - -static void vlr_subscr_gsup_insert_data(struct vlr_subscr *vsub, - const struct osmo_gsup_message *gsup_msg) -{ - unsigned idx; - int rc; - - if (gsup_msg->msisdn_enc) { - decode_bcd_number_safe(vsub->msisdn, sizeof(vsub->msisdn), - gsup_msg->msisdn_enc, - gsup_msg->msisdn_enc_len, 0); - LOGP(DVLR, LOGL_DEBUG, "IMSI:%s has MSISDN:%s\n", - vsub->imsi, vsub->msisdn); - } - - if (gsup_msg->hlr_enc) { - if (gsup_msg->hlr_enc_len > sizeof(vsub->hlr.buf)) { - LOGP(DVLR, LOGL_ERROR, "HLR-Number too long (%zu)\n", - gsup_msg->hlr_enc_len); - vsub->hlr.len = 0; - } else { - memcpy(vsub->hlr.buf, gsup_msg->hlr_enc, - gsup_msg->hlr_enc_len); - vsub->hlr.len = gsup_msg->hlr_enc_len; - } - } - - if (gsup_msg->pdp_info_compl) { - rc = vlr_subscr_pdp_data_clear(vsub); - if (rc > 0) - LOGP(DVLR, LOGL_INFO, "Cleared existing PDP info\n"); - } - - for (idx = 0; idx < gsup_msg->num_pdp_infos; idx++) { - const struct osmo_gsup_pdp_info *pdp_info = &gsup_msg->pdp_infos[idx]; - size_t ctx_id = pdp_info->context_id; - struct sgsn_subscriber_pdp_data *pdp_data; - - if (pdp_info->apn_enc_len >= sizeof(pdp_data->apn_str)-1) { - LOGVSUBP(LOGL_ERROR, vsub, - "APN too long, context id = %zu, APN = %s\n", - ctx_id, osmo_hexdump(pdp_info->apn_enc, - pdp_info->apn_enc_len)); - continue; - } - - if (pdp_info->qos_enc_len > sizeof(pdp_data->qos_subscribed)) { - LOGVSUBP(LOGL_ERROR, vsub, - "QoS info too long (%zu)\n", - pdp_info->qos_enc_len); - continue; - } - - LOGVSUBP(LOGL_INFO, vsub, - "Will set PDP info, context id = %zu, APN = %s\n", - ctx_id, osmo_hexdump(pdp_info->apn_enc, pdp_info->apn_enc_len)); - - /* Set PDP info [ctx_id] */ - pdp_data = vlr_subscr_pdp_data_get_by_id(vsub, ctx_id); - if (!pdp_data) { - pdp_data = vlr_subscr_pdp_data_alloc(vsub); - pdp_data->context_id = ctx_id; - } - - OSMO_ASSERT(pdp_data != NULL); - pdp_data->pdp_type = pdp_info->pdp_type; - osmo_apn_to_str(pdp_data->apn_str, - pdp_info->apn_enc, pdp_info->apn_enc_len); - memcpy(pdp_data->qos_subscribed, pdp_info->qos_enc, pdp_info->qos_enc_len); - pdp_data->qos_subscribed_len = pdp_info->qos_enc_len; - } -} - - -/* Handle InsertSubscrData Result from HLR */ -static int vlr_subscr_handle_isd_req(struct vlr_subscr *vsub, - const struct osmo_gsup_message *gsup) -{ - struct osmo_gsup_message gsup_reply = {0}; - - vlr_subscr_gsup_insert_data(vsub, gsup); - vsub->vlr->ops.subscr_update(vsub); - - gsup_reply.message_type = OSMO_GSUP_MSGT_INSERT_DATA_RESULT; - return vlr_subscr_tx_gsup_message(vsub, &gsup_reply); -} - -/* Handle UpdateLocation Result from HLR */ -static int vlr_subscr_handle_lu_res(struct vlr_subscr *vsub, - const struct osmo_gsup_message *gsup) -{ - if (!vsub->lu_fsm) { - LOGVSUBP(LOGL_ERROR, vsub, "Rx GSUP LU Result " - "without LU in progress\n"); - return -ENODEV; - } - - /* contrary to MAP, we allow piggy-backing subscriber data onto the - * UPDATE LOCATION RESULT, and don't mandate the use of a separate - * nested INSERT SUBSCRIBER DATA transaction */ - vlr_subscr_gsup_insert_data(vsub, gsup); - - osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_HLR_LU_RES, NULL); - - return 0; -} - -/* Handle UpdateLocation Result from HLR */ -static int vlr_subscr_handle_lu_err(struct vlr_subscr *vsub, - const struct osmo_gsup_message *gsup) -{ - if (!vsub->lu_fsm) { - LOGVSUBP(LOGL_ERROR, vsub, "Rx GSUP LU Error " - "without LU in progress\n"); - return -ENODEV; - } - - LOGVSUBP(LOGL_DEBUG, vsub, "UpdateLocation failed; gmm_cause: %s\n", - get_value_string(gsm48_gmm_cause_names, gsup->cause)); - - osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_HLR_LU_RES, - (void *)&gsup->cause); - - return 0; -} - -/* Handle LOCATION CANCEL request from HLR */ -static int vlr_subscr_handle_cancel_req(struct vlr_subscr *vsub, - struct osmo_gsup_message *gsup_msg) -{ - struct osmo_gsup_message gsup_reply = {0}; - int is_update_procedure = !gsup_msg->cancel_type || - gsup_msg->cancel_type == OSMO_GSUP_CANCEL_TYPE_UPDATE; - - LOGVSUBP(LOGL_INFO, vsub, "Cancelling MS subscriber (%s)\n", - is_update_procedure ? - "update procedure" : "subscription withdraw"); - - gsup_reply.message_type = OSMO_GSUP_MSGT_LOCATION_CANCEL_RESULT; - vlr_subscr_tx_gsup_message(vsub, &gsup_reply); - - vlr_subscr_cancel(vsub, gsup_msg->cause); - - return 0; -} - -/* Incoming handler for GSUP from HLR. - * Keep this function non-static for direct invocation by unit tests. */ -int vlr_gsupc_read_cb(struct gsup_client *gsupc, struct msgb *msg) -{ - struct vlr_instance *vlr = (struct vlr_instance *) gsupc->data; - struct vlr_subscr *vsub; - struct osmo_gsup_message gsup; - int rc; - - DEBUGP(DVLR, "GSUP rx %u: %s\n", msgb_l2len(msg), - osmo_hexdump_nospc(msgb_l2(msg), msgb_l2len(msg))); - - rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup); - if (rc < 0) { - LOGP(DVLR, LOGL_ERROR, - "decoding GSUP message fails with error '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, -rc), -rc); - return rc; - } - - if (!gsup.imsi[0]) { - LOGP(DVLR, LOGL_ERROR, "Missing IMSI in GSUP message\n"); - if (OSMO_GSUP_IS_MSGT_REQUEST(gsup.message_type)) - vlr_tx_gsup_error_reply(vlr, &gsup, - GMM_CAUSE_INV_MAND_INFO); - return -GMM_CAUSE_INV_MAND_INFO; - } - - vsub = vlr_subscr_find_by_imsi(vlr, gsup.imsi); - if (!vsub) { - switch (gsup.message_type) { - case OSMO_GSUP_MSGT_PURGE_MS_RESULT: - case OSMO_GSUP_MSGT_PURGE_MS_ERROR: - return vlr_rx_gsup_purge_no_subscr(vlr, &gsup); - default: - return vlr_rx_gsup_unknown_imsi(vlr, &gsup); - } - } - - switch (gsup.message_type) { - case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: - case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: - rc = vlr_subscr_handle_sai_res(vsub, &gsup); - break; - case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: - rc = vlr_subscr_handle_isd_req(vsub, &gsup); - break; - case OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST: - rc = vlr_subscr_handle_cancel_req(vsub, &gsup); - break; - case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: - rc = vlr_subscr_handle_lu_res(vsub, &gsup); - break; - case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: - rc = vlr_subscr_handle_lu_err(vsub, &gsup); - break; - case OSMO_GSUP_MSGT_PURGE_MS_ERROR: - case OSMO_GSUP_MSGT_PURGE_MS_RESULT: - case OSMO_GSUP_MSGT_DELETE_DATA_REQUEST: - LOGVSUBP(LOGL_ERROR, vsub, - "Rx GSUP msg_type=%d not yet implemented\n", - gsup.message_type); - rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; - break; - default: - LOGVSUBP(LOGL_ERROR, vsub, - "Rx GSUP msg_type=%d not valid at VLR/SGSN side\n", - gsup.message_type); - rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; - break; - } - - vlr_subscr_put(vsub); - return rc; -} - -/* MSC->VLR: Subscriber has provided IDENTITY RESPONSE */ -int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, - const uint8_t *mi, size_t mi_len) -{ - char mi_string[GSM48_MI_SIZE]; - uint8_t mi_type = mi[0] & GSM_MI_TYPE_MASK; - - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); - - /* update the vlr_subscr with the given identity */ - switch (mi_type) { - case GSM_MI_TYPE_IMSI: - if (vsub->imsi[0] - && !vlr_subscr_matches_imsi(vsub, mi_string)) { - LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP differs:" - " %s\n", mi_string); - } else - vlr_subscr_set_imsi(vsub, mi_string); - break; - case GSM_MI_TYPE_IMEI: - vlr_subscr_set_imei(vsub, mi_string); - break; - case GSM_MI_TYPE_IMEISV: - vlr_subscr_set_imeisv(vsub, mi_string); - break; - } - - if (vsub->auth_fsm) { - switch (mi_type) { - case GSM_MI_TYPE_IMSI: - osmo_fsm_inst_dispatch(vsub->auth_fsm, - VLR_AUTH_E_MS_ID_IMSI, mi_string); - break; - } - } - - if (vsub->lu_fsm) { - uint32_t event = 0; - switch (mi_type) { - case GSM_MI_TYPE_IMSI: - event = VLR_ULA_E_ID_IMSI; - break; - case GSM_MI_TYPE_IMEI: - event = VLR_ULA_E_ID_IMEI; - break; - case GSM_MI_TYPE_IMEISV: - event = VLR_ULA_E_ID_IMEISV; - break; - default: - OSMO_ASSERT(0); - break; - } - osmo_fsm_inst_dispatch(vsub->lu_fsm, event, mi_string); - } else { - LOGVSUBP(LOGL_NOTICE, vsub, "gratuitous ID RESPONSE?!?\n"); - } - - return 0; -} - -/* MSC->VLR: Subscriber has provided IDENTITY RESPONSE */ -int vlr_subscr_rx_tmsi_reall_compl(struct vlr_subscr *vsub) -{ - if (vsub->lu_fsm) { - return osmo_fsm_inst_dispatch(vsub->lu_fsm, - VLR_ULA_E_NEW_TMSI_ACK, NULL); - } else if (vsub->proc_arq_fsm) { - return osmo_fsm_inst_dispatch(vsub->proc_arq_fsm, - PR_ARQ_E_TMSI_ACK, NULL); - } else { - LOGVSUBP(LOGL_NOTICE, vsub, - "gratuitous TMSI REALLOC COMPL"); - return -EINVAL; - } -} - -int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub) -{ - /* paranoia: should any LU or PARQ FSMs still be running, stop them. */ - vlr_subscr_cancel(vsub, GMM_CAUSE_IMPL_DETACHED); - - vsub->imsi_detached_flag = true; - if (vsub->lu_complete) { - vsub->lu_complete = false; - /* balancing the get from vlr_lu_compl_fsm_success() */ - vlr_subscr_put(vsub); - } - return 0; -} - -/* Tear down any running FSMs due to MSC connection timeout. - * Visit all vsub->*_fsm pointers and give them a queue to send a final reject - * message before the entire connection is torn down. - * \param[in] vsub subscriber to tear down - */ -void vlr_subscr_conn_timeout(struct vlr_subscr *vsub) -{ - if (!vsub) - return; - - vlr_loc_update_conn_timeout(vsub->lu_fsm); - vlr_parq_conn_timeout(vsub->proc_arq_fsm); -} - -struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops) -{ - struct vlr_instance *vlr = talloc_zero(ctx, struct vlr_instance); - OSMO_ASSERT(vlr); - - /* Some of these are needed only on UTRAN, but in case the caller wants - * only GERAN, she should just provide dummy callbacks. */ - OSMO_ASSERT(ops->tx_auth_req); - OSMO_ASSERT(ops->tx_auth_rej); - OSMO_ASSERT(ops->tx_id_req); - OSMO_ASSERT(ops->tx_lu_acc); - OSMO_ASSERT(ops->tx_lu_rej); - OSMO_ASSERT(ops->tx_cm_serv_acc); - OSMO_ASSERT(ops->tx_cm_serv_rej); - OSMO_ASSERT(ops->set_ciph_mode); - OSMO_ASSERT(ops->tx_common_id); - OSMO_ASSERT(ops->subscr_update); - OSMO_ASSERT(ops->subscr_assoc); - - INIT_LLIST_HEAD(&vlr->subscribers); - INIT_LLIST_HEAD(&vlr->operations); - memcpy(&vlr->ops, ops, sizeof(vlr->ops)); - - /* osmo_auth_fsm.c */ - osmo_fsm_register(&vlr_auth_fsm); - /* osmo_lu_fsm.c */ - vlr_lu_fsm_init(); - /* vlr_access_request_fsm.c */ - vlr_parq_fsm_init(); - - return vlr; -} - -int vlr_start(const char *gsup_unit_name, struct vlr_instance *vlr, - const char *gsup_server_addr_str, uint16_t gsup_server_port) -{ - OSMO_ASSERT(vlr); - - vlr->gsup_client = gsup_client_create(gsup_unit_name, - gsup_server_addr_str, - gsup_server_port, - &vlr_gsupc_read_cb, NULL); - if (!vlr->gsup_client) - return -ENOMEM; - vlr->gsup_client->data = vlr; - - return 0; -} - -/* MSC->VLR: Subscribre has disconnected */ -int vlr_subscr_disconnected(struct vlr_subscr *vsub) -{ - /* This corresponds to a MAP-ABORT from MSC->VLR on a classic B - * interface */ - osmo_fsm_inst_term(vsub->lu_fsm, OSMO_FSM_TERM_REQUEST, NULL); - osmo_fsm_inst_term(vsub->auth_fsm, OSMO_FSM_TERM_REQUEST, NULL); - vsub->msc_conn_ref = NULL; - - return 0; -} - -/* MSC->VLR: Receive Authentication Failure from Subscriber */ -int vlr_subscr_rx_auth_fail(struct vlr_subscr *vsub, const uint8_t *auts) -{ - struct vlr_auth_resp_par par = {0}; - par.auts = auts; - - osmo_fsm_inst_dispatch(vsub->auth_fsm, VLR_AUTH_E_MS_AUTH_FAIL, &par); - return 0; -} - -/* MSC->VLR: Receive Authentication Response from MS - * \returns 1 in case of success, 0 in case of delay, -1 on auth error */ -int vlr_subscr_rx_auth_resp(struct vlr_subscr *vsub, bool is_r99, - bool is_utran, const uint8_t *res, uint8_t res_len) -{ - struct osmo_fsm_inst *auth_fi = vsub->auth_fsm; - struct vlr_auth_resp_par par; - - par.is_r99 = is_r99; - par.is_utran = is_utran; - par.res = res; - par.res_len = res_len; - osmo_fsm_inst_dispatch(auth_fi, VLR_AUTH_E_MS_AUTH_RESP, (void *) &par); - - return 0; -} - -/* MSC->VLR: Receive result of Ciphering Mode Command from MS */ -void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, struct vlr_ciph_result *res) -{ - if (vsub->lu_fsm && vsub->lu_fsm->state == VLR_ULA_S_WAIT_CIPH) - osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_CIPH_RES, res); - if (vsub->proc_arq_fsm - && vsub->proc_arq_fsm->state == PR_ARQ_S_WAIT_CIPH) - osmo_fsm_inst_dispatch(vsub->proc_arq_fsm, PR_ARQ_E_CIPH_RES, - res); -} - -/* Internal evaluation of requested ciphering mode. - * Send set_ciph_mode() to MSC depending on the ciph_mode argument. - * \param[in] vlr VLR instance. - * \param[in] fi Calling FSM instance, for logging. - * \param[in] msc_conn_ref MSC conn to send to. - * \param[in] ciph_mode Ciphering config, to decide whether to do ciphering. - * \returns 0 if no ciphering is needed or message was sent successfully, - * or a negative value if ciph_mode is invalid or sending failed. - */ -int vlr_set_ciph_mode(struct vlr_instance *vlr, - struct osmo_fsm_inst *fi, - void *msc_conn_ref, - enum vlr_ciph ciph_mode, - bool retrieve_imeisv) -{ - switch (ciph_mode) { - case VLR_CIPH_NONE: - return 0; - - case VLR_CIPH_A5_1: - case VLR_CIPH_A5_3: - return vlr->ops.set_ciph_mode(msc_conn_ref, - ciph_mode, - retrieve_imeisv); - - case VLR_CIPH_A5_2: - /* TODO policy by user config? */ - LOGPFSML(fi, LOGL_ERROR, "A5/2 ciphering is not allowed\n"); - return -EINVAL; - - default: - LOGPFSML(fi, LOGL_ERROR, "unknown ciphering value: %d\n", - ciph_mode); - return -EINVAL; - } -} - -void log_set_filter_vlr_subscr(struct log_target *target, - struct vlr_subscr *vlr_subscr) -{ - struct vlr_subscr **fsub = (void*)&target->filter_data[LOG_FLT_VLR_SUBSCR]; - - /* free the old data */ - if (*fsub) { - vlr_subscr_put(*fsub); - *fsub = NULL; - } - - if (vlr_subscr) { - target->filter_map |= (1 << LOG_FLT_VLR_SUBSCR); - *fsub = vlr_subscr_get(vlr_subscr); - } else - target->filter_map &= ~(1 << LOG_FLT_VLR_SUBSCR); -} diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c deleted file mode 100644 index f9ed0b57d..000000000 --- a/src/libvlr/vlr_access_req_fsm.c +++ /dev/null @@ -1,795 +0,0 @@ -/* Osmocom Visitor Location Register (VLR): Access Request FSMs */ - -/* (C) 2016 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include - -#include "vlr_core.h" -#include "vlr_auth_fsm.h" -#include "vlr_lu_fsm.h" -#include "vlr_access_req_fsm.h" - -#define S(x) (1 << (x)) - -/*********************************************************************** - * Process_Access_Request_VLR, TS 29.002 Chapter 25.4.2 - ***********************************************************************/ - -const struct value_string vlr_proc_arq_result_names[] = { - OSMO_VALUE_STRING(VLR_PR_ARQ_RES_NONE), - OSMO_VALUE_STRING(VLR_PR_ARQ_RES_SYSTEM_FAILURE), - OSMO_VALUE_STRING(VLR_PR_ARQ_RES_ILLEGAL_SUBSCR), - OSMO_VALUE_STRING(VLR_PR_ARQ_RES_UNIDENT_SUBSCR), - OSMO_VALUE_STRING(VLR_PR_ARQ_RES_ROAMING_NOTALLOWED), - OSMO_VALUE_STRING(VLR_PR_ARQ_RES_ILLEGAL_EQUIP), - OSMO_VALUE_STRING(VLR_PR_ARQ_RES_UNKNOWN_ERROR), - OSMO_VALUE_STRING(VLR_PR_ARQ_RES_TIMEOUT), - OSMO_VALUE_STRING(VLR_PR_ARQ_RES_PASSED), - { 0, NULL } -}; - -static const struct value_string proc_arq_vlr_event_names[] = { - OSMO_VALUE_STRING(PR_ARQ_E_START), - OSMO_VALUE_STRING(PR_ARQ_E_ID_IMSI), - OSMO_VALUE_STRING(PR_ARQ_E_AUTH_RES), - OSMO_VALUE_STRING(PR_ARQ_E_CIPH_RES), - OSMO_VALUE_STRING(PR_ARQ_E_UPD_LOC_RES), - OSMO_VALUE_STRING(PR_ARQ_E_TRACE_RES), - OSMO_VALUE_STRING(PR_ARQ_E_IMEI_RES), - OSMO_VALUE_STRING(PR_ARQ_E_PRES_RES), - OSMO_VALUE_STRING(PR_ARQ_E_TMSI_ACK), - { 0, NULL } -}; - -struct proc_arq_priv { - struct vlr_instance *vlr; - struct vlr_subscr *vsub; - void *msc_conn_ref; - struct osmo_fsm_inst *ul_child_fsm; - struct osmo_fsm_inst *sub_pres_vlr_fsm; - uint32_t parent_event_success; - uint32_t parent_event_failure; - void *parent_event_data; - - enum vlr_parq_type type; - enum vlr_proc_arq_result result; - bool by_tmsi; - char imsi[16]; - uint32_t tmsi; - struct osmo_location_area_id lai; - bool authentication_required; - enum vlr_ciph ciphering_required; - bool is_r99; - bool is_utran; - bool implicitly_accepted_parq_by_ciphering_cmd; -}; - -static void assoc_par_with_subscr(struct osmo_fsm_inst *fi, struct vlr_subscr *vsub) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_instance *vlr = par->vlr; - - vsub->msc_conn_ref = par->msc_conn_ref; - par->vsub = vsub; - /* Tell MSC to associate this subscriber with the given - * connection */ - vlr->ops.subscr_assoc(par->msc_conn_ref, par->vsub); -} - -#define proc_arq_fsm_done(fi, res) _proc_arq_fsm_done(fi, res, __FILE__, __LINE__) -static void _proc_arq_fsm_done(struct osmo_fsm_inst *fi, - enum vlr_proc_arq_result res, - const char *file, int line) -{ - struct proc_arq_priv *par = fi->priv; - LOGPFSMSRC(fi, file, line, "proc_arq_fsm_done(%s)\n", - vlr_proc_arq_result_name(res)); - par->result = res; - osmo_fsm_inst_state_chg(fi, PR_ARQ_S_DONE, 0, 0); -} - -static void proc_arq_vlr_dispatch_result(struct osmo_fsm_inst *fi, - uint32_t prev_state) -{ - struct proc_arq_priv *par = fi->priv; - bool success; - int rc; - LOGPFSM(fi, "Process Access Request result: %s\n", - vlr_proc_arq_result_name(par->result)); - - success = (par->result == VLR_PR_ARQ_RES_PASSED); - - /* It would be logical to first dispatch the success event to the - * parent FSM, but that could start actions that send messages to the - * MS. Rather send the CM Service Accept message first and then signal - * success. Since messages are handled synchronously, the success event - * will be processed before we handle new incoming data from the MS. */ - - if (par->type == VLR_PR_ARQ_T_CM_SERV_REQ) { - if (success - && !par->implicitly_accepted_parq_by_ciphering_cmd) { - rc = par->vlr->ops.tx_cm_serv_acc(par->msc_conn_ref); - if (rc) { - LOGPFSML(fi, LOGL_ERROR, - "Failed to send CM Service Accept\n"); - success = false; - } - } - if (!success) { - rc = par->vlr->ops.tx_cm_serv_rej(par->msc_conn_ref, - par->result); - if (rc) - LOGPFSML(fi, LOGL_ERROR, - "Failed to send CM Service Reject\n"); - } - } - - /* For VLR_PR_ARQ_T_PAGING_RESP, there is nothing to send. The conn_fsm - * will start handling pending paging transactions. */ - - if (!fi->proc.parent) { - LOGPFSML(fi, LOGL_ERROR, "No parent FSM"); - return; - } - osmo_fsm_inst_dispatch(fi->proc.parent, - success ? par->parent_event_success - : par->parent_event_failure, - par->parent_event_data); -} - -void proc_arq_vlr_cleanup(struct osmo_fsm_inst *fi, - enum osmo_fsm_term_cause cause) -{ - struct proc_arq_priv *par = fi->priv; - if (par->vsub && par->vsub->proc_arq_fsm == fi) - par->vsub->proc_arq_fsm = NULL; -} - -static void _proc_arq_vlr_post_imei(struct osmo_fsm_inst *fi) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_subscr *vsub = par->vsub; - - LOGPFSM(fi, "%s()\n", __func__); - - /* See 3GPP TS 29.002 Proc_Acc_Req_VLR3. */ - /* TODO: Identity := IMSI */ - if (0 /* TODO: TMSI reallocation at access: vlr->cfg.alloc_tmsi_arq */) { - vlr_subscr_alloc_tmsi(vsub); - /* TODO: forward TMSI to MS, wait for TMSI - * REALLOC COMPLETE */ - /* TODO: Freeze old TMSI */ - osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_TMSI_ACK, 0, 0); - return; - } - - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_PASSED); -} - -static void _proc_arq_vlr_post_trace(struct osmo_fsm_inst *fi) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_subscr *vsub = par->vsub; - struct vlr_instance *vlr = vsub->vlr; - - LOGPFSM(fi, "%s()\n", __func__); - - /* Node 3 */ - /* See 3GPP TS 29.002 Proc_Acc_Req_VLR3. */ - if (0 /* IMEI check required */) { - /* Chck_IMEI_VLR */ - vlr->ops.tx_id_req(par->msc_conn_ref, GSM_MI_TYPE_IMEI); - osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_CHECK_IMEI, - vlr_timer(vlr, 3270), 3270); - } else - _proc_arq_vlr_post_imei(fi); -} - -/* After Subscriber_Present_VLR */ -static void _proc_arq_vlr_post_pres(struct osmo_fsm_inst *fi) -{ - LOGPFSM(fi, "%s()\n", __func__); - /* See 3GPP TS 29.002 Proc_Acc_Req_VLR3. */ - if (0 /* TODO: tracing required */) { - /* TODO: Trace_Subscriber_Activity_VLR */ - osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_TRACE_SUB, 0, 0); - } - _proc_arq_vlr_post_trace(fi); -} - -/* After Update_Location_Child_VLR */ -static void _proc_arq_vlr_node2_post_vlr(struct osmo_fsm_inst *fi) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_subscr *vsub = par->vsub; - - LOGPFSM(fi, "%s()\n", __func__); - - if (!vsub->sub_dataconf_by_hlr_ind) { - /* Set User Error: Unidentified Subscriber */ - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_UNIDENT_SUBSCR); - return; - } - /* We don't feature location area specific blocking (yet). */ - if (0 /* roaming not allowed in LA */) { - /* Set User Error: Roaming not allowed in this LA */ - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_ROAMING_NOTALLOWED); - return; - } - vsub->imsi_detached_flag = false; - if (vsub->ms_not_reachable_flag) { - /* Start Subscriber_Present_VLR */ - osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_SUB_PRES, 0, 0); - par->sub_pres_vlr_fsm = sub_pres_vlr_fsm_start(fi, vsub, - PR_ARQ_E_PRES_RES); - return; - } - _proc_arq_vlr_post_pres(fi); -} - -static void _proc_arq_vlr_node2_post_ciph(struct osmo_fsm_inst *fi) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_subscr *vsub = par->vsub; - - LOGPFSM(fi, "%s()\n", __func__); - - if (par->is_utran) { - int rc; - rc = par->vlr->ops.tx_common_id(par->msc_conn_ref); - if (rc) - LOGPFSML(fi, LOGL_ERROR, - "Error while sending Common ID (%d)\n", rc); - } - - vsub->conf_by_radio_contact_ind = true; - if (vsub->loc_conf_in_hlr_ind == false) { - /* start Update_Location_Child_VLR. WE use - * Update_HLR_VLR instead, the differences appear - * insignificant for now. */ - par->ul_child_fsm = upd_hlr_vlr_proc_start(fi, vsub, - PR_ARQ_E_UPD_LOC_RES); - osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_UPD_LOC_CHILD, 0, 0); - return; - } - _proc_arq_vlr_node2_post_vlr(fi); -} - -static bool is_ciph_required(struct proc_arq_priv *par) -{ - return par->ciphering_required != VLR_CIPH_NONE; -} - -static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_subscr *vsub = par->vsub; - - LOGPFSM(fi, "%s()\n", __func__); - - if (!is_ciph_required(par)) { - _proc_arq_vlr_node2_post_ciph(fi); - return; - } - - if (vlr_set_ciph_mode(vsub->vlr, fi, par->msc_conn_ref, - par->ciphering_required, - vsub->vlr->cfg.retrieve_imeisv_ciphered)) { - LOGPFSML(fi, LOGL_ERROR, - "Failed to send Ciphering Mode Command\n"); - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_SYSTEM_FAILURE); - return; - } - - par->implicitly_accepted_parq_by_ciphering_cmd = true; - osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_CIPH, 0, 0); -} - -static bool is_auth_required(struct proc_arq_priv *par) -{ - /* The cases where the authentication procedure should be used - * are defined in 3GPP TS 33.102 */ - /* For now we use a default value passed in to vlr_lu_fsm(). */ - return par->authentication_required - || (par->ciphering_required != VLR_CIPH_NONE); -} - -/* after the IMSI is known */ -static void proc_arq_vlr_fn_post_imsi(struct osmo_fsm_inst *fi) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_subscr *vsub = par->vsub; - - LOGPFSM(fi, "%s()\n", __func__); - - OSMO_ASSERT(vsub); - - /* TODO: Identity IMEI -> System Failure */ - if (is_auth_required(par)) { - osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_AUTH, - 0, 0); - vsub->auth_fsm = auth_fsm_start(vsub, fi->log_level, fi, - PR_ARQ_E_AUTH_RES, - par->is_r99, - par->is_utran); - } else { - _proc_arq_vlr_node2(fi); - } -} - -static void proc_arq_vlr_fn_init(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_instance *vlr = par->vlr; - struct vlr_subscr *vsub = NULL; - - OSMO_ASSERT(event == PR_ARQ_E_START); - - /* Obtain_Identity_VLR */ - if (!par->by_tmsi) { - /* IMSI was included */ - vsub = vlr_subscr_find_by_imsi(par->vlr, par->imsi); - } else { - /* TMSI was included */ - vsub = vlr_subscr_find_by_tmsi(par->vlr, par->tmsi); - } - if (vsub) { - log_set_context(LOG_CTX_VLR_SUBSCR, vsub); - if (vsub->proc_arq_fsm && fi != vsub->proc_arq_fsm) { - LOGPFSML(fi, LOGL_ERROR, - "Another proc_arq_fsm is already" - " associated with subscr %s," - " terminating the other FSM.\n", - vlr_subscr_name(vsub)); - proc_arq_fsm_done(vsub->proc_arq_fsm, - VLR_PR_ARQ_RES_SYSTEM_FAILURE); - } - vsub->proc_arq_fsm = fi; - assoc_par_with_subscr(fi, vsub); - proc_arq_vlr_fn_post_imsi(fi); - vlr_subscr_put(vsub); - return; - } - /* No VSUB could be resolved. What now? */ - - if (!par->by_tmsi) { - /* We couldn't find a subscriber even by IMSI, - * Set User Error: Unidentified Subscriber */ - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_UNIDENT_SUBSCR); - return; - } else { - /* TMSI was included, are we permitted to use it? */ - if (vlr->cfg.parq_retrieve_imsi) { - /* Obtain_IMSI_VLR */ - osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_OBTAIN_IMSI, - vlr_timer(vlr, 3270), 3270); - return; - } else { - /* Set User Error: Unidentified Subscriber */ - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_UNIDENT_SUBSCR); - return; - } - } -} - -/* ID REQ(IMSI) has returned */ -static void proc_arq_vlr_fn_w_obt_imsi(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_instance *vlr = par->vlr; - struct vlr_subscr *vsub; - - OSMO_ASSERT(event == PR_ARQ_E_ID_IMSI); - - vsub = vlr_subscr_find_by_imsi(vlr, par->imsi); - if (!vsub) { - /* Set User Error: Unidentified Subscriber */ - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_UNIDENT_SUBSCR); - return; - } - assoc_par_with_subscr(fi, vsub); - proc_arq_vlr_fn_post_imsi(fi); - vlr_subscr_put(vsub); -} - -/* Authenticate_VLR has completed */ -static void proc_arq_vlr_fn_w_auth(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - enum vlr_auth_fsm_result res; - enum vlr_proc_arq_result ret; - - OSMO_ASSERT(event == PR_ARQ_E_AUTH_RES); - - res = data ? *(enum vlr_auth_fsm_result*)data : -1; - LOGPFSM(fi, "got %s\n", vlr_auth_fsm_result_name(res)); - - switch (res) { - case VLR_AUTH_RES_PASSED: - /* Node 2 */ - _proc_arq_vlr_node2(fi); - return; - case VLR_AUTH_RES_ABORTED: - /* Error */ - ret = VLR_PR_ARQ_RES_UNKNOWN_ERROR; - break; - case VLR_AUTH_RES_UNKNOWN_SUBSCR: - /* Set User Error: Unidentified Subscriber */ - ret = VLR_PR_ARQ_RES_UNIDENT_SUBSCR; - break; - case VLR_AUTH_RES_AUTH_FAILED: - /* Set User Error: Illegal Subscriber */ - ret = VLR_PR_ARQ_RES_ILLEGAL_SUBSCR; - break; - case VLR_AUTH_RES_PROC_ERR: - /* Set User Error: System failure */ - ret = VLR_PR_ARQ_RES_SYSTEM_FAILURE; - break; - default: - LOGPFSML(fi, LOGL_ERROR, "Unexpected vlr_auth_fsm_result value: %d (data=%p)\n", res, data); - ret = VLR_PR_ARQ_RES_UNKNOWN_ERROR; - break; - } - - /* send process_access_req response to caller, enter error state */ - proc_arq_fsm_done(fi, ret); -} - -static void proc_arq_vlr_fn_w_ciph(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - struct proc_arq_priv *par = fi->priv; - struct vlr_subscr *vsub = par->vsub; - struct vlr_ciph_result res = { .cause = VLR_CIPH_REJECT }; - - OSMO_ASSERT(event == PR_ARQ_E_CIPH_RES); - - if (!data) - LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: NULL\n"); - else - res = *(struct vlr_ciph_result*)data; - - switch (res.cause) { - case VLR_CIPH_COMPL: - break; - case VLR_CIPH_REJECT: - LOGPFSM(fi, "ciphering rejected\n"); - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_ILLEGAL_SUBSCR); - return; - default: - LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: %d\n", - res.cause); - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_ILLEGAL_SUBSCR); - return; - } - - - if (res.imeisv) { - LOGPFSM(fi, "got IMEISV: %s\n", res.imeisv); - vlr_subscr_set_imeisv(vsub, res.imeisv); - } - _proc_arq_vlr_node2_post_ciph(fi); -} - -/* Update_Location_Child_VLR has completed */ -static void proc_arq_vlr_fn_w_upd_loc(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - OSMO_ASSERT(event == PR_ARQ_E_UPD_LOC_RES); - - _proc_arq_vlr_node2_post_vlr(fi); -} - -/* Subscriber_Present_VLR has completed */ -static void proc_arq_vlr_fn_w_pres(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - OSMO_ASSERT(event == PR_ARQ_E_PRES_RES); - - _proc_arq_vlr_post_pres(fi); -} - -static void proc_arq_vlr_fn_w_trace(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - OSMO_ASSERT(event == PR_ARQ_E_TRACE_RES); - - _proc_arq_vlr_post_trace(fi); -} - -/* we have received the ID RESPONSE (IMEI) */ -static void proc_arq_vlr_fn_w_imei(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - OSMO_ASSERT(event == PR_ARQ_E_IMEI_RES); - - _proc_arq_vlr_post_imei(fi); -} - -/* MSC tells us that MS has acknowleded TMSI re-allocation */ -static void proc_arq_vlr_fn_w_tmsi(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - OSMO_ASSERT(event == PR_ARQ_E_TMSI_ACK); - - /* FIXME: check confirmation? unfreeze? */ - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_PASSED); -} - -static const struct osmo_fsm_state proc_arq_vlr_states[] = { - [PR_ARQ_S_INIT] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_INIT), - .in_event_mask = S(PR_ARQ_E_START), - .out_state_mask = S(PR_ARQ_S_DONE) | - S(PR_ARQ_S_WAIT_OBTAIN_IMSI) | - S(PR_ARQ_S_WAIT_AUTH) | - S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) | - S(PR_ARQ_S_WAIT_SUB_PRES) | - S(PR_ARQ_S_WAIT_TRACE_SUB) | - S(PR_ARQ_S_WAIT_CHECK_IMEI) | - S(PR_ARQ_S_WAIT_TMSI_ACK), - .action = proc_arq_vlr_fn_init, - }, - [PR_ARQ_S_WAIT_OBTAIN_IMSI] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_OBTAIN_IMSI), - .in_event_mask = S(PR_ARQ_E_ID_IMSI), - .out_state_mask = S(PR_ARQ_S_DONE) | - S(PR_ARQ_S_WAIT_AUTH) | - S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) | - S(PR_ARQ_S_WAIT_SUB_PRES) | - S(PR_ARQ_S_WAIT_TRACE_SUB) | - S(PR_ARQ_S_WAIT_CHECK_IMEI) | - S(PR_ARQ_S_WAIT_TMSI_ACK), - .action = proc_arq_vlr_fn_w_obt_imsi, - }, - [PR_ARQ_S_WAIT_AUTH] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_AUTH), - .in_event_mask = S(PR_ARQ_E_AUTH_RES), - .out_state_mask = S(PR_ARQ_S_DONE) | - S(PR_ARQ_S_WAIT_CIPH) | - S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) | - S(PR_ARQ_S_WAIT_SUB_PRES) | - S(PR_ARQ_S_WAIT_TRACE_SUB) | - S(PR_ARQ_S_WAIT_CHECK_IMEI) | - S(PR_ARQ_S_WAIT_TMSI_ACK), - .action = proc_arq_vlr_fn_w_auth, - }, - [PR_ARQ_S_WAIT_CIPH] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_CIPH), - .in_event_mask = S(PR_ARQ_E_CIPH_RES), - .out_state_mask = S(PR_ARQ_S_DONE) | - S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) | - S(PR_ARQ_S_WAIT_SUB_PRES) | - S(PR_ARQ_S_WAIT_TRACE_SUB) | - S(PR_ARQ_S_WAIT_CHECK_IMEI) | - S(PR_ARQ_S_WAIT_TMSI_ACK), - .action = proc_arq_vlr_fn_w_ciph, - }, - [PR_ARQ_S_WAIT_UPD_LOC_CHILD] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_UPD_LOC_CHILD), - .in_event_mask = S(PR_ARQ_E_UPD_LOC_RES), - .out_state_mask = S(PR_ARQ_S_DONE) | - S(PR_ARQ_S_WAIT_SUB_PRES) | - S(PR_ARQ_S_WAIT_TRACE_SUB) | - S(PR_ARQ_S_WAIT_CHECK_IMEI) | - S(PR_ARQ_S_WAIT_TMSI_ACK), - .action = proc_arq_vlr_fn_w_upd_loc, - }, - [PR_ARQ_S_WAIT_SUB_PRES] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_SUB_PRES), - .in_event_mask = S(PR_ARQ_E_PRES_RES), - .out_state_mask = S(PR_ARQ_S_DONE) | - S(PR_ARQ_S_WAIT_TRACE_SUB) | - S(PR_ARQ_S_WAIT_CHECK_IMEI) | - S(PR_ARQ_S_WAIT_TMSI_ACK), - .action = proc_arq_vlr_fn_w_pres, - }, - [PR_ARQ_S_WAIT_TRACE_SUB] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_TRACE_SUB), - .in_event_mask = S(PR_ARQ_E_TRACE_RES), - .out_state_mask = S(PR_ARQ_S_DONE) | - S(PR_ARQ_S_WAIT_CHECK_IMEI) | - S(PR_ARQ_S_WAIT_TMSI_ACK), - .action = proc_arq_vlr_fn_w_trace, - }, - [PR_ARQ_S_WAIT_CHECK_IMEI] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_CHECK_IMEI), - .in_event_mask = S(PR_ARQ_E_IMEI_RES), - .out_state_mask = S(PR_ARQ_S_DONE) | - S(PR_ARQ_S_WAIT_TMSI_ACK), - .action = proc_arq_vlr_fn_w_imei, - }, - [PR_ARQ_S_WAIT_TMSI_ACK] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_TMSI_ACK), - .in_event_mask = S(PR_ARQ_E_TMSI_ACK), - .out_state_mask = S(PR_ARQ_S_DONE), - .action = proc_arq_vlr_fn_w_tmsi, - }, - [PR_ARQ_S_DONE] = { - .name = OSMO_STRINGIFY(PR_ARQ_S_DONE), - .onenter = proc_arq_vlr_dispatch_result, - }, -}; - -static struct osmo_fsm proc_arq_vlr_fsm = { - .name = "Process_Access_Request_VLR", - .states = proc_arq_vlr_states, - .num_states = ARRAY_SIZE(proc_arq_vlr_states), - .allstate_event_mask = 0, - .allstate_action = NULL, - .log_subsys = DVLR, - .event_names = proc_arq_vlr_event_names, - .cleanup = proc_arq_vlr_cleanup, -}; - -void -vlr_proc_acc_req(struct osmo_fsm_inst *parent, - uint32_t parent_event_success, - uint32_t parent_event_failure, - void *parent_event_data, - struct vlr_instance *vlr, void *msc_conn_ref, - enum vlr_parq_type type, const uint8_t *mi_lv, - const struct osmo_location_area_id *lai, - bool authentication_required, - enum vlr_ciph ciphering_required, - bool is_r99, bool is_utran) -{ - struct osmo_fsm_inst *fi; - struct proc_arq_priv *par; - char mi_string[GSM48_MI_SIZE]; - uint8_t mi_type; - - fi = osmo_fsm_inst_alloc_child(&proc_arq_vlr_fsm, parent, - parent_event_failure); - if (!fi) - return; - - par = talloc_zero(fi, struct proc_arq_priv); - fi->priv = par; - par->vlr = vlr; - par->msc_conn_ref = msc_conn_ref; - par->type = type; - par->lai = *lai; - par->parent_event_success = parent_event_success; - par->parent_event_failure = parent_event_failure; - par->parent_event_data = parent_event_data; - par->authentication_required = authentication_required; - par->ciphering_required = ciphering_required; - par->is_r99 = is_r99; - par->is_utran = is_utran; - - LOGPFSM(fi, "rev=%s net=%s%s%s\n", - is_r99 ? "R99" : "GSM", - is_utran ? "UTRAN" : "GERAN", - (authentication_required || ciphering_required)? - " Auth" : " (no Auth)", - (authentication_required || ciphering_required)? - (ciphering_required? "+Ciph" : " (no Ciph)") - : ""); - - if (is_utran && !authentication_required) - LOGPFSML(fi, LOGL_ERROR, - "Authentication off on UTRAN network. Good luck.\n"); - - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, mi_lv[0]); - mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; - switch (mi_type) { - case GSM_MI_TYPE_IMSI: - strncpy(par->imsi, mi_string, sizeof(par->imsi)-1); - par->imsi[sizeof(par->imsi)-1] = '\0'; - par->by_tmsi = false; - break; - case GSM_MI_TYPE_TMSI: - par->by_tmsi = true; - par->tmsi = osmo_load32be(mi_lv+2); - break; - case GSM_MI_TYPE_IMEI: - /* TODO: IMEI (emergency call) */ - default: - /* FIXME: directly send reject? */ - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_UNIDENT_SUBSCR); - return; - } - - osmo_fsm_inst_dispatch(fi, PR_ARQ_E_START, NULL); -} - -/* Gracefully terminate an FSM created by vlr_proc_acc_req() in case of - * external timeout (i.e. from MSC). */ -void vlr_parq_conn_timeout(struct osmo_fsm_inst *fi) -{ - if (!fi || fi->state == PR_ARQ_S_DONE) - return; - LOGPFSM(fi, "Connection timed out\n"); - proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_TIMEOUT); -} - - -#if 0 -/*********************************************************************** - * Update_Location_Child_VLR, TS 29.002 Chapter 25.4.4 - ***********************************************************************/ - -enum upd_loc_child_vlr_state { - ULC_S_IDLE, - ULC_S_WAIT_HLR_RESP, - ULC_S_DONE, -}; - -enum upd_loc_child_vlr_event { - ULC_E_START, -}; - -static const struct value_string upd_loc_child_vlr_event_names[] = { - { ULC_E_START, "START" }, - { 0, NULL } -}; - -static void upd_loc_child_f_idle(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - OSMO_ASSERT(event == ULC_E_START); - - /* send update location */ -} - -static void upd_loc_child_f_w_hlr(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ -} - -static const struct osmo_fsm_state upd_loc_child_vlr_states[] = { - [ULC_S_IDLE] = { - .in_event_mask = , - .out_state_mask = S(ULC_S_WAIT_HLR_RESP) | - S(ULC_S_DONE), - .name = "IDLE", - .action = upd_loc_child_f_idle, - }, - [ULC_S_WAIT_HLR_RESP] = { - .in_event_mask = , - .out_state_mask = S(ULC_S_DONE), - .name = "WAIT-HLR-RESP", - .action = upd_loc_child_f_w_hlr, - }, - [ULC_S_DONE] = { - .name = "DONE", - }, -}; - -static struct osmo_fsm upd_loc_child_vlr_fsm = { - .name = "Update_Location_Child_VLR", - .states = upd_loc_child_vlr_states, - .num_states = ARRAY_SIZE(upd_loc_child_vlr_states), - .log_subsys = DVLR, - .event_names = upd_loc_child_vlr_event_names, -}; -#endif - -void vlr_parq_fsm_init(void) -{ - //osmo_fsm_register(&upd_loc_child_vlr_fsm); - osmo_fsm_register(&proc_arq_vlr_fsm); -} diff --git a/src/libvlr/vlr_access_req_fsm.h b/src/libvlr/vlr_access_req_fsm.h deleted file mode 100644 index 8386da6f2..000000000 --- a/src/libvlr/vlr_access_req_fsm.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -enum proc_arq_vlr_state { - PR_ARQ_S_INIT, - /* Waiting for Obtain_Identity_VLR (IMSI) result */ - PR_ARQ_S_WAIT_OBTAIN_IMSI, - /* Waiting for Authenticate_VLR result */ - PR_ARQ_S_WAIT_AUTH, - PR_ARQ_S_WAIT_CIPH, - PR_ARQ_S_WAIT_UPD_LOC_CHILD, - PR_ARQ_S_WAIT_SUB_PRES, - PR_ARQ_S_WAIT_TRACE_SUB, - PR_ARQ_S_WAIT_CHECK_IMEI, - PR_ARQ_S_WAIT_TMSI_ACK, - PR_ARQ_S_WAIT_CECK_CONF, - PR_ARQ_S_DONE, -}; diff --git a/src/libvlr/vlr_auth_fsm.c b/src/libvlr/vlr_auth_fsm.c deleted file mode 100644 index 0eb86e749..000000000 --- a/src/libvlr/vlr_auth_fsm.c +++ /dev/null @@ -1,605 +0,0 @@ -/* Osmocom Visitor Location Register (VLR) Autentication FSM */ - -/* (C) 2016 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - - -#include -#include -#include -#include -#include - -#include "vlr_core.h" -#include "vlr_auth_fsm.h" - -#define S(x) (1 << (x)) - -static const struct value_string fsm_auth_event_names[] = { - OSMO_VALUE_STRING(VLR_AUTH_E_START), - OSMO_VALUE_STRING(VLR_AUTH_E_HLR_SAI_ACK), - OSMO_VALUE_STRING(VLR_AUTH_E_HLR_SAI_NACK), - OSMO_VALUE_STRING(VLR_AUTH_E_HLR_SAI_ABORT), - OSMO_VALUE_STRING(VLR_AUTH_E_MS_AUTH_RESP), - OSMO_VALUE_STRING(VLR_AUTH_E_MS_AUTH_FAIL), - OSMO_VALUE_STRING(VLR_AUTH_E_MS_ID_IMSI), - { 0, NULL } -}; - -const struct value_string vlr_auth_fsm_result_names[] = { - OSMO_VALUE_STRING(VLR_AUTH_RES_ABORTED), - OSMO_VALUE_STRING(VLR_AUTH_RES_UNKNOWN_SUBSCR), - OSMO_VALUE_STRING(VLR_AUTH_RES_PROC_ERR), - OSMO_VALUE_STRING(VLR_AUTH_RES_AUTH_FAILED), - OSMO_VALUE_STRING(VLR_AUTH_RES_PASSED), - {0, NULL} -}; - -/* private state of the auth_fsm_instance */ -struct auth_fsm_priv { - struct vlr_subscr *vsub; - bool by_imsi; - bool is_r99; - bool is_utran; - bool auth_requested; - - int auth_tuple_max_use_count; /* see vlr->cfg instead */ -}; - -/*********************************************************************** - * Utility functions - ***********************************************************************/ - -/* Always use either vlr_subscr_get_auth_tuple() or vlr_subscr_has_auth_tuple() - * instead, to ensure proper use count. - * Return an auth tuple with the lowest use_count among the auth tuples. If - * max_use_count >= 0, return NULL if all available auth tuples have a use - * count > max_use_count. If max_use_count is negative, return a currently - * least used auth tuple without enforcing a maximum use count. If there are - * no auth tuples, return NULL. - */ -static struct gsm_auth_tuple * -_vlr_subscr_next_auth_tuple(struct vlr_subscr *vsub, int max_use_count) -{ - unsigned int count; - unsigned int idx; - struct gsm_auth_tuple *at = NULL; - unsigned int key_seq = GSM_KEY_SEQ_INVAL; - - if (!vsub) - return NULL; - - if (vsub->last_tuple) - key_seq = vsub->last_tuple->key_seq; - - if (key_seq == GSM_KEY_SEQ_INVAL) - /* Start with 0 after increment modulo array size */ - idx = ARRAY_SIZE(vsub->auth_tuples) - 1; - else - idx = key_seq; - - for (count = ARRAY_SIZE(vsub->auth_tuples); count > 0; count--) { - idx = (idx + 1) % ARRAY_SIZE(vsub->auth_tuples); - - if (vsub->auth_tuples[idx].key_seq == GSM_KEY_SEQ_INVAL) - continue; - - if (!at || vsub->auth_tuples[idx].use_count < at->use_count) - at = &vsub->auth_tuples[idx]; - } - - if (!at || (max_use_count >= 0 && at->use_count > max_use_count)) - return NULL; - - return at; -} - -/* Return an auth tuple and increment its use count. */ -static struct gsm_auth_tuple * -vlr_subscr_get_auth_tuple(struct vlr_subscr *vsub, int max_use_count) -{ - struct gsm_auth_tuple *at = _vlr_subscr_next_auth_tuple(vsub, - max_use_count); - if (!at) - return NULL; - at->use_count++; - return at; -} - -/* Return whether an auth tuple with the given max_use_count is available. */ -static bool vlr_subscr_has_auth_tuple(struct vlr_subscr *vsub, - int max_use_count) -{ - return _vlr_subscr_next_auth_tuple(vsub, max_use_count) != NULL; -} - -static bool check_auth_resp(struct vlr_subscr *vsub, bool is_r99, - bool is_utran, const uint8_t *res, - uint8_t res_len) -{ - struct gsm_auth_tuple *at = vsub->last_tuple; - struct osmo_auth_vector *vec = &at->vec; - bool check_umts; - OSMO_ASSERT(at); - - LOGVSUBP(LOGL_DEBUG, vsub, "received res: %s\n", - osmo_hexdump(res, res_len)); - - /* RES must be present and at least 32bit */ - if (!res || res_len < sizeof(vec->sres)) { - LOGVSUBP(LOGL_NOTICE, vsub, "AUTH RES missing or too short " - "(%u)\n", res_len); - goto out_false; - } - - check_umts = false; - if (is_r99 && (vec->auth_types & OSMO_AUTH_TYPE_UMTS)) { - check_umts = true; - /* We have a R99 capable UE and have a UMTS AKA capable USIM. - * However, the ME may still choose to only perform GSM AKA, as - * long as the bearer is GERAN */ - if (res_len != vec->res_len) { - if (is_utran) { - LOGVSUBP(LOGL_NOTICE, vsub, - "AUTH via UTRAN but " - "res_len(%u) != vec->res_len(%u)\n", - res_len, vec->res_len); - goto out_false; - } - check_umts = false; - } - } - - if (check_umts) { - if (res_len != vec->res_len - || memcmp(res, vec->res, res_len)) { - LOGVSUBP(LOGL_INFO, vsub, "UMTS AUTH failure:" - " mismatching res (expected res=%s)\n", - osmo_hexdump(vec->res, vec->res_len)); - goto out_false; - } - - LOGVSUBP(LOGL_INFO, vsub, "AUTH established UMTS security" - " context\n"); - vsub->sec_ctx = VLR_SEC_CTX_UMTS; - return true; - } else { - if (res_len != sizeof(vec->sres) - || memcmp(res, vec->sres, sizeof(vec->sres))) { - LOGVSUBP(LOGL_INFO, vsub, "GSM AUTH failure:" - " mismatching sres (expected sres=%s)\n", - osmo_hexdump(vec->sres, sizeof(vec->sres))); - goto out_false; - } - - LOGVSUBP(LOGL_INFO, vsub, "AUTH established GSM security" - " context\n"); - vsub->sec_ctx = VLR_SEC_CTX_GSM; - return true; - } - -out_false: - vsub->sec_ctx = VLR_SEC_CTX_NONE; - return false; -} - -static void auth_fsm_onenter_failed(struct osmo_fsm_inst *fi, uint32_t prev_state) -{ - struct auth_fsm_priv *afp = fi->priv; - struct vlr_subscr *vsub = afp->vsub; - - /* If authentication hasn't even started, e.g. the HLR sent no auth - * info, then we also don't need to tell the HLR about an auth failure. - */ - if (afp->auth_requested) - vlr_subscr_tx_auth_fail_rep(vsub); -} - -static bool is_umts_auth(struct auth_fsm_priv *afp, - uint32_t auth_types) -{ - if (!afp->is_r99) - return false; - if (!(auth_types & OSMO_AUTH_TYPE_UMTS)) - return false; - return true; -} - -/* Terminate the Auth FSM Instance and notify parent */ -static void auth_fsm_term(struct osmo_fsm_inst *fi, enum vlr_auth_fsm_result res) -{ - struct auth_fsm_priv *afp = fi->priv; - struct vlr_subscr *vsub = afp->vsub; - - LOGPFSM(fi, "Authentication terminating with result %s\n", - vlr_auth_fsm_result_name(res)); - - /* Do one final state transition (mostly for logging purpose) */ - if (res == VLR_AUTH_RES_PASSED) - osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTHENTICATED, 0, 0); - else - osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTH_FAILED, 0, 0); - - /* return the result to the parent FSM */ - osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, &res); - vsub->auth_fsm = NULL; -} - -/* back-end function transmitting authentication. Caller ensures we have valid - * tuple */ -static int _vlr_subscr_authenticate(struct osmo_fsm_inst *fi) -{ - struct auth_fsm_priv *afp = fi->priv; - struct vlr_subscr *vsub = afp->vsub; - struct gsm_auth_tuple *at; - - /* Caller ensures we have vectors available */ - at = vlr_subscr_get_auth_tuple(vsub, afp->auth_tuple_max_use_count); - if (!at) { - LOGPFSML(fi, LOGL_ERROR, "A previous check ensured that an" - " auth tuple was available, but now there is in fact" - " none.\n"); - auth_fsm_term(fi, VLR_AUTH_RES_PROC_ERR); - return -1; - } - - LOGPFSM(fi, "got auth tuple: use_count=%d key_seq=%d\n", - at->use_count, at->key_seq); - - OSMO_ASSERT(at); - - /* Transmit auth req to subscriber */ - afp->auth_requested = true; - vsub->last_tuple = at; - vsub->vlr->ops.tx_auth_req(vsub->msc_conn_ref, at, - is_umts_auth(afp, at->vec.auth_types)); - return 0; -} - -/*********************************************************************** - * FSM State Action functions - ***********************************************************************/ - -/* Initial State of TS 23.018 AUT_VLR */ -static void auth_fsm_needs_auth(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct auth_fsm_priv *afp = fi->priv; - struct vlr_subscr *vsub = afp->vsub; - - OSMO_ASSERT(event == VLR_AUTH_E_START); - - /* Start off with the default max_use_count, possibly change that if we - * need to re-use an old tuple. */ - afp->auth_tuple_max_use_count = vsub->vlr->cfg.auth_tuple_max_use_count; - - /* Check if we have vectors available */ - if (!vlr_subscr_has_auth_tuple(vsub, afp->auth_tuple_max_use_count)) { - /* Obtain_Authentication_Sets_VLR */ - vlr_subscr_req_sai(vsub, NULL, NULL); - osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_NEEDS_AUTH_WAIT_AI, - GSM_29002_TIMER_M, 0); - } else { - /* go straight ahead with sending auth request */ - osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP, - vlr_timer(vsub->vlr, 3260), 3260); - _vlr_subscr_authenticate(fi); - } -} - -/* Waiting for Authentication Info from HLR */ -static void auth_fsm_wait_ai(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct auth_fsm_priv *afp = fi->priv; - struct vlr_subscr *vsub = afp->vsub; - struct osmo_gsup_message *gsup = data; - - if (event == VLR_AUTH_E_HLR_SAI_NACK) - LOGPFSM(fi, "GSUP: rx Auth Info Error cause: %d: %s\n", - gsup->cause, - get_value_string(gsm48_gmm_cause_names, gsup->cause)); - - /* We are in what corresponds to the - * Wait_For_Authentication_Sets state of TS 23.018 OAS_VLR */ - if ((event == VLR_AUTH_E_HLR_SAI_ACK && !gsup->num_auth_vectors) - || (event == VLR_AUTH_E_HLR_SAI_NACK && - gsup->cause != GMM_CAUSE_IMSI_UNKNOWN) - || (event == VLR_AUTH_E_HLR_SAI_ABORT)) { - if (vsub->vlr->cfg.auth_reuse_old_sets_on_error - && vlr_subscr_has_auth_tuple(vsub, -1)) { - /* To re-use an old tuple, disable the max_use_count - * constraint. */ - afp->auth_tuple_max_use_count = -1; - goto pass; - } - /* result = procedure error */ - auth_fsm_term(fi, VLR_AUTH_RES_PROC_ERR); - return; - } - - switch (event) { - case VLR_AUTH_E_HLR_SAI_ACK: - vlr_subscr_update_tuples(vsub, gsup); - goto pass; - break; - case VLR_AUTH_E_HLR_SAI_NACK: - auth_fsm_term(fi, - gsup->cause == GMM_CAUSE_IMSI_UNKNOWN? - VLR_AUTH_RES_UNKNOWN_SUBSCR - : VLR_AUTH_RES_PROC_ERR); - break; - } - - return; -pass: - osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP, - vlr_timer(vsub->vlr, 3260), 3260); - _vlr_subscr_authenticate(fi); -} - -/* Waiting for Authentication Response from MS */ -static void auth_fsm_wait_auth_resp(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct auth_fsm_priv *afp = fi->priv; - struct vlr_subscr *vsub = afp->vsub; - struct vlr_instance *vlr = vsub->vlr; - struct vlr_auth_resp_par *par = data; - int rc; - - switch (event) { - case VLR_AUTH_E_MS_AUTH_RESP: - rc = check_auth_resp(vsub, par->is_r99, par->is_utran, - par->res, par->res_len); - if (rc == false) { - if (!afp->by_imsi) { - vlr->ops.tx_id_req(vsub->msc_conn_ref, - GSM_MI_TYPE_IMSI); - osmo_fsm_inst_state_chg(fi, - VLR_SUB_AS_WAIT_ID_IMSI, - vlr_timer(vlr, 3270), 3270); - } else { - auth_fsm_term(fi, VLR_AUTH_RES_AUTH_FAILED); - } - } else { - auth_fsm_term(fi, VLR_AUTH_RES_PASSED); - } - break; - case VLR_AUTH_E_MS_AUTH_FAIL: - if (par->auts) { - /* First failure, start re-sync attempt */ - vlr_subscr_req_sai(vsub, par->auts, - vsub->last_tuple->vec.rand); - osmo_fsm_inst_state_chg(fi, - VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC, - GSM_29002_TIMER_M, 0); - } else - auth_fsm_term(fi, VLR_AUTH_RES_AUTH_FAILED); - break; - } -} - -/* Waiting for Authentication Info from HLR (resync case) */ -static void auth_fsm_wait_ai_resync(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - struct auth_fsm_priv *afp = fi->priv; - struct vlr_subscr *vsub = afp->vsub; - struct osmo_gsup_message *gsup = data; - - /* We are in what corresponds to the - * Wait_For_Authentication_Sets state of TS 23.018 OAS_VLR */ - if ((event == VLR_AUTH_E_HLR_SAI_ACK && !gsup->num_auth_vectors) || - (event == VLR_AUTH_E_HLR_SAI_NACK && - gsup->cause != GMM_CAUSE_IMSI_UNKNOWN) || - (event == VLR_AUTH_E_HLR_SAI_ABORT)) { - /* result = procedure error */ - auth_fsm_term(fi, VLR_AUTH_RES_PROC_ERR); - } - switch (event) { - case VLR_AUTH_E_HLR_SAI_ACK: - vlr_subscr_update_tuples(vsub, gsup); - goto pass; - break; - case VLR_AUTH_E_HLR_SAI_NACK: - auth_fsm_term(fi, - gsup->cause == GMM_CAUSE_IMSI_UNKNOWN? - VLR_AUTH_RES_UNKNOWN_SUBSCR - : VLR_AUTH_RES_PROC_ERR); - break; - } - - return; -pass: - osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP_RESYNC, - vlr_timer(vsub->vlr, 3260), 3260); - _vlr_subscr_authenticate(fi); -} - -/* Waiting for AUTH RESP from MS (re-sync case) */ -static void auth_fsm_wait_auth_resp_resync(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - struct auth_fsm_priv *afp = fi->priv; - struct vlr_subscr *vsub = afp->vsub; - struct vlr_auth_resp_par *par = data; - struct vlr_instance *vlr = vsub->vlr; - int rc; - - switch (event) { - case VLR_AUTH_E_MS_AUTH_RESP: - rc = check_auth_resp(vsub, par->is_r99, par->is_utran, - par->res, par->res_len); - if (rc == false) { - if (!afp->by_imsi) { - vlr->ops.tx_id_req(vsub->msc_conn_ref, - GSM_MI_TYPE_IMSI); - osmo_fsm_inst_state_chg(fi, - VLR_SUB_AS_WAIT_ID_IMSI, - vlr_timer(vlr, 3270), 3270); - } else { - /* Result = Aborted */ - auth_fsm_term(fi, VLR_AUTH_RES_ABORTED); - } - } else { - /* Result = Pass */ - auth_fsm_term(fi, VLR_AUTH_RES_PASSED); - } - break; - case VLR_AUTH_E_MS_AUTH_FAIL: - /* Second failure: Result = Fail */ - auth_fsm_term(fi, VLR_AUTH_RES_AUTH_FAILED); - break; - } -} - -/* AUT_VLR waiting for Obtain_IMSI_VLR result */ -static void auth_fsm_wait_imsi(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct auth_fsm_priv *afp = fi->priv; - struct vlr_subscr *vsub = afp->vsub; - const char *mi_string = data; - - switch (event) { - case VLR_AUTH_E_MS_ID_IMSI: - if (vsub->imsi[0] - && !vlr_subscr_matches_imsi(vsub, mi_string)) { - LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP differs:" - " %s\n", mi_string); - } else { - strncpy(vsub->imsi, mi_string, sizeof(vsub->imsi)); - vsub->imsi[sizeof(vsub->imsi)-1] = '\0'; - } - /* retry with identity=IMSI */ - afp->by_imsi = true; - osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_NEEDS_AUTH, 0, 0); - osmo_fsm_inst_dispatch(fi, VLR_AUTH_E_START, NULL); - break; - } -} - -static const struct osmo_fsm_state auth_fsm_states[] = { - [VLR_SUB_AS_NEEDS_AUTH] = { - .name = OSMO_STRINGIFY(VLR_SUB_AS_NEEDS_AUTH), - .in_event_mask = S(VLR_AUTH_E_START), - .out_state_mask = S(VLR_SUB_AS_NEEDS_AUTH_WAIT_AI) | - S(VLR_SUB_AS_WAIT_RESP), - .action = auth_fsm_needs_auth, - }, - [VLR_SUB_AS_NEEDS_AUTH_WAIT_AI] = { - .name = OSMO_STRINGIFY(VLR_SUB_AS_NEEDS_AUTH_WAIT_AI), - .in_event_mask = S(VLR_AUTH_E_HLR_SAI_ACK) | - S(VLR_AUTH_E_HLR_SAI_NACK), - .out_state_mask = S(VLR_SUB_AS_AUTH_FAILED) | - S(VLR_SUB_AS_WAIT_RESP), - .action = auth_fsm_wait_ai, - }, - [VLR_SUB_AS_WAIT_RESP] = { - .name = OSMO_STRINGIFY(VLR_SUB_AS_WAIT_RESP), - .in_event_mask = S(VLR_AUTH_E_MS_AUTH_RESP) | - S(VLR_AUTH_E_MS_AUTH_FAIL), - .out_state_mask = S(VLR_SUB_AS_WAIT_ID_IMSI) | - S(VLR_SUB_AS_AUTH_FAILED) | - S(VLR_SUB_AS_AUTHENTICATED) | - S(VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC), - .action = auth_fsm_wait_auth_resp, - }, - [VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC] = { - .name = OSMO_STRINGIFY(VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC), - .in_event_mask = S(VLR_AUTH_E_HLR_SAI_ACK) | - S(VLR_AUTH_E_HLR_SAI_NACK), - .out_state_mask = S(VLR_SUB_AS_AUTH_FAILED) | - S(VLR_SUB_AS_WAIT_RESP_RESYNC), - .action = auth_fsm_wait_ai_resync, - }, - [VLR_SUB_AS_WAIT_RESP_RESYNC] = { - .name = OSMO_STRINGIFY(VLR_SUB_AS_WAIT_RESP_RESYNC), - .in_event_mask = S(VLR_AUTH_E_MS_AUTH_RESP) | - S(VLR_AUTH_E_MS_AUTH_FAIL), - .out_state_mask = S(VLR_SUB_AS_AUTH_FAILED) | - S(VLR_SUB_AS_AUTHENTICATED), - .action = auth_fsm_wait_auth_resp_resync, - }, - [VLR_SUB_AS_WAIT_ID_IMSI] = { - .name = OSMO_STRINGIFY(VLR_SUB_AS_WAIT_ID_IMSI), - .in_event_mask = S(VLR_AUTH_E_MS_ID_IMSI), - .out_state_mask = S(VLR_SUB_AS_NEEDS_AUTH), - .action = auth_fsm_wait_imsi, - }, - [VLR_SUB_AS_AUTHENTICATED] = { - .name = OSMO_STRINGIFY(VLR_SUB_AS_AUTHENTICATED), - .in_event_mask = 0, - .out_state_mask = 0, - }, - [VLR_SUB_AS_AUTH_FAILED] = { - .name = OSMO_STRINGIFY(VLR_SUB_AS_AUTH_FAILED), - .in_event_mask = 0, - .out_state_mask = 0, - .onenter = auth_fsm_onenter_failed, - }, -}; - -struct osmo_fsm vlr_auth_fsm = { - .name = "VLR_Authenticate", - .states = auth_fsm_states, - .num_states = ARRAY_SIZE(auth_fsm_states), - .allstate_event_mask = 0, - .allstate_action = NULL, - .log_subsys = DVLR, - .event_names = fsm_auth_event_names, -}; - -/*********************************************************************** - * User API (for SGSN/MSC code) - ***********************************************************************/ - -/* MSC->VLR: Start Procedure Authenticate_VLR (TS 23.012 Ch. 4.1.2.2) */ -struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub, - uint32_t log_level, - struct osmo_fsm_inst *parent, - uint32_t parent_term_event, - bool is_r99, - bool is_utran) -{ - struct osmo_fsm_inst *fi; - struct auth_fsm_priv *afp; - - fi = osmo_fsm_inst_alloc_child(&vlr_auth_fsm, parent, - parent_term_event); - - - afp = talloc_zero(fi, struct auth_fsm_priv); - if (!afp) { - osmo_fsm_inst_dispatch(parent, parent_term_event, 0); - return NULL; - } - - afp->vsub = vsub; - if (vsub->imsi[0]) - afp->by_imsi = true; - afp->is_r99 = is_r99; - afp->is_utran = is_utran; - fi->priv = afp; - vsub->auth_fsm = fi; - - osmo_fsm_inst_dispatch(fi, VLR_AUTH_E_START, NULL); - - return fi; -} diff --git a/src/libvlr/vlr_auth_fsm.h b/src/libvlr/vlr_auth_fsm.h deleted file mode 100644 index 226435f83..000000000 --- a/src/libvlr/vlr_auth_fsm.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include - -/* Parameters to VLR_AUTH_E_MS_AUTH_RESP */ -struct vlr_auth_resp_par { - bool is_r99; - bool is_utran; - const uint8_t *res; - unsigned int res_len; - const uint8_t *auts; -}; - -/* Result communicated back to parent FMS */ -enum vlr_auth_fsm_result { - VLR_AUTH_RES_ABORTED, - VLR_AUTH_RES_UNKNOWN_SUBSCR, - VLR_AUTH_RES_PROC_ERR, - VLR_AUTH_RES_AUTH_FAILED, - VLR_AUTH_RES_PASSED, -}; - -extern const struct value_string vlr_auth_fsm_result_names[]; -static inline const char *vlr_auth_fsm_result_name(enum vlr_auth_fsm_result val) -{ - return get_value_string(vlr_auth_fsm_result_names, val); -} - -enum vlr_fsm_auth_event { - VLR_AUTH_E_START, - /* TS 23.018 OAS_VLR1(2): SendAuthInfo ACK from HLR */ - VLR_AUTH_E_HLR_SAI_ACK, - /* TS 23.018 OAS_VLR1(2): SendAuthInfo NACK from HLR */ - VLR_AUTH_E_HLR_SAI_NACK, - /* FIXME: merge with NACK? */ - VLR_AUTH_E_HLR_SAI_ABORT, - /* Authentication Response from MS */ - VLR_AUTH_E_MS_AUTH_RESP, - /* Authentication Failure from MS */ - VLR_AUTH_E_MS_AUTH_FAIL, - /* Identity Response (IMSI) from MS */ - VLR_AUTH_E_MS_ID_IMSI, -}; - -struct osmo_fsm vlr_auth_fsm; - -struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub, - uint32_t log_level, - struct osmo_fsm_inst *parent, - uint32_t parent_term_event, - bool is_r99, - bool is_utran); diff --git a/src/libvlr/vlr_core.h b/src/libvlr/vlr_core.h deleted file mode 100644 index 0e63c7e69..000000000 --- a/src/libvlr/vlr_core.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#define LOGGSUPP(level, gsup, fmt, args...) \ - LOGP(DVLR, level, "GSUP(%s) " fmt, \ - (gsup)->imsi, \ - ## args) - -#define LOGVSUBP(level, vsub, fmt, args...) \ - LOGP(DVLR, level, "SUBSCR(%s) " fmt, \ - vlr_subscr_name(vsub), ## args) - - -const char *vlr_subscr_name(struct vlr_subscr *vsub); -int vlr_subscr_req_lu(struct vlr_subscr *vsub, bool is_ps); -int vlr_subscr_req_sai(struct vlr_subscr *vsub, const uint8_t *auts, - const uint8_t *auts_rand); -struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr); -void vlr_subscr_update_tuples(struct vlr_subscr *vsub, - const struct osmo_gsup_message *gsup); diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c deleted file mode 100644 index 94bea560f..000000000 --- a/src/libvlr/vlr_lu_fsm.c +++ /dev/null @@ -1,1449 +0,0 @@ -/* Osmocom Visitor Location Register (VLR): Location Update FSMs */ - -/* (C) 2016 by Harald Welte - * - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include - -#include "vlr_core.h" -#include "vlr_auth_fsm.h" -#include "vlr_lu_fsm.h" - -#define S(x) (1 << (x)) - -#define LU_TIMEOUT_LONG 30 - -enum vlr_fsm_result { - VLR_FSM_RESULT_NONE, - VLR_FSM_RESULT_SUCCESS, - VLR_FSM_RESULT_FAILURE, -}; - - -/*********************************************************************** - * Update_HLR_VLR, TS 23.012 Chapter 4.1.2.4 - ***********************************************************************/ - -enum upd_hlr_vlr_state { - UPD_HLR_VLR_S_INIT, - UPD_HLR_VLR_S_WAIT_FOR_DATA, - UPD_HLR_VLR_S_DONE, -}; - -enum upd_hlr_vlr_evt { - UPD_HLR_VLR_E_START, - UPD_HLR_VLR_E_INS_SUB_DATA, - UPD_HLR_VLR_E_ACT_TRACE_MODE, - UPD_HLR_VLR_E_FW_CHECK_SS_IND, - UPD_HLR_VLR_E_UPD_LOC_ACK, - UPD_HLR_VLR_E_UPD_LOC_NACK, -}; - -static const struct value_string upd_hlr_vlr_event_names[] = { - OSMO_VALUE_STRING(UPD_HLR_VLR_E_START), - OSMO_VALUE_STRING(UPD_HLR_VLR_E_INS_SUB_DATA), - OSMO_VALUE_STRING(UPD_HLR_VLR_E_ACT_TRACE_MODE), - OSMO_VALUE_STRING(UPD_HLR_VLR_E_FW_CHECK_SS_IND), - OSMO_VALUE_STRING(UPD_HLR_VLR_E_UPD_LOC_ACK), - OSMO_VALUE_STRING(UPD_HLR_VLR_E_UPD_LOC_NACK), - { 0, NULL } -}; - -static void upd_hlr_vlr_fsm_init(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct vlr_subscr *vsub = fi->priv; - - OSMO_ASSERT(event == UPD_HLR_VLR_E_START); - - /* Send UpdateLocation to HLR */ - vlr_subscr_req_lu(vsub, vsub->vlr->cfg.is_ps); - osmo_fsm_inst_state_chg(fi, UPD_HLR_VLR_S_WAIT_FOR_DATA, - LU_TIMEOUT_LONG, 0); -} - -static void upd_hlr_vlr_fsm_wait_data(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct vlr_subscr *vsub = fi->priv; - - switch (event) { - case UPD_HLR_VLR_E_INS_SUB_DATA: - /* FIXME: Insert_Subscr_Data_VLR */ - break; - case UPD_HLR_VLR_E_ACT_TRACE_MODE: - /* TODO: Activate_Tracing_VLR */ - break; - case UPD_HLR_VLR_E_FW_CHECK_SS_IND: - /* TODO: Forward Check SS Ind to MSC */ - break; - case UPD_HLR_VLR_E_UPD_LOC_ACK: - /* Inside Update_HLR_VLR after UpdateLocationAck */ - vsub->sub_dataconf_by_hlr_ind = true; - vsub->loc_conf_in_hlr_ind = true; - osmo_fsm_inst_state_chg(fi, UPD_HLR_VLR_S_DONE, 0, 0); - osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL); - break; - case UPD_HLR_VLR_E_UPD_LOC_NACK: - /* Inside Update_HLR_VLR after UpdateLocationNack */ - /* TODO: Check_User_Error_In_Serving_Network_Entity */ - vsub->sub_dataconf_by_hlr_ind = false; - vsub->loc_conf_in_hlr_ind = false; - osmo_fsm_inst_state_chg(fi, UPD_HLR_VLR_S_DONE, 0, 0); - /* Data is a pointer to a gsm48_gmm_cause which we - * simply pass through */ - osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, data); - break; - } -} - -static const struct osmo_fsm_state upd_hlr_vlr_states[] = { - [UPD_HLR_VLR_S_INIT] = { - .in_event_mask = S(UPD_HLR_VLR_E_START), - .out_state_mask = S(UPD_HLR_VLR_S_WAIT_FOR_DATA), - .name = OSMO_STRINGIFY(UPD_HLR_VLR_S_INIT), - .action = upd_hlr_vlr_fsm_init, - }, - [UPD_HLR_VLR_S_WAIT_FOR_DATA] = { - .in_event_mask = S(UPD_HLR_VLR_E_INS_SUB_DATA) | - S(UPD_HLR_VLR_E_ACT_TRACE_MODE) | - S(UPD_HLR_VLR_E_FW_CHECK_SS_IND) | - S(UPD_HLR_VLR_E_UPD_LOC_ACK) | - S(UPD_HLR_VLR_E_UPD_LOC_NACK), - .out_state_mask = S(UPD_HLR_VLR_S_DONE), - .name = OSMO_STRINGIFY(UPD_HLR_VLR_S_WAIT_FOR_DATA), - .action = upd_hlr_vlr_fsm_wait_data, - }, - [UPD_HLR_VLR_S_DONE] = { - .name = OSMO_STRINGIFY(UPD_HLR_VLR_S_DONE), - }, -}; - -static struct osmo_fsm upd_hlr_vlr_fsm = { - .name = "upd_hlr_vlr_fsm", - .states = upd_hlr_vlr_states, - .num_states = ARRAY_SIZE(upd_hlr_vlr_states), - .allstate_event_mask = 0, - .allstate_action = NULL, - .log_subsys = DVLR, - .event_names = upd_hlr_vlr_event_names, -}; - -struct osmo_fsm_inst * -upd_hlr_vlr_proc_start(struct osmo_fsm_inst *parent, - struct vlr_subscr *vsub, - uint32_t parent_event) -{ - struct osmo_fsm_inst *fi; - - fi = osmo_fsm_inst_alloc_child(&upd_hlr_vlr_fsm, parent, - parent_event); - if (!fi) - return NULL; - - fi->priv = vsub; - osmo_fsm_inst_dispatch(fi, UPD_HLR_VLR_E_START, NULL); - - return fi; -} - - -/*********************************************************************** - * Subscriber_Present_VLR, TS 29.002 Chapter 25.10.1 - ***********************************************************************/ - -enum sub_pres_vlr_state { - SUB_PRES_VLR_S_INIT, - SUB_PRES_VLR_S_WAIT_FOR_HLR, - SUB_PRES_VLR_S_DONE, -}; - -enum sub_pres_vlr_event { - SUB_PRES_VLR_E_START, - SUB_PRES_VLR_E_READY_SM_CNF, - SUB_PRES_VLR_E_READY_SM_ERR, -}; - -static const struct value_string sub_pres_vlr_event_names[] = { - OSMO_VALUE_STRING(SUB_PRES_VLR_E_START), - OSMO_VALUE_STRING(SUB_PRES_VLR_E_READY_SM_CNF), - OSMO_VALUE_STRING(SUB_PRES_VLR_E_READY_SM_ERR), - { 0, NULL } -}; - -static void sub_pres_vlr_fsm_init(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct vlr_subscr *vsub = fi->priv; - OSMO_ASSERT(event == SUB_PRES_VLR_E_START); - - if (!vsub->ms_not_reachable_flag) { - osmo_fsm_inst_state_chg(fi, SUB_PRES_VLR_S_DONE, 0, 0); - osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL); - return; - } - /* FIXME: Send READY_FOR_SM via GSUP */ - osmo_fsm_inst_state_chg(fi, SUB_PRES_VLR_S_WAIT_FOR_HLR, - LU_TIMEOUT_LONG, 0); -} - -static void sub_pres_vlr_fsm_wait_hlr(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct vlr_subscr *vsub = fi->priv; - - switch (event) { - case SUB_PRES_VLR_E_READY_SM_CNF: - vsub->ms_not_reachable_flag = false; - break; - case SUB_PRES_VLR_E_READY_SM_ERR: - break; - } - osmo_fsm_inst_state_chg(fi, SUB_PRES_VLR_S_DONE, 0, 0); - osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL); -} - -static const struct osmo_fsm_state sub_pres_vlr_states[] = { - [SUB_PRES_VLR_S_INIT] = { - .in_event_mask = S(SUB_PRES_VLR_E_START), - .out_state_mask = S(SUB_PRES_VLR_S_WAIT_FOR_HLR) | - S(SUB_PRES_VLR_S_DONE), - .name = OSMO_STRINGIFY(SUB_PRES_VLR_S_INIT), - .action = sub_pres_vlr_fsm_init, - }, - [SUB_PRES_VLR_S_WAIT_FOR_HLR] = { - .in_event_mask = S(SUB_PRES_VLR_E_READY_SM_CNF) | - S(SUB_PRES_VLR_E_READY_SM_ERR), - .out_state_mask = S(SUB_PRES_VLR_S_DONE), - .name = OSMO_STRINGIFY(SUB_PRES_VLR_S_WAIT_FOR_HLR), - .action = sub_pres_vlr_fsm_wait_hlr, - }, - [SUB_PRES_VLR_S_DONE] = { - .name = OSMO_STRINGIFY(SUB_PRES_VLR_S_DONE), - }, -}; - -static struct osmo_fsm sub_pres_vlr_fsm = { - .name = "sub_pres_vlr_fsm", - .states = sub_pres_vlr_states, - .num_states = ARRAY_SIZE(sub_pres_vlr_states), - .allstate_event_mask = 0, - .allstate_action = NULL, - .log_subsys = DVLR, - .event_names = sub_pres_vlr_event_names, -}; - -struct osmo_fsm_inst *sub_pres_vlr_fsm_start(struct osmo_fsm_inst *parent, - struct vlr_subscr *vsub, - uint32_t term_event) -{ - struct osmo_fsm_inst *fi; - - fi = osmo_fsm_inst_alloc_child(&sub_pres_vlr_fsm, parent, - term_event); - if (!fi) - return NULL; - - fi->priv = vsub; - osmo_fsm_inst_dispatch(fi, SUB_PRES_VLR_E_START, NULL); - - return fi; -} - -/*********************************************************************** - * Location_Update_Completion_VLR, TS 23.012 Chapter 4.1.2.3 - ***********************************************************************/ - -enum lu_compl_vlr_state { - LU_COMPL_VLR_S_INIT, - LU_COMPL_VLR_S_WAIT_SUB_PRES, - LU_COMPL_VLR_S_WAIT_IMEI, - LU_COMPL_VLR_S_WAIT_IMEI_TMSI, - LU_COMPL_VLR_S_WAIT_TMSI_CNF, - LU_COMPL_VLR_S_DONE, -}; - -enum lu_compl_vlr_event { - LU_COMPL_VLR_E_START, - LU_COMPL_VLR_E_SUB_PRES_COMPL, - LU_COMPL_VLR_E_IMEI_CHECK_ACK, - LU_COMPL_VLR_E_IMEI_CHECK_NACK, - LU_COMPL_VLR_E_NEW_TMSI_ACK, -}; - -static const struct value_string lu_compl_vlr_event_names[] = { - OSMO_VALUE_STRING(LU_COMPL_VLR_E_START), - OSMO_VALUE_STRING(LU_COMPL_VLR_E_SUB_PRES_COMPL), - OSMO_VALUE_STRING(LU_COMPL_VLR_E_IMEI_CHECK_ACK), - OSMO_VALUE_STRING(LU_COMPL_VLR_E_IMEI_CHECK_NACK), - OSMO_VALUE_STRING(LU_COMPL_VLR_E_NEW_TMSI_ACK), - { 0, NULL } -}; - -struct lu_compl_vlr_priv { - struct vlr_subscr *vsub; - void *msc_conn_ref; - struct osmo_fsm_inst *sub_pres_vlr_fsm; - uint32_t parent_event_success; - uint32_t parent_event_failure; - void *parent_event_data; - enum vlr_fsm_result result; - uint8_t cause; - bool assign_tmsi; -}; - -static void _vlr_lu_compl_fsm_done(struct osmo_fsm_inst *fi, - enum vlr_fsm_result result, - uint8_t cause) -{ - struct lu_compl_vlr_priv *lcvp = fi->priv; - lcvp->result = result; - lcvp->cause = cause; - osmo_fsm_inst_state_chg(fi, LU_COMPL_VLR_S_DONE, 0, 0); -} - -static void vlr_lu_compl_fsm_success(struct osmo_fsm_inst *fi) -{ - struct lu_compl_vlr_priv *lcvp = fi->priv; - struct vlr_subscr *vsub = lcvp->vsub; - if (!vsub->lu_complete) { - vsub->lu_complete = true; - /* Balanced by vlr_subscr_rx_imsi_detach() */ - vlr_subscr_get(vsub); - } - _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_SUCCESS, 0); -} - -static void vlr_lu_compl_fsm_failure(struct osmo_fsm_inst *fi, uint8_t cause) -{ - struct lu_compl_vlr_priv *lcvp = fi->priv; - lcvp->vsub->vlr->ops.tx_lu_rej(lcvp->msc_conn_ref, cause); - _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, cause); -} - -static void vlr_lu_compl_fsm_dispatch_result(struct osmo_fsm_inst *fi, - uint32_t prev_state) -{ - struct lu_compl_vlr_priv *lcvp = fi->priv; - if (!fi->proc.parent) { - LOGPFSML(fi, LOGL_ERROR, "No parent FSM\n"); - return; - } - osmo_fsm_inst_dispatch(fi->proc.parent, - (lcvp->result == VLR_FSM_RESULT_SUCCESS) - ? lcvp->parent_event_success - : lcvp->parent_event_failure, - &lcvp->cause); -} - -static void lu_compl_vlr_init(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct lu_compl_vlr_priv *lcvp = fi->priv; - struct vlr_subscr *vsub = lcvp->vsub; - struct vlr_instance *vlr; - OSMO_ASSERT(vsub); - vlr = vsub->vlr; - OSMO_ASSERT(vlr); - - OSMO_ASSERT(event == LU_COMPL_VLR_E_START); - - /* TODO: National Roaming restrictions? */ - /* TODO: Roaming restriction due to unsupported feature in subscriber - * data? */ - /* TODO: Regional subscription restriction? */ - /* TODO: Administrative restriction of subscribres' access feature? */ - /* TODO: AccessRestrictuionData parameter available? */ - /* TODO: AccessRestrictionData permits RAT? */ - /* Node 1 */ - /* TODO: Autonomous CSG supported in VPLMN and allowed by HPLMN? */ - /* TODO: Hybrid Cel / CSG Cell */ - /* Node 2 */ - vsub->la_allowed = true; - vsub->imsi_detached_flag = false; - /* Start Subscriber_Present_VLR Procedure */ - osmo_fsm_inst_state_chg(fi, LU_COMPL_VLR_S_WAIT_SUB_PRES, - LU_TIMEOUT_LONG, 0); - - lcvp->sub_pres_vlr_fsm = sub_pres_vlr_fsm_start(fi, vsub, - LU_COMPL_VLR_E_SUB_PRES_COMPL); - -} - -static void lu_compl_vlr_new_tmsi(struct osmo_fsm_inst *fi) -{ - struct lu_compl_vlr_priv *lcvp = fi->priv; - struct vlr_subscr *vsub = lcvp->vsub; - struct vlr_instance *vlr = vsub->vlr; - - LOGPFSM(fi, "%s()\n", __func__); - - if (vlr_subscr_alloc_tmsi(vsub)) { - vlr_lu_compl_fsm_failure(fi, - GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER); - return; - } - - osmo_fsm_inst_state_chg(fi, LU_COMPL_VLR_S_WAIT_TMSI_CNF, - vlr_timer(vlr, 3250), 3250); - - vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, vsub->tmsi_new); -} - -/* After completion of Subscriber_Present_VLR */ -static void lu_compl_vlr_wait_subscr_pres(struct osmo_fsm_inst *fi, - uint32_t event, - void *data) -{ - struct lu_compl_vlr_priv *lcvp = fi->priv; - struct vlr_subscr *vsub = lcvp->vsub; - struct vlr_instance *vlr = vsub->vlr; - - OSMO_ASSERT(event == LU_COMPL_VLR_E_SUB_PRES_COMPL); - - lcvp->sub_pres_vlr_fsm = NULL; - - /* TODO: Trace_Subscriber_Activity_VLR */ - - if (vlr->cfg.check_imei_rqd) { - /* Check IMEI VLR */ - osmo_fsm_inst_state_chg(fi, - lcvp->assign_tmsi ? - LU_COMPL_VLR_S_WAIT_IMEI_TMSI - : LU_COMPL_VLR_S_WAIT_IMEI, - vlr_timer(vlr, 3270), 3270); - vlr->ops.tx_id_req(lcvp->msc_conn_ref, GSM_MI_TYPE_IMEI); - return; - } - - /* Do we need to allocate a TMSI? */ - if (lcvp->assign_tmsi) { - lu_compl_vlr_new_tmsi(fi); - return; - } - - /* Location Updating Accept */ - vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI); - vlr_lu_compl_fsm_success(fi); -} - -/* Waiting for completion of CHECK_IMEI_VLR */ -static void lu_compl_vlr_wait_imei(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct lu_compl_vlr_priv *lcvp = fi->priv; - struct vlr_subscr *vsub = lcvp->vsub; - struct vlr_instance *vlr = vsub->vlr; - - switch (event) { - case LU_COMPL_VLR_E_IMEI_CHECK_ACK: - if (!vsub->imei[0]) { - /* Abort: Do nothing */ - vlr_lu_compl_fsm_failure(fi, - GSM48_REJECT_PROTOCOL_ERROR); - return; - } - /* Pass */ - break; - - case LU_COMPL_VLR_E_IMEI_CHECK_NACK: - vlr_lu_compl_fsm_failure(fi, GSM48_REJECT_ILLEGAL_ME); - /* FIXME: IMEI Check Fail to VLR Application (Detach IMSI VLR) */ - return; - } - - /* IMEI is available. Allocate TMSI if needed. */ - if (lcvp->assign_tmsi) { - if (fi->state != LU_COMPL_VLR_S_WAIT_IMEI_TMSI) - LOGPFSML(fi, LOGL_ERROR, - "TMSI required, expected to be in state" - " LU_COMPL_VLR_S_WAIT_IMEI_TMSI," - " am in %s instead\n", - osmo_fsm_state_name(fi->fsm, fi->state)); - /* Logged an error, continue anyway. */ - - lu_compl_vlr_new_tmsi(fi); - - /* Wait for TMSI ack */ - return; - } - - /* No TMSI needed, accept now. */ - vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI); - vlr_lu_compl_fsm_success(fi); -} - -/* Waiting for TMSI confirmation */ -static void lu_compl_vlr_wait_tmsi(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct lu_compl_vlr_priv *lcvp = fi->priv; - struct vlr_subscr *vsub = lcvp->vsub; - - OSMO_ASSERT(event == LU_COMPL_VLR_E_NEW_TMSI_ACK); - - if (!vsub || vsub->tmsi_new == GSM_RESERVED_TMSI) { - LOGPFSML(fi, LOGL_ERROR, "TMSI Realloc Compl implies that" - " the subscriber has a new TMSI allocated, but" - " the new TMSI is unset.\n"); - vlr_lu_compl_fsm_failure(fi, GSM48_REJECT_NETWORK_FAILURE); - return; - } - - vsub->tmsi = vsub->tmsi_new; - vsub->tmsi_new = GSM_RESERVED_TMSI; - - vlr_lu_compl_fsm_success(fi); -} - -static const struct osmo_fsm_state lu_compl_vlr_states[] = { - [LU_COMPL_VLR_S_INIT] = { - .in_event_mask = S(LU_COMPL_VLR_E_START), - .out_state_mask = S(LU_COMPL_VLR_S_DONE) | - S(LU_COMPL_VLR_S_WAIT_SUB_PRES) | - S(LU_COMPL_VLR_S_WAIT_IMEI), - .name = OSMO_STRINGIFY(LU_COMPL_VLR_S_INIT), - .action = lu_compl_vlr_init, - }, - [LU_COMPL_VLR_S_WAIT_SUB_PRES] = { - .in_event_mask = S(LU_COMPL_VLR_E_SUB_PRES_COMPL), - .out_state_mask = S(LU_COMPL_VLR_S_WAIT_IMEI) | - S(LU_COMPL_VLR_S_WAIT_IMEI_TMSI) | - S(LU_COMPL_VLR_S_WAIT_TMSI_CNF) | - S(LU_COMPL_VLR_S_DONE), - .name = OSMO_STRINGIFY(LU_COMPL_VLR_S_WAIT_SUB_PRES), - .action = lu_compl_vlr_wait_subscr_pres, - }, - [LU_COMPL_VLR_S_WAIT_IMEI] = { - .in_event_mask = S(LU_COMPL_VLR_E_IMEI_CHECK_ACK) | - S(LU_COMPL_VLR_E_IMEI_CHECK_NACK), - .out_state_mask = S(LU_COMPL_VLR_S_DONE), - .name = OSMO_STRINGIFY(LU_COMPL_VLR_S_WAIT_IMEI), - .action = lu_compl_vlr_wait_imei, - }, - [LU_COMPL_VLR_S_WAIT_IMEI_TMSI] = { - .in_event_mask = S(LU_COMPL_VLR_E_IMEI_CHECK_ACK) | - S(LU_COMPL_VLR_E_IMEI_CHECK_NACK), - .out_state_mask = S(LU_COMPL_VLR_S_DONE) | - S(LU_COMPL_VLR_S_WAIT_TMSI_CNF), - .name = OSMO_STRINGIFY(LU_COMPL_VLR_S_WAIT_IMEI_TMSI), - .action = lu_compl_vlr_wait_imei, - }, - [LU_COMPL_VLR_S_WAIT_TMSI_CNF] = { - .in_event_mask = S(LU_COMPL_VLR_E_NEW_TMSI_ACK), - .out_state_mask = S(LU_COMPL_VLR_S_DONE), - .name = OSMO_STRINGIFY(LU_COMPL_VLR_S_WAIT_TMSI_CNF), - .action = lu_compl_vlr_wait_tmsi, - }, - [LU_COMPL_VLR_S_DONE] = { - .name = OSMO_STRINGIFY(LU_COMPL_VLR_S_DONE), - .onenter = vlr_lu_compl_fsm_dispatch_result, - }, -}; - -static struct osmo_fsm lu_compl_vlr_fsm = { - .name = "lu_compl_vlr_fsm", - .states = lu_compl_vlr_states, - .num_states = ARRAY_SIZE(lu_compl_vlr_states), - .allstate_event_mask = 0, - .allstate_action = NULL, - .log_subsys = DVLR, - .event_names = lu_compl_vlr_event_names, -}; - -struct osmo_fsm_inst * -lu_compl_vlr_proc_alloc(struct osmo_fsm_inst *parent, - struct vlr_subscr *vsub, - void *msc_conn_ref, - uint32_t parent_event_success, - uint32_t parent_event_failure, - bool assign_tmsi) -{ - struct osmo_fsm_inst *fi; - struct lu_compl_vlr_priv *lcvp; - - fi = osmo_fsm_inst_alloc_child(&lu_compl_vlr_fsm, parent, - parent_event_failure); - if (!fi) - return NULL; - - lcvp = talloc_zero(fi, struct lu_compl_vlr_priv); - lcvp->vsub = vsub; - lcvp->msc_conn_ref = msc_conn_ref; - lcvp->parent_event_success = parent_event_success; - lcvp->parent_event_failure = parent_event_failure; - lcvp->assign_tmsi = assign_tmsi; - fi->priv = lcvp; - - return fi; -} - - -/*********************************************************************** - * Update_Location_Area_VLR, TS 23.012 Chapter 4.1.2.1 - ***********************************************************************/ - -static const struct value_string fsm_lu_event_names[] = { - OSMO_VALUE_STRING(VLR_ULA_E_UPDATE_LA), - OSMO_VALUE_STRING(VLR_ULA_E_SEND_ID_ACK), - OSMO_VALUE_STRING(VLR_ULA_E_SEND_ID_NACK), - OSMO_VALUE_STRING(VLR_ULA_E_AUTH_RES), - OSMO_VALUE_STRING(VLR_ULA_E_CIPH_RES), - OSMO_VALUE_STRING(VLR_ULA_E_ID_IMSI), - OSMO_VALUE_STRING(VLR_ULA_E_ID_IMEI), - OSMO_VALUE_STRING(VLR_ULA_E_ID_IMEISV), - OSMO_VALUE_STRING(VLR_ULA_E_HLR_LU_RES), - OSMO_VALUE_STRING(VLR_ULA_E_UPD_HLR_COMPL), - OSMO_VALUE_STRING(VLR_ULA_E_LU_COMPL_SUCCESS), - OSMO_VALUE_STRING(VLR_ULA_E_LU_COMPL_FAILURE), - OSMO_VALUE_STRING(VLR_ULA_E_NEW_TMSI_ACK), - { 0, NULL } -}; - -struct lu_fsm_priv { - struct vlr_instance *vlr; - struct vlr_subscr *vsub; - void *msc_conn_ref; - struct osmo_fsm_inst *upd_hlr_vlr_fsm; - struct osmo_fsm_inst *lu_compl_vlr_fsm; - uint32_t parent_event_success; - uint32_t parent_event_failure; - void *parent_event_data; - enum vlr_fsm_result result; - uint8_t rej_cause; - - enum vlr_lu_type type; - bool lu_by_tmsi; - char imsi[16]; - uint32_t tmsi; - struct osmo_location_area_id old_lai; - struct osmo_location_area_id new_lai; - bool authentication_required; - enum vlr_ciph ciphering_required; - bool is_r99; - bool is_utran; - bool assign_tmsi; -}; - - -/* Determine if given location area is served by this VLR */ -static bool lai_in_this_vlr(struct vlr_instance *vlr, - const struct osmo_location_area_id *lai) -{ - /* TODO: VLR needs to keep a locally configued list of LAIs */ - return true; -} - -/* Determine if authentication is required */ -static bool is_auth_required(struct lu_fsm_priv *lfp) -{ - /* The cases where the authentication procedure should be used - * are defined in 3GPP TS 33.102 */ - /* For now we use a default value passed in to vlr_lu_fsm(). */ - return lfp->authentication_required - || (lfp->ciphering_required != VLR_CIPH_NONE); -} - -/* Determine if ciphering is required */ -static bool is_ciph_required(struct lu_fsm_priv *lfp) -{ - return lfp->ciphering_required != VLR_CIPH_NONE; -} - -/* Determine if a HLR Update is required */ -static bool hlr_update_needed(struct vlr_subscr *vsub) -{ - /* TODO: properly decide this, rather than always assuming we - * need to update the HLR. */ - return true; -} - -static void lu_fsm_dispatch_result(struct osmo_fsm_inst *fi, - uint32_t prev_state) -{ - struct lu_fsm_priv *lfp = fi->priv; - if (!fi->proc.parent) { - LOGPFSML(fi, LOGL_ERROR, "No parent FSM\n"); - return; - } - osmo_fsm_inst_dispatch(fi->proc.parent, - (lfp->result == VLR_FSM_RESULT_SUCCESS) - ? lfp->parent_event_success - : lfp->parent_event_failure, - lfp->parent_event_data); -} - -static void _lu_fsm_done(struct osmo_fsm_inst *fi, - enum vlr_fsm_result result) -{ - struct lu_fsm_priv *lfp = fi->priv; - lfp->result = result; - osmo_fsm_inst_state_chg(fi, VLR_ULA_S_DONE, 0, 0); -} - -static void lu_fsm_success(struct osmo_fsm_inst *fi) -{ - _lu_fsm_done(fi, VLR_FSM_RESULT_SUCCESS); -} - -static void lu_fsm_failure(struct osmo_fsm_inst *fi, uint8_t rej_cause) -{ - struct lu_fsm_priv *lfp = fi->priv; - if (rej_cause) - lfp->vlr->ops.tx_lu_rej(lfp->msc_conn_ref, rej_cause); - _lu_fsm_done(fi, VLR_FSM_RESULT_FAILURE); -} - -static void vlr_loc_upd_start_lu_compl_fsm(struct osmo_fsm_inst *fi) -{ - struct lu_fsm_priv *lfp = fi->priv; - lfp->lu_compl_vlr_fsm = - lu_compl_vlr_proc_alloc(fi, lfp->vsub, lfp->msc_conn_ref, - VLR_ULA_E_LU_COMPL_SUCCESS, - VLR_ULA_E_LU_COMPL_FAILURE, - lfp->assign_tmsi); - - osmo_fsm_inst_dispatch(lfp->lu_compl_vlr_fsm, LU_COMPL_VLR_E_START, NULL); -} - -static void lu_fsm_discard_lu_compl_fsm(struct osmo_fsm_inst *fi) -{ - struct lu_fsm_priv *lfp = fi->priv; - if (!lfp->lu_compl_vlr_fsm) - return; - osmo_fsm_inst_term(lfp->lu_compl_vlr_fsm, OSMO_FSM_TERM_PARENT, NULL); -} - -/* 4.1.2.1 Node 4 */ -static void vlr_loc_upd_node_4(struct osmo_fsm_inst *fi) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_subscr *vsub = lfp->vsub; - bool hlr_unknown = false; - - LOGPFSM(fi, "%s()\n", __func__); - - if (hlr_unknown) { - /* FIXME: Delete subscriber record */ - /* LU REJ: Roaming not allowed */ - lu_fsm_failure(fi, GSM48_REJECT_ROAMING_NOT_ALLOWED); - } else { - /* Update_HLR_VLR */ - osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_HLR_UPD, - LU_TIMEOUT_LONG, 0); - lfp->upd_hlr_vlr_fsm = - upd_hlr_vlr_proc_start(fi, vsub, VLR_ULA_E_UPD_HLR_COMPL); - } -} - -/* 4.1.2.1 Node B */ -static void vlr_loc_upd_node_b(struct osmo_fsm_inst *fi) -{ - LOGPFSM(fi, "%s()\n", __func__); - - /* OsmoHLR does not support PgA, neither stores the IMEISV, so we have no need to update the HLR - * with either. TODO: depend on actual HLR configuration. See 3GPP TS 23.012 Release 14, process - * Update_Location_Area_VLR (ULA_VLR2). */ - if (0) { /* IMEISV or PgA to send */ - vlr_loc_upd_node_4(fi); - } else { - /* Location_Update_Completion */ - osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_LU_COMPL, - LU_TIMEOUT_LONG, 0); - vlr_loc_upd_start_lu_compl_fsm(fi); - } -} - -/* Non-standard: after Ciphering Mode Complete (or no ciph required) */ -static void vlr_loc_upd_post_ciph(struct osmo_fsm_inst *fi) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_subscr *vsub = lfp->vsub; - - LOGPFSM(fi, "%s()\n", __func__); - - OSMO_ASSERT(vsub); - - if (lfp->is_utran) { - int rc; - rc = lfp->vlr->ops.tx_common_id(lfp->msc_conn_ref); - if (rc) - LOGPFSML(fi, LOGL_ERROR, - "Error while sending Common ID (%d)\n", rc); - } - - vsub->conf_by_radio_contact_ind = true; - /* Update LAI */ - vsub->cgi.lai = lfp->new_lai; - vsub->dormant_ind = false; - vsub->cancel_loc_rx = false; - if (hlr_update_needed(vsub)) { - vlr_loc_upd_node_4(fi); - } else { - /* TODO: ADD Support */ - /* TODO: Node A: PgA Support */ - vlr_loc_upd_node_b(fi); - } -} - -/* 4.1.2.1 after Authentication successful (or no auth rqd) */ -static void vlr_loc_upd_post_auth(struct osmo_fsm_inst *fi) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_subscr *vsub = lfp->vsub; - - LOGPFSM(fi, "%s()\n", __func__); - - OSMO_ASSERT(vsub); - - if (!is_ciph_required(lfp)) { - vlr_loc_upd_post_ciph(fi); - return; - } - - if (vlr_set_ciph_mode(vsub->vlr, fi, lfp->msc_conn_ref, - lfp->ciphering_required, - vsub->vlr->cfg.retrieve_imeisv_ciphered)) { - LOGPFSML(fi, LOGL_ERROR, - "Failed to send Ciphering Mode Command\n"); - vlr_lu_compl_fsm_failure(fi, GSM48_REJECT_NETWORK_FAILURE); - return; - } - - osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_CIPH, LU_TIMEOUT_LONG, 0); -} - -static void vlr_loc_upd_node1(struct osmo_fsm_inst *fi) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_subscr *vsub = lfp->vsub; - - LOGPFSM(fi, "%s()\n", __func__); - - OSMO_ASSERT(vsub); - - if (is_auth_required(lfp)) { - /* Authenticate_VLR */ - osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_AUTH, - LU_TIMEOUT_LONG, 0); - vsub->auth_fsm = auth_fsm_start(lfp->vsub, fi->log_level, - fi, VLR_ULA_E_AUTH_RES, - lfp->is_r99, - lfp->is_utran); - } else { - /* no need for authentication */ - vlr_loc_upd_post_auth(fi); - } -} - -static void vlr_loc_upd_want_imsi(struct osmo_fsm_inst *fi) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_instance *vlr = lfp->vlr; - - LOGPFSM(fi, "%s()\n", __func__); - - OSMO_ASSERT(lfp->vsub); - - /* Obtain_IMSI_VLR */ - osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_IMSI, - vlr_timer(vlr, 3270), 3270); - vlr->ops.tx_id_req(lfp->msc_conn_ref, GSM_MI_TYPE_IMSI); - /* will continue at vlr_loc_upd_node1() once IMSI arrives */ -} - -static int assoc_lfp_with_sub(struct osmo_fsm_inst *fi, struct vlr_subscr *vsub) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_instance *vlr = lfp->vlr; - - if (vsub->lu_fsm) { - LOGPFSML(fi, LOGL_ERROR, - "A Location Updating process is already pending for" - " this subscriber. Aborting.\n"); - /* Also get rid of the other pending LU attempt? */ - /*lu_fsm_failure(vsub->lu_fsm, GSM48_REJECT_CONGESTION);*/ - lu_fsm_failure(fi, GSM48_REJECT_CONGESTION); - return -EINVAL; - } - vsub->lu_fsm = fi; - vsub->msc_conn_ref = lfp->msc_conn_ref; - /* FIXME: send new LAC to HLR? */ - vsub->lac = lfp->new_lai.lac; - lfp->vsub = vsub; - /* Tell MSC to associate this subscriber with the given - * connection */ - vlr->ops.subscr_assoc(lfp->msc_conn_ref, lfp->vsub); - return 0; -} - -static const char *lai_name(struct osmo_location_area_id *lai) -{ - static char buf[64]; - snprintf(buf, sizeof(buf),"MCC:%u, MNC:%u, LAC:%u", - lai->plmn.mcc, lai->plmn.mnc, lai->lac); - return buf; -} - -static int _lu_fsm_associate_vsub(struct osmo_fsm_inst *fi) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_instance *vlr = lfp->vlr; - struct vlr_subscr *vsub = NULL; - - if (!lfp->imsi[0]) { - /* TMSI was used */ - lfp->lu_by_tmsi = true; - /* TMSI clash: if a different subscriber already has this TMSI, - * we will find that other subscriber in the VLR. So the IMSIs - * would mismatch, but we don't know about it. Theoretically, - * an authentication process would thwart any attempt to use - * someone else's TMSI. - * TODO: Otherwise we can ask for the IMSI and verify that it - * matches the IMSI on record. */ - vsub = vlr_subscr_find_or_create_by_tmsi(vlr, lfp->tmsi, NULL); - - if (!vsub) { - LOGPFSML(fi, LOGL_ERROR, "VLR subscriber allocation failed\n"); - lu_fsm_failure(fi, GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER); - return -1; - } - - vsub->sub_dataconf_by_hlr_ind = false; - if (assoc_lfp_with_sub(fi, vsub)) { - vlr_subscr_put(vsub); - return -1; /* error, fsm failure invoked in assoc_lfp_with_sub() */ - } - vlr_subscr_put(vsub); - } else { - /* IMSI was used */ - vsub = vlr_subscr_find_or_create_by_imsi(vlr, lfp->imsi, NULL); - - if (!vsub) { - LOGPFSML(fi, LOGL_ERROR, "VLR subscriber allocation failed\n"); - lu_fsm_failure(fi, GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER); - vlr_subscr_put(vsub); - return -1; - } - - vsub->sub_dataconf_by_hlr_ind = false; - if (assoc_lfp_with_sub(fi, vsub)) { - vlr_subscr_put(vsub); - return -1; /* error, fsm failure invoked in assoc_lfp_with_sub() */ - } - vlr_subscr_put(vsub); - } - return 0; -} - -/* 4.1.2.1: Subscriber (via MSC/SGSN) requests location update */ -static void _start_lu_main(struct osmo_fsm_inst *fi) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_instance *vlr = lfp->vlr; - - /* TODO: PUESBINE related handling */ - - /* Is previous LAI in this VLR? */ - if (!lai_in_this_vlr(vlr, &lfp->old_lai)) { -#if 0 - /* FIXME: check previous VLR, (3) */ - osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_PVLR, - LU_TIMEOUT_LONG, 0); - return; -#endif - LOGPFSML(fi, LOGL_NOTICE, "LAI change from %s," - " but checking previous VLR not implemented\n", - lai_name(&lfp->old_lai)); - } - - /* If this is a TMSI based LU, we may not have the IMSI. Make sure that - * we know the IMSI, either on record, or request it. */ - if (!lfp->vsub->imsi[0]) - vlr_loc_upd_want_imsi(fi); - else - vlr_loc_upd_node1(fi); -} - -static void lu_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_instance *vlr = lfp->vlr; - - OSMO_ASSERT(event == VLR_ULA_E_UPDATE_LA); - - if (_lu_fsm_associate_vsub(fi)) - return; /* error. FSM already terminated. */ - - OSMO_ASSERT(lfp->vsub); - - /* See 3GPP TS 23.012, procedure Retrieve_IMEISV_If_Required */ - if ((!vlr->cfg.retrieve_imeisv_early) - || (lfp->type == VLR_LU_TYPE_PERIODIC && lfp->vsub->imeisv[0])) { - /* R_IMEISV_IR1 passed */ - _start_lu_main(fi); - } else { - vlr->ops.tx_id_req(lfp->msc_conn_ref, GSM_MI_TYPE_IMEISV); - osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_IMEISV, - vlr_timer(vlr, 3270), 3270); - } -} - -static void lu_fsm_wait_imeisv(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - switch (event) { - case VLR_ULA_E_ID_IMEISV: - /* IMEISV was copied in vlr_subscr_rx_id_resp(), and that's - * where we received this event from. */ - _start_lu_main(fi); - break; - default: - LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n", - osmo_fsm_event_name(fi->fsm, event)); - break; - } -} - -/* Wait for response from Send_Identification to PVLR */ -static void lu_fsm_wait_pvlr(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - switch (event) { - case VLR_ULA_E_SEND_ID_ACK: - vlr_loc_upd_node1(fi); - break; - case VLR_ULA_E_SEND_ID_NACK: - vlr_loc_upd_want_imsi(fi); - break; - default: - LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n", - osmo_fsm_event_name(fi->fsm, event)); - break; - } -} - -/* Wait for result of Authenticate_VLR procedure */ -static void lu_fsm_wait_auth(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct lu_fsm_priv *lfp = fi->priv; - enum vlr_auth_fsm_result *res = data; - uint8_t rej_cause = 0; - - OSMO_ASSERT(event == VLR_ULA_E_AUTH_RES); - - lfp->upd_hlr_vlr_fsm = NULL; - - if (res) { - switch (*res) { - case VLR_AUTH_RES_PASSED: - /* Result == Pass */ - vlr_loc_upd_post_auth(fi); - return; - case VLR_AUTH_RES_ABORTED: - /* go to Idle with no response */ - rej_cause = 0; - break; - case VLR_AUTH_RES_UNKNOWN_SUBSCR: - /* FIXME: delete subscribe record */ - rej_cause = GSM48_REJECT_IMSI_UNKNOWN_IN_HLR; - break; - case VLR_AUTH_RES_AUTH_FAILED: - /* cause = illegal subscriber */ - rej_cause = GSM48_REJECT_ILLEGAL_MS; - break; - case VLR_AUTH_RES_PROC_ERR: - /* cause = system failure */ - rej_cause = GSM48_REJECT_NETWORK_FAILURE; - break; - default: - LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n", - osmo_fsm_event_name(fi->fsm, event)); - break; - } - } else - rej_cause = GSM48_REJECT_NETWORK_FAILURE; - - lu_fsm_failure(fi, rej_cause); -} - -static void lu_fsm_wait_ciph(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_subscr *vsub = lfp->vsub; - struct vlr_ciph_result res = { .cause = VLR_CIPH_REJECT }; - - OSMO_ASSERT(event == VLR_ULA_E_CIPH_RES); - - if (!data) - LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: NULL\n"); - else - res = *(struct vlr_ciph_result*)data; - - switch (res.cause) { - case VLR_CIPH_COMPL: - break; - case VLR_CIPH_REJECT: - LOGPFSM(fi, "ciphering rejected\n"); - lu_fsm_failure(fi, GSM48_REJECT_INVALID_MANDANTORY_INF); - return; - default: - LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: %d\n", - res.cause); - lu_fsm_failure(fi, GSM48_REJECT_INVALID_MANDANTORY_INF); - return; - } - - if (res.imeisv) { - LOGPFSM(fi, "got IMEISV: %s\n", res.imeisv); - vlr_subscr_set_imeisv(vsub, res.imeisv); - } - vlr_loc_upd_post_ciph(fi); -} - -static void lu_fsm_wait_imsi(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_subscr *vsub = lfp->vsub; - char *mi_string = data; - - switch (event) { - case VLR_ULA_E_ID_IMSI: - vlr_subscr_set_imsi(vsub, mi_string); - vlr_loc_upd_node1(fi); - break; - default: - LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n", - osmo_fsm_event_name(fi->fsm, event)); - break; - } -} - -/* At the end of Update_HLR_VLR */ -static void lu_fsm_wait_hlr_ul_res(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct lu_fsm_priv *lfp = fi->priv; - - switch (event) { - case VLR_ULA_E_HLR_LU_RES: - /* pass-through this event to Update_HLR_VLR */ - if (data == NULL) - osmo_fsm_inst_dispatch(lfp->upd_hlr_vlr_fsm, UPD_HLR_VLR_E_UPD_LOC_ACK, NULL); - else - osmo_fsm_inst_dispatch(lfp->upd_hlr_vlr_fsm, UPD_HLR_VLR_E_UPD_LOC_NACK, data); - break; - case VLR_ULA_E_UPD_HLR_COMPL: - if (data == NULL) { - /* successful case */ - osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_LU_COMPL, - LU_TIMEOUT_LONG, 0); - vlr_loc_upd_start_lu_compl_fsm(fi); - /* continue in MSC ?!? */ - } else { - /* unsuccessful case */ - enum gsm48_gmm_cause cause = - *(enum gsm48_gmm_cause *)data; - /* Ignoring standalone mode for now. */ - if (0 /* procedure_error && vlr->cfg.standalone_mode */) { - osmo_fsm_inst_state_chg(fi, - VLR_ULA_S_WAIT_LU_COMPL_STANDALONE, - LU_TIMEOUT_LONG, 0); - vlr_loc_upd_start_lu_compl_fsm(fi); - } else { - lu_fsm_failure(fi, cause); - } - } - break; - default: - LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n", - osmo_fsm_event_name(fi->fsm, event)); - break; - } -} - -/* Wait for end of Location_Update_Completion_VLR */ -static void lu_fsm_wait_lu_compl(struct osmo_fsm_inst *fi, uint32_t event, - void *data) -{ - struct lu_fsm_priv *lfp = fi->priv; - uint8_t cause; - - switch (event) { - case VLR_ULA_E_NEW_TMSI_ACK: - osmo_fsm_inst_dispatch(lfp->lu_compl_vlr_fsm, - LU_COMPL_VLR_E_NEW_TMSI_ACK, NULL); - break; - case VLR_ULA_E_ID_IMEI: - osmo_fsm_inst_dispatch(lfp->lu_compl_vlr_fsm, - LU_COMPL_VLR_E_IMEI_CHECK_ACK, NULL); - break; - case VLR_ULA_E_LU_COMPL_SUCCESS: - lu_fsm_discard_lu_compl_fsm(fi); - - /* Update Register */ - /* TODO: Set_Notification_Type 23.078 */ - /* TODO: Notify_gsmSCF 23.078 */ - /* TODO: Authenticated Radio Contact Established -> ARC */ - lu_fsm_success(fi); - break; - case VLR_ULA_E_LU_COMPL_FAILURE: - cause = GSM48_REJECT_NETWORK_FAILURE; - if (data) - cause = *(uint8_t*)data; - lu_fsm_discard_lu_compl_fsm(fi); - lu_fsm_failure(fi, cause); - break; - default: - LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n", - osmo_fsm_event_name(fi->fsm, event)); - break; - } -} - -/* Wait for end of Location_Update_Completion_VLR (standalone case) */ -static void lu_fsm_wait_lu_compl_standalone(struct osmo_fsm_inst *fi, - uint32_t event, void *data) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_subscr *vsub = lfp->vsub; - uint8_t cause; - - switch (event) { - case VLR_ULA_E_NEW_TMSI_ACK: - osmo_fsm_inst_dispatch(lfp->lu_compl_vlr_fsm, - LU_COMPL_VLR_E_NEW_TMSI_ACK, NULL); - break; - case VLR_ULA_E_LU_COMPL_SUCCESS: - lu_fsm_discard_lu_compl_fsm(fi); - vsub->sub_dataconf_by_hlr_ind = false; - lu_fsm_success(fi); - break; - case VLR_ULA_E_LU_COMPL_FAILURE: - vsub->sub_dataconf_by_hlr_ind = false; - cause = GSM48_REJECT_NETWORK_FAILURE; - if (data) - cause = *(uint8_t*)data; - lu_fsm_discard_lu_compl_fsm(fi); - lu_fsm_failure(fi, cause); - break; - default: - LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n", - osmo_fsm_event_name(fi->fsm, event)); - break; - } -} - -static const struct osmo_fsm_state vlr_lu_fsm_states[] = { - [VLR_ULA_S_IDLE] = { - .in_event_mask = S(VLR_ULA_E_UPDATE_LA), - .out_state_mask = S(VLR_ULA_S_WAIT_IMEISV) | - S(VLR_ULA_S_WAIT_PVLR) | - S(VLR_ULA_S_WAIT_IMSI) | - S(VLR_ULA_S_WAIT_AUTH) | - S(VLR_ULA_S_WAIT_HLR_UPD) | - S(VLR_ULA_S_DONE), - .name = OSMO_STRINGIFY(VLR_ULA_S_IDLE), - .action = lu_fsm_idle, - }, - [VLR_ULA_S_WAIT_IMEISV] = { - .in_event_mask = S(VLR_ULA_E_ID_IMEISV), - .out_state_mask = S(VLR_ULA_S_WAIT_PVLR) | - S(VLR_ULA_S_WAIT_IMSI) | - S(VLR_ULA_S_WAIT_AUTH) | - S(VLR_ULA_S_WAIT_HLR_UPD) | - S(VLR_ULA_S_DONE), - .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_IMEISV), - .action = lu_fsm_wait_imeisv, - }, - [VLR_ULA_S_WAIT_PVLR] = { - .in_event_mask = S(VLR_ULA_E_SEND_ID_ACK) | - S(VLR_ULA_E_SEND_ID_NACK), - .out_state_mask = S(VLR_ULA_S_WAIT_IMSI) | - S(VLR_ULA_S_WAIT_AUTH) | - S(VLR_ULA_S_DONE), - .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_PVLR), - .action = lu_fsm_wait_pvlr, - }, - [VLR_ULA_S_WAIT_AUTH] = { - .in_event_mask = S(VLR_ULA_E_AUTH_RES), - .out_state_mask = S(VLR_ULA_S_WAIT_CIPH) | - S(VLR_ULA_S_WAIT_LU_COMPL) | - S(VLR_ULA_S_WAIT_HLR_UPD) | - S(VLR_ULA_S_DONE), - .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_AUTH), - .action = lu_fsm_wait_auth, - }, - [VLR_ULA_S_WAIT_CIPH] = { - .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_CIPH), - .in_event_mask = S(VLR_ULA_E_CIPH_RES), - .out_state_mask = S(VLR_ULA_S_WAIT_LU_COMPL) | - S(VLR_ULA_S_WAIT_HLR_UPD) | - S(VLR_ULA_S_DONE), - .action = lu_fsm_wait_ciph, - }, - [VLR_ULA_S_WAIT_IMSI] = { - .in_event_mask = S(VLR_ULA_E_ID_IMSI), - .out_state_mask = S(VLR_ULA_S_WAIT_AUTH) | - S(VLR_ULA_S_WAIT_HLR_UPD) | - S(VLR_ULA_S_DONE), - .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_IMSI), - .action = lu_fsm_wait_imsi, - }, - [VLR_ULA_S_WAIT_HLR_UPD] = { - .in_event_mask = S(VLR_ULA_E_HLR_LU_RES) | - S(VLR_ULA_E_UPD_HLR_COMPL), - .out_state_mask = S(VLR_ULA_S_WAIT_LU_COMPL) | - S(VLR_ULA_S_WAIT_LU_COMPL_STANDALONE) | - S(VLR_ULA_S_DONE), - .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_HLR_UPD), - .action = lu_fsm_wait_hlr_ul_res, - }, - [VLR_ULA_S_WAIT_LU_COMPL] = { - .in_event_mask = S(VLR_ULA_E_LU_COMPL_SUCCESS) | - S(VLR_ULA_E_LU_COMPL_FAILURE) | - S(VLR_ULA_E_NEW_TMSI_ACK) | - S(VLR_ULA_E_ID_IMEI) | - S(VLR_ULA_E_ID_IMEISV), - .out_state_mask = S(VLR_ULA_S_DONE), - .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_LU_COMPL), - .action = lu_fsm_wait_lu_compl, - }, - [VLR_ULA_S_WAIT_LU_COMPL_STANDALONE] = { - .in_event_mask = S(VLR_ULA_E_LU_COMPL_SUCCESS) | - S(VLR_ULA_E_LU_COMPL_FAILURE) | - S(VLR_ULA_E_NEW_TMSI_ACK), - .out_state_mask = S(VLR_ULA_S_DONE), - .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_LU_COMPL_STANDALONE), - .action = lu_fsm_wait_lu_compl_standalone, - }, - [VLR_ULA_S_DONE] = { - .name = OSMO_STRINGIFY(VLR_ULA_S_DONE), - .onenter = lu_fsm_dispatch_result, - }, -}; - -static void fsm_lu_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) -{ - struct lu_fsm_priv *lfp = fi->priv; - struct vlr_subscr *vsub = lfp->vsub; - - LOGPFSM(fi, "fsm_lu_cleanup called with cause %s\n", - osmo_fsm_term_cause_name(cause)); - if (vsub && vsub->lu_fsm == fi) - vsub->lu_fsm = NULL; -} - -static struct osmo_fsm vlr_lu_fsm = { - .name = "vlr_lu_fsm", - .states = vlr_lu_fsm_states, - .num_states = ARRAY_SIZE(vlr_lu_fsm_states), - .allstate_event_mask = 0, - .allstate_action = NULL, - .log_subsys = DVLR, - .event_names = fsm_lu_event_names, - .cleanup = fsm_lu_cleanup, -}; - -struct osmo_fsm_inst * -vlr_loc_update(struct osmo_fsm_inst *parent, - uint32_t parent_event_success, - uint32_t parent_event_failure, - void *parent_event_data, - struct vlr_instance *vlr, void *msc_conn_ref, - enum vlr_lu_type type, uint32_t tmsi, const char *imsi, - const struct osmo_location_area_id *old_lai, - const struct osmo_location_area_id *new_lai, - bool authentication_required, - enum vlr_ciph ciphering_required, - bool is_r99, bool is_utran, - bool assign_tmsi) -{ - struct osmo_fsm_inst *fi; - struct lu_fsm_priv *lfp; - - fi = osmo_fsm_inst_alloc_child(&vlr_lu_fsm, parent, parent_event_failure); - if (!fi) - return NULL; - - lfp = talloc_zero(fi, struct lu_fsm_priv); - lfp->vlr = vlr; - lfp->msc_conn_ref = msc_conn_ref; - lfp->tmsi = tmsi; - lfp->type = type; - lfp->old_lai = *old_lai; - lfp->new_lai = *new_lai; - lfp->lu_by_tmsi = true; - lfp->parent_event_success = parent_event_success; - lfp->parent_event_failure = parent_event_failure; - lfp->parent_event_data = parent_event_data; - lfp->authentication_required = authentication_required; - lfp->ciphering_required = ciphering_required; - lfp->is_r99 = is_r99; - lfp->is_utran = is_utran; - lfp->assign_tmsi = assign_tmsi; - if (imsi) { - strncpy(lfp->imsi, imsi, sizeof(lfp->imsi)-1); - lfp->imsi[sizeof(lfp->imsi)-1] = '\0'; - lfp->lu_by_tmsi = false; - } - fi->priv = lfp; - - LOGPFSM(fi, "rev=%s net=%s%s%s\n", - is_r99 ? "R99" : "GSM", - is_utran ? "UTRAN" : "GERAN", - (authentication_required || ciphering_required)? - " Auth" : " (no Auth)", - (authentication_required || ciphering_required)? - (ciphering_required? "+Ciph" : " (no Ciph)") - : ""); - - if (is_utran && !authentication_required) - LOGPFSML(fi, LOGL_ERROR, - "Authentication off on UTRAN network. Good luck.\n"); - - osmo_fsm_inst_dispatch(fi, VLR_ULA_E_UPDATE_LA, NULL); - - return fi; -} - -/* Gracefully terminate an FSM created by vlr_loc_update() in case of external - * timeout (i.e. from MSC). */ -void vlr_loc_update_conn_timeout(struct osmo_fsm_inst *fi) -{ - if (!fi || fi->state == VLR_ULA_S_DONE) - return; - LOGPFSM(fi, "Connection timed out\n"); - lu_fsm_failure(fi, GSM48_REJECT_CONGESTION); -} - -void vlr_lu_fsm_init(void) -{ - osmo_fsm_register(&vlr_lu_fsm); - osmo_fsm_register(&upd_hlr_vlr_fsm); - osmo_fsm_register(&sub_pres_vlr_fsm); - osmo_fsm_register(&lu_compl_vlr_fsm); -} diff --git a/src/libvlr/vlr_lu_fsm.h b/src/libvlr/vlr_lu_fsm.h deleted file mode 100644 index 5cf13c77e..000000000 --- a/src/libvlr/vlr_lu_fsm.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -enum vlr_lu_state { - VLR_ULA_S_IDLE, - VLR_ULA_S_WAIT_IMEISV, - VLR_ULA_S_WAIT_PVLR, /* Waiting for ID from PVLR */ - VLR_ULA_S_WAIT_AUTH, /* Waiting for Authentication */ - VLR_ULA_S_WAIT_CIPH, /* Waiting for Ciphering Complete */ - VLR_ULA_S_WAIT_IMSI, /* Waiting for IMSI from MS */ - VLR_ULA_S_WAIT_HLR_UPD, /* Waiting for end of HLR update */ - VLR_ULA_S_WAIT_LU_COMPL,/* Waiting for LU complete */ - VLR_ULA_S_WAIT_LU_COMPL_STANDALONE, /* Standalone VLR */ - VLR_ULA_S_DONE -}; - -void vlr_lu_fsm_init(void); diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am index 5642fb2ed..dfc4defcb 100644 --- a/src/osmo-bsc/Makefile.am +++ b/src/osmo-bsc/Makefile.am @@ -43,7 +43,6 @@ osmo_bsc_LDADD = \ $(top_builddir)/src/libfilter/libfilter.a \ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ - $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libtrau/libtrau.a \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOSCCP_LIBS) \ diff --git a/src/osmo-bsc/osmo_bsc_api.c b/src/osmo-bsc/osmo_bsc_api.c index f7343f743..8e47069c1 100644 --- a/src/osmo-bsc/osmo_bsc_api.c +++ b/src/osmo-bsc/osmo_bsc_api.c @@ -22,9 +22,12 @@ #include #include +#include #include #include +#include +#include #include #include diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index 9a5288bdc..3417783a6 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -26,10 +26,12 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -42,8 +44,7 @@ /* Helper function for match_codec_pref(), looks up a matching permitted speech * value for a given msc audio codec pref */ -enum gsm0808_permitted_speech audio_support_to_gsm88(struct gsm_audio_support - *audio) +enum gsm0808_permitted_speech audio_support_to_gsm88(struct gsm_audio_support *audio) { if (audio->hr) { switch (audio->ver) { @@ -517,9 +518,18 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn, * local preferences of the BSC */ rc = match_codec_pref(&full_rate, &chan_mode, &ct, scl_ptr, msc); if (rc < 0) { - LOGP(DMSC, LOGL_ERROR, "No supported audio type found.\n"); + LOGP(DMSC, LOGL_ERROR, "No supported audio type found for channel_type =" + " { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=[ %s] }\n", + ct.ch_indctr, ct.ch_rate_type, osmo_hexdump(ct.perm_spch, ct.perm_spch_len)); + /* TODO: actually output codec names, e.g. implement gsm0808_permitted_speech_names[] and + * iterate perm_spch. */ goto reject; } + DEBUGP(DMSC, "Found matching audio type: %s %s for channel_type =" + " { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=[ %s] }\n", + full_rate? "full rate" : "half rate", + get_value_string(gsm48_chan_mode_names, chan_mode), + ct.ch_indctr, ct.ch_rate_type, osmo_hexdump(ct.perm_spch, ct.perm_spch_len)); if (aoip == false) { /* map it to a MGCP Endpoint and a RTP port */ diff --git a/src/osmo-bsc/osmo_bsc_filter.c b/src/osmo-bsc/osmo_bsc_filter.c index 2c84b169f..2a9820d40 100644 --- a/src/osmo-bsc/osmo_bsc_filter.c +++ b/src/osmo-bsc/osmo_bsc_filter.c @@ -17,6 +17,8 @@ * */ +#include + #include #include #include diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c index cf188a9e0..61ef33cb4 100644 --- a/src/osmo-bsc/osmo_bsc_main.c +++ b/src/osmo-bsc/osmo_bsc_main.c @@ -58,7 +58,7 @@ #include "../../bscconfig.h" struct gsm_network *bsc_gsmnet = 0; -static const char *config_file = "openbsc.cfg"; +static const char *config_file = "osmo-bsc.cfg"; static const char *rf_ctrl = NULL; extern const char *openbsc_copyright; static int daemonize = 0; diff --git a/src/osmo-bsc_nat/bsc_nat_rewrite.c b/src/osmo-bsc_nat/bsc_nat_rewrite.c index e7c387c22..943e1fa7a 100644 --- a/src/osmo-bsc_nat/bsc_nat_rewrite.c +++ b/src/osmo-bsc_nat/bsc_nat_rewrite.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include diff --git a/src/osmo-bsc_nat/bsc_nat_vty.c b/src/osmo-bsc_nat/bsc_nat_vty.c index fed530676..875cefb72 100644 --- a/src/osmo-bsc_nat/bsc_nat_vty.c +++ b/src/osmo-bsc_nat/bsc_nat_vty.c @@ -24,10 +24,10 @@ #include #include #include -#include #include #include #include +#include #include #include diff --git a/src/osmo-bsc_nat/bsc_ussd.c b/src/osmo-bsc_nat/bsc_ussd.c index 9769bbd39..29b4feef9 100644 --- a/src/osmo-bsc_nat/bsc_ussd.c +++ b/src/osmo-bsc_nat/bsc_ussd.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -40,6 +41,7 @@ #include #include #include +#include #define USSD_LAC_IE 0 #define USSD_CI_IE 1 diff --git a/src/osmo-msc/Makefile.am b/src/osmo-msc/Makefile.am deleted file mode 100644 index 0d4876fa9..000000000 --- a/src/osmo-msc/Makefile.am +++ /dev/null @@ -1,58 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - -I$(top_builddir) \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - $(COVERAGE_CFLAGS) \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOCTRL_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(LIBSMPP34_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) \ - $(LIBOSMORANAP_CFLAGS) \ - $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) \ - $(LIBOSMOLEGACYMGCP_CFLAGS) \ - $(NULL) - -AM_LDFLAGS = \ - $(COVERAGE_LDFLAGS) \ - $(NULL) - -bin_PROGRAMS = \ - osmo-msc \ - $(NULL) - -osmo_msc_SOURCES = \ - msc_main.c \ - $(NULL) - -osmo_msc_LDADD = \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libvlr/libvlr.a \ - $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOCTRL_LIBS) \ - $(LIBOSMOABIS_LIBS) \ - $(LIBSMPP34_LIBS) \ - $(LIBCRYPTO_LIBS) \ - $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBOSMOLEGACYMGCP_LIBS) \ - $(LIBRARY_GSM) \ - -ldbi \ - $(NULL) -if BUILD_IU -osmo_msc_LDADD += \ - $(LIBOSMORANAP_LIBS) \ - $(LIBASN1C_LIBS) \ - $(NULL) -endif diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c deleted file mode 100644 index 30b11d983..000000000 --- a/src/osmo-msc/msc_main.c +++ /dev/null @@ -1,589 +0,0 @@ -/* OsmoMSC - Circuit-Switched Core Network (MSC+VLR+HLR+SMSC) implementation - */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Based on OsmoNITB: - * (C) 2008-2010 by Harald Welte - * (C) 2009-2012 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include - -#define _GNU_SOURCE -#include - -/* build switches from the configure script */ -#include "../../bscconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BUILD_IU -#include -#endif - -#include -#include -#include -#include - -static const char * const osmomsc_copyright = - "OsmoMSC - Osmocom Circuit-Switched Core Network implementation\r\n" - "Copyright (C) 2016 by sysmocom s.f.m.c. GmbH \r\n" - "Based on OsmoNITB:\r\n" - " (C) 2008-2010 by Harald Welte \r\n" - " (C) 2009-2012 by Holger Hans Peter Freyther \r\n" - "Contributions by Daniel Willmann, Jan Lübbe, Stefan Schmidt\r\n" - "Dieter Spaar, Andreas Eversberg, Sylvain Munaut, Neels Hofmeyr\r\n\r\n" - "License AGPLv3+: GNU AGPL version 3 or later \r\n" - "This is free software: you are free to change and redistribute it.\r\n" - "There is NO WARRANTY, to the extent permitted by law.\r\n"; - -void *tall_msc_ctx = NULL; - -/* satisfy deps from libbsc legacy. - TODO double check these */ -void *tall_fle_ctx = NULL; -void *tall_paging_ctx = NULL; -void *tall_map_ctx = NULL; -void *tall_upq_ctx = NULL; -/* end deps from libbsc legacy. */ - -static struct { - const char *database_name; - const char *config_file; - int daemonize; - const char *mncc_sock_path; - int use_db_counter; -} msc_cmdline_config = { - "sms.db", - "osmo-msc.cfg", - 0, - 0, - 1 -}; - -/* timer to store statistics */ -#define DB_SYNC_INTERVAL 60, 0 -#define EXPIRE_INTERVAL 10, 0 - -static struct osmo_timer_list db_sync_timer; - -static void create_pcap_file(char *file) -{ - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode); - - if (fd < 0) { - perror("Failed to open file for pcap"); - return; - } - - e1_set_pcap_fd(fd); -} - -static void print_usage() -{ - printf("Usage: osmo-nitb\n"); -} - -static void print_help() -{ - printf(" Some useful help...\n"); - printf(" -h --help This text.\n"); - printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM Enable debugging.\n"); - printf(" -D --daemonize Fork the process into a background daemon.\n"); - printf(" -c --config-file filename The config file to use.\n"); - printf(" -s --disable-color\n"); - printf(" -l --database db-name The database to use.\n"); - printf(" -T --timestamp Prefix every log line with a timestamp.\n"); - printf(" -V --version Print the version of OpenBSC.\n"); - printf(" -P --rtp-proxy Enable the RTP Proxy code inside OpenBSC.\n"); - printf(" -e --log-level number Set a global loglevel.\n"); - printf(" -M --mncc-sock-path PATH Disable built-in MNCC handler and offer socket.\n"); - printf(" -m --mncc-sock Same as `-M /tmp/bsc_mncc' (deprecated).\n"); - printf(" -C --no-dbcounter Disable regular syncing of counters to database.\n"); - printf(" -r --rf-ctl PATH A unix domain socket to listen for cmds.\n"); - printf(" -p --pcap PATH Write abis communication to pcap trace file.\n"); -} - -static void handle_options(int argc, char **argv) -{ - while (1) { - int option_index = 0, c; - static struct option long_options[] = { - {"help", 0, 0, 'h'}, - {"debug", 1, 0, 'd'}, - {"daemonize", 0, 0, 'D'}, - {"config-file", 1, 0, 'c'}, - {"disable-color", 0, 0, 's'}, - {"database", 1, 0, 'l'}, - {"pcap", 1, 0, 'p'}, - {"timestamp", 0, 0, 'T'}, - {"version", 0, 0, 'V' }, - {"rtp-proxy", 0, 0, 'P'}, - {"log-level", 1, 0, 'e'}, - {"mncc-sock", 0, 0, 'm'}, - {"mncc-sock-path", 1, 0, 'M'}, - {"no-dbcounter", 0, 0, 'C'}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "hd:Dsl:ap:TPVc:e:mCM:", - long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - print_usage(); - print_help(); - exit(0); - case 's': - log_set_use_color(osmo_stderr_target, 0); - break; - case 'd': - log_parse_category_mask(osmo_stderr_target, optarg); - break; - case 'D': - msc_cmdline_config.daemonize = 1; - break; - case 'l': - msc_cmdline_config.database_name = optarg; - break; - case 'c': - msc_cmdline_config.config_file = optarg; - break; - case 'p': - create_pcap_file(optarg); - break; - case 'T': - log_set_print_timestamp(osmo_stderr_target, 1); - break; -#if BEFORE_MSCSPLIT - case 'P': - ipacc_rtp_direct = 0; - break; -#endif - case 'e': - log_set_log_level(osmo_stderr_target, atoi(optarg)); - break; - case 'M': - msc_cmdline_config.mncc_sock_path = optarg; - break; - case 'm': - msc_cmdline_config.mncc_sock_path = "/tmp/bsc_mncc"; - break; - case 'C': - msc_cmdline_config.use_db_counter = 0; - break; - case 'V': - print_version(1); - exit(0); - break; - default: - /* catch unknown options *as well as* missing arguments. */ - fprintf(stderr, "Error in command line options. Exiting.\n"); - exit(-1); - } - } -} - -struct gsm_network *msc_network_alloc(void *ctx, - mncc_recv_cb_t mncc_recv) -{ - struct gsm_network *net = gsm_network_init(ctx, 1, 1, mncc_recv); - if (!net) - return NULL; - - net->name_long = talloc_strdup(net, "OsmoMSC"); - net->name_short = talloc_strdup(net, "OsmoMSC"); - - net->gsup_server_addr_str = talloc_strdup(net, - MSC_HLR_REMOTE_IP_DEFAULT); - net->gsup_server_port = MSC_HLR_REMOTE_PORT_DEFAULT; - - mgcpgw_client_conf_init(&net->mgcpgw.conf); - - return net; -} - -void msc_network_shutdown(struct gsm_network *net) -{ - /* nothing here yet */ -} - -static struct gsm_network *msc_network = NULL; - -extern void *tall_vty_ctx; -static void signal_handler(int signal) -{ - fprintf(stdout, "signal %u received\n", signal); - - switch (signal) { - case SIGINT: - case SIGTERM: - msc_network_shutdown(msc_network); - osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); - sleep(3); - exit(0); - break; - case SIGABRT: - osmo_generate_backtrace(); - /* in case of abort, we want to obtain a talloc report - * and then return to the caller, who will abort the process */ - case SIGUSR1: - talloc_report(tall_vty_ctx, stderr); - talloc_report_full(tall_msc_ctx, stderr); - break; - case SIGUSR2: - talloc_report_full(tall_vty_ctx, stderr); - break; - default: - break; - } -} - -/* timer handling */ -static int _db_store_counter(struct osmo_counter *counter, void *data) -{ - return db_store_counter(counter); -} - -static void db_sync_timer_cb(void *data) -{ - /* store counters to database and re-schedule */ - osmo_counters_for_each(_db_store_counter, NULL); - osmo_timer_schedule(&db_sync_timer, DB_SYNC_INTERVAL); -} - -extern int bsc_vty_go_parent(struct vty *vty); - -static struct vty_app_info msc_vty_info = { - .name = "OsmoMSC", - .version = PACKAGE_VERSION, - .go_parent_cb = bsc_vty_go_parent, - .is_config_node = bsc_vty_is_config_node, -}; - -#ifdef BUILD_IU -static int rcvmsg_iu_cs(struct msgb *msg, struct gprs_ra_id *ra_id, uint16_t *sai) -{ - DEBUGP(DIUCS, "got IuCS message" - " %d bytes: %s\n", - msg->len, osmo_hexdump(msg->data, msg->len)); - if (ra_id) { - DEBUGP(DIUCS, "got IuCS message on" - " MNC %d MCC %d LAC %d RAC %d\n", - ra_id->mnc, ra_id->mcc, ra_id->lac, ra_id->rac); - } - - return gsm0408_rcvmsg_iucs(msc_network, msg, ra_id? &ra_id->lac : NULL); -} - -static int rx_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type, - void *data) -{ - DEBUGP(DIUCS, "got IuCS event %u: %s\n", type, - ranap_iu_event_type_str(type)); - - return iucs_rx_ranap_event(msc_network, ctx, type, data); -} -#endif - -#define DEFAULT_M3UA_REMOTE_IP "127.0.0.1" -#define DEFAULT_PC_A "0.23.1" -#define DEFAULT_PC_IU "0.23.2" -#define DEFAULT_PC_A_IU DEFAULT_PC_A - -static struct osmo_sccp_instance *sccp_setup(void *ctx, uint32_t cs7_instance, - const char *label, const char *default_pc_str) -{ - int default_pc = osmo_ss7_pointcode_parse(NULL, default_pc_str); - if (default_pc < 0) - return NULL; - - return osmo_sccp_simple_client_on_ss7_id(ctx, cs7_instance, label, default_pc, - OSMO_SS7_ASP_PROT_M3UA, - 0, NULL, /* local: use arbitrary port and 0.0.0.0. */ - 0, /* remote: use protocol default port */ - DEFAULT_M3UA_REMOTE_IP); - /* Note: If a differing remote IP is to be used, it was already entered in the vty config at - * 'cs7' / 'asp' / 'remote-ip', and this default remote IP has no effect. - * Similarly, 'cs7' / 'listen' can specify the local IP address. */ -} - -static int ss7_setup(void *ctx) -{ - uint32_t cs7_instance_a = msc_network->a.cs7_instance; -#if BUILD_IU - uint32_t cs7_instance_iu = msc_network->iu.cs7_instance; - - if (cs7_instance_a == cs7_instance_iu) { - /* Create one single SCCP instance which will be used for both, - * Iu and A at the same time, under the same point-code */ - LOGP(DMSC, LOGL_NOTICE, "CS7 Instance identifiers: A = Iu = %u\n", cs7_instance_a); - - msc_network->a.sccp = sccp_setup(ctx, cs7_instance_a, "OsmoMSC-A-Iu", DEFAULT_PC_A_IU); - if (!msc_network->a.sccp) - return -EINVAL; - - msc_network->iu.sccp = msc_network->a.sccp; - } else { - /* Create two separate SCCP instances to run A and Iu independently on different - * pointcodes */ - LOGP(DMSC, LOGL_NOTICE, "CS7 Instance identifiers: A = %u, Iu = %u\n", - cs7_instance_a, cs7_instance_iu); - - msc_network->a.sccp = sccp_setup(ctx, cs7_instance_a, "OsmoMSC-A", DEFAULT_PC_A); - if (!msc_network->a.sccp) - return -EINVAL; - - msc_network->iu.sccp = sccp_setup(ctx, cs7_instance_iu, "OsmoMSC-Iu", DEFAULT_PC_IU); - if (!msc_network->iu.sccp) - return -EINVAL; - } -#else - /* No Iu support, just open up an A instance */ - msc_network->a.sccp = sccp_setup(ctx, cs7_instance_a, "OsmoMSC-A", DEFAULT_PC_A); - if (!msc_network->a.sccp) - return -EINVAL; -#endif - - return 0; -} - -int main(int argc, char **argv) -{ - int rc; - - msc_vty_info.copyright = osmomsc_copyright; - - tall_msc_ctx = talloc_named_const(NULL, 1, "osmo_msc"); - talloc_ctx_init(tall_msc_ctx); - - osmo_init_logging(&log_info); - osmo_stats_init(tall_msc_ctx); - - /* For --version, vty_init() must be called before handling options */ - vty_init(&msc_vty_info); - - osmo_ss7_init(); - osmo_ss7_vty_init_asp(tall_msc_ctx); - - /* Parse options */ - handle_options(argc, argv); - - /* Allocate global gsm_network struct; choose socket/internal MNCC */ - msc_network = msc_network_alloc(tall_msc_ctx, - msc_cmdline_config.mncc_sock_path? - mncc_sock_from_cc - : int_mncc_recv); - if (!msc_network) - return -ENOMEM; - - if (msc_vlr_alloc(msc_network)) { - fprintf(stderr, "Failed to allocate VLR\n"); - exit(1); - } - - ctrl_vty_init(tall_msc_ctx); - logging_vty_add_cmds(&log_info); - msc_vty_init(msc_network); - bsc_vty_init_extra(); - -#ifdef BUILD_SMPP - if (smpp_openbsc_alloc_init(tall_msc_ctx) < 0) - return -1; -#endif - - /* - * For osmo-nitb, skip TCH/F for now, because otherwise dyn TS - * always imply the possibility to have a mix of TCH/F and - * TCH/H channels; if two phones request a TCH/F and a TCH/H, - * respectively, they cannot call each other. If we deny TCH/F, - * they will both fall back to TCH/H, and dynamic channels are - * usable. See OS#1778. - * - * A third-party MSC may well be able to handle a TCH/H TCH/F - * mismatch. Moreover, this option may be overwritten in the - * config file or in VTY. - */ - msc_network->dyn_ts_allow_tch_f = false; - - rc = vty_read_config_file(msc_cmdline_config.config_file, NULL); - if (rc < 0) { - LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", - msc_cmdline_config.config_file); - return 1; - } - - /* Initialize MNCC socket if appropriate */ - if (msc_cmdline_config.mncc_sock_path) { - rc = mncc_sock_init(msc_network, - msc_cmdline_config.mncc_sock_path); - if (rc) { - fprintf(stderr, "MNCC socket initialization failed. exiting.\n"); - exit(1); - } - } else - DEBUGP(DMNCC, "Using internal MNCC handler.\n"); - - /* start telnet after reading config for vty_get_bind_addr() */ - rc = telnet_init_dynif(tall_msc_ctx, &msc_network, - vty_get_bind_addr(), OSMO_VTY_PORT_MSC); - if (rc < 0) - return 2; - - /* BSC stuff is to be split behind an A-interface to be used with - * OsmoBSC, but there is no need to remove it yet. Most of the - * following code until iu_init() is legacy. */ - -#ifdef BUILD_SMPP - smpp_openbsc_start(msc_network); -#endif - - /* start control interface after reading config for - * ctrl_vty_get_bind_addr() */ - msc_network->ctrl = ctrl_interface_setup_dynip(msc_network, ctrl_vty_get_bind_addr(), - OSMO_CTRL_PORT_MSC, NULL); - if (!msc_network->ctrl) { - printf("Failed to initialize control interface. Exiting.\n"); - return -1; - } - -#if 0 -TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_install(). - if (bsc_base_ctrl_cmds_install() != 0) { - printf("Failed to initialize the BSC control commands.\n"); - return -1; - } -#endif - - if (msc_ctrl_cmds_install(msc_network) != 0) { - printf("Failed to initialize the MSC control commands.\n"); - return -1; - } - - /* seed the PRNG */ - srand(time(NULL)); - /* TODO: is this used for crypto?? Improve randomness, at least we - * should try to use the nanoseconds part of the current time. */ - - if (db_init(msc_cmdline_config.database_name)) { - printf("DB: Failed to init database: %s\n", - msc_cmdline_config.database_name); - return 4; - } - - osmo_fsm_log_addr(true); - if (msc_vlr_start(msc_network)) { - fprintf(stderr, "Failed to start VLR\n"); - exit(1); - } - - msc_subscr_conn_init(); - - if (db_prepare()) { - printf("DB: Failed to prepare database.\n"); - return 5; - } - - /* setup the timer */ - osmo_timer_setup(&db_sync_timer, db_sync_timer_cb, NULL); - if (msc_cmdline_config.use_db_counter) - osmo_timer_schedule(&db_sync_timer, DB_SYNC_INTERVAL); - - signal(SIGINT, &signal_handler); - signal(SIGTERM, &signal_handler); - signal(SIGABRT, &signal_handler); - signal(SIGUSR1, &signal_handler); - signal(SIGUSR2, &signal_handler); - osmo_init_ignore_signals(); - - /* start the SMS queue */ - if (sms_queue_start(msc_network, 20) != 0) - return -1; - - msc_network->mgcpgw.client = mgcpgw_client_init( - msc_network, &msc_network->mgcpgw.conf); - - if (mgcpgw_client_connect(msc_network->mgcpgw.client)) { - printf("MGCPGW connect failed\n"); - return 7; - } - - if (ss7_setup(tall_msc_ctx)) { - printf("Setting up SCCP client failed.\n"); - return 8; - } - -#ifdef BUILD_IU - /* Set up IuCS */ - ranap_iu_init(tall_msc_ctx, DRANAP, "OsmoMSC-IuCS", msc_network->iu.sccp, rcvmsg_iu_cs, rx_iu_event); -#endif - - /* Set up A interface */ - a_init(msc_network->a.sccp, msc_network); - - if (msc_cmdline_config.daemonize) { - rc = osmo_daemonize(); - if (rc < 0) { - perror("Error during daemonize"); - return 6; - } - } - - while (1) { - log_reset_context(); - osmo_select_main(0); - } -} diff --git a/tests/Makefile.am b/tests/Makefile.am index 7e17ad8de..fc7fc570d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,14 +1,10 @@ SUBDIRS = \ gsm0408 \ channel \ - gprs \ abis \ - gbproxy \ trau \ subscr \ nanobts_omlattr \ - sms_queue \ - msc_vlr \ $(NULL) if BUILD_NAT @@ -22,27 +18,6 @@ SUBDIRS += \ bsc \ $(NULL) endif -if BUILD_SMPP -SUBDIRS += \ - smpp \ - $(NULL) -endif -if HAVE_LIBGTP -SUBDIRS += \ - gtphub \ - $(NULL) - -if HAVE_LIBCARES -SUBDIRS += \ - sgsn \ - oap \ - xid \ - sndcp_xid \ - slhc \ - v42bis \ - $(NULL) -endif -endif # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac @@ -68,7 +43,6 @@ EXTRA_DIST = \ $(TESTSUITE) \ vty_test_runner.py \ ctrl_test_runner.py \ - smpp_test_runner.py \ $(NULL) TESTSUITE = $(srcdir)/testsuite @@ -83,9 +57,6 @@ python-tests: $(BUILT_SOURCES) osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v $(PYTHON) $(srcdir)/vty_test_runner.py -w $(abs_top_builddir) -v $(PYTHON) $(srcdir)/ctrl_test_runner.py -w $(abs_top_builddir) -v -if BUILD_SMPP - $(PYTHON) $(srcdir)/smpp_test_runner.py -w $(abs_top_builddir) -v -endif rm -f $(top_builddir)/sms.db $(top_builddir)/gsn_restart $(top_builddir)/gtphub_restart_count else python-tests: $(BUILT_SOURCES) diff --git a/tests/channel/Makefile.am b/tests/channel/Makefile.am index dd78bdcf9..d190cbaa9 100644 --- a/tests/channel/Makefile.am +++ b/tests/channel/Makefile.am @@ -25,7 +25,6 @@ channel_test_SOURCES = \ channel_test_LDADD = \ $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libvlr/libvlr.a \ $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOCORE_LIBS) \ diff --git a/tests/channel/channel_test.c b/tests/channel/channel_test.c index beae658e9..e66bed3b1 100644 --- a/tests/channel/channel_test.c +++ b/tests/channel/channel_test.c @@ -29,7 +29,6 @@ #include #include #include -#include void test_bts_debug_print(void) { diff --git a/tests/db/Makefile.am b/tests/db/Makefile.am deleted file mode 100644 index bcb66ec32..000000000 --- a/tests/db/Makefile.am +++ /dev/null @@ -1,47 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(LIBSMPP34_CFLAGS) \ - $(COVERAGE_CFLAGS) \ - $(NULL) - -AM_LDFLAGS = \ - $(COVERAGE_LDFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - db_test.ok \ - db_test.err \ - hlr.sqlite3 \ - $(NULL) - -noinst_PROGRAMS = \ - db_test \ - $(NULL) - -db_test_SOURCES = \ - db_test.c \ - $(NULL) - -db_test_LDADD = \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/tests/libiudummy/libiudummy.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBSMPP34_LIBS) \ - $(LIBOSMOVTY_LIBS) \ - $(LIBCRYPTO_LIBS) \ - -ldbi \ - $(NULL) diff --git a/tests/db/db_test.c b/tests/db/db_test.c deleted file mode 100644 index a0c1e79c3..000000000 --- a/tests/db/db_test.c +++ /dev/null @@ -1,286 +0,0 @@ -/* (C) 2008 by Jan Luebbe - * (C) 2009-2016 by Holger Hans Peter Freyther - * (C) 2014 by Alexander Chemeris - * All Rights Reserved - * - * 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 . - * - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -static struct gsm_network dummy_net; -static struct gsm_subscriber_group dummy_sgrp; - -#define SUBSCR_PUT(sub) \ - sub->group = &dummy_sgrp; \ - subscr_put(sub); - -#define COMPARE(original, copy) \ - if (original->id != copy->id) \ - printf("Ids do not match in %s:%d %llu %llu\n", \ - __FUNCTION__, __LINE__, original->id, copy->id); \ - if (original->lac != copy->lac) \ - printf("LAC do not match in %s:%d %d %d\n", \ - __FUNCTION__, __LINE__, original->lac, copy->lac); \ - if (original->authorized != copy->authorized) \ - printf("Authorize do not match in %s:%d %d %d\n", \ - __FUNCTION__, __LINE__, original->authorized, \ - copy->authorized); \ - if (strcmp(original->imsi, copy->imsi) != 0) \ - printf("IMSIs do not match in %s:%d '%s' '%s'\n", \ - __FUNCTION__, __LINE__, original->imsi, copy->imsi); \ - if (original->tmsi != copy->tmsi) \ - printf("TMSIs do not match in %s:%d '%u' '%u'\n", \ - __FUNCTION__, __LINE__, original->tmsi, copy->tmsi); \ - if (strcmp(original->name, copy->name) != 0) \ - printf("names do not match in %s:%d '%s' '%s'\n", \ - __FUNCTION__, __LINE__, original->name, copy->name); \ - if (strcmp(original->extension, copy->extension) != 0) \ - printf("Extensions do not match in %s:%d '%s' '%s'\n", \ - __FUNCTION__, __LINE__, original->extension, copy->extension); \ - -/* - * Create/Store a SMS and then try to load it. - */ -static void test_sms(void) -{ - int rc; - struct gsm_sms *sms; - struct gsm_subscriber *subscr; - subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "9993245423445"); - OSMO_ASSERT(subscr); - subscr->group = &dummy_sgrp; - - sms = sms_alloc(); - sms->receiver = subscr_get(subscr); - - sms->src.ton = 0x23; - sms->src.npi = 0x24; - memcpy(sms->src.addr, "1234", strlen("1234") + 1); - - sms->dst.ton = 0x32; - sms->dst.npi = 0x42; - memcpy(sms->dst.addr, subscr->extension, sizeof(subscr->extension)); - - memcpy(sms->text, "Text123", strlen("Text123") + 1); - memcpy(sms->user_data, "UserData123", strlen("UserData123") + 1); - sms->user_data_len = strlen("UserData123"); - - /* random values */ - sms->reply_path_req = 1; - sms->status_rep_req = 2; - sms->ud_hdr_ind = 3; - sms->protocol_id = 4; - sms->data_coding_scheme = 5; - - rc = db_sms_store(sms); - sms_free(sms); - OSMO_ASSERT(rc == 0); - - /* now query */ - sms = db_sms_get_unsent_for_subscr(subscr); - OSMO_ASSERT(sms); - OSMO_ASSERT(sms->receiver == subscr); - OSMO_ASSERT(sms->reply_path_req == 1); - OSMO_ASSERT(sms->status_rep_req == 2); - OSMO_ASSERT(sms->ud_hdr_ind == 3); - OSMO_ASSERT(sms->protocol_id == 4); - OSMO_ASSERT(sms->data_coding_scheme == 5); - OSMO_ASSERT(sms->src.ton == 0x23); - OSMO_ASSERT(sms->src.npi == 0x24); - OSMO_ASSERT(sms->dst.ton == 0x32); - OSMO_ASSERT(sms->dst.npi == 0x42); - OSMO_ASSERT(strcmp((char *) sms->text, "Text123") == 0); - OSMO_ASSERT(sms->user_data_len == strlen("UserData123")); - OSMO_ASSERT(strcmp((char *) sms->user_data, "UserData123") == 0); - - /* Mark the SMS as delivered */ - db_sms_mark_delivered(sms); - sms_free(sms); - - sms = db_sms_get_unsent_for_subscr(subscr); - OSMO_ASSERT(!sms); - - subscr_put(subscr); -} - -static void test_sms_migrate(void) -{ - struct gsm_subscriber *rcv_subscr; - struct gsm_sms *sms; - static const uint8_t user_data_1[] = { - 0x41, 0xf1, 0xd8, 0x05, 0x22, 0x96, 0xcd, 0x2e, - 0x90, 0xf1, 0xfd, 0x06, 0x00 }; - static const uint8_t user_data_2[] = { - 0x41, 0xf1, 0xd8, 0x05, 0x22, 0x96, 0xcd, 0x2e, - 0xd0, 0xf1, 0xfd, 0x06, 0x00 }; - - rcv_subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "901010000001111"); - rcv_subscr->group = &dummy_sgrp; - - sms = db_sms_get(&dummy_net, 1); - OSMO_ASSERT(sms->id == 1); - OSMO_ASSERT(sms->receiver == rcv_subscr); - OSMO_ASSERT(strcmp(sms->text, "Abc. Def. Foo") == 0); - OSMO_ASSERT(sms->user_data_len == ARRAY_SIZE(user_data_1)); - OSMO_ASSERT(memcmp(sms->user_data, user_data_1, ARRAY_SIZE(user_data_1)) == 0); - sms_free(sms); - - sms = db_sms_get(&dummy_net, 2); - OSMO_ASSERT(sms->id == 2); - OSMO_ASSERT(sms->receiver == rcv_subscr); - OSMO_ASSERT(strcmp(sms->text, "Abc. Def. Goo") == 0); - OSMO_ASSERT(sms->user_data_len == ARRAY_SIZE(user_data_2)); - OSMO_ASSERT(memcmp(sms->user_data, user_data_2, ARRAY_SIZE(user_data_2)) == 0); - sms_free(sms); - - subscr_put(rcv_subscr); -} - -static void test_subs(const char *imsi, char *imei1, char *imei2, bool make_ext) -{ - struct gsm_subscriber *alice = NULL, *alice_db; - char scratch_str[256]; - - alice = db_create_subscriber(imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN, - make_ext); - db_subscriber_assoc_imei(alice, imei1); - if (imei2) - db_subscriber_assoc_imei(alice, imei2); - db_subscriber_alloc_tmsi(alice); - alice->lac=42; - db_sync_subscriber(alice); - /* Get by TMSI */ - snprintf(scratch_str, sizeof(scratch_str), "%"PRIu32, alice->tmsi); - alice_db = db_get_subscriber(GSM_SUBSCRIBER_TMSI, scratch_str); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - /* Get by IMSI */ - alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, imsi); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - /* Get by id */ - snprintf(scratch_str, sizeof(scratch_str), "%llu", alice->id); - alice_db = db_get_subscriber(GSM_SUBSCRIBER_ID, scratch_str); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - /* Get by extension */ - alice_db = db_get_subscriber(GSM_SUBSCRIBER_EXTENSION, alice->extension); - if (alice_db) { - if (!make_ext) - printf("FAIL: bogus extension created for IMSI %s\n", - imsi); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - } else if (make_ext) - printf("FAIL: no subscriber extension for IMSI %s\n", imsi); - SUBSCR_PUT(alice); -} - -int main() -{ - printf("Testing subscriber database code.\n"); - osmo_init_logging(&log_info); - log_set_print_filename(osmo_stderr_target, 0); - - dummy_net.subscr_group = &dummy_sgrp; - dummy_sgrp.net = &dummy_net; - - if (db_init("hlr.sqlite3")) { - printf("DB: Failed to init database. Please check the option settings.\n"); - return 1; - } - printf("DB: Database initialized.\n"); - - if (db_prepare()) { - printf("DB: Failed to prepare database.\n"); - return 1; - } - printf("DB: Database prepared.\n"); - - struct gsm_subscriber *alice = NULL; - struct gsm_subscriber *alice_db; - - char *alice_imsi = "3243245432345"; - alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN, - true); - db_sync_subscriber(alice); - alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice->imsi); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - SUBSCR_PUT(alice); - - test_subs("3693245423445", "1234567890", NULL, true); - test_subs("9993245423445", "1234567890", "6543560920", true); - test_subs("3123122223445", "1234567890", NULL, false); - test_subs("9123121223445", "1234567890", "6543560920", false); - - /* create it again and see it fails */ - alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN, - true); - OSMO_ASSERT(!alice); - - test_sms(); - test_sms_migrate(); - - db_fini(); - - printf("Done\n"); - return 0; -} - -/* stubs */ -void vty_out() {} -void vlr_subscr_disconnected() {} -void vlr_subscr_rx_tmsi_reall_compl() {} -void vlr_subscr_rx_id_resp() {} -void vlr_subscr_rx_auth_resp() {} -void vlr_loc_update() {} -void vlr_proc_acc_req() {} -void vlr_init() {} -unsigned int mgcpgw_client_next_endpoint(struct mgcpgw_client *client) -{ return 0; } -struct msgb *mgcp_msg_crcx(struct mgcpgw_client *mgcp, - uint16_t rtp_endpoint, unsigned int call_id, - enum mgcp_connection_mode mode) -{ return NULL; } -struct msgb *mgcp_msg_mdcx(struct mgcpgw_client *mgcp, - uint16_t rtp_endpoint, const char *rtp_conn_addr, - uint16_t rtp_port, enum mgcp_connection_mode mode) -{ return NULL; } -int mgcpgw_client_tx(struct mgcpgw_client *mgcp, struct msgb *msg, - mgcp_response_cb_t response_cb, void *priv) -{ return -EINVAL; } -const char *mgcpgw_client_remote_addr_str(struct mgcpgw_client *mgcp) -{ return "0.0.0.0"; } -uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp) -{ return 0; } -int mgcp_response_parse_params(struct mgcp_response *r) -{ return -EINVAL; } -struct RANAP_Cause; -int iu_tx_release(struct ue_conn_ctx *ctx, const struct RANAP_Cause *cause) -{ return 0; } diff --git a/tests/db/db_test.err b/tests/db/db_test.err deleted file mode 100644 index 27e570372..000000000 --- a/tests/db/db_test.err +++ /dev/null @@ -1,3 +0,0 @@ -Going to migrate from revision 3 -Going to migrate from revision 4 - \ No newline at end of file diff --git a/tests/db/db_test.ok b/tests/db/db_test.ok deleted file mode 100644 index 2632a8c8a..000000000 --- a/tests/db/db_test.ok +++ /dev/null @@ -1,4 +0,0 @@ -Testing subscriber database code. -DB: Database initialized. -DB: Database prepared. -Done diff --git a/tests/db/hlr.sqlite3 b/tests/db/hlr.sqlite3 deleted file mode 100644 index e59dcdca3..000000000 Binary files a/tests/db/hlr.sqlite3 and /dev/null differ diff --git a/tests/gbproxy/Makefile.am b/tests/gbproxy/Makefile.am deleted file mode 100644 index 2dd66dfd4..000000000 --- a/tests/gbproxy/Makefile.am +++ /dev/null @@ -1,54 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(NULL) - -AM_LDFLAGS = \ - $(COVERAGE_LDFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - gbproxy_test.ok \ - $(NULL) - -noinst_PROGRAMS = \ - gbproxy_test \ - $(NULL) - -gbproxy_test_SOURCES = \ - gbproxy_test.c \ - $(NULL) - -gbproxy_test_LDFLAGS = \ - -Wl,--wrap=RAND_bytes \ - $(NULL) - -gbproxy_test_LDADD = \ - $(top_builddir)/src/gprs/gb_proxy.o \ - $(top_builddir)/src/gprs/gb_proxy_patch.o \ - $(top_builddir)/src/gprs/gb_proxy_peer.o \ - $(top_builddir)/src/gprs/gb_proxy_tlli.o \ - $(top_builddir)/src/gprs/gprs_gb_parse.o \ - $(top_builddir)/src/gprs/gprs_llc_parse.o \ - $(top_builddir)/src/gprs/crc24.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGB_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) \ - $(LIBRARY_DL) \ - $(LIBCRYPTO_LIBS) \ - -lrt \ - $(NULL) diff --git a/tests/gbproxy/gbproxy_test.c b/tests/gbproxy/gbproxy_test.c deleted file mode 100644 index 577daa95e..000000000 --- a/tests/gbproxy/gbproxy_test.c +++ /dev/null @@ -1,4971 +0,0 @@ -/* test routines for gbproxy - * send NS messages to the gbproxy and dumps what happens - * (C) 2013 by sysmocom s.f.m.c. GmbH - * Author: Jacob Erlbeck - */ - -#undef _GNU_SOURCE -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#define REMOTE_BSS_ADDR 0x01020304 -#define REMOTE_SGSN_ADDR 0x05060708 - -#define SGSN_NSEI 0x0100 - -#define REMOTE_SGSN2_ADDR 0x15161718 -#define SGSN2_NSEI 0x0102 - -#define MATCH_ANY (-1) - -struct gbproxy_config gbcfg = {0}; - -struct llist_head *received_messages = NULL; - -/* override, requires '-Wl,--wrap=RAND_bytes' */ -int __real_RAND_bytes(unsigned char *buf, int num); -int mock_RAND_bytes(unsigned char *buf, int num); -int (*RAND_bytes_cb)(unsigned char *, int) = - &mock_RAND_bytes; - -int __wrap_RAND_bytes(unsigned char *buf, int num) -{ - return (*RAND_bytes_cb)(buf, num); -} - -static int rand_seq_num = 0; -int mock_RAND_bytes(unsigned char *buf, int num) -{ - uint32_t val; - - OSMO_ASSERT(num == sizeof(val)); - OSMO_ASSERT(__real_RAND_bytes(buf, num) == 1); - - val = 0x00dead00 + rand_seq_num; - - rand_seq_num++; - - memcpy(buf, &val, num); - - return 1; -} - -static void cleanup_test() -{ - rand_seq_num = 0; -} - -static int dump_global(FILE *stream, int indent) -{ - unsigned int i; - const struct rate_ctr_group_desc *desc; - int rc; - - rc = fprintf(stream, "%*sGbproxy global:\n", indent, ""); - if (rc < 0) - return rc; - - desc = gbcfg.ctrg->desc; - - for (i = 0; i < desc->num_ctr; i++) { - struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i]; - if (ctr->current) { - rc = fprintf(stream, "%*s %s: %llu\n", - indent, "", - desc->ctr_desc[i].description, - (long long)ctr->current); - - if (rc < 0) - return rc; - } - } - - return 0; -} - -static int dump_peers(FILE *stream, int indent, time_t now, - struct gbproxy_config *cfg) -{ - struct gbproxy_peer *peer; - struct gprs_ra_id raid; - unsigned int i; - const struct rate_ctr_group_desc *desc; - int rc; - - rc = fprintf(stream, "%*sPeers:\n", indent, ""); - if (rc < 0) - return rc; - - llist_for_each_entry(peer, &cfg->bts_peers, list) { - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - gsm48_parse_ra(&raid, peer->ra); - - rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, " - "RAI %u-%u-%u-%u\n", - indent, "", - peer->nsei, peer->bvci, - peer->blocked ? "" : "not ", - raid.mcc, raid.mnc, raid.lac, raid.rac); - - if (rc < 0) - return rc; - - desc = peer->ctrg->desc; - - for (i = 0; i < desc->num_ctr; i++) { - struct rate_ctr *ctr = &peer->ctrg->ctr[i]; - if (ctr->current) { - rc = fprintf(stream, "%*s %s: %llu\n", - indent, "", - desc->ctr_desc[i].description, - (long long)ctr->current); - - if (rc < 0) - return rc; - } - } - - fprintf(stream, "%*s TLLI-Cache: %d\n", - indent, "", state->logical_link_count); - llist_for_each_entry(link_info, &state->logical_links, list) { - char mi_buf[200]; - time_t age = now ? now - link_info->timestamp : 0; - int stored_msgs = 0; - struct llist_head *iter; - enum gbproxy_match_id match_id; - llist_for_each(iter, &link_info->stored_msgs) - stored_msgs++; - - if (link_info->imsi_len > 0) { - snprintf(mi_buf, sizeof(mi_buf), "(invalid)"); - gsm48_mi_to_string(mi_buf, sizeof(mi_buf), - link_info->imsi, - link_info->imsi_len); - } else { - snprintf(mi_buf, sizeof(mi_buf), "(none)"); - } - fprintf(stream, "%*s TLLI %08x", - indent, "", link_info->tlli.current); - if (link_info->tlli.assigned) - fprintf(stream, "/%08x", link_info->tlli.assigned); - if (link_info->sgsn_tlli.current) { - fprintf(stream, " -> %08x", - link_info->sgsn_tlli.current); - if (link_info->sgsn_tlli.assigned) - fprintf(stream, "/%08x", - link_info->sgsn_tlli.assigned); - } - fprintf(stream, ", IMSI %s, AGE %d", - mi_buf, (int)age); - - if (stored_msgs) - fprintf(stream, ", STORED %d", stored_msgs); - - for (match_id = 0; match_id < ARRAY_SIZE(cfg->matches); - ++match_id) { - if (cfg->matches[match_id].enable && - link_info->is_matching[match_id]) { - fprintf(stream, ", IMSI matches"); - break; - } - } - - if (link_info->imsi_acq_pending) - fprintf(stream, ", IMSI acquisition in progress"); - - if (cfg->route_to_sgsn2) - fprintf(stream, ", SGSN NSEI %d", - link_info->sgsn_nsei); - - if (link_info->is_deregistered) - fprintf(stream, ", DE-REGISTERED"); - - rc = fprintf(stream, "\n"); - if (rc < 0) - return rc; - } - } - - return 0; -} - -const uint8_t *convert_ra(struct gprs_ra_id *raid) -{ - static uint8_t buf[6]; - gsm48_construct_ra(buf, raid); - return buf; -} - -/* DTAP - Attach Request */ -static const unsigned char dtap_attach_req[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, - 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, - 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, - 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8, - 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, -}; - -/* DTAP - Attach Request (invalid RAI) */ -static const unsigned char dtap_attach_req2[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99, - 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, - 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, - 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8, - 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, -}; - -/* DTAP - Attach Request (P-TMSI 0x3f32b700) */ -static const unsigned char dtap_attach_req3[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22, - 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, - 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, - 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8, - 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, -}; - -/* DTAP - Attach Request (IMSI 12131415161718) */ -static const unsigned char dtap_attach_req4[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19, - 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, - 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, - 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, - 0x00, -}; - -/* DTAP - Identity Request */ -static const unsigned char dtap_identity_req[] = { - 0x08, 0x15, 0x01 -}; - -/* DTAP - Identity Response */ -static const unsigned char dtap_identity_resp[] = { - 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18 -}; - -/* DTAP - Identity Response, IMSI 2 */ -static const unsigned char dtap_identity2_resp[] = { - 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99, - 0x16, 0x17, 0x18 -}; - -/* DTAP - Identity Response, IMSI 3 */ -static const unsigned char dtap_identity3_resp[] = { - 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99, - 0x26, 0x27, 0x28 -}; - -/* DTAP - Attach Accept */ -static const unsigned char dtap_attach_acc[] = { - 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17, - 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00 -}; - -/* DTAP - Attach Accept, P-TMSI 2 */ -static const unsigned char dtap_attach_acc2[] = { - 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17, - 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54 -}; - -/* DTAP - Attach Complete */ -static const unsigned char dtap_attach_complete[] = { - 0x08, 0x03 -}; - -/* DTAP - Attach Reject (GPRS services not allowed) */ -static const unsigned char dtap_attach_rej7[] = { - 0x08, 0x04, 0x07 -}; - -/* DTAP - GMM Information */ -static const unsigned char dtap_gmm_information[] = { - 0x08, 0x21 -}; - -/* DTAP - Routing Area Update Request */ -static const unsigned char dtap_ra_upd_req[] = { - 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, - 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, - 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, - 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, - 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, - 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, - 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 -}; - -/* DTAP - Routing Area Update Accept */ -static const unsigned char dtap_ra_upd_acc[] = { - 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18, - 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16, -}; - -/* DTAP - Routing Area Update Accept, P-TMSI 2 */ -static const unsigned char dtap_ra_upd_acc2[] = { - 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18, - 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16, -}; - -/* DTAP - Routing Area Update Accept, P-TMSI 3 */ -static const unsigned char dtap_ra_upd_acc3[] = { - 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18, - 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16, -}; - -/* DTAP - Routing Area Update Complete */ -static const unsigned char dtap_ra_upd_complete[] = { - 0x08, 0x0a -}; - -/* DTAP - Routing Area Update Reject */ -/* cause = 10 ("Implicitly detached"), force_standby = 0 */ -static const unsigned char dtap_ra_upd_rej[] = { - 0x08, 0x0b, 0x0a, 0x00, -}; - -/* DTAP - Activate PDP Context Request */ -static const unsigned char dtap_act_pdp_ctx_req[] = { - 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00, - 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03, - 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21, - 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00, - 0x00 -}; - -/* DTAP - Detach Request (MO) */ -/* normal detach, power_off = 1 */ -static const unsigned char dtap_detach_po_req[] = { - 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2, - 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb -}; - -/* DTAP - Detach Request (MO) */ -/* normal detach, power_off = 0 */ -static const unsigned char dtap_detach_req[] = { - 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2, - 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb -}; - -/* DTAP - Detach Accept (MO) */ -static const unsigned char dtap_detach_acc[] = { - 0x08, 0x06, 0x00 -}; - -/* DTAP - Detach Request (MT) */ -/* normal detach, reattach required, implicitly detached */ -static const unsigned char dtap_mt_detach_rea_req[] = { - 0x08, 0x05, 0x01, 0x25, 0x0a -}; - -/* DTAP - Detach Request (MT) */ -/* normal detach, reattach not required, implicitly detached */ -static const unsigned char dtap_mt_detach_req[] = { - 0x08, 0x05, 0x02, 0x25, 0x0a -}; - -/* DTAP - Detach Accept (MT) */ -static const unsigned char dtap_mt_detach_acc[] = { - 0x08, 0x06 -}; - -/* GPRS-LLC - SAPI: LLGMM, U, XID */ -static const unsigned char llc_u_xid_ul[] = { - 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11, - 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28 -}; - -/* GPRS-LLC - SAPI: LLGMM, U, XID */ -static const unsigned char llc_u_xid_dl[] = { - 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64, - 0xe4, 0xa9, 0x1a, 0x9e -}; - -/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */ -static const unsigned char llc_ui_ll11_dns_query_ul[] = { - 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45, - 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45, - 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac, - 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00, - 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02, - 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47, - 0x8f, 0x07 -}; - -/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */ -static const unsigned char llc_ui_ll11_dns_resp_dl[] = { - 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e, - 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a, - 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00, - 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01, - 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02, - 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, - 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, - 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0, - 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, - 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c, - 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, - 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74, - 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73, - 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c, - 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, - 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e, - 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, - 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0, - 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, - 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70, - 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f, - 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31 -}; - -static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *peer, const unsigned char* data, - size_t data_len); - -static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - enum ns_cause cause, uint16_t nsvci, uint16_t nsei) -{ - /* GPRS Network Service, PDU type: NS_RESET, - */ - unsigned char msg[12] = { - 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22, - 0x04, 0x82, 0x11, 0x22 - }; - - msg[3] = cause; - msg[6] = nsvci / 256; - msg[7] = nsvci % 256; - msg[10] = nsei / 256; - msg[11] = nsei % 256; - - gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg)); -} - -static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - uint16_t nsvci, uint16_t nsei) -{ - /* GPRS Network Service, PDU type: NS_RESET_ACK, - */ - unsigned char msg[9] = { - 0x03, 0x01, 0x82, 0x11, 0x22, - 0x04, 0x82, 0x11, 0x22 - }; - - msg[3] = nsvci / 256; - msg[4] = nsvci % 256; - msg[7] = nsei / 256; - msg[8] = nsei % 256; - - gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg)); -} - -static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr) -{ - /* GPRS Network Service, PDU type: NS_ALIVE */ - unsigned char msg[1] = { - 0x0a - }; - - gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg)); -} - -static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr) -{ - /* GPRS Network Service, PDU type: NS_ALIVE_ACK */ - unsigned char msg[1] = { - 0x0b - }; - - gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg)); -} - -static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr) -{ - /* GPRS Network Service, PDU type: NS_UNBLOCK */ - unsigned char msg[1] = { - 0x06 - }; - - gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg)); -} - -static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr) -{ - /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */ - unsigned char msg[1] = { - 0x07 - }; - - gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg)); -} - -static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, - const unsigned char *bssgp_msg, size_t bssgp_msg_size) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA */ - unsigned char msg[4096] = { - 0x00, 0x00, 0x00, 0x00 - }; - - OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4); - - msg[2] = nsbvci / 256; - msg[3] = nsbvci % 256; - memcpy(msg + 4, bssgp_msg, bssgp_msg_size); - - gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4); -} - -static void send_bssgp_ul_unitdata( - struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli, - struct gprs_ra_id *raid, uint16_t cell_id, - const uint8_t *llc_msg, size_t llc_msg_size) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA */ - /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */ - unsigned char msg[4096] = { - 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, - /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00, - }; - - size_t bssgp_msg_size = 23 + llc_msg_size; - - OSMO_ASSERT(bssgp_msg_size <= sizeof(msg)); - - gsm48_construct_ra(msg + 10, raid); - msg[1] = (uint8_t)(tlli >> 24); - msg[2] = (uint8_t)(tlli >> 16); - msg[3] = (uint8_t)(tlli >> 8); - msg[4] = (uint8_t)(tlli >> 0); - msg[16] = cell_id / 256; - msg[17] = cell_id % 256; - msg[21] = llc_msg_size / 256; - msg[22] = llc_msg_size % 256; - memcpy(msg + 23, llc_msg, llc_msg_size); - - send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA", - src_addr, nsbvci, msg, bssgp_msg_size); -} - -static void send_bssgp_dl_unitdata( - struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli, - int with_racap_drx, const uint8_t *imsi, size_t imsi_size, - const uint8_t *llc_msg, size_t llc_msg_size) -{ - /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */ - unsigned char msg[4096] = { - 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20, - 0x16, 0x82, 0x02, 0x58, - }; - unsigned char racap_drx[] = { - 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, - 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, - 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, - 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02 - }; - - size_t bssgp_msg_size = 0; - - OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg)); - - msg[1] = (uint8_t)(tlli >> 24); - msg[2] = (uint8_t)(tlli >> 16); - msg[3] = (uint8_t)(tlli >> 8); - msg[4] = (uint8_t)(tlli >> 0); - - bssgp_msg_size = 12; - - if (with_racap_drx) { - memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx)); - bssgp_msg_size += sizeof(racap_drx); - } - - if (imsi) { - OSMO_ASSERT(imsi_size <= 127); - msg[bssgp_msg_size] = BSSGP_IE_IMSI; - msg[bssgp_msg_size + 1] = 0x80 | imsi_size; - memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size); - bssgp_msg_size += 2 + imsi_size; - } - - if ((bssgp_msg_size % 4) != 0) { - size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4; - msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT; - msg[bssgp_msg_size + 1] = 0x80 | abytes; - memset(msg + bssgp_msg_size + 2, 0, abytes); - bssgp_msg_size += 2 + abytes; - } - - msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU; - if (llc_msg_size < 128) { - msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size; - bssgp_msg_size += 2; - } else { - msg[bssgp_msg_size + 1] = llc_msg_size / 256; - msg[bssgp_msg_size + 2] = llc_msg_size % 256; - bssgp_msg_size += 3; - } - memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size); - bssgp_msg_size += llc_msg_size; - - - send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA", - src_addr, nsbvci, msg, bssgp_msg_size); -} - -static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - uint16_t bvci) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0 - * BSSGP RESET */ - unsigned char msg[18] = { - 0x22, 0x04, 0x82, 0x4a, - 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22, - 0x33, 0x40, 0x50, 0x60, 0x10, 0x00 - }; - - msg[3] = bvci / 256; - msg[4] = bvci % 256; - - send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, uint16_t bvci) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0 - * BSSGP RESET_ACK */ - static unsigned char msg[5] = { - 0x23, 0x04, 0x82, 0x00, - 0x00 - }; - - msg[3] = bvci / 256; - msg[4] = bvci % 256; - - send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_suspend(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint32_t tlli, - struct gprs_ra_id *raid) -{ - /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */ - unsigned char msg[15] = { - 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b, - 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }; - - msg[3] = (uint8_t)(tlli >> 24); - msg[4] = (uint8_t)(tlli >> 16); - msg[5] = (uint8_t)(tlli >> 8); - msg[6] = (uint8_t)(tlli >> 0); - - gsm48_construct_ra(msg + 9, raid); - - send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint32_t tlli, - struct gprs_ra_id *raid) -{ - /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */ - unsigned char msg[18] = { - 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b, - 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d, - 0x81, 0x01 - }; - - msg[3] = (uint8_t)(tlli >> 24); - msg[4] = (uint8_t)(tlli >> 16); - msg[5] = (uint8_t)(tlli >> 8); - msg[6] = (uint8_t)(tlli >> 0); - - gsm48_construct_ra(msg + 9, raid); - - send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint16_t bvci, uint32_t tlli, - unsigned n_frames, unsigned n_octets) -{ - /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */ - unsigned char msg[] = { - 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f, - 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83, - /* n octets */ 0xff, 0xff, 0xff - }; - - msg[3] = (uint8_t)(tlli >> 24); - msg[4] = (uint8_t)(tlli >> 16); - msg[5] = (uint8_t)(tlli >> 8); - msg[6] = (uint8_t)(tlli >> 0); - msg[9] = (uint8_t)(n_frames); - msg[12] = (uint8_t)(bvci >> 8); - msg[13] = (uint8_t)(bvci >> 0); - msg[16] = (uint8_t)(n_octets >> 16); - msg[17] = (uint8_t)(n_octets >> 8); - msg[18] = (uint8_t)(n_octets >> 0); - - send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_paging(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - const uint8_t *imsi, size_t imsi_size, - struct gprs_ra_id *raid, uint32_t ptmsi) -{ - /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */ - unsigned char msg[100] = { - 0x06, - }; - - const unsigned char drx_ie[] = {0x0a, 0x82, 0x07, 0x04}; - const unsigned char qos_ie[] = {0x18, 0x83, 0x00, 0x00, 0x00}; - - size_t bssgp_msg_size = 1; - - if (imsi) { - OSMO_ASSERT(imsi_size <= 127); - msg[bssgp_msg_size] = BSSGP_IE_IMSI; - msg[bssgp_msg_size + 1] = 0x80 | imsi_size; - memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size); - bssgp_msg_size += 2 + imsi_size; - } - - memcpy(msg + bssgp_msg_size, drx_ie, sizeof(drx_ie)); - bssgp_msg_size += sizeof(drx_ie); - - if (raid) { - msg[bssgp_msg_size] = BSSGP_IE_ROUTEING_AREA; - msg[bssgp_msg_size+1] = 0x86; - gsm48_construct_ra(msg + bssgp_msg_size + 2, raid); - bssgp_msg_size += 8; - } - - memcpy(msg + bssgp_msg_size, qos_ie, sizeof(qos_ie)); - bssgp_msg_size += sizeof(qos_ie); - - if (ptmsi != GSM_RESERVED_TMSI) { - const uint32_t ptmsi_be = htonl(ptmsi); - msg[bssgp_msg_size] = BSSGP_IE_TMSI; - msg[bssgp_msg_size+1] = 0x84; - memcpy(msg + bssgp_msg_size + 2, &ptmsi_be, 4); - bssgp_msg_size += 6; - } - - send_ns_unitdata(nsi, "PAGING_PS", src_addr, 0, msg, bssgp_msg_size); -} - -static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint16_t bvci, uint8_t tag) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA, - * BSSGP FLOW_CONTROL_BVC */ - unsigned char msg[] = { - 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc, - 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50, - 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03 - }; - - msg[3] = tag; - - send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci, - msg, sizeof(msg)); -} - -static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint16_t bvci, uint8_t tag) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA, - * BSSGP FLOW_CONTROL_BVC_ACK */ - unsigned char msg[] = { - 0x27, 0x1e, 0x81, /* Tag */ 0xce - }; - - msg[3] = tag; - - send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci, - msg, sizeof(msg)); -} - -static void send_llc_ul_ui( - struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli, - struct gprs_ra_id *raid, uint16_t cell_id, - unsigned sapi, unsigned nu, - const uint8_t *msg, size_t msg_size) -{ - unsigned char llc_msg[4096] = { - 0x00, 0xc0, 0x01 - }; - - size_t llc_msg_size = 3 + msg_size + 3; - uint8_t e_bit = 0; - uint8_t pm_bit = 1; - unsigned fcs; - - nu &= 0x01ff; - - OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg)); - - llc_msg[0] = (sapi & 0x0f); - llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */ - llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1); - - memcpy(llc_msg + 3, msg, msg_size); - - fcs = gprs_llc_fcs(llc_msg, msg_size + 3); - llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0); - llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8); - llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16); - - send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI", - src_addr, nsbvci, tlli, raid, cell_id, - llc_msg, llc_msg_size); -} - -static void send_llc_dl_ui( - struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli, - int with_racap_drx, const uint8_t *imsi, size_t imsi_size, - unsigned sapi, unsigned nu, - const uint8_t *msg, size_t msg_size) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA */ - /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */ - unsigned char llc_msg[4096] = { - 0x00, 0x00, 0x01 - }; - - size_t llc_msg_size = 3 + msg_size + 3; - uint8_t e_bit = 0; - uint8_t pm_bit = 1; - unsigned fcs; - - nu &= 0x01ff; - - OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg)); - - llc_msg[0] = 0x40 | (sapi & 0x0f); - llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */ - llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1); - - memcpy(llc_msg + 3, msg, msg_size); - - fcs = gprs_llc_fcs(llc_msg, msg_size + 3); - llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0); - llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8); - llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16); - - send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI", - src_addr, nsbvci, tlli, - with_racap_drx, imsi, imsi_size, - llc_msg, llc_msg_size); -} - - -static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - uint16_t nsvci, uint16_t nsei) -{ - printf("Setup NS-VC: remote 0x%08x:%d, " - "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n", - ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port), - nsvci, nsvci, nsei, nsei); - - send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei); - send_ns_alive(nsi, src_addr); - send_ns_unblock(nsi, src_addr); - send_ns_alive_ack(nsi, src_addr); -} - -static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - uint16_t bvci) -{ - printf("Setup BSSGP: remote 0x%08x:%d, " - "BVCI 0x%04x(%d)\n\n", - ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port), - bvci, bvci); - - send_bssgp_reset(nsi, src_addr, bvci); -} - -static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer, - uint32_t sgsn_nsei) -{ - gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1); - send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei); - send_ns_alive_ack(nsi, sgsn_peer); - send_ns_unblock_ack(nsi, sgsn_peer); - send_ns_alive(nsi, sgsn_peer); -} - -static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer) -{ - sgsn_peer->sin_family = AF_INET; - sgsn_peer->sin_port = htons(32000); - sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR); -} - -static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer) -{ - sgsn_peer->sin_family = AF_INET; - sgsn_peer->sin_port = htons(32001); - sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR); -} - -static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size) -{ - size_t i; - - for (i = 0; i < size; ++i) { - bss_peers[i].sin_family = AF_INET; - bss_peers[i].sin_port = htons((i + 1) * 1111); - bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR); - } -} - -int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg, - struct sockaddr_in *saddr, enum gprs_ns_ll ll); - -/* override */ -int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, - struct msgb *msg, uint16_t bvci) -{ - printf("CALLBACK, event %d, msg length %zu, bvci 0x%04x\n%s\n\n", - event, msgb_bssgp_len(msg), bvci, - osmo_hexdump(msgb_l2(msg), msgb_l2len(msg))); - - switch (event) { - case GPRS_NS_EVT_UNIT_DATA: - return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci); - default: - break; - } - return 0; -} - -/* override */ -ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, - const struct sockaddr *dest_addr, socklen_t addrlen) -{ - typedef ssize_t (*sendto_t)(int, const void *, size_t, int, - const struct sockaddr *, socklen_t); - static sendto_t real_sendto = NULL; - uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr); - int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port); - - if (!real_sendto) - real_sendto = dlsym(RTLD_NEXT, "sendto"); - - if (dest_host == REMOTE_BSS_ADDR) - printf("MESSAGE to BSS at 0x%08x:%d, msg length %zu\n%s\n\n", - dest_host, dest_port, - len, osmo_hexdump(buf, len)); - else if (dest_host == REMOTE_SGSN_ADDR) - printf("MESSAGE to SGSN at 0x%08x:%d, msg length %zu\n%s\n\n", - dest_host, dest_port, - len, osmo_hexdump(buf, len)); - else if (dest_host == REMOTE_SGSN2_ADDR) - printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %zu\n%s\n\n", - dest_host, dest_port, - len, osmo_hexdump(buf, len)); - else - return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); - - return len; -} - -/* override */ -int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg) -{ - typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg); - static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL; - uint16_t bvci = msgb_bvci(msg); - uint16_t nsei = msgb_nsei(msg); - - size_t len = msgb_length(msg); - - if (!real_gprs_ns_sendmsg) - real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg"); - - if (nsei == SGSN_NSEI) - printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, " - "msg length %zu (%s)\n", - bvci, len, __func__); - else if (nsei == SGSN2_NSEI) - printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, " - "msg length %zu (%s)\n", - bvci, len, __func__); - else - printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, " - "msg length %zu (%s)\n", - bvci, len, __func__); - - if (received_messages) { - struct msgb *msg_copy; - msg_copy = gprs_msgb_copy(msg, "received_messages"); - llist_add_tail(&msg_copy->list, received_messages); - } - - return real_gprs_ns_sendmsg(nsi, msg); -} - -/* Get the next message from the receive FIFO - * - * \returns a pointer to the message which will be invalidated at the next call - * to expect_msg. Returns NULL, if there is no message left. - */ -static struct msgb *expect_msg(void) -{ - static struct msgb *msg = NULL; - - msgb_free(msg); - msg = NULL; - - if (!received_messages) - return NULL; - - if (llist_empty(received_messages)) - return NULL; - - msg = llist_entry(received_messages->next, struct msgb, list); - llist_del(&msg->list); - - return msg; -} - -struct expect_result { - struct msgb *msg; - struct gprs_gb_parse_context parse_ctx; -}; - -static struct expect_result *expect_bssgp_msg( - int match_nsei, int match_bvci, int match_pdu_type) -{ - static struct expect_result result; - static const struct expect_result empty_result = {0,}; - static struct msgb *msg; - uint16_t nsei; - int rc; - - memcpy(&result, &empty_result, sizeof(result)); - - msg = expect_msg(); - if (!msg) - return NULL; - - nsei = msgb_nsei(msg); - - if (match_nsei != MATCH_ANY && match_nsei != nsei) { - fprintf(stderr, "%s: NSEI mismatch (expected %u, got %u)\n", - __func__, match_nsei, nsei); - return NULL; - } - - if (match_bvci != MATCH_ANY && match_bvci != msgb_bvci(msg)) { - fprintf(stderr, "%s: BVCI mismatch (expected %u, got %u)\n", - __func__, match_bvci, msgb_bvci(msg)); - return NULL; - } - - result.msg = msg; - - result.parse_ctx.to_bss = nsei != SGSN_NSEI && nsei != SGSN2_NSEI; - result.parse_ctx.peer_nsei = nsei; - - if (!msgb_bssgph(msg)) { - fprintf(stderr, "%s: Expected BSSGP\n", __func__); - return NULL; - } - - rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg), - &result.parse_ctx); - - if (!rc) { - fprintf(stderr, "%s: Failed to parse message\n", __func__); - return NULL; - } - - if (match_pdu_type != MATCH_ANY && - match_pdu_type != result.parse_ctx.pdu_type) { - fprintf(stderr, "%s: PDU type mismatch (expected %u, got %u)\n", - __func__, match_pdu_type, result.parse_ctx.pdu_type); - return NULL; - } - - return &result; -} - -static struct expect_result *expect_llc_msg( - int match_nsei, int match_bvci, int match_sapi, int match_type) -{ - static struct expect_result *result; - - result = expect_bssgp_msg(match_nsei, match_bvci, MATCH_ANY); - if (!result) - return NULL; - - if (!result->parse_ctx.llc) { - fprintf(stderr, "%s: Expected LLC message\n", __func__); - return NULL; - } - - if (match_sapi != MATCH_ANY && - match_sapi != result->parse_ctx.llc_hdr_parsed.sapi) { - fprintf(stderr, "%s: LLC SAPI mismatch (expected %u, got %u)\n", - __func__, match_sapi, result->parse_ctx.llc_hdr_parsed.sapi); - return NULL; - } - - if (match_type != MATCH_ANY && - match_type != result->parse_ctx.llc_hdr_parsed.cmd) { - fprintf(stderr, - "%s: LLC command/type mismatch (expected %u, got %u)\n", - __func__, match_type, result->parse_ctx.llc_hdr_parsed.cmd); - return NULL; - } - - return result; -} - -static struct expect_result *expect_gmm_msg(int match_nsei, int match_bvci, - int match_type) -{ - static struct expect_result *result; - - result = expect_llc_msg(match_nsei, match_bvci, GPRS_SAPI_GMM, GPRS_LLC_UI); - if (!result) - return NULL; - - if (!result->parse_ctx.g48_hdr) { - fprintf(stderr, "%s: Expected GSM 04.08 message\n", __func__); - return NULL; - } - - if (match_type != MATCH_ANY && - match_type != result->parse_ctx.g48_hdr->msg_type) { - fprintf(stderr, - "%s: GSM 04.08 message type mismatch (expected %u, got %u)\n", - __func__, match_type, result->parse_ctx.g48_hdr->msg_type); - return NULL; - } - - return result; -} - -static void dump_rate_ctr_group(FILE *stream, const char *prefix, - struct rate_ctr_group *ctrg) -{ - unsigned int i; - - for (i = 0; i < ctrg->desc->num_ctr; i++) { - struct rate_ctr *ctr = &ctrg->ctr[i]; - if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.')) - fprintf(stream, " %s%s: %llu%s", - prefix, ctrg->desc->ctr_desc[i].description, - (long long)ctr->current, - "\n"); - }; -} - -/* Signal handler for signals from NS layer */ -static int test_signal(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct ns_signal_data *nssd = signal_data; - int rc; - - if (subsys != SS_L_NS) - return 0; - - switch (signal) { - case S_NS_RESET: - printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - - case S_NS_ALIVE_EXP: - printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - - case S_NS_BLOCK: - printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - - case S_NS_UNBLOCK: - printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - - case S_NS_REPLACED: - printf("==> got signal NS_REPLACED: 0x%04x/%s", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - printf(" -> 0x%04x/%s\n", - nssd->old_nsvc->nsvci, - gprs_ns_ll_str(nssd->old_nsvc)); - break; - - default: - printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal, - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - } - printf("\n"); - rc = gbprox_signal(subsys, signal, handler_data, signal_data); - return rc; -} - -static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len) -{ - struct msgb *msg; - int ret; - if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) { - fprintf(stderr, "message too long: %zu\n", data_len); - return -1; - } - - msg = gprs_ns_msgb_alloc(); - OSMO_ASSERT(msg); - memmove(msg->data, data, data_len); - msg->l2h = msg->data; - msgb_put(msg, data_len); - - printf("PROCESSING %s from 0x%08x:%d\n%s\n\n", - text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port), - osmo_hexdump(data, data_len)); - - ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP); - - printf("result (%s) = %d\n\n", text, ret); - - msgb_free(msg); - - return ret; -} - -static void gprs_dump_nsi(struct gprs_ns_inst *nsi) -{ - struct gprs_nsvc *nsvc; - - printf("Current NS-VCIs:\n"); - llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) { - struct sockaddr_in *peer = &(nsvc->ip.bts_addr); - printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n", - nsvc->nsvci, nsvc->nsei, - ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port), - nsvc->state & NSE_S_BLOCKED ? ", blocked" : "", - nsvc->state & NSE_S_ALIVE ? "" : ", dead" - ); - dump_rate_ctr_group(stdout, " ", nsvc->ctrg); - } - printf("\n"); -} - -static void test_gbproxy() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[4] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - gprs_dump_nsi(nsi); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - printf("--- Initialise BSS 2 ---\n\n"); - - setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000); - setup_bssgp(nsi, &bss_peer[1], 0x2002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002); - - printf("--- Move BSS 1 to new port ---\n\n"); - - setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 2 to former BSS 1 port ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 1 to current BSS 2 port ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 2 to new port ---\n\n"); - - setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 2 to former BSS 1 port ---\n\n"); - - setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 1 to original BSS 1 port ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Reset BSS 1 with a new BVCI ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], 0x1012); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012); - - printf("--- Reset BSS 1 with the old BVCI ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - printf("--- Reset BSS 1 with the old BVCI again ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0); - - printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n"); - - setup_bssgp(nsi, &bss_peer[2], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0); - - /* Find peer */ - OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL); - OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL); - OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL); - OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL); - OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL); - OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL); - - - /* Cleanup */ - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0); - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0); - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0); - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1); - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; -} - -static void test_gbproxy_ident_changes() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - uint16_t nsei[2] = {0x1000, 0x2000}; - uint16_t nsvci[2] = {0x1001, 0x2001}; - uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002}; - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - gprs_dump_nsi(nsi); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]); - gprs_dump_nsi(nsi); - - printf("--- Setup BVCI 1 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[0]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Setup BVCI 2 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[1]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0); - - printf("--- Change NSEI ---\n\n"); - - setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]); - gprs_dump_nsi(nsi); - - printf("--- Setup BVCI 1 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[0]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Setup BVCI 3 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[2]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 " - " (should fail) ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0); - dump_peers(stdout, 0, 0, &gbcfg); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0); - - printf("--- Change NSVCI ---\n\n"); - - setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]); - gprs_dump_nsi(nsi); - - printf("--- Setup BVCI 1 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[0]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Setup BVCI 4 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[3]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 " - " (should fail) ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0); - dump_peers(stdout, 0, 0, &gbcfg); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0); - - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; -} - -static void test_gbproxy_ra_patching() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_sgsn = - {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x7530; - const char *err_msg = NULL; - const uint32_t ptmsi = 0xefe2b700; - const uint32_t local_tlli = 0xefe2b700; - const uint32_t foreign_tlli = 0xbbc54679; - const uint32_t foreign_tlli2 = 0xbb00beef; - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; - const char *patch_re = "^9898|^121314"; - struct gbproxy_link_info *link_info; - struct gbproxy_peer *peer; - LLIST_HEAD(rcv_list); - struct expect_result *expect_res; - - OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_mcc = 123; - gbcfg.core_mnc = 456; - gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 0; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING], - patch_re, &err_msg) != 0) { - fprintf(stderr, "Failed to compile RE '%s': %s\n", - patch_re, err_msg); - exit(1); - } - - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - gprs_dump_nsi(nsi); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - - received_messages = &rcv_list; - - setup_bssgp(nsi, &bss_peer[0], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_BVC_RESET)); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_BVC_RESET_ACK)); - - send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss); - - OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_SUSPEND)); - - send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn); - - OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_SUSPEND_ACK)); - - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 0, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, 0, - dtap_identity_req, sizeof(dtap_identity_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP)); - - OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 1, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL); - OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL); - OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL); - - OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL); - OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL); - OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL); - - OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL); - OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL); - OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current != local_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 4, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current != local_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - /* Replace APN (1) */ - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ)); - - OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current != local_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 2, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO)); - - OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->tlli.current == local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli); - - /* Replace APN (2) */ - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ); - OSMO_ASSERT(expect_res != NULL); - OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == gbcfg.core_apn_size + 2); - - OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - gbcfg.core_apn[0] = 0; - gbcfg.core_apn_size = 0; - - /* Remove APN */ - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ); - OSMO_ASSERT(expect_res != NULL); - OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0); - - OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 6, - dtap_detach_req, sizeof(dtap_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 5, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- RA update ---\n\n"); - - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, 0x7080, - GPRS_SAPI_GMM, 5, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ)); - - OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 6, - dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_ACK)); - - OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - /* Remove APN */ - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ); - OSMO_ASSERT(expect_res != NULL); - OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0); - - OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (power off -> no Detach Accept) */ - send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 6, - dtap_detach_po_req, sizeof(dtap_detach_po_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Bad cases ---\n\n"); - - /* The RAI in the Attach Request message differs from the RAI in the - * BSSGP message, only patch the latter */ - - send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002, - foreign_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, 0, - dtap_attach_req2, sizeof(dtap_attach_req2)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - printf("TLLI is already detached, shouldn't patch\n"); - send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ)); - - printf("Invalid RAI, shouldn't patch\n"); - send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown); - - /* TODO: The following breaks with the current libosmocore, enable it - * again (and remove the plain expect_msg), when the msgb_bssgph patch - * is integrated */ - /* OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_STATUS)); */ - OSMO_ASSERT(expect_msg()); - - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!expect_msg()); - received_messages = NULL; - - gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING]); - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; -} - -static void test_gbproxy_ptmsi_assignment() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t ptmsi = 0xefe2b700; - const uint32_t local_tlli = 0xefe2b700; - - const uint32_t foreign_tlli1 = 0x8000dead; - const uint32_t foreign_tlli2 = 0x8000beef; - - const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; - const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18}; - - struct gbproxy_link_info *link_info, *link_info2; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_mcc = 0; - gbcfg.core_mnc = 0; - gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 0; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Establish first LLC connection ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli1, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli1, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1); - link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_tlli1); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_tlli1); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2))); - - link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->tlli.current == local_tlli); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - printf("--- Establish second LLC connection with the same P-TMSI ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli2, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli2, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity2_resp, sizeof(dtap_identity2_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli2, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2); - link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_tlli2); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_tlli2); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1))); - - link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->tlli.current == local_tlli); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - dump_global(stdout, 0); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -static void test_gbproxy_ptmsi_patching() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_sgsn = - {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_wrong_mcc_sgsn = - {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t sgsn_ptmsi = 0xefe2b700; - const uint32_t sgsn_ptmsi2 = 0xe0987654; - const uint32_t sgsn_ptmsi3 = 0xe0543210; - const uint32_t local_sgsn_tlli = 0xefe2b700; - const uint32_t local_sgsn_tlli2 = 0xe0987654; - const uint32_t local_sgsn_tlli3 = 0xe0543210; - const uint32_t random_sgsn_tlli = 0x78dead00; - const uint32_t unknown_sgsn_tlli = 0xeebadbad; - - const uint32_t bss_ptmsi = 0xc0dead01; - const uint32_t bss_ptmsi2 = 0xc0dead02; - const uint32_t bss_ptmsi3 = 0xc0dead03; - const uint32_t local_bss_tlli = 0xc0dead01; - const uint32_t local_bss_tlli2 = 0xc0dead02; - const uint32_t local_bss_tlli3 = 0xc0dead03; - const uint32_t foreign_bss_tlli = 0x8000dead; - - - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; - struct gbproxy_link_info *link_info; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - int old_ctr; - - OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL)); - OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL)); - OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL)); - OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL)); - OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL)); - OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_mcc = 123; - gbcfg.core_mnc = 456; - gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 1; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - random_sgsn_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - random_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Non-DTAP */ - send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_u_xid_ul, sizeof(llc_u_xid_ul)); - - send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - llc_u_xid_dl, sizeof(llc_u_xid_dl)); - - send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_ui_ll11_dns_query_ul, - sizeof(llc_ui_ll11_dns_query_ul)); - - send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - llc_ui_ll11_dns_resp_dl, - sizeof(llc_ui_ll11_dns_resp_dl)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Repeated RA Update Requests */ - send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2); - - send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002, - local_sgsn_tlli2, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL); - OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3); - - send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli3, &rai_bss, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete)); - - link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3); - - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_sgsn_tlli3, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Other messages */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002, - local_bss_tlli3, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn); - - dump_peers(stdout, 0, 0, &gbcfg); - - old_ctr = peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current; - - send_bssgp_paging(nsi, &sgsn_peer, imsi, sizeof(imsi), &rai_bss, sgsn_ptmsi3); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(old_ctr + 1 == - peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current); - - /* Bad case: Invalid BVCI */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1, - local_bss_tlli3, 1, 12); - dump_global(stdout, 0); - - /* Bad case: Invalid RAI */ - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown); - - dump_global(stdout, 0); - - /* Bad case: Invalid MCC (LAC ok) */ - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, - &rai_wrong_mcc_sgsn); - - dump_global(stdout, 0); - - /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */ - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - unknown_sgsn_tlli, 1, NULL, 0, - GPRS_SAPI_GMM, 2, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - /* Bad case: Invalid TLLI from SGSN (IMSI known) */ - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - unknown_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 3, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_sgsn_tlli3, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -static void test_gbproxy_ptmsi_patching_bad_cases() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t sgsn_ptmsi = 0xefe2b700; - const uint32_t local_sgsn_tlli = 0xefe2b700; - const uint32_t random_sgsn_tlli = 0x78dead00; - - const uint32_t bss_ptmsi = 0xc0dead01; - const uint32_t local_bss_tlli = 0xc0dead01; - const uint32_t foreign_bss_tlli = 0x8000dead; - - - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; - struct gbproxy_link_info *link_info; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL)); - OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_mcc = 123; - gbcfg.core_mnc = 456; - gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 1; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - random_sgsn_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - random_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT (duplicated)", &sgsn_peer, 0x1002, - random_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - - -static void test_gbproxy_imsi_acquisition() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_sgsn = - {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_wrong_mcc_sgsn = - {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t sgsn_ptmsi = 0xefe2b700; - const uint32_t local_sgsn_tlli = 0xefe2b700; - const uint32_t random_sgsn_tlli = 0x78dead00; - const uint32_t random_sgsn_tlli2 = 0x78dead02; - - const uint32_t bss_ptmsi = 0xc0dead01; - const uint32_t local_bss_tlli = 0xc0dead01; - const uint32_t foreign_bss_tlli = 0x8000dead; - const uint32_t other_bss_tlli = 0x8000beef; - - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; - struct gbproxy_link_info *link_info; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_mcc = 123; - gbcfg.core_mnc = 456; - gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 1; - gbcfg.acquire_imsi = 1; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - random_sgsn_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - random_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Non-DTAP */ - send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_u_xid_ul, sizeof(llc_u_xid_ul)); - - send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - llc_u_xid_dl, sizeof(llc_u_xid_dl)); - - send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_ui_ll11_dns_query_ul, - sizeof(llc_ui_ll11_dns_query_ul)); - - send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - llc_ui_ll11_dns_resp_dl, - sizeof(llc_ui_ll11_dns_resp_dl)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Other messages */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002, - local_bss_tlli, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Bad case: Invalid BVCI */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1, - local_bss_tlli, 1, 12); - dump_global(stdout, 0); - - /* Bad case: Invalid RAI */ - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown); - - dump_global(stdout, 0); - - /* Bad case: Invalid MCC (LAC ok) */ - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, - &rai_wrong_mcc_sgsn); - - dump_global(stdout, 0); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* RA Update request */ - - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002, - random_sgsn_tlli2, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach */ - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Special case: Repeated Attach Requests */ - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Special case: Detach from an unknown TLLI */ - - send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002, - other_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Special case: Repeated RA Update Requests */ - - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -static void test_gbproxy_secondary_sgsn() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer[2]= {{0},}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_sgsn = - {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t sgsn_ptmsi = 0xefe2b700; - const uint32_t local_sgsn_tlli = 0xefe2b700; - const uint32_t random_sgsn_tlli = 0x78dead00; - - const uint32_t bss_ptmsi = 0xc0dead01; - const uint32_t local_bss_tlli = 0xc0dead01; - const uint32_t foreign_bss_tlli = 0x8000dead; - - const uint32_t sgsn_ptmsi2 = 0xe0987654; - const uint32_t local_sgsn_tlli2 = 0xe0987654; - const uint32_t random_sgsn_tlli2 = 0x78dead02; - const uint32_t bss_ptmsi2 = 0xc0dead03; - const uint32_t local_bss_tlli2 = 0xc0dead03; - const uint32_t foreign_bss_tlli2 = 0x8000beef; - - const uint32_t random_sgsn_tlli3 = 0x78dead04; - const uint32_t bss_ptmsi3 = 0xc0dead05; - const uint32_t local_bss_tlli3 = 0xc0dead05; - const uint32_t foreign_bss_tlli3 = 0x8000feed; - - const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; - const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18}; - const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28}; - struct gbproxy_link_info *link_info; - struct gbproxy_link_info *other_info; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - const char *err_msg = NULL; - const char *filter_re = "999999"; - - OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL)); - OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_mcc = 123; - gbcfg.core_mnc = 456; - gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 1; - gbcfg.acquire_imsi = 1; - - gbcfg.route_to_sgsn2 = 1; - gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI; - - if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING], - filter_re, &err_msg) != 0) { - fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n", - err_msg); - OSMO_ASSERT(err_msg == NULL); - } - - configure_sgsn_peer(&sgsn_peer[0]); - configure_sgsn2_peer(&sgsn_peer[1]); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN 1 ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI); - - printf("--- Initialise SGSN 2 ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x0); - send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002); - send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Flow control ---\n\n"); - - send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1); - send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1); - send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1); - - printf("--- Establish GPRS connection (SGSN 1) ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002, - random_sgsn_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002, - random_sgsn_tlli, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Non-DTAP */ - send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_u_xid_ul, sizeof(llc_u_xid_ul)); - - send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, imsi1, sizeof(imsi1), - llc_u_xid_dl, sizeof(llc_u_xid_dl)); - - send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_ui_ll11_dns_query_ul, - sizeof(llc_ui_ll11_dns_query_ul)); - - send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, imsi1, sizeof(imsi1), - llc_ui_ll11_dns_resp_dl, - sizeof(llc_ui_ll11_dns_resp_dl)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Other messages */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002, - local_bss_tlli, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Establish GPRS connection (SGSN 2) ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli2, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity2_resp, sizeof(dtap_identity2_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002, - random_sgsn_tlli2, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity2_resp, sizeof(dtap_identity2_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002, - random_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc2, sizeof(dtap_attach_acc2)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Non-DTAP */ - send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, cell_id, - llc_u_xid_ul, sizeof(llc_u_xid_ul)); - - send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - llc_u_xid_dl, sizeof(llc_u_xid_dl)); - - send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, cell_id, - llc_ui_ll11_dns_query_ul, - sizeof(llc_ui_ll11_dns_query_ul)); - - send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - llc_ui_ll11_dns_resp_dl, - sizeof(llc_ui_ll11_dns_resp_dl)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Other messages */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002, - local_bss_tlli2, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli3, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity3_resp, sizeof(dtap_identity3_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002, - random_sgsn_tlli3, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity3_resp, sizeof(dtap_identity3_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002, - random_sgsn_tlli3, 1, imsi3, sizeof(imsi3), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(other_info); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info != other_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002, - local_sgsn_tlli, 1, imsi3, sizeof(imsi3), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(other_info); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info != other_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - - printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n"); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n"); - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n"); - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002, - local_sgsn_tlli, 1, imsi3, sizeof(imsi3), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING]); - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -static void test_gbproxy_keep_info() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t ptmsi = 0xefe2b700; - const uint32_t local_tlli = 0xefe2b700; - const uint32_t foreign_tlli = 0xafe2b700; - - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; - struct gbproxy_link_info *link_info, *link_info2; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - LLIST_HEAD(rcv_list); - - OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.patch_ptmsi = 0; - gbcfg.acquire_imsi = 1; - gbcfg.core_mcc = 0; - gbcfg.core_mnc = 0; - gbcfg.core_apn = NULL; - gbcfg.core_apn_size = 0; - gbcfg.route_to_sgsn2 = 0; - gbcfg.nsip_sgsn2_nsei = 0xffff; - gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - received_messages = &rcv_list; - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len > 0); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(gprs_tlli_type(link_info->sgsn_tlli.current) == TLLI_FOREIGN); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len > 0); - OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi))); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - /* Detach (MO) */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - OSMO_ASSERT(!expect_msg()); - - /* Re-Attach */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(gprs_tlli_type(link_info->sgsn_tlli.current) == TLLI_FOREIGN); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Re-Attach */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Re-Attach with IMSI */ - send_llc_ul_ui(nsi, "ATTACH REQUEST (IMSI)", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req4, sizeof(dtap_attach_req4)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(link_info->sgsn_tlli.current == foreign_tlli); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Re-Attach */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* RA update procedure (reject -> Detach) */ - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ)); - - send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_REJ)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Bad case: Re-Attach with wrong (initial) P-TMSI */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info != link_info2); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len > 0); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - OSMO_ASSERT(!expect_msg()); - - /* Bad case: Re-Attach with local TLLI */ - send_llc_ul_ui(nsi, "ATTACH REQUEST (local TLLI)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Bad case: Unexpected Re-Attach with IMSI after completed attachment - * procedure */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH REQUEST (unexpected, IMSI)", - &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req4, sizeof(dtap_attach_req4)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(link_info->sgsn_tlli.current == foreign_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Bad case: Unexpected Re-Attach with P-TMSI after completed attachment - * procedure */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH REQUEST (unexpected)", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(link_info->sgsn_tlli.current == foreign_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - - /* Attach rejected */ - - gbproxy_delete_link_infos(peer); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_rej7, sizeof(dtap_attach_rej7)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_REJ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli)); - - OSMO_ASSERT(!expect_msg()); - - /* Attach (incomplete) and Detach (MO) */ - - gbproxy_delete_link_infos(peer); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!expect_msg()); - - /* Attach (incomplete) and Detach (MT) */ - - gbproxy_delete_link_infos(peer); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - /* TODO: The stored messaged should be cleaned when receiving a Detach - * Ack. Remove the first OSMO_ASSERT when this is fixed. */ - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - OSMO_ASSERT(!expect_msg()); - received_messages = NULL; - - dump_global(stdout, 0); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -struct gbproxy_link_info *register_tlli( - struct gbproxy_peer *peer, uint32_t tlli, - const uint8_t *imsi, size_t imsi_len, time_t now) -{ - struct gbproxy_link_info *link_info; - int imsi_matches = -1; - int tlli_already_known = 0; - struct gbproxy_config *cfg = peer->cfg; - - /* Check, whether the IMSI matches */ - if (gprs_is_mi_imsi(imsi, imsi_len)) { - imsi_matches = gbproxy_check_imsi( - &cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len); - if (imsi_matches < 0) - return NULL; - } - - link_info = gbproxy_link_info_by_tlli(peer, tlli); - - if (!link_info) { - link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len); - - if (link_info) { - /* TLLI has changed somehow, adjust it */ - LOGP(DGPRS, LOGL_INFO, - "The TLLI has changed from %08x to %08x\n", - link_info->tlli.current, tlli); - link_info->tlli.current = tlli; - } - } - - if (!link_info) { - link_info = gbproxy_link_info_alloc(peer); - link_info->tlli.current = tlli; - } else { - gbproxy_detach_link_info(peer, link_info); - tlli_already_known = 1; - } - - OSMO_ASSERT(link_info != NULL); - - if (!tlli_already_known) - LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli); - - gbproxy_attach_link_info(peer, now, link_info); - gbproxy_update_link_info(link_info, imsi, imsi_len); - - if (imsi_matches >= 0) - link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches; - - return link_info; -} - -static void test_gbproxy_tlli_expire(void) -{ - struct gbproxy_config cfg = {0}; - struct gbproxy_peer *peer; - const char *err_msg = NULL; - const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 }; - const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 }; - const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 }; - const uint32_t tlli1 = 1234 | 0xc0000000; - const uint32_t tlli2 = 5678 | 0xc0000000; - const uint32_t tlli3 = 3456 | 0xc0000000; - const char *filter_re = ".*"; - time_t now = 1407479214; - - printf("Test TLLI info expiry\n\n"); - - gbproxy_init_config(&cfg); - - if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING], - filter_re, &err_msg) != 0) { - fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n", - err_msg); - OSMO_ASSERT(err_msg == NULL); - } - - { - struct gbproxy_link_info *link_info; - - printf("Test TLLI replacement:\n"); - - cfg.tlli_max_len = 0; - cfg.tlli_max_age = 0; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1\n"); - link_info = register_tlli(peer, tlli1, - imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - /* replace the old entry */ - printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n"); - link_info = register_tlli(peer, tlli2, - imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli2); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now, &cfg); - - /* verify that 5678 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli2); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(!link_info); - - printf("\n"); - - gbproxy_peer_free(peer); - } - - { - struct gbproxy_link_info *link_info; - - printf("Test IMSI replacement:\n"); - - cfg.tlli_max_len = 0; - cfg.tlli_max_age = 0; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1\n"); - link_info = register_tlli(peer, tlli1, - imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - /* try to replace the old entry */ - printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n"); - link_info = register_tlli(peer, tlli1, - imsi2, ARRAY_SIZE(imsi2), now); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now, &cfg); - - /* verify that 5678 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli1); - - printf("\n"); - - gbproxy_peer_free(peer); - } - - { - struct gbproxy_link_info *link_info; - int num_removed; - - printf("Test TLLI expiry, max_len == 1:\n"); - - cfg.tlli_max_len = 1; - cfg.tlli_max_age = 0; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1\n"); - register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - /* replace the old entry */ - printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n"); - register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now); - OSMO_ASSERT(peer->patch_state.logical_link_count == 2); - - num_removed = gbproxy_remove_stale_link_infos(peer, now + 2); - OSMO_ASSERT(num_removed == 1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now, &cfg); - - /* verify that 5678 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli2); - - printf("\n"); - - gbproxy_peer_free(peer); - } - - { - struct gbproxy_link_info *link_info; - int num_removed; - - printf("Test TLLI expiry, max_age == 1:\n"); - - cfg.tlli_max_len = 0; - cfg.tlli_max_age = 1; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n"); - register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n"); - register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), - now + 1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 2); - - num_removed = gbproxy_remove_stale_link_infos(peer, now + 2); - OSMO_ASSERT(num_removed == 1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now + 2, &cfg); - - /* verify that 5678 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli2); - - printf("\n"); - - gbproxy_peer_free(peer); - } - - { - struct gbproxy_link_info *link_info; - int num_removed; - - printf("Test TLLI expiry, max_len == 2, max_age == 1:\n"); - - cfg.tlli_max_len = 0; - cfg.tlli_max_age = 1; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1 (should expire)\n"); - register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n"); - register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), - now + 1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 2); - - printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n"); - register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3), - now + 2); - OSMO_ASSERT(peer->patch_state.logical_link_count == 3); - - dump_peers(stdout, 2, now + 2, &cfg); - - printf(" Remove stale TLLIs\n"); - num_removed = gbproxy_remove_stale_link_infos(peer, now + 3); - OSMO_ASSERT(num_removed == 2); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now + 2, &cfg); - - /* verify that tlli3 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli3); - - printf("\n"); - - gbproxy_peer_free(peer); - } - gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]); - gbprox_reset(&cfg); - - cleanup_test(); -} - -static void test_gbproxy_imsi_matching(void) -{ - const char *err_msg = NULL; - const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 }; - const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 }; - const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff }; - const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 }; - const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 }; - const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 }; - const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 }; - const char *filter_re1 = ".*"; - const char *filter_re2 = "^1234"; - const char *filter_re3 = "^4321"; - const char *filter_re4_bad = "^12["; - struct gbproxy_match match = {0,}; - - printf("=== Test IMSI/TMSI matching ===\n\n"); - - OSMO_ASSERT(match.enable == 0); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - err_msg = NULL; - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1); - OSMO_ASSERT(err_msg != NULL); - OSMO_ASSERT(match.enable == 0); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0); - OSMO_ASSERT(match.enable == 0); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - gbproxy_clear_patch_filter(&match); - OSMO_ASSERT(match.enable == 0); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1); - /* imsi3_bad contains 0xE and 0xF digits, but the conversion function - * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this - * case. */ - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0); - OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0); - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0); - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0); - OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1); - - /* TODO: Check correct length but wrong type with is_mi_tmsi */ - - gbproxy_clear_patch_filter(&match); - OSMO_ASSERT(match.enable == 0); - - cleanup_test(); -} - -static void test_gbproxy_stored_messages() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t ptmsi = 0xefe2b700; - const uint32_t local_tlli = 0xefe2b700; - - const uint32_t foreign_tlli1 = 0x8000dead; - - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_mcc = 0; - gbcfg.core_mnc = 0; - gbcfg.core_apn = talloc_zero_size(NULL, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 0; - gbcfg.acquire_imsi = 1; - gbcfg.keep_link_infos = 0; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Establish first LLC connection ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli1, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "DETACH ACCEPT", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -static struct log_info_cat gprs_categories[] = { - [DGPRS] = { - .name = "DGPRS", - .description = "GPRS Packet Service", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DNS] = { - .name = "DNS", - .description = "GPRS Network Service (NS)", - .enabled = 1, .loglevel = LOGL_INFO, - }, - [DBSSGP] = { - .name = "DBSSGP", - .description = "GPRS BSS Gateway Protocol (BSSGP)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, -}; - -static struct log_info info = { - .cat = gprs_categories, - .num_cat = ARRAY_SIZE(gprs_categories), -}; - -int main(int argc, char **argv) -{ - msgb_talloc_ctx_init(NULL, 0); - - osmo_init_logging(&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, &gbcfg); - - log_set_print_filename(osmo_stderr_target, 0); - log_set_log_level(osmo_stderr_target, LOGL_DEBUG); - log_set_all_filter(osmo_stderr_target, 1); - - rate_ctr_init(NULL); - - setlinebuf(stdout); - - printf("===== GbProxy test START\n"); - gbproxy_init_config(&gbcfg); - test_gbproxy(); - test_gbproxy_ident_changes(); - test_gbproxy_imsi_matching(); - test_gbproxy_ptmsi_assignment(); - test_gbproxy_ra_patching(); - test_gbproxy_ptmsi_patching(); - test_gbproxy_ptmsi_patching_bad_cases(); - test_gbproxy_imsi_acquisition(); - test_gbproxy_secondary_sgsn(); - test_gbproxy_keep_info(); - test_gbproxy_tlli_expire(); - test_gbproxy_stored_messages(); - printf("===== GbProxy test END\n\n"); - - exit(EXIT_SUCCESS); -} diff --git a/tests/gbproxy/gbproxy_test.ok b/tests/gbproxy/gbproxy_test.ok deleted file mode 100644 index 737aec0ba..000000000 --- a/tests/gbproxy/gbproxy_test.ok +++ /dev/null @@ -1,7244 +0,0 @@ -===== GbProxy test START -=== test_gbproxy === ---- Initialise SGSN --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - -Current NS-VCIs: - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - ---- Initialise BSS 2 --- - -Setup NS-VC: remote 0x01020304:2222, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:2222 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:2222 - -MESSAGE to BSS at 0x01020304:2222, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:2222, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:2222 -0a - -MESSAGE to BSS at 0x01020304:2222, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:2222 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:2222 - -MESSAGE to BSS at 0x01020304:2222, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:2222 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:2222, BVCI 0x2002(8194) - -PROCESSING BVC_RESET from 0x01020304:2222 -00 00 00 00 22 04 82 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 20 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:2222, msg length 9 -00 00 00 00 23 04 82 20 02 - -result (BVC_RESET_ACK) = 9 - ---- Move BSS 1 to new port --- - -Setup NS-VC: remote 0x01020304:3333, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:3333 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:3333 - -MESSAGE to BSS at 0x01020304:3333, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:3333 -0a - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:3333 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:3333 - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:3333 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 2 to former BSS 1 port --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 1 to current BSS 2 port --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 2 to new port --- - -Setup NS-VC: remote 0x01020304:4444, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:4444 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:4444 - -MESSAGE to BSS at 0x01020304:4444, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:4444, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:4444 -0a - -MESSAGE to BSS at 0x01020304:4444, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:4444 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:4444 - -MESSAGE to BSS at 0x01020304:4444, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:4444 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:4444 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 2 to former BSS 1 port --- - -Setup NS-VC: remote 0x01020304:3333, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:3333 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_REPLACED: 0x2001/1.2.3.4:4444 -> 0x1001/1.2.3.4:3333 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:3333 - -MESSAGE to BSS at 0x01020304:3333, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:3333 -0a - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:3333 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:3333 - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:3333 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x00000000:0 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 1 to original BSS 1 port --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Reset BSS 1 with a new BVCI --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1012(4114) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 12 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 12 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 12 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4114, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 12 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 12 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 12 - -result (BVC_RESET_ACK) = 9 - ---- Reset BSS 1 with the old BVCI --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4114, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - ---- Reset BSS 1 with the old BVCI again --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4114, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - ---- Send message from BSS 1 to SGSN, BVCI 0x1012 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 12 - -result (UNITDATA) = 4 - ---- Send message from SGSN to BSS 1, BVCI 0x1012 --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 12 - -result (UNITDATA) = 4 - ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 12 - -result (UNITDATA) = 4 - ---- Send message from SGSN to BSS 1, BVCI 0x1002 --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 12 - -result (UNITDATA) = 4 - ---- Send message from BSS 2 to SGSN, BVCI 0x2002 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 20 02 - -result (UNITDATA) = 4 - ---- Send message from SGSN to BSS 2, BVCI 0x2002 --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:3333, msg length 4 -00 00 20 02 - -result (UNITDATA) = 4 - ---- Reset BSS 1 with the old BVCI on BSS2's link --- - -Setup BSSGP: remote 0x01020304:3333, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:3333 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4114, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -Gbproxy global: -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:3333, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 12 - -result (UNITDATA) = 4 - ---- Send message from SGSN to BSS 1, BVCI 0x1002 --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 12 - -result (UNITDATA) = 4 - ---- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 ff - -CALLBACK, event 0, msg length 0, bvci 0x10ff -00 00 10 ff - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 10 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 14 -00 00 00 00 41 07 81 05 04 82 10 ff 15 80 - -result (UNITDATA) = 14 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -Gbproxy global: - Invalid BVC Identifier : 1 -=== test_gbproxy_ident_changes === ---- Initialise SGSN --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - -Current NS-VCIs: - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - ---- Setup BVCI 1 --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Setup BVCI 2 --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x2002(8194) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 20 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 20 02 - -result (BVC_RESET_ACK) = 9 - -Peers: - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 1 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 02 - -result (UNITDATA) = 4 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 02 - -result (UNITDATA) = 4 - ---- Send message from BSS 1 to SGSN and back, BVCI 2 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 20 02 - -result (UNITDATA) = 4 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 20 02 - -result (UNITDATA) = 4 - ---- Change NSEI --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 20 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x2000, peer 0x01020304:1111 - NS-VC changed NSEI count : 1 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - ---- Setup BVCI 1 --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -Peers: - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Setup BVCI 3 --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x3002(12290) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 30 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 30 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 30 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 30 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 30 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 30 02 - -result (BVC_RESET_ACK) = 9 - -Peers: - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 1 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 02 - -result (UNITDATA) = 4 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 02 - -result (UNITDATA) = 4 - ---- Send message from BSS 1 to SGSN and back, BVCI 2 (should fail) --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 20 02 - -result (UNITDATA) = 4 - -Peers: - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -PROCESSING UNITDATA from 0x05060708:32000 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -result (UNITDATA) = -22 - -Peers: - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - NS Transmission error : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 3 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 30 02 - -CALLBACK, event 0, msg length 0, bvci 0x3002 -00 00 30 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 30 02 - -result (UNITDATA) = 4 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 30 02 - -CALLBACK, event 0, msg length 0, bvci 0x3002 -00 00 30 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 30 02 - -result (UNITDATA) = 4 - ---- Change NSVCI --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_REPLACED: 0x2001/0.0.0.0:0 -> 0x1001/1.2.3.4:1111 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x2000, peer 0x00000000:0 - NS-VC changed NSEI count : 1 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - ---- Setup BVCI 1 --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -Peers: - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - NS Transmission error : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Setup BVCI 4 --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x4002(16386) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 40 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 40 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 40 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 40 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 40 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 40 02 - -result (BVC_RESET_ACK) = 9 - -Peers: - NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - NS Transmission error : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 1 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 02 - -result (UNITDATA) = 4 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 02 - -result (UNITDATA) = 4 - ---- Send message from BSS 1 to SGSN and back, BVCI 2 (should fail) --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 20 02 - -result (UNITDATA) = 4 - -Peers: - NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 2 - NS Transmission error : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -PROCESSING UNITDATA from 0x05060708:32000 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -result (UNITDATA) = -22 - -Peers: - NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 2 - NS Transmission error : 2 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 3 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 30 02 - -CALLBACK, event 0, msg length 0, bvci 0x3002 -00 00 30 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 30 02 - -result (UNITDATA) = 4 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 30 02 - -CALLBACK, event 0, msg length 0, bvci 0x3002 -00 00 30 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 30 02 - -result (UNITDATA) = 4 - ---- Send message from BSS 1 to SGSN and back, BVCI 4 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 40 02 - -CALLBACK, event 0, msg length 0, bvci 0x4002 -00 00 40 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x4002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 40 02 - -result (UNITDATA) = 4 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 40 02 - -CALLBACK, event 0, msg length 0, bvci 0x4002 -00 00 40 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x4002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 40 02 - -result (UNITDATA) = 4 - -Gbproxy global: -Peers: - NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 2 - NS Transmission error : 2 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -=== Test IMSI/TMSI matching === - -=== test_gbproxy_ptmsi_assignment === ---- Initialise SGSN --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Establish first LLC connection --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -result (ATTACH REQUEST) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 8000dead, IMSI (none), AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 8000dead, IMSI (none), AGE 0 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 44 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -result (IDENT RESPONSE) = 44 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 8000dead, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/efe2b700 -> 8000dead/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/efe2b700 -> 8000dead/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 ---- Establish second LLC connection with the same P-TMSI --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 0d 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 46 42 6e - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 0d 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 46 42 6e - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 0d 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 46 42 6e - -result (ATTACH REQUEST) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 8000beef, IMSI (none), AGE 0 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18 - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18 - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 8000beef, IMSI (none), AGE 0 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 11 08 16 08 11 12 99 99 99 16 17 18 bf d2 01 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 11 08 16 08 11 12 99 99 99 16 17 18 bf d2 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 44 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 11 08 16 08 11 12 99 99 99 16 17 18 bf d2 01 - -result (IDENT RESPONSE) = 44 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 8000beef, IMSI 12199999961718, AGE 0 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000beef/efe2b700 -> 8000beef/efe2b700, IMSI 12199999961718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 15 08 03 86 ac 47 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 15 08 03 86 ac 47 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 15 08 03 86 ac 47 - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000beef/efe2b700 -> 8000beef/efe2b700, IMSI 12199999961718, AGE 0 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12199999961718, AGE 0 -Gbproxy global: -=== test_gbproxy_ra_patching === ---- Initialise SGSN --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - -Current NS-VCIs: - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00 - -result (BVC_RESET) = 22 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - TLLI-Cache: 0 -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -PROCESSING BVC_SUSPEND from 0x01020304:1111 -00 00 00 00 0b 1f 84 cc d1 75 8b 1b 86 11 22 33 40 50 60 - -CALLBACK, event 0, msg length 15, bvci 0x0000 -00 00 00 00 0b 1f 84 cc d1 75 8b 1b 86 11 22 33 40 50 60 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 19 -00 00 00 00 0b 1f 84 cc d1 75 8b 1b 86 21 63 54 40 50 60 - -result (BVC_SUSPEND) = 19 - -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 21 63 54 40 50 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 21 63 54 40 50 60 1d 81 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 22 -00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 22 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - RAID patched (SGSN): 1 - TLLI from SGSN unknown : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 21 63 54 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 8e cd 32 - -result (ATTACH REQUEST) = 79 - -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -result (IDENT REQUEST) = 27 - -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 18 b7 1b 9a - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 18 b7 1b 9a - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 44 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 18 b7 1b 9a - -result (IDENT RESPONSE) = 44 - -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 be 38 c0 - -result (ATTACH ACCEPT) = 92 - -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ea 67 11 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ea 67 11 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ea 67 11 - -result (ATTACH COMPLETE) = 35 - -PROCESSING ACT PDP CTX REQ (REPLACE APN) from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -CALLBACK, event 0, msg length 76, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 81 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 85 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75 - -result (ACT PDP CTX REQ (REPLACE APN)) = 85 - -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 70 - -PROCESSING ACT PDP CTX REQ (REPLACE APN) from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -CALLBACK, event 0, msg length 76, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 81 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 85 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75 - -result (ACT PDP CTX REQ (REPLACE APN)) = 85 - -PROCESSING ACT PDP CTX REQ (REMOVE APN) from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -CALLBACK, event 0, msg length 76, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 71 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 75 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 30 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 85 fa 60 - -result (ACT PDP CTX REQ (REMOVE APN)) = 75 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 2 - APN patched : 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - PDP Activation Request count : 3 - TLLI from SGSN unknown : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0, IMSI matches -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 7e e1 41 - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 7e e1 41 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 48 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 7e e1 41 - -result (DETACH REQ) = 48 - -PROCESSING DETACH ACC from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0 - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0 - -result (DETACH ACC) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 2 - APN patched : 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - Detach Request count : 1 - Detach Accept count : 1 - PDP Activation Request count : 3 - TLLI from SGSN unknown : 1 - TLLI-Cache: 0 ---- RA update --- - -PROCESSING RA UPD REQ from 0x01020304:1111 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 89 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 1d f0 41 - -result (RA UPD REQ) = 89 - -PROCESSING RA UPD ACC from 0x05060708:32000 -00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 d7 59 65 - -CALLBACK, event 0, msg length 87, bvci 0x1002 -00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 d7 59 65 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 87 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 91 -00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 3a 03 54 - -result (RA UPD ACC) = 91 - -PROCESSING ACT PDP CTX REQ (REMOVE APN) from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -CALLBACK, event 0, msg length 76, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 71 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 75 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 30 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 85 fa 60 - -result (ACT PDP CTX REQ (REMOVE APN)) = 75 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 3 - APN patched : 4 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 1 - Detach Accept count : 1 - PDP Activation Request count : 4 - TLLI from SGSN unknown : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI bbc54679/efe2b700 -> bbc54679/efe2b700, IMSI 12131415161718, AGE 0, IMSI matches -PROCESSING DETACH REQ (PWR OFF) from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 09 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 84 0c eb - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 09 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 84 0c eb - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 48 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 09 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 84 0c eb - -result (DETACH REQ (PWR OFF)) = 48 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 14 - RAID patched (SGSN): 3 - APN patched : 4 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 2 - Detach Accept count : 1 - PDP Activation Request count : 4 - TLLI from SGSN unknown : 1 - TLLI-Cache: 0 ---- Bad cases --- - -PROCESSING ATTACH REQUEST (foreign RAI) from 0x01020304:1111 -00 00 10 02 01 bb 00 be ef 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb 00 be ef 99 99 99 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 2d c7 df - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 bb 00 be ef 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb 00 be ef 99 99 99 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 2d c7 df - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 bb 00 be ef 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb 00 be ef 99 99 99 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 2d c7 df - -result (ATTACH REQUEST (foreign RAI)) = 79 - -TLLI is already detached, shouldn't patch -PROCESSING ACT PDP CTX REQ from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -CALLBACK, event 0, msg length 76, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 76 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 80 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -result (ACT PDP CTX REQ) = 80 - -Invalid RAI, shouldn't patch -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 00 f1 99 00 63 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 00 f1 99 00 63 60 1d 81 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 28 -00 00 00 00 41 07 81 21 15 92 0c 1f 84 cc d1 75 8b 1b 86 00 f1 99 00 63 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 28 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - Patch error: no peer : 1 -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 16 - RAID patched (SGSN): 3 - APN patched : 4 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 2 - Detach Accept count : 1 - PDP Activation Request count : 5 - TLLI from SGSN unknown : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI efe2b700 -> efe2b700, IMSI (none), AGE 0 - TLLI bb00beef -> bb00beef, IMSI (none), AGE 0 -=== test_gbproxy_ptmsi_patching === ---- Initialise SGSN --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -result (ATTACH REQUEST) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 44 -00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -result (IDENT RESPONSE) = 44 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 0c 0a 29 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ACT PDP CTX REQ (REPLACE APN) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -CALLBACK, event 0, msg length 76, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 81 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 85 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75 - -result (ACT PDP CTX REQ (REPLACE APN)) = 85 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 1 - APN patched : 1 - TLLI patched (BSS ): 4 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING XID (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -CALLBACK, event 0, msg length 38, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 38 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 42 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -result (XID (UL)) = 42 - -PROCESSING XID (DL) from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -CALLBACK, event 0, msg length 70, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 70 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 74 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -result (XID (DL)) = 74 - -PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -CALLBACK, event 0, msg length 89, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 89 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 93 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -result (LL11 DNS QUERY (UL)) = 93 - -PROCESSING LL11 DNS RESP (DL) from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -CALLBACK, event 0, msg length 267, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 267 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 271 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -result (LL11 DNS RESP (DL)) = 271 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 1 - APN patched : 1 - TLLI patched (BSS ): 6 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING RA UPD REQ (P-TMSI 2) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 11 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 e2 6d 78 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 11 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 e2 6d 78 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 89 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 11 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 69 a3 ae - -result (RA UPD REQ (P-TMSI 2)) = 89 - -PROCESSING RA UDP ACC (P-TMSI 2) from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 0d 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 98 76 54 17 16 9f e8 ea - -CALLBACK, event 0, msg length 87, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 0d 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 98 76 54 17 16 9f e8 ea - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 87 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 91 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 0d 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 c0 de ad 02 17 16 bb 4d a0 - -result (RA UDP ACC (P-TMSI 2)) = 91 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 2 - APN patched : 1 - TLLI patched (BSS ): 7 - TLLI patched (SGSN): 6 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01/c0dead02 -> efe2b700/e0987654, IMSI 12131415161718, AGE 0 -PROCESSING RA UPD REQ (P-TMSI 3) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 02 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 c0 de ad 02 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 89 -00 00 10 02 01 e0 98 76 54 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 1d f0 41 - -result (RA UPD REQ (P-TMSI 3)) = 89 - -PROCESSING RA UDP ACC (P-TMSI 3) from 0x05060708:32000 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 11 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 54 32 10 17 16 1b a3 a8 - -CALLBACK, event 0, msg length 87, bvci 0x1002 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 11 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 54 32 10 17 16 1b a3 a8 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 87 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 91 -00 00 10 02 00 c0 de ad 02 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 11 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 c0 de ad 03 17 16 6e 58 26 - -result (RA UDP ACC (P-TMSI 3)) = 91 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 11 - RAID patched (SGSN): 3 - APN patched : 1 - TLLI patched (BSS ): 8 - TLLI patched (SGSN): 7 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01/c0dead03 -> efe2b700/e0543210, IMSI 12131415161718, AGE 0 -PROCESSING RA UPD COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 08 01 c0 19 08 0a d5 5f 5e - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 08 01 c0 19 08 0a d5 5f 5e - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 e0 54 32 10 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 08 01 c0 19 08 0a d5 5f 5e - -result (RA UPD COMPLETE) = 35 - -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 e0 54 32 10 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 e0 54 32 10 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 12 - RAID patched (SGSN): 3 - APN patched : 1 - TLLI patched (BSS ): 9 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 23 -00 00 00 00 2c 1f 84 e0 54 32 10 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 23 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 12 - RAID patched (SGSN): 3 - APN patched : 1 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING BVC_SUSPEND from 0x01020304:1111 -00 00 00 00 0b 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 - -CALLBACK, event 0, msg length 15, bvci 0x0000 -00 00 00 00 0b 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 19 -00 00 00 00 0b 1f 84 e0 54 32 10 1b 86 21 63 54 40 50 60 - -result (BVC_SUSPEND) = 19 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 3 - APN patched : 1 - TLLI patched (BSS ): 11 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 21 63 54 40 50 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 21 63 54 40 50 60 1d 81 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 22 -00 00 00 00 0c 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 22 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 4 - APN patched : 1 - TLLI patched (BSS ): 11 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING PAGING_PS from 0x05060708:32000 -00 00 00 00 06 0d 88 11 12 13 14 15 16 17 18 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 e0 54 32 10 - -CALLBACK, event 0, msg length 34, bvci 0x0000 -00 00 00 00 06 0d 88 11 12 13 14 15 16 17 18 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 e0 54 32 10 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 34 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 38 -00 00 00 00 06 0d 88 11 12 13 14 15 16 17 18 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 c0 de ad 03 - -result (PAGING_PS) = 38 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 5 - APN patched : 1 - TLLI patched (BSS ): 11 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 4 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 ee e1 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 ee e1 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 23 -00 00 00 00 2c 1f 84 e0 54 32 10 0f 81 01 04 82 ee e1 25 83 00 00 0c - -result (LLC_DISCARDED) = 23 - -Gbproxy global: -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 00 f1 99 00 63 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 00 f1 99 00 63 60 1d 81 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 28 -00 00 00 00 41 07 81 21 15 92 0c 1f 84 e0 54 32 10 1b 86 00 f1 99 00 63 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 28 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - Patch error: no peer : 1 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 99 69 54 40 50 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 99 69 54 40 50 60 1d 81 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 22 -00 00 00 00 0c 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 22 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - Patch error: no peer : 1 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ee ba db ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 00 83 00 00 00 0e 88 41 c0 09 08 21 04 ba 3d - -CALLBACK, event 0, msg length 58, bvci 0x1002 -00 00 10 02 00 ee ba db ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 00 83 00 00 00 0e 88 41 c0 09 08 21 04 ba 3d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 58 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 62 -00 00 10 02 00 ee ba db ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 00 83 00 00 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 62 - -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ee ba db ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ee ba db ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 ee ba db ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -result (GMM INFO) = 70 - -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb aa cc a3 - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb aa cc a3 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 48 -00 00 10 02 01 e0 54 32 10 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 e0 54 32 10 19 03 b9 97 cb ea 6d af - -result (DETACH REQ) = 48 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 14 - RAID patched (SGSN): 6 - APN patched : 1 - TLLI patched (BSS ): 13 - TLLI patched (SGSN): 10 - P-TMSI patched (BSS ): 1 - P-TMSI patched (SGSN): 4 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - Detach Request count : 1 - PDP Activation Request count : 1 - TLLI from SGSN unknown : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x05060708:32000 -00 00 10 02 00 e0 54 32 10 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 19 08 06 00 04 ff 52 - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 e0 54 32 10 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 19 08 06 00 04 ff 52 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 19 08 06 00 04 ff 52 - -result (DETACH ACC) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 14 - RAID patched (SGSN): 6 - APN patched : 1 - TLLI patched (BSS ): 13 - TLLI patched (SGSN): 11 - P-TMSI patched (BSS ): 1 - P-TMSI patched (SGSN): 4 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - Detach Request count : 1 - Detach Accept count : 1 - PDP Activation Request count : 1 - TLLI from SGSN unknown : 2 - TLLI-Cache: 0 -Gbproxy global: - Invalid Routing Area Identifier : 1 - Patch error: no peer : 1 -=== test_gbproxy_ptmsi_patching_bad_cases === ---- Initialise SGSN --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -result (ATTACH REQUEST) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 44 -00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -result (IDENT RESPONSE) = 44 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 0c 0a 29 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT (duplicated) from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 09 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 1d 9e 24 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 09 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 1d 9e 24 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 09 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 42 f6 fc - -result (ATTACH ACCEPT (duplicated)) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 4 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 0d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 37 67 c6 - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 0d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 37 67 c6 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 48 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 0d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 37 67 c6 - -result (DETACH REQ) = 48 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 4 - TLLI patched (SGSN): 4 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - Attach Completed count : 1 - Detach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 11 08 06 00 cf 8a 58 - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 11 08 06 00 cf 8a 58 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 11 08 06 00 cf 8a 58 - -result (DETACH ACC) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 4 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - Attach Completed count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI-Cache: 0 -Gbproxy global: -=== test_gbproxy_imsi_acquisition === ---- Initialise SGSN --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 21 63 54 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 8e cd 32 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 1 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 44 -00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -result (IDENT RESPONSE) = 44 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 0c 0a 29 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING XID (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -CALLBACK, event 0, msg length 38, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 38 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 42 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -result (XID (UL)) = 42 - -PROCESSING XID (DL) from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -CALLBACK, event 0, msg length 70, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 70 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 74 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -result (XID (DL)) = 74 - -PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -CALLBACK, event 0, msg length 89, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 89 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 93 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -result (LL11 DNS QUERY (UL)) = 93 - -PROCESSING LL11 DNS RESP (DL) from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -CALLBACK, event 0, msg length 267, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 267 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 271 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -result (LL11 DNS RESP (DL)) = 271 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 5 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 23 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 23 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 6 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x05060708:32000 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 25 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 29 -00 00 00 00 41 07 81 27 15 93 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 29 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 6 - TLLI patched (SGSN): 6 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING BVC_SUSPEND from 0x01020304:1111 -00 00 00 00 0b 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 - -CALLBACK, event 0, msg length 15, bvci 0x0000 -00 00 00 00 0b 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 19 -00 00 00 00 0b 1f 84 ef e2 b7 00 1b 86 21 63 54 40 50 60 - -result (BVC_SUSPEND) = 19 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 8 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 7 - TLLI patched (SGSN): 6 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 21 63 54 40 50 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 21 63 54 40 50 60 1d 81 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 22 -00 00 00 00 0c 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 22 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 8 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 7 - TLLI patched (SGSN): 7 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 ee e1 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 ee e1 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 23 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 ee e1 25 83 00 00 0c - -result (LLC_DISCARDED) = 23 - -Gbproxy global: - BSSGP protocol error (SGSN): 1 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 00 f1 99 00 63 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 00 f1 99 00 63 60 1d 81 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 28 -00 00 00 00 41 07 81 21 15 92 0c 1f 84 ef e2 b7 00 1b 86 00 f1 99 00 63 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 28 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - BSSGP protocol error (SGSN): 1 - Patch error: no peer : 1 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 99 69 54 40 50 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 99 69 54 40 50 60 1d 81 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 22 -00 00 00 00 0c 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 22 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - BSSGP protocol error (SGSN): 1 - Patch error: no peer : 1 -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 48 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de - -result (DETACH REQ) = 48 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 9 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - Detach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee - -result (DETACH ACC) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 9 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI-Cache: 0 -PROCESSING RA UPD REQ from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (RA UPD REQ) = 0 - -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 19 08 16 08 11 12 13 14 15 16 17 18 35 23 fc - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 19 08 16 08 11 12 13 14 15 16 17 18 35 23 fc - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 89 -00 00 10 02 01 78 de ad 02 00 00 04 08 88 21 63 54 00 63 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead02, IMSI 12131415161718, AGE 0 -PROCESSING RA UDP ACC from 0x05060708:32000 -00 00 10 02 00 78 de ad 02 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 11 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 36 98 77 - -CALLBACK, event 0, msg length 87, bvci 0x1002 -00 00 10 02 00 78 de ad 02 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 11 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 36 98 77 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 87 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 91 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 11 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 c0 de ad 03 17 16 6e 58 26 - -result (RA UDP ACC) = 91 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 10 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead03 -> 78dead02/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb aa cc a3 - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb aa cc a3 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 06 00 11 f5 c0 - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 10 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 2 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead03 -> 78dead02/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0 - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0 - -result (DETACH ACC) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 11 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 2 - Detach Accept count : 2 - TLLI-Cache: 0 -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 b6 bb - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 b6 bb - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 25 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 1d aa 57 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 25 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 1d aa 57 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 05 08 15 01 8f 47 9e - -result (ATTACH REQUEST) = 0 - -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 29 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb d9 1d ef - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 29 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb d9 1d ef - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 09 08 06 00 da 80 ca - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 11 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 3 - Detach Accept count : 2 - TLLI-Cache: 0 -PROCESSING DETACH REQ (unknown TLLI) from 0x01020304:1111 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 2d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 0d 30 0d - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 2d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 0d 30 0d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 06 00 11 f5 c0 - -result (DETACH REQ (unknown TLLI)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 11 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 4 - Detach Accept count : 2 - TLLI-Cache: 0 -PROCESSING RA UPD REQ from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 31 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 d8 cf d8 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 31 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 d8 cf d8 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (RA UPD REQ) = 0 - -PROCESSING RA UPD REQ from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 35 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 ac 9c 37 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 35 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 ac 9c 37 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 05 08 15 01 8f 47 9e - -result (RA UPD REQ) = 0 - -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 39 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 44 b6 8a - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 39 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 44 b6 8a - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 09 08 06 00 da 80 ca - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 11 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 3 - RoutingArea Update Accept count : 1 - Detach Request count : 5 - Detach Accept count : 2 - TLLI-Cache: 0 -Gbproxy global: - Invalid Routing Area Identifier : 1 - BSSGP protocol error (SGSN): 1 - Patch error: no peer : 1 -=== test_gbproxy_secondary_sgsn === ---- Initialise SGSN 1 --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - ---- Initialise SGSN 2 --- - -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 12 -02 00 81 01 01 82 01 03 04 82 01 02 - -PROCESSING RESET_ACK from 0x15161718:32001 -03 01 82 01 03 04 82 01 02 - -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x15161718:32001 -0b - -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x15161718:32001 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0103/21.22.23.24:32001 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x15161718:32001 -0a - -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1 -0b - -result (ALIVE) = 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x0000(0) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 00 00 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 00 00 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 00 00 - -result (BVC_RESET) = 9 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 00 00 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 00 00 - -result (BVC_RESET_ACK) = -2 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -PROCESSING BVC_RESET_ACK from 0x15161718:32001 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 1 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0103, NSEI 0x0102, peer 0x15161718:32001 - NS-VC Block count : 1 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Gbproxy global: - Invalid BVC Identifier : 1 - Patch error: no peer : 1 -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - TLLI-Cache: 0 ---- Flow control --- - -PROCESSING FLOW_CONTROL_BVC from 0x01020304:1111 -00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03 - -CALLBACK, event 0, msg length 24, bvci 0x1002 -00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 28 -00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 28 -00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03 - -result (FLOW_CONTROL_BVC) = 28 - -PROCESSING FLOW_CONTROL_BVC_ACK from 0x05060708:32000 -00 00 10 02 27 1e 81 01 - -CALLBACK, event 0, msg length 4, bvci 0x1002 -00 00 10 02 27 1e 81 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 4 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 8 -00 00 10 02 27 1e 81 01 - -result (FLOW_CONTROL_BVC_ACK) = 8 - -PROCESSING FLOW_CONTROL_BVC_ACK from 0x15161718:32001 -00 00 10 02 27 1e 81 01 - -CALLBACK, event 0, msg length 4, bvci 0x1002 -00 00 10 02 27 1e 81 01 - -result (FLOW_CONTROL_BVC_ACK) = 0 - ---- Establish GPRS connection (SGSN 1) --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress, SGSN NSEI 65535 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 44 -00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -result (IDENT RESPONSE) = 44 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 78 de ad 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 0c 0a 29 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING XID (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -CALLBACK, event 0, msg length 38, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 38 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 42 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -result (XID (UL)) = 42 - -PROCESSING XID (DL) from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -CALLBACK, event 0, msg length 70, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 70 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 74 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -result (XID (DL)) = 74 - -PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -CALLBACK, event 0, msg length 89, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 89 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 93 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -result (LL11 DNS QUERY (UL)) = 93 - -PROCESSING LL11 DNS RESP (DL) from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -CALLBACK, event 0, msg length 267, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 267 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 271 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -result (LL11 DNS RESP (DL)) = 271 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 6 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 5 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 23 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 23 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 6 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 6 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING LLC_DISCARDED from 0x05060708:32000 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 25 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 29 -00 00 00 00 41 07 81 27 15 93 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 29 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 6 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 6 - TLLI patched (SGSN): 6 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING BVC_SUSPEND from 0x01020304:1111 -00 00 00 00 0b 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 - -CALLBACK, event 0, msg length 15, bvci 0x0000 -00 00 00 00 0b 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 19 -00 00 00 00 0b 1f 84 ef e2 b7 00 1b 86 21 63 54 40 50 60 - -result (BVC_SUSPEND) = 19 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 7 - TLLI patched (SGSN): 6 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 21 63 54 40 50 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 21 63 54 40 50 60 1d 81 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 22 -00 00 00 00 0c 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 22 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 7 - TLLI patched (SGSN): 7 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 ---- Establish GPRS connection (SGSN 2) --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 11 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 bf 00 5c - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 11 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 bf 00 5c - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 7 - TLLI patched (SGSN): 7 - P-TMSI patched (SGSN): 1 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 78dead02, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress, SGSN NSEI 65535 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 15 08 16 08 11 12 99 99 99 16 17 18 b2 dd 58 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 15 08 16 08 11 12 99 99 99 16 17 18 b2 dd 58 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 79 -00 00 10 02 01 78 de ad 02 00 00 04 08 88 21 63 54 00 63 60 12 34 00 80 0e 00 34 01 c0 11 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 bf 00 5c - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 8 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 8 - TLLI patched (SGSN): 7 - P-TMSI patched (SGSN): 1 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 78dead02, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING IDENT REQUEST from 0x15161718:32001 -00 00 10 02 00 78 de ad 02 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18 - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 78 de ad 02 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18 - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 8 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 8 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 1 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 78dead02, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 19 08 16 08 11 12 99 99 99 16 17 18 a5 cc b3 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 19 08 16 08 11 12 99 99 99 16 17 18 a5 cc b3 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 44 -00 00 10 02 01 78 de ad 02 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 19 08 16 08 11 12 99 99 99 16 17 18 a5 cc b3 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 9 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 1 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 78dead02, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING ATTACH ACCEPT from 0x15161718:32001 -00 00 10 02 00 78 de ad 02 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 e0 98 76 54 cb 1c 5b - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 78 de ad 02 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 e0 98 76 54 cb 1c 5b - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 03 32 40 fa - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 9 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 2 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef/c0dead03 -> 78dead02/e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 1d 08 03 5e 3a ea - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 1d 08 03 5e 3a ea - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 35 -00 00 10 02 01 e0 98 76 54 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 1d 08 03 5e 3a ea - -result (ATTACH COMPLETE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 2 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef/c0dead03 -> 78dead02/e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING GMM INFO from 0x15161718:32001 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 10 - P-TMSI patched (SGSN): 2 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING XID (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -CALLBACK, event 0, msg length 38, bvci 0x1002 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 38 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 42 -00 00 10 02 01 e0 98 76 54 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28 - -result (XID (UL)) = 0 - -PROCESSING XID (DL) from 0x15161718:32001 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -CALLBACK, event 0, msg length 70, bvci 0x1002 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 70 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 74 -00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -result (XID (DL)) = 74 - -PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -CALLBACK, event 0, msg length 89, bvci 0x1002 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 89 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 93 -00 00 10 02 01 e0 98 76 54 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07 - -result (LL11 DNS QUERY (UL)) = 0 - -PROCESSING LL11 DNS RESP (DL) from 0x15161718:32001 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -CALLBACK, event 0, msg length 267, bvci 0x1002 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 267 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 271 -00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31 - -result (LL11 DNS RESP (DL)) = 271 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 12 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 12 - TLLI patched (SGSN): 12 - P-TMSI patched (SGSN): 2 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 23 -00 00 00 00 2c 1f 84 e0 98 76 54 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 12 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 13 - TLLI patched (SGSN): 12 - P-TMSI patched (SGSN): 2 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING LLC_DISCARDED from 0x15161718:32001 -00 00 00 00 2c 1f 84 e0 98 76 54 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 e0 98 76 54 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x0000, msg length 25 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 29 -00 00 00 00 41 07 81 27 15 93 2c 1f 84 e0 98 76 54 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 29 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 12 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 13 - TLLI patched (SGSN): 13 - P-TMSI patched (SGSN): 2 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING BVC_SUSPEND from 0x01020304:1111 -00 00 00 00 0b 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 - -CALLBACK, event 0, msg length 15, bvci 0x0000 -00 00 00 00 0b 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 19 -00 00 00 00 0b 1f 84 e0 98 76 54 1b 86 21 63 54 40 50 60 - -result (BVC_SUSPEND) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 14 - TLLI patched (SGSN): 13 - P-TMSI patched (SGSN): 2 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING BVC_SUSPEND_ACK from 0x15161718:32001 -00 00 00 00 0c 1f 84 e0 98 76 54 1b 86 21 63 54 40 50 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 e0 98 76 54 1b 86 21 63 54 40 50 60 1d 81 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 22 -00 00 00 00 0c 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 22 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 14 - TLLI patched (SGSN): 14 - P-TMSI patched (SGSN): 2 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 ---- Establish GPRS connection (SGSN 2, P-TMSI collision) --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 fe ed 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 b6 bb - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 fe ed 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 b6 bb - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 fe ed 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 14 - TLLI patched (SGSN): 14 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 3 - TLLI-Cache: 3 - TLLI 8000feed -> 78dead04, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress, SGSN NSEI 65535 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 fe ed 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 25 08 16 08 11 12 99 99 99 26 27 28 58 c7 cb - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 fe ed 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 25 08 16 08 11 12 99 99 99 26 27 28 58 c7 cb - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 79 -00 00 10 02 01 78 de ad 04 00 00 04 08 88 21 63 54 00 63 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 b6 bb - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 14 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 15 - TLLI patched (SGSN): 14 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 3 - TLLI-Cache: 3 - TLLI 8000feed -> 78dead04, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING IDENT REQUEST from 0x15161718:32001 -00 00 10 02 00 78 de ad 04 00 50 20 16 82 02 58 0e 89 41 c0 19 08 15 01 a2 f2 a4 - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 78 de ad 04 00 50 20 16 82 02 58 0e 89 41 c0 19 08 15 01 a2 f2 a4 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 80 00 fe ed 00 50 20 16 82 02 58 0e 89 41 c0 19 08 15 01 a2 f2 a4 - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 14 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 15 - TLLI patched (SGSN): 15 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 3 - TLLI-Cache: 3 - TLLI 8000feed -> 78dead04, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 fe ed 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 29 08 16 08 11 12 99 99 99 26 27 28 4f d6 20 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 fe ed 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 29 08 16 08 11 12 99 99 99 26 27 28 4f d6 20 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 44 -00 00 10 02 01 78 de ad 04 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 29 08 16 08 11 12 99 99 99 26 27 28 4f d6 20 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 15 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 16 - TLLI patched (SGSN): 15 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 3 - TLLI-Cache: 3 - TLLI 8000feed -> 78dead04, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING ATTACH ACCEPT (P-TMSI 1) from 0x15161718:32001 -00 00 10 02 00 78 de ad 04 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 9e 41 c0 1d 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 74 91 01 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 78 de ad 04 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 9e 41 c0 1d 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 74 91 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 80 00 fe ed 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 9e 41 c0 1d 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 05 3e 78 6e - -result (ATTACH ACCEPT (P-TMSI 1)) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 15 - RAID patched (SGSN): 5 - TLLI patched (BSS ): 16 - TLLI patched (SGSN): 16 - P-TMSI patched (SGSN): 3 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 2 - TLLI cache size : 3 - TLLI-Cache: 3 - TLLI 8000feed/c0dead05 -> 78dead04/efe2b700, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 05 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 2d 08 03 43 50 ea - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 c0 de ad 05 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 2d 08 03 43 50 ea - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 2d 08 03 43 50 ea - -result (ATTACH COMPLETE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 16 - RAID patched (SGSN): 5 - TLLI patched (BSS ): 17 - TLLI patched (SGSN): 16 - P-TMSI patched (SGSN): 3 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - TLLI cache size : 3 - TLLI-Cache: 3 - TLLI 8000feed/c0dead05 -> 78dead04/efe2b700, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING GMM INFO from 0x15161718:32001 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 88 41 c0 21 08 21 ca 60 90 - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 88 41 c0 21 08 21 ca 60 90 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 c0 de ad 05 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 88 41 c0 21 08 21 ca 60 90 - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 16 - RAID patched (SGSN): 5 - TLLI patched (BSS ): 17 - TLLI patched (SGSN): 17 - P-TMSI patched (SGSN): 3 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - TLLI cache size : 3 - TLLI-Cache: 3 - TLLI c0dead05 -> efe2b700, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 ---- Shutdown GPRS connection (SGSN 1) --- - -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 31 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 57 e6 15 - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 31 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 57 e6 15 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 48 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 31 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 57 e6 15 - -result (DETACH REQ) = 48 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 17 - RAID patched (SGSN): 5 - TLLI patched (BSS ): 18 - TLLI patched (SGSN): 17 - P-TMSI patched (SGSN): 3 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 1 - TLLI cache size : 3 - TLLI-Cache: 3 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0, SGSN NSEI 256 - TLLI c0dead05 -> efe2b700, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 -PROCESSING DETACH ACC from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 25 08 06 00 4d 09 cd - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 25 08 06 00 4d 09 cd - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 25 08 06 00 4d 09 cd - -result (DETACH ACC) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 17 - RAID patched (SGSN): 5 - TLLI patched (BSS ): 18 - TLLI patched (SGSN): 18 - P-TMSI patched (SGSN): 3 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI c0dead05 -> efe2b700, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 ---- Shutdown GPRS connection (SGSN 2) --- - -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 35 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 83 cb f7 - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 35 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 83 cb f7 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 48 -00 00 10 02 01 e0 98 76 54 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 35 08 05 01 18 05 f4 e0 98 76 54 19 03 b9 97 cb b4 31 31 - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 18 - RAID patched (SGSN): 5 - TLLI patched (BSS ): 19 - TLLI patched (SGSN): 18 - P-TMSI patched (BSS ): 1 - P-TMSI patched (SGSN): 3 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 2 - Detach Accept count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI c0dead03 -> e0987654, IMSI 12199999961718, AGE 0, IMSI matches, SGSN NSEI 258 - TLLI c0dead05 -> efe2b700, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 -PROCESSING DETACH ACC from 0x15161718:32001 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 89 41 c0 29 08 06 00 be c3 6f - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 89 41 c0 29 08 06 00 be c3 6f - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 89 41 c0 29 08 06 00 be c3 6f - -result (DETACH ACC) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 18 - RAID patched (SGSN): 5 - TLLI patched (BSS ): 19 - TLLI patched (SGSN): 19 - P-TMSI patched (BSS ): 1 - P-TMSI patched (SGSN): 3 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 2 - Detach Accept count : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead05 -> efe2b700, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 ---- Shutdown GPRS connection (SGSN 2, P-TMSI 1) --- - -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 05 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 39 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 44 b6 8a - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 05 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 39 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 44 b6 8a - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 48 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 39 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 44 b6 8a - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 19 - RAID patched (SGSN): 5 - TLLI patched (BSS ): 20 - TLLI patched (SGSN): 19 - P-TMSI patched (BSS ): 1 - P-TMSI patched (SGSN): 3 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 3 - Detach Accept count : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead05 -> efe2b700, IMSI 12199999962728, AGE 0, IMSI matches, SGSN NSEI 258 -PROCESSING DETACH ACC from 0x15161718:32001 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 89 41 c0 2d 08 06 00 86 7c c7 - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 89 41 c0 2d 08 06 00 86 7c c7 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 c0 de ad 05 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 89 41 c0 2d 08 06 00 86 7c c7 - -result (DETACH ACC) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 19 - RAID patched (SGSN): 5 - TLLI patched (BSS ): 20 - TLLI patched (SGSN): 20 - P-TMSI patched (BSS ): 1 - P-TMSI patched (SGSN): 3 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 3 - Detach Accept count : 3 - TLLI-Cache: 0 -Gbproxy global: - Invalid BVC Identifier : 1 - BSSGP protocol error (SGSN): 2 - Patch error: no peer : 1 -=== test_gbproxy_keep_info === ---- Initialise SGSN --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 44 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -result (IDENT RESPONSE) = 44 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 48 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de - -result (DETACH REQ) = 48 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - Detach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee - -result (DETACH ACC) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 15 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e6 71 c7 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 15 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e6 71 c7 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 15 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e6 71 c7 - -result (ATTACH REQUEST) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 19 08 03 32 f1 bc - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 19 08 03 32 f1 bc - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 19 08 03 32 f1 bc - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ (re-attach) from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 15 08 05 01 25 0a 67 0e 96 - -CALLBACK, event 0, msg length 69, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 15 08 05 01 25 0a 67 0e 96 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 73 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 15 08 05 01 25 0a 67 0e 96 - -result (DETACH REQ (re-attach)) = 73 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 1d 08 06 3d 1c 8b - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 1d 08 06 3d 1c 8b - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 1d 08 06 3d 1c 8b - -result (DETACH ACC) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 db cc - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 db cc - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 db cc - -result (ATTACH REQUEST) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 3 - Attach Accept count : 2 - Attach Completed count : 2 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 19 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 27 3c 84 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 19 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 27 3c 84 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 19 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 27 3c 84 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 2 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 25 08 03 9b c6 47 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 25 08 03 9b c6 47 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 25 08 03 9b c6 47 - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 1d 08 05 02 25 0a dd 56 6c - -CALLBACK, event 0, msg length 69, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 1d 08 05 02 25 0a dd 56 6c - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 73 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 1d 08 05 02 25 0a dd 56 6c - -result (DETACH REQ) = 73 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 29 08 06 4c bd dd - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 29 08 06 4c bd dd - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 29 08 06 4c bd dd - -result (DETACH ACC) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 3 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST (IMSI) from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 37 01 c0 2d 08 01 02 f5 e0 21 08 02 08 11 12 13 14 15 16 17 18 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 a5 85 76 - -CALLBACK, event 0, msg length 78, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 37 01 c0 2d 08 01 02 f5 e0 21 08 02 08 11 12 13 14 15 16 17 18 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 a5 85 76 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 78 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 82 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 37 01 c0 2d 08 01 02 f5 e0 21 08 02 08 11 12 13 14 15 16 17 18 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 a5 85 76 - -result (ATTACH REQUEST (IMSI)) = 82 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 4 - Attach Accept count : 3 - Attach Completed count : 3 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 21 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 cf 80 6e - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 21 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 cf 80 6e - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 21 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 cf 80 6e - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 4 - Attach Accept count : 4 - Attach Completed count : 3 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 31 08 03 fc 2b 11 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 31 08 03 fc 2b 11 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 31 08 03 fc 2b 11 - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 4 - Attach Accept count : 4 - Attach Completed count : 4 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 25 08 05 02 25 0a 8e ee 85 - -CALLBACK, event 0, msg length 69, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 25 08 05 02 25 0a 8e ee 85 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 73 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 25 08 05 02 25 0a 8e ee 85 - -result (DETACH REQ) = 73 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 4 - Attach Accept count : 4 - Attach Completed count : 4 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 35 08 06 f3 c6 26 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 35 08 06 f3 c6 26 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 35 08 06 f3 c6 26 - -result (DETACH ACC) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 4 - Attach Accept count : 4 - Attach Completed count : 4 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 39 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e4 85 12 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 39 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e4 85 12 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 39 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e4 85 12 - -result (ATTACH REQUEST) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 5 - Attach Accept count : 4 - Attach Completed count : 4 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 29 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 d2 d1 3e - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 29 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 d2 d1 3e - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 29 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 d2 d1 3e - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 5 - Attach Accept count : 5 - Attach Completed count : 4 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 3d 08 03 48 76 ea - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 3d 08 03 48 76 ea - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 3d 08 03 48 76 ea - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 5 - Attach Accept count : 5 - Attach Completed count : 5 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING RA UPD REQ from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 41 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 30 73 32 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 41 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 30 73 32 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 89 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 41 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 30 73 32 - -result (RA UPD REQ) = 89 - -PROCESSING RA UDP REJ from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8a 41 c0 2d 08 0b 0a 00 41 30 a7 - -CALLBACK, event 0, msg length 68, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8a 41 c0 2d 08 0b 0a 00 41 30 a7 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 68 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 72 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8a 41 c0 2d 08 0b 0a 00 41 30 a7 - -result (RA UDP REJ) = 72 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 5 - Attach Accept count : 5 - Attach Completed count : 5 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 45 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 50 cc c3 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 45 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 50 cc c3 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 6 - Attach Accept count : 5 - Attach Completed count : 5 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI afe2b700 -> afe2b700, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 49 08 16 08 11 12 13 14 15 16 17 18 86 ca 3f - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 49 08 16 08 11 12 13 14 15 16 17 18 86 ca 3f - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 45 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 50 cc c3 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 6 - Attach Accept count : 5 - Attach Completed count : 5 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 31 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 f5 22 ce - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 31 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 f5 22 ce - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 31 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 f5 22 ce - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 6 - Attach Accept count : 6 - Attach Completed count : 5 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 4d 08 03 79 84 ea - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 4d 08 03 79 84 ea - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 4d 08 03 79 84 ea - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 6 - Attach Accept count : 6 - Attach Completed count : 6 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 35 08 05 02 25 0a 9b fa 57 - -CALLBACK, event 0, msg length 69, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 35 08 05 02 25 0a 9b fa 57 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 73 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 35 08 05 02 25 0a 9b fa 57 - -result (DETACH REQ) = 73 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 6 - Attach Accept count : 6 - Attach Completed count : 6 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 51 08 06 a5 d9 70 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 51 08 06 a5 d9 70 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 51 08 06 a5 d9 70 - -result (DETACH ACC) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 6 - Attach Accept count : 6 - Attach Completed count : 6 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST (local TLLI) from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 55 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 f9 cc e9 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 55 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 f9 cc e9 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 55 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 f9 cc e9 - -result (ATTACH REQUEST (local TLLI)) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 7 - Attach Accept count : 6 - Attach Completed count : 6 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 39 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 e8 73 9e - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 39 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 e8 73 9e - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 39 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 e8 73 9e - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 7 - Attach Accept count : 7 - Attach Completed count : 6 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 59 08 03 1e 69 bc - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 59 08 03 1e 69 bc - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 59 08 03 1e 69 bc - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 7 - Attach Accept count : 7 - Attach Completed count : 7 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ (re-attach) from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 3d 08 05 01 25 0a 21 a2 ad - -CALLBACK, event 0, msg length 69, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 3d 08 05 01 25 0a 21 a2 ad - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 73 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 3d 08 05 01 25 0a 21 a2 ad - -result (DETACH REQ (re-attach)) = 73 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 7 - Attach Accept count : 7 - Attach Completed count : 7 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 5d 08 06 11 84 8b - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 5d 08 06 11 84 8b - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 5d 08 06 11 84 8b - -result (DETACH ACC) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 7 - Attach Accept count : 7 - Attach Completed count : 7 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 61 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 5b 66 e2 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 61 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 5b 66 e2 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 61 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 5b 66 e2 - -result (ATTACH REQUEST) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 8 - Attach Accept count : 7 - Attach Completed count : 7 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 41 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 9e 50 40 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 41 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 9e 50 40 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 41 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 9e 50 40 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 8 - Attach Accept count : 8 - Attach Completed count : 7 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 65 08 03 b7 5e 47 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 65 08 03 b7 5e 47 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 65 08 03 b7 5e 47 - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 8 - Attach Accept count : 8 - Attach Completed count : 8 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 45 08 21 9c 7f c6 - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 45 08 21 9c 7f c6 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 45 08 21 9c 7f c6 - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 8 - Attach Accept count : 8 - Attach Completed count : 8 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH REQUEST (unexpected, IMSI) from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 37 01 c0 69 08 01 02 f5 e0 21 08 02 08 11 12 13 14 15 16 17 18 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e1 11 8e - -CALLBACK, event 0, msg length 78, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 37 01 c0 69 08 01 02 f5 e0 21 08 02 08 11 12 13 14 15 16 17 18 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e1 11 8e - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 78 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 82 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 37 01 c0 69 08 01 02 f5 e0 21 08 02 08 11 12 13 14 15 16 17 18 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e1 11 8e - -result (ATTACH REQUEST (unexpected, IMSI)) = 82 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 9 - Attach Accept count : 8 - Attach Completed count : 8 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 49 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 83 01 10 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 49 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 83 01 10 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 49 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 83 01 10 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 9 - Attach Accept count : 9 - Attach Completed count : 8 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 6d 08 03 6f c8 ea - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 6d 08 03 6f c8 ea - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 6d 08 03 6f c8 ea - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 9 - Attach Accept count : 9 - Attach Completed count : 9 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 4d 08 05 02 25 0a 51 0e 1b - -CALLBACK, event 0, msg length 69, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 4d 08 05 02 25 0a 51 0e 1b - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 73 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 4d 08 05 02 25 0a 51 0e 1b - -result (DETACH REQ) = 73 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 9 - Attach Accept count : 9 - Attach Completed count : 9 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 71 08 06 b3 95 70 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 71 08 06 b3 95 70 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 71 08 06 b3 95 70 - -result (DETACH ACC) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 9 - Attach Accept count : 9 - Attach Completed count : 9 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 75 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 ab 17 53 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 75 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 ab 17 53 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 75 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 ab 17 53 - -result (ATTACH REQUEST) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 10 - Attach Accept count : 9 - Attach Completed count : 9 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 51 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 a4 f2 e0 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 51 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 a4 f2 e0 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 51 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 a4 f2 e0 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 10 - Attach Accept count : 10 - Attach Completed count : 9 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 79 08 03 08 25 bc - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 79 08 03 08 25 bc - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 79 08 03 08 25 bc - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 10 - Attach Accept count : 10 - Attach Completed count : 10 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 55 08 21 97 59 c6 - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 55 08 21 97 59 c6 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 70 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 55 08 21 97 59 c6 - -result (GMM INFO) = 70 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 10 - Attach Accept count : 10 - Attach Completed count : 10 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH REQUEST (unexpected) from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 7d 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 a2 24 d0 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 7d 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 a2 24 d0 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 7d 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 a2 24 d0 - -result (ATTACH REQUEST (unexpected)) = 79 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 11 - Attach Accept count : 10 - Attach Completed count : 10 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 59 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 b9 a3 b0 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 59 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 b9 a3 b0 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 92 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 59 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 b9 a3 b0 - -result (ATTACH ACCEPT) = 92 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 11 - Attach Accept count : 11 - Attach Completed count : 10 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 81 08 03 b9 71 10 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 81 08 03 b9 71 10 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 81 08 03 b9 71 10 - -result (ATTACH COMPLETE) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 11 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700/efe2b700 -> afe2b700/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x05060708:32000 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 5d 08 05 02 25 0a 44 1a c9 - -CALLBACK, event 0, msg length 69, bvci 0x1002 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 5d 08 05 02 25 0a 44 1a c9 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 73 -00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 5d 08 05 02 25 0a 44 1a c9 - -result (DETACH REQ) = 73 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 11 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x01020304:1111 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 85 08 06 b6 9c 27 - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 85 08 06 b6 9c 27 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 85 08 06 b6 9c 27 - -result (DETACH ACC) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 11 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 89 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 21 24 df - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 89 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 21 24 df - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 12 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 8d 08 16 08 11 12 13 14 15 16 17 18 74 ac 38 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 8d 08 16 08 11 12 13 14 15 16 17 18 74 ac 38 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 89 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 21 24 df - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 12 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH REJECT from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 61 08 04 07 79 ba a5 - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 61 08 04 07 79 ba a5 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 71 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 61 08 04 07 79 ba a5 - -result (ATTACH REJECT) = 71 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 12 - Attach Reject count : 1 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 91 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 81 7a 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 91 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 81 7a 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 13 - Attach Reject count : 1 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress -PROCESSING DETACH REQ (MO) from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 95 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 9c dc fc - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 95 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 9c dc fc - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 00 09 41 c4 05 08 06 00 29 4a 68 - -result (DETACH REQ (MO)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 13 - Attach Reject count : 1 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 2 - Detach Accept count : 1 - TLLI-Cache: 0 -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 99 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 88 49 82 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 99 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 88 49 82 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 14 - Attach Reject count : 1 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 2 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress -PROCESSING DETACH REQ (MT) from 0x05060708:32000 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 65 08 05 02 25 0a 17 a2 20 - -CALLBACK, event 0, msg length 69, bvci 0x1002 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 65 08 05 02 25 0a 17 a2 20 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 73 -00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 65 08 05 02 25 0a 17 a2 20 - -result (DETACH REQ (MT)) = 73 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 14 - Attach Reject count : 1 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 2 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI afe2b700 -> afe2b700, IMSI 12131415161718, AGE 0, STORED 1, IMSI acquisition in progress -PROCESSING DETACH ACC from 0x01020304:1111 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 9d 08 06 65 2c 8a - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 9d 08 06 65 2c 8a - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 99 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 88 49 82 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 35 -00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 9d 08 06 65 2c 8a - -result (DETACH ACC) = 35 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 14 - Attach Reject count : 1 - Attach Accept count : 11 - Attach Completed count : 11 - RoutingArea Update Request count: 1 - RoutingArea Update Reject count : 1 - Detach Request count : 2 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 00000000, IMSI 12131415161718, AGE 0, DE-REGISTERED -Gbproxy global: -Test TLLI info expiry - -Test TLLI replacement: - Add TLLI 1, IMSI 1 - Add TLLI 2, IMSI 1 (should replace TLLI 1) - Peers: - NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c000162e, IMSI 03242526, AGE 0, IMSI matches - -Test IMSI replacement: - Add TLLI 1, IMSI 1 - Add TLLI 1, IMSI 2 (should replace IMSI 1) - Peers: - NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c00004d2, IMSI 06272829, AGE 0, IMSI matches - -Test TLLI expiry, max_len == 1: - Add TLLI 1, IMSI 1 - Add TLLI 2, IMSI 2 (should replace IMSI 1) - Peers: - NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c000162e, IMSI 06272829, AGE 0, IMSI matches - -Test TLLI expiry, max_age == 1: - Add TLLI 1, IMSI 1 (should expire after timeout) - Add TLLI 2, IMSI 2 (should not expire after timeout) - Peers: - NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c000162e, IMSI 06272829, AGE 1, IMSI matches - -Test TLLI expiry, max_len == 2, max_age == 1: - Add TLLI 1, IMSI 1 (should expire) - Add TLLI 2, IMSI 2 (should expire after timeout) - Add TLLI 3, IMSI 3 (should not expire after timeout) - Peers: - NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0 - TLLI cache size : 3 - TLLI-Cache: 3 - TLLI c0000d80, IMSI 12345678, AGE 0, IMSI matches - TLLI c000162e, IMSI 06272829, AGE 1, IMSI matches - TLLI c00004d2, IMSI 03242526, AGE 2, IMSI matches - Remove stale TLLIs - Peers: - NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0000d80, IMSI 12345678, AGE 0, IMSI matches - -=== test_gbproxy_stored_messages === ---- Initialise SGSN --- - -MESSAGE to SGSN at 0x05060708:32000, msg length 12 -02 00 81 01 01 82 01 01 04 82 01 00 - -PROCESSING RESET_ACK from 0x05060708:32000 -03 01 82 01 01 04 82 01 00 - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0a - -result (RESET_ACK) = 1 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 1 - -PROCESSING UNBLOCK_ACK from 0x05060708:32000 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x05060708:32000 -0a - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -0b - -result (ALIVE) = 1 - ---- Initialise BSS 1 --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 9 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 1 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -result (UNBLOCK) = 1 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 22 -00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 22 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 9 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Establish first LLC connection --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 8000dead, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 27 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -result (IDENT REQUEST) = 27 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 8000dead, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress -PROCESSING DETACH ACCEPT from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 09 01 c0 05 08 06 00 f8 92 41 - -CALLBACK, event 0, msg length 32, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 09 01 c0 05 08 06 00 f8 92 41 - -result (DETACH ACCEPT) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 8000dead, IMSI (none), AGE 0, STORED 2, IMSI acquisition in progress -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI-Cache: 0 -Gbproxy global: -===== GbProxy test END - diff --git a/tests/gprs/Makefile.am b/tests/gprs/Makefile.am deleted file mode 100644 index 902313f2a..000000000 --- a/tests/gprs/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) - -EXTRA_DIST = gprs_test.ok - -noinst_PROGRAMS = gprs_test - -gprs_test_SOURCES = gprs_test.c $(top_srcdir)/src/gprs/gprs_utils.c - -gprs_test_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) diff --git a/tests/gprs/gprs_test.c b/tests/gprs/gprs_test.c deleted file mode 100644 index aac9bb896..000000000 --- a/tests/gprs/gprs_test.c +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include -#include - -#include -#include - -#include - -#include -#include - -#define ASSERT_FALSE(x) if (x) { printf("Should have returned false.\n"); abort(); } -#define ASSERT_TRUE(x) if (!x) { printf("Should have returned true.\n"); abort(); } - -/** - * GSM 04.64 8.4.2 Receipt of unacknowledged information - */ -static int nu_is_retransmission(uint16_t nu, uint16_t vur) -{ - int ret = gprs_llc_is_retransmit(nu, vur); - printf("N(U) = %d, V(UR) = %d => %s\n", nu, vur, - ret == 1 ? "retransmit" : "new"); - return ret; -} - -static void test_8_4_2() -{ - printf("Testing gprs_llc_is_retransmit.\n"); - - ASSERT_FALSE(nu_is_retransmission(0, 0)); - ASSERT_TRUE (nu_is_retransmission(0, 1)); - - /* expect 1... check for retransmissions */ - ASSERT_TRUE (nu_is_retransmission(0, 1)); - ASSERT_TRUE (nu_is_retransmission(511, 1)); - ASSERT_TRUE (nu_is_retransmission(483, 1)); - ASSERT_TRUE (nu_is_retransmission(482, 1)); - ASSERT_FALSE(nu_is_retransmission(481, 1)); - - /* expect 511... check for retransmissions */ - ASSERT_FALSE(nu_is_retransmission(0, 240)); // ahead - ASSERT_FALSE(nu_is_retransmission(0, 511)); // ahead - ASSERT_FALSE(nu_is_retransmission(1, 511)); // ahead - ASSERT_FALSE(nu_is_retransmission(511, 511)); // same - ASSERT_TRUE (nu_is_retransmission(510, 511)); // behind - ASSERT_TRUE (nu_is_retransmission(481, 511)); // behind - ASSERT_FALSE(nu_is_retransmission(479, 511)); // wrapped -} - -static void test_gprs_timer_enc_dec(void) -{ - int i, u, secs, tmr; - const int upper_secs_test_limit = 12000; - int dec_secs, last_dec_secs = -1; - - printf("Test GPRS timer decoding/encoding\n"); - - /* Check gprs_tmr_to_secs with all 256 encoded values */ - for (u = 0; u <= GPRS_TMR_DEACTIVATED; u += 32) { - fprintf(stderr, "Testing decoding with timer value unit %u\n", - u / 32); - for (i = 0; i < 32; i++) { - switch (u) { - case GPRS_TMR_2SECONDS: - OSMO_ASSERT(gprs_tmr_to_secs(u + i) == 2 * i); - break; - - default: - case GPRS_TMR_MINUTE: - OSMO_ASSERT(gprs_tmr_to_secs(u + i) == 60 * i); - break; - - case GPRS_TMR_6MINUTE: - OSMO_ASSERT(gprs_tmr_to_secs(u + i) == 360 * i); - break; - - case GPRS_TMR_DEACTIVATED: - OSMO_ASSERT(gprs_tmr_to_secs(u + i) == -1); - break; - } - - OSMO_ASSERT(gprs_tmr_to_secs(u + i) < upper_secs_test_limit); - } - } - - /* Check gprs_secs_to_tmr_floor for secs that can exactly be - * represented as GPRS timer values */ - for (i = 0; i < GPRS_TMR_DEACTIVATED; i++) { - int j; - secs = gprs_tmr_to_secs(i); - tmr = gprs_secs_to_tmr_floor(secs); - OSMO_ASSERT(secs == gprs_tmr_to_secs(tmr)); - - /* Check that the highest resolution is used */ - for (j = 0; j < tmr; j++) - OSMO_ASSERT(secs != gprs_tmr_to_secs(j)); - } - OSMO_ASSERT(GPRS_TMR_DEACTIVATED == gprs_secs_to_tmr_floor(-1)); - - /* Check properties of gprs_secs_to_tmr_floor */ - for (secs = 0; secs <= upper_secs_test_limit; secs++) { - int tmr = gprs_secs_to_tmr_floor(secs); - int delta_secs = gprs_tmr_to_secs((tmr & ~0x1f) | 1); - dec_secs = gprs_tmr_to_secs(tmr); - - /* Check floor */ - OSMO_ASSERT(dec_secs <= secs); - /* Check monotonicity */ - OSMO_ASSERT(dec_secs >= last_dec_secs); - /* Check max distance (<= resolution) */ - OSMO_ASSERT(dec_secs - last_dec_secs <= delta_secs); - - last_dec_secs = dec_secs; - } -} - -const struct log_info_cat default_categories[] = { - [DGPRS] = { - .name = "DGPRS", - .description = "GPRS Packet Service", - .enabled = 0, .loglevel = LOGL_DEBUG, - }, -}; - -static struct log_info info = { - .cat = default_categories, - .num_cat = ARRAY_SIZE(default_categories), -}; - -int main(int argc, char **argv) -{ - osmo_init_logging(&info); - - test_8_4_2(); - test_gprs_timer_enc_dec(); - - printf("Done.\n"); - return EXIT_SUCCESS; -} diff --git a/tests/gprs/gprs_test.ok b/tests/gprs/gprs_test.ok deleted file mode 100644 index da7888c6a..000000000 --- a/tests/gprs/gprs_test.ok +++ /dev/null @@ -1,17 +0,0 @@ -Testing gprs_llc_is_retransmit. -N(U) = 0, V(UR) = 0 => new -N(U) = 0, V(UR) = 1 => retransmit -N(U) = 0, V(UR) = 1 => retransmit -N(U) = 511, V(UR) = 1 => retransmit -N(U) = 483, V(UR) = 1 => retransmit -N(U) = 482, V(UR) = 1 => retransmit -N(U) = 481, V(UR) = 1 => new -N(U) = 0, V(UR) = 240 => new -N(U) = 0, V(UR) = 511 => new -N(U) = 1, V(UR) = 511 => new -N(U) = 511, V(UR) = 511 => new -N(U) = 510, V(UR) = 511 => retransmit -N(U) = 481, V(UR) = 511 => retransmit -N(U) = 479, V(UR) = 511 => new -Test GPRS timer decoding/encoding -Done. diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c index fcdc8f8ed..d9ff305ef 100644 --- a/tests/gsm0408/gsm0408_test.c +++ b/tests/gsm0408/gsm0408_test.c @@ -25,8 +25,6 @@ #include #include -#include -#include #include #include #include @@ -36,6 +34,7 @@ #include #include +#include #define COMPARE(result, op, value) \ if (!((result) op (value))) {\ @@ -648,6 +647,7 @@ static void test_si_range_helpers() VERIFY(f0, ==, 1); } +#ifdef BEFORE_MSCSPLIT static void test_gsm411_rp_ref_wrap(void) { struct gsm_subscriber_connection conn; @@ -670,6 +670,7 @@ static void test_gsm411_rp_ref_wrap(void) printf("Allocated reference: %d\n", res); OSMO_ASSERT(res == 1); } +#endif int main(int argc, char **argv) { @@ -683,7 +684,9 @@ int main(int argc, char **argv) test_arfcn_filter(); test_print_encoding(); test_range_encoding(); +#ifdef BEFORE_MSCSPLIT test_gsm411_rp_ref_wrap(); +#endif test_si2q_segfault(); test_si2q_e(); diff --git a/tests/gtphub/Makefile.am b/tests/gtphub/Makefile.am deleted file mode 100644 index f2a6b888e..000000000 --- a/tests/gtphub/Makefile.am +++ /dev/null @@ -1,44 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBGTP_CFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - gtphub_test.ok \ - $(NULL) - -if HAVE_LIBGTP -if HAVE_LIBCARES -noinst_PROGRAMS = \ - gtphub_test \ - $(NULL) -endif -endif - -gtphub_test_SOURCES = \ - gtphub_test.c \ - $(NULL) - -gtphub_test_LDFLAGS = \ - -Wl,--wrap=gtphub_resolve_ggsn_addr \ - -Wl,--wrap=gtphub_ares_init \ - -Wl,--wrap=gtphub_write \ - $(NULL) - -gtphub_test_LDADD = \ - $(top_builddir)/src/gprs/gtphub.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBGTP_LIBS) \ - -lrt \ - $(NULL) diff --git a/tests/gtphub/gtphub_test.c b/tests/gtphub/gtphub_test.c deleted file mode 100644 index e7c27d2cb..000000000 --- a/tests/gtphub/gtphub_test.c +++ /dev/null @@ -1,1786 +0,0 @@ -/* Test the GTP hub */ - -/* (C) 2015 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#define ZERO_STRUCT(struct_pointer) memset(struct_pointer, '\0', \ - sizeof(*(struct_pointer))) - -#define LVL2_ASSERT(exp) LVL2_ASSERT_R(exp, return 0) -#define LVL2_ASSERT_R(exp, ret) \ - if (!(exp)) { \ - fprintf(stderr, "LVL2 Assert failed %s %s:%d\n", #exp, \ - __FILE__, __LINE__); \ - osmo_generate_backtrace(); \ - ret; \ - } - -/* Convenience makro, note: only within this C file. */ -#define LOG(label) \ - { fprintf(stderr, "\n" label "\n"); \ - printf(label "\n"); } - -void gtphub_init(struct gtphub *hub); -void gtphub_free(struct gtphub *hub); - -void *osmo_gtphub_ctx; - -static void nr_mapping_free(struct expiring_item *e) -{ - struct nr_mapping *m = container_of(e, struct nr_mapping, - expiry_entry); - nr_mapping_del(m); - talloc_free(m); -} - -static struct nr_mapping *nr_mapping_alloc(void) -{ - struct nr_mapping *m; - m = talloc(osmo_gtphub_ctx, struct nr_mapping); - nr_mapping_init(m); - m->expiry_entry.del_cb = nr_mapping_free; - return m; -} - -static struct nr_mapping *nr_map_have(struct nr_map *map, void *origin, - nr_t orig, time_t now) -{ - struct nr_mapping *mapping; - - mapping = nr_map_get(map, origin, orig); - if (!mapping) { - mapping = nr_mapping_alloc(); - mapping->origin = origin; - mapping->orig = orig; - nr_map_add(map, mapping, now); - } - - return mapping; -} - -static nr_t nr_map_verify(const struct nr_map *map, void *origin, nr_t orig, - nr_t expect_repl) -{ - struct nr_mapping *m; - m = nr_map_get(map, origin, orig); - - if (!m) { - printf("mapping not found for %p %d\n", origin, orig); - return 0; - } - - if (m->repl != expect_repl) { - printf("mapping found, but nr mismatches: expect %d, got %d\n", - (int)expect_repl, (int)m->repl); - return 0; - } - - return 1; -} - -static int nr_map_verify_inv(const struct nr_map *map, nr_t repl, - void *expect_origin, nr_t expect_orig) -{ - struct nr_mapping *m; - m = nr_map_get_inv(map, repl); - if (!m) { - printf("mapping not found for %d\n", (int)repl); - return 0; - } - - if (m->origin != expect_origin) { - printf("mapping found, but origin mismatches:" - " expect %p, got %p\n", - expect_origin, m->origin); - return 0; - } - - if (m->orig != expect_orig) { - printf("mapping found, but nr mismatches: expect %d, got %d\n", - (int)expect_orig, (int)m->orig); - return 0; - } - - return 1; -} - - -static void test_nr_map_basic(void) -{ - struct nr_pool _pool; - struct nr_pool *pool = &_pool; - struct nr_map _map; - struct nr_map *map = &_map; - - nr_pool_init(pool, 1, 1000); - nr_map_init(map, pool, NULL); - - OSMO_ASSERT(llist_empty(&map->mappings)); - -#define TEST_N_HALF 100 -#define TEST_N (2*TEST_N_HALF) -#define TEST_I 123 - uint32_t i, check_i; - uint32_t m[TEST_N]; - struct nr_mapping *mapping; - - /* create half of TEST_N mappings from one origin */ - void *origin1 = (void*)0x1234; - for (i = 0; i < TEST_N_HALF; i++) { - nr_t orig = TEST_I + i; - mapping = nr_map_have(map, origin1, orig, 0); - m[i] = mapping->repl; - OSMO_ASSERT(m[i] != 0); - OSMO_ASSERT(llist_count(&map->mappings) == (i+1)); - for (check_i = 0; check_i < i; check_i++) - OSMO_ASSERT(m[check_i] != m[i]); - } - OSMO_ASSERT(llist_count(&map->mappings) == TEST_N_HALF); - - /* create another TEST_N mappings with the same original numbers, but - * from a different origin */ - void *origin2 = (void*)0x5678; - for (i = 0; i < TEST_N_HALF; i++) { - int i2 = TEST_N_HALF + i; - nr_t orig = TEST_I + i; - mapping = nr_map_have(map, origin2, orig, 0); - m[i2] = mapping->repl; - OSMO_ASSERT(m[i2] != 0); - OSMO_ASSERT(llist_count(&map->mappings) == (i2+1)); - for (check_i = 0; check_i < i2; check_i++) - OSMO_ASSERT(m[check_i] != m[i2]); - } - OSMO_ASSERT(llist_count(&map->mappings) == TEST_N); - - /* verify mappings */ - for (i = 0; i < TEST_N_HALF; i++) { - nr_t orig = TEST_I + i; - { - OSMO_ASSERT(nr_map_verify(map, origin1, orig, m[i])); - OSMO_ASSERT(nr_map_verify_inv(map, m[i], origin1, - orig)); - } - { - int i2 = TEST_N_HALF + i; - OSMO_ASSERT(nr_map_verify(map, origin2, orig, m[i2])); - OSMO_ASSERT(nr_map_verify_inv(map, m[i2], origin2, - orig)); - } - } - - /* remove all mappings */ - for (i = 0; i < TEST_N_HALF; i++) { - OSMO_ASSERT(llist_count(&map->mappings) == (TEST_N - 2*i)); - - nr_t orig = TEST_I + i; - nr_mapping_del(nr_map_get(map, origin1, orig)); - nr_mapping_del(nr_map_get(map, origin2, orig)); - } - OSMO_ASSERT(llist_empty(&map->mappings)); -#undef TEST_N -#undef TEST_I -} - -static int nr_map_is(struct nr_map *map, const char *str) -{ - static char buf[4096]; - char *pos = buf; - size_t len = sizeof(buf); - struct nr_mapping *m; - llist_for_each_entry(m, &map->mappings, entry) { - size_t wrote = snprintf(pos, len, "(%u->%u@%d), ", - m->orig, - m->repl, - (int)m->expiry_entry.expiry); - OSMO_ASSERT(wrote < len); - pos += wrote; - len -= wrote; - } - *pos = '\0'; - - if (strncmp(buf, str, sizeof(buf)) != 0) { - printf("FAILURE: nr_map_is() mismatches expected value:\n" - "expected: \"%s\"\n" - "is: \"%s\"\n", - str, buf); - return 0; - } - return 1; -} - -static int test_nr_map_wrap_with(nr_t nr_min, nr_t nr_max, nr_t repl_last, - nr_t orig_start, int orig_n, - const char *expect) -{ - struct nr_pool _pool; - struct nr_pool *pool = &_pool; - struct nr_map _map; - struct nr_map *map = &_map; - - nr_pool_init(pool, nr_min, nr_max); - nr_map_init(map, pool, NULL); - - pool->last_nr = repl_last; - - void *origin = (void*)0x1234; - - int i; - for (i = 0; i < orig_n; i++) - LVL2_ASSERT(nr_map_have(map, origin, orig_start + i, 0)); - - LVL2_ASSERT(nr_map_is(map, expect)); - - nr_map_clear(map); - return 1; -} - -static void test_nr_map_wrap(void) -{ - OSMO_ASSERT(test_nr_map_wrap_with( - 0, UINT_MAX, UINT_MAX - 2, - 1, 5, - "(1->4294967294@0), " - "(2->4294967295@0), " - "(3->0@0), " - "(4->1@0), " - "(5->2@0), " - )); - OSMO_ASSERT(test_nr_map_wrap_with( - 5, 10, 8, - 1, 5, - "(1->9@0), (2->10@0), (3->5@0), (4->6@0), (5->7@0), " - )); -} - -static void test_expiry(void) -{ - struct expiry expiry; - struct nr_pool pool; - struct nr_map map; - int i; - - expiry_init(&expiry, 30); - nr_pool_init(&pool, 1, 1000); - nr_map_init(&map, &pool, &expiry); - OSMO_ASSERT(nr_map_is(&map, "")); - - /* tick on empty map */ - OSMO_ASSERT(expiry_tick(&expiry, 10000) == 0); - OSMO_ASSERT(nr_map_is(&map, "")); - -#define MAP1 \ - "(10->1@10040), " \ - "" - -#define MAP2 \ - "(20->2@10050), " \ - "(21->3@10051), " \ - "(22->4@10052), " \ - "(23->5@10053), " \ - "(24->6@10054), " \ - "(25->7@10055), " \ - "(26->8@10056), " \ - "(27->9@10057), " \ - "" - -#define MAP3 \ - "(420->10@10072), " \ - "(421->11@10072), " \ - "(422->12@10072), " \ - "(423->13@10072), " \ - "(424->14@10072), " \ - "(425->15@10072), " \ - "(426->16@10072), " \ - "(427->17@10072), " \ - "" - - /* add mapping at time 10010. */ - nr_map_have(&map, 0, 10, 10010); - OSMO_ASSERT(nr_map_is(&map, MAP1)); - - /* tick on unexpired item. */ - OSMO_ASSERT(expiry_tick(&expiry, 10010) == 0); - OSMO_ASSERT(expiry_tick(&expiry, 10011) == 0); - OSMO_ASSERT(nr_map_is(&map, MAP1)); - - /* Spread mappings at 10020, 10021, ... 10027. */ - for (i = 0; i < 8; i++) - nr_map_have(&map, 0, 20 + i, 10020 + i); - OSMO_ASSERT(nr_map_is(&map, MAP1 MAP2)); - - /* tick on unexpired items. */ - OSMO_ASSERT(expiry_tick(&expiry, 10030) == 0); - OSMO_ASSERT(expiry_tick(&expiry, 10039) == 0); - OSMO_ASSERT(nr_map_is(&map, MAP1 MAP2)); - - /* expire the first item (from 10010). */ - OSMO_ASSERT(expiry_tick(&expiry, 10010 + 30) == 1); - OSMO_ASSERT(nr_map_is(&map, MAP2)); - - /* again nothing to expire */ - OSMO_ASSERT(expiry_tick(&expiry, 10041) == 0); - OSMO_ASSERT(nr_map_is(&map, MAP2)); - - /* Mappings all at the same time. */ - for (i = 0; i < 8; i++) - nr_map_have(&map, 0, 420 + i, 10042); - OSMO_ASSERT(nr_map_is(&map, MAP2 MAP3)); - - /* Eight to expire, were added further above to be chronologically - * correct, at 10020..10027. */ - OSMO_ASSERT(expiry_tick(&expiry, 10027 + 30) == 8); - OSMO_ASSERT(nr_map_is(&map, MAP3)); - - /* again nothing to expire */ - OSMO_ASSERT(expiry_tick(&expiry, 10027 + 30) == 0); - OSMO_ASSERT(nr_map_is(&map, MAP3)); - - /* Eight to expire, from 10042. Now at 10042 + 30: */ - OSMO_ASSERT(expiry_tick(&expiry, 10042 + 30) == 8); - OSMO_ASSERT(nr_map_is(&map, "")); - -#undef MAP1 -#undef MAP2 -#undef MAP3 -} - -char resolve_ggsn_got_imsi[GSM23003_IMSI_MAX_DIGITS+1]; -char resolve_ggsn_got_ni[GSM_APN_LENGTH]; - -struct osmo_sockaddr resolved_ggsn_addr; -static int resolve_to_ggsn(const char *addr, uint16_t port) -{ - LVL2_ASSERT(osmo_sockaddr_init_udp(&resolved_ggsn_addr, - addr, port) - == 0); - return 1; -} - -struct osmo_sockaddr resolved_sgsn_addr; -static int resolve_to_sgsn(const char *addr, uint16_t port) -{ - LVL2_ASSERT(osmo_sockaddr_init_udp(&resolved_sgsn_addr, - addr, port) - == 0); - return 1; -} - -struct osmo_sockaddr sgsn_sender; -static int send_from_sgsn(const char *addr, uint16_t port) -{ - LVL2_ASSERT(osmo_sockaddr_init_udp(&sgsn_sender, - addr, port) - == 0); - return 1; -} - -struct osmo_sockaddr ggsn_sender; -static int send_from_ggsn(const char *addr, uint16_t port) -{ - LVL2_ASSERT(osmo_sockaddr_init_udp(&ggsn_sender, - addr, port) - == 0); - return 1; -} - - -/* override, requires '-Wl,--wrap=gtphub_resolve_ggsn_addr' */ -struct gtphub_peer_port *__real_gtphub_resolve_ggsn_addr(struct gtphub *hub, - const char *imsi_str, - const char *apn_ni_str); - -struct gtphub_peer_port *__wrap_gtphub_resolve_ggsn_addr(struct gtphub *hub, - const char *imsi_str, - const char *apn_ni_str) -{ - struct gsn_addr resolved_gsna; - uint16_t resolved_port; - - OSMO_ASSERT(gsn_addr_from_sockaddr(&resolved_gsna, &resolved_port, - &resolved_ggsn_addr) == 0); - - struct gtphub_peer_port *pp; - pp = gtphub_port_have(hub, &hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], - &resolved_gsna, resolved_port); - printf("- __wrap_gtphub_resolve_ggsn_addr():\n" - " returning GGSN addr from imsi %s ni %s: %s\n", - imsi_str, apn_ni_str, gtphub_port_str(pp)); - - if (!imsi_str) - imsi_str = "(null)"; - osmo_strlcpy(resolve_ggsn_got_imsi, imsi_str, - sizeof(resolve_ggsn_got_imsi)); - - if (!apn_ni_str) - apn_ni_str = "(null)"; - osmo_strlcpy(resolve_ggsn_got_ni, apn_ni_str, - sizeof(resolve_ggsn_got_ni)); - - return pp; -} - -#define was_resolved_for(IMSI,NI) _was_resolved_for(IMSI, NI, __FILE__, __LINE__) -static int _was_resolved_for(const char *imsi, const char *ni, const char - *file, int line) -{ - int cmp0 = strncmp(imsi, resolve_ggsn_got_imsi, - sizeof(resolve_ggsn_got_imsi)); - - if (cmp0 != 0) { - printf("\n%s:%d: was_resolved_for(): MISMATCH for IMSI\n" - " expecting: '%s'\n" - " got: '%s'\n\n", - file, - line, - imsi, resolve_ggsn_got_imsi); - } - - int cmp1 = strncmp(ni, resolve_ggsn_got_ni, - sizeof(resolve_ggsn_got_ni)); - if (cmp1 != 0) { - printf("\n%s:%d: was_resolved_for(): MISMATCH for NI\n" - " expecting: '%s'\n" - " got: '%s'\n\n", - file, - line, - ni, resolve_ggsn_got_ni); - } - - return (cmp0 == 0) && (cmp1 == 0); -} - -/* override, requires '-Wl,--wrap=gtphub_ares_init' */ -int __real_gtphub_ares_init(struct gtphub *hub); - -int __wrap_gtphub_ares_init(struct gtphub *hub) -{ - /* Do nothing. */ - return 0; -} - -/* override, requires '-Wl,--wrap=gtphub_write' */ -int __real_gtphub_write(const struct osmo_fd *to, - const struct osmo_sockaddr *to_addr, - const uint8_t *buf, size_t buf_len); - -int __wrap_gtphub_write(const struct osmo_fd *to, - const struct osmo_sockaddr *to_addr, - const uint8_t *buf, size_t buf_len) -{ - printf("Out-of-band gtphub_write(%d):\n" - "to %s\n" - "%s\n", - (int)buf_len, - osmo_sockaddr_to_str(to_addr), - osmo_hexdump(buf, buf_len)); - return 0; -} - -#define buf_len 1024 -static uint8_t buf[buf_len]; -static uint8_t *reply_buf; - -static unsigned int msg(const char *hex) -{ - unsigned int l = osmo_hexparse(hex, buf, buf_len); - OSMO_ASSERT(l > 0); - return l; -} - -/* Compare static buf to given string constant. The amount of bytes is obtained - * from parsing the GTP header in buf. hex must match an osmo_hexdump() of the - * desired message. Return 1 if size and content match. */ -#define reply_is(MSG) _reply_is(MSG, __FILE__, __LINE__) -static int _reply_is(const char *hex, const char *file, int line) -{ - struct gtp1_header_long *h = (void*)reply_buf; - int len = ntoh16(h->length) + 8; - const char *dump = osmo_hexdump_nospc(reply_buf, len); - int cmp = strcmp(dump, hex); - - if (cmp != 0) { - printf("\n%s:%d: reply_is(): MISMATCH\n" - " expecting:\n'%s'\n" - " got:\n'%s'\n\n", - file, - line, - hex, dump); - int i; - int l = strlen(hex); - int m = strlen(dump); - if (m < l) - l = m; - for (i = 0; i < l; i++) { - if (hex[i] != dump[i]) { - printf("First mismatch at position %d:\n" - " %s\n %s\n", i, hex + i, dump + i); - break; - } - } - } - return cmp == 0; -} - -#define same_addr(GOT, EXPECTED) _same_addr((GOT),(EXPECTED), __FILE__, __LINE__) -static int _same_addr(const struct osmo_sockaddr *got, - const struct osmo_sockaddr *expected, - const char *file, int line) -{ - int cmp = osmo_sockaddr_cmp(got, expected); - if (!cmp) - return 1; - char buf[256]; - printf("\n%s:%d: addr_is(): MISMATCH\n" - " expecting: '%s'\n" - " got: '%s'\n\n", - file, line, - osmo_sockaddr_to_str(expected), - osmo_sockaddr_to_strb(got, buf, sizeof(buf))); - return 0; -} - - -time_t now; -static struct gtphub _hub; -static struct gtphub *hub = &_hub; - -static int setup_test_hub() -{ - /* Not really needed, but to make 100% sure... */ - ZERO_STRUCT(hub); - - gtphub_init(hub); - - /* Tell this mock gtphub its local address for this test. */ - LVL2_ASSERT(gsn_addr_from_str(&hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].local_addr, - "127.0.1.1") == 0); - LVL2_ASSERT(gsn_addr_from_str(&hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].local_addr, - "127.0.1.2") == 0); - LVL2_ASSERT(gsn_addr_from_str(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].local_addr, - "127.0.2.1") == 0); - LVL2_ASSERT(gsn_addr_from_str(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].local_addr, - "127.0.2.2") == 0); - - hub->restart_counter = 0x23; - now = 345; - LVL2_ASSERT(send_from_sgsn("192.168.42.23", 423)); - LVL2_ASSERT(resolve_to_ggsn("192.168.43.34", 2123)); - LVL2_ASSERT(send_from_ggsn("192.168.43.34", 434)); - LVL2_ASSERT(resolve_to_sgsn("192.168.42.23", 2123)); - -#define GGSNS_CTRL_FD 1 -#define GGSNS_USER_FD 2 -#define SGSNS_CTRL_FD 3 -#define SGSNS_USER_FD 4 - hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].ofd.priv_nr = GGSNS_CTRL_FD; - hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].ofd.priv_nr = GGSNS_USER_FD; - hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].ofd.priv_nr = SGSNS_CTRL_FD; - hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].ofd.priv_nr = SGSNS_USER_FD; - - return 1; -} - -static int clear_test_hub() -{ - /* expire all */ - gtphub_gc(hub, now + (60 * GTPH_EXPIRE_SLOWLY_MINUTES) + 1); - - int plane_idx; - plane_idx = GTPH_PLANE_CTRL; - LVL2_ASSERT(llist_empty(&hub->to_gsns[GTPH_SIDE_GGSN][plane_idx].peers)); - LVL2_ASSERT(llist_empty(&hub->to_gsns[GTPH_SIDE_SGSN][plane_idx].peers)); - plane_idx = GTPH_PLANE_USER; - LVL2_ASSERT(llist_empty(&hub->to_gsns[GTPH_SIDE_GGSN][plane_idx].peers)); - LVL2_ASSERT(llist_empty(&hub->to_gsns[GTPH_SIDE_SGSN][plane_idx].peers)); - - LVL2_ASSERT(llist_empty(&hub->tunnels)); - LVL2_ASSERT(llist_empty(&hub->pending_deletes)); - LVL2_ASSERT(llist_empty(&hub->ggsn_lookups)); - LVL2_ASSERT(llist_empty(&hub->resolved_ggsns)); - - gtphub_free(hub); - return 1; -} - -static int tunnels_are(const char *expect) -{ - static char buf[4096]; - char *pos = buf; - size_t len = sizeof(buf); - struct gtphub_tunnel *t; - llist_for_each_entry(t, &hub->tunnels, entry) { - size_t wrote = snprintf(pos, len, "%s @%d\n", - gtphub_tunnel_str(t), - (int)t->expiry_entry.expiry); - LVL2_ASSERT(wrote < len); - pos += wrote; - len -= wrote; - } - *pos = '\0'; - - if (strncmp(buf, expect, sizeof(buf)) != 0) { - fprintf(stderr, "FAILURE: tunnels_are() mismatches expected value:\n" - "EXPECTED:\n%s\n" - "IS:\n%s\n", - expect, buf); - LVL2_ASSERT("tunnels do not match expected listing."); - return 0; - } - return 1; -} - -static void test_echo(void) -{ - LOG("test_echo"); - OSMO_ASSERT(setup_test_hub()); - - now = 123; - - struct osmo_fd *to_ofd; - struct osmo_sockaddr to_addr; - struct gtphub_peer_port *pp; - int send; - - const char *gtp_ping_from_sgsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "01" /* type 01: Echo request */ - "0004" /* length of 4 after header TEI */ - "00000000" /* header TEI == 0 in Echo */ - "abcd" /* some 2 octet sequence nr */ - "0000" /* N-PDU 0, no extension header (why is this here?) */ - ; - - const char *gtp_pong_to_sgsn = - "32" - "02" /* type 02: Echo response */ - "0006" /* length of 6 after header TEI */ - "00000000" /* header TEI == 0 in Echo */ - "abcd" /* same sequence nr */ - "0000" - "0e23" /* Recovery with restart counter */ - ; - - to_ofd = NULL; - ZERO_STRUCT(&to_addr); - send = gtphub_handle_buf(hub, GTPH_SIDE_SGSN, GTPH_PLANE_CTRL, - &sgsn_sender, buf, msg(gtp_ping_from_sgsn), - now, &reply_buf, &to_ofd, &to_addr); - OSMO_ASSERT(send > 0); - OSMO_ASSERT(to_addr.l); - OSMO_ASSERT(same_addr(&to_addr, &sgsn_sender)); - OSMO_ASSERT(to_ofd && (to_ofd->priv_nr == SGSNS_CTRL_FD)); - OSMO_ASSERT(reply_is(gtp_pong_to_sgsn)); - - pp = gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL], - &sgsn_sender); - /* We don't record Echo peers. */ - OSMO_ASSERT(!pp); - - const char *gtp_ping_from_ggsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "01" /* type 01: Echo request */ - "0004" /* length of 4 after header TEI */ - "00000000" /* header TEI == 0 in Echo */ - "cdef" /* some 2 octet sequence nr */ - "0000" /* N-PDU 0, no extension header (why is this here?) */ - ; - - const char *gtp_pong_to_ggsn = - "32" - "02" /* type 02: Echo response */ - "0006" /* length of 6 after header TEI */ - "00000000" /* header TEI == 0 in Echo */ - "cdef" /* same sequence nr */ - "0000" - "0e23" /* Recovery with restart counter */ - ; - - to_ofd = NULL; - ZERO_STRUCT(&to_addr); - send = gtphub_handle_buf(hub, GTPH_SIDE_GGSN, GTPH_PLANE_CTRL, - &ggsn_sender, buf, msg(gtp_ping_from_ggsn), - now, &reply_buf, &to_ofd, &to_addr); - OSMO_ASSERT(send > 0); - OSMO_ASSERT(same_addr(&to_addr, &ggsn_sender)); - OSMO_ASSERT(to_ofd && (to_ofd->priv_nr == GGSNS_CTRL_FD)); - OSMO_ASSERT(reply_is(gtp_pong_to_ggsn)); - - pp = gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], - &sgsn_sender); - OSMO_ASSERT(!pp); - - - /* And all the same on the user plane. */ - - to_ofd = NULL; - ZERO_STRUCT(&to_addr); - send = gtphub_handle_buf(hub, GTPH_SIDE_SGSN, GTPH_PLANE_USER, - &sgsn_sender, buf, msg(gtp_ping_from_sgsn), - now, &reply_buf, &to_ofd, &to_addr); - OSMO_ASSERT(send > 0); - OSMO_ASSERT(to_addr.l); - OSMO_ASSERT(same_addr(&to_addr, &sgsn_sender)); - OSMO_ASSERT(to_ofd && (to_ofd->priv_nr == SGSNS_USER_FD)); - OSMO_ASSERT(reply_is(gtp_pong_to_sgsn)); - - pp = gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER], - &sgsn_sender); - OSMO_ASSERT(!pp); - - to_ofd = NULL; - ZERO_STRUCT(&to_addr); - send = gtphub_handle_buf(hub, GTPH_SIDE_GGSN, GTPH_PLANE_USER, - &ggsn_sender, buf, msg(gtp_ping_from_ggsn), - now, &reply_buf, &to_ofd, &to_addr); - OSMO_ASSERT(send > 0); - OSMO_ASSERT(same_addr(&to_addr, &ggsn_sender)); - OSMO_ASSERT(to_ofd && (to_ofd->priv_nr == GGSNS_USER_FD)); - OSMO_ASSERT(reply_is(gtp_pong_to_ggsn)); - - pp = gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER], - &sgsn_sender); - OSMO_ASSERT(!pp); - - - OSMO_ASSERT(clear_test_hub()); -} - - -#define MSG_PDP_CTX_REQ(len, seq, restart, imsi, tei_u, tei_c, apn, gsn_c, gsn_u) \ - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr. */ \ - "10" /* type 16: Create PDP Context Request */ \ - len /* msg length = 8 + len (2 octets) */ \ - "00000000" /* No TEI yet */ \ - seq /* Sequence nr (2 octets) */ \ - "00" /* N-PDU 0 */ \ - "00" /* No extensions */ \ - /* IEs */ \ - "0e" restart /* 14: Recovery (restart counter: 1 octet) */ \ - "02" /* 2 = IMSI */ \ - imsi /* (8 octets) */ \ - "0f01" /* 15: Selection mode = MS provided APN, subscription not verified*/ \ - "10" /* 16: TEI Data I */ \ - tei_u /* (4 octets) */ \ - "11" /* 17: TEI Control Plane */ \ - tei_c /* (4 octets) */ \ - "1400" /* 20: NSAPI = 0*/ \ - "1a" /* 26: Charging Characteristics */ \ - "0800" \ - "80" /* 128: End User Address */ \ - "0002" /* length = 2: empty PDP Address */ \ - "f121" /* spare 0xf0, PDP organization 1, PDP type number 0x21 = 33 */ \ - "83" /* 131: Access Point Name */ \ - apn /* (2 octets length, N octets encoded APN-NI) */ \ - "84" /* 132: Protocol Configuration Options */ \ - "0015" /* length = 21 */ \ - "80c0231101010011036d69670868656d6d656c6967" \ - "85" /* 133: GSN Address */ \ - gsn_c /* (2 octets length, N octets addr) */ \ - "85" /* 133: GSN Address (second entry) */ \ - gsn_u /* (2 octets length, N octets addr) */ \ - "86" /* 134: MS International PSTN/ISDN Number (MSISDN) */ \ - "0007" /* length */ \ - "916407123254f6" /* 1946702123456(f) */ \ - "87" /* 135: Quality of Service (QoS) Profile */ \ - "0004" /* length */ \ - "00" /* priority */ \ - "0b921f" /* QoS profile data */ - -#define MSG_PDP_CTX_RSP(len, tei_h, seq, restart, tei_u, tei_c, gsn_c, gsn_u) \ - "32" \ - "11" /* Create PDP Context Response */ \ - len /* msg length = 8 + len (2 octets) */ \ - tei_h /* destination TEI (sent in req above) */ \ - seq /* mapped seq */ \ - "00" "00" \ - /* IEs */ \ - "01" /* 1: Cause */ \ - "80" /* value = 0b10000000 = response, no rejection. */ \ - "08" /* 8: Reordering Required */ \ - "00" /* not required. */ \ - "0e" restart /* 14: Recovery */ \ - "10" /* 16: TEI Data I */ \ - tei_u \ - "11" /* 17: TEI Control */ \ - tei_c \ - "7f" /* 127: Charging ID */ \ - "00000001" \ - "80" /* 128: End User Address */ \ - "0006" /* length = 6 */ \ - "f121" /* spare 0xf0, PDP organization 1, PDP type number 0x21 = 33 */ \ - "7f000002" \ - "84" /* 132: Protocol Configuration Options */ \ - "0014" /* len = 20 */ \ - "8080211002000010810608080808830600000000" \ - "85" /* 133: GSN Address (Ctrl) */ \ - gsn_c \ - "85" /* 133: GSN Address (User) */ \ - gsn_u \ - "87" /* 135: Quality of Service (QoS) Profile */ \ - "0004" /* length */ \ - "00" /* priority */ \ - "0b921f" /* QoS profile data */ - -#define msg_from_sgsn_c(A,B,C,D) msg_from_sgsn(GTPH_PLANE_CTRL, A,B,C,D) -#define msg_from_sgsn_u(A,B,C,D) msg_from_sgsn(GTPH_PLANE_USER, A,B,C,D) -static int msg_from_sgsn(int plane_idx, - struct osmo_sockaddr *_sgsn_sender, - struct osmo_sockaddr *ggsn_receiver, - const char *hex_from_sgsn, - const char *hex_to_ggsn) -{ - struct osmo_fd *ggsn_ofd = NULL; - struct osmo_sockaddr ggsn_addr; - int send; - send = gtphub_handle_buf(hub, GTPH_SIDE_SGSN, plane_idx, _sgsn_sender, - buf, msg(hex_from_sgsn), now, - &reply_buf, &ggsn_ofd, &ggsn_addr); - LVL2_ASSERT(send > 0); - LVL2_ASSERT(same_addr(&ggsn_addr, ggsn_receiver)); - LVL2_ASSERT(reply_is(hex_to_ggsn)); - return 1; -} - -#define msg_from_ggsn_c(A,B,C,D) msg_from_ggsn(GTPH_PLANE_CTRL, A,B,C,D) -#define msg_from_ggsn_u(A,B,C,D) msg_from_ggsn(GTPH_PLANE_USER, A,B,C,D) -static int msg_from_ggsn(int plane_idx, - struct osmo_sockaddr *ggsn_sender, - struct osmo_sockaddr *sgsn_receiver, - const char *msg_from_ggsn, - const char *msg_to_sgsn) -{ - struct osmo_fd *sgsn_ofd; - struct osmo_sockaddr sgsn_addr; - int send; - send = gtphub_handle_buf(hub, GTPH_SIDE_GGSN, plane_idx, ggsn_sender, - buf, msg(msg_from_ggsn), now, - &reply_buf, &sgsn_ofd, &sgsn_addr); - if (*msg_to_sgsn) { - LVL2_ASSERT(send > 0); - LVL2_ASSERT(same_addr(&sgsn_addr, sgsn_receiver)); - LVL2_ASSERT(reply_is(msg_to_sgsn)); - } - else - LVL2_ASSERT(send == 0); - return 1; -} - -static int create_pdp_ctx() -{ - const char *gtp_req_from_sgsn = - MSG_PDP_CTX_REQ("0068", - "abcd", - "60", - "42000121436587f9", - "00000123", - "00000321", - "0009""08696e7465726e6574", /* "(8)internet" */ - "0004""c0a82a17", /* same as default sgsn_sender */ - "0004""c0a82a17" - ); - const char *gtp_req_to_ggsn = - MSG_PDP_CTX_REQ("0068", - "6d31", /* mapped seq ("abcd") */ - "23", - "42000121436587f9", - "00000001", /* Data I: tunnel's TEI */ - "00000001", /* Control: tunnel's TEI */ - "0009""08696e7465726e6574", - "0004""7f000201", /* replaced with gtphub's ggsn ctrl */ - "0004""7f000202" /* replaced with gtphub's ggsn user */ - ); - - LVL2_ASSERT(msg_from_sgsn_c(&sgsn_sender, - &resolved_ggsn_addr, - gtp_req_from_sgsn, - gtp_req_to_ggsn)); - LVL2_ASSERT(was_resolved_for("240010123456789", "internet")); - - LVL2_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" - " @21945\n")); - - const char *gtp_resp_from_ggsn = - MSG_PDP_CTX_RSP("004e", - "00000001", /* destination TEI (sent in req above) */ - "6d31", /* mapped seq */ - "01", /* restart */ - "00000567", /* TEI U */ - "00000765", /* TEI C */ - "0004""c0a82b22", /* GSN addresses */ - "0004""c0a82b22" /* (== resolved_ggsn_addr) */ - ); - const char *gtp_resp_to_sgsn = - MSG_PDP_CTX_RSP("004e", - "00000321", /* unmapped TEI ("001") */ - "abcd", /* unmapped seq ("6d31") */ - "23", - "00000001", /* mapped TEI from GGSN ("567") */ - "00000001", /* mapped TEI from GGSN ("765") */ - "0004""7f000101", /* gtphub's address towards SGSNs (Ctrl) */ - "0004""7f000102" /* gtphub's address towards SGSNs (User) */ - ); - /* The response should go back to whichever port the request came from - * (unmapped by sequence nr) */ - LVL2_ASSERT(msg_from_ggsn_c(&resolved_ggsn_addr, - &sgsn_sender, - gtp_resp_from_ggsn, - gtp_resp_to_sgsn)); - - return 1; -} - -#define MSG_DEL_PDP_CTX_REQ(tei, seq) \ - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr. */ \ - "14" /* type 20: Delete PDP Context Request */ \ - "0008" /* msg length = 8 + len (2 octets) */ \ - tei /* TEI Ctrl */ \ - seq /* Sequence nr (2 octets) */ \ - "00" /* N-PDU 0 */ \ - "00" /* No extensions */ \ - /* IEs */ \ - "13fe" /* 19: Teardown ind = 0 */ \ - "1400" /* 20: NSAPI = 0*/ \ - -#define MSG_DEL_PDP_CTX_RSP(tei, seq) \ - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr. */ \ - "15" /* type 21: Delete PDP Context Response */ \ - "0006" /* msg length = 8 + len (2 octets) */ \ - tei /* TEI Ctrl */ \ - seq /* Sequence nr (2 octets) */ \ - "00" /* N-PDU 0 */ \ - "00" /* No extensions */ \ - /* IEs */ \ - "01" /* 1: Cause */ \ - "80" /* value = 0b10000000 = response, no rejection. */ \ - -static int delete_pdp_ctx_from_sgsn(void) -{ - now += GTPH_EXPIRE_QUICKLY_SECS + 1; - gtphub_gc(hub, now); - - LVL2_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21945\n")); - - /* TEI Ctrl from above and next sequence after abcd. */ - const char *gtp_req_from_sgsn = MSG_DEL_PDP_CTX_REQ("00000001", "abce"); - const char *gtp_req_to_ggsn = MSG_DEL_PDP_CTX_REQ("00000765", "6d32"); - - LVL2_ASSERT(msg_from_sgsn_c(&sgsn_sender, - &resolved_ggsn_addr, - gtp_req_from_sgsn, - gtp_req_to_ggsn)); - - /* 21945 + 31 = 21976 */ - LVL2_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21976\n")); - - const char *gtp_resp_from_ggsn = - MSG_DEL_PDP_CTX_RSP("00000001", "6d32"); - const char *gtp_resp_to_sgsn = - MSG_DEL_PDP_CTX_RSP("00000321", "abce"); - - /* The response should go back to whichever port the request came from - * (unmapped by sequence nr) */ - LVL2_ASSERT(msg_from_ggsn_c(&resolved_ggsn_addr, - &sgsn_sender, - gtp_resp_from_ggsn, - gtp_resp_to_sgsn)); - - LVL2_ASSERT(tunnels_are("")); - - return 1; -} - -static int delete_pdp_ctx_from_ggsn(void) -{ - now += GTPH_EXPIRE_QUICKLY_SECS + 1; - gtphub_gc(hub, now); - - LVL2_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21945\n")); - - /* TEI Ctrl from above and next sequence after abcd. */ - const char *gtp_req_from_ggsn = MSG_DEL_PDP_CTX_REQ("00000001", "5432"); - const char *gtp_req_to_sgsn = MSG_DEL_PDP_CTX_REQ("00000321", "6d31"); - - LVL2_ASSERT(msg_from_ggsn_c(&ggsn_sender, - &resolved_sgsn_addr, - gtp_req_from_ggsn, - gtp_req_to_sgsn)); - - /* 21945 + 31 = 21976 */ - LVL2_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21976\n")); - - const char *gtp_resp_from_sgsn = - MSG_DEL_PDP_CTX_RSP("00000001", "6d31"); - const char *gtp_resp_to_ggsn = - MSG_DEL_PDP_CTX_RSP("00000765", "5432"); - - /* The response should go back to whichever port the request came from - * (unmapped by sequence nr) */ - LVL2_ASSERT(msg_from_sgsn_c(&resolved_sgsn_addr, - &ggsn_sender, - gtp_resp_from_sgsn, - gtp_resp_to_ggsn)); - - LVL2_ASSERT(tunnels_are("")); - - return 1; -} - -static void test_one_pdp_ctx(int del_from_side) -{ - if (del_from_side == GTPH_SIDE_SGSN) - LOG("test_one_pdp_ctx (del from SGSN)") - else LOG("test_one_pdp_ctx (del from GGSN)"); - OSMO_ASSERT(setup_test_hub()); - - OSMO_ASSERT(create_pdp_ctx()); - - struct gtphub_peer_port *ggsn_port = - gtphub_port_find_sa(&hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL], - &resolved_ggsn_addr); - OSMO_ASSERT(ggsn_port); - struct gtphub_peer *ggsn = ggsn_port->peer_addr->peer; - /* now == 345; now + 30 == 375. - * seq mapping from above: - * 0xabcd == 43981 (sent in the packet) - * 0x6d31 == 27953 (harcoded seq mapping start val) */ - OSMO_ASSERT(nr_map_is(&ggsn->seq_map, "(43981->27953@375), ")); - - /* now == 345; now + (6 * 60 * 60) == 21600 + 345 == 21945. - * 0x00000321 == 801 (TEI from SGSN Ctrl) - * 0x00000123 == 291 (TEI from SGSN User) - * 0x00000765 == 1893 (TEI from GGSN Ctrl) - * 0x00000567 == 1383 (TEI from GGSN User) - * Mapped TEIs should be 1 and 2. */ - OSMO_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21945\n")); - - if (del_from_side == GTPH_SIDE_SGSN) { - OSMO_ASSERT(delete_pdp_ctx_from_sgsn()); - } else { - OSMO_ASSERT(delete_pdp_ctx_from_ggsn()); - } - OSMO_ASSERT(tunnels_are("")); - - OSMO_ASSERT(clear_test_hub()); -} - -static void test_user_data(void) -{ - LOG("test_user_data"); - - OSMO_ASSERT(setup_test_hub()); - - OSMO_ASSERT(create_pdp_ctx()); - - /* now == 345; now + (6 * 60 * 60) == 21600 + 345 == 21945. */ - OSMO_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21945\n")); - - LOG("- user data starts"); - /* Now expect default port numbers for User plane. */ - resolve_to_ggsn("192.168.43.34", 2152); - resolve_to_sgsn("192.168.42.23", 2152); - - /* 10 minutes later */ - now += 600; - - const char *u_from_ggsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "ff" /* type 255: G-PDU */ - "0058" /* length: 88 + 8 octets == 96 */ - "00000001" /* mapped TEI for SGSN from create_pdp_ctx() */ - "0070" /* seq */ - "0000" /* No extensions */ - /* User data (ICMP packet), 96 - 12 = 84 octets */ - "45000054daee40004001f7890a172a010a172a02080060d23f590071e3f8" - "4156000000007241010000000000101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f3031323334353637" - ; - const char *u_to_sgsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "ff" /* type 255: G-PDU */ - "0058" /* length: 88 + 8 octets == 96 */ - "00000123" /* unmapped User TEI */ - "6d31" /* new mapped seq */ - "0000" - "45000054daee40004001f7890a172a010a172a02080060d23f590071e3f8" - "4156000000007241010000000000101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f3031323334353637" - ; - - /* This depends on create_pdp_ctx() sending resolved_sgsn_addr as GSN - * Address IEs in the GGSN's Create PDP Ctx Response. */ - OSMO_ASSERT(msg_from_ggsn_u(&ggsn_sender, - &resolved_sgsn_addr, - u_from_ggsn, - u_to_sgsn)); - - /* Make sure the user plane messages have refreshed the TEI mapping - * timeouts: 21945 + 600 == 22545. */ - OSMO_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @22545\n")); - - const char *u_from_sgsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "ff" /* type 255: G-PDU */ - "0058" /* length: 88 + 8 octets == 96 */ - "00000001" /* mapped User TEI for GGSN from create_pdp_ctx() */ - "1234" /* unknown seq */ - "0000" /* No extensions */ - /* User data (ICMP packet), 96 - 12 = 84 octets */ - "45000054daee40004001f7890a172a010a172a02080060d23f590071e3f8" - "4156000000007241010000000000101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f3031323334353637" - ; - const char *u_to_ggsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "ff" /* type 255: G-PDU */ - "0058" /* length: 88 + 8 octets == 96 */ - "00000567" /* unmapped User TEI */ - "6d31" /* unmapped seq */ - "0000" - "45000054daee40004001f7890a172a010a172a02080060d23f590071e3f8" - "4156000000007241010000000000101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f3031323334353637" - ; - - OSMO_ASSERT(msg_from_sgsn_u(&sgsn_sender, - &resolved_ggsn_addr, - u_from_sgsn, - u_to_ggsn)); - - /* Make sure the user plane messages have refreshed the TEI mapping - * timeouts: 21945 + 600 == 22545. Both timeouts refreshed: */ - OSMO_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @22545\n")); - - OSMO_ASSERT(clear_test_hub()); -} - -static void test_reused_tei(void) -{ - LOG("test_reused_tei"); - - OSMO_ASSERT(setup_test_hub()); - - OSMO_ASSERT(create_pdp_ctx()); - - const char *gtp_req_from_sgsn = - MSG_PDP_CTX_REQ("0068", - "abce", /* Next seq */ - "60", - "42000121436587f9", - "00000123", /* Same TEIs as before */ - "00000321", - "0009""08696e7465726e6574", /* "(8)internet" */ - "0004""c0a82a17", /* same as default sgsn_sender */ - "0004""c0a82a17" - ); - const char *gtp_req_to_ggsn = - MSG_PDP_CTX_REQ("0068", - "6d32", /* mapped seq ("abce") */ - "23", - "42000121436587f9", - "00000002", /* mapped TEI Data I ("123") */ - "00000002", /* mapped TEI Control ("321") */ - "0009""08696e7465726e6574", - "0004""7f000201", /* replaced with gtphub's ggsn ctrl */ - "0004""7f000202" /* replaced with gtphub's ggsn user */ - ); - - OSMO_ASSERT(msg_from_sgsn_c(&sgsn_sender, - &resolved_ggsn_addr, - gtp_req_from_sgsn, - gtp_req_to_ggsn)); - OSMO_ASSERT(was_resolved_for("240010123456789", "internet")); - - OSMO_ASSERT(tunnels_are( - "TEI=2:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" - " @21945\n")); - - const char *gtp_resp_from_ggsn = - MSG_PDP_CTX_RSP("004e", - "00000002", /* destination TEI (sent in req above) */ - "6d32", /* mapped seq */ - "01", /* restart */ - "00000567", /* TEI U */ - "00000765", /* TEI C */ - "0004""c0a82b22", /* GSN addresses */ - "0004""c0a82b22" /* (== resolved_ggsn_addr) */ - ); - const char *gtp_resp_to_sgsn = - MSG_PDP_CTX_RSP("004e", - "00000321", /* unmapped TEI ("001") */ - "abce", /* unmapped seq ("6d32") */ - "23", - "00000002", /* mapped TEI from GGSN ("567") */ - "00000002", /* mapped TEI from GGSN ("765") */ - "0004""7f000101", /* gtphub's address towards SGSNs (Ctrl) */ - "0004""7f000102" /* gtphub's address towards SGSNs (User) */ - ); - /* The response should go back to whichever port the request came from - * (unmapped by sequence nr) */ - OSMO_ASSERT(msg_from_ggsn_c(&resolved_ggsn_addr, - &sgsn_sender, - gtp_resp_from_ggsn, - gtp_resp_to_sgsn)); - - OSMO_ASSERT(clear_test_hub()); -} - -static void test_peer_restarted(void) -{ - LOG("test_peer_restarted"); - - OSMO_ASSERT(setup_test_hub()); - - OSMO_ASSERT(create_pdp_ctx()); - - now += 10; - - const char *gtp_req_from_sgsn = - MSG_PDP_CTX_REQ("0068", - "1234", /* brand new seq */ - "61", /* DIFFERING restart counter */ - "42000121436587f9", - "00000abc", - "00000cba", - "0009""08696e7465726e6574", /* "(8)internet" */ - "0004""c0a82a17", /* same as default sgsn_sender */ - "0004""c0a82a17" - ); - const char *gtp_req_to_ggsn = - MSG_PDP_CTX_REQ("0068", - "6d33", /* mapped seq ("1234") */ - "23", - "42000121436587f9", - "00000002", /* mapped TEI Data I ("123") */ - "00000002", /* mapped TEI Control ("321") */ - "0009""08696e7465726e6574", - "0004""7f000201", /* replaced with gtphub's ggsn ctrl */ - "0004""7f000202" /* replaced with gtphub's ggsn user */ - ); - - OSMO_ASSERT(msg_from_sgsn_c(&sgsn_sender, - &resolved_ggsn_addr, - gtp_req_from_sgsn, - gtp_req_to_ggsn)); - OSMO_ASSERT(was_resolved_for("240010123456789", "internet")); - - OSMO_ASSERT(tunnels_are( - "TEI=2:" - " 192.168.42.23 (TEI C=cba U=abc)" - " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" - " @21955\n" - "TEI=1:" - " (uninitialized) (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21945\n" - )); - - const char *gtp_resp_from_ggsn = - MSG_PDP_CTX_RSP("004e", - "00000002", /* destination TEI (sent in req above) */ - "6d33", /* mapped seq */ - "01", /* restart */ - "00000def", /* TEI U */ - "00000fde", /* TEI C */ - "0004""c0a82b22", /* GSN addresses */ - "0004""c0a82b22" /* (== resolved_ggsn_addr) */ - ); - const char *gtp_resp_to_sgsn = - MSG_PDP_CTX_RSP("004e", - "00000cba", /* unmapped TEI ("005") */ - "1234", /* unmapped seq ("6d32") */ - "23", - "00000002", /* mapped TEI from GGSN ("567") */ - "00000002", /* mapped TEI from GGSN ("765") */ - "0004""7f000101", /* gtphub's address towards SGSNs (Ctrl) */ - "0004""7f000102" /* gtphub's address towards SGSNs (User) */ - ); - /* The response should go back to whichever port the request came from - * (unmapped by sequence nr) */ - OSMO_ASSERT(msg_from_ggsn_c(&resolved_ggsn_addr, - &sgsn_sender, - gtp_resp_from_ggsn, - gtp_resp_to_sgsn)); - - OSMO_ASSERT(clear_test_hub()); -} - -static void test_peer_restarted_reusing_tei(void) -{ - LOG("test_peer_restarted_reusing_tei"); - - OSMO_ASSERT(setup_test_hub()); - - OSMO_ASSERT(create_pdp_ctx()); - - now += 10; - - const char *gtp_req_from_sgsn = - MSG_PDP_CTX_REQ("0068", - "1234", /* brand new seq */ - "61", /* DIFFERING restart counter */ - "42000121436587f9", - "00000123", /* SAME TEI */ - "00000321", - "0009""08696e7465726e6574", /* "(8)internet" */ - "0004""c0a82a17", /* same as default sgsn_sender */ - "0004""c0a82a17" - ); - const char *gtp_req_to_ggsn = - MSG_PDP_CTX_REQ("0068", - "6d33", /* seq 6d31 + 2, after "out-of-band" Delete PDP Ctx - due to differing restart counter. */ - "23", - "42000121436587f9", - "00000002", /* mapped TEI Data I ("123") */ - "00000002", /* mapped TEI Control ("321") */ - "0009""08696e7465726e6574", - "0004""7f000201", /* replaced with gtphub's ggsn ctrl */ - "0004""7f000202" /* replaced with gtphub's ggsn user */ - ); - - OSMO_ASSERT(msg_from_sgsn_c(&sgsn_sender, - &resolved_ggsn_addr, - gtp_req_from_sgsn, - gtp_req_to_ggsn)); - OSMO_ASSERT(was_resolved_for("240010123456789", "internet")); - - OSMO_ASSERT(tunnels_are( - "TEI=2:" /* being established after restart */ - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" - " @21955\n" - "TEI=1:" /* invalidated due to restart */ - " (uninitialized) (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21945\n" - )); - - /* An "out-of-band" delete request should have been sent to the GGSN - * (checked by expected log output in gtphub_test.ok), and the GGSN - * will (usually) send a Delete Response like this: */ - const char *gtp_del_resp_from_ggsn = - MSG_DEL_PDP_CTX_RSP("00000001", "6d32"); - - /* For this response (due to peer restart) we expect no forwarded - * message. */ - OSMO_ASSERT(msg_from_ggsn_c(&resolved_ggsn_addr, - &sgsn_sender, - gtp_del_resp_from_ggsn, - "")); - - OSMO_ASSERT(tunnels_are( - "TEI=2:" /* still being established after restart */ - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" - " @21955\n" - )); - - const char *gtp_resp_from_ggsn = - MSG_PDP_CTX_RSP("004e", - "00000002", /* destination TEI (sent in req above) */ - "6d33", /* mapped seq */ - "01", /* restart */ - "00000def", /* TEI U */ - "00000fde", /* TEI C */ - "0004""c0a82b22", /* GSN addresses */ - "0004""c0a82b22" /* (== resolved_ggsn_addr) */ - ); - const char *gtp_resp_to_sgsn = - MSG_PDP_CTX_RSP("004e", - "00000321", /* unmapped TEI ("005") */ - "1234", /* unmapped seq ("6d33") */ - "23", - "00000002", /* mapped TEI from GGSN ("567") */ - "00000002", /* mapped TEI from GGSN ("765") */ - "0004""7f000101", /* gtphub's address towards SGSNs (Ctrl) */ - "0004""7f000102" /* gtphub's address towards SGSNs (User) */ - ); - /* The response should go back to whichever port the request came from - * (unmapped by sequence nr) */ - OSMO_ASSERT(msg_from_ggsn_c(&resolved_ggsn_addr, - &sgsn_sender, - gtp_resp_from_ggsn, - gtp_resp_to_sgsn)); - - OSMO_ASSERT(tunnels_are( - "TEI=2:" /* still being established after restart */ - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=fde U=def)" - " @21955\n" - )); - - OSMO_ASSERT(clear_test_hub()); -} - -static void test_sgsn_behind_nat(void) -{ - LOG("test_user_data"); - - OSMO_ASSERT(setup_test_hub()); - hub->sgsn_use_sender = 1; /* <-- Main difference to test_user_data() */ - resolve_to_sgsn("192.168.42.23", 423); /* Same as sender */ - - OSMO_ASSERT(create_pdp_ctx()); - - /* now == 345; now + (6 * 60 * 60) == 21600 + 345 == 21945. */ - OSMO_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21945\n")); - - LOG("- user data starts"); - /* Now expect default port numbers for User plane -- except SGSN. */ - resolve_to_ggsn("192.168.43.34", 2152); - - /* 10 minutes later */ - now += 600; - - const char *u_from_ggsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "ff" /* type 255: G-PDU */ - "0058" /* length: 88 + 8 octets == 96 */ - "00000001" /* mapped User TEI for SGSN from create_pdp_ctx() */ - "0070" /* seq */ - "0000" /* No extensions */ - /* User data (ICMP packet), 96 - 12 = 84 octets */ - "45000054daee40004001f7890a172a010a172a02080060d23f590071e3f8" - "4156000000007241010000000000101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f3031323334353637" - ; - const char *u_to_sgsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "ff" /* type 255: G-PDU */ - "0058" /* length: 88 + 8 octets == 96 */ - "00000123" /* unmapped User TEI */ - "6d31" /* new mapped seq */ - "0000" - "45000054daee40004001f7890a172a010a172a02080060d23f590071e3f8" - "4156000000007241010000000000101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f3031323334353637" - ; - - /* This depends on create_pdp_ctx() sending resolved_sgsn_addr as GSN - * Address IEs in the GGSN's Create PDP Ctx Response. */ - OSMO_ASSERT(msg_from_ggsn_u(&ggsn_sender, - &resolved_sgsn_addr, - u_from_ggsn, - u_to_sgsn)); - - /* Make sure the user plane messages have refreshed the TEI mapping - * timeouts: 21945 + 600 == 22545. */ - OSMO_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @22545\n")); - - const char *u_from_sgsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "ff" /* type 255: G-PDU */ - "0058" /* length: 88 + 8 octets == 96 */ - "00000001" /* mapped User TEI for GGSN from create_pdp_ctx() */ - "1234" /* unknown seq */ - "0000" /* No extensions */ - /* User data (ICMP packet), 96 - 12 = 84 octets */ - "45000054daee40004001f7890a172a010a172a02080060d23f590071e3f8" - "4156000000007241010000000000101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f3031323334353637" - ; - const char *u_to_ggsn = - "32" /* 0b001'1 0010: version 1, protocol GTP, with seq nr */ - "ff" /* type 255: G-PDU */ - "0058" /* length: 88 + 8 octets == 96 */ - "00000567" /* unmapped User TEI */ - "6d31" /* unmapped seq */ - "0000" - "45000054daee40004001f7890a172a010a172a02080060d23f590071e3f8" - "4156000000007241010000000000101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f3031323334353637" - ; - - OSMO_ASSERT(msg_from_sgsn_u(&sgsn_sender, - &resolved_ggsn_addr, - u_from_sgsn, - u_to_ggsn)); - - /* Make sure the user plane messages have refreshed the TEI mapping - * timeouts: 21945 + 600 == 22545. Both timeouts refreshed: */ - OSMO_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @22545\n")); - - OSMO_ASSERT(clear_test_hub()); -} - -void test_parallel_context_creation(void) -{ - LOG("test_parallel_context_creation"); - - OSMO_ASSERT(setup_test_hub()); - - const char *gtp_req_from_sgsn1 = - MSG_PDP_CTX_REQ("0068", - "abcd", - "60", - "42000121436587f9", - "00000123", - "00000321", - "0009""08696e7465726e6574", /* "(8)internet" */ - "0004""c0a82a17", /* same as default sgsn_sender */ - "0004""c0a82a17" - ); - const char *gtp_req_to_ggsn1 = - MSG_PDP_CTX_REQ("0068", - "6d31", /* mapped seq ("abcd") */ - "23", - "42000121436587f9", - "00000001", /* mapped TEI Data I ("123") */ - "00000001", /* mapped TEI Control ("321") */ - "0009""08696e7465726e6574", - "0004""7f000201", /* replaced with gtphub's ggsn ctrl */ - "0004""7f000202" /* replaced with gtphub's ggsn user */ - ); - - OSMO_ASSERT(msg_from_sgsn_c(&sgsn_sender, - &resolved_ggsn_addr, - gtp_req_from_sgsn1, - gtp_req_to_ggsn1)); - - OSMO_ASSERT(tunnels_are( - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" - " @21945\n")); - - now ++; - - const char *gtp_req_from_sgsn2 = - MSG_PDP_CTX_REQ("0068", - "abce", - "60", - "42000121436588f9", - "00000124", - "00000322", - "0009""08696e7465726e6574", /* "(8)internet" */ - "0004""c0a82a17", /* same as default sgsn_sender */ - "0004""c0a82a17" - ); - const char *gtp_req_to_ggsn2 = - MSG_PDP_CTX_REQ("0068", - "6d32", /* mapped seq ("abce") */ - "23", - "42000121436588f9", - "00000002", /* mapped TEI Data I ("124") */ - "00000002", /* mapped TEI Control ("322") */ - "0009""08696e7465726e6574", - "0004""7f000201", /* replaced with gtphub's ggsn ctrl */ - "0004""7f000202" /* replaced with gtphub's ggsn user */ - ); - - OSMO_ASSERT(msg_from_sgsn_c(&sgsn_sender, - &resolved_ggsn_addr, - gtp_req_from_sgsn2, - gtp_req_to_ggsn2)); - - OSMO_ASSERT(tunnels_are( - "TEI=2:" - " 192.168.42.23 (TEI C=322 U=124)" - " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" - " @21946\n" - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" - " @21945\n" - )); - - now ++; - - const char *gtp_resp_from_ggsn1 = - MSG_PDP_CTX_RSP("004e", - "00000001", /* destination TEI (sent in req above) */ - "6d31", /* mapped seq */ - "01", /* restart */ - "00000567", /* TEI U */ - "00000765", /* TEI C */ - "0004""c0a82b22", /* GSN addresses */ - "0004""c0a82b22" /* (== resolved_ggsn_addr) */ - ); - const char *gtp_resp_to_sgsn1 = - MSG_PDP_CTX_RSP("004e", - "00000321", /* unmapped TEI ("001") */ - "abcd", /* unmapped seq ("6d31") */ - "23", - "00000001", /* mapped TEI from GGSN ("567") */ - "00000001", /* mapped TEI from GGSN ("765") */ - "0004""7f000101", /* gtphub's address towards SGSNs (Ctrl) */ - "0004""7f000102" /* gtphub's address towards SGSNs (User) */ - ); - - OSMO_ASSERT(msg_from_ggsn_c(&resolved_ggsn_addr, - &sgsn_sender, - gtp_resp_from_ggsn1, - gtp_resp_to_sgsn1)); - - OSMO_ASSERT(tunnels_are( - "TEI=2:" - " 192.168.42.23 (TEI C=322 U=124)" - " <-> 192.168.43.34/(uninitialized) (TEI C=0 U=0)" - " @21946\n" - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21947\n" - )); - - now ++; - - const char *gtp_resp_from_ggsn2 = - MSG_PDP_CTX_RSP("004e", - "00000002", /* destination TEI (sent in req above) */ - "6d32", /* mapped seq */ - "01", /* restart */ - "00000568", /* TEI U */ - "00000766", /* TEI C */ - "0004""c0a82b22", /* GSN addresses */ - "0004""c0a82b22" /* (== resolved_ggsn_addr) */ - ); - const char *gtp_resp_to_sgsn2 = - MSG_PDP_CTX_RSP("004e", - "00000322", /* unmapped TEI ("001") */ - "abce", /* unmapped seq ("6d31") */ - "23", - "00000002", /* mapped TEI from GGSN ("567") */ - "00000002", /* mapped TEI from GGSN ("765") */ - "0004""7f000101", /* gtphub's address towards SGSNs (Ctrl) */ - "0004""7f000102" /* gtphub's address towards SGSNs (User) */ - ); - - OSMO_ASSERT(msg_from_ggsn_c(&resolved_ggsn_addr, - &sgsn_sender, - gtp_resp_from_ggsn2, - gtp_resp_to_sgsn2)); - - OSMO_ASSERT(tunnels_are( - "TEI=2:" - " 192.168.42.23 (TEI C=322 U=124)" - " <-> 192.168.43.34 (TEI C=766 U=568)" - " @21948\n" - "TEI=1:" - " 192.168.42.23 (TEI C=321 U=123)" - " <-> 192.168.43.34 (TEI C=765 U=567)" - " @21947\n" - )); - - OSMO_ASSERT(clear_test_hub()); -} - - -static struct log_info_cat gtphub_categories[] = { - [DGTPHUB] = { - .name = "DGTPHUB", - .description = "GTP Hub", - .color = "\033[1;33m", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, -}; - -static struct log_info info = { - .cat = gtphub_categories, - .num_cat = ARRAY_SIZE(gtphub_categories), -}; - -int main(int argc, char **argv) -{ - osmo_init_logging(&info); - osmo_gtphub_ctx = talloc_named_const(NULL, 0, "osmo_gtphub"); - - test_nr_map_basic(); - test_nr_map_wrap(); - test_expiry(); - test_echo(); - test_one_pdp_ctx(GTPH_SIDE_SGSN); - test_one_pdp_ctx(GTPH_SIDE_GGSN); - test_user_data(); - test_reused_tei(); - test_peer_restarted(); - test_peer_restarted_reusing_tei(); - test_sgsn_behind_nat(); - test_parallel_context_creation(); - printf("Done\n"); - - talloc_report_full(osmo_gtphub_ctx, stderr); - OSMO_ASSERT(talloc_total_blocks(osmo_gtphub_ctx) == 1); - return 0; -} - diff --git a/tests/gtphub/gtphub_test.ok b/tests/gtphub/gtphub_test.ok deleted file mode 100644 index e60d5f2b2..000000000 --- a/tests/gtphub/gtphub_test.ok +++ /dev/null @@ -1,42 +0,0 @@ -test_echo -test_one_pdp_ctx (del from SGSN) -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -test_one_pdp_ctx (del from GGSN) -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -test_user_data -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -- user data starts -test_reused_tei -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -test_peer_restarted -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -Out-of-band gtphub_write(16): -to 192.168.43.34 port 2123 -32 14 00 08 00 00 07 65 6d 32 00 00 13 ff 14 00 -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -test_peer_restarted_reusing_tei -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -Out-of-band gtphub_write(16): -to 192.168.43.34 port 2123 -32 14 00 08 00 00 07 65 6d 32 00 00 13 ff 14 00 -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -test_user_data -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -- user data starts -test_parallel_context_creation -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456789 ni internet: 192.168.43.34 port 2123 -- __wrap_gtphub_resolve_ggsn_addr(): - returning GGSN addr from imsi 240010123456889 ni internet: 192.168.43.34 port 2123 -Done diff --git a/tests/msc_vlr/Makefile.am b/tests/msc_vlr/Makefile.am deleted file mode 100644 index 10184fa4b..000000000 --- a/tests/msc_vlr/Makefile.am +++ /dev/null @@ -1,168 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBSMPP34_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) \ - $(LIBOSMORANAP_CFLAGS) \ - $(LIBASN1C_CFLAGS) \ - $(LIBOSMOLEGACYMGCP_CFLAGS) \ - $(NULL) - -noinst_HEADERS = \ - msc_vlr_tests.h \ - $(NULL) - -EXTRA_DIST = \ - msc_vlr_test_no_authen.ok \ - msc_vlr_test_no_authen.err \ - msc_vlr_test_gsm_authen.ok \ - msc_vlr_test_gsm_authen.err \ - msc_vlr_test_gsm_ciph.ok \ - msc_vlr_test_gsm_ciph.err \ - msc_vlr_test_umts_authen.ok \ - msc_vlr_test_umts_authen.err \ - msc_vlr_test_hlr_reject.ok \ - msc_vlr_test_hlr_reject.err \ - msc_vlr_test_hlr_timeout.ok \ - msc_vlr_test_hlr_timeout.err \ - msc_vlr_test_ms_timeout.ok \ - msc_vlr_test_ms_timeout.err \ - msc_vlr_test_reject_concurrency.ok \ - msc_vlr_test_reject_concurrency.err \ - msc_vlr_test_rest.ok \ - msc_vlr_test_rest.err \ - $(NULL) - -COMMON_LDADD = \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ - $(top_builddir)/src/libvlr/libvlr.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBSMPP34_LIBS) \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBCRYPTO_LIBS) \ - $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBOSMORANAP_LIBS) \ - $(LIBASN1C_LIBS) \ - $(LIBOSMOLEGACYMGCP_LIBS) \ - $(LIBRARY_GSM) \ - -ldbi \ - -lrt \ - $(NULL) - -COMMON_LDFLAGS = \ - -Wl,--wrap=gsup_client_create \ - -Wl,--wrap=gsup_client_send \ - -Wl,--wrap=a_iface_tx_dtap \ - -Wl,--wrap=a_iface_tx_clear_cmd \ - -Wl,--wrap=a_iface_tx_paging \ - -Wl,--wrap=ranap_iu_tx \ - -Wl,--wrap=ranap_iu_tx_release \ - -Wl,--wrap=ranap_iu_tx_common_id \ - -Wl,--wrap=ranap_iu_page_cs \ - -Wl,--wrap=msc_stop_paging \ - -Wl,--wrap=gsm340_gen_scts \ - -Wl,--wrap=RAND_bytes \ - $(NULL) - -noinst_PROGRAMS = \ - msc_vlr_test_no_authen \ - msc_vlr_test_gsm_authen \ - msc_vlr_test_gsm_ciph \ - msc_vlr_test_umts_authen \ - msc_vlr_test_hlr_reject \ - msc_vlr_test_hlr_timeout \ - msc_vlr_test_ms_timeout \ - msc_vlr_test_reject_concurrency \ - msc_vlr_test_rest \ - $(NULL) - -msc_vlr_test_no_authen_SOURCES = \ - msc_vlr_test_no_authen.c \ - msc_vlr_tests.c \ - $(NULL) -msc_vlr_test_no_authen_LDADD = $(COMMON_LDADD) -msc_vlr_test_no_authen_LDFLAGS = $(COMMON_LDFLAGS) - -msc_vlr_test_gsm_authen_SOURCES = \ - msc_vlr_test_gsm_authen.c \ - msc_vlr_tests.c \ - $(NULL) -msc_vlr_test_gsm_authen_LDADD = $(COMMON_LDADD) -msc_vlr_test_gsm_authen_LDFLAGS = $(COMMON_LDFLAGS) - -msc_vlr_test_gsm_ciph_SOURCES = \ - msc_vlr_test_gsm_ciph.c \ - msc_vlr_tests.c \ - $(NULL) -msc_vlr_test_gsm_ciph_LDADD = $(COMMON_LDADD) -msc_vlr_test_gsm_ciph_LDFLAGS = $(COMMON_LDFLAGS) - -msc_vlr_test_umts_authen_SOURCES = \ - msc_vlr_test_umts_authen.c \ - msc_vlr_tests.c \ - $(NULL) -msc_vlr_test_umts_authen_LDADD = $(COMMON_LDADD) -msc_vlr_test_umts_authen_LDFLAGS = $(COMMON_LDFLAGS) - -msc_vlr_test_hlr_reject_SOURCES = \ - msc_vlr_test_hlr_reject.c \ - msc_vlr_tests.c \ - $(NULL) -msc_vlr_test_hlr_reject_LDADD = $(COMMON_LDADD) -msc_vlr_test_hlr_reject_LDFLAGS = $(COMMON_LDFLAGS) - -msc_vlr_test_hlr_timeout_SOURCES = \ - msc_vlr_test_hlr_timeout.c \ - msc_vlr_tests.c \ - $(NULL) -msc_vlr_test_hlr_timeout_LDADD = $(COMMON_LDADD) -msc_vlr_test_hlr_timeout_LDFLAGS = $(COMMON_LDFLAGS) - -msc_vlr_test_ms_timeout_SOURCES = \ - msc_vlr_test_ms_timeout.c \ - msc_vlr_tests.c \ - $(NULL) -msc_vlr_test_ms_timeout_LDADD = $(COMMON_LDADD) -msc_vlr_test_ms_timeout_LDFLAGS = $(COMMON_LDFLAGS) - -msc_vlr_test_reject_concurrency_SOURCES = \ - msc_vlr_test_reject_concurrency.c \ - msc_vlr_tests.c \ - $(NULL) -msc_vlr_test_reject_concurrency_LDADD = $(COMMON_LDADD) -msc_vlr_test_reject_concurrency_LDFLAGS = $(COMMON_LDFLAGS) - -msc_vlr_test_rest_SOURCES = \ - msc_vlr_test_rest.c \ - msc_vlr_tests.c \ - $(NULL) -msc_vlr_test_rest_LDADD = $(COMMON_LDADD) -msc_vlr_test_rest_LDFLAGS = $(COMMON_LDFLAGS) - -.PHONY: update_exp -update_exp: - $(builddir)/msc_vlr_test_no_authen >$(srcdir)/msc_vlr_test_no_authen.ok 2>$(srcdir)/msc_vlr_test_no_authen.err - $(builddir)/msc_vlr_test_gsm_authen >$(srcdir)/msc_vlr_test_gsm_authen.ok 2>$(srcdir)/msc_vlr_test_gsm_authen.err - $(builddir)/msc_vlr_test_gsm_ciph >$(srcdir)/msc_vlr_test_gsm_ciph.ok 2>$(srcdir)/msc_vlr_test_gsm_ciph.err - $(builddir)/msc_vlr_test_umts_authen >$(srcdir)/msc_vlr_test_umts_authen.ok 2>$(srcdir)/msc_vlr_test_umts_authen.err - $(builddir)/msc_vlr_test_hlr_reject >$(srcdir)/msc_vlr_test_hlr_reject.ok 2>$(srcdir)/msc_vlr_test_hlr_reject.err - $(builddir)/msc_vlr_test_hlr_timeout >$(srcdir)/msc_vlr_test_hlr_timeout.ok 2>$(srcdir)/msc_vlr_test_hlr_timeout.err - $(builddir)/msc_vlr_test_ms_timeout >$(srcdir)/msc_vlr_test_ms_timeout.ok 2>$(srcdir)/msc_vlr_test_ms_timeout.err - $(builddir)/msc_vlr_test_reject_concurrency >$(srcdir)/msc_vlr_test_reject_concurrency.ok 2>$(srcdir)/msc_vlr_test_reject_concurrency.err - $(builddir)/msc_vlr_test_rest >$(srcdir)/msc_vlr_test_rest.ok 2>$(srcdir)/msc_vlr_test_rest.err diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.c b/tests/msc_vlr/msc_vlr_test_gsm_authen.c deleted file mode 100644 index 70b7614d0..000000000 --- a/tests/msc_vlr/msc_vlr_test_gsm_authen.c +++ /dev/null @@ -1,924 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include "msc_vlr_tests.h" - -void test_gsm_authen() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - net->authentication_required = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject"); - gsup_rx("06010809710000004026f0", NULL); - EXPECT_ACCEPTED(false); - - thwart_rx_non_initial_requests(); - - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector"); - auth_request_sent = false; - auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b"; - cm_service_result_sent = RES_NONE; - ms_sends_msg("05247803305886089910070000006402"); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts with a CM Service Accept"); - gsup_expect_tx(NULL); - ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */); - VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - - btw("a USSD request is serviced"); - dtap_expect_tx_ussd("Your extension is 46071\r"); - expect_bssap_clear(); - ms_sends_msg("0b3b1c15a11302010002013b300b04010f0406aa510c061b017f0100"); - OSMO_ASSERT(dtap_tx_confirmed); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("all requests serviced, conn has been released"); - EXPECT_CONN_COUNT(0); - - BTW("an SMS is sent, MS is paged"); - paging_expect_imsi(imsi); - paging_sent = false; - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - - send_sms(vsub, vsub, - "Privacy in residential applications is a desirable" - " marketing option."); - - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - vsub = NULL; - VERBOSE_ASSERT(paging_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); - - btw("the subscriber and its pending request should remain"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - - btw("MS replies with Paging Response, and VLR sends Auth Request with third key"); - auth_request_sent = false; - auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42"; - ms_sends_msg("06270703305882089910070000006402"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts and sends pending SMS"); - dtap_expect_tx("09" /* SMS messages */ - "01" /* CP-DATA */ - "58" /* length */ - "01" /* Network to MS */ - "00" /* reference */ - /* originator (gsm411_send_sms() hardcodes this weird nr) */ - "0791" "447758100650" /* 447785016005 */ - "00" /* dest */ - /* SMS TPDU */ - "4c" /* len */ - "00" /* SMS deliver */ - "05806470f1" /* originating address 46071 */ - "00" /* TP-PID */ - "00" /* GSM default alphabet */ - "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/ - "000000" /* H-M-S */ - "00" /* GMT+0 */ - "44" /* data length */ - "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" - "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" - "0c7ac3e9e9b7db05"); - ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - - btw("SMS was delivered, no requests pending for subscr"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("conn is still open to wait for SMS ack dance"); - EXPECT_CONN_COUNT(1); - - btw("MS replies with CP-ACK for received SMS"); - ms_sends_msg("8904"); - EXPECT_CONN_COUNT(1); - - btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that"); - dtap_expect_tx("0904"); - expect_bssap_clear(); - ms_sends_msg("890106020041020000"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("SMS is done, conn is gone"); - EXPECT_CONN_COUNT(0); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_gsm_authen_tmsi() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - net->authentication_required = true; - net->vlr->cfg.assign_tmsi = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject"); - gsup_rx("06010809710000004026f0", NULL); - EXPECT_ACCEPTED(false); - - thwart_rx_non_initial_requests(); - - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - gsup_rx("06010809710000004026f0", NULL); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the new TMSI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("after a while, a new conn sends a CM Service Request using above TMSI. VLR responds with Auth Req, 2nd auth vector"); - auth_request_sent = false; - auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b"; - cm_service_result_sent = RES_NONE; - ms_sends_msg("05247803305886" "05f4" "03020100"); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts with a CM Service Accept"); - gsup_expect_tx(NULL); - ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */); - VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - - btw("a USSD request is serviced"); - dtap_expect_tx_ussd("Your extension is 46071\r"); - expect_bssap_clear(); - ms_sends_msg("0b3b1c15a11302010002013b300b04010f0406aa510c061b017f0100"); - OSMO_ASSERT(dtap_tx_confirmed); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("all requests serviced, conn has been released"); - EXPECT_CONN_COUNT(0); - - BTW("an SMS is sent, MS is paged"); - paging_expect_tmsi(0x03020100); - paging_sent = false; - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - - send_sms(vsub, vsub, - "Privacy in residential applications is a desirable" - " marketing option."); - - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - vsub = NULL; - VERBOSE_ASSERT(paging_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); - - btw("the subscriber and its pending request should remain"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - - btw("MS replies with Paging Response using TMSI, and VLR sends Auth Request with third key"); - auth_request_sent = false; - auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42"; - ms_sends_msg("06270703305882" "05f4" "03020100"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts and sends pending SMS"); - dtap_expect_tx("09" /* SMS messages */ - "01" /* CP-DATA */ - "58" /* length */ - "01" /* Network to MS */ - "00" /* reference */ - /* originator (gsm411_send_sms() hardcodes this weird nr) */ - "0791" "447758100650" /* 447785016005 */ - "00" /* dest */ - /* SMS TPDU */ - "4c" /* len */ - "00" /* SMS deliver */ - "05806470f1" /* originating address 46071 */ - "00" /* TP-PID */ - "00" /* GSM default alphabet */ - "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/ - "000000" /* H-M-S */ - "00" /* GMT+0 */ - "44" /* data length */ - "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" - "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" - "0c7ac3e9e9b7db05"); - ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - - btw("SMS was delivered, no requests pending for subscr"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("conn is still open to wait for SMS ack dance"); - EXPECT_CONN_COUNT(1); - - btw("MS replies with CP-ACK for received SMS"); - ms_sends_msg("8904"); - EXPECT_CONN_COUNT(1); - - btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that"); - dtap_expect_tx("0904"); - expect_bssap_clear(); - ms_sends_msg("890106020041020000"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("SMS is done, conn is gone"); - EXPECT_CONN_COUNT(0); - - /* TODO: when the subscriber detaches, the vlr_subscr gets - * deallocated and we no longer know the TMSI. This case is covered by - * test_lu_unknown_tmsi(), so here I'd like to still have the TMSI. - BTW("subscriber detaches, using TMSI"); - expect_bssap_clear(); - ms_sends_msg("050130" "05f4" "03020100"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - */ - - BTW("subscriber sends LU Request, this time with the TMSI"); - btw("Location Update request causes an Auth Req to MS"); - lu_result_sent = RES_NONE; - auth_request_sent = false; - auth_request_expect_rand = "fa8f20b781b5881329d4fea26b1a3c51"; - ms_sends_msg("050802008168000130" "05f4" "03020100"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05545afc8d72"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - gsup_rx("06010809710000004026f0", NULL); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x07060504, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - btw("subscriber has the new TMSI"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == 0x07060504, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches, using new TMSI"); - expect_bssap_clear(); - ms_sends_msg("050130" "05f4" "07060504"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_gsm_authen_imei() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - net->authentication_required = true; - net->vlr->cfg.check_imei_rqd = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject"); - gsup_rx("06010809710000004026f0", NULL); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS"); - dtap_expect_tx("051802"); - gsup_rx("06010809710000004026f0", NULL); - - btw("We will only do business when the IMEI is known"); - EXPECT_CONN_COUNT(1); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(vsub->imei[0], == 0, "%d"); - vlr_subscr_put(vsub); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS replies with an Identity Response"); - expect_bssap_clear(); - ms_sends_msg("0559084a32244332244302"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the IMEI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_gsm_authen_tmsi_imei() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - net->authentication_required = true; - net->vlr->cfg.assign_tmsi = true; - net->vlr->cfg.check_imei_rqd = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject"); - gsup_rx("06010809710000004026f0", NULL); - EXPECT_ACCEPTED(false); - - thwart_rx_non_initial_requests(); - - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS"); - dtap_expect_tx("051802"); - gsup_rx("06010809710000004026f0", NULL); - - btw("We will only do business when the IMEI is known"); - EXPECT_CONN_COUNT(1); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(vsub->imei[0], == 0, "%d"); - vlr_subscr_put(vsub); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS replies with an Identity Response"); - ms_sends_msg("0559084a32244332244302"); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the IMEI and TMSI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches, using TMSI"); - expect_bssap_clear(); - ms_sends_msg("050130" "05f4" "03020100"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_gsm_milenage_authen() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000010650"; - - comment_start(); - - net->authentication_required = true; - rx_from_ran = RAN_GERAN_A; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0"); - ms_sends_msg("0508" /* MM LU */ - "7" /* ciph key seq: no key available */ - "0" /* LU type: normal */ - "ffffff" "0000" /* LAI, LAC */ - "30" /* classmark 1: GSM phase 2 */ - "089910070000106005" /* IMSI */ - ); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - /* based on auc_3g: - * K = 'EB215756028D60E3275E613320AEC880', - * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308' - * SQN = 0 - */ - auth_request_sent = false; - auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d"; - auth_request_expect_autn = NULL; - gsup_rx("0a" - /* imsi */ - "0108" "09710000000156f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0362" "2010" "39fa2f4e3d523d8619a73b4f65c3e14d" - /* TL sres TL kc */ - "2104" "9b36efdf" "2208" "059a4f668f6fbe39" - /* TL 3G IK */ - "2310" "27497388b6cb044648f396aa155b95ef" - /* TL 3G CK */ - "2410" "f64735036e5871319c679f4742a75ea1" - /* TL AUTN */ - "2510" "8704f5ba55f30000d2ee44b22c8ea919" - /* TL RES */ - "2708" "e229c19e791f2e41" - "0362" "2010" "c187a53a5e6b9d573cac7c74451fd46d" - "2104" "85aa3130" "2208" "d3d50a000bf04f6e" - "2310" "1159ec926a50e98c034a6b7d7c9f418d" - "2410" "df3a03d9ca5335641efc8e36d76cd20b" - "2510" "1843a645b98d00005b2d666af46c45d9" - "2708" "7db47cf7f81e4dc7" - "0362" "2010" "efa9c29a9742148d5c9070348716e1bb" - "2104" "69d5f9fb" "2208" "3df176f0c29f1a3d" - "2310" "eb50e770ddcc3060101d2f43b6c2b884" - "2410" "76542abce5ff9345b0e8947f4c6e019c" - "2510" "f9375e6d41e1000096e7fe4ff1c27e39" - "2708" "706f996719ba609c" - ,NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0"); - ms_sends_msg("0554" "9b36efdf"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000000156f00804032443f2", - "12010809710000000156f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000000156f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector"); - auth_request_sent = false; - auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d"; - auth_request_expect_autn = NULL; - cm_service_result_sent = RES_NONE; - ms_sends_msg("052478" - "03305886" /* classmark 2: GSM phase 2 */ - "089910070000106005" /* IMSI */); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts with a CM Service Accept"); - gsup_expect_tx(NULL); - ms_sends_msg("0554" "85aa3130"); /* 2nd vector's sres, s.a. */ - VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - - btw("a USSD request is serviced"); - dtap_expect_tx_ussd("Your extension is 42342\r"); - expect_bssap_clear(); - ms_sends_msg("0b3b1c15a11302010002013b300b04010f0406aa510c061b017f0100"); - OSMO_ASSERT(dtap_tx_confirmed); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("all requests serviced, conn has been released"); - EXPECT_CONN_COUNT(0); - - BTW("an SMS is sent, MS is paged"); - paging_expect_imsi(imsi); - paging_sent = false; - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - - send_sms(vsub, vsub, - "Privacy in residential applications is a desirable" - " marketing option."); - - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - vsub = NULL; - VERBOSE_ASSERT(paging_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); - - btw("the subscriber and its pending request should remain"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - - btw("MS replies with Paging Response, and VLR sends Auth Request with third key"); - auth_request_sent = false; - auth_request_expect_rand = "efa9c29a9742148d5c9070348716e1bb"; - auth_request_expect_autn = NULL; - ms_sends_msg("062707" - "03305886" /* classmark 2 */ - "089910070000106005" /* IMSI */); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts and sends pending SMS"); - dtap_expect_tx("09" /* SMS messages */ - "01" /* CP-DATA */ - "58" /* length */ - "01" /* Network to MS */ - "00" /* reference */ - /* originator (gsm411_send_sms() hardcodes this weird nr) */ - "0791" "447758100650" /* 447785016005 */ - "00" /* dest */ - /* SMS TPDU */ - "4c" /* len */ - "00" /* SMS deliver */ - "05802443f2" /* originating address 42342 */ - "00" /* TP-PID */ - "00" /* GSM default alphabet */ - "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/ - "000000" /* H-M-S */ - "00" /* GMT+0 */ - "44" /* data length */ - "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" - "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" - "0c7ac3e9e9b7db05"); - ms_sends_msg("0554" "69d5f9fb"); /* 3nd vector's sres, s.a. */ - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - - btw("SMS was delivered, no requests pending for subscr"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("conn is still open to wait for SMS ack dance"); - EXPECT_CONN_COUNT(1); - - btw("MS replies with CP-ACK for received SMS"); - ms_sends_msg("8904"); - EXPECT_CONN_COUNT(1); - - btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that"); - dtap_expect_tx("0904"); - expect_bssap_clear(); - ms_sends_msg("890106020041020000"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("SMS is done, conn is gone"); - EXPECT_CONN_COUNT(0); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130" - "089910070000106005" /* IMSI */); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -msc_vlr_test_func_t msc_vlr_tests[] = { - test_gsm_authen, - test_gsm_authen_tmsi, - test_gsm_authen_imei, - test_gsm_authen_tmsi_imei, - test_gsm_milenage_authen, - NULL -}; diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.err b/tests/msc_vlr/msc_vlr_test_gsm_authen.err deleted file mode 100644 index c12eba118..000000000 --- a/tests/msc_vlr/msc_vlr_test_gsm_authen.err +++ /dev/null @@ -1,1997 +0,0 @@ -===== test_gsm_authen -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Event VLR_ULA_E_HLR_LU_RES not permitted -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and... -- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b -- ...expecting sres=20bde240 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 0 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts with a CM Service Accept - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: 20 bd e2 40 -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -- sending CM Service Accept for MSISDN:46071 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 1 -- a USSD request is serviced - expecting USSD: - Your extension is 46071 - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:46071: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:46071: MSISDN = 46071 -DMSC msc_tx 43 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d -- DTAP matches expected message -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:46071 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM Subscriber MSISDN:46071 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 0 - strcmp(paging_expecting_imsi, imsi) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- the subscriber and its pending request should remain -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -- MS replies with Paging Response, and VLR sends Auth Request with third key - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 4 -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=2 auth_types=0x1 and... -- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42 -- ...expecting sres=a29514ae -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and sends pending SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: a2 95 14 ae -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:46071 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - dtap_tx_confirmed == 1 - paging_stopped == 1 -- SMS was delivered, no requests pending for subscr -DREF VLR subscr MSISDN:46071 usage increases to: 5 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF MSISDN:46071: MSC conn use - 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done, conn is gone - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_gsm_authen: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_gsm_authen_tmsi -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Event VLR_ULA_E_HLR_LU_RES not permitted -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -- Subscriber has the new TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0xffffffff - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- after a while, a new conn sends a CM Service Request using above TMSI. VLR responds with Auth Req, 2nd auth vector - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(TMSI)=50462976 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and... -- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b -- ...expecting sres=20bde240 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 0 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts with a CM Service Accept - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: 20 bd e2 40 -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -- sending CM Service Accept for MSISDN:46071 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 1 -- a USSD request is serviced - expecting USSD: - Your extension is 46071 - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:46071: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:46071: MSISDN = 46071 -DMSC msc_tx 43 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d -- DTAP matches expected message -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:46071 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM Subscriber MSISDN:46071 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0x03020100, LAC 0 - paging_expecting_tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- the subscriber and its pending request should remain -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -- MS replies with Paging Response using TMSI, and VLR sends Auth Request with third key - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(TMSI)=50462976 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 4 -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=2 auth_types=0x1 and... -- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42 -- ...expecting sres=a29514ae -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and sends pending SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: a2 95 14 ae -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:46071 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - dtap_tx_confirmed == 1 - paging_stopped == 1 -- SMS was delivered, no requests pending for subscr -DREF VLR subscr MSISDN:46071 usage increases to: 5 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF MSISDN:46071: MSC conn use - 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done, conn is gone - llist_count(&net->subscr_conns) == 0 ---- -- subscriber sends LU Request, this time with the TMSI -- Location Update request causes an Auth Req to MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(TMSI)=50462976 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: is child of Subscr_Conn(50462976) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=3 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=3 auth_types=0x1 and... -- ...rand=fa8f20b781b5881329d4fea26b1a3c51 -- ...expecting sres=5afc8d72 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 5afc8d72) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: 5a fc 8d 72 -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(50462976) -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(50462976) -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(50462976) -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(50462976) -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(50462976) -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x07060504 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:46071 usage increases to: 3 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x07060504 - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(50462976) -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(50462976) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -- subscriber has the new TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0xffffffff - vsub->tmsi == 0x07060504 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches, using new TMSI - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(TMSI)=117835012 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_gsm_authen_tmsi: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_gsm_authen_imei -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Event VLR_ULA_E_HLR_LU_RES not permitted -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI -DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- We will only do business when the IMEI is known - llist_count(&net->subscr_conns) == 1 -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->imei[0] == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS replies with an Identity Response - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420 -DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -- Subscriber has the IMEI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - strcmp(vsub->imei, "423423423423420") == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_gsm_authen_imei: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_gsm_authen_tmsi_imei -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Event VLR_ULA_E_HLR_LU_RES not permitted -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI -DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- We will only do business when the IMEI is known - llist_count(&net->subscr_conns) == 1 -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->imei[0] == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS replies with an Identity Response - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420 -DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x03020100 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -- Subscriber has the IMEI and TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - strcmp(vsub->imei, "423423423423420") == 0 - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches, using TMSI - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(TMSI)=50462976 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_gsm_authen_tmsi_imei: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_gsm_milenage_authen -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL -DMM LU/new-LAC: 0/0 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 -DVLR New subscr, IMSI: 901700000010650 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c -DVLR GSUP rx 311: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000010650) Received 3 auth tuples -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000010650: tuple use_count=1 key_seq=0 auth_types=0x3 and... -- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d -- ...expecting sres=9b36efdf -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000010650: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000010650: MM GSM AUTHENTICATION RESPONSE (sres = 9b36efdf) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000010650) received res: 9b 36 ef df -DVLR SUBSCR(IMSI:901700000010650) AUTH established GSM security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0 -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f2 -DVLR GSUP rx 17: 10010809710000000156f00804032443f2 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR IMSI:901700000010650 has MSISDN:42342 -DVLR GSUP tx: 12010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f0 -DVLR GSUP rx 11: 06010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:42342 -DREF VLR subscr MSISDN:42342 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DREF VLR subscr MSISDN:42342 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- sending GSM Auth Request for MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and... -- ...rand=c187a53a5e6b9d573cac7c74451fd46d -- ...expecting sres=85aa3130 -DREF VLR subscr MSISDN:42342 usage decreases to: 2 -DMM MSISDN:42342: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:42342: MSC conn use - 1 == 1 - cm_service_result_sent == 0 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts with a CM Service Accept - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = 85aa3130) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:42342) received res: 85 aa 31 30 -DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -- sending CM Service Accept for MSISDN:42342 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:42342: MSC conn use - 1 == 1 - cm_service_result_sent == 1 -- a USSD request is serviced - expecting USSD: - Your extension is 42342 - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:42342: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:42342: MSISDN = 42342 -DMSC msc_tx 43 bytes to MSISDN:42342 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d273104d36a3c91a0d -- DTAP matches expected message -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - bssap_clear_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:42342 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:42342 usage increases to: 3 -DMM Subscriber MSISDN:42342 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000010650, TMSI 0xffffffff, LAC 0 - strcmp(paging_expecting_imsi, imsi) == 0 -DREF VLR subscr MSISDN:42342 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:42342 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- the subscriber and its pending request should remain -DREF VLR subscr MSISDN:42342 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:42342 usage decreases to: 3 -- MS replies with Paging Response, and VLR sends Auth Request with third key - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000010650 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:42342 usage increases to: 4 -DREF VLR subscr MSISDN:42342 usage increases to: 5 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- sending GSM Auth Request for MSISDN:42342: tuple use_count=1 key_seq=2 auth_types=0x3 and... -- ...rand=efa9c29a9742148d5c9070348716e1bb -- ...expecting sres=69d5f9fb -DREF VLR subscr MSISDN:42342 usage decreases to: 4 -DMM MSISDN:42342: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:42342: MSC conn use - 1 == 1 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and sends pending SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = 69d5f9fb) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:42342) received res: 69 d5 f9 fb -DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:42342 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:42342 usage increases to: 5 -DREF MSISDN:42342: MSC conn use + 1 == 3 -DMSC msc_tx 91 bytes to MSISDN:42342 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:42342 usage decreases to: 4 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:42342: MSC conn use - 1 == 2 - dtap_tx_confirmed == 1 - paging_stopped == 1 -- SMS was delivered, no requests pending for subscr -DREF VLR subscr MSISDN:42342 usage increases to: 5 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:42342 usage decreases to: 4 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:42342: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:42342: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:42342: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:42342 usage decreases to: 3 -DREF VLR subscr MSISDN:42342 usage decreases to: 2 -DREF MSISDN:42342: MSC conn use - 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done, conn is gone - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DMM IMSI DETACH for MSISDN:42342 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -DREF VLR subscr MSISDN:42342 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:42342 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_gsm_milenage_authen: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.ok b/tests/msc_vlr/msc_vlr_test_gsm_authen.ok deleted file mode 100644 index a965a70ed..000000000 --- a/tests/msc_vlr/msc_vlr_test_gsm_authen.ok +++ /dev/null @@ -1 +0,0 @@ -Done diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c deleted file mode 100644 index e0bd9673a..000000000 --- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c +++ /dev/null @@ -1,845 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include "msc_vlr_tests.h" - -void test_ciph() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - /* implicit: net->authentication_required = true; */ - net->a5_encryption = VLR_CIPH_A5_1; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS"); - cipher_mode_cmd_sent = false; - ms_sends_msg("05542d8b2c3e"); - OSMO_ASSERT(cipher_mode_cmd_sent); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("needs ciph, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0632"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector"); - cm_service_result_sent = RES_NONE; - auth_request_sent = false; - auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b"; - ms_sends_msg("05247803305886089910070000006402"); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts and requests Ciphering"); - cipher_mode_cmd_sent = false; - ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d"); - - btw("needs ciph, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept"); - ms_sends_msg("0632"); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - - btw("a USSD request is serviced"); - dtap_expect_tx_ussd("Your extension is 46071\r"); - expect_bssap_clear(); - ms_sends_msg("0b3b1c15a11302010002013b300b04010f0406aa510c061b017f0100"); - OSMO_ASSERT(dtap_tx_confirmed); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("all requests serviced, conn has been released"); - EXPECT_CONN_COUNT(0); - - BTW("an SMS is sent, MS is paged"); - paging_expect_imsi(imsi); - paging_sent = false; - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - - send_sms(vsub, vsub, - "Privacy in residential applications is a desirable" - " marketing option."); - - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - vsub = NULL; - VERBOSE_ASSERT(paging_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); - - btw("the subscriber and its pending request should remain"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - - btw("MS replies with Paging Response, and VLR sends Auth Request with third key"); - auth_request_sent = false; - auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42"; - ms_sends_msg("06270703305882089910070000006402"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts and requests Ciphering"); - cipher_mode_cmd_sent = false; - ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */); - VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d"); - - btw("needs ciph, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS"); - dtap_expect_tx("09" /* SMS messages */ - "01" /* CP-DATA */ - "58" /* length */ - "01" /* Network to MS */ - "00" /* reference */ - /* originator (gsm411_send_sms() hardcodes this weird nr) */ - "0791" "447758100650" /* 447785016005 */ - "00" /* dest */ - /* SMS TPDU */ - "4c" /* len */ - "00" /* SMS deliver */ - "05806470f1" /* originating address 46071 */ - "00" /* TP-PID */ - "00" /* GSM default alphabet */ - "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/ - "000000" /* H-M-S */ - "00" /* GMT+0 */ - "44" /* data length */ - "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" - "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" - "0c7ac3e9e9b7db05"); - ms_sends_msg("0632"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - - btw("SMS was delivered, no requests pending for subscr"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("conn is still open to wait for SMS ack dance"); - EXPECT_CONN_COUNT(1); - - btw("MS replies with CP-ACK for received SMS"); - ms_sends_msg("8904"); - EXPECT_CONN_COUNT(1); - - btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that"); - dtap_expect_tx("0904"); - expect_bssap_clear(); - ms_sends_msg("890106020041020000"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("SMS is done, conn is gone"); - EXPECT_CONN_COUNT(0); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_ciph_tmsi() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - /* implicit: net->authentication_required = true; */ - net->a5_encryption = VLR_CIPH_A5_1; - net->vlr->cfg.assign_tmsi = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS"); - cipher_mode_cmd_sent = false; - ms_sends_msg("05542d8b2c3e"); - OSMO_ASSERT(cipher_mode_cmd_sent); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs ciph, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0632"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - gsup_rx("06010809710000004026f0", NULL); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the new TMSI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("after a while, a new conn sends a CM Service Request using above TMSI. VLR responds with Auth Req, 2nd auth vector"); - cm_service_result_sent = RES_NONE; - auth_request_sent = false; - auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b"; - auth_request_expect_autn = NULL; - ms_sends_msg("05247803305886" "05f4" "03020100"); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts and requests Ciphering"); - cipher_mode_cmd_sent = false; - ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d"); - - btw("needs ciph, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept"); - ms_sends_msg("0632"); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - - btw("a USSD request is serviced"); - dtap_expect_tx_ussd("Your extension is 46071\r"); - expect_bssap_clear(); - ms_sends_msg("0b3b1c15a11302010002013b300b04010f0406aa510c061b017f0100"); - OSMO_ASSERT(dtap_tx_confirmed); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("all requests serviced, conn has been released"); - EXPECT_CONN_COUNT(0); - - BTW("an SMS is sent, MS is paged"); - paging_expect_tmsi(0x03020100); - paging_sent = false; - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - - send_sms(vsub, vsub, - "Privacy in residential applications is a desirable" - " marketing option."); - - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - vsub = NULL; - VERBOSE_ASSERT(paging_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); - - btw("the subscriber and its pending request should remain"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - - btw("MS replies with Paging Response using TMSI, and VLR sends Auth Request with third key"); - auth_request_sent = false; - auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42"; - ms_sends_msg("06270703305882" "05f4" "03020100"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Authen Response, VLR accepts and requests Ciphering"); - cipher_mode_cmd_sent = false; - ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */); - VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d"); - - btw("needs ciph, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS"); - dtap_expect_tx("09" /* SMS messages */ - "01" /* CP-DATA */ - "58" /* length */ - "01" /* Network to MS */ - "00" /* reference */ - /* originator (gsm411_send_sms() hardcodes this weird nr) */ - "0791" "447758100650" /* 447785016005 */ - "00" /* dest */ - /* SMS TPDU */ - "4c" /* len */ - "00" /* SMS deliver */ - "05806470f1" /* originating address 46071 */ - "00" /* TP-PID */ - "00" /* GSM default alphabet */ - "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/ - "000000" /* H-M-S */ - "00" /* GMT+0 */ - "44" /* data length */ - "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" - "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" - "0c7ac3e9e9b7db05"); - ms_sends_msg("0632"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - - btw("SMS was delivered, no requests pending for subscr"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("conn is still open to wait for SMS ack dance"); - EXPECT_CONN_COUNT(1); - - btw("MS replies with CP-ACK for received SMS"); - ms_sends_msg("8904"); - EXPECT_CONN_COUNT(1); - - btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that"); - dtap_expect_tx("0904"); - expect_bssap_clear(); - ms_sends_msg("890106020041020000"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("SMS is done, conn is gone"); - EXPECT_CONN_COUNT(0); - - BTW("subscriber detaches, using TMSI"); - expect_bssap_clear(); - ms_sends_msg("050130" "05f4" "03020100"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_ciph_imei() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - /* implicit: net->authentication_required = true; */ - net->a5_encryption = VLR_CIPH_A5_1; - net->vlr->cfg.check_imei_rqd = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS"); - cipher_mode_cmd_sent = false; - ms_sends_msg("05542d8b2c3e"); - OSMO_ASSERT(cipher_mode_cmd_sent); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("needs ciph, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0632"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS"); - dtap_expect_tx("051802"); - gsup_rx("06010809710000004026f0", NULL); - - btw("We will only do business when the IMEI is known"); - EXPECT_CONN_COUNT(1); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(vsub->imei[0], == 0, "%d"); - vlr_subscr_put(vsub); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS replies with an Identity Response"); - expect_bssap_clear(); - ms_sends_msg("0559084a32244332244302"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the IMEI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_ciph_imeisv() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - /* implicit: net->authentication_required = true; */ - net->a5_encryption = VLR_CIPH_A5_1; - net->vlr->cfg.retrieve_imeisv_ciphered = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS"); - cipher_mode_cmd_sent = false; - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d"); - VERBOSE_ASSERT(cipher_mode_cmd_sent_with_imeisv, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("needs ciph, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(vsub->imeisv[0], == 0, "%d"); - vlr_subscr_put(vsub); - - btw("MS sends Ciphering Mode Complete with IMEISV, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("063217094b32244332244372f5"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("Subscriber has the IMEISV"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d"); - vlr_subscr_put(vsub); - - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_ciph_tmsi_imei() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - /* implicit: net->authentication_required = true; */ - net->a5_encryption = VLR_CIPH_A5_1; - net->vlr->cfg.assign_tmsi = true; - net->vlr->cfg.check_imei_rqd = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS"); - cipher_mode_cmd_sent = false; - ms_sends_msg("05542d8b2c3e"); - OSMO_ASSERT(cipher_mode_cmd_sent); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("needs ciph, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0632"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS"); - dtap_expect_tx("051802"); - gsup_rx("06010809710000004026f0", NULL); - - btw("We will only do business when the IMEI is known"); - EXPECT_CONN_COUNT(1); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(vsub->imei[0], == 0, "%d"); - vlr_subscr_put(vsub); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS replies with an Identity Response"); - ms_sends_msg("0559084a32244332244302"); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the IMEI and TMSI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches, using TMSI"); - expect_bssap_clear(); - ms_sends_msg("050130" "05f4" "03020100"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_lu_unknown_tmsi() -{ - comment_start(); - - btw("Location Update request with unknown TMSI sends ID Request for IMSI"); - lu_result_sent = RES_NONE; - dtap_expect_tx("051801"); - ms_sends_msg("050802008168000130" "05f4" "23422342"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS tells us the IMSI, causes a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0559089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -msc_vlr_test_func_t msc_vlr_tests[] = { - test_ciph, - test_ciph_tmsi, - test_ciph_imei, - test_ciph_imeisv, - test_ciph_tmsi_imei, - NULL -}; diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err deleted file mode 100644 index b26f0d20e..000000000 --- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err +++ /dev/null @@ -1,1679 +0,0 @@ -===== test_ciph -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 - auth_request_sent == 1 -- MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- needs ciph, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL -DRR IMSI:901700000004620: CIPHERING MODE COMPLETE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and... -- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b -- ...expecting sres=20bde240 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - auth_request_sent == 1 - cm_service_result_sent == 0 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and requests Ciphering - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: 20 bd e2 40 -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -- sending Ciphering Mode Command for MSISDN:46071: cipher=VLR_CIPH_A5_1 kc=07fa7502e07e1c00 retrieve_imeisv=0 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 0 - cipher_mode_cmd_sent == 1 -- needs ciph, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL -DRR MSISDN:46071: CIPHERING MODE COMPLETE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request - cm_service_result_sent == 0 -- a USSD request is serviced - expecting USSD: - Your extension is 46071 - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:46071: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:46071: MSISDN = 46071 -DMSC msc_tx 43 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d -- DTAP matches expected message -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:46071 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM Subscriber MSISDN:46071 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 0 - strcmp(paging_expecting_imsi, imsi) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- the subscriber and its pending request should remain -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -- MS replies with Paging Response, and VLR sends Auth Request with third key - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 4 -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=2 auth_types=0x1 and... -- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42 -- ...expecting sres=a29514ae -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and requests Ciphering - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: a2 95 14 ae -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -- sending Ciphering Mode Command for MSISDN:46071: cipher=VLR_CIPH_A5_1 kc=e2b234f807886400 retrieve_imeisv=0 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - cipher_mode_cmd_sent == 1 -- needs ciph, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL -DRR MSISDN:46071: CIPHERING MODE COMPLETE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:46071 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DREF MSISDN:46071: MSC conn use + 1 == 2 -DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS - dtap_tx_confirmed == 1 - paging_stopped == 1 -- SMS was delivered, no requests pending for subscr -DREF VLR subscr MSISDN:46071 usage increases to: 5 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF MSISDN:46071: MSC conn use - 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done, conn is gone - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_ciph: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_ciph_tmsi -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - auth_request_sent == 1 -- needs ciph, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL -DRR IMSI:901700000004620: CIPHERING MODE COMPLETE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -- Subscriber has the new TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0xffffffff - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- after a while, a new conn sends a CM Service Request using above TMSI. VLR responds with Auth Req, 2nd auth vector - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(TMSI)=50462976 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and... -- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b -- ...expecting sres=20bde240 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - auth_request_sent == 1 - cm_service_result_sent == 0 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and requests Ciphering - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: 20 bd e2 40 -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -- sending Ciphering Mode Command for MSISDN:46071: cipher=VLR_CIPH_A5_1 kc=07fa7502e07e1c00 retrieve_imeisv=0 -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 0 - cipher_mode_cmd_sent == 1 -- needs ciph, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL -DRR MSISDN:46071: CIPHERING MODE COMPLETE -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request - cm_service_result_sent == 0 -- a USSD request is serviced - expecting USSD: - Your extension is 46071 - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:46071: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:46071: MSISDN = 46071 -DMSC msc_tx 43 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d -- DTAP matches expected message -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:46071 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM Subscriber MSISDN:46071 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0x03020100, LAC 0 - paging_expecting_tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- the subscriber and its pending request should remain -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -- MS replies with Paging Response using TMSI, and VLR sends Auth Request with third key - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(TMSI)=50462976 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 4 -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=2 auth_types=0x1 and... -- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42 -- ...expecting sres=a29514ae -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and requests Ciphering - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: a2 95 14 ae -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(50462976) -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -- sending Ciphering Mode Command for MSISDN:46071: cipher=VLR_CIPH_A5_1 kc=e2b234f807886400 retrieve_imeisv=0 -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - cipher_mode_cmd_sent == 1 -- needs ciph, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL -DRR MSISDN:46071: CIPHERING MODE COMPLETE -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:46071 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DREF MSISDN:46071: MSC conn use + 1 == 2 -DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS - dtap_tx_confirmed == 1 - paging_stopped == 1 -- SMS was delivered, no requests pending for subscr -DREF VLR subscr MSISDN:46071 usage increases to: 5 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF MSISDN:46071: MSC conn use - 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done, conn is gone - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches, using TMSI - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(TMSI)=50462976 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_ciph_tmsi: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_ciph_imei -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- needs ciph, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL -DRR IMSI:901700000004620: CIPHERING MODE COMPLETE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI -DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- We will only do business when the IMEI is known - llist_count(&net->subscr_conns) == 1 -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->imei[0] == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS replies with an Identity Response - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420 -DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -- Subscriber has the IMEI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - strcmp(vsub->imei, "423423423423420") == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_ciph_imei: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_ciph_imeisv -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - cipher_mode_cmd_sent == 1 - cipher_mode_cmd_sent_with_imeisv == 1 - lu_result_sent == 0 -- needs ciph, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 - vsub->imeisv[0] == 0 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -- MS sends Ciphering Mode Complete with IMEISV, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL -DRR IMSI:901700000004620: CIPHERING MODE COMPLETE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: got IMEISV: 4234234234234275F -DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA - lu_result_sent == 0 -- Subscriber has the IMEISV -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 - strcmp(vsub->imeisv, "4234234234234275") == 0 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_ciph_imeisv: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_ciph_tmsi_imei -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -- sending Ciphering Mode Command for IMSI:901700000004620: cipher=VLR_CIPH_A5_1 kc=61855fb81fc2a800 retrieve_imeisv=0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- needs ciph, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL -DRR IMSI:901700000004620: CIPHERING MODE COMPLETE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI -DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- We will only do business when the IMEI is known - llist_count(&net->subscr_conns) == 1 -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->imei[0] == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS replies with an Identity Response - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420 -DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x03020100 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -- Subscriber has the IMEI and TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - strcmp(vsub->imei, "423423423423420") == 0 - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches, using TMSI - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(TMSI)=50462976 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_ciph_tmsi_imei: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.ok b/tests/msc_vlr/msc_vlr_test_gsm_ciph.ok deleted file mode 100644 index a965a70ed..000000000 --- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.ok +++ /dev/null @@ -1 +0,0 @@ -Done diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.c b/tests/msc_vlr/msc_vlr_test_hlr_reject.c deleted file mode 100644 index 095da8172..000000000 --- a/tests/msc_vlr/msc_vlr_test_hlr_reject.c +++ /dev/null @@ -1,447 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include "msc_vlr_tests.h" - -void test_hlr_rej_auth_info_unknown_imsi() -{ - comment_start(); - - net->authentication_required = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _SEND_AUTH_INFO_ERROR = unknown IMSI"); - auth_request_sent = false; - expect_bssap_clear(); - gsup_rx("09" "010809710000004026f0" "020102", NULL); - VERBOSE_ASSERT(auth_request_sent, == false, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_hlr_rej_auth_info_net_fail() -{ - comment_start(); - - net->authentication_required = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _SEND_AUTH_INFO_ERROR = net fail"); - auth_request_sent = false; - expect_bssap_clear(); - gsup_rx("09" "010809710000004026f0" "020111", NULL); - VERBOSE_ASSERT(auth_request_sent, == false, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_hlr_rej_auth_info_net_fail_no_reuse_tuples() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - net->authentication_required = true; - net->vlr->cfg.auth_reuse_old_sets_on_error = false; - net->vlr->cfg.auth_tuple_max_use_count = 0; - - BTW("Submit a used auth tuple in the VLR"); - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - ,NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - - BTW("Now one auth tuple is available, but used."); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - OSMO_ASSERT(vsub->last_tuple); - VERBOSE_ASSERT(vsub->last_tuple->use_count, == 1, "%d"); - /* no need to look at all auth tuples, the ongoing test would take an - * unexpected course if there were more. */ - vlr_subscr_put(vsub); - - BTW("Another LU wants to get new tuples; HLR sends Network Failure, we reject."); - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _SEND_AUTH_INFO_ERROR = net fail"); - auth_request_sent = false; - expect_bssap_clear(); - gsup_rx("09" "010809710000004026f0" "020111", NULL); - VERBOSE_ASSERT(auth_request_sent, == false, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - net->authentication_required = true; - net->vlr->cfg.auth_reuse_old_sets_on_error = true; - net->vlr->cfg.auth_tuple_max_use_count = 0; - - BTW("Submit a used auth tuple in the VLR"); - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - ,NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - - BTW("Now one auth tuple is available, but used."); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - OSMO_ASSERT(vsub->last_tuple); - VERBOSE_ASSERT(vsub->last_tuple->use_count, == 1, "%d"); - /* no need to look at all auth tuples, the ongoing test would take an - * unexpected course if there were more. */ - vlr_subscr_put(vsub); - - BTW("Another LU wants to get new tuples; HLR sends IMSI Unknown. Even though we would re-use an old tuple, reject the unknown IMSI."); - VERBOSE_ASSERT(net->vlr->cfg.auth_reuse_old_sets_on_error, == true, "%d"); - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _SEND_AUTH_INFO_ERROR = unknown IMSI"); - auth_request_sent = false; - expect_bssap_clear(); - gsup_rx("09" "010809710000004026f0" "020102", NULL); - VERBOSE_ASSERT(auth_request_sent, == false, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_hlr_acc_but_no_auth_tuples() -{ - comment_start(); - - net->authentication_required = true; - net->vlr->cfg.auth_reuse_old_sets_on_error = true; - net->vlr->cfg.auth_tuple_max_use_count = 0; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT but it lacks auth tuples"); - auth_request_sent = false; - expect_bssap_clear(); - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* NO auth vectors */ - ,NULL); - VERBOSE_ASSERT(auth_request_sent, == false, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_hlr_rej_auth_info_net_fail_reuse_tuples() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - comment_start(); - - net->authentication_required = true; - net->vlr->cfg.auth_reuse_old_sets_on_error = true; - net->vlr->cfg.auth_tuple_max_use_count = 0; - - BTW("Submit a used auth tuple in the VLR"); - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - ,NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - - BTW("Now one auth tuple is available, but used."); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - OSMO_ASSERT(vsub->last_tuple); - VERBOSE_ASSERT(vsub->last_tuple->use_count, == 1, "%d"); - /* no need to look at all auth tuples, the ongoing test would take an - * unexpected course if there were more. */ - vlr_subscr_put(vsub); - - BTW("Another LU wants to get new tuples; even though HLR sends Network Failure, we are reusing the old tuples."); - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _SEND_AUTH_INFO_ERROR = net fail"); - auth_request_sent = false; - gsup_rx("09" "010809710000004026f0" "020111", NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); - comment_end(); -} - -void test_hlr_rej_lu() -{ - comment_start(); - - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends UPDATE_LOCATION_ERROR"); - expect_bssap_clear(); - gsup_rx("05" "010809710000004026f0" "020102", - NULL); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); - comment_end(); -} - -void test_hlr_no_insert_data() -{ - comment_start(); - - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends only _UPDATE_LOCATION_RESULT, no INSERT DATA"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - /* TODO should we wait for OSMO_GSUP_MSGT_INSERT_DATA_REQUEST? */ - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -msc_vlr_test_func_t msc_vlr_tests[] = { - test_hlr_rej_auth_info_unknown_imsi, - test_hlr_rej_auth_info_net_fail, - test_hlr_rej_auth_info_net_fail_reuse_tuples, - test_hlr_rej_auth_info_net_fail_no_reuse_tuples, - test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples, - test_hlr_acc_but_no_auth_tuples, - test_hlr_rej_lu, - test_hlr_no_insert_data, - NULL -}; diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.err b/tests/msc_vlr/msc_vlr_test_hlr_reject.err deleted file mode 100644 index c946c1efa..000000000 --- a/tests/msc_vlr/msc_vlr_test_hlr_reject.err +++ /dev/null @@ -1,1165 +0,0 @@ -===== test_hlr_rej_auth_info_unknown_imsi -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _SEND_AUTH_INFO_ERROR = unknown IMSI -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020102 -DVLR GSUP rx 14: 09010809710000004026f0020102 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 2: IMSI unknown in HLR -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result VLR_AUTH_RES_UNKNOWN_SUBSCR -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -- sending LU Reject for IMSI:901700000004620, cause 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=IMSI:901700000004620, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF IMSI:901700000004620: MSC conn use - 1 == 0 -DRLL subscr IMSI:901700000004620: Freeing subscriber connection -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr IMSI:901700000004620 usage decreases to: 0 -DREF freeing VLR subscr IMSI:901700000004620 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 0 - lu_result_sent == 2 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_hlr_rej_auth_info_unknown_imsi: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_hlr_rej_auth_info_net_fail -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _SEND_AUTH_INFO_ERROR = net fail -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020111 -DVLR GSUP rx 14: 09010809710000004026f0020111 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result VLR_AUTH_RES_PROC_ERR -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -- sending LU Reject for IMSI:901700000004620, cause 17 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=IMSI:901700000004620, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF IMSI:901700000004620: MSC conn use - 1 == 0 -DRLL subscr IMSI:901700000004620: Freeing subscriber connection -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr IMSI:901700000004620 usage decreases to: 0 -DREF freeing VLR subscr IMSI:901700000004620 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 0 - lu_result_sent == 2 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_hlr_rej_auth_info_net_fail: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_hlr_rej_auth_info_net_fail_reuse_tuples ---- -- Submit a used auth tuple in the VLR -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800 -DVLR GSUP rx 47: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 1 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- Now one auth tuple is available, but used. -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->last_tuple->use_count == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- Another LU wants to get new tuples; even though HLR sends Network Failure, we are reusing the old tuples. -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _SEND_AUTH_INFO_ERROR = net fail -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020111 -DVLR GSUP rx 14: 09010809710000004026f0020111 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=2 key_seq=0 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=2 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:46071) received res: 2d 8b 2c 3e -DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_hlr_rej_auth_info_net_fail_reuse_tuples: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_hlr_rej_auth_info_net_fail_no_reuse_tuples ---- -- Submit a used auth tuple in the VLR -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800 -DVLR GSUP rx 47: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 1 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- Now one auth tuple is available, but used. -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->last_tuple->use_count == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- Another LU wants to get new tuples; HLR sends Network Failure, we reject. -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _SEND_AUTH_INFO_ERROR = net fail -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020111 -DVLR GSUP rx 14: 09010809710000004026f0020111 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result VLR_AUTH_RES_PROC_ERR -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -- sending LU Reject for MSISDN:46071, cause 17 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 0 - lu_result_sent == 2 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_hlr_rej_auth_info_net_fail_no_reuse_tuples: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples ---- -- Submit a used auth tuple in the VLR -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800 -DVLR GSUP rx 47: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 1 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- Now one auth tuple is available, but used. -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->last_tuple->use_count == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- Another LU wants to get new tuples; HLR sends IMSI Unknown. Even though we would re-use an old tuple, reject the unknown IMSI. - net->vlr->cfg.auth_reuse_old_sets_on_error == 1 -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _SEND_AUTH_INFO_ERROR = unknown IMSI -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020102 -DVLR GSUP rx 14: 09010809710000004026f0020102 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 2: IMSI unknown in HLR -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result VLR_AUTH_RES_UNKNOWN_SUBSCR -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -- sending LU Reject for MSISDN:46071, cause 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 0 - lu_result_sent == 2 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_hlr_acc_but_no_auth_tuples -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT but it lacks auth tuples -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f0 -DVLR GSUP rx 11: 0a010809710000004026f0 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result VLR_AUTH_RES_PROC_ERR -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -- sending LU Reject for IMSI:901700000004620, cause 17 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=IMSI:901700000004620, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF IMSI:901700000004620: MSC conn use - 1 == 0 -DRLL subscr IMSI:901700000004620: Freeing subscriber connection -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr IMSI:901700000004620 usage decreases to: 0 -DREF freeing VLR subscr IMSI:901700000004620 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 0 - lu_result_sent == 2 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_hlr_acc_but_no_auth_tuples: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_hlr_rej_lu -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends UPDATE_LOCATION_ERROR -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: 05010809710000004026f0020102 -DVLR GSUP rx 14: 05010809710000004026f0020102 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR SUBSCR(IMSI:901700000004620) UpdateLocation failed; gmm_cause: IMSI unknown in HLR -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_NACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -- sending LU Reject for IMSI:901700000004620, cause 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=IMSI:901700000004620, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF IMSI:901700000004620: MSC conn use - 1 == 0 -DRLL subscr IMSI:901700000004620: Freeing subscriber connection -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr IMSI:901700000004620 usage decreases to: 0 -DREF freeing VLR subscr IMSI:901700000004620 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 2 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_hlr_rej_lu: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_hlr_no_insert_data -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends only _UPDATE_LOCATION_RESULT, no INSERT DATA -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for IMSI:901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=IMSI:901700000004620, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF IMSI:901700000004620: MSC conn use - 1 == 0 -DRLL subscr IMSI:901700000004620: Freeing subscriber connection -DREF VLR subscr IMSI:901700000004620 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr IMSI:901700000004620 -===== test_hlr_no_insert_data: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.ok b/tests/msc_vlr/msc_vlr_test_hlr_reject.ok deleted file mode 100644 index a965a70ed..000000000 --- a/tests/msc_vlr/msc_vlr_test_hlr_reject.ok +++ /dev/null @@ -1 +0,0 @@ -Done diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.c b/tests/msc_vlr/msc_vlr_test_hlr_timeout.c deleted file mode 100644 index c2f17c85f..000000000 --- a/tests/msc_vlr/msc_vlr_test_hlr_timeout.c +++ /dev/null @@ -1,118 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include "msc_vlr_tests.h" - -#include - -void test_hlr_timeout_lu_auth_info() -{ - comment_start(); - - fake_time_start(); - - net->authentication_required = true; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - BTW("HLR never replies"); - - btw("At first, we're still waiting"); - fake_time_passes(0, 423); - EXPECT_CONN_COUNT(1); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - expect_bssap_clear(); - fake_time_passes(1, 235); - btw("SUBSCR_CONN_TIMEOUT has passed, conn is gone."); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - - clear_vlr(); - comment_end(); -} - -void test_hlr_timeout_lu_upd_loc_result() -{ - comment_start(); - - fake_time_start(); - - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - BTW("HLR never sends GSUP _UPDATE_LOCATION_RESULT"); - - btw("At first, we're still waiting"); - fake_time_passes(0, 423); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - expect_bssap_clear(); - fake_time_passes(1, 235); - btw("SUBSCR_CONN_TIMEOUT has passed, conn is gone."); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - - clear_vlr(); - comment_end(); -} - -msc_vlr_test_func_t msc_vlr_tests[] = { - test_hlr_timeout_lu_auth_info, - test_hlr_timeout_lu_upd_loc_result, - NULL -}; diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.err b/tests/msc_vlr/msc_vlr_test_hlr_timeout.err deleted file mode 100644 index e34490d8c..000000000 --- a/tests/msc_vlr/msc_vlr_test_hlr_timeout.err +++ /dev/null @@ -1,189 +0,0 @@ -===== test_hlr_timeout_lu_auth_info -- Total time passed: 0.000000 s -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 ---- -- HLR never replies -- At first, we're still waiting -- Total time passed: 0.000423 s - llist_count(&net->subscr_conns) == 1 -- Total time passed: 1.000658 s - llist_count(&net->subscr_conns) == 1 -- Total time passed: 2.000893 s - llist_count(&net->subscr_conns) == 1 -- Total time passed: 3.001128 s - llist_count(&net->subscr_conns) == 1 -- Total time passed: 4.001363 s - llist_count(&net->subscr_conns) == 1 -- Total time passed: 5.001598 s -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Timeout of T0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Connection timed out -- sending LU Reject for IMSI:901700000004620, cause 22 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=IMSI:901700000004620, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF IMSI:901700000004620: MSC conn use - 1 == 0 -DRLL subscr IMSI:901700000004620: Freeing subscriber connection -DREF VLR subscr IMSI:901700000004620 usage decreases to: 0 -DREF freeing VLR subscr IMSI:901700000004620 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Event SUBSCR_CONN_E_CN_CLOSE not permitted -- SUBSCR_CONN_TIMEOUT has passed, conn is gone. - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 - lu_result_sent == 2 -===== test_hlr_timeout_lu_auth_info: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_hlr_timeout_lu_upd_loc_result -- Total time passed: 0.000000 s -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 ---- -- HLR never sends GSUP _UPDATE_LOCATION_RESULT -- At first, we're still waiting -- Total time passed: 0.000423 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 1.000658 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 2.000893 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 3.001128 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 4.001363 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 5.001598 s -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Timeout of T0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Connection timed out -- sending LU Reject for MSISDN:46071, cause 22 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Event SUBSCR_CONN_E_CN_CLOSE not permitted -- SUBSCR_CONN_TIMEOUT has passed, conn is gone. - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 - lu_result_sent == 2 -===== test_hlr_timeout_lu_upd_loc_result: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.ok b/tests/msc_vlr/msc_vlr_test_hlr_timeout.ok deleted file mode 100644 index a965a70ed..000000000 --- a/tests/msc_vlr/msc_vlr_test_hlr_timeout.ok +++ /dev/null @@ -1 +0,0 @@ -Done diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.c b/tests/msc_vlr/msc_vlr_test_ms_timeout.c deleted file mode 100644 index d8a3a314e..000000000 --- a/tests/msc_vlr/msc_vlr_test_ms_timeout.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include "msc_vlr_tests.h" - -void test_ms_timeout_lu_auth_resp() -{ - comment_start(); - - net->authentication_required = true; - - fake_time_start(); - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - ,NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - BTW("MS fails to send an Authentication Response"); - - btw("At first, we're still waiting"); - fake_time_passes(0, 423); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - expect_bssap_clear(); - fake_time_passes(1, 235); - btw("SUBSCR_CONN_TIMEOUT has passed, conn is gone."); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - - comment_end(); -} - -void test_ms_timeout_cm_auth_resp() -{ - comment_start(); - - net->authentication_required = true; - - fake_time_start(); - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - auth_request_sent = false; - auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b"; - auth_request_expect_autn = NULL; - /* Based on a Ki of 000102030405060708090a0b0c0d0e0f */ - gsup_rx("0a" - /* imsi */ - "0108" "09710000004026f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0322" "2010" "585df1ae287f6e273dce07090d61320b" - /* TL sres TL kc */ - "2104" "2d8b2c3e" "2208" "61855fb81fc2a800" - "0322" "2010" "12aca96fb4ffdea5c985cbafa9b6e18b" - "2104" "20bde240" "2208" "07fa7502e07e1c00" - "0322" "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42" - "2104" "a29514ae" "2208" "e2b234f807886400" - "0322" "2010" "fa8f20b781b5881329d4fea26b1a3c51" - "2104" "5afc8d72" "2208" "2392f14f709ae000" - "0322" "2010" "0fd4cc8dbe8715d1f439e304edfd68dc" - "2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("05542d8b2c3e"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector"); - auth_request_sent = false; - auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b"; - cm_service_result_sent = RES_NONE; - ms_sends_msg("05247803305886089910070000006402"); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - BTW("MS fails to send an Authentication Response"); - - btw("At first, we're still waiting"); - fake_time_passes(0, 423); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - fake_time_passes(1, 235); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - expect_bssap_clear(); - fake_time_passes(1, 235); - btw("SUBSCR_CONN_TIMEOUT has passed, conn is gone."); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - VERBOSE_ASSERT(cm_service_result_sent, == RES_REJECT, "%d"); - - clear_vlr(); - comment_end(); -} - -msc_vlr_test_func_t msc_vlr_tests[] = { - test_ms_timeout_lu_auth_resp, - test_ms_timeout_cm_auth_resp, - NULL -}; diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.err b/tests/msc_vlr/msc_vlr_test_ms_timeout.err deleted file mode 100644 index e267c5b0c..000000000 --- a/tests/msc_vlr/msc_vlr_test_ms_timeout.err +++ /dev/null @@ -1,342 +0,0 @@ -===== test_ms_timeout_lu_auth_resp -- Total time passed: 0.000000 s -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800 -DVLR GSUP rx 47: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 1 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 ---- -- MS fails to send an Authentication Response -- At first, we're still waiting -- Total time passed: 0.000423 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 1.000658 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 2.000893 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 3.001128 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 4.001363 s - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 0 -- Total time passed: 5.001598 s -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Timeout of T0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Connection timed out -- sending LU Reject for IMSI:901700000004620, cause 22 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=IMSI:901700000004620, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF IMSI:901700000004620: MSC conn use - 1 == 0 -DRLL subscr IMSI:901700000004620: Freeing subscriber connection -DREF VLR subscr IMSI:901700000004620 usage decreases to: 0 -DREF freeing VLR subscr IMSI:901700000004620 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Event SUBSCR_CONN_E_CN_CLOSE not permitted -- SUBSCR_CONN_TIMEOUT has passed, conn is gone. - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 - lu_result_sent == 2 -===== test_ms_timeout_lu_auth_resp: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_ms_timeout_cm_auth_resp -- Total time passed: 0.000000 s -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and... -- ...rand=585df1ae287f6e273dce07090d61320b -- ...expecting sres=2d8b2c3e -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000004620) received res: 2d 8b 2c 3e -DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and... -- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b -- ...expecting sres=20bde240 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 0 - auth_request_sent == 1 ---- -- MS fails to send an Authentication Response -- At first, we're still waiting -- Total time passed: 0.000423 s - llist_count(&net->subscr_conns) == 1 - cm_service_result_sent == 0 -- Total time passed: 1.000658 s - llist_count(&net->subscr_conns) == 1 - cm_service_result_sent == 0 -- Total time passed: 2.000893 s - llist_count(&net->subscr_conns) == 1 - cm_service_result_sent == 0 -- Total time passed: 3.001128 s - llist_count(&net->subscr_conns) == 1 - cm_service_result_sent == 0 -- Total time passed: 4.001363 s - llist_count(&net->subscr_conns) == 1 - cm_service_result_sent == 0 -- Total time passed: 5.001598 s -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Timeout of T0 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: Connection timed out -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_TIMEOUT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_TIMEOUT -- sending CM Service Reject for MSISDN:46071, result VLR_PR_ARQ_RES_TIMEOUT -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Removing from parent Process_Access_Request_VLR(901700000004620) -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Freeing instance -DVLR VLR_Authenticate(901700000004620){VLR_SUB_AS_WAIT_RESP}: Deallocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Event SUBSCR_CONN_E_CN_CLOSE not permitted -- SUBSCR_CONN_TIMEOUT has passed, conn is gone. - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 - cm_service_result_sent == 2 -DREF freeing VLR subscr MSISDN:46071 -===== test_ms_timeout_cm_auth_resp: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.ok b/tests/msc_vlr/msc_vlr_test_ms_timeout.ok deleted file mode 100644 index a965a70ed..000000000 --- a/tests/msc_vlr/msc_vlr_test_ms_timeout.ok +++ /dev/null @@ -1 +0,0 @@ -Done diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.c b/tests/msc_vlr/msc_vlr_test_no_authen.c deleted file mode 100644 index 32e0b40e2..000000000 --- a/tests/msc_vlr/msc_vlr_test_no_authen.c +++ /dev/null @@ -1,908 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include "msc_vlr_tests.h" - -void test_no_authen() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - /* No auth only works on GERAN */ - rx_from_ran = RAN_GERAN_A; - - comment_start(); - - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - - thwart_rx_non_initial_requests(); - - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - - BTW("after a while, a new conn sends a CM Service Request"); - cm_service_result_sent = RES_NONE; - ms_sends_msg("05247803305886089910070000006402"); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(true); - - btw("a USSD request is serviced"); - dtap_expect_tx_ussd("Your extension is 46071\r"); - expect_bssap_clear(); - ms_sends_msg("0b3b1c15a11302010002013b300b04010f0406aa510c061b017f0100"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("all requests serviced, conn has been released"); - EXPECT_CONN_COUNT(0); - - BTW("an SMS is sent, MS is paged"); - paging_expect_imsi(imsi); - paging_sent = false; - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - - send_sms(vsub, vsub, - "Privacy in residential applications is a desirable" - " marketing option."); - - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - vsub = NULL; - VERBOSE_ASSERT(paging_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); - - btw("the subscriber and its pending request should remain"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - - btw("MS replies with Paging Response, we deliver the SMS"); - dtap_expect_tx("09" /* SMS messages */ - "01" /* CP-DATA */ - "58" /* length */ - "01" /* Network to MS */ - "00" /* reference */ - /* originator (gsm411_send_sms() hardcodes this weird nr) */ - "0791" "447758100650" /* 447785016005 */ - "00" /* dest */ - /* SMS TPDU */ - "4c" /* len */ - "00" /* SMS deliver */ - "05806470f1" /* originating address 46071 */ - "00" /* TP-PID */ - "00" /* GSM default alphabet */ - "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/ - "000000" /* H-M-S */ - "00" /* GMT+0 */ - "44" /* data length */ - "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" - "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" - "0c7ac3e9e9b7db05"); - ms_sends_msg("06270703305882089910070000006402"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - - btw("SMS was delivered, no requests pending for subscr"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("conn is still open to wait for SMS ack dance"); - EXPECT_CONN_COUNT(1); - - btw("MS replies with CP-ACK for received SMS"); - ms_sends_msg("8904"); - EXPECT_CONN_COUNT(1); - - btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that"); - dtap_expect_tx("0904"); - expect_bssap_clear(); - ms_sends_msg("890106020041020000"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("SMS is done, conn is gone"); - EXPECT_CONN_COUNT(0); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_no_authen_tmsi() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - rx_from_ran = RAN_GERAN_A; - - comment_start(); - - net->vlr->cfg.assign_tmsi = true; - - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - gsup_rx("06010809710000004026f0", NULL); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the new TMSI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("after a while, a new conn sends a CM Service Request using above TMSI"); - cm_service_result_sent = RES_NONE; - ms_sends_msg("05247803305886" "05f4" "03020100"); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(true); - - btw("a USSD request is serviced"); - dtap_expect_tx_ussd("Your extension is 46071\r"); - expect_bssap_clear(); - ms_sends_msg("0b3b1c15a11302010002013b300b04010f0406aa510c061b017f0100"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("all requests serviced, conn has been released"); - EXPECT_CONN_COUNT(0); - - BTW("an SMS is sent, MS is paged using above TMSI"); - paging_expect_tmsi(0x03020100); - paging_sent = false; - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - - send_sms(vsub, vsub, - "Privacy in residential applications is a desirable" - " marketing option."); - - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - vsub = NULL; - VERBOSE_ASSERT(paging_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); - - btw("the subscriber and its pending request should remain"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - - btw("MS replies with Paging Response using TMSI, we deliver the SMS"); - dtap_expect_tx("09" /* SMS messages */ - "01" /* CP-DATA */ - "58" /* length */ - "01" /* Network to MS */ - "00" /* reference */ - /* originator (gsm411_send_sms() hardcodes this weird nr) */ - "0791" "447758100650" /* 447785016005 */ - "00" /* dest */ - /* SMS TPDU */ - "4c" /* len */ - "00" /* SMS deliver */ - "05806470f1" /* originating address 46071 */ - "00" /* TP-PID */ - "00" /* GSM default alphabet */ - "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/ - "000000" /* H-M-S */ - "00" /* GMT+0 */ - "44" /* data length */ - "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" - "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" - "0c7ac3e9e9b7db05"); - ms_sends_msg("06270703305882" "05f4" "03020100"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - - btw("SMS was delivered, no requests pending for subscr"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("conn is still open to wait for SMS ack dance"); - EXPECT_CONN_COUNT(1); - - btw("MS replies with CP-ACK for received SMS"); - ms_sends_msg("8904"); - EXPECT_CONN_COUNT(1); - - btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that"); - dtap_expect_tx("0904"); - expect_bssap_clear(); - ms_sends_msg("890106020041020000"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("SMS is done, conn is gone"); - EXPECT_CONN_COUNT(0); - - /* TODO: when the subscriber detaches, the vlr_subscr gets - * deallocated and we no longer know the TMSI. This case is covered by - * test_lu_unknown_tmsi(), so here I'd like to still have the TMSI. - BTW("subscriber detaches, using TMSI"); - ms_sends_msg("050130" "05f4" "03020100"); - EXPECT_CONN_COUNT(0); - */ - - BTW("subscriber sends LU Request, this time with the TMSI"); - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130" "05f4" "03020100"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - gsup_rx("06010809710000004026f0", NULL); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x07060504, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - btw("subscriber has the new TMSI"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == 0x07060504, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches, using new TMSI"); - expect_bssap_clear(); - ms_sends_msg("050130" "05f4" "07060504"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_no_authen_imei() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - rx_from_ran = RAN_GERAN_A; - - comment_start(); - - net->vlr->cfg.check_imei_rqd = true; - - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS"); - dtap_expect_tx("051802"); - gsup_rx("06010809710000004026f0", NULL); - - btw("We will only do business when the IMEI is known"); - EXPECT_CONN_COUNT(1); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(vsub->imei[0], == 0, "%d"); - vlr_subscr_put(vsub); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS replies with an Identity Response"); - expect_bssap_clear(); - /* 3GPP TS 23.003: 6.2.1 Composition of IMEI: the IMEI ends with a - * spare digit that shall be sent as zero by the MS. */ - ms_sends_msg("0559084a32244332244302"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the IMEI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_no_authen_tmsi_imei() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - rx_from_ran = RAN_GERAN_A; - - comment_start(); - - net->vlr->cfg.assign_tmsi = true; - net->vlr->cfg.check_imei_rqd = true; - - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS"); - dtap_expect_tx("051802"); - gsup_rx("06010809710000004026f0", NULL); - - btw("We will only do business when the IMEI is known"); - EXPECT_CONN_COUNT(1); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(vsub->imei[0], == 0, "%d"); - vlr_subscr_put(vsub); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS replies with an Identity Response"); - ms_sends_msg("0559084a32244332244302"); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the IMEI and TMSI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_no_authen_imeisv() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - /* No auth only works on GERAN */ - rx_from_ran = RAN_GERAN_A; - - comment_start(); - - net->vlr->cfg.retrieve_imeisv_early = true; - - btw("Location Update request causes an IMEISV ID request back to the MS"); - lu_result_sent = RES_NONE; - dtap_expect_tx("051803"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(dtap_tx_confirmed); - - btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0559094332244332244372f5"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("Subscriber has the IMEISV from the ID Response"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - - thwart_rx_non_initial_requests(); - - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_no_authen_imeisv_imei() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - rx_from_ran = RAN_GERAN_A; - - comment_start(); - - net->vlr->cfg.retrieve_imeisv_early = true; - net->vlr->cfg.check_imei_rqd = true; - - btw("Location Update request causes an IMEISV ID request back to the MS"); - lu_result_sent = RES_NONE; - dtap_expect_tx("051803"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(dtap_tx_confirmed); - - btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0559094332244332244372f5"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("Subscriber has the IMEISV from the ID Response"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS"); - dtap_expect_tx("051802"); - gsup_rx("06010809710000004026f0", NULL); - - btw("We will only do business when the IMEI is known"); - EXPECT_CONN_COUNT(1); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(vsub->imei[0], == 0, "%d"); - vlr_subscr_put(vsub); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS replies with an Identity Response"); - expect_bssap_clear(); - ms_sends_msg("0559084a32244332244302"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the IMEI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_no_authen_imeisv_tmsi() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - rx_from_ran = RAN_GERAN_A; - - comment_start(); - - net->vlr->cfg.retrieve_imeisv_early = true; - net->vlr->cfg.assign_tmsi = true; - - btw("Location Update request causes an IMEISV ID request back to the MS"); - lu_result_sent = RES_NONE; - dtap_expect_tx("051803"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(dtap_tx_confirmed); - - btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0559094332244332244372f5"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("Subscriber has the IMEISV from the ID Response"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - gsup_rx("06010809710000004026f0", NULL); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - - BTW("subscriber sends LU Request, this time with the TMSI"); - btw("Location Update request causes an IMEISV ID request back to the MS"); - lu_result_sent = RES_NONE; - dtap_expect_tx("051803"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(dtap_tx_confirmed); - - btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0559095332244332244372f6"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("Subscriber has the IMEISV from the ID Response"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imeisv, "5234234234234276"), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - gsup_rx("06010809710000004026f0", NULL); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x07060504, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - btw("subscriber has the new TMSI"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == 0x07060504, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches, using new TMSI"); - expect_bssap_clear(); - ms_sends_msg("050130" "05f4" "07060504"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_no_authen_imeisv_tmsi_imei() -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000004620"; - - rx_from_ran = RAN_GERAN_A; - - comment_start(); - - net->vlr->cfg.retrieve_imeisv_early = true; - net->vlr->cfg.assign_tmsi = true; - net->vlr->cfg.check_imei_rqd = true; - - btw("Location Update request causes an IMEISV ID request back to the MS"); - lu_result_sent = RES_NONE; - dtap_expect_tx("051803"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(dtap_tx_confirmed); - - btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0559094332244332244372f5"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("Subscriber has the IMEISV from the ID Response"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS"); - dtap_expect_tx("051802"); - gsup_rx("06010809710000004026f0", NULL); - - btw("We will only do business when the IMEI is known"); - EXPECT_CONN_COUNT(1); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(vsub->imei[0], == 0, "%d"); - vlr_subscr_put(vsub); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS replies with an Identity Response"); - ms_sends_msg("0559084a32244332244302"); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS sends TMSI Realloc Complete"); - expect_bssap_clear(); - ms_sends_msg("055b"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - btw("Subscriber has the IMEISV, IMEI and TMSI"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x"); - vlr_subscr_put(vsub); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - - -msc_vlr_test_func_t msc_vlr_tests[] = { - test_no_authen, - test_no_authen_tmsi, - test_no_authen_imei, - test_no_authen_tmsi_imei, - test_no_authen_imeisv, - test_no_authen_imeisv_imei, - test_no_authen_imeisv_tmsi, - test_no_authen_imeisv_tmsi_imei, - NULL -}; diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.err b/tests/msc_vlr/msc_vlr_test_no_authen.err deleted file mode 100644 index 931a72f78..000000000 --- a/tests/msc_vlr/msc_vlr_test_no_authen.err +++ /dev/null @@ -1,2119 +0,0 @@ -===== test_no_authen -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- after a while, a new conn sends a CM Service Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -- sending CM Service Accept for MSISDN:46071 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 1 -msc_subscr_conn_is_accepted() == true -- a USSD request is serviced - expecting USSD: - Your extension is 46071 - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:46071: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:46071: MSISDN = 46071 -DMSC msc_tx 43 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d -- DTAP matches expected message -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:46071 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM Subscriber MSISDN:46071 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 0 - strcmp(paging_expecting_imsi, imsi) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- the subscriber and its pending request should remain -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -- MS replies with Paging Response, we deliver the SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 4 -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:46071 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:46071 usage increases to: 6 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 5 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - dtap_tx_confirmed == 1 - paging_stopped == 1 -- SMS was delivered, no requests pending for subscr -DREF VLR subscr MSISDN:46071 usage increases to: 5 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF MSISDN:46071: MSC conn use - 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done, conn is gone - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_no_authen: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_no_authen_tmsi -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -- Subscriber has the new TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0xffffffff - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- after a while, a new conn sends a CM Service Request using above TMSI - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(TMSI)=50462976 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -- sending CM Service Accept for MSISDN:46071 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 1 -msc_subscr_conn_is_accepted() == true -- a USSD request is serviced - expecting USSD: - Your extension is 46071 - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:46071: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:46071: MSISDN = 46071 -DMSC msc_tx 43 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d -- DTAP matches expected message -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged using above TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM Subscriber MSISDN:46071 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0x03020100, LAC 0 - paging_expecting_tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- the subscriber and its pending request should remain -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -- MS replies with Paging Response using TMSI, we deliver the SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(TMSI)=50462976 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 4 -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:46071 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:46071 usage increases to: 6 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 5 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - dtap_tx_confirmed == 1 - paging_stopped == 1 -- SMS was delivered, no requests pending for subscr -DREF VLR subscr MSISDN:46071 usage increases to: 5 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF MSISDN:46071: MSC conn use - 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(50462976) -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done, conn is gone - llist_count(&net->subscr_conns) == 0 ---- -- subscriber sends LU Request, this time with the TMSI -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(TMSI)=50462976 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: is child of Subscr_Conn(50462976) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(50462976) -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(50462976) -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(50462976){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(50462976) -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(50462976) -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(50462976) -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(50462976){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x07060504 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:46071 usage increases to: 3 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x07060504 - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(50462976) -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(50462976){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(50462976) -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(50462976){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(50462976){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -- subscriber has the new TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0xffffffff - vsub->tmsi == 0x07060504 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches, using new TMSI - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(TMSI)=117835012 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_no_authen_tmsi: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_no_authen_imei -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI -DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- We will only do business when the IMEI is known - llist_count(&net->subscr_conns) == 1 -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->imei[0] == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS replies with an Identity Response - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420 -DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -- Subscriber has the IMEI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - strcmp(vsub->imei, "423423423423420") == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_no_authen_imei: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_no_authen_tmsi_imei -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI -DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- We will only do business when the IMEI is known - llist_count(&net->subscr_conns) == 1 -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->imei[0] == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS replies with an Identity Response - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420 -DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x03020100 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -- Subscriber has the IMEI and TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - strcmp(vsub->imei, "423423423423420") == 0 - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_no_authen_tmsi_imei: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_no_authen_imeisv -- Location Update request causes an IMEISV ID request back to the MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803 -- DTAP matches expected message -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 -- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI-SV)=4234234234234275 -DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- Subscriber has the IMEISV from the ID Response -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 - strcmp(vsub->imeisv, "4234234234234275") == 0 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_no_authen_imeisv: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_no_authen_imeisv_imei -- Location Update request causes an IMEISV ID request back to the MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803 -- DTAP matches expected message -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 -- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI-SV)=4234234234234275 -DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- Subscriber has the IMEISV from the ID Response -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 - strcmp(vsub->imeisv, "4234234234234275") == 0 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI -DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- We will only do business when the IMEI is known - llist_count(&net->subscr_conns) == 1 -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->imei[0] == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS replies with an Identity Response - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420 -DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -- Subscriber has the IMEI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - strcmp(vsub->imei, "423423423423420") == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_no_authen_imeisv_imei: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_no_authen_imeisv_tmsi -- Location Update request causes an IMEISV ID request back to the MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803 -- DTAP matches expected message -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 -- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI-SV)=4234234234234275 -DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- Subscriber has the IMEISV from the ID Response -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 - strcmp(vsub->imeisv, "4234234234234275") == 0 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 ---- -- subscriber sends LU Request, this time with the TMSI -- Location Update request causes an IMEISV ID request back to the MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803 -- DTAP matches expected message -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 -- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI-SV)=5234234234234276 -DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=5234234234234276 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - lu_result_sent == 0 -- Subscriber has the IMEISV from the ID Response -DREF VLR subscr MSISDN:46071 usage increases to: 3 - strcmp(vsub->imeisv, "5234234234234276") == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x07060504 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:46071 usage increases to: 3 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x07060504 - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -- subscriber has the new TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0xffffffff - vsub->tmsi == 0x07060504 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches, using new TMSI - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(TMSI)=117835012 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_no_authen_imeisv_tmsi: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_no_authen_imeisv_tmsi_imei -- Location Update request causes an IMEISV ID request back to the MS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803 -- DTAP matches expected message -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 -- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI-SV)=4234234234234275 -DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- Subscriber has the IMEISV from the ID Response -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 - strcmp(vsub->imeisv, "4234234234234275") == 0 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI -DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 -- We will only do business when the IMEI is known - llist_count(&net->subscr_conns) == 1 -DREF VLR subscr MSISDN:46071 usage increases to: 2 - vsub->imei[0] == 0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS replies with an Identity Response - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420 -DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:46071, with TMSI 0x03020100 -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 - lu_result_sent == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -- Subscriber has the IMEISV, IMEI and TMSI -DREF VLR subscr MSISDN:46071 usage increases to: 2 - strcmp(vsub->imeisv, "4234234234234275") == 0 - strcmp(vsub->imei, "423423423423420") == 0 - vsub->tmsi == 0x03020100 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_no_authen_imeisv_tmsi_imei: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.ok b/tests/msc_vlr/msc_vlr_test_no_authen.ok deleted file mode 100644 index a965a70ed..000000000 --- a/tests/msc_vlr/msc_vlr_test_no_authen.ok +++ /dev/null @@ -1 +0,0 @@ -Done diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.c b/tests/msc_vlr/msc_vlr_test_reject_concurrency.c deleted file mode 100644 index 2377c19b3..000000000 --- a/tests/msc_vlr/msc_vlr_test_reject_concurrency.c +++ /dev/null @@ -1,397 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include "msc_vlr_tests.h" - -void test_reject_2nd_conn() -{ - struct gsm_subscriber_connection *conn1; - comment_start(); - - btw("Location Update Request on one connection"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - EXPECT_CONN_COUNT(1); - - btw("Another Location Update Request from the same subscriber on another connection is rejected"); - conn1 = g_conn; - g_conn = NULL; - expect_bssap_clear(); - ms_sends_msg("050802008168000130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d"); - EXPECT_CONN_COUNT(1); - - - BTW("The first connection can still complete its LU"); - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - g_conn = conn1; - lu_result_sent = RES_NONE; - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); - comment_end(); -} - -void _normal_lu_part1() -{ - btw("Location Update Request"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - EXPECT_CONN_COUNT(1); -} - -void _normal_lu_part2() -{ - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - lu_result_sent = RES_NONE; - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); -} - -void _normal_lu() -{ - BTW("Subscriber does a normal LU"); - _normal_lu_part1(); - _normal_lu_part2(); -} - -void _normal_cm_service_req() -{ - BTW("Subscriber does a normal CM Service Request"); - cm_service_result_sent = RES_NONE; - ms_sends_msg("05247803305886089910070000006402"); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - EXPECT_ACCEPTED(true); -} - -void _page() -{ - const char *imsi = "901700000004620"; - struct vlr_subscr *vsub; - - BTW("an SMS is sent, MS is paged"); - paging_expect_imsi(imsi); - paging_sent = false; - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - - send_sms(vsub, vsub, - "Privacy in residential applications is a desirable" - " marketing option."); - - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - vsub = NULL; - VERBOSE_ASSERT(paging_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); -} - -void _paging_resp_part1() -{ - btw("MS replies with Paging Response, we deliver the SMS"); - dtap_expect_tx("09" /* SMS messages */ - "01" /* CP-DATA */ - "58" /* length */ - "01" /* Network to MS */ - "00" /* reference */ - /* originator (gsm411_send_sms() hardcodes this weird nr) */ - "0791" "447758100650" /* 447785016005 */ - "00" /* dest */ - /* SMS TPDU */ - "4c" /* len */ - "00" /* SMS deliver */ - "05806470f1" /* originating address 46071 */ - "00" /* TP-PID */ - "00" /* GSM default alphabet */ - "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/ - "000000" /* H-M-S */ - "00" /* GMT+0 */ - "44" /* data length */ - "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" - "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" - "0c7ac3e9e9b7db05"); - ms_sends_msg("06270703305882089910070000006402"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - - btw("conn is still open to wait for SMS ack dance"); - EXPECT_CONN_COUNT(1); -} - -void _paging_resp_part2(int expect_conn_count, bool expect_clear) -{ - btw("MS replies with CP-ACK for received SMS"); - ms_sends_msg("8904"); - EXPECT_CONN_COUNT(1); - - btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that"); - dtap_expect_tx("0904"); - if (expect_clear) - expect_bssap_clear(); - ms_sends_msg("890106020041020000"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - if (expect_clear) - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("SMS is done"); - EXPECT_CONN_COUNT(expect_conn_count); -} - -void test_reject_lu_during_lu() -{ - comment_start(); - - _normal_lu_part1(); - - BTW("Another Location Update Request from the same subscriber on the same conn is dropped silently"); - ms_sends_msg("050802008168000130089910070000006402"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - EXPECT_CONN_COUNT(1); - - BTW("The first LU can still complete"); - _normal_lu_part2(); - - clear_vlr(); - comment_end(); -} - -void test_reject_cm_during_lu() -{ - comment_start(); - - _normal_lu_part1(); - - BTW("A CM Service Request in the middle of a LU is rejected"); - cm_service_result_sent = RES_NONE; - dtap_expect_tx("052211"); - ms_sends_msg("05247803305886089910070000006402"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - EXPECT_CONN_COUNT(1); - - BTW("The first LU can still complete"); - _normal_lu_part2(); - - clear_vlr(); - comment_end(); -} - -void test_reject_paging_resp_during_lu() -{ - comment_start(); - - _normal_lu_part1(); - - BTW("An erratic Paging Response is dropped silently"); - ms_sends_msg("06270703305882089910070000006402"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - EXPECT_CONN_COUNT(1); - - BTW("The first LU can still complete"); - _normal_lu_part2(); - - clear_vlr(); - comment_end(); -} - -void test_reject_lu_during_cm() -{ - comment_start(); - - _normal_lu(); - _normal_cm_service_req(); - - btw("A LU request on an open conn is dropped silently"); - /* TODO: accept periodic LU on an already open conn? */ - lu_result_sent = RES_NONE; - ms_sends_msg("050802008168000130089910070000006402"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - EXPECT_CONN_COUNT(1); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); - comment_end(); -} - -void test_reject_cm_during_cm() -{ - comment_start(); - - _normal_lu(); - _normal_cm_service_req(); - - btw("A second CM Service Request on the same conn is accepted without another auth dance"); - cm_service_result_sent = RES_NONE; - ms_sends_msg("05247803305886089910070000006402"); - VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(1); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); - comment_end(); -} - -void test_reject_paging_resp_during_cm() -{ - comment_start(); - - _normal_lu(); - _normal_cm_service_req(); - - BTW("An erratic Paging Response on the same conn is dropped silently"); - ms_sends_msg("06270703305882089910070000006402"); - EXPECT_CONN_COUNT(1); - - BTW("The original CM Service Request can conclude"); - btw("a USSD request is serviced"); - dtap_expect_tx_ussd("Your extension is 46071\r"); - expect_bssap_clear(); - ms_sends_msg("0b3b1c15a11302010002013b300b04010f0406aa510c061b017f0100"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("all requests serviced, conn has been released"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); - comment_end(); -} - -void test_reject_paging_resp_during_paging_resp() -{ - comment_start(); - - _normal_lu(); - _page(); - _paging_resp_part1(); - - BTW("MS sends another erratic Paging Response which is dropped silently"); - ms_sends_msg("06270703305882089910070000006402"); - - _paging_resp_part2(0, true); - - clear_vlr(); - comment_end(); -} - -void test_reject_lu_during_paging_resp() -{ - comment_start(); - - _normal_lu(); - _page(); - _paging_resp_part1(); - - BTW("MS sends erratic LU Request, which is dropped silently"); - lu_result_sent = RES_NONE; - ms_sends_msg("050802008168000130089910070000006402"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - EXPECT_CONN_COUNT(1); - - _paging_resp_part2(0, true); - - clear_vlr(); - comment_end(); -} - -void test_accept_cm_during_paging_resp() -{ - comment_start(); - - _normal_lu(); - _page(); - _paging_resp_part1(); - - BTW("CM Service Request during open connection is accepted"); - cm_service_result_sent = RES_NONE; - ms_sends_msg("05247803305886089910070000006402"); - VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(1); - VERBOSE_ASSERT(g_conn->received_cm_service_request, == true, "%d"); - - _paging_resp_part2(1, false); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); - comment_end(); -} - -msc_vlr_test_func_t msc_vlr_tests[] = { - test_reject_2nd_conn, - test_reject_lu_during_lu, - test_reject_cm_during_lu, - test_reject_paging_resp_during_lu, - test_reject_lu_during_cm, - test_reject_cm_during_cm, - test_reject_paging_resp_during_cm, - test_reject_lu_during_paging_resp, - test_accept_cm_during_paging_resp, - test_reject_paging_resp_during_paging_resp, - NULL -}; diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err deleted file mode 100644 index 00945cb89..000000000 --- a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err +++ /dev/null @@ -1,1817 +0,0 @@ -===== test_reject_2nd_conn -- Location Update Request on one connection - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 -- Another Location Update Request from the same subscriber on another connection is rejected - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: A Location Updating process is already pending for this subscriber. Aborting. -- sending LU Reject for unknown, cause 22 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=unknown, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DRR 901700000004620: internal error during Location Updating attempt -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - lu_result_sent == 2 - llist_count(&net->subscr_conns) == 1 ---- -- The first connection can still complete its LU -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_reject_2nd_conn: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_reject_lu_during_lu -- Location Update Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 ---- -- Another Location Update Request from the same subscriber on the same conn is dropped silently - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DMM 901700000004620: Error: connection already in use -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 ---- -- The first LU can still complete -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_reject_lu_during_lu: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_reject_cm_during_lu -- Location Update Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 ---- -- A CM Service Request in the middle of a LU is rejected - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DMM IMSI:901700000004620: connection already in use -DMM -> CM SERVICE Reject cause: 17 -DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_CM_SERV_REJ: 052211 -- DTAP matches expected message -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - cm_service_result_sent == 0 - llist_count(&net->subscr_conns) == 1 ---- -- The first LU can still complete -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_reject_cm_during_lu: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_reject_paging_resp_during_lu -- Location Update Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 ---- -- An erratic Paging Response is dropped silently - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP -DREF IMSI:901700000004620: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000004620 -DMM 901700000004620: Error: connection already in use -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 ---- -- The first LU can still complete -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_reject_paging_resp_during_lu: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_reject_lu_during_cm ---- -- Subscriber does a normal LU -- Location Update Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- Subscriber does a normal CM Service Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -- sending CM Service Accept for MSISDN:46071 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 1 -msc_subscr_conn_is_accepted() == true -- A LU request on an open conn is dropped silently - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DMM 901700000004620: Error: connection already in use -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM IMSI DETACH for MSISDN:46071 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_ERROR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=0): already dispatching release, ignore. -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_reject_lu_during_cm: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_reject_cm_during_cm ---- -- Subscriber does a normal LU -- Location Update Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- Subscriber does a normal CM Service Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -- sending CM Service Accept for MSISDN:46071 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 1 -msc_subscr_conn_is_accepted() == true -- A second CM Service Request on the same conn is accepted without another auth dance - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DMM MSISDN:46071: re-using already accepted connection -- sending CM Service Accept for MSISDN:46071 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 1 - llist_count(&net->subscr_conns) == 1 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM IMSI DETACH for MSISDN:46071 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_ERROR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=0): already dispatching release, ignore. -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_reject_cm_during_cm: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_reject_paging_resp_during_cm ---- -- Subscriber does a normal LU -- Location Update Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- Subscriber does a normal CM Service Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -- sending CM Service Accept for MSISDN:46071 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - cm_service_result_sent == 1 -msc_subscr_conn_is_accepted() == true ---- -- An erratic Paging Response on the same conn is dropped silently - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000004620 -DMM 901700000004620: Error: connection already in use -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - llist_count(&net->subscr_conns) == 1 ---- -- The original CM Service Request can conclude -- a USSD request is serviced - expecting USSD: - Your extension is 46071 - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:46071: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:46071: MSISDN = 46071 -DMSC msc_tx 43 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d -- DTAP matches expected message -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - bssap_clear_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_reject_paging_resp_during_cm: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_reject_lu_during_paging_resp ---- -- Subscriber does a normal LU -- Location Update Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:46071 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM Subscriber MSISDN:46071 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 0 - strcmp(paging_expecting_imsi, imsi) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- MS replies with Paging Response, we deliver the SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 4 -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:46071 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:46071 usage increases to: 6 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 5 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - dtap_tx_confirmed == 1 - paging_stopped == 1 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 ---- -- MS sends erratic LU Request, which is dropped silently - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DMM 901700000004620: Error: connection already in use -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF MSISDN:46071: MSC conn use - 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_reject_lu_during_paging_resp: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_accept_cm_during_paging_resp ---- -- Subscriber does a normal LU -- Location Update Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:46071 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM Subscriber MSISDN:46071 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 0 - strcmp(paging_expecting_imsi, imsi) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- MS replies with Paging Response, we deliver the SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 4 -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:46071 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:46071 usage increases to: 6 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 5 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - dtap_tx_confirmed == 1 - paging_stopped == 1 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 ---- -- CM Service Request during open connection is accepted - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DMM MSISDN:46071: re-using already accepted connection -- sending CM Service Accept for MSISDN:46071 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 2 - cm_service_result_sent == 1 - llist_count(&net->subscr_conns) == 1 - g_conn->received_cm_service_request == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF MSISDN:46071: MSC conn use - 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:46071: MSC conn use - 1 == 1 - dtap_tx_confirmed == 1 -- SMS is done - llist_count(&net->subscr_conns) == 1 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND -DREF MSISDN:46071: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM IMSI DETACH for MSISDN:46071 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_ERROR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=0): already dispatching release, ignore. -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_accept_cm_during_paging_resp: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_reject_paging_resp_during_paging_resp ---- -- Subscriber does a normal LU -- Location Update Request - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 - llist_count(&net->subscr_conns) == 1 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:46071 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DMM Subscriber MSISDN:46071 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 0 - strcmp(paging_expecting_imsi, imsi) == 0 -DREF VLR subscr MSISDN:46071 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- MS replies with Paging Response, we deliver the SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:46071 usage increases to: 4 -DREF VLR subscr MSISDN:46071 usage increases to: 5 -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:46071 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:46071 usage increases to: 6 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 5 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF VLR subscr MSISDN:46071 usage decreases to: 4 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - dtap_tx_confirmed == 1 - paging_stopped == 1 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 ---- -- MS sends another erratic Paging Response which is dropped silently - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000004620 -DMM 901700000004620: Error: connection already in use -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:46071: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:46071: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:46071 usage decreases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DREF MSISDN:46071: MSC conn use - 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_reject_paging_resp_during_paging_resp: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.ok b/tests/msc_vlr/msc_vlr_test_reject_concurrency.ok deleted file mode 100644 index a965a70ed..000000000 --- a/tests/msc_vlr/msc_vlr_test_reject_concurrency.ok +++ /dev/null @@ -1 +0,0 @@ -Done diff --git a/tests/msc_vlr/msc_vlr_test_rest.c b/tests/msc_vlr/msc_vlr_test_rest.c deleted file mode 100644 index c5f7fcfb9..000000000 --- a/tests/msc_vlr/msc_vlr_test_rest.c +++ /dev/null @@ -1,201 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include "msc_vlr_tests.h" - -void test_early_stage() -{ - comment_start(); - - btw("NULL conn"); - EXPECT_ACCEPTED(false); - - btw("freshly allocated conn"); - g_conn = msc_subscr_con_allocate(net); - g_conn->bts = the_bts; - EXPECT_ACCEPTED(false); - - btw("conn_fsm present, in state NEW"); - OSMO_ASSERT(msc_create_conn_fsm(g_conn, "test") == 0); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->conn_fsm->state == SUBSCR_CONN_S_NEW); - EXPECT_ACCEPTED(false); - - thwart_rx_non_initial_requests(); - - btw("fake: acceptance"); - g_conn->vsub = vlr_subscr_alloc(net->vlr); - g_conn->via_ran = RAN_GERAN_A; - OSMO_ASSERT(g_conn->vsub); - /* mark as silent call so it sticks around */ - g_conn->silent_call = 1; - osmo_fsm_inst_state_chg(g_conn->conn_fsm, SUBSCR_CONN_S_ACCEPTED, 0, 0); - EXPECT_CONN_COUNT(1); - EXPECT_ACCEPTED(true); - - btw("CLOSE event marks conn_fsm as released and frees the conn"); - expect_bssap_clear(); - osmo_fsm_inst_dispatch(g_conn->conn_fsm, SUBSCR_CONN_E_CN_CLOSE, NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); - comment_end(); -} - -void test_cm_service_without_lu() -{ - comment_start(); - - btw("CM Service Request without a prior Location Updating"); - expect_bssap_clear(); - ms_sends_msg("05247803305886089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("conn was released"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); - comment_end(); -} - -void test_two_lu() -{ - comment_start(); - - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - - thwart_rx_non_initial_requests(); - - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - - BTW("verify that the MS can send another LU request"); - btw("Location Update request causes a GSUP LU request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("050802008168000130089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - - thwart_rx_non_initial_requests(); - - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - - BTW("subscriber detaches"); - expect_bssap_clear(); - ms_sends_msg("050130089910070000006402"); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -void test_lu_unknown_tmsi() -{ - comment_start(); - - btw("Location Update request with unknown TMSI sends ID Request for IMSI"); - lu_result_sent = RES_NONE; - dtap_expect_tx("051801"); - ms_sends_msg("050802008168000130" "05f4" "23422342"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("MS tells us the IMSI, causes a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0"); - ms_sends_msg("0559089910070000006402"); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000004026f00804036470f1", - "12010809710000004026f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("having received subscriber data does not mean acceptance"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - expect_bssap_clear(); - gsup_rx("06010809710000004026f0", NULL); - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); - - btw("LU was successful, and the conn has already been closed"); - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - EXPECT_CONN_COUNT(0); - clear_vlr(); - comment_end(); -} - -msc_vlr_test_func_t msc_vlr_tests[] = { - test_early_stage, - test_cm_service_without_lu, - test_two_lu, - test_lu_unknown_tmsi, - NULL -}; diff --git a/tests/msc_vlr/msc_vlr_test_rest.err b/tests/msc_vlr/msc_vlr_test_rest.err deleted file mode 100644 index 1b5f3406d..000000000 --- a/tests/msc_vlr/msc_vlr_test_rest.err +++ /dev/null @@ -1,493 +0,0 @@ -===== test_early_stage -- NULL conn -msc_subscr_conn_is_accepted() == false -- freshly allocated conn -msc_subscr_conn_is_accepted() == false -- conn_fsm present, in state NEW -DREF unknown: MSC conn use + 1 == 1 -DMM Subscr_Conn(test){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(test){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(test){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr unknown: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr unknown: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr unknown: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr unknown: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- fake: acceptance -DREF VLR subscr unknown usage increases to: 1 -DMM Subscr_Conn(test){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED - llist_count(&net->subscr_conns) == 1 -msc_subscr_conn_is_accepted() == true -- CLOSE event marks conn_fsm as released and frees the conn -DMM Subscr_Conn(test){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(test){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(test){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DMM msc_subscr_conn_close(vsub=unknown, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL subscr unknown: Freeing subscriber connection -DREF VLR subscr unknown usage decreases to: 0 -DREF freeing VLR subscr unknown -DMM Subscr_Conn(test){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(test){SUBSCR_CONN_S_RELEASED}: Deallocated - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_early_stage: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_cm_service_without_lu -- CM Service Request without a prior Location Updating - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(VLR_PR_ARQ_RES_UNIDENT_SUBSCR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_UNIDENT_SUBSCR -- sending CM Service Reject for unknown, result VLR_PR_ARQ_RES_UNIDENT_SUBSCR -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Close event, cause 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=unknown, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 -- conn was released - llist_count(&net->subscr_conns) == 0 -===== test_cm_service_without_lu: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_two_lu -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR New subscr, IMSI: 901700000004620 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DREF VLR subscr IMSI:901700000004620 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- verify that the MS can send another LU request -- Location Update request causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM MSISDN:46071: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:46071: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000004620) -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000004620) -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000004620) -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000004620){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DMM IMSI DETACH for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -DREF VLR subscr MSISDN:46071 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:46071 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_two_lu: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_lu_unknown_tmsi -- Location Update request with unknown TMSI sends ID Request for IMSI - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(TMSI)=591536962 type=IMSI ATTACH -DMM LU/new-LAC: 1/0 -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_IDLE}: is child of Subscr_Conn(591536962) -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth) -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR New subscr, TMSI: 0x23422342 -DREF VLR subscr TMSI:0x23422342 usage increases to: 2 -DREF VLR subscr TMSI:0x23422342 usage decreases to: 1 -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_IDLE}: vlr_loc_upd_want_imsi() -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMSI -DMSC msc_tx 3 bytes to TMSI:0x23422342 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051801 -- DTAP matches expected message -DMM TMSI:0x23422342: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF TMSI:0x23422342: MSC conn use - 1 == 1 - lu_result_sent == 0 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr TMSI:0x23422342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr TMSI:0x23422342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr TMSI:0x23422342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr TMSI:0x23422342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS tells us the IMSI, causes a GSUP LU request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP -DREF TMSI:0x23422342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19) -DMM IDENTITY RESPONSE: MI(IMSI)=901700000004620 -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_IMSI}: Received Event VLR_ULA_E_ID_IMSI -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_IMSI}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(591536962) -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0 -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000004620: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000004620: MSC conn use - 1 == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1 -DVLR GSUP rx 17: 10010809710000004026f00804036470f1 -DREF VLR subscr IMSI:901700000004620 usage increases to: 2 -DVLR IMSI:901700000004620 has MSISDN:46071 -DVLR GSUP tx: 12010809710000004026f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- having received subscriber data does not mean acceptance -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0 -DVLR GSUP rx 11: 06010809710000004026f0 -DREF VLR subscr MSISDN:46071 usage increases to: 2 -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(591536962) -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(591536962){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(591536962) -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(591536962){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(591536962){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(591536962) -DVLR sub_pres_vlr_fsm(591536962){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(591536962){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(591536962){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(591536962){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(591536962) -DVLR sub_pres_vlr_fsm(591536962){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(591536962){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -- sending LU Accept for MSISDN:46071 -DREF VLR subscr MSISDN:46071 usage increases to: 3 -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(591536962) -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(591536962){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(591536962) -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(591536962){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:46071, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:46071: MSC conn use - 1 == 0 -DRLL subscr MSISDN:46071: Freeing subscriber connection -DREF VLR subscr MSISDN:46071 usage decreases to: 2 -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(591536962){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF VLR subscr MSISDN:46071 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - lu_result_sent == 1 - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:46071 -===== test_lu_unknown_tmsi: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - diff --git a/tests/msc_vlr/msc_vlr_test_rest.ok b/tests/msc_vlr/msc_vlr_test_rest.ok deleted file mode 100644 index a965a70ed..000000000 --- a/tests/msc_vlr/msc_vlr_test_rest.ok +++ /dev/null @@ -1 +0,0 @@ -Done diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.c b/tests/msc_vlr/msc_vlr_test_umts_authen.c deleted file mode 100644 index 1175bf875..000000000 --- a/tests/msc_vlr/msc_vlr_test_umts_authen.c +++ /dev/null @@ -1,581 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include "msc_vlr_tests.h" - -#define ASSERT_RELEASE_CLEAR(via_ran) \ - switch (via_ran) { \ - case RAN_GERAN_A: \ - VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); \ - break; \ - case RAN_UTRAN_IU: \ - VERBOSE_ASSERT(iu_release_sent, == true, "%d"); \ - break; \ - default: \ - OSMO_ASSERT(false); \ - break; \ - } - -void _test_umts_authen(enum ran_type via_ran) -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000010650"; - const char *sms = - "09" /* SMS messages */ - "01" /* CP-DATA */ - "58" /* length */ - "01" /* Network to MS */ - "00" /* reference */ - /* originator (gsm411_send_sms() hardcodes this weird nr) */ - "0791" "447758100650" /* 447785016005 */ - "00" /* dest */ - /* SMS TPDU */ - "4c" /* len */ - "00" /* SMS deliver */ - "05802443f2" /* originating address 42342 */ - "00" /* TP-PID */ - "00" /* GSM default alphabet */ - "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/ - "000000" /* H-M-S */ - "00" /* GMT+0 */ - "44" /* data length */ - "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" - "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" - "0c7ac3e9e9b7db05"; - - net->authentication_required = true; - net->vlr->cfg.assign_tmsi = true; - rx_from_ran = via_ran; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0"); - ms_sends_msg("0508" /* MM LU */ - "7" /* ciph key seq: no key available */ - "0" /* LU type: normal */ - "ffffff" "0000" /* LAI, LAC */ - "57" /* classmark 1: R99, early classmark, no power lvl */ - "089910070000106005" /* IMSI */ - "3303575886" /* classmark 2 */ - ); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - /* based on auc_3g: - * K = 'EB215756028D60E3275E613320AEC880', - * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308' - * SQN = 0 - */ - auth_request_sent = false; - auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d"; - auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919"; - gsup_rx("0a" - /* imsi */ - "0108" "09710000000156f0" - /* 5 auth vectors... */ - /* TL TL rand */ - "0362" "2010" "39fa2f4e3d523d8619a73b4f65c3e14d" - /* TL sres TL kc */ - "2104" "9b36efdf" "2208" "059a4f668f6fbe39" - /* TL 3G IK */ - "2310" "27497388b6cb044648f396aa155b95ef" - /* TL 3G CK */ - "2410" "f64735036e5871319c679f4742a75ea1" - /* TL AUTN */ - "2510" "8704f5ba55f30000d2ee44b22c8ea919" - /* TL RES */ - "2708" "e229c19e791f2e41" - /* TL TL rand */ - "0362" "2010" "c187a53a5e6b9d573cac7c74451fd46d" - "2104" "85aa3130" "2208" "d3d50a000bf04f6e" - "2310" "1159ec926a50e98c034a6b7d7c9f418d" - "2410" "df3a03d9ca5335641efc8e36d76cd20b" - "2510" "1843a645b98d00005b2d666af46c45d9" - "2708" "7db47cf7f81e4dc7" - "0362" "2010" "efa9c29a9742148d5c9070348716e1bb" - "2104" "69d5f9fb" "2208" "3df176f0c29f1a3d" - "2310" "eb50e770ddcc3060101d2f43b6c2b884" - "2410" "76542abce5ff9345b0e8947f4c6e019c" - "2510" "f9375e6d41e1000096e7fe4ff1c27e39" - "2708" "706f996719ba609c" - "0362" "2010" "f023d5a3b24726e0631b64b3840f8253" - "2104" "d570c03f" "2208" "ec011be8919883d6" - "2310" "c4e58af4ba43f3bcd904e16984f086d7" - "2410" "0593f65e752e5cb7f473862bda05aa0a" - "2510" "541ff1f077270000c5ea00d658bc7e9a" - "2708" "3fd26072eaa2a04d" - "0362" "2010" "2f8f90c780d6a9c0c53da7ac57b6707e" - "2104" "b072446f220823f39f9f425ad6e6" - "2310" "65af0527fda95b0dc5ae4aa515cdf32f" - "2410" "537c3b35a3b13b08d08eeb28098f45cc" - "2510" "4bf4e564f75300009bc796706bc65744" - "2708" "0edb0eadbea94ac2", - NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - if (via_ran == RAN_GERAN_A) { - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0"); - ms_sends_msg("0554" "e229c19e" "2104" "791f2e41"); - VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - } else { - /* On UTRAN */ - btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl"); - cipher_mode_cmd_sent = false; - ms_sends_msg("0554" "e229c19e" "2104" "791f2e41"); - VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0"); - ms_sends_security_mode_complete(); - VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - } - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000000156f00804032443f2", - "12010809710000000156f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - gsup_rx("06010809710000000156f0", NULL); - - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_release_clear(via_ran); - ms_sends_msg("055b"); - ASSERT_RELEASE_CLEAR(via_ran); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector"); - auth_request_sent = false; - auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d"; - auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9"; - cm_service_result_sent = RES_NONE; - ms_sends_msg("052478" - "03575886" /* classmark 2 */ - "089910070000106005" /* IMSI */); - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->conn_fsm); - OSMO_ASSERT(g_conn->vsub); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - if (via_ran == RAN_GERAN_A) { - btw("MS sends Authen Response, VLR accepts with a CM Service Accept"); - gsup_expect_tx(NULL); - ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */ - VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - } else { - /* On UTRAN */ - btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl"); - cipher_mode_cmd_sent = false; - ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */ - VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d"); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - - btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept"); - ms_sends_security_mode_complete(); - VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); - } - - btw("a USSD request is serviced"); - dtap_expect_tx_ussd("Your extension is 42342\r"); - expect_release_clear(via_ran); - ms_sends_msg("0b3b1c15a11302010002013b300b04010f0406aa510c061b017f0100"); - OSMO_ASSERT(dtap_tx_confirmed); - ASSERT_RELEASE_CLEAR(via_ran); - - btw("all requests serviced, conn has been released"); - EXPECT_CONN_COUNT(0); - - BTW("an SMS is sent, MS is paged"); - paging_expect_imsi(imsi); - paging_sent = false; - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - - send_sms(vsub, vsub, - "Privacy in residential applications is a desirable" - " marketing option."); - - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - vsub = NULL; - VERBOSE_ASSERT(paging_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); - - btw("the subscriber and its pending request should remain"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d"); - vlr_subscr_put(vsub); - - btw("MS replies with Paging Response, and VLR sends Auth Request with third key"); - auth_request_sent = false; - auth_request_expect_rand = "efa9c29a9742148d5c9070348716e1bb"; - auth_request_expect_autn = "f9375e6d41e1000096e7fe4ff1c27e39"; - ms_sends_msg("062707" - "03575886" /* classmark 2 */ - "089910070000106005" /* IMSI */); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - - btw("needs auth, not yet accepted"); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - if (via_ran == RAN_GERAN_A) { - btw("MS sends Authen Response, VLR accepts and sends pending SMS"); - dtap_expect_tx(sms); - ms_sends_msg("0554" "706f9967" "2104" "19ba609c"); /* 3nd vector's res, s.a. */ - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - } else { - /* On UTRAN */ - btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl"); - cipher_mode_cmd_sent = false; - ms_sends_msg("0554" "706f9967" "2104" "19ba609c"); /* 3nd vector's res, s.a. */ - VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d"); - VERBOSE_ASSERT(paging_stopped, == false, "%d"); - - btw("MS sends SecurityModeControl acceptance, VLR accepts and sends SMS"); - dtap_expect_tx(sms); - ms_sends_security_mode_complete(); - VERBOSE_ASSERT(paging_stopped, == true, "%d"); - } - - btw("SMS was delivered, no requests pending for subscr"); - vsub = vlr_subscr_find_by_imsi(net->vlr, imsi); - OSMO_ASSERT(vsub); - VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d"); - vlr_subscr_put(vsub); - - btw("conn is still open to wait for SMS ack dance"); - EXPECT_CONN_COUNT(1); - - btw("MS replies with CP-ACK for received SMS"); - ms_sends_msg("8904"); - EXPECT_CONN_COUNT(1); - - btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that"); - dtap_expect_tx("0904"); - expect_release_clear(via_ran); - ms_sends_msg("890106020041020000"); - VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - ASSERT_RELEASE_CLEAR(via_ran); - - btw("SMS is done, conn is gone"); - EXPECT_CONN_COUNT(0); - - BTW("subscriber detaches"); - expect_release_clear(via_ran); - ms_sends_msg("050130" - "089910070000106005" /* IMSI */); - ASSERT_RELEASE_CLEAR(via_ran); - - EXPECT_CONN_COUNT(0); - clear_vlr(); -} - -void test_umts_authen_geran() -{ - comment_start(); - _test_umts_authen(RAN_GERAN_A); - comment_end(); -} - -void test_umts_authen_utran() -{ - comment_start(); - _test_umts_authen(RAN_UTRAN_IU); - comment_end(); -} - -#define RECALC_AUTS 0 - -#if RECALC_AUTS -typedef uint8_t u8; -extern int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, - u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar); -extern int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, - const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s); -#endif - -void _test_umts_authen_resync(enum ran_type via_ran) -{ - struct vlr_subscr *vsub; - const char *imsi = "901700000010650"; - - net->authentication_required = true; - net->vlr->cfg.assign_tmsi = true; - rx_from_ran = via_ran; - - btw("Location Update request causes a GSUP Send Auth Info request to HLR"); - lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0"); - ms_sends_msg("0508" /* MM LU */ - "7" /* ciph key seq: no key available */ - "0" /* LU type: normal */ - "ffffff" "0000" /* LAI, LAC */ - "57" /* classmark 1: R99, early classmark, no power lvl */ - "089910070000106005" /* IMSI */ - "3303575886" /* classmark 2 */ - ); - OSMO_ASSERT(gsup_tx_confirmed); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS"); - /* based on auc_3g: - * K = 'EB215756028D60E3275E613320AEC880', - * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308' - * SQN = 0 - */ - auth_request_sent = false; - auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d"; - auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919"; - gsup_rx("0a" - /* imsi */ - "0108" "09710000000156f0" - /* auth vectors... */ - /* TL TL rand */ - "0362" "2010" "39fa2f4e3d523d8619a73b4f65c3e14d" - /* TL sres TL kc */ - "2104" "9b36efdf" "2208" "059a4f668f6fbe39" - /* TL 3G IK */ - "2310" "27497388b6cb044648f396aa155b95ef" - /* TL 3G CK */ - "2410" "f64735036e5871319c679f4742a75ea1" - /* TL AUTN */ - "2510" "8704f5ba55f30000d2ee44b22c8ea919" - /* TL RES */ - "2708" "e229c19e791f2e41" - ,NULL); - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - /* The AUTN sent was 8704f5ba55f30000d2ee44b22c8ea919 - * (see expected error output) - * with the first 6 bytes being SQN ^ AK. - * K = EB215756028D60E3275E613320AEC880 - * OPC = FB2A3D1B360F599ABAB99DB8669F8308 - * RAND = 39fa2f4e3d523d8619a73b4f65c3e14d - * --milenage-f5--> - * AK = 8704f5ba55f3 - * - * The first six bytes are 8704f5ba55f3, - * and 8704f5ba55f3 ^ AK = 0. - * --> SQN = 0. - * - * Say the USIM doesn't like that, let's say it is at SQN 23. - * SQN_MS = 000000000017 - * - * AUTS = Conc(SQN_MS) || MAC-S - * Conc(SQN_MS) = SQN_MS ⊕ f5*[K](RAND) - * MAC-S = f1*[K] (SQN MS || RAND || AMF) - * - * f5*--> Conc(SQN_MS) = 000000000017 ^ 979498b1f73a - * = 979498b1f72d - * AMF = 0000 (TS 33.102 v7.0.0, 6.3.3) - * - * MAC-S = f1*[K] (000000000017 || 39fa2f4e3d523d8619a73b4f65c3e14d || 0000) - * = 3e28c59fa2e72f9c - * - * AUTS = 979498b1f72d || 3e28c59fa2e72f9c - */ -#if RECALC_AUTS - uint8_t ak[6]; - uint8_t akstar[6]; - uint8_t opc[16]; - uint8_t k[16]; - uint8_t rand[16]; - osmo_hexparse("EB215756028D60E3275E613320AEC880", k, sizeof(k)); - osmo_hexparse("FB2A3D1B360F599ABAB99DB8669F8308", opc, sizeof(opc)); - osmo_hexparse("39fa2f4e3d523d8619a73b4f65c3e14d", rand, sizeof(rand)); - milenage_f2345(opc, k, rand, NULL, NULL, NULL, ak, akstar); - btw("ak = %s", osmo_hexdump_nospc(ak, sizeof(ak))); - btw("akstar = %s", osmo_hexdump_nospc(akstar, sizeof(akstar))); - - uint8_t sqn_ms[6] = { 0, 0, 0, 0, 0, 23 }; - uint8_t amf[2] = { 0 }; - uint8_t mac_s[8]; - milenage_f1(opc, k, rand, sqn_ms, amf, NULL, mac_s); - btw("mac_s = %s", osmo_hexdump_nospc(mac_s, sizeof(mac_s))); - /* verify valid AUTS resulting in SQN 23 with: - osmo-auc-gen -3 -a milenage -k EB215756028D60E3275E613320AEC880 \ - -o FB2A3D1B360F599ABAB99DB8669F8308 \ - -r 39fa2f4e3d523d8619a73b4f65c3e14d \ - -A 979498b1f72d3e28c59fa2e72f9c - */ -#endif - - btw("MS sends Authen Failure with Resync cause, VLR sends GSUP to HLR to resync"); - auth_request_sent = false; - gsup_expect_tx("08" /* OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST */ - "0108" "09710000000156f0" /* IMSI */ - "260e" "979498b1f72d3e28c59fa2e72f9c" /* AUTS */ - "2010" "39fa2f4e3d523d8619a73b4f65c3e14d" /* RAND */); - ms_sends_msg("051c" /* 05 = MM; 1c = Auth Failure */ - "15" /* cause = Synch Failure */ - "220e" "979498b1f72d3e28c59fa2e72f9c" /* AUTS */); - VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(auth_request_sent, == false, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR replies with new tuples"); - auth_request_sent = false; - auth_request_expect_rand = "0f1feb1623e1bf626334e37ec448ac18"; - auth_request_expect_autn = "02a83f62e9470000660d51afc75f169d"; - gsup_rx("0a" - /* imsi */ - "0108" "09710000000156f0" - /* 1 auth vector */ - /* TL TL rand */ - "0362" "2010" "0f1feb1623e1bf626334e37ec448ac18" - /* TL sres TL kc */ - "2104" "efde99da" "2208" "14778c855c523730" - /* TL 3G IK */ - "2310" "8a90c769b7272f3bb7a1c1fbb1ea9349" - /* TL 3G CK */ - "2410" "43ffc1cf8c89a7fd6ab94bd8d6162cbf" - /* TL AUTN */ - "2510" "02a83f62e9470000660d51afc75f169d" - /* TL RES */ - "2708" "1df5f0b4f22b696e" - /* TL TL rand */ - "0362" "2010" "ac21d34937b4e1142a2c757af2949319" - /* TL sres TL kc */ - "2104" "7818bfdc" "2208" "d175571f41f314a4" - /* TL 3G IK */ - "2310" "ff8edbceb6dd24799c77c3b9a6790c10" - /* TL 3G CK */ - "2410" "157c39022ca9d885a7f0766a7dfee448" - /* TL AUTN */ - "2510" "8a43b91898e500002cf354c6f5d1f8c3" - /* TL RES */ - "2708" "f748a7078f5018db" - ,NULL); - - VERBOSE_ASSERT(auth_request_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - if (via_ran == RAN_GERAN_A) { - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0"); - ms_sends_msg("0554" "1df5f0b4" "2104" "f22b696e"); - VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - } else { - /* On UTRAN */ - btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl"); - cipher_mode_cmd_sent = false; - ms_sends_msg("0554" "1df5f0b4" "2104" "f22b696e"); - VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0"); - ms_sends_security_mode_complete(); - VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - } - - btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); - gsup_rx("10010809710000000156f00804032443f2", - "12010809710000000156f0"); - VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - - btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); - gsup_rx("06010809710000000156f0", NULL); - - VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); - - btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl"); - EXPECT_CONN_COUNT(1); - EXPECT_ACCEPTED(false); - thwart_rx_non_initial_requests(); - - btw("even though the TMSI is not acked, we can already find the subscr with it"); - vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100); - VERBOSE_ASSERT(vsub != NULL, == true, "%d"); - VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d"); - VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x"); - VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x"); - vlr_subscr_put(vsub); - - btw("MS sends TMSI Realloc Complete"); - expect_release_clear(via_ran); - ms_sends_msg("055b"); - ASSERT_RELEASE_CLEAR(via_ran); - - btw("LU was successful, and the conn has already been closed"); - EXPECT_CONN_COUNT(0); - - clear_vlr(); -} - -void test_umts_authen_resync_geran() -{ - comment_start(); - _test_umts_authen_resync(RAN_GERAN_A); - comment_end(); -} - -void test_umts_authen_resync_utran() -{ - comment_start(); - _test_umts_authen_resync(RAN_UTRAN_IU); - comment_end(); -} - -msc_vlr_test_func_t msc_vlr_tests[] = { - test_umts_authen_geran, - test_umts_authen_utran, - test_umts_authen_resync_geran, - test_umts_authen_resync_utran, - NULL -}; diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.err b/tests/msc_vlr/msc_vlr_test_umts_authen.err deleted file mode 100644 index 57f5e8e85..000000000 --- a/tests/msc_vlr/msc_vlr_test_umts_authen.err +++ /dev/null @@ -1,1381 +0,0 @@ -===== test_umts_authen_geran -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL -DMM LU/new-LAC: 0/0 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 -DVLR New subscr, IMSI: 901700000010650 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2 -DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000010650) Received 5 auth tuples -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending UMTS Auth Request for IMSI:901700000010650: tuple use_count=1 key_seq=0 auth_types=0x3 and... -- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d -- ...autn=8704f5ba55f30000d2ee44b22c8ea919 -- ...expecting res=e229c19e791f2e41 -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000010650: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000010650: MM R99 AUTHENTICATION RESPONSE (res = e229c19e791f2e41) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000010650) received res: e2 29 c1 9e 79 1f 2e 41 -DVLR SUBSCR(IMSI:901700000010650) AUTH established UMTS security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0 -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - gsup_tx_confirmed == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f2 -DVLR GSUP rx 17: 10010809710000000156f00804032443f2 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR IMSI:901700000010650 has MSISDN:42342 -DVLR GSUP tx: 12010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f0 -DVLR GSUP rx 11: 06010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:42342, with TMSI 0x03020100 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 1 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:42342 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 ---- -- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DREF VLR subscr MSISDN:42342 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- sending UMTS Auth Request for MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and... -- ...rand=c187a53a5e6b9d573cac7c74451fd46d -- ...autn=1843a645b98d00005b2d666af46c45d9 -- ...expecting res=7db47cf7f81e4dc7 -DREF VLR subscr MSISDN:42342 usage decreases to: 2 -DMM MSISDN:42342: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:42342: MSC conn use - 1 == 1 - cm_service_result_sent == 0 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts with a CM Service Accept - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:42342: MM R99 AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:42342) received res: 7d b4 7c f7 f8 1e 4d c7 -DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -- sending CM Service Accept for MSISDN:42342 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request -DREF MSISDN:42342: MSC conn use - 1 == 1 - cm_service_result_sent == 1 -- a USSD request is serviced - expecting USSD: - Your extension is 42342 - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:42342: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:42342: MSISDN = 42342 -DMSC msc_tx 43 bytes to MSISDN:42342 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d273104d36a3c91a0d -- DTAP matches expected message -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - bssap_clear_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:42342 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:42342 usage increases to: 3 -DMM Subscriber MSISDN:42342 not paged yet, start paging. - RAN_GERAN_A sends out paging request to IMSI 901700000010650, TMSI 0x03020100, LAC 0 - strcmp(paging_expecting_imsi, imsi) == 0 -DREF VLR subscr MSISDN:42342 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:42342 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- the subscriber and its pending request should remain -DREF VLR subscr MSISDN:42342 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:42342 usage decreases to: 3 -- MS replies with Paging Response, and VLR sends Auth Request with third key - MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000010650 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:42342 usage increases to: 4 -DREF VLR subscr MSISDN:42342 usage increases to: 5 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- sending UMTS Auth Request for MSISDN:42342: tuple use_count=1 key_seq=2 auth_types=0x3 and... -- ...rand=efa9c29a9742148d5c9070348716e1bb -- ...autn=f9375e6d41e1000096e7fe4ff1c27e39 -- ...expecting res=706f996719ba609c -DREF VLR subscr MSISDN:42342 usage decreases to: 4 -DMM MSISDN:42342: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:42342: MSC conn use - 1 == 1 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and sends pending SMS - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:42342: MM R99 AUTHENTICATION RESPONSE (res = 706f996719ba609c) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:42342) received res: 70 6f 99 67 19 ba 60 9c -DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:42342 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:42342 usage increases to: 5 -DREF MSISDN:42342: MSC conn use + 1 == 3 -DMSC msc_tx 91 bytes to MSISDN:42342 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:42342 usage decreases to: 4 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:42342: MSC conn use - 1 == 2 - dtap_tx_confirmed == 1 - paging_stopped == 1 -- SMS was delivered, no requests pending for subscr -DREF VLR subscr MSISDN:42342 usage increases to: 5 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:42342 usage decreases to: 4 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:42342: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:42342: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_GERAN_A-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:42342: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_GERAN_A -- DTAP --RAN_GERAN_A--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:42342 usage decreases to: 3 -DREF VLR subscr MSISDN:42342 usage decreases to: 2 -DREF MSISDN:42342: MSC conn use - 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - dtap_tx_confirmed == 1 - bssap_clear_sent == 1 -- SMS is done, conn is gone - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DMM IMSI DETACH for MSISDN:42342 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -DREF VLR subscr MSISDN:42342 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:42342 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - bssap_clear_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_umts_authen_geran: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_umts_authen_utran -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL -DMM LU/new-LAC: 0/0 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 -DVLR New subscr, IMSI: 901700000010650 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2 -DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000010650) Received 5 auth tuples -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending UMTS Auth Request for IMSI:901700000010650: tuple use_count=1 key_seq=0 auth_types=0x3 and... -- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d -- ...autn=8704f5ba55f30000d2ee44b22c8ea919 -- ...expecting res=e229c19e791f2e41 -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends SecurityModeControl - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000010650: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000010650: MM R99 AUTHENTICATION RESPONSE (res = e229c19e791f2e41) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000010650) received res: e2 29 c1 9e 79 1f 2e 41 -DVLR SUBSCR(IMSI:901700000010650) AUTH established UMTS security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -- sending SecurityModeControl for IMSI:901700000010650 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - cipher_mode_cmd_sent == 1 - lu_result_sent == 0 -- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR -DMM <- SECURITY MODE COMPLETE IMSI:901700000010650 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() -DIUCS IMSI:901700000010650: tx CommonID 901700000010650 -- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0 -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA - gsup_tx_confirmed == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f2 -DVLR GSUP rx 17: 10010809710000000156f00804032443f2 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR IMSI:901700000010650 has MSISDN:42342 -DVLR GSUP tx: 12010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f0 -DVLR GSUP rx 11: 06010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:42342, with TMSI 0x03020100 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 1 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:42342 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- Iu Release --RAN_UTRAN_IU--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - iu_release_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 ---- -- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24) -DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DREF VLR subscr MSISDN:42342 usage increases to: 3 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- sending UMTS Auth Request for MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and... -- ...rand=c187a53a5e6b9d573cac7c74451fd46d -- ...autn=1843a645b98d00005b2d666af46c45d9 -- ...expecting res=7db47cf7f81e4dc7 -DREF VLR subscr MSISDN:42342 usage decreases to: 2 -DMM MSISDN:42342: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:42342: MSC conn use - 1 == 1 - cm_service_result_sent == 0 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and sends SecurityModeControl - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:42342: MM R99 AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:42342) received res: 7d b4 7c f7 f8 1e 4d c7 -DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -- sending SecurityModeControl for MSISDN:42342 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH -DMM MSISDN:42342: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:42342: MSC conn use - 1 == 1 - cipher_mode_cmd_sent == 1 - cm_service_result_sent == 0 -- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept -DMM <- SECURITY MODE COMPLETE MSISDN:42342 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() -DIUCS MSISDN:42342: tx CommonID 901700000010650 -- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_CM_SERVICE_REQ -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: received_cm_service_request = true -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: still awaiting first request after a CM Service Request - cm_service_result_sent == 0 -- a USSD request is serviced - expecting USSD: - Your extension is 42342 - MSC <--RAN_UTRAN_IU-- MS: GSM48_PDISC_NC_SS:0x3b -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_PDISC_NC_SS:0x3b (0xb:0x3b) -DMM MSISDN:42342: rx msg GSM48_PDISC_NC_SS:0x3b: received_cm_service_request changes to false -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM USSD: Own number requested -DMM MSISDN:42342: MSISDN = 42342 -DMSC msc_tx 43 bytes to MSISDN:42342 via RAN_UTRAN_IU -- DTAP --RAN_UTRAN_IU--> MS: GSM48_PDISC_NC_SS:0x2a: 8b2a1c27a225020100302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d273104d36a3c91a0d -- DTAP matches expected message -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- Iu Release --RAN_UTRAN_IU--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - iu_release_sent == 1 -- all requests serviced, conn has been released - llist_count(&net->subscr_conns) == 0 ---- -- an SMS is sent, MS is paged -DREF VLR subscr MSISDN:42342 usage increases to: 2 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:42342 usage increases to: 3 -DMM Subscriber MSISDN:42342 not paged yet, start paging. - RAN_UTRAN_IU sends out paging request to IMSI 901700000010650, TMSI 0x03020100, LAC 0 - strcmp(paging_expecting_imsi, imsi) == 0 -DREF VLR subscr MSISDN:42342 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:42342 usage decreases to: 3 - paging_sent == 1 - paging_stopped == 0 -- the subscriber and its pending request should remain -DREF VLR subscr MSISDN:42342 usage increases to: 4 - llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr MSISDN:42342 usage decreases to: 3 -- MS replies with Paging Response, and VLR sends Auth Request with third key - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_RR_PAG_RESP - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27) -DRR PAGING RESPONSE: MI(IMSI)=901700000010650 -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Allocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr MSISDN:42342 usage increases to: 4 -DREF VLR subscr MSISDN:42342 usage increases to: 5 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- sending UMTS Auth Request for MSISDN:42342: tuple use_count=1 key_seq=2 auth_types=0x3 and... -- ...rand=efa9c29a9742148d5c9070348716e1bb -- ...autn=f9375e6d41e1000096e7fe4ff1c27e39 -- ...expecting res=706f996719ba609c -DREF VLR subscr MSISDN:42342 usage decreases to: 4 -DMM MSISDN:42342: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:42342: MSC conn use - 1 == 1 - auth_request_sent == 1 -- needs auth, not yet accepted -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- MS sends Authen Response, VLR accepts and sends SecurityModeControl - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM MSISDN:42342: MM R99 AUTHENTICATION RESPONSE (res = 706f996719ba609c) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(MSISDN:42342) received res: 70 6f 99 67 19 ba 60 9c -DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: got VLR_AUTH_RES_PASSED -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() -- sending SecurityModeControl for MSISDN:42342 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH -DMM MSISDN:42342: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF MSISDN:42342: MSC conn use - 1 == 1 - cipher_mode_cmd_sent == 1 - paging_stopped == 0 -- MS sends SecurityModeControl acceptance, VLR accepts and sends SMS -DMM <- SECURITY MODE COMPLETE MSISDN:42342 -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() -DIUCS MSISDN:42342: tx CommonID 901700000010650 -- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei() -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(VLR_PR_ARQ_RES_PASSED) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Process Access Request result: VLR_PR_ARQ_RES_PASSED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DPAG Paging success for MSISDN:42342 (event=0) -DPAG Calling paging cbfn. -DREF VLR subscr MSISDN:42342 usage increases to: 5 -DREF MSISDN:42342: MSC conn use + 1 == 2 -DMSC msc_tx 91 bytes to MSISDN:42342 via RAN_UTRAN_IU -- DTAP --RAN_UTRAN_IU--> MS: GSM48_PDISC_SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 -- DTAP matches expected message -DREF VLR subscr MSISDN:42342 usage decreases to: 4 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: connection still has active transaction: GSM48_PDISC_SMS - paging_stopped == 1 -- SMS was delivered, no requests pending for subscr -DREF VLR subscr MSISDN:42342 usage increases to: 5 - llist_count(&vsub->cs.requests) == 0 -DREF VLR subscr MSISDN:42342 usage decreases to: 4 -- conn is still open to wait for SMS ack dance - llist_count(&net->subscr_conns) == 1 -- MS replies with CP-ACK for received SMS - MSC <--RAN_UTRAN_IU-- MS: GSM48_PDISC_SMS:0x04 -DREF MSISDN:42342: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x04 (0x9:0x4) -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: bump: connection still has active transaction: GSM48_PDISC_SMS -DREF MSISDN:42342: MSC conn use - 1 == 2 - llist_count(&net->subscr_conns) == 1 -- MS also sends RP-ACK, MSC in turn sends CP-ACK for that - MSC <--RAN_UTRAN_IU-- MS: GSM48_PDISC_SMS:0x01 -DREF MSISDN:42342: MSC conn use + 1 == 3 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING -DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU -- DTAP --RAN_UTRAN_IU--> MS: GSM48_PDISC_SMS:0x04: 0904 -- DTAP matches expected message -DREF VLR subscr MSISDN:42342 usage decreases to: 3 -DREF VLR subscr MSISDN:42342 usage decreases to: 2 -DREF MSISDN:42342: MSC conn use - 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Freeing instance -DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- Iu Release --RAN_UTRAN_IU--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - dtap_tx_confirmed == 1 - iu_release_sent == 1 -- SMS is done, conn is gone - llist_count(&net->subscr_conns) == 0 ---- -- subscriber detaches - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_IMSI_DETACH_IND - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1) -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DMM IMSI DETACH for MSISDN:42342 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -DREF VLR subscr MSISDN:42342 usage decreases to: 0 -DREF freeing VLR subscr MSISDN:42342 -DMM msc_subscr_conn_close(vsub=unknown, cause=0): no conn fsm, releasing directly without release event. -- Iu Release --RAN_UTRAN_IU--> MS -DREF unknown: MSC conn use - 1 == 0 -DRLL Freeing subscriber connection with NULL subscriber - iu_release_sent == 1 - llist_count(&net->subscr_conns) == 0 -===== test_umts_authen_utran: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_umts_authen_resync_geran -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL -DMM LU/new-LAC: 0/0 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 -DVLR New subscr, IMSI: 901700000010650 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41 -DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000010650) Received 1 auth tuples -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending UMTS Auth Request for IMSI:901700000010650: tuple use_count=1 key_seq=0 auth_types=0x3 and... -- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d -- ...autn=8704f5ba55f30000d2ee44b22c8ea919 -- ...expecting res=e229c19e791f2e41 -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Failure with Resync cause, VLR sends GSUP to HLR to resync - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_FAIL -DREF IMSI:901700000010650: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_FAIL (0x5:0x1c) -DMM IMSI:901700000010650: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL -DVLR GSUP tx: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - gsup_tx_confirmed == 1 - auth_request_sent == 0 - lu_result_sent == 0 -- HLR replies with new tuples -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db -DVLR GSUP rx 211: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000010650) Received 2 auth tuples -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: state_chg to VLR_SUB_AS_WAIT_RESP_RESYNC -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: got auth tuple: use_count=1 key_seq=0 -- sending UMTS Auth Request for IMSI:901700000010650: tuple use_count=1 key_seq=0 auth_types=0x3 and... -- ...rand=0f1feb1623e1bf626334e37ec448ac18 -- ...autn=02a83f62e9470000660d51afc75f169d -- ...expecting res=1df5f0b4f22b696e -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000010650: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000010650: MM R99 AUTHENTICATION RESPONSE (res = 1df5f0b4f22b696e) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000010650) received res: 1d f5 f0 b4 f2 2b 69 6e -DVLR SUBSCR(IMSI:901700000010650) AUTH established UMTS security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0 -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - gsup_tx_confirmed == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f2 -DVLR GSUP rx 17: 10010809710000000156f00804032443f2 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR IMSI:901700000010650 has MSISDN:42342 -DVLR GSUP tx: 12010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f0 -DVLR GSUP rx 11: 06010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:42342, with TMSI 0x03020100 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 1 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:42342 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- BSSAP Clear --RAN_GERAN_A--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - bssap_clear_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:42342 -===== test_umts_authen_resync_geran: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -===== test_umts_authen_resync_utran -- Location Update request causes a GSUP Send Auth Info request to HLR - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST - new conn -DREF unknown: MSC conn use + 1 == 1 -DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8) -DREF unknown: MSC conn use + 1 == 2 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Allocated -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: Received Event SUBSCR_CONN_E_START -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_INIT}: state_chg to SUBSCR_CONN_S_NEW -DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL -DMM LU/new-LAC: 0/0 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Allocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA -DREF VLR subscr unknown usage increases to: 1 -DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 -DVLR New subscr, IMSI: 901700000010650 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -DVLR GSUP tx: 08010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - lu_result_sent == 0 -- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41 -DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000010650) Received 1 auth tuples -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- sending UMTS Auth Request for IMSI:901700000010650: tuple use_count=1 key_seq=0 auth_types=0x3 and... -- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d -- ...autn=8704f5ba55f30000d2ee44b22c8ea919 -- ...expecting res=e229c19e791f2e41 -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Failure with Resync cause, VLR sends GSUP to HLR to resync - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_FAIL -DREF IMSI:901700000010650: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_FAIL (0x5:0x1c) -DMM IMSI:901700000010650: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL -DVLR GSUP tx: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - gsup_tx_confirmed == 1 - auth_request_sent == 0 - lu_result_sent == 0 -- HLR replies with new tuples -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db -DVLR GSUP rx 211: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR SUBSCR(IMSI:901700000010650) Received 2 auth tuples -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: state_chg to VLR_SUB_AS_WAIT_RESP_RESYNC -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: got auth tuple: use_count=1 key_seq=0 -- sending UMTS Auth Request for IMSI:901700000010650: tuple use_count=1 key_seq=0 auth_types=0x3 and... -- ...rand=0f1feb1623e1bf626334e37ec448ac18 -- ...autn=02a83f62e9470000660d51afc75f169d -- ...expecting res=1df5f0b4f22b696e -DREF VLR subscr IMSI:901700000010650 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 - auth_request_sent == 1 - lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends SecurityModeControl - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP -DREF IMSI:901700000010650: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14) -DMM IMSI:901700000010650: MM R99 AUTHENTICATION RESPONSE (res = 1df5f0b4f22b696e) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: Received Event VLR_AUTH_E_MS_AUTH_RESP -DVLR SUBSCR(IMSI:901700000010650) received res: 1d f5 f0 b4 f2 2b 69 6e -DVLR SUBSCR(IMSI:901700000010650) AUTH established UMTS security context -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: Authentication terminating with result VLR_AUTH_RES_PASSED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance -DVLR VLR_Authenticate(901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() -- sending SecurityModeControl for IMSI:901700000010650 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH -DMM IMSI:901700000010650: bump: conn still being established (SUBSCR_CONN_S_NEW) -DREF IMSI:901700000010650: MSC conn use - 1 == 1 - cipher_mode_cmd_sent == 1 - lu_result_sent == 0 -- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR -DMM <- SECURITY MODE COMPLETE IMSI:901700000010650 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() -DIUCS IMSI:901700000010650: tx CommonID 901700000010650 -- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Allocated -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START -DVLR GSUP tx: 04010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0 -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA - gsup_tx_confirmed == 1 - lu_result_sent == 0 -- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f2 -DVLR GSUP rx 17: 10010809710000000156f00804032443f2 -DREF VLR subscr IMSI:901700000010650 usage increases to: 2 -DVLR IMSI:901700000010650 has MSISDN:42342 -DVLR GSUP tx: 12010809710000000156f0 -GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 0 -- HLR also sends GSUP _UPDATE_LOCATION_RESULT -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f0 -DVLR GSUP rx 11: 06010809710000000156f0 -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance -DVLR upd_hlr_vlr_fsm(901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Allocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Allocated -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(901700000010650) -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance -DVLR sub_pres_vlr_fsm(901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF -- sending LU Accept for MSISDN:42342, with TMSI 0x03020100 -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 - lu_result_sent == 1 -- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl - llist_count(&net->subscr_conns) == 1 -msc_subscr_conn_is_accepted() == false - requests shall be thwarted -DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP -DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33 -DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 -DRLL Dispatching 04.08 message GSM48_PDISC_SMS:0x01 (0x9:0x1) -DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_PDISC_SMS:0x01 -- even though the TMSI is not acked, we can already find the subscr with it -DREF VLR subscr MSISDN:42342 usage increases to: 2 - vsub != NULL == 1 - strcmp(vsub->imsi, imsi) == 0 - vsub->tmsi_new == 0x03020100 - vsub->tmsi == 0xffffffff -DREF VLR subscr MSISDN:42342 usage decreases to: 1 -- MS sends TMSI Realloc Complete - MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL -DREF MSISDN:42342: MSC conn use + 1 == 2 -DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b) -DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342 -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK -DREF VLR subscr MSISDN:42342 usage increases to: 2 -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(901700000010650) -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance -DVLR lu_compl_vlr_fsm(901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_LU -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_BUMP -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: bump: releasing conn -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASED -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(901700000010650) -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Freeing instance -DVLR vlr_lu_fsm(901700000010650){VLR_ULA_S_DONE}: Deallocated -DMM msc_subscr_conn_close(vsub=MSISDN:42342, cause=2): no conn fsm, releasing directly without release event. -- Iu Release --RAN_UTRAN_IU--> MS -DREF MSISDN:42342: MSC conn use - 1 == 1 -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance -DMM Subscr_Conn(901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated -DREF MSISDN:42342: MSC conn use - 1 == 0 -DRLL subscr MSISDN:42342: Freeing subscriber connection -DREF VLR subscr MSISDN:42342 usage decreases to: 1 - iu_release_sent == 1 -- LU was successful, and the conn has already been closed - llist_count(&net->subscr_conns) == 0 -DREF freeing VLR subscr MSISDN:42342 -===== test_umts_authen_resync_utran: SUCCESS - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 9 - diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.ok b/tests/msc_vlr/msc_vlr_test_umts_authen.ok deleted file mode 100644 index a965a70ed..000000000 --- a/tests/msc_vlr/msc_vlr_test_umts_authen.ok +++ /dev/null @@ -1 +0,0 @@ -Done diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c deleted file mode 100644 index 71f971352..000000000 --- a/tests/msc_vlr/msc_vlr_tests.c +++ /dev/null @@ -1,805 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if BUILD_IU -#include -#include -#else -#include -#endif - -#include "msc_vlr_tests.h" - -bool _log_lines = false; - -struct gsm_network *net = NULL; - -struct gsm_bts *the_bts; - -const char *gsup_tx_expected = NULL; -bool gsup_tx_confirmed; - -struct msgb *dtap_tx_expected = NULL; -bool dtap_tx_confirmed; - -enum result_sent lu_result_sent; -enum result_sent cm_service_result_sent; -bool auth_request_sent; -const char *auth_request_expect_rand; -const char *auth_request_expect_autn; -bool cipher_mode_cmd_sent; -bool cipher_mode_cmd_sent_with_imeisv; - -bool iu_release_expected = false; -bool iu_release_sent = false; -bool bssap_clear_expected = false; -bool bssap_clear_sent = false; - -struct msgb *msgb_from_hex(const char *label, uint16_t size, const char *hex) -{ - struct msgb *msg = msgb_alloc(size, label); - unsigned char *rc; - msg->l2h = msg->head; - rc = msgb_put(msg, osmo_hexparse(hex, msg->head, msgb_tailroom(msg))); - OSMO_ASSERT(rc == msg->l2h); - return msg; -} - -const char *gh_type_name(struct gsm48_hdr *gh) -{ - return gsm48_pdisc_msgtype_name(gsm48_hdr_pdisc(gh), - gsm48_hdr_msg_type(gh)); -} - -const char *msg_type_name(struct msgb *msg) -{ - return gh_type_name((void*)msg->data); -} - -void dtap_expect_tx(const char *hex) -{ - /* Has the previously expected dtap been received? */ - OSMO_ASSERT(!dtap_tx_expected); - if (!hex) - return; - dtap_tx_expected = msgb_from_hex("dtap_tx_expected", 1024, hex); - dtap_tx_confirmed = false; -} - -void dtap_expect_tx_ussd(char *ussd_text) -{ - uint8_t ussd_enc[128]; - int len; - /* header */ - char ussd_msg_hex[128] = "8b2a1c27a225020100302002013b301b04010f0416"; - - log("expecting USSD:\n %s", ussd_text); - /* append encoded USSD text */ - gsm_7bit_encode_n_ussd(ussd_enc, sizeof(ussd_enc), ussd_text, - &len); - strncat(ussd_msg_hex, osmo_hexdump_nospc(ussd_enc, len), - sizeof(ussd_msg_hex) - strlen(ussd_msg_hex)); - dtap_expect_tx(ussd_msg_hex); -} - -int vlr_gsupc_read_cb(struct gsup_client *gsupc, struct msgb *msg); - -void gsup_rx(const char *rx_hex, const char *expect_tx_hex) -{ - int rc; - struct msgb *msg; - const char *label; - - gsup_expect_tx(expect_tx_hex); - - msg = msgb_from_hex("gsup", 1024, rx_hex); - label = osmo_gsup_message_type_name(msg->l2h[0]); - fprintf(stderr, "<-- GSUP rx %s: %s\n", label, - osmo_hexdump_nospc(msgb_l2(msg), msgb_l2len(msg))); - rc = vlr_gsupc_read_cb(net->vlr->gsup_client, msg); - fprintf(stderr, "<-- GSUP rx %s: vlr_gsupc_read_cb() returns %d\n", - label, rc); - if (expect_tx_hex) - OSMO_ASSERT(gsup_tx_confirmed); - talloc_free(msg); -} - -bool conn_exists(struct gsm_subscriber_connection *conn) -{ - struct gsm_subscriber_connection *c; - llist_for_each_entry(c, &net->subscr_conns, entry) { - if (c == conn) - return true; - } - return false; -} - -enum ran_type rx_from_ran = RAN_GERAN_A; - -struct gsm_subscriber_connection *conn_new(void) -{ - struct gsm_subscriber_connection *conn; - conn = msc_subscr_con_allocate(net); - conn->bts = the_bts; - conn->via_ran = rx_from_ran; - if (conn->via_ran == RAN_UTRAN_IU) { - struct ranap_ue_conn_ctx *ue_ctx = talloc_zero(conn, struct ranap_ue_conn_ctx); - *ue_ctx = (struct ranap_ue_conn_ctx){ - .conn_id = 42, - }; - conn->iu.ue_ctx = ue_ctx; - } - return conn; -} - -struct gsm_subscriber_connection *g_conn = NULL; - -void rx_from_ms(struct msgb *msg) -{ - int rc; - - struct gsm48_hdr *gh = msgb_l3(msg); - - log("MSC <--%s-- MS: %s", - ran_type_name(rx_from_ran), - gh_type_name(gh)); - - if (g_conn && !conn_exists(g_conn)) - g_conn = NULL; - - if (!g_conn) { - log("new conn"); - g_conn = conn_new(); - rc = msc_compl_l3(g_conn, msg, 23); - if (rc == BSC_API_CONN_POL_REJECT) { - msc_subscr_con_free(g_conn); - g_conn = NULL; - } - } else { - if ((gsm48_hdr_pdisc(gh) == GSM48_PDISC_RR) - && (gsm48_hdr_msg_type(gh) == GSM48_MT_RR_CIPH_M_COMPL)) - msc_cipher_mode_compl(g_conn, msg, 0); - else - msc_dtap(g_conn, 23, msg); - } - - if (g_conn && !conn_exists(g_conn)) - g_conn = NULL; -} - -void ms_sends_msg(const char *hex) -{ - struct msgb *msg; - - msg = msgb_from_hex("ms_sends_msg", 1024, hex); - msg->l1h = msg->l2h = msg->l3h = msg->data; - rx_from_ms(msg); - talloc_free(msg); -} - -int ms_sends_msg_fake(uint8_t pdisc, uint8_t msg_type) -{ - int rc; - struct msgb *msg; - struct gsm48_hdr *gh; - - msg = msgb_alloc(1024, "ms_sends_msg_fake"); - msg->l1h = msg->l2h = msg->l3h = msg->data; - - gh = (struct gsm48_hdr*)msgb_put(msg, sizeof(*gh)); - gh->proto_discr = pdisc; - gh->msg_type = msg_type; - /* some amount of data, whatever */ - msgb_put(msg, 123); - - rc = gsm0408_dispatch(g_conn, msg); - - talloc_free(msg); - return rc; -} - -void thwart_rx_non_initial_requests() -{ - log("requests shall be thwarted"); - OSMO_ASSERT(ms_sends_msg_fake(GSM48_PDISC_CC, GSM48_MT_CC_SETUP) == -EACCES); - OSMO_ASSERT(ms_sends_msg_fake(GSM48_PDISC_MM, 0x33 /* nonexistent */) == -EACCES); - OSMO_ASSERT(ms_sends_msg_fake(GSM48_PDISC_RR, GSM48_MT_RR_SYSINFO_1) == -EACCES); - OSMO_ASSERT(ms_sends_msg_fake(GSM48_PDISC_SMS, GSM411_MT_CP_DATA) == -EACCES); -} - -void send_sms(struct vlr_subscr *receiver, - struct vlr_subscr *sender, - char *str) -{ - struct gsm_sms *sms = sms_from_text(receiver, sender, 0, str); - gsm411_send_sms_subscr(receiver, sms); -} - -unsigned char next_rand_byte = 0; -/* override, requires '-Wl,--wrap=RAND_bytes' */ -int __real_RAND_bytes(unsigned char *buf, int num); -int __wrap_RAND_bytes(unsigned char *buf, int num) -{ - int i; - for (i = 0; i < num; i++) - buf[i] = next_rand_byte++; - return 1; -} - -/* override, requires '-Wl,--wrap=gsm340_gen_scts' */ -void __real_gsm340_gen_scts(uint8_t *scts, time_t time); -void __wrap_gsm340_gen_scts(uint8_t *scts, time_t time) -{ - /* Write fixed time bytes for deterministic test results */ - osmo_hexparse("07101000000000", scts, 7); -} - -const char *paging_expecting_imsi = NULL; -uint32_t paging_expecting_tmsi; -bool paging_sent; -bool paging_stopped; - -void paging_expect_imsi(const char *imsi) -{ - paging_expecting_imsi = imsi; - paging_expecting_tmsi = GSM_RESERVED_TMSI; -} - -void paging_expect_tmsi(uint32_t tmsi) -{ - paging_expecting_tmsi = tmsi; - paging_expecting_imsi = NULL; -} - -int _paging_sent(enum ran_type via_ran, const char *imsi, uint32_t tmsi, uint32_t lac) -{ - log("%s sends out paging request to IMSI %s, TMSI 0x%08x, LAC %u", - ran_type_name(via_ran), imsi, tmsi, lac); - OSMO_ASSERT(paging_expecting_imsi || (paging_expecting_tmsi != GSM_RESERVED_TMSI)); - if (paging_expecting_imsi) - VERBOSE_ASSERT(strcmp(paging_expecting_imsi, imsi), == 0, "%d"); - if (paging_expecting_tmsi != GSM_RESERVED_TMSI) { - VERBOSE_ASSERT(paging_expecting_tmsi, == tmsi, "0x%08x"); - } - paging_sent = true; - paging_stopped = false; - return 1; -} - -/* override, requires '-Wl,--wrap=ranap_iu_page_cs' */ -int __real_ranap_iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac); -int __wrap_ranap_iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac) -{ - return _paging_sent(RAN_UTRAN_IU, imsi, tmsi ? *tmsi : GSM_RESERVED_TMSI, lac); -} - -/* override, requires '-Wl,--wrap=a_iface_tx_paging' */ -int __real_a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac); -int __wrap_a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac) -{ - return _paging_sent(RAN_GERAN_A, imsi, tmsi, lac); -} - -/* override, requires '-Wl,--wrap=msc_stop_paging' */ -void __real_msc_stop_paging(struct vlr_subscr *vsub); -void __wrap_msc_stop_paging(struct vlr_subscr *vsub) -{ - paging_stopped = true; -} - -void clear_vlr() -{ - struct vlr_subscr *vsub, *n; - llist_for_each_entry_safe(vsub, n, &net->vlr->subscribers, list) { - vlr_subscr_free(vsub); - } - - net->authentication_required = false; - net->a5_encryption = VLR_CIPH_NONE; - net->vlr->cfg.check_imei_rqd = false; - net->vlr->cfg.assign_tmsi = false; - net->vlr->cfg.retrieve_imeisv_early = false; - net->vlr->cfg.retrieve_imeisv_ciphered = false; - - rx_from_ran = RAN_GERAN_A; - auth_request_sent = false; - auth_request_expect_rand = NULL; - auth_request_expect_autn = NULL; - - next_rand_byte = 0; - - iu_release_expected = false; - iu_release_sent = false; - bssap_clear_expected = false; - bssap_clear_sent = false; - - osmo_gettimeofday_override = false; -} - -static struct log_info_cat test_categories[] = { - [DMSC] = { - .name = "DMSC", - .description = "Mobile Switching Center", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DRLL] = { - .name = "DRLL", - .description = "A-bis Radio Link Layer (RLL)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DMM] = { - .name = "DMM", - .description = "Layer3 Mobility Management (MM)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DRR] = { - .name = "DRR", - .description = "Layer3 Radio Resource (RR)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DCC] = { - .name = "DCC", - .description = "Layer3 Call Control (CC)", - .enabled = 1, .loglevel = LOGL_NOTICE, - }, - [DMM] = { - .name = "DMM", - .description = "Layer3 Mobility Management (MM)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DVLR] = { - .name = "DVLR", - .description = "Visitor Location Register", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DREF] = { - .name = "DREF", - .description = "Reference Counting", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DPAG] = { - .name = "DPAG", - .description = "Paging Subsystem", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DIUCS] = { - .name = "DIUCS", - .description = "Iu-CS Protocol", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, -}; - -static struct log_info info = { - .cat = test_categories, - .num_cat = ARRAY_SIZE(test_categories), -}; - -extern void *tall_bsc_ctx; - -int fake_mncc_recv(struct gsm_network *net, struct msgb *msg) -{ - fprintf(stderr, "rx MNCC\n"); - return 0; -} - -/* override, requires '-Wl,--wrap=gsup_client_create' */ -struct gsup_client * -__real_gsup_client_create(const char *ip_addr, unsigned int tcp_port, - gsup_client_read_cb_t read_cb, - struct oap_client_config *oap_config); -struct gsup_client * -__wrap_gsup_client_create(const char *ip_addr, unsigned int tcp_port, - gsup_client_read_cb_t read_cb, - struct oap_client_config *oap_config) -{ - struct gsup_client *gsupc; - gsupc = talloc_zero(tall_bsc_ctx, struct gsup_client); - OSMO_ASSERT(gsupc); - return gsupc; -} - -/* override, requires '-Wl,--wrap=gsup_client_send' */ -int __real_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg); -int __wrap_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg) -{ - const char *is = osmo_hexdump_nospc(msg->data, msg->len); - fprintf(stderr, "GSUP --> HLR: %s: %s\n", - osmo_gsup_message_type_name(msg->data[0]), is); - - OSMO_ASSERT(gsup_tx_expected); - if (strcmp(gsup_tx_expected, is)) { - fprintf(stderr, "Mismatch! Expected:\n%s\n", gsup_tx_expected); - abort(); - } - - talloc_free(msg); - gsup_tx_confirmed = true; - gsup_tx_expected = NULL; - return 0; -} - -int _validate_dtap(struct msgb *msg, enum ran_type to_ran) -{ - btw("DTAP --%s--> MS: %s: %s", - ran_type_name(to_ran), msg_type_name(msg), - osmo_hexdump_nospc(msg->data, msg->len)); - - OSMO_ASSERT(dtap_tx_expected); - if (msg->len != dtap_tx_expected->len - || memcmp(msg->data, dtap_tx_expected->data, msg->len)) { - fprintf(stderr, "Mismatch! Expected:\n%s\n", - osmo_hexdump_nospc(dtap_tx_expected->data, - dtap_tx_expected->len)); - abort(); - } - - btw("DTAP matches expected message"); - - talloc_free(msg); - dtap_tx_confirmed = true; - talloc_free(dtap_tx_expected); - dtap_tx_expected = NULL; - return 0; -} - -/* override, requires '-Wl,--wrap=ranap_iu_tx' */ -int __real_ranap_iu_tx(struct msgb *msg, uint8_t sapi); -int __wrap_ranap_iu_tx(struct msgb *msg, uint8_t sapi) -{ - return _validate_dtap(msg, RAN_UTRAN_IU); -} - -/* override, requires '-Wl,--wrap=ranap_iu_tx_release' */ -int __real_ranap_iu_tx_release(struct ranap_ue_conn_ctx *ctx, const struct RANAP_Cause *cause); -int __wrap_ranap_iu_tx_release(struct ranap_ue_conn_ctx *ctx, const struct RANAP_Cause *cause) -{ - btw("Iu Release --%s--> MS", ran_type_name(RAN_UTRAN_IU)); - OSMO_ASSERT(iu_release_expected); - iu_release_expected = false; - iu_release_sent = true; - return 0; -} - -/* override, requires '-Wl,--wrap=iu_tx_common_id' */ -int __real_ranap_iu_tx_common_id(struct ranap_ue_conn_ctx *ue_ctx, const char *imsi); -int __wrap_ranap_iu_tx_common_id(struct ranap_ue_conn_ctx *ue_ctx, const char *imsi) -{ - btw("Iu Common ID --%s--> MS (IMSI=%s)", ran_type_name(RAN_UTRAN_IU), imsi); - return 0; -} - -/* override, requires '-Wl,--wrap=a_iface_tx_dtap' */ -int __real_a_iface_tx_dtap(struct msgb *msg); -int __wrap_a_iface_tx_dtap(struct msgb *msg) -{ - return _validate_dtap(msg, RAN_GERAN_A); -} - -/* override, requires '-Wl,--wrap=a_iface_tx_clear_cmd' */ -int __real_a_iface_tx_clear_cmd(struct gsm_subscriber_connection *conn); -int __wrap_a_iface_tx_clear_cmd(struct gsm_subscriber_connection *conn) -{ - btw("BSSAP Clear --%s--> MS", ran_type_name(RAN_GERAN_A)); - OSMO_ASSERT(bssap_clear_expected); - bssap_clear_expected = false; - bssap_clear_sent = true; - return 0; -} - -static int fake_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - if (send_tmsi == GSM_RESERVED_TMSI) - btw("sending LU Accept for %s", vlr_subscr_name(conn->vsub)); - else - btw("sending LU Accept for %s, with TMSI 0x%08x", - vlr_subscr_name(conn->vsub), send_tmsi); - lu_result_sent |= RES_ACCEPT; - return 0; -} - -static int fake_vlr_tx_lu_rej(void *msc_conn_ref, uint8_t cause) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - btw("sending LU Reject for %s, cause %u", vlr_subscr_name(conn->vsub), cause); - lu_result_sent |= RES_REJECT; - return 0; -} - -static int fake_vlr_tx_cm_serv_acc(void *msc_conn_ref) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - btw("sending CM Service Accept for %s", vlr_subscr_name(conn->vsub)); - cm_service_result_sent |= RES_ACCEPT; - return 0; -} - -static int fake_vlr_tx_cm_serv_rej(void *msc_conn_ref, - enum vlr_proc_arq_result result) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - btw("sending CM Service Reject for %s, result %s", - vlr_subscr_name(conn->vsub), - vlr_proc_arq_result_name(result)); - cm_service_result_sent |= RES_REJECT; - return 0; -} - -static int fake_vlr_tx_auth_req(void *msc_conn_ref, struct gsm_auth_tuple *at, - bool send_autn) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - char *hex; - bool ok = true; - btw("sending %s Auth Request for %s: tuple use_count=%d key_seq=%d auth_types=0x%x and...", - send_autn? "UMTS" : "GSM", vlr_subscr_name(conn->vsub), - at->use_count, at->key_seq, at->vec.auth_types); - - hex = osmo_hexdump_nospc((void*)&at->vec.rand, sizeof(at->vec.rand)); - btw("...rand=%s", hex); - if (!auth_request_expect_rand - || strcmp(hex, auth_request_expect_rand) != 0) { - ok = false; - log("FAILURE: expected rand=%s", - auth_request_expect_rand ? auth_request_expect_rand : "-"); - } - - if (send_autn) { - hex = osmo_hexdump_nospc((void*)&at->vec.autn, sizeof(at->vec.autn)); - btw("...autn=%s", hex); - if (!auth_request_expect_autn - || strcmp(hex, auth_request_expect_autn) != 0) { - ok = false; - log("FAILURE: expected autn=%s", - auth_request_expect_autn ? auth_request_expect_autn : "-"); - } - } else if (auth_request_expect_autn) { - ok = false; - log("FAILURE: no AUTN sent, expected AUTN = %s", - auth_request_expect_autn); - } - - if (send_autn) - btw("...expecting res=%s", - osmo_hexdump_nospc((void*)&at->vec.res, at->vec.res_len)); - else - btw("...expecting sres=%s", - osmo_hexdump_nospc((void*)&at->vec.sres, sizeof(at->vec.sres))); - - auth_request_sent = ok; - return 0; -} - -static int fake_vlr_tx_auth_rej(void *msc_conn_ref) -{ - struct gsm_subscriber_connection *conn = msc_conn_ref; - btw("sending Auth Reject for %s", vlr_subscr_name(conn->vsub)); - return 0; -} - -static int fake_vlr_tx_ciph_mode_cmd(void *msc_conn_ref, enum vlr_ciph ciph, - bool retrieve_imeisv) -{ - /* FIXME: we actually would like to see the message bytes checked here, - * not possible while msc_vlr_set_ciph_mode() calls - * gsm0808_cipher_mode() directly. When the MSCSPLIT is ready, check - * the tx bytes in the sense of dtap_expect_tx() above. */ - struct gsm_subscriber_connection *conn = msc_conn_ref; - switch (conn->via_ran) { - case RAN_GERAN_A: - btw("sending Ciphering Mode Command for %s: cipher=%s kc=%s" - " retrieve_imeisv=%d", - vlr_subscr_name(conn->vsub), - vlr_ciph_name(conn->network->a5_encryption), - osmo_hexdump_nospc(conn->vsub->last_tuple->vec.kc, 8), - retrieve_imeisv); - break; - case RAN_UTRAN_IU: - btw("sending SecurityModeControl for %s", - vlr_subscr_name(conn->vsub)); - break; - default: - btw("UNKNOWN RAN TYPE %d", conn->via_ran); - OSMO_ASSERT(false); - return -1; - } - cipher_mode_cmd_sent = true; - cipher_mode_cmd_sent_with_imeisv = retrieve_imeisv; - return 0; -} - -void ms_sends_security_mode_complete() -{ - OSMO_ASSERT(g_conn); - OSMO_ASSERT(g_conn->via_ran == RAN_UTRAN_IU); - OSMO_ASSERT(g_conn->iu.ue_ctx); - msc_rx_sec_mode_compl(g_conn); -} - -const struct timeval fake_time_start_time = { 123, 456 }; - -void fake_time_start() -{ - osmo_gettimeofday_override_time = fake_time_start_time; - osmo_gettimeofday_override = true; - fake_time_passes(0, 0); -} - -void check_talloc(void *msgb_ctx, void *tall_bsc_ctx, int expected_blocks) -{ - talloc_report_full(msgb_ctx, stderr); - fprintf(stderr, "talloc_total_blocks(tall_bsc_ctx) == %zu\n", - talloc_total_blocks(tall_bsc_ctx)); - if (talloc_total_blocks(tall_bsc_ctx) != expected_blocks) - talloc_report_full(tall_bsc_ctx, stderr); - fprintf(stderr, "\n"); -} - -static struct { - bool verbose; - int run_test_nr; -} cmdline_opts = { - .verbose = false, - .run_test_nr = -1, -}; - -static void print_help(const char *program) -{ - printf("Usage:\n" - " %s [-v] [N [N...]]\n" - "Options:\n" - " -h --help show this text.\n" - " -v --verbose print source file and line numbers\n" - " N run only the Nth test (first test is N=1)\n", - program - ); -} - -static void handle_options(int argc, char **argv) -{ - while (1) { - int option_index = 0, c; - static struct option long_options[] = { - {"help", 0, 0, 'h'}, - {"verbose", 1, 0, 'v'}, - {0, 0, 0, 0} - }; - - c = getopt_long(argc, argv, "hv", - long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - print_help(argv[0]); - exit(0); - case 'v': - cmdline_opts.verbose = true; - break; - default: - /* catch unknown options *as well as* missing arguments. */ - fprintf(stderr, "Error in command line options. Exiting.\n"); - exit(-1); - break; - } - } -} - -void *msgb_ctx = NULL; - -void run_tests(int nr) -{ - int test_nr; - nr --; /* arg's first test is 1, in here it's 0 */ - for (test_nr = 0; msc_vlr_tests[test_nr]; test_nr ++) { - if (nr >= 0 && test_nr != nr) - continue; - - if (cmdline_opts.verbose) - fprintf(stderr, "(test nr %d)\n", test_nr + 1); - - msc_vlr_tests[test_nr](); - - if (cmdline_opts.verbose) - fprintf(stderr, "(test nr %d)\n", test_nr + 1); - - check_talloc(msgb_ctx, tall_bsc_ctx, 9); - } while(0); -} - -int main(int argc, char **argv) -{ - handle_options(argc, argv); - - tall_bsc_ctx = talloc_named_const(NULL, 0, "subscr_conn_test_ctx"); - msgb_ctx = msgb_talloc_ctx_init(tall_bsc_ctx, 0); - osmo_init_logging(&info); - - _log_lines = cmdline_opts.verbose; - - 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, _log_lines? 1 : 0); - log_set_print_category(osmo_stderr_target, 1); - - net = gsm_network_init(tall_bsc_ctx, 1, 1, fake_mncc_recv); - net->gsup_server_addr_str = talloc_strdup(net, "no_gsup_server"); - net->gsup_server_port = 0; - - osmo_fsm_log_addr(false); - OSMO_ASSERT(msc_vlr_alloc(net) == 0); - OSMO_ASSERT(msc_vlr_start(net) == 0); - OSMO_ASSERT(net->vlr); - OSMO_ASSERT(net->vlr->gsup_client); - msc_subscr_conn_init(); - - net->vlr->ops.tx_lu_acc = fake_vlr_tx_lu_acc; - net->vlr->ops.tx_lu_rej = fake_vlr_tx_lu_rej; - net->vlr->ops.tx_cm_serv_acc = fake_vlr_tx_cm_serv_acc; - net->vlr->ops.tx_cm_serv_rej = fake_vlr_tx_cm_serv_rej; - net->vlr->ops.tx_auth_req = fake_vlr_tx_auth_req; - net->vlr->ops.tx_auth_rej = fake_vlr_tx_auth_rej; - net->vlr->ops.set_ciph_mode = fake_vlr_tx_ciph_mode_cmd; - - clear_vlr(); - - if (optind >= argc) - run_tests(-1); - else { - int arg; - long int nr; - for (arg = optind; arg < argc; arg++) { - nr = strtol(argv[arg], NULL, 10); - if (errno) { - fprintf(stderr, "Invalid argument: %s\n", - argv[arg]); - exit(1); - } - - run_tests(nr); - } - } - - printf("Done\n"); - - talloc_free(the_bts); - - check_talloc(msgb_ctx, tall_bsc_ctx, 9); - return 0; -} diff --git a/tests/msc_vlr/msc_vlr_tests.h b/tests/msc_vlr/msc_vlr_tests.h deleted file mode 100644 index c2c5a58a7..000000000 --- a/tests/msc_vlr/msc_vlr_tests.h +++ /dev/null @@ -1,186 +0,0 @@ -/* Osmocom MSC+VLR end-to-end tests */ - -/* (C) 2017 by sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#pragma once - -#include -#include - -#include -#include -#include - -extern bool _log_lines; -#define _log(fmt, args...) do { \ - if (_log_lines) \ - fprintf(stderr, " %4d:%s: " fmt "\n", \ - __LINE__, __FILE__, ## args ); \ - else \ - fprintf(stderr, fmt "\n", ## args ); \ - } while (false) - -/* btw means "by the way", the test tells the log what's happening. - * BTW() marks a larger section, btw() is the usual logging. */ -#define BTW(fmt, args...) _log("---\n- " fmt, ## args ) -#define btw(fmt, args...) _log("- " fmt, ## args ) -#define log(fmt, args...) _log(" " fmt, ## args ) - -#define comment_start() fprintf(stderr, "===== %s\n", __func__); -#define comment_end() fprintf(stderr, "===== %s: SUCCESS\n\n", __func__); - -extern struct gsm_subscriber_connection *g_conn; -extern struct gsm_network *net; -extern struct gsm_bts *the_bts; -extern void *msgb_ctx; - -extern enum ran_type rx_from_ran; - -extern const char *gsup_tx_expected; -extern bool gsup_tx_confirmed; - -extern struct msgb *dtap_tx_expected; -extern bool dtap_tx_confirmed; - -enum result_sent { - RES_NONE = 0, - RES_ACCEPT = 1, - RES_REJECT = 2, -}; -extern enum result_sent lu_result_sent; -extern enum result_sent cm_service_result_sent; - -extern bool auth_request_sent; -extern const char *auth_request_expect_rand; -extern const char *auth_request_expect_autn; - -extern bool cipher_mode_cmd_sent; -extern bool cipher_mode_cmd_sent_with_imeisv; - -extern bool paging_sent; -extern bool paging_stopped; - -extern bool iu_release_expected; -extern bool iu_release_sent; -extern bool bssap_clear_expected; -extern bool bssap_clear_sent; - -static inline void expect_iu_release() -{ - iu_release_expected = true; - iu_release_sent = false; -} - -static inline void expect_bssap_clear() -{ - bssap_clear_expected = true; - bssap_clear_sent = false; -} - -static inline void expect_release_clear(enum ran_type via_ran) -{ - switch (via_ran) { - case RAN_GERAN_A: - expect_bssap_clear(); - return; - case RAN_UTRAN_IU: - expect_iu_release(); - return; - default: - OSMO_ASSERT(false); - break; - } -} - -struct msc_vlr_test_cmdline_opts { - bool verbose; - int run_test_nr; -}; - -typedef void (* msc_vlr_test_func_t )(void); -extern msc_vlr_test_func_t msc_vlr_tests[]; - -struct msgb *msgb_from_hex(const char *label, uint16_t size, const char *hex); - -void clear_vlr(); -bool conn_exists(struct gsm_subscriber_connection *conn); - -void dtap_expect_tx(const char *hex); -void dtap_expect_tx_ussd(char *ussd_text); -void paging_expect_imsi(const char *imsi); -void paging_expect_tmsi(uint32_t tmsi); - -void ms_sends_msg(const char *hex); -void ms_sends_security_mode_complete(); -void gsup_rx(const char *rx_hex, const char *expect_tx_hex); -void send_sms(struct vlr_subscr *receiver, - struct vlr_subscr *sender, - char *str); - -void thwart_rx_non_initial_requests(); - -void check_talloc(void *msgb_ctx, void *tall_bsc_ctx, int expected_blocks); - -#define EXPECT_ACCEPTED(expect_accepted) do { \ - if (g_conn) \ - OSMO_ASSERT(conn_exists(g_conn)); \ - bool accepted = msc_subscr_conn_is_accepted(g_conn); \ - fprintf(stderr, "msc_subscr_conn_is_accepted() == %s\n", \ - accepted ? "true" : "false"); \ - OSMO_ASSERT(accepted == expect_accepted); \ - } while (false) - -#define VERBOSE_ASSERT(val, expect_op, fmt) \ - do { \ - log(#val " == " fmt, (val)); \ - OSMO_ASSERT((val) expect_op); \ - } while (0); - -#define EXPECT_CONN_COUNT(N) VERBOSE_ASSERT(llist_count(&net->subscr_conns), == N, "%d") - -#define gsup_expect_tx(hex) do \ -{ \ - if (gsup_tx_expected) { \ - log("Previous expected GSUP tx was not confirmed!"); \ - OSMO_ASSERT(!gsup_tx_expected); \ - } \ - if (!hex) \ - break; \ - gsup_tx_expected = hex; \ - gsup_tx_confirmed = false; \ -} while (0) - -void fake_time_start(); - -/* as macro to get the test file's source line number */ -#define fake_time_passes(secs, usecs) do \ -{ \ - struct timeval diff; \ - osmo_gettimeofday_override_add(secs, usecs); \ - timersub(&osmo_gettimeofday_override_time, &fake_time_start_time, &diff); \ - btw("Total time passed: %d.%06d s", \ - (int)diff.tv_sec, (int)diff.tv_usec); \ - osmo_timers_prepare(); \ - osmo_timers_update(); \ -} while (0) - -extern const struct timeval fake_time_start_time; diff --git a/tests/nanobts_omlattr/Makefile.am b/tests/nanobts_omlattr/Makefile.am index b03d50cc1..050d7cd73 100644 --- a/tests/nanobts_omlattr/Makefile.am +++ b/tests/nanobts_omlattr/Makefile.am @@ -24,7 +24,6 @@ nanobts_omlattr_test_SOURCES = \ nanobts_omlattr_test_LDADD = \ $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libtrau/libtrau.a \ $(top_builddir)/src/libcommon/libcommon.a \ $(LIBOSMOCORE_LIBS) \ diff --git a/tests/nanobts_omlattr/nanobts_omlattr_test.c b/tests/nanobts_omlattr/nanobts_omlattr_test.c index ee138b8f7..96d56efab 100644 --- a/tests/nanobts_omlattr/nanobts_omlattr_test.c +++ b/tests/nanobts_omlattr/nanobts_omlattr_test.c @@ -19,7 +19,6 @@ * along with this program. If not, see . */ -#include #include #include #include diff --git a/tests/oap/Makefile.am b/tests/oap/Makefile.am deleted file mode 100644 index 1bb672d44..000000000 --- a/tests/oap/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - oap_client_test.ok \ - oap_client_test.err \ - $(NULL) - -if HAVE_LIBGTP -if HAVE_LIBCARES -noinst_PROGRAMS = \ - oap_client_test \ - $(NULL) -endif -endif - -oap_client_test_SOURCES = \ - oap_client_test.c \ - $(NULL) - -oap_client_test_LDADD = \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - -lrt - diff --git a/tests/oap/oap_client_test.c b/tests/oap/oap_client_test.c deleted file mode 100644 index e6501cb6d..000000000 --- a/tests/oap/oap_client_test.c +++ /dev/null @@ -1,270 +0,0 @@ -/* Test Osmocom Authentication Protocol */ -/* - * (C) 2015 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include - -#include -#include - -#include -#include - -static void test_oap_api(void) -{ - printf("Testing OAP API\n"); - - struct oap_client_config _config; - struct oap_client_config *config = &_config; - - struct oap_client_state _state; - struct oap_client_state *state = &_state; - - struct osmo_oap_message oap_rx; - struct msgb *msg_rx; - - struct osmo_oap_message oap_tx; - struct msgb *msg_tx; - - memset(config, 0, sizeof(*config)); - memset(state, 0, sizeof(*state)); - - OSMO_ASSERT(osmo_hexparse("0102030405060708090a0b0c0d0e0f10", config->secret_k, 16) == 16); - OSMO_ASSERT(osmo_hexparse("1112131415161718191a1b1c1d1e1f20", config->secret_opc, 16) == 16); - - fprintf(stderr, "- make sure filling with zeros means uninitialized\n"); - OSMO_ASSERT(state->state == OAP_UNINITIALIZED); - - fprintf(stderr, "- reject messages in uninitialized state\n"); - memset(&oap_rx, 0, sizeof(oap_rx)); - state->client_id = 1; - oap_rx.message_type = OAP_MSGT_REGISTER_ERROR; - msg_rx = oap_client_encoded(&oap_rx); - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0); - OSMO_ASSERT(state->state == OAP_UNINITIALIZED); - msgb_free(msg_rx); - OSMO_ASSERT(!msg_tx); - - fprintf(stderr, "- NULL config should disable\n"); - OSMO_ASSERT( oap_client_init(NULL, state) == 0 ); - OSMO_ASSERT(state->state == OAP_DISABLED); - - fprintf(stderr, "- reject messages in disabled state\n"); - memset(state, 0, sizeof(*state)); - memset(&oap_rx, 0, sizeof(oap_rx)); - state->state = OAP_DISABLED; - state->client_id = 1; - oap_rx.message_type = OAP_MSGT_REGISTER_ERROR; - msg_rx = oap_client_encoded(&oap_rx); - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0); - OSMO_ASSERT(state->state == OAP_DISABLED); - msgb_free(msg_rx); - OSMO_ASSERT(!msg_tx); - - fprintf(stderr, "- invalid client_id and shared secret\n"); - memset(state, 0, sizeof(*state)); - config->client_id = 0; - config->secret_k_present = 0; - config->secret_opc_present = 0; - OSMO_ASSERT( oap_client_init(config, state) == 0 ); - OSMO_ASSERT(state->state == OAP_DISABLED); - - fprintf(stderr, "- reset state\n"); - memset(state, 0, sizeof(*state)); - - fprintf(stderr, "- only client_id is invalid\n"); - config->client_id = 0; - config->secret_k_present = 1; - config->secret_opc_present = 1; - OSMO_ASSERT( oap_client_init(config, state) == 0 ); - OSMO_ASSERT(state->state == OAP_DISABLED); - - memset(state, 0, sizeof(*state)); - - fprintf(stderr, "- valid id, but omitted shared_secret (1/2)\n"); - config->client_id = 12345; - config->secret_k_present = 0; - config->secret_opc_present = 1; - OSMO_ASSERT( oap_client_init(config, state) == 0 ); - OSMO_ASSERT(state->state == OAP_DISABLED); - - memset(state, 0, sizeof(*state)); - - fprintf(stderr, "- valid id, but omitted shared_secret (2/2)\n"); - config->client_id = 12345; - config->secret_k_present = 1; - config->secret_opc_present = 0; - OSMO_ASSERT( oap_client_init(config, state) == 0 ); - OSMO_ASSERT(state->state == OAP_DISABLED); - - memset(state, 0, sizeof(*state)); - - - fprintf(stderr, "- mint configuration\n"); - config->client_id = 12345; - config->secret_k_present = 1; - config->secret_opc_present = 1; - /*config->secret_* buffers are still set from the top */ - OSMO_ASSERT( oap_client_init(config, state) == 0 ); - OSMO_ASSERT(state->state == OAP_INITIALIZED); - - - fprintf(stderr, "- Missing challenge data\n"); - memset(&oap_rx, 0, sizeof(oap_rx)); - oap_rx.message_type = OAP_MSGT_CHALLENGE_REQUEST; - oap_rx.rand_present = 0; - oap_rx.autn_present = 0; - msg_rx = oap_client_encoded(&oap_rx); - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2); - msgb_free(msg_rx); - OSMO_ASSERT(!msg_tx); - - fprintf(stderr, "- AUTN missing\n"); - osmo_hexparse("0102030405060708090a0b0c0d0e0f10", - oap_rx.rand, 16); - oap_rx.rand_present = 1; - msg_rx = oap_client_encoded(&oap_rx); - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2); - msgb_free(msg_rx); - OSMO_ASSERT(!msg_tx); - - fprintf(stderr, "- RAND missing\n"); - oap_rx.rand_present = 0; - osmo_hexparse("cec4e3848a33000086781158ca40f136", - oap_rx.autn, 16); - oap_rx.autn_present = 1; - msg_rx = oap_client_encoded(&oap_rx); - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2); - msgb_free(msg_rx); - OSMO_ASSERT(!msg_tx); - - fprintf(stderr, "- wrong autn (by one bit)\n"); - osmo_hexparse("0102030405060708090a0b0c0d0e0f10", - oap_rx.rand, 16); - osmo_hexparse("dec4e3848a33000086781158ca40f136", - oap_rx.autn, 16); - oap_rx.rand_present = 1; - oap_rx.autn_present = 1; - msg_rx = oap_client_encoded(&oap_rx); - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2); - msgb_free(msg_rx); - OSMO_ASSERT(!msg_tx); - - fprintf(stderr, "- all data correct\n"); - osmo_hexparse("cec4e3848a33000086781158ca40f136", - oap_rx.autn, 16); - msg_rx = oap_client_encoded(&oap_rx); - - fprintf(stderr, "- but refuse to evaluate in uninitialized state\n"); - OSMO_ASSERT(state->state == OAP_INITIALIZED); - - state->state = OAP_UNINITIALIZED; - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0); - OSMO_ASSERT(!msg_tx); - - state->state = OAP_DISABLED; - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0); - OSMO_ASSERT(!msg_tx); - - state->state = OAP_INITIALIZED; - - fprintf(stderr, "- now everything is correct\n"); - /* a successful return value here indicates correct autn */ - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == 0); - msgb_free(msg_rx); - - fprintf(stderr, "- Expect the challenge response in msg_tx\n"); - OSMO_ASSERT(msg_tx); - OSMO_ASSERT(osmo_oap_decode(&oap_tx, msg_tx->data, msg_tx->len) == 0); - OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_CHALLENGE_RESULT); - OSMO_ASSERT(strcmp("e2d05b598c61d9ba", - osmo_hexdump_nospc(oap_tx.xres, sizeof(oap_tx.xres))) - == 0); - OSMO_ASSERT(state->state == OAP_SENT_CHALLENGE_RESULT); - msgb_free(msg_tx); - msg_tx = 0; - - struct oap_client_state saved_state = _state; - - fprintf(stderr, "- Receive registration error for the first time.\n"); - - memset(&oap_rx, 0, sizeof(oap_rx)); - oap_rx.message_type = OAP_MSGT_REGISTER_ERROR; - oap_rx.cause = GMM_CAUSE_PROTO_ERR_UNSPEC; - msg_rx = oap_client_encoded(&oap_rx); - - OSMO_ASSERT(state->registration_failures == 0); - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == 0); - OSMO_ASSERT(state->registration_failures == 1); - OSMO_ASSERT(msg_tx); - OSMO_ASSERT(osmo_oap_decode(&oap_tx, msg_tx->data, msg_tx->len) == 0); - OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_REGISTER_REQUEST); - OSMO_ASSERT(state->state == OAP_REQUESTED_CHALLENGE); - msgb_free(msg_tx); - msg_tx = 0; - - fprintf(stderr, "- Receive registration error for the Nth time.\n"); - state->registration_failures = 999; - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -11); - OSMO_ASSERT(!msg_tx); - OSMO_ASSERT(state->state == OAP_INITIALIZED); - msgb_free(msg_tx); - msg_tx = 0; - - msgb_free(msg_rx); - - fprintf(stderr, "- Registration success\n"); - - _state = saved_state; - memset(&oap_rx, 0, sizeof(oap_rx)); - oap_rx.message_type = OAP_MSGT_REGISTER_RESULT; - msg_rx = oap_client_encoded(&oap_rx); - OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == 0); - OSMO_ASSERT(!msg_tx); - OSMO_ASSERT(state->state == OAP_REGISTERED); - msgb_free(msg_rx); -} - -static struct log_info_cat oap_client_test_categories[] = { -}; - -static struct log_info info = { - .cat = oap_client_test_categories, - .num_cat = ARRAY_SIZE(oap_client_test_categories), -}; - -int main(int argc, char **argv) -{ - msgb_talloc_ctx_init(NULL, 0); - osmo_init_logging(&info); - - 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_category(osmo_stderr_target, 1); - log_parse_category_mask(osmo_stderr_target, "DLOAP,1"); - - test_oap_api(); - printf("Done\n"); - - return 0; -} - diff --git a/tests/oap/oap_client_test.err b/tests/oap/oap_client_test.err deleted file mode 100644 index 62ddc9efa..000000000 --- a/tests/oap/oap_client_test.err +++ /dev/null @@ -1,35 +0,0 @@ -- make sure filling with zeros means uninitialized -- reject messages in uninitialized state -DLOAP Received OAP message 5, but the OAP client is not initialized -- NULL config should disable -- reject messages in disabled state -DLOAP Received OAP message 5, but the OAP client is disabled -- invalid client_id and shared secret -- reset state -- only client_id is invalid -- valid id, but omitted shared_secret (1/2) -DLOAP OAP: client ID set, but secret K missing. -- valid id, but omitted shared_secret (2/2) -DLOAP OAP: client ID set, but secret OPC missing. -- mint configuration -- Missing challenge data -DLOAP OAP challenge incomplete (rand_present: 0, autn_present: 0) -- AUTN missing -DLOAP OAP challenge incomplete (rand_present: 1, autn_present: 0) -- RAND missing -DLOAP OAP challenge incomplete (rand_present: 0, autn_present: 1) -- wrong autn (by one bit) -DLOAP OAP: AUTN mismatch! -DLOAP OAP: AUTN from server: dec4e3848a33000086781158ca40f136 -DLOAP OAP: AUTN expected: cec4e3848a33000086781158ca40f136 -- all data correct -- but refuse to evaluate in uninitialized state -DLOAP Received OAP message 8, but the OAP client is not initialized -DLOAP Received OAP message 8, but the OAP client is disabled -- now everything is correct -- Expect the challenge response in msg_tx -- Receive registration error for the first time. -DLOAP OAP registration failed -- Receive registration error for the Nth time. -DLOAP OAP registration failed -- Registration success diff --git a/tests/oap/oap_client_test.ok b/tests/oap/oap_client_test.ok deleted file mode 100644 index 59108a792..000000000 --- a/tests/oap/oap_client_test.ok +++ /dev/null @@ -1,2 +0,0 @@ -Testing OAP API -Done diff --git a/tests/sgsn/Makefile.am b/tests/sgsn/Makefile.am deleted file mode 100644 index ccb8f44f4..000000000 --- a/tests/sgsn/Makefile.am +++ /dev/null @@ -1,81 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBCARES_CFLAGS) \ - $(NULL) -if BUILD_IU -AM_CFLAGS += \ - $(LIBASN1C_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) \ - $(LIBOSMORANAP_CFLAGS) \ - $(NULL) -endif - -EXTRA_DIST = \ - sgsn_test.ok \ - $(NULL) - -noinst_PROGRAMS = \ - sgsn_test \ - $(NULL) - -sgsn_test_SOURCES = \ - sgsn_test.c \ - $(NULL) - -sgsn_test_LDFLAGS = \ - -Wl,--wrap=RAND_bytes \ - -Wl,--wrap=sgsn_update_subscriber_data \ - -Wl,--wrap=gprs_subscr_request_update_location \ - -Wl,--wrap=gprs_subscr_request_auth_info \ - -Wl,--wrap=gsup_client_send \ - $(NULL) - -sgsn_test_LDADD = \ - $(top_builddir)/src/gprs/gprs_llc_parse.o \ - $(top_builddir)/src/gprs/gprs_llc.o \ - $(top_builddir)/src/gprs/crc24.o \ - $(top_builddir)/src/gprs/gprs_sndcp.o \ - $(top_builddir)/src/gprs/gprs_gmm.o \ - $(top_builddir)/src/gprs/gprs_sgsn.o \ - $(top_builddir)/src/gprs/sgsn_vty.o \ - $(top_builddir)/src/gprs/sgsn_libgtp.o \ - $(top_builddir)/src/gprs/sgsn_auth.o \ - $(top_builddir)/src/gprs/sgsn_ares.o \ - $(top_builddir)/src/gprs/gprs_utils.o \ - $(top_builddir)/src/gprs/gprs_subscriber.o \ - $(top_builddir)/src/gprs/gprs_gb_parse.o \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ - $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ - $(top_builddir)/src/gprs/slhc.o \ - $(top_builddir)/src/gprs/gprs_sndcp_comp.o \ - $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \ - $(top_builddir)/src/gprs/v42bis.o \ - $(top_builddir)/src/gprs/gprs_sndcp_dcomp.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOGB_LIBS) \ - $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) \ - $(LIBGTP_LIBS) \ - -lrt \ - -lm \ - $(NULL) - -if BUILD_IU -sgsn_test_LDADD += \ - $(LIBOSMORANAP_LIBS) \ - $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBASN1C_LIBS) \ - $(NULL) -endif diff --git a/tests/sgsn/sgsn_test.c b/tests/sgsn/sgsn_test.c deleted file mode 100644 index d66c5dd84..000000000 --- a/tests/sgsn/sgsn_test.c +++ /dev/null @@ -1,2487 +0,0 @@ -/* Test the SGSN */ -/* - * (C) 2014 by Holger Hans Peter Freyther - * (C) 2014 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include - -#include - -void *tall_bsc_ctx; -static struct sgsn_instance sgsn_inst = { - .config_file = "osmo_sgsn.cfg", - .cfg = { - .gtp_statedir = "./", - .auth_policy = SGSN_AUTH_POLICY_CLOSED, - }, -}; -struct sgsn_instance *sgsn = &sgsn_inst; -unsigned sgsn_tx_counter = 0; -struct msgb *last_msg = NULL; -struct gprs_gb_parse_context last_dl_parse_ctx; - -static void reset_last_msg() -{ - if (last_msg) - msgb_free(last_msg); - - last_msg = NULL; - memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx)); -} - -static void cleanup_test() -{ - reset_last_msg(); -} - -static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx) -{ - uint32_t new_ptmsi = GSM_RESERVED_TMSI; - - if (parse_ctx->new_ptmsi_enc) - gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi); - - return new_ptmsi; -} - -/* override */ -int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime, - struct bssgp_dl_ud_par *dup) -{ - int rc; - - reset_last_msg(); - - last_msg = msg; - OSMO_ASSERT(msgb_data(last_msg) != NULL); - - rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg), - &last_dl_parse_ctx); - - fprintf(stderr, "Got DL LLC message: %s\n", - gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN")); - - OSMO_ASSERT(rc > 0); - - sgsn_tx_counter += 1; - return 0; -} - -/* override, requires '-Wl,--wrap=RAND_bytes' */ -int __real_RAND_bytes(unsigned char *buf, int num); -int mock_RAND_bytes(unsigned char *buf, int num); -int (*RAND_bytes_cb)(unsigned char *, int) = - &mock_RAND_bytes; - -int __wrap_RAND_bytes(unsigned char *buf, int num) -{ - return (*RAND_bytes_cb)(buf, num); -} -/* make results of A&C ref predictable */ -int mock_RAND_bytes(unsigned char *buf, int num) -{ - if (num > 1) - return __real_RAND_bytes(buf, num); - buf[0] = 0; - return 1; -} - -/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */ -void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *); -void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) = - &__real_sgsn_update_subscriber_data; - -void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx) -{ - (*update_subscriber_data_cb)(mmctx); -} - -/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */ -int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx); -int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) = - &__real_gprs_subscr_request_update_location; - -int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) { - return (*subscr_request_update_location_cb)(mmctx); -}; - -/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */ -int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand); -int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand) = - &__real_gprs_subscr_request_auth_info; - -int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand) { - return (*subscr_request_auth_info_cb)(mmctx, auts, auts_rand); -}; - -/* override, requires '-Wl,--wrap=gsup_client_send' */ -int __real_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg); -int (*gsup_client_send_cb)(struct gsup_client *gsupc, struct msgb *msg) = - &__real_gsup_client_send; - -int __wrap_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg) -{ - return (*gsup_client_send_cb)(gsupc, msg); -}; - -static int count(struct llist_head *head) -{ - struct llist_head *cur; - int count = 0; - - llist_for_each(cur, head) - count += 1; - - return count; -} - -static struct msgb *create_msg(const uint8_t *data, size_t len) -{ - struct msgb *msg = msgb_alloc(len + 8, "test message"); - msg->l1h = msgb_put(msg, 8); - msg->l2h = msgb_put(msg, len); - memcpy(msg->l2h, data, len); - - msgb_bcid(msg) = msg->l1h; - msgb_gmmh(msg) = msg->l2h; - return msg; -} - -/* - * Create a context and search for it - */ -static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid) -{ - struct sgsn_mm_ctx *ctx, *ictx; - struct gprs_llc_lle *lle; - int old_count = count(gprs_llme_list()); - - lle = gprs_lle_get_or_create(tlli, 3); - ctx = sgsn_mm_ctx_alloc_gb(tlli, raid); - ctx->gmm_state = GMM_REGISTERED_NORMAL; - ctx->gb.llme = lle->llme; - - ictx = sgsn_mm_ctx_by_tlli(tlli, raid); - OSMO_ASSERT(ictx == ctx); - - OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1); - - return ctx; -} - -static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli, - const struct gprs_ra_id *bssgp_raid, - const uint8_t *data, size_t data_len) -{ - struct msgb *msg; - - reset_last_msg(); - sgsn_tx_counter = 0; - - msg = create_msg(data, data_len); - msgb_tlli(msg) = tlli; - bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0); - gsm0408_gprs_rcvmsg_gb(msg, llme, false); - msgb_free(msg); -} - -static void test_llme(void) -{ - struct gprs_llc_lle *lle, *lle_copy; - uint32_t local_tlli; - - printf("Testing LLME allocations\n"); - local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL); - - /* initial state */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - - /* Create a new entry */ - lle = gprs_lle_get_or_create(local_tlli, 3); - OSMO_ASSERT(lle); - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* No new entry is created */ - lle_copy = gprs_lle_get_or_create(local_tlli, 3); - OSMO_ASSERT(lle == lle_copy); - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* unassign which should delete it*/ - gprs_llgmm_unassign(lle->llme); - - /* Check that everything was cleaned up */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - - cleanup_test(); -} - -struct gprs_subscr *last_updated_subscr = NULL; -void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx) -{ - OSMO_ASSERT(mmctx); - fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n", - __func__, mmctx, mmctx->subscr); - last_updated_subscr = mmctx->subscr; -} - -static void assert_subscr(const struct gprs_subscr *subscr, const char *imsi) -{ - struct gprs_subscr *sfound; - OSMO_ASSERT(subscr); - OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0); - - sfound = gprs_subscr_get_by_imsi(imsi); - OSMO_ASSERT(sfound == subscr); - - gprs_subscr_put(sfound); -} - -static void show_subscrs(FILE *out) -{ - struct gprs_subscr *subscr; - - llist_for_each_entry(subscr, gprs_subscribers, entry) { - fprintf(out, " Subscriber: %s, " - "use count: %d\n", - subscr->imsi, subscr->use_count); - } -} - -static void assert_no_subscrs() -{ - show_subscrs(stdout); - fflush(stdout); - OSMO_ASSERT(llist_empty(gprs_subscribers)); -} - -#define VERBOSE_ASSERT(val, expect_op, fmt) \ - do { \ - printf(#val " == " fmt "\n", (val)); \ - OSMO_ASSERT((val) expect_op); \ - } while (0); - -static void test_subscriber(void) -{ - struct gprs_subscr *s1, *s2, *s3; - const char *imsi1 = "1234567890"; - const char *imsi2 = "9876543210"; - const char *imsi3 = "5656565656"; - - update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data; - - printf("Testing core subscriber data API\n"); - - /* Check for emptiness */ - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL); - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL); - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL); - VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d"); - - /* Allocate entry 1 */ - s1 = gprs_subscr_get_or_create(imsi1); - VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d"); - s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; - assert_subscr(s1, imsi1); - VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d"); - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL); - - /* Allocate entry 2 */ - s2 = gprs_subscr_get_or_create(imsi2); - VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d"); - s2->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; - - /* Allocate entry 3 */ - s3 = gprs_subscr_get_or_create(imsi3); - VERBOSE_ASSERT(llist_count(gprs_subscribers), == 3, "%d"); - - /* Check entries */ - assert_subscr(s1, imsi1); - assert_subscr(s2, imsi2); - assert_subscr(s3, imsi3); - - /* Update entry 1 */ - last_updated_subscr = NULL; - gprs_subscr_update(s1); - OSMO_ASSERT(last_updated_subscr == NULL); - OSMO_ASSERT(s1->sgsn_data->mm == NULL); - OSMO_ASSERT((s1->flags & GPRS_SUBSCRIBER_FIRST_CONTACT) == 0); - - /* There is no subscriber cache. Verify it */ - gprs_subscr_cleanup(s1); - gprs_subscr_put(s1); - s1 = NULL; - VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d"); - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL); - - assert_subscr(s2, imsi2); - assert_subscr(s3, imsi3); - - /* Free entry 2 (GPRS_SUBSCRIBER_FIRST_CONTACT is set) */ - gprs_subscr_cleanup(s2); - gprs_subscr_put(s2); - s2 = NULL; - VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d"); - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL); - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL); - assert_subscr(s3, imsi3); - - /* Try to delete entry 3 */ - gprs_subscr_cleanup(s3); - gprs_subscr_put(s3); - s3 = NULL; - VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d"); - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL); - - OSMO_ASSERT(llist_empty(gprs_subscribers)); - - update_subscriber_data_cb = __real_sgsn_update_subscriber_data; - - cleanup_test(); -} - -static void test_auth_triplets(void) -{ - struct gprs_subscr *s1, *s1found; - const char *imsi1 = "1234567890"; - struct gsm_auth_tuple *at; - struct sgsn_mm_ctx *ctx; - struct gprs_ra_id raid = { 0, }; - uint32_t local_tlli = 0xffeeddcc; - - printf("Testing authentication triplet handling\n"); - - /* Check for emptiness */ - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL); - - /* Allocate entry 1 */ - s1 = gprs_subscr_get_or_create(imsi1); - s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; - s1found = gprs_subscr_get_by_imsi(imsi1); - OSMO_ASSERT(s1found == s1); - gprs_subscr_put(s1found); - - /* Create a context */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ctx = alloc_mm_ctx(local_tlli, &raid); - - /* Attach s1 to ctx */ - ctx->subscr = gprs_subscr_get(s1); - ctx->subscr->sgsn_data->mm = ctx; - - /* Try to get auth tuple */ - at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL); - OSMO_ASSERT(at == NULL); - - /* Add triplets */ - s1->sgsn_data->auth_triplets[0].key_seq = 0; - s1->sgsn_data->auth_triplets[1].key_seq = 1; - s1->sgsn_data->auth_triplets[2].key_seq = 2; - - /* Try to get auth tuple */ - at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL); - OSMO_ASSERT(at != NULL); - OSMO_ASSERT(at->key_seq == 0); - OSMO_ASSERT(at->use_count == 1); - at = sgsn_auth_get_tuple(ctx, at->key_seq); - OSMO_ASSERT(at != NULL); - OSMO_ASSERT(at->key_seq == 1); - OSMO_ASSERT(at->use_count == 1); - at = sgsn_auth_get_tuple(ctx, at->key_seq); - OSMO_ASSERT(at != NULL); - OSMO_ASSERT(at->key_seq == 2); - OSMO_ASSERT(at->use_count == 1); - at = sgsn_auth_get_tuple(ctx, at->key_seq); - OSMO_ASSERT(at == NULL); - - /* Free MM context and subscriber */ - gprs_subscr_put(s1); - sgsn_mm_ctx_cleanup_free(ctx); - s1found = gprs_subscr_get_by_imsi(imsi1); - OSMO_ASSERT(s1found == NULL); - - cleanup_test(); -} - -#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09 - -static int rx_gsup_message(const uint8_t *data, size_t data_len) -{ - struct msgb *msg; - int rc; - - msg = msgb_alloc(1024, __func__); - msg->l2h = msgb_put(msg, data_len); - OSMO_ASSERT(msg->l2h != NULL); - memcpy(msg->l2h, data, data_len); - rc = gprs_subscr_rx_gsup_message(msg); - msgb_free(msg); - - return rc; -} - -static void test_subscriber_gsup(void) -{ - struct gprs_subscr *s1, *s1found; - const char *imsi1 = "1234567890"; - struct sgsn_mm_ctx *ctx; - struct gprs_ra_id raid = { 0, }; - uint32_t local_tlli = 0xffeeddcc; - struct sgsn_subscriber_pdp_data *pdpd; - int rc; - - static const uint8_t send_auth_info_res[] = { - 0x0a, - TEST_GSUP_IMSI1_IE, - 0x03, 0x22, /* Auth tuple */ - 0x20, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x21, 0x04, - 0x21, 0x22, 0x23, 0x24, - 0x22, 0x08, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x03, 0x22, /* Auth tuple */ - 0x20, 0x10, - 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, - 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, - 0x21, 0x04, - 0xa1, 0xa2, 0xa3, 0xa4, - 0x22, 0x08, - 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, - }; - - static const uint8_t send_auth_info_err[] = { - 0x09, - TEST_GSUP_IMSI1_IE, - 0x02, 0x01, 0x07 /* GPRS not allowed */ - }; - -#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 - - static const uint8_t s1_msisdn[] = { MSISDN }; - - static const uint8_t update_location_res[] = { - 0x06, - TEST_GSUP_IMSI1_IE, - 0x08, 0x09, MSISDN, - 0x04, 0x00, /* PDP info complete */ - 0x05, 0x12, - 0x10, 0x01, 0x01, - 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ - 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n', - 0x05, 0x11, - 0x10, 0x01, 0x02, - 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ - 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n', - }; - -#undef MSISDN - - static const uint8_t update_location_err[] = { - 0x05, - TEST_GSUP_IMSI1_IE, - 0x02, 0x01, 0x07 /* GPRS not allowed */ - }; - - static const uint8_t location_cancellation_req[] = { - 0x1c, - TEST_GSUP_IMSI1_IE, - 0x06, 0x01, 0x00, - }; - - static const uint8_t location_cancellation_req_withdraw[] = { - 0x1c, - TEST_GSUP_IMSI1_IE, - 0x06, 0x01, 0x01, - }; - - static const uint8_t location_cancellation_req_other[] = { - 0x1c, - 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01, - 0x06, 0x01, 0x00, - }; - - static const uint8_t purge_ms_err[] = { - 0x0d, - TEST_GSUP_IMSI1_IE, - 0x02, 0x01, 0x02, /* IMSI unknown in HLR */ - }; - - static const uint8_t purge_ms_err_no_cause[] = { - 0x0d, - TEST_GSUP_IMSI1_IE, - }; - - static const uint8_t purge_ms_res[] = { - 0x0e, - TEST_GSUP_IMSI1_IE, - 0x07, 0x00, - }; - - - static const uint8_t insert_data_req[] = { - 0x10, - TEST_GSUP_IMSI1_IE, - 0x05, 0x11, - 0x10, 0x01, 0x03, - 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ - 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n', - }; - - static const uint8_t delete_data_req[] = { - 0x14, - TEST_GSUP_IMSI1_IE, - 0x10, 0x01, 0x03, - }; - - printf("Testing subscriber GSUP handling\n"); - - update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data; - - /* Check for emptiness */ - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL); - - /* Allocate entry 1 */ - s1 = gprs_subscr_get_or_create(imsi1); - s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; - s1found = gprs_subscr_get_by_imsi(imsi1); - OSMO_ASSERT(s1found == s1); - gprs_subscr_put(s1found); - - /* Create a context */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ctx = alloc_mm_ctx(local_tlli, &raid); - - /* Attach s1 to ctx */ - ctx->subscr = gprs_subscr_get(s1); - ctx->subscr->sgsn_data->mm = ctx; - - /* Inject SendAuthInfoReq GSUP message */ - rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res)); - OSMO_ASSERT(rc >= 0); - OSMO_ASSERT(last_updated_subscr == s1); - - /* Check triplets */ - OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0); - OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1); - OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL); - - /* Inject SendAuthInfoErr GSUP message */ - rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err)); - OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED); - OSMO_ASSERT(last_updated_subscr == s1); - OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED); - - /* Check triplets */ - OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL); - OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL); - OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL); - - /* Inject UpdateLocRes GSUP message */ - rc = rx_gsup_message(update_location_res, sizeof(update_location_res)); - OSMO_ASSERT(rc >= 0); - OSMO_ASSERT(last_updated_subscr == s1); - OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE); - OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE); - OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn)); - OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0); - OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list)); - pdpd = llist_entry(s1->sgsn_data->pdp_list.next, - struct sgsn_subscriber_pdp_data, list); - OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0); - pdpd = llist_entry(pdpd->list.next, - struct sgsn_subscriber_pdp_data, list); - OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0); - - /* Check authorization */ - OSMO_ASSERT(s1->authorized == 1); - - /* Inject UpdateLocErr GSUP message */ - rc = rx_gsup_message(update_location_err, sizeof(update_location_err)); - OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED); - OSMO_ASSERT(last_updated_subscr == s1); - OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED); - - /* Check authorization */ - OSMO_ASSERT(s1->authorized == 0); - - /* Inject InsertSubscrData GSUP message */ - last_updated_subscr = NULL; - rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req)); - OSMO_ASSERT(rc == -ENOTSUP); /* not connected */ - OSMO_ASSERT(last_updated_subscr == s1); - - /* Inject DeleteSubscrData GSUP message */ - last_updated_subscr = NULL; - rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req)); - if (rc != -GMM_CAUSE_SEM_INCORR_MSG) - printf("Unexpected response to DSD: %d\n", rc); - OSMO_ASSERT(last_updated_subscr == NULL); - - /* Inject wrong LocCancelReq GSUP message */ - last_updated_subscr = NULL; - rc = rx_gsup_message(location_cancellation_req_other, - sizeof(location_cancellation_req_other)); - OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN); - OSMO_ASSERT(last_updated_subscr == NULL); - - /* Check cancellation result */ - OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED)); - OSMO_ASSERT(s1->sgsn_data->mm != NULL); - - /* Inject LocCancelReq GSUP message */ - rc = rx_gsup_message(location_cancellation_req, - sizeof(location_cancellation_req)); - OSMO_ASSERT(rc >= 0); - OSMO_ASSERT(last_updated_subscr == s1); - OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE); - - /* Check cancellation result */ - OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED); - OSMO_ASSERT(s1->sgsn_data->mm == NULL); - - /* Inject LocCancelReq(withdraw) GSUP message */ - rc = rx_gsup_message(location_cancellation_req_withdraw, - sizeof(location_cancellation_req_withdraw)); - OSMO_ASSERT(rc >= 0); - OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED); - - /* Inject PurgeMsRes GSUP message */ - rc = rx_gsup_message(purge_ms_res, - sizeof(purge_ms_res)); - OSMO_ASSERT(rc >= 0); - OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE)); - - /* Free MM context and subscriber */ - OSMO_ASSERT(ctx->subscr == NULL); - sgsn_mm_ctx_cleanup_free(ctx); - gprs_subscr_put(s1); - s1found = gprs_subscr_get_by_imsi(imsi1); - OSMO_ASSERT(s1found == NULL); - - /* Inject PurgeMsRes GSUP message */ - rc = rx_gsup_message(purge_ms_res, - sizeof(purge_ms_res)); - OSMO_ASSERT(rc >= 0); - - /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */ - rc = rx_gsup_message(purge_ms_err, - sizeof(purge_ms_err)); - OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN); - - /* Inject PurgeMsErr() GSUP message */ - rc = rx_gsup_message(purge_ms_err_no_cause, - sizeof(purge_ms_err_no_cause)); - OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL); - - /* Inject InsertSubscrData GSUP message (unknown IMSI) */ - last_updated_subscr = NULL; - rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req)); - OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN); - OSMO_ASSERT(last_updated_subscr == NULL); - - /* Inject DeleteSubscrData GSUP message (unknown IMSI) */ - rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req)); - OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN); - OSMO_ASSERT(last_updated_subscr == NULL); - - /* Inject LocCancelReq GSUP message (unknown IMSI) */ - rc = rx_gsup_message(location_cancellation_req, - sizeof(location_cancellation_req)); - OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN); - OSMO_ASSERT(last_updated_subscr == NULL); - - update_subscriber_data_cb = __real_sgsn_update_subscriber_data; - - cleanup_test(); -} - -int my_gsup_client_send_dummy(struct gsup_client *gsupc, struct msgb *msg) -{ - msgb_free(msg); - return 0; -}; - -/* - * Test that a GMM Detach will remove the MMCTX and the - * associated LLME. - */ -static void test_gmm_detach(void) -{ - struct gprs_ra_id raid = { 0, }; - struct sgsn_mm_ctx *ctx, *ictx; - uint32_t local_tlli; - - printf("Testing GMM detach\n"); - - /* DTAP - Detach Request (MO) */ - /* normal detach, power_off = 0 */ - static const unsigned char detach_req[] = { - 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2, - 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb - }; - - local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL); - - /* Create a context */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ctx = alloc_mm_ctx(local_tlli, &raid); - - /* inject the detach */ - send_0408_message(ctx->gb.llme, local_tlli, &raid, - detach_req, ARRAY_SIZE(detach_req)); - - /* verify that a single message (hopefully the Detach Accept) has been - * sent by the SGSN */ - OSMO_ASSERT(sgsn_tx_counter == 1); - - /* verify that things are gone */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid); - OSMO_ASSERT(!ictx); - - cleanup_test(); -} - -/* - * Test that a GMM Detach will remove the MMCTX and the associated LLME but - * will not sent a Detach Accept message (power_off = 1) - */ -static void test_gmm_detach_power_off(void) -{ - struct gprs_ra_id raid = { 0, }; - struct sgsn_mm_ctx *ctx, *ictx; - uint32_t local_tlli; - - printf("Testing GMM detach (power off)\n"); - - /* DTAP - Detach Request (MO) */ - /* normal detach, power_off = 1 */ - static const unsigned char detach_req[] = { - 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2, - 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb - }; - - local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL); - - /* Create a context */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ctx = alloc_mm_ctx(local_tlli, &raid); - - /* inject the detach */ - send_0408_message(ctx->gb.llme, local_tlli, &raid, - detach_req, ARRAY_SIZE(detach_req)); - - /* verify that no message (and therefore no Detach Accept) has been - * sent by the SGSN */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - /* verify that things are gone */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid); - OSMO_ASSERT(!ictx); - - cleanup_test(); -} - -/* - * Test that a GMM Detach will remove the associated LLME if there is no MMCTX. - */ -static void test_gmm_detach_no_mmctx(void) -{ - struct gprs_ra_id raid = { 0, }; - struct gprs_llc_lle *lle; - uint32_t local_tlli; - - printf("Testing GMM detach (no MMCTX)\n"); - - /* DTAP - Detach Request (MO) */ - /* normal detach, power_off = 0 */ - static const unsigned char detach_req[] = { - 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2, - 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb - }; - - /* Create an LLME */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL); - lle = gprs_lle_get_or_create(local_tlli, 3); - - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* inject the detach */ - send_0408_message(lle->llme, local_tlli, &raid, - detach_req, ARRAY_SIZE(detach_req)); - - /* verify that the LLME is gone */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - - cleanup_test(); -} - -/* - * Test that a single GMM Detach Accept message will not cause the SGSN to send - * any message or leave an MM context at the SGSN. - */ -static void test_gmm_detach_accept_unexpected(void) -{ - struct gprs_ra_id raid = { 0, }; - struct gprs_llc_lle *lle; - uint32_t local_tlli; - - printf("Testing GMM detach accept (unexpected)\n"); - - /* DTAP - Detach Accept (MT) */ - /* normal detach */ - static const unsigned char detach_acc[] = { - 0x08, 0x06 - }; - - /* Create an LLME */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL); - lle = gprs_lle_get_or_create(local_tlli, 3); - - /* inject the detach */ - send_0408_message(lle->llme, local_tlli, &raid, - detach_acc, ARRAY_SIZE(detach_acc)); - - /* verify that no message (and therefore no Status or XID reset) has been - * sent by the SGSN */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - /* verify that things are gone */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - - cleanup_test(); -} - -/* - * Test that a GMM Status will remove the associated LLME if there is no MMCTX. - */ -static void test_gmm_status_no_mmctx(void) -{ - struct gprs_ra_id raid = { 0, }; - struct gprs_llc_lle *lle; - uint32_t local_tlli; - - printf("Testing GMM Status (no MMCTX)\n"); - - /* DTAP - GMM Status, protocol error */ - static const unsigned char gmm_status[] = { - 0x08, 0x20, 0x6f - }; - - /* Create an LLME */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL); - lle = gprs_lle_get_or_create(local_tlli, 3); - - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* inject the detach */ - send_0408_message(lle->llme, local_tlli, &raid, - gmm_status, ARRAY_SIZE(gmm_status)); - - /* verify that no message has been sent by the SGSN */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - /* verify that the LLME is gone */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - - cleanup_test(); -} - -/* - * Test the GMM Attach procedure - */ -static void test_gmm_attach(int retry) -{ - struct gprs_ra_id raid = { 0, }; - struct sgsn_mm_ctx *ctx = NULL; - struct sgsn_mm_ctx *ictx; - uint32_t ptmsi1; - uint32_t foreign_tlli; - uint32_t local_tlli = 0; - struct gprs_llc_lle *lle; - - /* DTAP - Attach Request */ - /* The P-TMSI is not known by the SGSN */ - static const unsigned char attach_req[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4, - 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, - 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, - 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8, - 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00 - }; - - /* DTAP - Identity Response IMEI */ - static const unsigned char ident_resp_imei[] = { - 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, - 0x56 - }; - - /* DTAP - Identity Response IMSI */ - static const unsigned char ident_resp_imsi[] = { - 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32, - 0x54 - }; - - /* DTAP - Authentication and Ciphering Resp */ - static const unsigned char auth_ciph_resp[] = { - 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09, - 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01 - }; - - /* DTAP - Attach Complete */ - static const unsigned char attach_compl[] = { - 0x08, 0x03 - }; - - /* DTAP - Detach Request (MO) */ - /* normal detach, power_off = 0 */ - static const unsigned char detach_req[] = { - 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b, - 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb - }; - - printf("Testing GMM attach%s\n", retry ? " with retry" : ""); - - foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN); - - /* Create a LLE/LLME */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - lle = gprs_lle_get_or_create(foreign_tlli, 3); - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* inject the attach request */ - send_0408_message(lle->llme, foreign_tlli, &raid, - attach_req, ARRAY_SIZE(attach_req)); - - ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid); - OSMO_ASSERT(ctx != NULL); - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - - /* we expect an identity request (IMEI) */ - OSMO_ASSERT(sgsn_tx_counter == 1); - - /* inject the identity response (IMEI) */ - send_0408_message(ctx->gb.llme, foreign_tlli, &raid, - ident_resp_imei, ARRAY_SIZE(ident_resp_imei)); - - /* we expect an identity request (IMSI) */ - OSMO_ASSERT(sgsn_tx_counter == 1); - - /* inject the identity response (IMSI) */ - send_0408_message(ctx->gb.llme, foreign_tlli, &raid, - ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi)); - - /* check that the MM context has not been removed due to a failed - * authorization */ - OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid)); - - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - -retry_attach_req: - - if (retry && sgsn_tx_counter == 0) { - fprintf(stderr, "Retrying attach request\n"); - /* re-inject the attach request */ - send_0408_message(lle->llme, foreign_tlli, &raid, - attach_req, ARRAY_SIZE(attach_req)); - } - - if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) { - /* we got an auth & ciph request */ - - /* inject the auth & ciph response */ - send_0408_message(ctx->gb.llme, foreign_tlli, &raid, - auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp)); - - /* check that the MM context has not been removed due to a - * failed authorization */ - OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid)); - if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0) - OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0); - } - - if (retry && sgsn_tx_counter == 0) - goto retry_attach_req; - - /* we expect an attach accept/reject */ - OSMO_ASSERT(sgsn_tx_counter == 1); - ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI); - - /* this has been randomly assigned by the SGSN */ - local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); - - /* inject the attach complete */ - send_0408_message(ctx->gb.llme, local_tlli, &raid, - attach_compl, ARRAY_SIZE(attach_compl)); - - OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL); - - /* we don't expect a response */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - /* inject the detach */ - send_0408_message(ctx->gb.llme, local_tlli, &raid, - detach_req, ARRAY_SIZE(detach_req)); - - /* verify that things are gone */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid); - OSMO_ASSERT(!ictx); - - cleanup_test(); -} - -static void test_gmm_attach_acl(void) -{ - const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - - sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED; - sgsn_acl_add("123456789012345", &sgsn->cfg); - printf("Auth policy 'closed': "); - test_gmm_attach(0); - sgsn_acl_del("123456789012345", &sgsn->cfg); - - sgsn->cfg.auth_policy = saved_auth_policy; - - cleanup_test(); -} - -int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) { - int rc; - rc = __real_gprs_subscr_request_update_location(mmctx); - if (rc == -ENOTSUP) { - OSMO_ASSERT(mmctx->subscr); - gprs_subscr_update(mmctx->subscr); - } - return rc; -}; - -int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) { - gprs_subscr_update(mmctx->subscr); - return 0; -}; - -static void test_gmm_attach_subscr(void) -{ - const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gprs_subscr *subscr; - - sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; - subscr_request_update_location_cb = my_subscr_request_update_location; - subscr_request_auth_info_cb = my_subscr_request_auth_info; - - subscr = gprs_subscr_get_or_create("123456789012345"); - subscr->authorized = 1; - - printf("Auth policy 'remote': "); - test_gmm_attach(0); - gprs_subscr_put(subscr); - assert_no_subscrs(); - - sgsn->cfg.auth_policy = saved_auth_policy; - subscr_request_update_location_cb = __real_gprs_subscr_request_update_location; - subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info; - - cleanup_test(); -} - -int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx) -{ - /* Fake an authentication */ - OSMO_ASSERT(mmctx->subscr); - mmctx->is_authenticated = 1; - gprs_subscr_update_auth_info(mmctx->subscr); - - return 0; -}; - -static void test_gmm_attach_subscr_fake_auth(void) -{ - const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gprs_subscr *subscr; - - sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; - subscr_request_update_location_cb = my_subscr_request_update_location; - subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth; - - subscr = gprs_subscr_get_or_create("123456789012345"); - subscr->authorized = 1; - sgsn->cfg.require_authentication = 1; - sgsn->cfg.require_update_location = 1; - - printf("Auth policy 'remote', auth faked: "); - test_gmm_attach(0); - gprs_subscr_put(subscr); - assert_no_subscrs(); - - sgsn->cfg.auth_policy = saved_auth_policy; - subscr_request_update_location_cb = __real_gprs_subscr_request_update_location; - subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info; - - cleanup_test(); -} - -int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand) -{ - struct gsm_auth_tuple at = { - .vec.sres = {0x51, 0xe5, 0x51, 0xe5}, - .vec.auth_types = OSMO_AUTH_TYPE_GSM, - .key_seq = 0 - }; - - /* Fake an authentication */ - OSMO_ASSERT(mmctx->subscr); - mmctx->subscr->sgsn_data->auth_triplets[0] = at; - - gprs_subscr_update_auth_info(mmctx->subscr); - - return 0; -}; - -static void test_gmm_attach_subscr_real_auth(void) -{ - const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gprs_subscr *subscr; - - sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; - subscr_request_update_location_cb = my_subscr_request_update_location; - subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth; - - subscr = gprs_subscr_get_or_create("123456789012345"); - subscr->authorized = 1; - sgsn->cfg.require_authentication = 1; - sgsn->cfg.require_update_location = 1; - - printf("Auth policy 'remote', triplet based auth: "); - - test_gmm_attach(0); - gprs_subscr_put(subscr); - assert_no_subscrs(); - - sgsn->cfg.auth_policy = saved_auth_policy; - subscr_request_update_location_cb = __real_gprs_subscr_request_update_location; - subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info; - - cleanup_test(); -} - -#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \ - 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5 - -static int auth_info_skip = 0; -static int upd_loc_skip = 0; - -int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx) -{ - static const uint8_t send_auth_info_res[] = { - 0x0a, - TEST_GSUP_IMSI_LONG_IE, - 0x03, 0x22, /* Auth tuple */ - 0x20, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x21, 0x04, - 0x51, 0xe5, 0x51, 0xe5, - 0x22, 0x08, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - }; - - OSMO_ASSERT(!mmctx || mmctx->subscr); - - if (auth_info_skip > 0) { - auth_info_skip -= 1; - return -EAGAIN; - } - - /* Fake an SendAuthInfoRes */ - rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res)); - - return 0; -}; - -int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) { - static const uint8_t update_location_res[] = { - 0x06, - TEST_GSUP_IMSI_LONG_IE, - 0x04, 0x00, /* PDP info complete */ - 0x05, 0x12, - 0x10, 0x01, 0x01, - 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ - 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n', - 0x08, 0x07, /* MSISDN 49166213323 encoded */ - 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3, - 0x09, 0x07, /* MSISDN 38166213323 encoded */ - 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3, - }; - - OSMO_ASSERT(!mmctx || mmctx->subscr); - - if (upd_loc_skip > 0) { - upd_loc_skip -= 1; - return -EAGAIN; - } - - /* Fake an UpdateLocRes */ - return rx_gsup_message(update_location_res, sizeof(update_location_res)); -}; - - -static void test_gmm_attach_subscr_gsup_auth(int retry) -{ - const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gprs_subscr *subscr; - - sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; - subscr_request_update_location_cb = my_subscr_request_update_gsup_auth; - subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth; - if (retry) { - upd_loc_skip = 3; - auth_info_skip = 3; - } - - subscr = gprs_subscr_get_or_create("123456789012345"); - subscr->authorized = 1; - sgsn->cfg.require_authentication = 1; - sgsn->cfg.require_update_location = 1; - gprs_subscr_put(subscr); - - printf("Auth policy 'remote', GSUP based auth: "); - test_gmm_attach(retry); - assert_no_subscrs(); - - sgsn->cfg.auth_policy = saved_auth_policy; - subscr_request_update_location_cb = __real_gprs_subscr_request_update_location; - subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info; - upd_loc_skip = 0; - auth_info_skip = 0; - - cleanup_test(); -} - -int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg) -{ - struct osmo_gsup_message to_peer = {0}; - struct osmo_gsup_message from_peer = {0}; - struct msgb *reply_msg; - int rc; - - /* Simulate the GSUP peer */ - rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer); - OSMO_ASSERT(rc >= 0); - OSMO_ASSERT(to_peer.imsi[0] != 0); - osmo_strlcpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi)); - - /* This invalidates the pointers in to_peer */ - msgb_free(msg); - - switch (to_peer.message_type) { - case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: - /* Send UPDATE_LOCATION_RESULT */ - return my_subscr_request_update_gsup_auth(NULL); - - case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: - /* Send SEND_AUTH_INFO_RESULT */ - return my_subscr_request_auth_info_gsup_auth(NULL); - - case OSMO_GSUP_MSGT_PURGE_MS_REQUEST: - from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT; - break; - - default: - if ((to_peer.message_type & 0b00000011) == 0) { - /* Unhandled request */ - /* Send error(NOT_IMPL) */ - from_peer.message_type = to_peer.message_type + 1; - from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; - break; - } - - /* Ignore it */ - return 0; - } - - reply_msg = gsup_client_msgb_alloc(); - reply_msg->l2h = reply_msg->data; - osmo_gsup_encode(reply_msg, &from_peer); - gprs_subscr_rx_gsup_message(reply_msg); - msgb_free(reply_msg); - - return 0; -}; - -static void test_gmm_attach_subscr_real_gsup_auth(int retry) -{ - const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gprs_subscr *subscr; - - sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; - gsup_client_send_cb = my_gsup_client_send; - - sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gsup_client); - - if (retry) { - upd_loc_skip = 3; - auth_info_skip = 3; - } - - printf("Auth policy 'remote', real GSUP based auth: "); - test_gmm_attach(retry); - - subscr = gprs_subscr_get_by_imsi("123456789012345"); - OSMO_ASSERT(subscr == NULL); - assert_no_subscrs(); - - sgsn->cfg.auth_policy = saved_auth_policy; - gsup_client_send_cb = __real_gsup_client_send; - upd_loc_skip = 0; - auth_info_skip = 0; - talloc_free(sgsn->gsup_client); - sgsn->gsup_client = NULL; - - cleanup_test(); -} - -/* - * Test the GMM Rejects - */ -static void test_gmm_reject(void) -{ - struct gprs_ra_id raid = { 0, }; - struct sgsn_mm_ctx *ctx = NULL; - uint32_t foreign_tlli; - struct gprs_llc_lle *lle; - int idx; - - /* DTAP - Attach Request */ - /* Invalid MI length */ - static const unsigned char attach_req_inv_mi_len[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4, - 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22, - 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, - 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, - 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00 - }; - - /* DTAP - Attach Request */ - /* Invalid MI type (IMEI) */ - static const unsigned char attach_req_inv_mi_type[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2, - 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, - 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, - 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8, - 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00 - }; - - /* DTAP - Routing Area Update Request */ - static const unsigned char dtap_ra_upd_req[] = { - 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, - 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, - 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, - 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, - 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, - 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, - 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 - }; - - /* DTAP - Routing Area Update Request */ - /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */ - static const unsigned char dtap_ra_upd_req_inv_type[] = { - 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50, - 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, - 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, - 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, - 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, - 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, - 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 - }; - - /* DTAP - Routing Area Update Request */ - /* Invalid cap length */ - static const unsigned char dtap_ra_upd_req_inv_cap_len[] = { - 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, - 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, - 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, - 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, - 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, - 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 - }; - - struct test { - const char *title; - const unsigned char *msg; - unsigned msg_len; - unsigned num_resp; - - }; - static struct test tests[] = { - { - .title = "Attach Request (invalid MI length)", - .msg = attach_req_inv_mi_len, - .msg_len = sizeof(attach_req_inv_mi_len), - .num_resp = 1 /* Reject */ - - }, - { - .title = "Attach Request (invalid MI type)", - .msg = attach_req_inv_mi_type, - .msg_len = sizeof(attach_req_inv_mi_type), - .num_resp = 1 /* Reject */ - }, - { - .title = "Routing Area Update Request (valid)", - .msg = dtap_ra_upd_req, - .msg_len = sizeof(dtap_ra_upd_req), - .num_resp = 2 /* XID Reset + Reject */ - }, - { - .title = "Routing Area Update Request (invalid type)", - .msg = dtap_ra_upd_req_inv_type, - .msg_len = sizeof(dtap_ra_upd_req_inv_type), - .num_resp = 1 /* Reject */ - }, - { - .title = "Routing Area Update Request (invalid CAP length)", - .msg = dtap_ra_upd_req_inv_cap_len, - .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len), - .num_resp = 1 /* Reject */ - }, - }; - - printf("Testing GMM reject\n"); - - /* reset the PRNG used by sgsn_alloc_ptmsi */ - srand(1); - - foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN); - - OSMO_ASSERT(count(gprs_llme_list()) == 0); - - for (idx = 0; idx < ARRAY_SIZE(tests); idx++) { - const struct test *test = &tests[idx]; - printf(" - %s\n", test->title); - - /* Create a LLE/LLME */ - lle = gprs_lle_get_or_create(foreign_tlli, 3); - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* Inject the Request message */ - send_0408_message(lle->llme, foreign_tlli, &raid, - test->msg, test->msg_len); - - /* We expect a Reject message */ - fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n", - sgsn_tx_counter, test->num_resp); - OSMO_ASSERT(sgsn_tx_counter == test->num_resp); - - /* verify that LLME/MM are removed */ - ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid); - OSMO_ASSERT(ctx == NULL); - OSMO_ASSERT(count(gprs_llme_list()) == 0); - } - - cleanup_test(); -} - -/* - * Test cancellation of attached MM contexts - */ -static void test_gmm_cancel(void) -{ - struct gprs_ra_id raid = { 0, }; - struct sgsn_mm_ctx *ctx = NULL; - struct sgsn_mm_ctx *ictx; - uint32_t ptmsi1; - uint32_t foreign_tlli; - uint32_t local_tlli = 0; - struct gprs_llc_lle *lle; - const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - - /* DTAP - Attach Request */ - /* The P-TMSI is not known by the SGSN */ - static const unsigned char attach_req[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4, - 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, - 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, - 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8, - 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00 - }; - - /* DTAP - Identity Response IMEI */ - static const unsigned char ident_resp_imei[] = { - 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, - 0x56 - }; - - /* DTAP - Identity Response IMSI */ - static const unsigned char ident_resp_imsi[] = { - 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32, - 0x54 - }; - - /* DTAP - Attach Complete */ - static const unsigned char attach_compl[] = { - 0x08, 0x03 - }; - - printf("Testing cancellation\n"); - - sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN; - - foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN); - - /* Create a LLE/LLME */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - lle = gprs_lle_get_or_create(foreign_tlli, 3); - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* inject the attach request */ - send_0408_message(lle->llme, foreign_tlli, &raid, - attach_req, ARRAY_SIZE(attach_req)); - - ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid); - OSMO_ASSERT(ctx != NULL); - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - - /* we expect an identity request (IMEI) */ - OSMO_ASSERT(sgsn_tx_counter == 1); - - /* inject the identity response (IMEI) */ - send_0408_message(ctx->gb.llme, foreign_tlli, &raid, - ident_resp_imei, ARRAY_SIZE(ident_resp_imei)); - - /* we expect an identity request (IMSI) */ - OSMO_ASSERT(sgsn_tx_counter == 1); - - /* inject the identity response (IMSI) */ - send_0408_message(ctx->gb.llme, foreign_tlli, &raid, - ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi)); - - /* check that the MM context has not been removed due to a failed - * authorization */ - OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid)); - - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - - /* we expect an attach accept/reject */ - OSMO_ASSERT(sgsn_tx_counter == 1); - ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI); - - /* this has been randomly assigned by the SGSN */ - local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); - - /* inject the attach complete */ - send_0408_message(ctx->gb.llme, foreign_tlli, &raid, - attach_compl, ARRAY_SIZE(attach_compl)); - - OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL); - - /* we don't expect a response */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - /* cancel */ - gsm0408_gprs_access_cancelled(ctx, 0); - - /* verify that things are gone */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid); - OSMO_ASSERT(!ictx); - - sgsn->cfg.auth_policy = saved_auth_policy; - - cleanup_test(); -} - -/* - * Test the dynamic allocation of P-TMSIs - */ -static void test_gmm_ptmsi_allocation(void) -{ - struct gprs_ra_id raid = {332, 112, 16464, 96}; - struct sgsn_mm_ctx *ctx = NULL; - struct sgsn_mm_ctx *ictx; - uint32_t foreign_tlli; - uint32_t ptmsi1; - uint32_t ptmsi2; - uint32_t received_ptmsi; - uint32_t old_ptmsi; - uint32_t local_tlli = 0; - struct gprs_llc_lle *lle; - const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - - /* DTAP - Attach Request (IMSI 12131415161718) */ - static const unsigned char attach_req[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19, - 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, - 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, - 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, - 0x00, - }; - - /* DTAP - Identity Response IMEI */ - static const unsigned char ident_resp_imei[] = { - 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, - 0x56 - }; - - /* DTAP - Attach Complete */ - static const unsigned char attach_compl[] = { - 0x08, 0x03 - }; - - /* DTAP - Routing Area Update Request */ - static const unsigned char ra_upd_req[] = { - 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, - 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, - 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, - 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, - 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, - 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, - 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 - }; - - /* DTAP - Routing Area Update Complete */ - static const unsigned char ra_upd_complete[] = { - 0x08, 0x0a - }; - - /* DTAP - Detach Request (MO) */ - /* normal detach, power_off = 1 */ - static const unsigned char detach_req[] = { - 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2, - 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb - }; - - sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN; - - printf("Testing P-TMSI allocation\n"); - - printf(" - sgsn_alloc_ptmsi\n"); - - /* reset the PRNG used by sgsn_alloc_ptmsi */ - srand(1); - - ptmsi1 = sgsn_alloc_ptmsi(); - OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI); - - ptmsi2 = sgsn_alloc_ptmsi(); - OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI); - - OSMO_ASSERT(ptmsi1 != ptmsi2); - - ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI; - - printf(" - Repeated Attach Request\n"); - - foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN); - - /* Create a LLE/LLME */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - lle = gprs_lle_get_or_create(foreign_tlli, 3); - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* inject the attach request */ - send_0408_message(lle->llme, foreign_tlli, &raid, - attach_req, ARRAY_SIZE(attach_req)); - - ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid); - OSMO_ASSERT(ctx != NULL); - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); - ptmsi1 = ctx->p_tmsi; - - old_ptmsi = ctx->p_tmsi_old; - - /* we expect an identity request (IMEI) */ - OSMO_ASSERT(sgsn_tx_counter == 1); - - /* inject the identity response (IMEI) */ - send_0408_message(ctx->gb.llme, foreign_tlli, &raid, - ident_resp_imei, ARRAY_SIZE(ident_resp_imei)); - - /* check that the MM context has not been removed due to a failed - * authorization */ - OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid)); - - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi == ptmsi1); - - /* we expect an attach accept */ - OSMO_ASSERT(sgsn_tx_counter == 1); - received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(received_ptmsi == ptmsi1); - - /* we ignore this and send the attach again */ - send_0408_message(lle->llme, foreign_tlli, &raid, - attach_req, ARRAY_SIZE(attach_req)); - - /* the allocated P-TMSI should be the same */ - ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid); - OSMO_ASSERT(ctx != NULL); - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi); - OSMO_ASSERT(ctx->p_tmsi == ptmsi1); - - /* we expect an attach accept */ - OSMO_ASSERT(sgsn_tx_counter == 1); - received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(received_ptmsi == ptmsi1); - - /* inject the attach complete */ - local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); - send_0408_message(ctx->gb.llme, local_tlli, &raid, - attach_compl, ARRAY_SIZE(attach_compl)); - - /* we don't expect a response */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL); - OSMO_ASSERT(ctx->p_tmsi_old == 0); - OSMO_ASSERT(ctx->p_tmsi == ptmsi1); - - printf(" - Repeated RA Update Request\n"); - - /* inject the RA update request */ - send_0408_message(ctx->gb.llme, local_tlli, &raid, - ra_upd_req, ARRAY_SIZE(ra_upd_req)); - - /* we expect an RA update accept */ - OSMO_ASSERT(sgsn_tx_counter == 1); - - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1); - OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); - OSMO_ASSERT(ctx->p_tmsi != ptmsi1); - ptmsi2 = ctx->p_tmsi; - - /* repeat the RA update request */ - send_0408_message(ctx->gb.llme, local_tlli, &raid, - ra_upd_req, ARRAY_SIZE(ra_upd_req)); - - /* we expect an RA update accept */ - OSMO_ASSERT(sgsn_tx_counter == 1); - received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(received_ptmsi == ptmsi2); - - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1); - OSMO_ASSERT(ctx->p_tmsi == ptmsi2); - - /* inject the RA update complete */ - local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL); - send_0408_message(ctx->gb.llme, local_tlli, &raid, - ra_upd_complete, ARRAY_SIZE(ra_upd_complete)); - - /* we don't expect a response */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL); - OSMO_ASSERT(ctx->p_tmsi_old == 0); - OSMO_ASSERT(ctx->p_tmsi == ptmsi2); - - /* inject the detach */ - send_0408_message(ctx->gb.llme, local_tlli, &raid, - detach_req, ARRAY_SIZE(detach_req)); - - /* verify that things are gone */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid); - OSMO_ASSERT(!ictx); - - sgsn->cfg.auth_policy = saved_auth_policy; - - cleanup_test(); -} - -/* - * Test changing of routing areas - */ -static void test_gmm_routing_areas(void) -{ - struct gprs_ra_id raid1 = {332, 112, 16464, 96}; - struct gprs_ra_id raid2 = {332, 112, 16464, 97}; - struct sgsn_mm_ctx *ctx = NULL; - struct sgsn_mm_ctx *ictx; - uint32_t ptmsi1; - uint32_t received_ptmsi; - uint32_t ms_tlli = 0; - struct gprs_llc_lle *lle; - const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - - /* DTAP - Attach Request (IMSI 12131415161718) */ - static const unsigned char attach_req[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19, - 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, - 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, - 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, - 0x00, - }; - - /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */ - static const unsigned char attach_req2[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19, - 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, - 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, - 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, - 0x00, - }; - - /* DTAP - Identity Response IMEI */ - static const unsigned char ident_resp_imei[] = { - 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, - 0x56 - }; - - /* DTAP - Attach Complete */ - static const unsigned char attach_compl[] = { - 0x08, 0x03 - }; - - /* DTAP - Routing Area Update Request (coming from RA 1) */ - static const unsigned char ra_upd_req1[] = { - 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, - 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, - 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, - 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, - 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, - 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, - 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 - }; - - /* DTAP - Routing Area Update Request (coming from RA 2) */ - static const unsigned char ra_upd_req2[] = { - 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, - 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, - 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, - 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, - 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, - 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, - 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 - }; - - /* DTAP - Routing Area Update Request (coming from RA other) */ - /* raid_other = {443, 223, 16464, 98}; */ - static const unsigned char ra_upd_req_other[] = { - 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50, - 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, - 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, - 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, - 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, - 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, - 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 - }; - - /* DTAP - Routing Area Update Complete */ - static const unsigned char ra_upd_complete[] = { - 0x08, 0x0a - }; - - /* DTAP - Detach Request (MO) */ - /* normal detach, power_off = 1 */ - static const unsigned char detach_req[] = { - 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2, - 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb - }; - - sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN; - - printf("Testing routing area changes\n"); - - /* reset the PRNG used by sgsn_alloc_ptmsi */ - srand(1); - - ptmsi1 = GSM_RESERVED_TMSI; - - printf(" - Attach Request (RA 1)\n"); - - ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM); - - /* Create a LLE/LLME */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - lle = gprs_lle_get_or_create(ms_tlli, 3); - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* inject the attach request */ - send_0408_message(lle->llme, ms_tlli, &raid1, - attach_req, ARRAY_SIZE(attach_req)); - - ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1); - OSMO_ASSERT(ctx != NULL); - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); - - /* we expect an identity request (IMEI) */ - OSMO_ASSERT(sgsn_tx_counter == 1); - OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ); - OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli); - - /* inject the identity response (IMEI) */ - send_0408_message(ctx->gb.llme, ms_tlli, &raid1, - ident_resp_imei, ARRAY_SIZE(ident_resp_imei)); - - /* check that the MM context has not been removed due to a failed - * authorization */ - OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1)); - - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - - /* we expect an attach accept */ - OSMO_ASSERT(sgsn_tx_counter == 1); - OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK); - OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli); - - received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); - ptmsi1 = received_ptmsi; - - /* inject the attach complete */ - ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); - send_0408_message(ctx->gb.llme, ms_tlli, &raid1, - attach_compl, ARRAY_SIZE(attach_compl)); - - /* we don't expect a response */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL); - OSMO_ASSERT(ctx->p_tmsi_old == 0); - OSMO_ASSERT(ctx->p_tmsi == ptmsi1); - - printf(" - RA Update Request (RA 1 -> RA 1)\n"); - - /* inject the RA update request */ - send_0408_message(ctx->gb.llme, ms_tlli, &raid1, - ra_upd_req1, ARRAY_SIZE(ra_upd_req1)); - - /* we expect an RA update accept */ - OSMO_ASSERT(sgsn_tx_counter == 1); - OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK); - // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli); - - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1); - OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); - OSMO_ASSERT(ctx->p_tmsi != ptmsi1); - - received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); - ptmsi1 = received_ptmsi; - - /* inject the RA update complete */ - ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); - send_0408_message(ctx->gb.llme, ms_tlli, &raid1, - ra_upd_complete, ARRAY_SIZE(ra_upd_complete)); - - /* we don't expect a response */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL); - OSMO_ASSERT(ctx->p_tmsi_old == 0); - OSMO_ASSERT(ctx->p_tmsi == ptmsi1); - OSMO_ASSERT(ctx->gb.tlli == ms_tlli); - - printf(" - RA Update Request (RA 1 -> RA 2)\n"); - - /* inject the RA update request */ - ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN); - - /* It is coming from RA 1 => ra_upd_req1 */ - send_0408_message(ctx->gb.llme, ms_tlli, &raid2, - ra_upd_req1, ARRAY_SIZE(ra_upd_req1)); - - /* we expect an RA update accept */ - OSMO_ASSERT(sgsn_tx_counter == 1); - OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK); - - printf(" - RA Update Request (RA other -> RA 2)\n"); - - /* inject the RA update request */ - ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN); - - /* It is coming from RA 1 => ra_upd_req1 */ - send_0408_message(ctx->gb.llme, ms_tlli, &raid2, - ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other)); - - /* we expect an RA update reject (and a LLC XID RESET) */ - OSMO_ASSERT(sgsn_tx_counter == 2); - OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ); - /* this has killed the LLE/LLME */ - - printf(" - Attach Request (RA 2)\n"); - - /* Create a LLE/LLME */ - OSMO_ASSERT(count(gprs_llme_list()) == 1); - lle = gprs_lle_get_or_create(ms_tlli, 3); - OSMO_ASSERT(count(gprs_llme_list()) == 1); - - /* inject the attach request */ - send_0408_message(lle->llme, ms_tlli, &raid2, - attach_req2, ARRAY_SIZE(attach_req2)); - - ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); - OSMO_ASSERT(ctx != NULL); - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); - - /* we expect an attach accept */ - OSMO_ASSERT(sgsn_tx_counter == 1); - OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK); - - received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); - ptmsi1 = received_ptmsi; - - /* inject the attach complete */ - ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); - ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); - OSMO_ASSERT(ictx != NULL); - OSMO_ASSERT(ictx == ctx); - - send_0408_message(ctx->gb.llme, ms_tlli, &raid2, - attach_compl, ARRAY_SIZE(attach_compl)); - - /* we don't expect a response */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL); - OSMO_ASSERT(ctx->p_tmsi_old == 0); - OSMO_ASSERT(ctx->p_tmsi == ptmsi1); - - printf(" - RA Update Request (RA 2 -> RA 2)\n"); - - /* inject the RA update request */ - send_0408_message(ctx->gb.llme, ms_tlli, &raid2, - ra_upd_req2, ARRAY_SIZE(ra_upd_req2)); - - /* we expect an RA update accept */ - OSMO_ASSERT(sgsn_tx_counter == 1); - OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK); - - OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT); - OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1); - OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI); - OSMO_ASSERT(ctx->p_tmsi != ptmsi1); - - received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx); - OSMO_ASSERT(received_ptmsi == ctx->p_tmsi); - ptmsi1 = received_ptmsi; - - /* inject the RA update complete */ - ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL); - send_0408_message(ctx->gb.llme, ms_tlli, &raid2, - ra_upd_complete, ARRAY_SIZE(ra_upd_complete)); - - /* we don't expect a response */ - OSMO_ASSERT(sgsn_tx_counter == 0); - - OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL); - OSMO_ASSERT(ctx->p_tmsi_old == 0); - OSMO_ASSERT(ctx->p_tmsi == ptmsi1); - OSMO_ASSERT(ctx->gb.tlli == ms_tlli); - - - /* inject the detach */ - send_0408_message(ctx->gb.llme, ms_tlli, &raid2, - detach_req, ARRAY_SIZE(detach_req)); - - /* verify that things are gone */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2); - OSMO_ASSERT(!ictx); - - sgsn->cfg.auth_policy = saved_auth_policy; - - cleanup_test(); -} - -static void test_apn_matching(void) -{ - struct apn_ctx *actx, *actxs[9]; - - printf("Testing APN matching\n"); - - actxs[0] = sgsn_apn_ctx_find_alloc("*.test", ""); - actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", ""); - actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", ""); - actxs[3] = NULL; - - actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456"); - actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123"); - actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456"); - actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123"); - - actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456"); - - actx = sgsn_apn_ctx_match("abc.def.test", "12345678"); - OSMO_ASSERT(actx == actxs[2]); - actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678"); - OSMO_ASSERT(actx == actxs[2]); - actx = sgsn_apn_ctx_match("xyz.def.test", "12345678"); - OSMO_ASSERT(actx == actxs[1]); - actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678"); - OSMO_ASSERT(actx == actxs[1]); - actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678"); - OSMO_ASSERT(actx == actxs[0]); - actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678"); - OSMO_ASSERT(actx == NULL); - - actxs[3] = sgsn_apn_ctx_find_alloc("*", ""); - actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678"); - OSMO_ASSERT(actx == actxs[3]); - - actx = sgsn_apn_ctx_match("abc.def.test", "45699900"); - OSMO_ASSERT(actx == actxs[4]); - - actx = sgsn_apn_ctx_match("xyz.def.test", "45699900"); - OSMO_ASSERT(actx == actxs[6]); - - actx = sgsn_apn_ctx_match("abc.def.test", "45612300"); - OSMO_ASSERT(actx == actxs[5]); - - actx = sgsn_apn_ctx_match("xyz.def.test", "45612300"); - OSMO_ASSERT(actx == actxs[7]); - - actx = sgsn_apn_ctx_match("ghi.def.test", "45699900"); - OSMO_ASSERT(actx == actxs[8]); - - actx = sgsn_apn_ctx_match("ghi.def.test", "45612300"); - OSMO_ASSERT(actx == actxs[7]); - - /* Free APN contexts and check how the matching changes */ - - sgsn_apn_ctx_free(actxs[7]); - actx = sgsn_apn_ctx_match("ghi.def.test", "45612300"); - OSMO_ASSERT(actx == actxs[8]); - - sgsn_apn_ctx_free(actxs[8]); - actx = sgsn_apn_ctx_match("ghi.def.test", "45612300"); - OSMO_ASSERT(actx == actxs[6]); - - sgsn_apn_ctx_free(actxs[6]); - actx = sgsn_apn_ctx_match("ghi.def.test", "45612300"); - OSMO_ASSERT(actx == actxs[1]); - - sgsn_apn_ctx_free(actxs[5]); - actx = sgsn_apn_ctx_match("abc.def.test", "45612300"); - OSMO_ASSERT(actx == actxs[4]); - - sgsn_apn_ctx_free(actxs[4]); - actx = sgsn_apn_ctx_match("abc.def.test", "45612300"); - OSMO_ASSERT(actx == actxs[2]); - - sgsn_apn_ctx_free(actxs[2]); - actx = sgsn_apn_ctx_match("abc.def.test", "12345678"); - OSMO_ASSERT(actx == actxs[1]); - - sgsn_apn_ctx_free(actxs[1]); - actx = sgsn_apn_ctx_match("abc.def.test", "12345678"); - OSMO_ASSERT(actx == actxs[0]); - - sgsn_apn_ctx_free(actxs[0]); - actx = sgsn_apn_ctx_match("abc.def.test", "12345678"); - OSMO_ASSERT(actx == actxs[3]); - - sgsn_apn_ctx_free(actxs[3]); - actx = sgsn_apn_ctx_match("abc.def.test", "12345678"); - OSMO_ASSERT(actx == NULL); - - cleanup_test(); -} - -struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc( - struct sgsn_subscriber_data *sdata); - -static void test_ggsn_selection(void) -{ - struct apn_ctx *actxs[4]; - struct sgsn_ggsn_ctx *ggc, *ggcs[3]; - struct gprs_subscr *s1; - const char *imsi1 = "1234567890"; - struct sgsn_mm_ctx *ctx; - struct gprs_ra_id raid = { 0, }; - uint32_t local_tlli = 0xffeeddcc; - enum gsm48_gsm_cause gsm_cause; - struct tlv_parsed tp; - uint8_t apn_enc[GSM_APN_LENGTH + 10]; - struct sgsn_subscriber_pdp_data *pdp_data; - char apn_str[GSM_APN_LENGTH]; - - printf("Testing GGSN selection\n"); - - gsup_client_send_cb = my_gsup_client_send_dummy; - - /* Check for emptiness */ - OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL); - - /* Create a context */ - OSMO_ASSERT(count(gprs_llme_list()) == 0); - ctx = alloc_mm_ctx(local_tlli, &raid); - osmo_strlcpy(ctx->imsi, imsi1, sizeof(ctx->imsi)); - - /* Allocate and attach a subscriber */ - s1 = gprs_subscr_get_or_create_by_mmctx(ctx); - assert_subscr(s1, imsi1); - - tp.lv[GSM48_IE_GSM_APN].len = 0; - tp.lv[GSM48_IE_GSM_APN].val = apn_enc; - - /* TODO: Add PDP info entries to s1 */ - - ggcs[0] = sgsn_ggsn_ctx_find_alloc(0); - ggcs[1] = sgsn_ggsn_ctx_find_alloc(1); - ggcs[2] = sgsn_ggsn_ctx_find_alloc(2); - - actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456"); - actxs[0]->ggsn = ggcs[0]; - actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456"); - actxs[1]->ggsn = ggcs[1]; - actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789"); - actxs[2]->ggsn = ggcs[2]; - - pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data); - pdp_data->context_id = 1; - pdp_data->pdp_type = 0x0121; - osmo_strlcpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)); - - /* Resolve GGSNs */ - - tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn"); - - ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); - OSMO_ASSERT(ggc != NULL); - OSMO_ASSERT(ggc->id == 0); - OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0); - - tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn"); - - ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); - OSMO_ASSERT(ggc != NULL); - OSMO_ASSERT(ggc->id == 1); - OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0); - - tp.lv[GSM48_IE_GSM_APN].len = 0; - tp.lv[GSM48_IE_GSM_APN].val = NULL; - - ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); - OSMO_ASSERT(ggc != NULL); - OSMO_ASSERT(ggc->id == 0); - OSMO_ASSERT(strcmp(apn_str, "") == 0); - - actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456"); - actxs[3]->ggsn = ggcs[2]; - ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); - OSMO_ASSERT(ggc != NULL); - OSMO_ASSERT(ggc->id == 2); - OSMO_ASSERT(strcmp(apn_str, "") == 0); - - sgsn_apn_ctx_free(actxs[3]); - tp.lv[GSM48_IE_GSM_APN].val = apn_enc; - - tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar"); - - ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); - OSMO_ASSERT(ggc == NULL); - OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN); - OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0); - - tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc); - ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); - OSMO_ASSERT(ggc == NULL); - OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO); - - /* Add PDP data entry to subscriber */ - - osmo_strlcpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)); - - tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn"); - - ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); - OSMO_ASSERT(ggc != NULL); - OSMO_ASSERT(ggc->id == 0); - OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0); - - tp.lv[GSM48_IE_GSM_APN].len = - gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn"); - - ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str); - OSMO_ASSERT(ggc == NULL); - OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB); - OSMO_ASSERT(strcmp(apn_str, "") == 0); - - /* Cleanup */ - - gprs_subscr_put(s1); - sgsn_mm_ctx_cleanup_free(ctx); - - assert_no_subscrs(); - - sgsn_apn_ctx_free(actxs[0]); - sgsn_apn_ctx_free(actxs[1]); - sgsn_apn_ctx_free(actxs[2]); - - sgsn_ggsn_ctx_free(ggcs[0]); - sgsn_ggsn_ctx_free(ggcs[1]); - sgsn_ggsn_ctx_free(ggcs[2]); - - gsup_client_send_cb = __real_gsup_client_send; - - cleanup_test(); -} - -static struct log_info_cat gprs_categories[] = { - [DMM] = { - .name = "DMM", - .description = "Layer3 Mobility Management (MM)", - .color = "\033[1;33m", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DPAG] = { - .name = "DPAG", - .description = "Paging Subsystem", - .color = "\033[1;38m", - .enabled = 1, .loglevel = LOGL_NOTICE, - }, - [DMEAS] = { - .name = "DMEAS", - .description = "Radio Measurement Processing", - .enabled = 0, .loglevel = LOGL_NOTICE, - }, - [DREF] = { - .name = "DREF", - .description = "Reference Counting", - .enabled = 0, .loglevel = LOGL_NOTICE, - }, - [DGPRS] = { - .name = "DGPRS", - .description = "GPRS Packet Service", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DNS] = { - .name = "DNS", - .description = "GPRS Network Service (NS)", - .enabled = 1, .loglevel = LOGL_INFO, - }, - [DBSSGP] = { - .name = "DBSSGP", - .description = "GPRS BSS Gateway Protocol (BSSGP)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DLLC] = { - .name = "DLLC", - .description = "GPRS Logical Link Control Protocol (LLC)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DSNDCP] = { - .name = "DSNDCP", - .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, -}; - -static struct log_info info = { - .cat = gprs_categories, - .num_cat = ARRAY_SIZE(gprs_categories), -}; - -int main(int argc, char **argv) -{ - void *osmo_sgsn_ctx; - void *msgb_ctx; - - osmo_init_logging(&info); - osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn"); - tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc"); - msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0); - - sgsn_rate_ctr_init(); - sgsn_auth_init(); - gprs_subscr_init(sgsn); - - test_llme(); - test_subscriber(); - test_auth_triplets(); - test_subscriber_gsup(); - test_gmm_detach(); - test_gmm_detach_power_off(); - test_gmm_detach_no_mmctx(); - test_gmm_detach_accept_unexpected(); - test_gmm_status_no_mmctx(); - test_gmm_attach_acl(); - test_gmm_attach_subscr(); - test_gmm_attach_subscr_fake_auth(); - test_gmm_attach_subscr_real_auth(); - test_gmm_attach_subscr_gsup_auth(0); - test_gmm_attach_subscr_gsup_auth(1); - test_gmm_attach_subscr_real_gsup_auth(0); - test_gmm_reject(); - test_gmm_cancel(); - test_gmm_ptmsi_allocation(); - test_gmm_routing_areas(); - test_apn_matching(); - test_ggsn_selection(); - printf("Done\n"); - - talloc_report_full(osmo_sgsn_ctx, stderr); - OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1); - OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 2); - return 0; -} - - -/* stubs */ -struct osmo_prim_hdr; -int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) -{ - abort(); -} diff --git a/tests/sgsn/sgsn_test.ok b/tests/sgsn/sgsn_test.ok deleted file mode 100644 index f38d7309d..000000000 --- a/tests/sgsn/sgsn_test.ok +++ /dev/null @@ -1,45 +0,0 @@ -Testing LLME allocations -Testing core subscriber data API -llist_count(gprs_subscribers) == 0 -llist_count(gprs_subscribers) == 1 -llist_count(gprs_subscribers) == 1 -llist_count(gprs_subscribers) == 2 -llist_count(gprs_subscribers) == 3 -llist_count(gprs_subscribers) == 2 -llist_count(gprs_subscribers) == 1 -llist_count(gprs_subscribers) == 0 -Testing authentication triplet handling -Testing subscriber GSUP handling -Testing GMM detach -Testing GMM detach (power off) -Testing GMM detach (no MMCTX) -Testing GMM detach accept (unexpected) -Testing GMM Status (no MMCTX) -Auth policy 'closed': Testing GMM attach -Auth policy 'remote': Testing GMM attach -Auth policy 'remote', auth faked: Testing GMM attach -Auth policy 'remote', triplet based auth: Testing GMM attach -Auth policy 'remote', GSUP based auth: Testing GMM attach -Auth policy 'remote', GSUP based auth: Testing GMM attach with retry -Auth policy 'remote', real GSUP based auth: Testing GMM attach -Testing GMM reject - - Attach Request (invalid MI length) - - Attach Request (invalid MI type) - - Routing Area Update Request (valid) - - Routing Area Update Request (invalid type) - - Routing Area Update Request (invalid CAP length) -Testing cancellation -Testing P-TMSI allocation - - sgsn_alloc_ptmsi - - Repeated Attach Request - - Repeated RA Update Request -Testing routing area changes - - Attach Request (RA 1) - - RA Update Request (RA 1 -> RA 1) - - RA Update Request (RA 1 -> RA 2) - - RA Update Request (RA other -> RA 2) - - Attach Request (RA 2) - - RA Update Request (RA 2 -> RA 2) -Testing APN matching -Testing GGSN selection -Done diff --git a/tests/slhc/Makefile.am b/tests/slhc/Makefile.am deleted file mode 100644 index 32a3cc447..000000000 --- a/tests/slhc/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) - -EXTRA_DIST = slhc_test.ok - -noinst_PROGRAMS = slhc_test - -slhc_test_SOURCES = slhc_test.c - -slhc_test_LDADD = \ - $(top_builddir)/src/gprs/slhc.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) - - diff --git a/tests/slhc/slhc_test.c b/tests/slhc/slhc_test.c deleted file mode 100644 index d2e1cd9dc..000000000 --- a/tests/slhc/slhc_test.c +++ /dev/null @@ -1,272 +0,0 @@ -/* Test SLHC/RFC1144 TCP/IP Header compression/decompression */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#include -#include - -#include -#include - -#include - -#include -#include -#include - -/* Number of compression slots (S0-1) */ -#define SLOTS 8 - -/* Maximum packet bytes to display */ -#define DISP_MAX_BYTES 100 - -/* Sample packets to test with */ -#define PACKETS_LEN 15 -char *packets[] = { - /* With TCP Option 10 (Timestamps) in place (forces UNCOMPRESSED_TCP) */ - "4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27", - "4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", - "4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01", - "4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01", - "4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", - "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20", - /* Regular TCP packets (COMPRESSED_TCP) */ - "4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27", - "4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", - "4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01", - "4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01", - "4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", - "4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20", - /* UDP packets (TYPE_IP */ - "450000396e0b40004011a0310a0901650a09170105da003500255489a60f01000001000000000000076f736d6f636f6d036f72670000010001", - "450000dc9eeb00004011aeae0a0917010a090165003505da00c83fbaa60f81800001000100030004076f736d6f636f6d036f72670000010001c00c00010001000079be0004904c2b4cc00c000200010000173d00130773756e6265616d08676e756d6f6e6b73c014c00c000200010000173d000603646e73c041c00c000200010000173d000a0767616e65736861c041c058000100010000173d0004d55f2e45c058001c00010000173d0010200107800045f0460000000000690001c06a0001000100006a710004d55f1b78c039000100010000173d000453ecb2cb", - "45000037652340004011a91b0a0901650a091701ef1b0035002376a2c3910100000100000000000006676f6f676c650264650000010001", - "0050b6162c10000db93a3ff908004500004726a6000038114083080808080a0901650035ef1b00338a8cc3918180000100010000000006676f6f676c650264650000010001c00c000100010000012b0004d83ad503", -}; - -/* Compress a packet using Van Jacobson RFC1144 header compression */ -static int compress(uint8_t *data_o, uint8_t *data_i, int len, - struct slcompress *comp) -{ - uint8_t *comp_ptr; /* Not used */ - int compr_len; - - /* Create a working copy of the incoming data */ - memcpy(data_o, data_i, len); - - /* Run compressor */ - compr_len = slhc_compress(comp, data_i, len, data_o, &comp_ptr, 0); - return compr_len; -} - -/* Expand a packet using Van Jacobson RFC1144 header compression */ -static int expand(uint8_t *data_o, uint8_t *data_i, int len, - struct slcompress *comp) -{ - int data_decompressed_len; - - /* Create a working copy of the incoming data */ - memcpy(data_o, data_i, len); - - /* Handle an uncompressed packet (learn header information */ - if ((data_i[0] & SL_TYPE_UNCOMPRESSED_TCP) == SL_TYPE_UNCOMPRESSED_TCP) { - data_o[0] &= 0x4F; - data_decompressed_len = slhc_remember(comp, data_o, len); - return data_decompressed_len; - } - - /* Uncompress compressed packets */ - else if (data_o[0] & SL_TYPE_COMPRESSED_TCP) { - data_decompressed_len = slhc_uncompress(comp, data_o, len); - return data_decompressed_len; - } - - /* Regular or unknown packets will not be touched */ - return len; -} - -/* Calculate IP Header checksum */ -static uint16_t calc_ip_csum(uint8_t *data, int len) -{ - int i; - uint32_t accumulator = 0; - uint16_t *pointer = (uint16_t *) data; - - for (i = len; i > 1; i -= 2) { - accumulator += *pointer; - pointer++; - } - - if (len % 2) - accumulator += *pointer; - - accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); - accumulator += (accumulator >> 16) & 0xffff; - return (~accumulator); -} - -/* Calculate TCP/IP checksum */ -static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) -{ - uint8_t *buf; - uint16_t csum; - - buf = talloc_zero_size(ctx, len); - memset(buf, 0, len); - memcpy(buf, packet + 12, 8); - buf[9] = packet[9]; - buf[11] = (len - 20) & 0xFF; - buf[10] = (len - 20) >> 8 & 0xFF; - memcpy(buf + 12, packet + 20, len - 20); - csum = calc_ip_csum(buf, len - 20 + 12); - talloc_free(buf); - return csum; -} - -/* Check TCP/IP packet */ -static void check_packet(const void *ctx, uint8_t *packet, int len) -{ - /* Check IP header */ - OSMO_ASSERT(len > 20); - OSMO_ASSERT(calc_ip_csum(packet, 20) == 0); - - printf("packet[9]=%02x\n", packet[9]); - - /* Check TCP packet */ - if (packet[9] != 0x06) - return; - OSMO_ASSERT(len > 40); - OSMO_ASSERT(calc_tcpip_csum(ctx, packet, len) == 0); -} - -/* Compress / Decompress packets */ -static void test_slhc(const void *ctx) -{ - char packet_ascii[2048]; - int i; - - struct slcompress *comp; - uint8_t packet[1024]; - int packet_len; - uint8_t packet_compr[1024]; - int packet_compr_len; - uint8_t packet_decompr[1024]; - int packet_decompr_len; - - printf("Allocating compression state...\n"); - comp = slhc_init(ctx, SLOTS, SLOTS); - OSMO_ASSERT(comp); - - for (i = 0; i < PACKETS_LEN; i++) { - printf("Testing with packet No. %d\n", i); - - /* Read input file */ - memset(packet_ascii, 0, sizeof(packet_ascii)); - memset(packet, 0, sizeof(packet)); - memset(packet_compr, 0, sizeof(packet_compr)); - memset(packet_decompr, 0, sizeof(packet_decompr)); - - OSMO_ASSERT(strlen(packets[i]) < sizeof(packet_ascii)); - strcpy(packet_ascii, packets[i]); - - packet_len = - osmo_hexparse(packet_ascii, packet, sizeof(packet)); - check_packet(ctx, packet, packet_len); - - /* Run compression/decompression algorithm */ - printf("Compressing...\n"); - packet_compr_len = - compress(packet_compr, packet, packet_len, comp); - printf("Decompressing...\n"); - packet_decompr_len = - expand(packet_decompr, packet_compr, packet_compr_len, - comp); - OSMO_ASSERT(packet_decompr_len == packet_len); - check_packet(ctx, packet_decompr, packet_decompr_len); - - /* Display results */ - printf("Results:\n"); - if (packet_compr_len > DISP_MAX_BYTES) - packet_compr_len = DISP_MAX_BYTES; - if (packet_len > DISP_MAX_BYTES) - packet_len = DISP_MAX_BYTES; - if (packet_decompr_len > DISP_MAX_BYTES) - packet_decompr_len = DISP_MAX_BYTES; - printf("Original Packet: (%i bytes) %s\n", packet_len, - osmo_hexdump_nospc(packet, packet_len)); - printf("DecompressedPacket: (%i bytes) %s\n", - packet_decompr_len, osmo_hexdump_nospc(packet_decompr, - packet_decompr_len)); - printf("CompressedPacket: (%i bytes) %s\n", packet_compr_len, - osmo_hexdump_nospc(packet_compr, packet_compr_len)); - slhc_o_status(comp); - slhc_o_status(comp); - - printf("\n"); - } - - printf("Freeing compression state...\n"); - slhc_free(comp); - printf("\n"); -} - -static struct log_info_cat gprs_categories[] = { - [DSNDCP] = { - .name = "DSNDCP", - .description = - "GPRS Sub-Network Dependent Control Protocol (SNDCP)", - .enabled = 1,.loglevel = LOGL_DEBUG, - }, - [DSLHC] = { - .name = "DSLHC", - .description = - "Van Jacobson RFC1144 TCP/IP header compression (SLHC)", - .enabled = 1,.loglevel = LOGL_DEBUG, - } -}; - -static struct log_info info = { - .cat = gprs_categories, - .num_cat = ARRAY_SIZE(gprs_categories), -}; - -int main(int argc, char **argv) -{ - void *ctx; - - osmo_init_logging(&info); - - ctx = talloc_named_const(NULL, 0, "slhc_ctx"); - - test_slhc(ctx); - - printf("Done\n"); - - talloc_report_full(ctx, stderr); - OSMO_ASSERT(talloc_total_blocks(ctx) == 1); - return 0; -} - -/* stubs */ -struct osmo_prim_hdr; -int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) -{ - abort(); -} diff --git a/tests/slhc/slhc_test.ok b/tests/slhc/slhc_test.ok deleted file mode 100644 index 71f48a179..000000000 --- a/tests/slhc/slhc_test.ok +++ /dev/null @@ -1,154 +0,0 @@ -Allocating compression state... -Testing with packet No. 0 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (64 bytes) 4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 -DecompressedPacket: (64 bytes) 4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 -CompressedPacket: (64 bytes) 7510004046dd40004000a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 - -Testing with packet No. 1 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (91 bytes) 4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 -DecompressedPacket: (91 bytes) 4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 -CompressedPacket: (91 bytes) 7510005b46de40004000a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 - -Testing with packet No. 2 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (55 bytes) 4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 -DecompressedPacket: (55 bytes) 4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 -CompressedPacket: (55 bytes) 7510003746df40004000a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 - -Testing with packet No. 3 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (55 bytes) 4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 -DecompressedPacket: (55 bytes) 4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 -CompressedPacket: (55 bytes) 7510003746e040004000a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 - -Testing with packet No. 4 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (100 bytes) 4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d -DecompressedPacket: (100 bytes) 4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d -CompressedPacket: (100 bytes) 7510007446e140004000a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d - -Testing with packet No. 5 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (66 bytes) 4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 -DecompressedPacket: (66 bytes) 4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 -CompressedPacket: (66 bytes) 7510004246e240004000a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 - -Testing with packet No. 6 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 -DecompressedPacket: (52 bytes) 4510003446dd40004006a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 -CompressedPacket: (52 bytes) 7510003446dd40004000a9b3c0a8646ec0a864640017ad8b81980100f3ac984d501800e371410000fffd18fffd20fffd23fffd27 - -Testing with packet No. 7 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 -DecompressedPacket: (79 bytes) 4510004f46de40004006a997c0a8646ec0a864640017ad8b8198010cf3ac984d501800e3cda40000fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 -CompressedPacket: (43 bytes) df00cda4fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 - -Testing with packet No. 8 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 -DecompressedPacket: (43 bytes) 4510002b46df40004006a9bac0a8646ec0a864640017ad8b81980133f3ac989f501800e3a70a0000fffd01 -CompressedPacket: (9 bytes) dc00a70a5227fffd01 - -Testing with packet No. 9 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 -DecompressedPacket: (43 bytes) 4510002b46e040004006a9b9c0a8646ec0a864640017ad8b81980136f3ac98a2501800e3a7060000fffb01 -CompressedPacket: (7 bytes) db00a706fffb01 - -Testing with packet No. 10 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d -DecompressedPacket: (100 bytes) 4510006846e140004006a97bc0a8646ec0a864640017ad8b81980139f3ac98a5501800e3c2d000000d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d -CompressedPacket: (68 bytes) db00c2d00d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a - -Testing with packet No. 11 -packet[9]=06 -Compressing... -Decompressing... -packet[9]=06 -Results: -Original Packet: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 -DecompressedPacket: (54 bytes) 4510003646e240004006a9acc0a8646ec0a864640017ad8b81980179f3ac98a5501800e321fb0000706f6c6c7578206c6f67696e3a20 -CompressedPacket: (18 bytes) df0021fb706f6c6c7578206c6f67696e3a20 - -Testing with packet No. 12 -packet[9]=11 -Compressing... -Decompressing... -packet[9]=11 -Results: -Original Packet: (57 bytes) 450000396e0b40004011a0310a0901650a09170105da003500255489a60f01000001000000000000076f736d6f636f6d036f72670000010001 -DecompressedPacket: (57 bytes) 450000396e0b40004011a0310a0901650a09170105da003500255489a60f01000001000000000000076f736d6f636f6d036f72670000010001 -CompressedPacket: (57 bytes) 450000396e0b40004011a0310a0901650a09170105da003500255489a60f01000001000000000000076f736d6f636f6d036f72670000010001 - -Testing with packet No. 13 -packet[9]=11 -Compressing... -Decompressing... -packet[9]=11 -Results: -Original Packet: (100 bytes) 450000dc9eeb00004011aeae0a0917010a090165003505da00c83fbaa60f81800001000100030004076f736d6f636f6d036f72670000010001c00c00010001000079be0004904c2b4cc00c000200010000173d00130773756e6265616d08676e756d6f6e -DecompressedPacket: (100 bytes) 450000dc9eeb00004011aeae0a0917010a090165003505da00c83fbaa60f81800001000100030004076f736d6f636f6d036f72670000010001c00c00010001000079be0004904c2b4cc00c000200010000173d00130773756e6265616d08676e756d6f6e -CompressedPacket: (100 bytes) 450000dc9eeb00004011aeae0a0917010a090165003505da00c83fbaa60f81800001000100030004076f736d6f636f6d036f72670000010001c00c00010001000079be0004904c2b4cc00c000200010000173d00130773756e6265616d08676e756d6f6e - -Testing with packet No. 14 -packet[9]=11 -Compressing... -Decompressing... -packet[9]=11 -Results: -Original Packet: (55 bytes) 45000037652340004011a91b0a0901650a091701ef1b0035002376a2c3910100000100000000000006676f6f676c650264650000010001 -DecompressedPacket: (55 bytes) 45000037652340004011a91b0a0901650a091701ef1b0035002376a2c3910100000100000000000006676f6f676c650264650000010001 -CompressedPacket: (55 bytes) 45000037652340004011a91b0a0901650a091701ef1b0035002376a2c3910100000100000000000006676f6f676c650264650000010001 - -Freeing compression state... - -Done diff --git a/tests/smpp/Makefile.am b/tests/smpp/Makefile.am deleted file mode 100644 index 508270753..000000000 --- a/tests/smpp/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - -I$(top_srcdir)/src/libmsc \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOSCCP_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(COVERAGE_CFLAGS) \ - $(LIBSMPP34_CFLAGS) \ - $(NULL) - -AM_LDFLAGS = \ - $(COVERAGE_LDFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - smpp_test.ok \ - smpp_test.err \ - $(NULL) - -noinst_PROGRAMS = \ - smpp_test \ - $(NULL) - -smpp_test_SOURCES = \ - smpp_test.c \ - $(top_builddir)/src/libmsc/smpp_utils.c \ - $(NULL) - -smpp_test_LDADD = \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(NULL) diff --git a/tests/smpp/smpp_test.c b/tests/smpp/smpp_test.c deleted file mode 100644 index 62fa9d2e9..000000000 --- a/tests/smpp/smpp_test.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * (C) 2013 by Holger Hans Peter Freyther - * All Rights Reserved - * - * 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 Affero 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 . - * - */ - -#include -#include - -#include - -#include -#include - -#include "smpp_smsc.h" - -struct coding_test { - uint8_t dcs; - uint8_t coding; - int mode; - int res; -}; - -static struct coding_test codecs[] = { - { .dcs = 0xf6 , .coding = 0x02, .mode = MODE_8BIT, .res = 0 }, - { .dcs = 0xf2 , .coding = 0x01, .mode = MODE_7BIT, .res = 0 }, - { .dcs = 0x02 , .coding = 0x01, .mode = MODE_7BIT, .res = 0 }, - { .dcs = 0x06 , .coding = 0x02, .mode = MODE_8BIT, .res = 0 }, - { .dcs = 0x0A , .coding = 0x08, .mode = MODE_8BIT, .res = 0 }, - { .dcs = 0x0E , .coding = 0xFF, .mode = 0xFF, .res = -1 }, - { .dcs = 0xE0 , .coding = 0xFF, .mode = 0xFF, .res = -1 }, -}; - -static void test_coding_scheme(void) -{ - int i; - printf("Testing coding scheme support\n"); - - for (i = 0; i < ARRAY_SIZE(codecs); ++i) { - uint8_t coding; - int mode, res; - - res = smpp_determine_scheme(codecs[i].dcs, &coding, &mode); - OSMO_ASSERT(res == codecs[i].res); - if (res != -1) { - OSMO_ASSERT(mode == codecs[i].mode); - OSMO_ASSERT(coding == codecs[i].coding); - } - } -} - -int main(int argc, char **argv) -{ - osmo_init_logging(&log_info); - log_set_use_color(osmo_stderr_target, 0); - log_set_print_filename(osmo_stderr_target, 0); - - test_coding_scheme(); - return EXIT_SUCCESS; -} diff --git a/tests/smpp/smpp_test.err b/tests/smpp/smpp_test.err deleted file mode 100644 index ec966ba47..000000000 --- a/tests/smpp/smpp_test.err +++ /dev/null @@ -1,2 +0,0 @@ -SMPP MO Unknown Data Coding 0x0e -SMPP MO Unknown Data Coding 0xe0 diff --git a/tests/smpp/smpp_test.ok b/tests/smpp/smpp_test.ok deleted file mode 100644 index fd44804d1..000000000 --- a/tests/smpp/smpp_test.ok +++ /dev/null @@ -1 +0,0 @@ -Testing coding scheme support diff --git a/tests/smpp_test_runner.py b/tests/smpp_test_runner.py deleted file mode 100644 index 7a3a342ec..000000000 --- a/tests/smpp_test_runner.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env python - -# (C) 2014 by Holger Hans Peter Freyther -# based on vty_test_runner.py: -# (C) 2013 by Katerina Barone-Adesi -# (C) 2013 by Holger Hans Peter Freyther -# 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 . - -import os -import sys -import time -import unittest -import socket - -import osmopy.obscvty as obscvty -import osmopy.osmoutil as osmoutil - -confpath = os.path.join(sys.path[0], '..') - -class TestVTYBase(unittest.TestCase): - - def vty_command(self): - raise Exception("Needs to be implemented by a subclass") - - def vty_app(self): - raise Exception("Needs to be implemented by a subclass") - - def setUp(self): - osmo_vty_cmd = self.vty_command()[:] - config_index = osmo_vty_cmd.index('-c') - if config_index: - cfi = config_index + 1 - osmo_vty_cmd[cfi] = os.path.join(confpath, osmo_vty_cmd[cfi]) - - try: - self.proc = osmoutil.popen_devnull(osmo_vty_cmd) - except OSError: - print >> sys.stderr, "Current directory: %s" % os.getcwd() - print >> sys.stderr, "Consider setting -b" - - appstring = self.vty_app()[2] - appport = self.vty_app()[0] - self.vty = obscvty.VTYInteract(appstring, "127.0.0.1", appport) - - def tearDown(self): - if self.vty: - self.vty._close_socket() - self.vty = None - osmoutil.end_proc(self.proc) - - -class TestSMPPMSC(TestVTYBase): - - def vty_command(self): - return ["./src/osmo-msc/osmo-msc", "-c", - "doc/examples/osmo-msc/osmo-msc.cfg"] - - def vty_app(self): - return (4254, "./src/osmo-msc/osmo-msc", "OsmoMSC", "msc") - - def testSMPPCrashes(self): - # Enable the configuration - self.vty.enable() - self.assertTrue(self.vty.verify("configure terminal", [''])) - self.assertEquals(self.vty.node(), 'config') - - self.assertTrue(self.vty.verify('smpp', [''])) - self.assertEquals(self.vty.node(), 'config-smpp') - self.assertTrue(self.vty.verify('system-id test', [''])) - self.assertTrue(self.vty.verify('local-tcp-port 2775', [''])) - self.assertTrue(self.vty.verify('esme test', [''])) - self.assertEquals(self.vty.node(), 'config-smpp-esme') - self.assertTrue(self.vty.verify('default-route', [''])) - self.assertTrue(self.vty.verify('end', [''])) - - # MSC should listen to 2775 now! - sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sck.setblocking(1) - sck.connect(('0.0.0.0', 2775)) - sck.sendall('\x00\x00\x00\x02\x00') - sck.close() - - # Check if the VTY is still there - self.vty.verify('disable',['']) - - # Now for the second packet - sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sck.setblocking(1) - sck.connect(('0.0.0.0', 2775)) - sck.sendall('\x00\x01\x00\x01\x01') - sck.close() - - self.vty.verify('enable',['']) - -if __name__ == '__main__': - import argparse - import sys - - workdir = '.' - - parser = argparse.ArgumentParser() - parser.add_argument("-v", "--verbose", dest="verbose", - action="store_true", help="verbose mode") - parser.add_argument("-p", "--pythonconfpath", dest="p", - help="searchpath for config") - parser.add_argument("-w", "--workdir", dest="w", - help="Working directory") - args = parser.parse_args() - - verbose_level = 1 - if args.verbose: - verbose_level = 2 - - if args.w: - workdir = args.w - - if args.p: - confpath = args.p - - print "confpath %s, workdir %s" % (confpath, workdir) - os.chdir(workdir) - print "Running tests for specific SMPP" - suite = unittest.TestSuite() - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestSMPPMSC)) - res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) - sys.exit(len(res.errors) + len(res.failures)) diff --git a/tests/sms_queue/Makefile.am b/tests/sms_queue/Makefile.am deleted file mode 100644 index 06c54bcec..000000000 --- a/tests/sms_queue/Makefile.am +++ /dev/null @@ -1,57 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBCRYPTO_CFLAGS) \ - $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(LIBOSMOSIGTRAN_CFLAGS) \ - $(LIBOSMORANAP_CFLAGS) \ - $(LIBASN1C_CFLAGS) \ - $(LIBOSMOLEGACYMGCP_CFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - sms_queue_test.ok \ - sms_queue_test.err \ - $(NULL) - -noinst_PROGRAMS = \ - sms_queue_test \ - $(NULL) - -sms_queue_test_SOURCES = \ - sms_queue_test.c \ - $(NULL) - -sms_queue_test_LDADD = \ - $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libvlr/libvlr.a \ - $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libtrau/libtrau.a \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ - $(LIBSMPP34_LIBS) \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBCRYPTO_LIBS) \ - $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOSIGTRAN_LIBS) \ - $(LIBOSMORANAP_LIBS) \ - $(LIBASN1C_LIBS) \ - $(LIBOSMOLEGACYMGCP_LIBS) \ - $(LIBRARY_GSM) \ - -ldbi \ - -lrt \ - $(NULL) - -sms_queue_test_LDFLAGS = \ - -Wl,--wrap=db_sms_get_next_unsent_rr_msisdn \ - $(NULL) diff --git a/tests/sms_queue/sms_queue_test.c b/tests/sms_queue/sms_queue_test.c deleted file mode 100644 index af25b0645..000000000 --- a/tests/sms_queue/sms_queue_test.c +++ /dev/null @@ -1,215 +0,0 @@ -/* Test Osmocom SMS queue */ - -/* - * (C) 2017 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 Affero 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 . - * - */ - -#include - -#include -#include - -static void *talloc_ctx = NULL; - -struct gsm_sms *smsq_take_next_sms(struct gsm_network *net, - char *last_msisdn, - size_t last_msisdn_buflen); - -static void _test_take_next_sms_print(int i, - struct gsm_sms *sms, - const char *last_msisdn) -{ - printf("#%d: ", i); - if (sms) - printf("sending SMS to %s", sms->text); - else - printf("no SMS to send"); - printf(" (last_msisdn='%s')\n", last_msisdn? last_msisdn : "NULL"); -} - -static struct gsm_sms fake_sms = { 0 }; - -struct { - const char *msisdn; - int nr_of_sms; - int failed_attempts; - bool vsub_attached; -} fake_sms_db[] = { - { - .msisdn = "1111", - .nr_of_sms = 0, - .vsub_attached = true, - }, - { - .msisdn = "2222", - .nr_of_sms = 2, - .failed_attempts = 2, - .vsub_attached = true, - }, - { - .msisdn = "3333", - .nr_of_sms = 2, - .failed_attempts = 3, - .vsub_attached = true, - }, - { - .msisdn = "4444", - .nr_of_sms = 0, - .vsub_attached = true, - }, - { - .msisdn = "5555", - .nr_of_sms = 2, - .failed_attempts = 5, - .vsub_attached = false, - }, -}; - -/* override, requires '-Wl,--wrap=db_sms_get_next_unsent_rr_msisdn' */ -struct gsm_sms *__real_db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net, - const char *last_msisdn, - unsigned int max_failed); -struct gsm_sms *__wrap_db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net, - const char *last_msisdn, - unsigned int max_failed) -{ - static struct vlr_subscr arbitrary_vsub = { .lu_complete = true }; - int i; - printf(" hitting database: looking for MSISDN > '%s', failed_attempts <= %d\n", - last_msisdn, max_failed); - - for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) { - if (!fake_sms_db[i].nr_of_sms) - continue; - if (strcmp(fake_sms_db[i].msisdn, last_msisdn) <= 0) - continue; - if (fake_sms_db[i].failed_attempts > max_failed) - continue; - osmo_strlcpy(fake_sms.dst.addr, fake_sms_db[i].msisdn, - sizeof(fake_sms.dst.addr)); - fake_sms.receiver = fake_sms_db[i].vsub_attached? &arbitrary_vsub : NULL; - osmo_strlcpy(fake_sms.text, fake_sms_db[i].msisdn, sizeof(fake_sms.text)); - if (fake_sms_db[i].vsub_attached) - fake_sms_db[i].nr_of_sms --; - return &fake_sms; - } - return NULL; -} - -void show_fake_sms_db() -{ - int i; - for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) { - printf(" %s%s has %u SMS pending, %u failed attempts\n", - fake_sms_db[i].msisdn, - fake_sms_db[i].vsub_attached ? "" : " (NOT attached)", - fake_sms_db[i].nr_of_sms, - fake_sms_db[i].failed_attempts); - } - printf("-->\n"); -} - -static void test_next_sms() -{ - int i; - char last_msisdn[GSM_EXTENSION_LENGTH+1] = ""; - - printf("Testing smsq_take_next_sms()\n"); - - printf("\n- vsub 2, 3 and 5 each have 2 SMS pending, but 5 is not attached\n"); - last_msisdn[0] = '\0'; - show_fake_sms_db(); - for (i = 0; i < 7; i++) { - struct gsm_sms *sms = smsq_take_next_sms(NULL, last_msisdn, sizeof(last_msisdn)); - _test_take_next_sms_print(i, sms, last_msisdn); - OSMO_ASSERT(i >= 4 || sms); - } - - printf("\n- SMS are pending at various nr failed attempts (cutoff at >= 10)\n"); - last_msisdn[0] = '\0'; - for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) { - fake_sms_db[i].vsub_attached = true; - fake_sms_db[i].nr_of_sms = 1 + i; - fake_sms_db[i].failed_attempts = i*5; - - } - show_fake_sms_db(); - for (i = 0; i < 7; i++) { - struct gsm_sms *sms = smsq_take_next_sms(NULL, last_msisdn, sizeof(last_msisdn)); - _test_take_next_sms_print(i, sms, last_msisdn); - OSMO_ASSERT(i >= 2 || sms); - } - - printf("\n- iterate the SMS DB at most once\n"); - osmo_strlcpy(last_msisdn, "2345", sizeof(last_msisdn)); - for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) { - fake_sms_db[i].vsub_attached = false; - fake_sms_db[i].nr_of_sms = 1; - fake_sms_db[i].failed_attempts = 0; - } - show_fake_sms_db(); - for (i = 0; i < 3; i++) { - struct gsm_sms *sms = smsq_take_next_sms(NULL, last_msisdn, sizeof(last_msisdn)); - _test_take_next_sms_print(i, sms, last_msisdn); - OSMO_ASSERT(!sms); - } - - printf("\n- there are no SMS in the DB\n"); - last_msisdn[0] = '\0'; - for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) { - fake_sms_db[i].vsub_attached = true; - fake_sms_db[i].nr_of_sms = 0; - fake_sms_db[i].failed_attempts = 0; - } - show_fake_sms_db(); - for (i = 0; i < 3; i++) { - struct gsm_sms *sms = smsq_take_next_sms(NULL, last_msisdn, sizeof(last_msisdn)); - _test_take_next_sms_print(i, sms, last_msisdn); - OSMO_ASSERT(!sms); - } -} - - -static struct log_info_cat sms_queue_test_categories[] = { -}; - -static struct log_info info = { - .cat = sms_queue_test_categories, - .num_cat = ARRAY_SIZE(sms_queue_test_categories), -}; - -int main(int argc, char **argv) -{ - talloc_ctx = talloc_named_const(NULL, 1, "sms_queue_test"); - msgb_talloc_ctx_init(talloc_ctx, 0); - osmo_init_logging(&info); - - 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_category(osmo_stderr_target, 1); - log_parse_category_mask(osmo_stderr_target, "DLOAP,1"); - - test_next_sms(); - printf("Done\n"); - - return 0; -} diff --git a/tests/sms_queue/sms_queue_test.err b/tests/sms_queue/sms_queue_test.err deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/sms_queue/sms_queue_test.ok b/tests/sms_queue/sms_queue_test.ok deleted file mode 100644 index 146400d21..000000000 --- a/tests/sms_queue/sms_queue_test.ok +++ /dev/null @@ -1,98 +0,0 @@ -Testing smsq_take_next_sms() - -- vsub 2, 3 and 5 each have 2 SMS pending, but 5 is not attached - 1111 has 0 SMS pending, 0 failed attempts - 2222 has 2 SMS pending, 2 failed attempts - 3333 has 2 SMS pending, 3 failed attempts - 4444 has 0 SMS pending, 0 failed attempts - 5555 (NOT attached) has 2 SMS pending, 5 failed attempts ---> - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#0: sending SMS to 2222 (last_msisdn='2222') - hitting database: looking for MSISDN > '2222', failed_attempts <= 9 -#1: sending SMS to 3333 (last_msisdn='3333') - hitting database: looking for MSISDN > '3333', failed_attempts <= 9 - hitting database: looking for MSISDN > '5555', failed_attempts <= 9 - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#2: sending SMS to 2222 (last_msisdn='2222') - hitting database: looking for MSISDN > '2222', failed_attempts <= 9 -#3: sending SMS to 3333 (last_msisdn='3333') - hitting database: looking for MSISDN > '3333', failed_attempts <= 9 - hitting database: looking for MSISDN > '5555', failed_attempts <= 9 - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#4: no SMS to send (last_msisdn='5555') - hitting database: looking for MSISDN > '5555', failed_attempts <= 9 - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#5: no SMS to send (last_msisdn='5555') - hitting database: looking for MSISDN > '5555', failed_attempts <= 9 - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#6: no SMS to send (last_msisdn='5555') - -- SMS are pending at various nr failed attempts (cutoff at >= 10) - 1111 has 1 SMS pending, 0 failed attempts - 2222 has 2 SMS pending, 5 failed attempts - 3333 has 3 SMS pending, 10 failed attempts - 4444 has 4 SMS pending, 15 failed attempts - 5555 has 5 SMS pending, 20 failed attempts ---> - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#0: sending SMS to 1111 (last_msisdn='1111') - hitting database: looking for MSISDN > '1111', failed_attempts <= 9 -#1: sending SMS to 2222 (last_msisdn='2222') - hitting database: looking for MSISDN > '2222', failed_attempts <= 9 - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#2: sending SMS to 2222 (last_msisdn='2222') - hitting database: looking for MSISDN > '2222', failed_attempts <= 9 - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#3: no SMS to send (last_msisdn='') - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#4: no SMS to send (last_msisdn='') - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#5: no SMS to send (last_msisdn='') - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#6: no SMS to send (last_msisdn='') - -- iterate the SMS DB at most once - 1111 (NOT attached) has 1 SMS pending, 0 failed attempts - 2222 (NOT attached) has 1 SMS pending, 0 failed attempts - 3333 (NOT attached) has 1 SMS pending, 0 failed attempts - 4444 (NOT attached) has 1 SMS pending, 0 failed attempts - 5555 (NOT attached) has 1 SMS pending, 0 failed attempts ---> - hitting database: looking for MSISDN > '2345', failed_attempts <= 9 - hitting database: looking for MSISDN > '3333', failed_attempts <= 9 - hitting database: looking for MSISDN > '4444', failed_attempts <= 9 - hitting database: looking for MSISDN > '5555', failed_attempts <= 9 - hitting database: looking for MSISDN > '', failed_attempts <= 9 - hitting database: looking for MSISDN > '1111', failed_attempts <= 9 - hitting database: looking for MSISDN > '2222', failed_attempts <= 9 -#0: no SMS to send (last_msisdn='3333') - hitting database: looking for MSISDN > '3333', failed_attempts <= 9 - hitting database: looking for MSISDN > '4444', failed_attempts <= 9 - hitting database: looking for MSISDN > '5555', failed_attempts <= 9 - hitting database: looking for MSISDN > '', failed_attempts <= 9 - hitting database: looking for MSISDN > '1111', failed_attempts <= 9 - hitting database: looking for MSISDN > '2222', failed_attempts <= 9 -#1: no SMS to send (last_msisdn='3333') - hitting database: looking for MSISDN > '3333', failed_attempts <= 9 - hitting database: looking for MSISDN > '4444', failed_attempts <= 9 - hitting database: looking for MSISDN > '5555', failed_attempts <= 9 - hitting database: looking for MSISDN > '', failed_attempts <= 9 - hitting database: looking for MSISDN > '1111', failed_attempts <= 9 - hitting database: looking for MSISDN > '2222', failed_attempts <= 9 -#2: no SMS to send (last_msisdn='3333') - -- there are no SMS in the DB - 1111 has 0 SMS pending, 0 failed attempts - 2222 has 0 SMS pending, 0 failed attempts - 3333 has 0 SMS pending, 0 failed attempts - 4444 has 0 SMS pending, 0 failed attempts - 5555 has 0 SMS pending, 0 failed attempts ---> - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#0: no SMS to send (last_msisdn='') - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#1: no SMS to send (last_msisdn='') - hitting database: looking for MSISDN > '', failed_attempts <= 9 -#2: no SMS to send (last_msisdn='') -Done diff --git a/tests/sndcp_xid/Makefile.am b/tests/sndcp_xid/Makefile.am deleted file mode 100644 index d09c41b28..000000000 --- a/tests/sndcp_xid/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) - -EXTRA_DIST = sndcp_xid_test.ok - -noinst_PROGRAMS = sndcp_xid_test - -sndcp_xid_test_SOURCES = sndcp_xid_test.c - -sndcp_xid_test_LDADD = \ - $(top_builddir)/src/gprs/gprs_sndcp_xid.o \ - $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOGB_LIBS) \ - $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) \ - $(LIBGTP_LIBS) \ - -lrt -lm - - diff --git a/tests/sndcp_xid/sndcp_xid_test.c b/tests/sndcp_xid/sndcp_xid_test.c deleted file mode 100644 index 151dd2bb5..000000000 --- a/tests/sndcp_xid/sndcp_xid_test.c +++ /dev/null @@ -1,284 +0,0 @@ -/* Test SNDCP-XID Encoding/Decoding */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#include -#include - -#include -#include - -#include - -#include -#include - -/* Test SNDCP-XID decoding with a real world sample */ -static void test_xid_decode_realworld(const void *ctx) -{ - struct llist_head *comp_fields; - int rc; - printf("Testing SNDCP XID-Decoder/Encoder (real world data)\n"); - - /* Example of a real world SNDCP-XID message */ - uint8_t xid[] = - { 0x00, 0x01, 0x00, 0x02, 0x31, 0x82, 0x02, 0x27, 0x89, 0xff, 0xe0, - 0x00, 0x0f, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, - 0x01, 0x02, 0x00, 0x03, 0x01, 0x03, 0x00, 0x04, 0x01, 0x04, 0x00, 0x05, - 0x01, 0x05, 0x00, 0x06, 0x00, 0x07, 0x01, 0x07, 0x00, 0x08, 0x01, 0x08, - 0x80, 0x00, 0x04, 0x12, 0x00, 0x40, 0x07 }; - uint8_t xid_r[512]; - - /* Parse and show contained comp fields */ - comp_fields = gprs_sndcp_parse_xid(NULL, ctx, xid, sizeof(xid), NULL); - OSMO_ASSERT(comp_fields); - printf("Decoded:\n"); - gprs_sndcp_dump_comp_fields(comp_fields, DSNDCP); - - /* Encode comp-fields again */ - rc = gprs_sndcp_compile_xid(xid_r,sizeof(xid_r), comp_fields, - DEFAULT_SNDCP_VERSION); - printf("Result length=%i\n",rc); - printf("Encoded: %s\n", osmo_hexdump_nospc(xid, sizeof(xid))); - printf("Rencoded: %s\n", osmo_hexdump_nospc(xid_r, rc)); - - OSMO_ASSERT(rc == 54); - OSMO_ASSERT(memcmp(xid, xid_r, sizeof(xid)) == 0); - - /* Free comp fields */ - talloc_free(comp_fields); - - printf("\n"); -} - -/* Encode and decode test with artificial test data */ -static void test_xid_encode_decode(const void *ctx) -{ - printf("Testing SNDCP XID-Encoder/Decoder\n"); - - LLIST_HEAD(comp_fields); - struct gprs_sndcp_pcomp_rfc1144_params rfc1144_params; - struct gprs_sndcp_comp_field rfc1144_comp_field; - struct gprs_sndcp_pcomp_rfc2507_params rfc2507_params; - struct gprs_sndcp_comp_field rfc2507_comp_field; - struct gprs_sndcp_pcomp_rohc_params rohc_params; - struct gprs_sndcp_comp_field rohc_comp_field; - struct gprs_sndcp_dcomp_v42bis_params v42bis_params; - struct gprs_sndcp_comp_field v42bis_comp_field; - struct gprs_sndcp_dcomp_v44_params v44_params; - struct gprs_sndcp_comp_field v44_comp_field; - struct llist_head *comp_fields_dec; - - uint8_t xid[512]; - unsigned int xid_len = sizeof(xid); - int rc; - - memset(&rfc1144_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); - memset(&rfc2507_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); - memset(&rohc_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); - memset(&v42bis_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); - memset(&v44_comp_field, 0, sizeof(struct gprs_sndcp_comp_field)); - - /* Setup which NSAPIs shall make use of rfc1144 */ - rfc1144_params.nsapi[0] = 5; - rfc1144_params.nsapi_len = 1; - - /* Setup rfc1144 operating parameters */ - rfc1144_params.s01 = 7; - - /* Setup rfc1144 compression field */ - rfc1144_comp_field.p = 1; - rfc1144_comp_field.entity = 0; - rfc1144_comp_field.algo = RFC_1144; - rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1; - rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2; - rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM; - rfc1144_comp_field.rfc1144_params = &rfc1144_params; - - /* Setup which NSAPIs shall make use of rfc1144 */ - rfc2507_params.nsapi[0] = 6; - rfc2507_params.nsapi_len = 1; - - /* Setup rfc2507 operating parameters */ - rfc2507_params.f_max_period = 256; - rfc2507_params.f_max_time = 5; - rfc2507_params.max_header = 168; - rfc2507_params.tcp_space = 15; - rfc2507_params.non_tcp_space = 15; - - /* Setup rfc2507 compression field */ - rfc2507_comp_field.p = 1; - rfc2507_comp_field.entity = 1; - rfc2507_comp_field.algo = RFC_2507; - rfc2507_comp_field.comp[RFC2507_PCOMP1] = 3; - rfc2507_comp_field.comp[RFC2507_PCOMP2] = 4; - rfc2507_comp_field.comp[RFC2507_PCOMP3] = 5; - rfc2507_comp_field.comp[RFC2507_PCOMP4] = 6; - rfc2507_comp_field.comp[RFC2507_PCOMP5] = 7; - rfc2507_comp_field.comp_len = RFC2507_PCOMP_NUM; - rfc2507_comp_field.rfc2507_params = &rfc2507_params; - - /* Setup which NSAPIs shall make use of ROHC */ - rohc_params.nsapi[0] = 5; - rohc_params.nsapi[1] = 6; - rohc_params.nsapi[2] = 7; - rohc_params.nsapi[3] = 8; - rohc_params.nsapi[4] = 9; - rohc_params.nsapi[5] = 10; - rohc_params.nsapi[6] = 11; - rohc_params.nsapi[7] = 12; - rohc_params.nsapi[8] = 13; - rohc_params.nsapi[9] = 14; - rohc_params.nsapi[10] = 15; - rohc_params.nsapi_len = 11; - - /* Setup ROHC operating parameters */ - rohc_params.max_cid = 15; /* default */ - rohc_params.max_header = 168; /* default */ - rohc_params.profile[0] = ROHC_UNCOMPRESSED; - rohc_params.profile[1] = ROHC_RTP; - rohc_params.profile[2] = ROHCV2_RTP; - rohc_params.profile[3] = ROHC_UDP; - rohc_params.profile[4] = ROHCv2_UDP; - rohc_params.profile[5] = ROHC_ESP; - rohc_params.profile[6] = ROHCV2_ESP; - rohc_params.profile[7] = ROHC_IP; - rohc_params.profile[8] = ROHCV2_IP; - rohc_params.profile[9] = ROHC_LLA; - rohc_params.profile[10] = ROHC_LLA_WITH_R_MODE; - rohc_params.profile[11] = ROHC_TCP; - rohc_params.profile[12] = ROHC_RTP_UDP_LITE; - rohc_params.profile[13] = ROHCV2_RTP_UDP_LITE; - rohc_params.profile[14] = ROHC_UDP_LITE; - rohc_params.profile[15] = ROHCV2_UDP_LITE; - rohc_params.profile_len = 16; - - /* Setup ROHC compression field */ - rohc_comp_field.p = 1; - rohc_comp_field.entity = 2; - rohc_comp_field.algo = ROHC; - rohc_comp_field.comp[ROHC_PCOMP1] = 8; - rohc_comp_field.comp[ROHC_PCOMP2] = 9; - rohc_comp_field.comp_len = ROHC_PCOMP_NUM; - rohc_comp_field.rohc_params = &rohc_params; - - /* Setup which NSAPIs shall make use of v42bis */ - v42bis_params.nsapi[0] = 5; - v42bis_params.nsapi_len = 1; - - /* Setup v42bis operating parameters */ - v42bis_params.p0 = 3; - v42bis_params.p1 = 2048; - v42bis_params.p2 = 20; - - /* Setup v42bis compression field */ - v42bis_comp_field.p = 1; - v42bis_comp_field.entity = 3; - v42bis_comp_field.algo = V42BIS; - v42bis_comp_field.comp[V42BIS_DCOMP1] = 10; - v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM; - v42bis_comp_field.v42bis_params = &v42bis_params; - - /* Setup which NSAPIs shall make use of v44 */ - v44_params.nsapi[0] = 5; - v44_params.nsapi_len = 1; - - /* Setup v44 operating parameters */ - v44_params.c0 = 0x80; - v44_params.p0 = 3; - v44_params.p1t = 300; - v44_params.p1r = 300; - v44_params.p3t = 600; - v44_params.p3r = 600; - - /* Setup v44 compression field */ - v44_comp_field.p = 1; - v44_comp_field.entity = 3; - v44_comp_field.algo = V44; - v44_comp_field.comp[V44_DCOMP1] = 10; - v44_comp_field.comp[V44_DCOMP2] = 11; - v44_comp_field.comp_len = V44_DCOMP_NUM; - v44_comp_field.v44_params = &v44_params; - - /* Add compression field(s) to list */ - llist_add(&v44_comp_field.list, &comp_fields); - llist_add(&v42bis_comp_field.list, &comp_fields); - llist_add(&rfc1144_comp_field.list, &comp_fields); - llist_add(&rfc2507_comp_field.list, &comp_fields); - llist_add(&rohc_comp_field.list, &comp_fields); - printf("Test input data:\n"); - gprs_sndcp_dump_comp_fields(&comp_fields, DSNDCP); - - /* Encode SNDCP-XID fields */ - rc = gprs_sndcp_compile_xid(xid, xid_len, &comp_fields, - DEFAULT_SNDCP_VERSION); - OSMO_ASSERT(rc > 0); - - printf("Encoded: %s (%i bytes)\n", osmo_hexdump_nospc(xid, rc), rc); - - /* Parse and show contained comp fields */ - comp_fields_dec = gprs_sndcp_parse_xid(NULL, ctx, xid, rc, NULL); - OSMO_ASSERT(comp_fields_dec); - - printf("Decoded:\n"); - gprs_sndcp_dump_comp_fields(comp_fields_dec, DSNDCP); - - /* Free comp fields */ - talloc_free(comp_fields_dec); -} - -static struct log_info_cat gprs_categories[] = { - [DSNDCP] = { - .name = "DSNDCP", - .description = - "GPRS Sub-Network Dependent Control Protocol (SNDCP)", - .enabled = 1,.loglevel = LOGL_DEBUG, - } -}; - -static struct log_info info = { - .cat = gprs_categories, - .num_cat = ARRAY_SIZE(gprs_categories), -}; - -int main(int argc, char **argv) -{ - void *xid_ctx; - - osmo_init_logging(&info); - - xid_ctx = talloc_named_const(NULL, 0, "xid_ctx"); - - test_xid_decode_realworld(xid_ctx); - test_xid_encode_decode(xid_ctx); - - printf("Done\n"); - - talloc_report_full(xid_ctx, stderr); - OSMO_ASSERT(talloc_total_blocks(xid_ctx) == 1); - return 0; -} - -/* stubs */ -struct osmo_prim_hdr; -int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) -{ - abort(); -} diff --git a/tests/sndcp_xid/sndcp_xid_test.ok b/tests/sndcp_xid/sndcp_xid_test.ok deleted file mode 100644 index f3572827c..000000000 --- a/tests/sndcp_xid/sndcp_xid_test.ok +++ /dev/null @@ -1,11 +0,0 @@ -Testing SNDCP XID-Decoder/Encoder (real world data) -Decoded: -Result length=54 -Encoded: 000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 -Rencoded: 000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 - -Testing SNDCP XID-Encoder/Decoder -Test input data: -Encoded: 000100011a83010dab00208003012c012c02580258830007a000200308001402408000041200200781010c3456700040010005a80f000f82022789ffe0000f00a80000000101010002010200030103000401040005010500060007010700080108 (97 bytes) -Decoded: -Done diff --git a/tests/testsuite.at b/tests/testsuite.at index 7a8d84bbe..a412f7cae 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -1,12 +1,6 @@ AT_INIT AT_BANNER([Regression tests.]) -AT_SETUP([gsm0408]) -AT_KEYWORDS([gsm0408]) -cat $abs_srcdir/gsm0408/gsm0408_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/gsm0408/gsm0408_test], [], [expout], [ignore]) -AT_CLEANUP - AT_SETUP([bsc_subscr]) AT_KEYWORDS([bsc_subscr]) cat $abs_srcdir/subscr/bsc_subscr_test.ok > expout @@ -20,30 +14,6 @@ cat $abs_srcdir/channel/channel_test.ok > expout AT_CHECK([$abs_top_builddir/tests/channel/channel_test], [], [expout], [ignore]) AT_CLEANUP -AT_SETUP([gprs]) -AT_KEYWORDS([gprs]) -cat $abs_srcdir/gprs/gprs_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/gprs/gprs_test], [], [expout], [ignore]) -AT_CLEANUP - -AT_SETUP([bsc-nat]) -AT_KEYWORDS([bsc-nat]) -AT_CHECK([test "$enable_nat_test" != no || exit 77]) -cp $abs_srcdir/bsc-nat/prefixes.csv . -cp $abs_srcdir/bsc-nat/barr.cfg . -cp $abs_srcdir/bsc-nat/barr_dup.cfg . -cat $abs_srcdir/bsc-nat/bsc_nat_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/bsc-nat/bsc_nat_test], [], [expout], [ignore]) -AT_CLEANUP - -AT_SETUP([smpp]) -AT_KEYWORDS([smpp]) -AT_CHECK([test "$enable_smpp_test" != no || exit 77]) -cat $abs_srcdir/smpp/smpp_test.ok > expout -cat $abs_srcdir/smpp/smpp_test.err > experr -AT_CHECK([$abs_top_builddir/tests/smpp/smpp_test], [], [expout], [experr]) -AT_CLEANUP - AT_SETUP([bsc-nat-trie]) AT_KEYWORDS([bsc-nat-trie]) AT_CHECK([test "$enable_nat_test" != no || exit 77]) @@ -65,140 +35,14 @@ cat $abs_srcdir/bsc/bsc_test.ok > expout AT_CHECK([$abs_top_builddir/tests/bsc/bsc_test], [], [expout], [ignore]) AT_CLEANUP -AT_SETUP([gbproxy]) -AT_KEYWORDS([gbproxy]) -cat $abs_srcdir/gbproxy/gbproxy_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/gbproxy/gbproxy_test], [], [expout], [ignore]) -AT_CLEANUP - AT_SETUP([trau]) AT_KEYWORDS([trau]) cat $abs_srcdir/trau/trau_test.ok > expout AT_CHECK([$abs_top_builddir/tests/trau/trau_test], [], [expout], [ignore]) AT_CLEANUP -AT_SETUP([sgsn]) -AT_KEYWORDS([sgsn]) -AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) -cat $abs_srcdir/sgsn/sgsn_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/sgsn/sgsn_test], [], [expout], [ignore]) -AT_CLEANUP - -AT_SETUP([oap]) -AT_KEYWORDS([oap]) -AT_CHECK([test "$enable_oap_test" != no || exit 77]) -cat $abs_srcdir/oap/oap_client_test.ok > expout -cat $abs_srcdir/oap/oap_client_test.err > experr -AT_CHECK([$abs_top_builddir/tests/oap/oap_client_test], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([gtphub]) -AT_KEYWORDS([gtphub]) -AT_CHECK([test "$enable_gtphub_test" != no || exit 77]) -cat $abs_srcdir/gtphub/gtphub_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/gtphub/gtphub_test], [], [expout], [ignore]) -AT_CLEANUP - -AT_SETUP([xid]) -AT_KEYWORDS([xid]) -AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) -cat $abs_srcdir/xid/xid_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/xid/xid_test], [], [expout], [ignore]) -AT_CLEANUP - -AT_SETUP([sndcp_xid]) -AT_KEYWORDS([sndcp_xid]) -AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) -cat $abs_srcdir/sndcp_xid/sndcp_xid_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/sndcp_xid/sndcp_xid_test], [], [expout], [ignore]) -AT_CLEANUP - -AT_SETUP([slhc]) -AT_KEYWORDS([slhc]) -AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) -cat $abs_srcdir/slhc/slhc_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/slhc/slhc_test], [], [expout], [ignore]) -AT_CLEANUP - -AT_SETUP([v42bis]) -AT_KEYWORDS([v42bis]) -AT_CHECK([test "$enable_sgsn_test" != no || exit 77]) -cat $abs_srcdir/v42bis/v42bis_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/v42bis/v42bis_test], [], [expout], [ignore]) -AT_CLEANUP - AT_SETUP([nanobts_omlattr]) AT_KEYWORDS([nanobts_omlattr]) cat $abs_srcdir/nanobts_omlattr/nanobts_omlattr_test.ok > expout AT_CHECK([$abs_top_builddir/tests/nanobts_omlattr/nanobts_omlattr_test], [], [expout], [ignore]) AT_CLEANUP - -AT_SETUP([sms_queue_test]) -AT_KEYWORDS([sms_queue_test]) -cat $abs_srcdir/sms_queue/sms_queue_test.ok > expout -cat $abs_srcdir/sms_queue/sms_queue_test.err > experr -AT_CHECK([$abs_top_builddir/tests/sms_queue/sms_queue_test], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([msc_vlr_test_no_authen]) -AT_KEYWORDS([msc_vlr_test_no_authen]) -cat $abs_srcdir/msc_vlr/msc_vlr_test_no_authen.ok > expout -cat $abs_srcdir/msc_vlr/msc_vlr_test_no_authen.err > experr -AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_no_authen], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([msc_vlr_test_gsm_authen]) -AT_KEYWORDS([msc_vlr_test_gsm_authen]) -cat $abs_srcdir/msc_vlr/msc_vlr_test_gsm_authen.ok > expout -cat $abs_srcdir/msc_vlr/msc_vlr_test_gsm_authen.err > experr -AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_gsm_authen], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([msc_vlr_test_gsm_ciph]) -AT_KEYWORDS([msc_vlr_test_gsm_ciph]) -cat $abs_srcdir/msc_vlr/msc_vlr_test_gsm_ciph.ok > expout -cat $abs_srcdir/msc_vlr/msc_vlr_test_gsm_ciph.err > experr -AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_gsm_ciph], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([msc_vlr_test_umts_authen]) -AT_KEYWORDS([msc_vlr_test_umts_authen]) -cat $abs_srcdir/msc_vlr/msc_vlr_test_umts_authen.ok > expout -cat $abs_srcdir/msc_vlr/msc_vlr_test_umts_authen.err > experr -AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_umts_authen], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([msc_vlr_test_hlr_reject]) -AT_KEYWORDS([msc_vlr_test_hlr_reject]) -cat $abs_srcdir/msc_vlr/msc_vlr_test_hlr_reject.ok > expout -cat $abs_srcdir/msc_vlr/msc_vlr_test_hlr_reject.err > experr -AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_hlr_reject], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([msc_vlr_test_hlr_timeout]) -AT_KEYWORDS([msc_vlr_test_hlr_timeout]) -cat $abs_srcdir/msc_vlr/msc_vlr_test_hlr_timeout.ok > expout -cat $abs_srcdir/msc_vlr/msc_vlr_test_hlr_timeout.err > experr -AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_hlr_timeout], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([msc_vlr_test_ms_timeout]) -AT_KEYWORDS([msc_vlr_test_ms_timeout]) -cat $abs_srcdir/msc_vlr/msc_vlr_test_ms_timeout.ok > expout -cat $abs_srcdir/msc_vlr/msc_vlr_test_ms_timeout.err > experr -AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_ms_timeout], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([msc_vlr_test_reject_concurrency]) -AT_KEYWORDS([msc_vlr_test_reject_concurrency]) -cat $abs_srcdir/msc_vlr/msc_vlr_test_reject_concurrency.ok > expout -cat $abs_srcdir/msc_vlr/msc_vlr_test_reject_concurrency.err > experr -AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_reject_concurrency], [], [expout], [experr]) -AT_CLEANUP - -AT_SETUP([msc_vlr_test_rest]) -AT_KEYWORDS([msc_vlr_test_rest]) -cat $abs_srcdir/msc_vlr/msc_vlr_test_rest.ok > expout -cat $abs_srcdir/msc_vlr/msc_vlr_test_rest.err > experr -AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_rest], [], [expout], [experr]) -AT_CLEANUP diff --git a/tests/v42bis/Makefile.am b/tests/v42bis/Makefile.am deleted file mode 100644 index a031e33bd..000000000 --- a/tests/v42bis/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBCARES_CFLAGS) - -EXTRA_DIST = v42bis_test.ok - -noinst_PROGRAMS = v42bis_test - -v42bis_test_SOURCES = v42bis_test.c - -v42bis_test_LDADD = \ - $(top_builddir)/src/gprs/v42bis.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOCORE_LIBS) - - diff --git a/tests/v42bis/v42bis_test.c b/tests/v42bis/v42bis_test.c deleted file mode 100644 index 7e907858d..000000000 --- a/tests/v42bis/v42bis_test.c +++ /dev/null @@ -1,435 +0,0 @@ -/* Test v42bis Compression/Decompression */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -/* V.42bis compression parameters */ -#define P0 3 /* Direction */ -#define P1 512 /* Max number of codewords */ -#define P2 20 /* Max string length */ - -/* V.42bis compression buffer size - * (Does not affect the compression/decompression result) */ -#define MAX_BLOCK_SIZE 1024 - -/* Compressed sample packets, sniffed from real communication */ -#define COMPR_PACKETS_LEN 33 -char *compr_packets[] = { - /* K800i */ - "4500010268000700004006cefac0a80002550d93d740000050462c7ba7e4d1753a80184000aad500000101080a0001a670084dafb4474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005ab97a052b960d59b368d5b2ddb3e60e9c372ef610b6dbf56bd8b165030f2e7cf88dd63b68f64c3d9b76ed1cb58847b490d122e8d0a24761185913d50e1aa423f0dc49036387d6d7b169e4d0cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a68b5b2864d9a3b629a30b1a2b5081b35384613357a07c6133271d4e021a3064d52347182ee81b119c69c3a72d2b079b37e4409c177e6f4902163738cdd71f8a0a903d68ec21866e4c0918185087dfb329cec9831834d951a337c4a2e1174891c3badf5e8d113a38f1c336e24520c8a65751d1844d4c7696d852c1f240e992becf8918d0c9145465441939fcc6a1950a206b7e1fca38e1145eaebc129230aeb24f57bcab011c3c68829f5efe7bfcbe4c814e731668c3042f6fef93a62d9909561e4c91123c163d0085a3a4e1c3466c6c649ea048d519d5ff3a0f95ef4280c2471269e61633ee9193469de8845a3554d9fa74199c48622e7fa7dac30ac602f9af40a9ef0236a54268247cd7f923946d0a8d1c3c68d1e35788c5002e54ad0a00100", - "4500010268000900004006cef8c0a80002550d93d740000050462c7ba7e4d1753a801840007e7f00000101080a0001d1cc084db0ae474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005ab97a052b960d59b368d5b2ddb3e60e9c372ef610b6dbf56bd8b165030f2e7cf88dd63b68f64c3d9b76ed1cb58847b490d122e8d0a24761185913d50e1aa423f0dc49036387d6d7b169e4d0cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a68b5b2864d9a3b629a30b1a2b5081b35384613357a07c6133271d4e021a3064d52347182ee81b119c69c3a72d2b079b37e4409c177e6f4902163738cdd71f8a0a903d68ec21866e4c0918185087dfb329cec9831834d951a337c4a2e1174891c3badf5e8d113a38f1c336e24520c8a65751d1844d4c7696d852c1f240e992becf8918d0c9145465441939fcc6a1950a206b7e1fca38e1145eaebc129230aeb24f57bcab011c3c68829f5efe7bfcbe4c814e731668c3042f6fef93a62d9909561e4c91123c163d0085a3a4e1c3466c6c649ea048d519d5ff3a0f95ef4280c2471269e61633ee9193469de8845a3554d9fa74199c48622e7fa7dac30ac602f9af40a9ef0236a54268247cd7f923946d0a8d1c3c68d1e35788c5002e54ad0a00100", - "4500010268000b00004006cef6c0a80002550d93d740000050462c7ba7e4d1753b80193fff131c00000101080a00022884084dc558474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005ab97a052b960d59b368d5b2ddb3e60e9c372ef610b6dbf56bd8b165030f2e7cf88dd63b68f64c3d9b76ed1cb58847b490d122e8d0a24761185913d50e1aa423f0dc49036387d6d7b169e4d0cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a68b5b2864d9a3b629a30b1a2b5081b35384613357a07c6133271d4e021a3064d52347182ee81b119c69c3a72d2b079b37e4409c177e6f4902163738cdd71f8a0a903d68ec21866e4c0918185087dfb329cec9831834d951a337c4a2e1174891c3badf5e8d113a38f1c336e24520c8a65751d1844d4c7696d852c1f240e992be4e8918d8c9045465441939fcc6a1950a206b7e1dca38e1145eaebb929230aeb24f579cab011c3c68829f5efe7afcbe4c814e731668c3042f6fef93a62d9909561e4c91123c163d0084a3a4e1c3466c6c649ea048dd19c5ff3a0f95ef4280c2471269e61633ee9193469de8845a3554d9fa74199c48622c7fa7dac30ac5c2f9af40a1ef0236a502682478dff913946d0a8d1c3c68d1e35788c5002e54ad0a00100", - "4500010268000c00004006cef5c0a80002550d93d740000050462c7ba7e4d1753b80193fff65ab00000101080a0002d5f4084dc558474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005ab97a052b960d59b368d5b2ddb3e60e9c372ef610b6dbf56bd8b165030f2e7cf88dd63b68f64c3d9b76ed1cb58847b490d122e8d0a24761185913d50e1aa423f0dc49036387d6d7b169e4d0cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a68b5b2864d9a3b629a30b1a2b5081b35384613357a07c6133271d4e021a3064d52347182ee81b119c69c3a72d2b079b37e4409c177e6f4902163738cdd71f8a0a903d68ec21866e4c0918185087dfb329cec9831834d951a337c4a2e1174891c3badf5e8d113a38f1c336e24520c8a65751d1844d4c7696d852c1f240e992be4e8918d8c9045465441939fcc6a1950a206b7e1dca38e1145eaebb929230aeb24f579cab011c3c68829f5efe7afcbe4c814e731668c3042f6fef93a62d9909561e4c91123c163d0084a3a4e1c3466c6c649ea048dd19c5ff3a0f95ef4280c2471269e61633ee9193469de8845a3554d9fa74199c48622c7fa7dac30ac5c2f9af40a1ef0236a502682478dff913946d0a8d1c3c68d1e35788c5002e54ad0a00100", - "450001022d000f00004006ac5ec0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00", - "450001022d001000004006ac5dc0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00", - "450001022d001100004006ac5cc0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00", - "450001022d001200004006ac5bc0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00", - "4500010268001300004006ceeec0a80002550d93d740000050462c7ba7e4d1753b80193fff7b4a00000101080a0003c054084dc558474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005bbb7e0d3b964dd9b369d7b6ddb3e60e9c372ef614beeb15ac58b2660513368cf8cdd63b68f65045ab96ed9cb58947b490d1422851a34861185923d50e9aa423f0dc490363c756d8b269e4d8cac68e9cd93b70f0804143376fe13372dcc801038f193b306a6cb5b2864d9a3b629a30b1b2b5081b353848173d7a07c6133271d4e021a3068d52347184ee81c119c69c3a72d2b079c37e4489c177e6f4902183730cde71f8a0a913d6cec21866e4c091818548fdfb329cec9831834d951a337e4e2e2174891c3baef5e8d113a38f1c336e2656148a85751d1844d6c7716da52c1f240f9b2fecf8918d0c9145465441a39f0c6b1950a40ab7f1fca38e1145ecebc129234aeb24f67bcab011c3c68829f6f1ebb7cbe4c894e731668c3052163ffa3a63d9949561e4c91123c263d0105a3a4e1c3466c8c651ea04cd519d60f3a0016f14290c2471289e61735ee9193469de8c45b3554d1fa84299c88622e73afeac30ac6037aaf40a9ef0236a54268247cd7f923946d0a8d1c3c68d1e35788c5002e58a50a10100", - "450001022d001400004006ac59c0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00", - "450001022d001500004006ac58c0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00", - "4500010239000500004006ac5cc0a800020a0901ab40001f90c286afa741a348cb801840007fcb0000050a41a348dc41a34a440000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d69786564330057b36eedfa954dd8b165cfa6ddb3e60e9c372ef6049eab95ab57b062fd02164cf8cdd53b68f640256b16ed9cb38547b490d1e22791a043efc030b2c6a91d344547e0b99306c68eabad5fd3c871958d1d39b077e0e00183c6eddcbf67e4b89103061e337660d4b86a650d9b3477c4346162e56a11366a7080164d14c6133271d4e021a3068d5134717eee818119c69c3a72d2b079837e4489bf77e6f4902103738cdc71f8a0a9d3d58ec11866e4c091818548fcf9329cec9831834d951a33783e2ef173891c3bab69cc88c1a3674f1d347a6cdcf8134bea3a30889c8fb3da4a583e48162a37a891231b19208b8ca882c63e99d432a038fd6d8339471d238ac8d793534614d549e40b956123868d1153e4d3b77f97c99129cc63cc1861242c7df275beb2092bc3c89323467ef7fc693a4e1c3466c0c631ea04cdd09d5cf3a0e96e66e81d1848e2403cc366bcd13368d2bcf98ae6aa9a3e4c7ffe0c00", - "450001025b000a00004006ac35c0a800020a0901ab40011f90c293b0a8af5e58be5018400072a60000474554202f72656470686f6e652e706e6720485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c33005cbd82154b368e59b46ad9ee597307ce1b177b066fedfa35ec583665010b266cf8cdd63b68f6543d9b76ed1cb58747b490d16268d1a34961185933d50e1aa523f0dc490363c7d6d7b169e4d8cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a6cb5b2864d9a3b629a30b1b2b5081b3538461b457a07c6133238f190518366299a3843f7c0d80c634e1d3969d8bc513fa244e03b737ac890b139c6ee387cd0d4096b07610c3372e0c8c042647e7d194e76cc98c1a64a8d1940259718ba448e9dd63466c4e01134a80e1a3d38721c8a65751d1844d2c7696d65261f240d9923dcd8918d0c9045465441839fcc6a1950a606b7e1bca38e1145e8ebd929230aeb24f485cab011c3c68829f4ede3d7cbe4c814e731668c3032d3be1a3c75c6b2296be4c91123c1830e451d270e1a3364e32c758206694fb079d07c3f9a1406923812cfb0c1b9f40c9a346fc6a2d9aaa64fd4a175d33064b894bfff812b5bc2a421b3e60c8e32860e0d00", - "4500010267001200004006ac21c0a800020a0901ab40011f90c293b0a8af5e58be80184000ee770000050aaf5e6437af5e8c230000474554202f72656470686f6e652e706e6720485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d33006fc8de41b3c72b5cb974e7cc853ca2858c164c9d42950ac3c81aae76d04c1d81e74e1a183bc8e2d64d2307593676e4ecde8183070c1ac2892b9f91e3460e1878ccd8815183ac95356cd2dc11d3848915b245d8a8c1c1fa69d43b309e90098a878c1a3454d1c461ba0706691873eac849c3e6cdfc112514df99d343860cd23188c7e183a68e5a3b126398910347061622fcfdcb70b263c60c36556acc48bab904d32572ecd8a63123060fa54a75d0e861d224532cb4ebc020223f8e6d2b3cf920b1585d62c9936c64a82c32a20a9a826468cb80c255b98deb27758c28d25f4f5119516a27e9df54868d1836464ce9ffbf20612647a65c8f316384119effd5e0a9c3968d5b234f8e1851ae94a9ec3871d098691b87aa1334518fa6cd83063d54a93090c4d978864d50aa67d0a479c3160d59357db432fd9ba66245aa0a193aac7953278d9e3f679894c1946900", - "4500010236003000004006cf03c0a80002550d93d740020050c30e84a9441d06ac80184000c2f400000101080a00052df410fc31bd474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005cbd82154b968d59b46ad9baddb3e60e9c372ef618c6fb35ecd8b26707173e9cf80dd73b68f6544dbbb6ed1cb68a47b490d16268d1a34961185933d50e1aa523f0dc49036307d7d8b369e4e0cac68e1cda3b70f080416377efe13372dcc801038f193b306a70b5b2864d9a3b629a30b1c2b5081b35384a1b457a07c6133271d4e021a306cd52347186ee81d119c69c3a72d2b079d37e4409c277e6f49021a3738cde71f8a0a923d60ec31866e4c0918185887dfc329cec9831834d951a3380522e3174891c3baff5e8d113a38f1c336e285a1c8aa5751d1844d8c7796dc52c1f24109d33f408928d8c9145465441b39f4c6b1950a60eb7011da48e1145eeebc929238aeb24f77dcab011c3c68829f7f3efbfcbe4c814e831668c3062367ffa3a64d9989561e4c91123c363d0186a3a4e1c3466cac659ea040dd29d61f3a0097f34290c24712a9e61837ee9193469de9045c3554d9fa843870600", - "4500010260004500004006cec4c0a80002550d93d740030050c3134faac89c8b2980184000578d00000101080a000535c010fc34c8474554202f6e697276616e612e63737320485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d33006fcede41b3072c5dbb78e7dcad3ca2858c164ea14aa50ac3c81aaf76d0541d81e74e1a183bcef2f64d23c7593676e4fcde8183070c1ac6913b9f91e3460e187884c2a871d6ca1a3669ee8869c2c4cad9226cd4e0801d75ea1d184f7caac143460d1aab68e238dd0303358c3975e4a461f3c6fe88128fefcce9214306ea18c8e3f04153a7edd0b841e5c0918185c87f83329cec9831834d951a33967e2ee174891c3bbaf5e8d113a38f1c336e3ac2718a05771d1844eac7d16d252e1f241985563489928d8c954546544193900c6e1950bc3ab7a11da58e11450aea292a234aee240595cab011c3c68829050f2624cce4c814ed31668c3012f7a0fc3a6fd9c49561e4c91123ce63d0702a3b4e1c3466e0c6b1ea04cdd4a36cf3a0592f952a0c2471ccc839c3268e1aab67d0a479f316cd59357db83af59b062346ab0d1f46b47933e7ce9e329c3a0d00", - "4500010264004600004006cebfc0a80002550d93d740040050c3135bab2189da61801840008f2d00000101080a000535c410fc34dc474554202f382d4269742f4c6162656c2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300952fbf517b07cd1e9f77f3ee9da317f38816325a48a56a152b0c236bc4da419375049e3b6960ec50fb3b388d1c6ad9d891237c070e1e3068245f1e7d468e1b3960e0316307460db556d6b04973474c132656d4f254836376d5ab7760008da3060f193568b4a28923750f8cd530e6d4919386cd9bfc234a48be33a7870c19ab632c8fc3074d1db87630c63023078e0c2c440c2294e164c78c196caad498f1547409a94be4d8e9ad478f9e187de498710352a4542cbbebc020823f4e6f2b74f920e1c81da34a966c64bc2c32a20a1a866476cb802236ba0def2c758c2872500f521951782739d854868d1836464c39a89061612647a6788f31638411ba0aebd791cb86ae0c234f8e18891e838654da71e2a03133378e562768ae2a7d9b078d7bab5861208913f20c1bfa5acfa049f3462e1ab56afa80950a38cdc68d5a214aa4a873e74fa144474a951a00", - "4500010264005800004006ceadc0a80002550d93d740050050c31389acaf7b26538018400075c900000101080a000537d010fc354a474554202f382d4269742f41636f726e2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300942dbf497b07cd1e9f76f1ea9d93f7f28816325a48a56af50e0c236bc2da418375049e3b6960ec48eb1b388d1c69d9d891137c070e1e306820570e7d468e1b3960e0316307468db456d6b04973474c132656d2f2548343b699aa57613c2113470d1e326ad064451347ea1e18aa61cca923270d9b37f94794887c674e0f193254c7501e870f9a3a6fed608c11148e0c2c440c2294e164c78c196caad498f1347409a94be4d8e1ad478f9e187de4987103520e1ca95874d78141047f1cde56e6f241c2713bc6942bd9c87059644415340cc9e89601252c741bdd57ea1851e4a09ea432a2ec4e72d0a90c1b316c8c9872502143c34c8e4ce91e63c608237315d6af1397cd5c19469e1c31023d060da9b4e3c44163466e9cac4ed0585dea360f9af6efefc0401227e81936f4b39e4193e64d5c3469d5f4f92a15709a8d1bb342944831a7ce9e42898a942a3500", - "4500010266007600004006ce8dc0a80002550d93d740060050c31431ada11fa06780184000f08e00000101080a00053b3c10fc35ef474554202f382d4269742f416d73747261642e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d33009733bf597b07cd9e9e78f5f2d5a379440b192da656bd9a1586913563eda0d13a02cf9d343076ac052e9c468eb56cecc819be03070f18349433973e23c78d1c30f098b103a3c65a2b6bd8a4b923a609132b6b77aac141db2ad63b309e9089a3060f193568b6a28933750f0cc830e6d4919386cd9bfd234a50be33a7870c199063308fc3074d9db87636c63023078e0c2c44103294e164c78c196caad49801957489a94be404ddaa478f9e187de4987133b2e4542cbcebc020a23f8e6f2b75f920f9d87d63cb976c64c82c32a20a9a876478cb803256ba8def2f758c28a2500f5319517a27512855868d1836464c51d8f061622647a67c8f31638491ba0defd799cba6ae0c234f8e18911e83c6d4db71e2a0314337ce562768b03a859b07cdfbab5961208943f20c1bfb5bcfa049f3662e9ab56afa849d3a388d478f5b2756bcf813e850a3484d4e9d1a00", - "4500010264007700004006ce8ec0a80002550d93d740040050c3135ddb2189e0108018400060d600000101080a00053b4010fc35e7474554202f382d4269742f41746172692e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300932bbf497b07cd1e9f76f1ea9d93d7f28816325a48a56a152b0c236b84da419375049e3b6960ec48dbfb378d1c69d9d891037c070e1e30681c4ffe7c468e1b3960e0316307468db456d6b04973474c132656d2f254832376d5ab77603c2113470d1e326ad068451347ea1e18a961cca923270d9b37f84794807c674e0f193252c7481e870f9aa1da2fc63023078e0c2c440a1e94e164c78c196caad498f1147409a94be4d8d9ad478f9e187de49871e311a4542cb9ebc020723fce6e2b73f920d968e7224a956c64b42c32a20a9a856472cb8022f4b90dee2a758c286250cf511951742731c854868d1836464c31887061612647a6708f31638491b908e9d789cb66ae0c234f8e18791e8386d4d971e2a03123378e562768ae26759b070d7bab58612089f3f10c9bf95acfa049f3262e9ab46afa8095fa378d468d5a1f469c8833e7ce9f41434a951a00", - "4500010264007c00004006ce89c0a80002550d93d740070050c314f3aefa37ceb18018400009f900000101080a00053e3410fc369e474554202f382d4269742f4170706c652e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300942dbf517b07cd1e9f76f1ea9d93f7f28816325a48a56a152b0c236bc4da419375049e3b6960ec50dbfb378d1c6ad9d891037c070e1e30681c4ffe7c468e1b3960e0316307460db556d6b04973474c132656d4f254832376d5ab77603c2113470d1e326ad068451347ea1e18a961cca923270d9ba15a4b44be33a7870c19a963248fc3074d9db7762cc63023078e0c2c400da691e164c78c196caad498f1147409a94be4d8d9ad478f9e187de49871e311a4542cb9ebc020723fce6e2b73f920d1a8dd224a956c64b42c32a20a9aa16472cb8022f6b90dee2a758c2862504f521951742731e854868d1836464c29a910cd602647a6708f31638491b908e9d789cb66ae0c234f8e18791e8386d4d971e2a03123378e562768ae2e7dc3260f1af656b1c24012e7e31936f3b59e4193e64d5c346ad5f4012bd56f9a8c19b53a84281167ce9d3f8b86942a3500", - "4500010265007d00004006ce87c0a80002550d93d740050050c3138bdcaf7b296780183cec0de600000101080a00053e3410fc368e474554202f382d4269742f447261676f6e2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d33009631bf597b07cd1e9f8df5f2d59379440b192da656bd9a1586913563eda0d13a02cf9d343076ac052e9c468eb56cecc819be03070f18349433973e23c78d1c30f098b103a3c65a2b6bd8a4b923a609132b6b79aac141db2ad63b309e9089a3068f50345bd1c499ba07c6631873eac849c3e68dfe112526df99d343868cc73198c7e183a64e5c3b1963989103470616220715ca70b263c60c36556acc804abac4d42572ecf8d6a3474f8c3e72ccb80939722a16de75601051c3dfb715a27c9074ec9e71654b363260161951054d4332bc6540192bddc6f7963a461441a847a98c28bd93208ce3d3460c1b23a6205cd89030932353bec79831c208d185f7ebcc6553d7c8932346a4c7a03175769c3868ccd08db3d5091aac4ce1e641f3fe6a561848e2883cc3c6fed63368d2bc998b66ad9a3e61a7fe4dc391e3d688132beeec0974a8519253a70600", - "4500010269008000004006ce80c0a80002550d93d740060050c3143301dfa11fa3de80183c892b5d00000101080a0005412c10fc3761474554202f382d4269742f456e74657270726973652e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f6600952f67defcc66dd03d3df7f6fd3bc72fe7112d64b4b08a552b571846d6983dda75049e3b6960ec701b7c388d1c6e8dca21be03070f183496db694e63468e1b3960e0316307460db756d6b04973474c132656dcee5483c376d6ad77603c2113470d1e326ad0784513c7ea1e18ae6110959386cd1bfe234a58be33a7870c19ae63548fc347285d3b1b63989103470616220ad3c870b263c60c36556acc986aba84d52572ecfcd6a3474f8c3e72ccb81149d22a96a3756010d91fe7b715bc7c90d4f9b891a54b36326216195105cd4332476540312bdd0678973a4614a923478f531951d0dc49d299aa0c1b316c8c98d2b9e143c64c8e4c011f63c60823781be2af63970d5e19469e1c31223d060dabbce3c44163e66e1caf4ed06c853a370f1af85ab9c2401267e41936f7bd9e4193e68d5d346ed5f4216bd5701aa142bd4eac78d1e7cfa1489596b46a3500", - "4500010268008100004006ce80c0a80002550d93d740040050c313600b2189e30280183d0e896b00000101080a000541d810fc379d474554202f382d4269742f436f6d6d6f646f72652e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f3300952f67defcc6ed1d347b7ceeedfb778e5fce235ac8686115ab56ae308cac316b074dd71178eea481b1c3edf0e23472b86563478ef11d3878c0a0d1fc79f519396ee48081c78c1d1835dc5a59c326cd1d314d985871cb530d8edb59b7de81f1844c1c3578c8a841e3154d1cab7b60bc8631a78e9c346cdef81f51c2f29d393d64c8781de3791c3e68ead0b5d3318699a032b01061e85086931d3366b0a95263c654d325ac2e916327b81e3d7a62f49163c64dc9a056b1fcae038348ff38c1ade0e5832424f88e2e61b29131b3c8882a682292f92d038ad9ea36c4c3d431a248433d4c6544019ea46154193662d81831a5e1c38889991c99223ec68c1146f03ed45fc72e1bbc328c3c3962a47a0c1a5671c78983c6ccdd385e9da0d9ea746e1e34f2b5728581248ec9336cf27b3d8326cd1bbb68dcaae943d62ae13420417aad78312350a1448d228523c3aad500", - "4500010263008200004006ce84c0a80002550d93d740050050c3138e0daf7b2cf180183962cb2f00000101080a000542b410fc3822474554202f382d4269742f454143412e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b330096dfa4bd83668f4fbb78f5cec97b79440b192da24ead7a1586913561eda0c13a02cf9d343076a4f50d9c468eb46cecc809be03070f1834902b873e23c78d1c30f098b103a3465a2b6bd8a4b923a609132b6979aac1219baad53b309e9089a3060f193568b2a28913750f0cd530e6d4919386cd9bfc234a44be33a7870c19aa63288fc3074d9db77630c63023078e0c2c440c2294e164c78c196caad498e1347489a84be4d8e1ad478f9e187de49871035264542cbaebc020823f0e6f2b73f920e1b81da34a966c64bc2c32a20a1a866474cb801216ba8dee2c758c287250cf511951762739c854868d1836464c39a89021612647a6748f31638491b90aebd789cb66ae0c234f8e18811e8346d4d971e2a03123374e562768ac26759b074dfbaa5761208913f20c1bfa59cfa049f3262e9ab46afa7c8dfa37cdc68d59214aa4a873e7cfa04347468d1a00", - "4500010262008500004006ce82c0a80002550d93d740070050c314f5defa37d29b80183c168b6100000101080a000542c810fc37e5474554202f382d4269742f4d53582e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b330095dfa0bd83668fcfba77f3cec16b79440b192da04aa56a1586913560eda0b93a02cf9d343076a0edfd9b460eb46cecc801be03070f18348e277f3e23c78d1c30f098b103a3065a2b6bd8a4b923a609132b6879aac1117b6ad53b309e9089a3060f193568b0a28903750f8cd430e6d4919386cd1bfc234a40be33a7870c19a963248fc3074d1db7762ec63023078e0c2c440a1e94e164c78c196caad498d1147409a84be4d8d9ad478f9e187de49871f33124542cb9ebc020723fce6e2b72f920d9a8fd62ca956c64b82c32a20a9a856472cb8002f6b90dee2b758c2862508f511951742731b854868d1836464c318870e1602647a6708f31638411b908e9d781cb46ae0c234f8e18791e830654d971e2a03113370e562768aa226d9b070d7baa5661208903f20c9bf958cfa049f3062e1ab46afa7885ea378d468d581f469c9853674fa0424542851a00", - "4500010265009400004006ce70c0a80002550d93d740060050c3143614a11fa986801836e1f43c00000101080a000545b010fc38b7474554202f382d4269742f4d617474656c2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300942dbf512b744fcfbb79f7ced17b79440b192da452b58a1586913562eda0c93a02cf9d343076a8edfd9b460eb56cecc801be03070f18348e277f3e23c78d1c30f098b103a3865a2b6bd8a4b923a609132b6a77aac111bbead53b309e9089a3060f193568b4a28923750f8cd430e6d4919386cd1bfc234a44be33a7870c19a963248fc3074d1db87630c63023078e0c2c440a1e94e164c78c196caad498f1347409a94be4d8d9ad478f9e187de498710352a4542cb9ebc020723fce6e2b74f920e1a81da34a966c64bc2c32a20a1a866472cb8022f6b90dee2c758c2862504f521951742731e854868d1836464c31889021612647a6708f31638411ba08e9d791bbd8c89323469ec7a02195769c3868cc7ca5abd5099aab4bdfe641c3de2a561848e2843cc366bed63368d2bc018a46ad9a3e60a5fe4db371a356881229eae4f97368d19152a50600", - "4500010263009900004006ce6dc0a80002550d93d740040050c313623f2189e66b801839a5739a00000101080a0005464c10fc38f3474554202f382d4269742f4f7269632e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b330095dfa4bd83668f4fc578f5eab13ca2858c1651a756bd0ac3c89ab076d0601d81e74e1a183bd2fa064e23475a3676e404df8183070c1ac895439f91e3460e1878ccd8815123ad95356cd2dc11d3848995b43cd5e0904dd5ea1d184fc8c45183878c1a3459d1c489ba0706631873eac849c3e64dfe112520df99d343860cc63194c7e18326e8768c31ccc88123030b1183086538d93163069b2a356638155d22ea12397678ebd1a327461f3966dc7c0c19158bee3a3088e08fc3db8a5c3e4838dac19872251b192e8b8ca882862119dd32a084856ea3fb4a1d238a1cd483544694dd490e36956123868d11530e2a642898c99129dd63cc186144aec2fa75e0b2912bc3c8932346a0c7a01135769c3868ccc48d93d5091aab4adde641d3beea551848e2803cc3867ed63368d2bc818b26ad9a3e5fa3f64db3716356881229e6d4d91328519151a30600", - "4500010269009e00004006ce62c0a80002550d93d740060050c3143845a11fab60801840003c1c00000101080a000547d810fc38b7474554202f382d4269742f526164696f536861636b2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f330096316be6fcc6ed1d347b7a46f60b584fe7112d64b4b08a552b5718468ad6b183a6eb083c77d2c0d8e17678711a39dcb2b123c7f80e1c3c60d068febcfa8c1c3772c0c063c60e8c1a6e89b24973474c132656dcee5483e376d6ad77603c2113470d1e326ad0784513c7ea1e189361cca923270d9b37fd4794b87c674e0f193226c7781e870f9a3a74ed748c61460e1c195888307428c3c98e1933d854a93163eae9125697c8b1135c8f1e3d31fac831e3a6e449ab587ed78141847f9ce056f0f24112127cc79731d9c8a0596444153411c9fc9601c56c751be263ea1851a4a19ea732a2004fd2b0aa0c1b316c8c98d2f061c4c54c8e4c111f63c60823781fe6af6357685e234f8e18a91e838655dd71e2a03173378e572768b6469d9b074d7cad5c61208963f20c1bfc5ecfa049f3c62e1ab76afa90b55a380d48905e2b5ecc1874e8d1a44b515ab51a00", - "4500010266009f00004006ce64c0a80002550d93d740050050c313903caf7b2f9580183d5ce4ef00000101080a0005481810fc3934474554202f382d4269742f5068696c6970732e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300952fbf597b07cd1e9f8cf5f2d58379440b192da85ac5aa1586913563eda0d93a02cf9d343076acfd1d9c468eb56cecc811be03070f1834922f8f3e23c78d1c30f098b103a3c65a2b41d3dc11d3848995b53cd5e0987d35eb1d184fc8c45183878c1a345cd1c4a1ba0786631873eac8492334ff881292efcce9214386e318cbe3f0415307b19d8b31ccc88123030b1183086538d93163069b2a3566441d5d82ea1239767aebd1a327461f3966dc7c0c4915cbee3a3088e08fd3db0a5d3e483672bf9872251b192e8b8ca882e60d1a32bb6540191bdd86f7953a461439a847a98c28bc931c7c2ac3460c1b23a61c5428f830932353bcc79831c2085d85f5ebc8654357869127478c448f4183eaed3871d098991b87ab133459990ecd83a63d56ad3090c40179860d7dae67d0a4792317cd5a357d8852059c46a346ae0f234ecca9b32750a322a9520d00", - "450001049b00ae00004006cc20c0a80002550d93d740050050c31396ceaf7b396e801840009ad400000101080a0005611010fc3d6b474554202f382d4269742f6d72776f6e672e67696620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d33009733bf617b07cd9e9f8ef7f6d5a379440b192da85ac5aa1586913564eda0d93a02cf9d343076b00d3e9c460eb66cecc821be03070f183496379f3e23c78d1c30f098b103a3065b2b6b92de11d3848915b63dd5e0a87d35eb1d184fc814c543460d1aae68e250dd0303328c3975e4a461f346ff881294efcce9214306e418cde3f0415347ae1d8c31ccc88123030b1183086538d93163069b2a3566442d5d82ea1239767eebd1a327461f3966dc801449154bef3a3088e48ff3db0a513e48387ac7a892251b192f8b8ca882862199de32a0909d6e033c4b1d238a1cd4a3544614df490e3e956123868d11530e2a644898c99129e063cc186184a8423578ead06563d7c8932346a6c7a04175769c3868ccd48dc3d5099aac4ce3e641f31eab561848e2843cc3a628d73368d2bca18b86ad9a3e62a9fe4db3712357881229eadce933e8d09154a92a417265848c1d307afec489074e198678e6108d31a7e8882557ae4c9111357903abdf7f7b052b96ec4f3868d51e7e1b77ae74198ef7f63d1a76ce52bf50cf4c9d7355b7ddb290634cae7cb9b4dec05f135b76c178c41d347b7e16eeabc732db16325a74cf7a07869135647bff0e3e7c075bdad3732c6f4e7c070e1ed37dcb993e23c78d1c30f07807cfd6ca1a3669ee8869c2c40adb9e6a70a8d60ae30999a278c8e4e78a260ed53d3020c33088900d43ae25204aa46818239f8d6cbc631c3a120b11ff6964a864c9e6e58ca8a54b505d220727579d3b7d06bd48158b52a6f99f72b542940f923a13ed600c39838d8c974546fc6548a63761b2d36d8067a96344913a72f428951105cd9d248a9fcab011c3c688298ad30c444398c99129e063cc18313bce683578eae8b66be4c91123d363246f003b0e1a33d2b93a41939569dc3c68d6df8181248e193967d814e57a064d9a3774d1b055d387cd1caa7fd36cdcc835618f853a63d07473510655aa0100", - - /* SGSN with IAXMODEM V.42bis */ - "45000101a0f3d84000400679210a0901abc0a800021f90400538e210f07a827bb1501900ed7be90000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205765642c203301312041756720323031362030393a32383a353220474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a66003f481c9162e40a97294800002068746d6c20506600588a3c6162644409183200002f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d66006f8234f87187cd1d006c653e4469726563746f7279206c697374696e672066016f72202f3c2f7469746c990068bcff2823e70c9fff6b6a943f9f7e7dfbf7f1e7d7bf9f5fb1c2ef6beafcc7d3fd3b7ced646aa34f03a404fa3373a4c64113630efdec27534e7509538d7e32ff657044a8f1bb0c82067f72f71e00", - "45000101a0e9a54000400683540a0901abc0a800021f904004437442f17a4ab3b1501900ed04900000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205765642c203301312041756720323031362030393a32373a353520474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a66003f481c9162e40a97294800002068746d6c20506600588a3c6162644409183200002f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e672066016f72202f3c2f7469746c990068beff2823e70c9f816b6a9847af9ebd7bf8f2e9dbc7af5ff142f06bea0cc4e31d7cfced646aa74f03a444fa3373a4c64113634e7ded28554e7d1953cd7e320365744cb811bc8c82078376ff1e00", -}; - -/* Uncompressed sample packets, sniffed from real communication */ -#define UNCOMPR_PACKETS_LEN 11 -char *uncompr_packets[] = { - "45000236000700004006cf2cc0a80002550d93d7400000501e200da7c0c95a70801840002e3700000101080a000174140853d489474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a", - "4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27", - "4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0", - "4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01", - "4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01", - "4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a", - "4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20", - "450001a0b41140004006b8e80a0901abc0a800021f904002d5b860b5bab240ae501900ed861d0000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205475652c2033302041756720323031362030393a34333a303720474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a3c21444f43545950452068746d6c205055424c494320222d2f2f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e6720666f72202f3c2f7469746c653e0a3c626f64793e0a3c68323e4469726563746f7279206c697374696e6720666f72202f3c2f68323e0a3c68723e0a3c756c3e0a3c6c693e3c6120687265663d2272656470686f6e652e706e67223e72656470686f6e652e706e673c2f613e0a3c2f756c3e0a3c68723e0a3c2f626f64793e0a3c2f68746d6c3e0a", - "450000e2971b40003706026c550d93d7c0a8000200504047217f5922c903759c8018007c4fb400000101080a1153ce39002cf6e8485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613134392d3436652d34323736386138656338656330220d0a0d0a", - "450000e224f1400037067496550d93d7c0a80002005040489387ebf0c904389f8018007cec5700000101080a1153cf01002cf8fc485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613338302d3861362d34323736383761323236383830220d0a0d0a", - "450000e2b66140003706e325550d93d7c0a8000200504049fbb679bcc9051ea48018007cebea00000101080a1153cfdc002cfdb4485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343120474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338313336642d3138642d34353832306530393638303430220d0a0d0a", -}; - -/* Calculate IP Header checksum */ -static uint16_t calc_ip_csum(uint8_t *data, int len) -{ - int i; - uint32_t accumulator = 0; - uint16_t *pointer = (uint16_t *) data; - - for (i = len; i > 1; i -= 2) { - accumulator += *pointer; - pointer++; - } - - if (len % 2) - accumulator += *pointer; - - accumulator = (accumulator & 0xffff) + ((accumulator >> 16) & 0xffff); - accumulator += (accumulator >> 16) & 0xffff; - return (~accumulator); -} - -/* Calculate TCP/IP checksum */ -static uint16_t calc_tcpip_csum(const void *ctx, uint8_t *packet, int len) -{ - uint8_t *buf; - uint16_t csum; - - buf = talloc_zero_size(ctx, len); - memset(buf, 0, len); - memcpy(buf, packet + 12, 8); - buf[9] = packet[9]; - buf[11] = (len - 20) & 0xFF; - buf[10] = (len - 20) >> 8 & 0xFF; - memcpy(buf + 12, packet + 20, len - 20); - csum = calc_ip_csum(buf, len - 20 + 12); - talloc_free(buf); - return csum; -} - -/* A simple function to show the ascii content of a packet */ -void show_packet(uint8_t *packet, int len) -{ - int i; - char c; - for (i = 0; i < len; i++) { - c = packet[i]; - if (c >= 0x20 && c <= 0x7E) - printf("%c", c); - else - printf("."); - } - printf("\n"); -} - -/* A struct to capture the output data of compressor and decompressor */ -struct v42bis_output_buffer { - uint8_t *buf; - uint8_t *buf_pointer; - int len; -}; - -/* A simple testpattern generator */ -static void gen_test_pattern(uint8_t *data, int len) -{ - int i; - for (i = 0; i < len; i++) - data[i] = i & 0xF0; -} - -/* Handler to capture the output data from the compressor */ -void tx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len) -{ - struct v42bis_output_buffer *output_buffer = - (struct v42bis_output_buffer *)user_data; - memcpy(output_buffer->buf_pointer, pkt, len); - output_buffer->buf_pointer += len; - output_buffer->len += len; - return; -} - -/* Handler to capture the output data from the decompressor */ -void tx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len) -{ - /* stub, never used */ - OSMO_ASSERT(false); - return; -} - -/* Handler to capture the output data from the compressor */ -void rx_v42bis_frame_handler(void *user_data, const uint8_t *pkt, int len) -{ - /* stub, never used */ - OSMO_ASSERT(false); - return; -} - -/* Handler to capture the output data from the decompressor */ -void rx_v42bis_data_handler(void *user_data, const uint8_t *buf, int len) -{ - struct v42bis_output_buffer *output_buffer = - (struct v42bis_output_buffer *)user_data; - memcpy(output_buffer->buf_pointer, buf, len); - output_buffer->buf_pointer += len; - output_buffer->len += len; - return; -} - -/* Test V.42bis compression and decompression */ -static void v42bis(const void *ctx, int mode, uint8_t *testvec, int len) -{ - v42bis_state_t *tx_state; - v42bis_state_t *rx_state; - uint8_t *uncompressed_original; - uint8_t *compressed; - uint8_t *uncompressed; - - uncompressed_original = talloc_zero_size(ctx, len); - uncompressed = talloc_zero_size(ctx, len); - - /* Note: We allocate double the size for the compressed buffer, - * because in some cases the compression may increase the amount. - * of data. */ - compressed = talloc_zero_size(ctx, len * 2); - - int rc; - int rc_sum = 0; - struct v42bis_output_buffer compressed_data; - struct v42bis_output_buffer uncompressed_data; - - /* Initalize */ - tx_state = - v42bis_init(ctx, NULL, P0, P1, P2, - &tx_v42bis_frame_handler, NULL, MAX_BLOCK_SIZE, - &tx_v42bis_data_handler, NULL, MAX_BLOCK_SIZE); - OSMO_ASSERT(tx_state); - rx_state = - v42bis_init(ctx, NULL, P0, P1, P2, - &rx_v42bis_frame_handler, NULL, MAX_BLOCK_SIZE, - &rx_v42bis_data_handler, NULL, MAX_BLOCK_SIZE); - OSMO_ASSERT(rx_state); - v42bis_compression_control(tx_state, mode); - - /* Setup input data */ - memcpy(uncompressed_original, testvec, len); - - /* Run compressor */ - compressed_data.buf = compressed; - compressed_data.buf_pointer = compressed; - compressed_data.len = 0; - tx_state->compress.user_data = (&compressed_data); - rc = v42bis_compress(tx_state, uncompressed_original, len); - printf("v42bis_compress() rc=%d\n", rc); - OSMO_ASSERT(rc == 0); - rc = v42bis_compress_flush(tx_state); - printf("v42bis_compress_flush() rc=%d\n", rc); - OSMO_ASSERT(rc == 0); - - /* Decompress again */ - uncompressed_data.buf = uncompressed; - uncompressed_data.buf_pointer = uncompressed; - uncompressed_data.len = 0; - rx_state->decompress.user_data = (&uncompressed_data); - rc = v42bis_decompress(rx_state, compressed_data.buf, - compressed_data.len); - printf("v42bis_decompress() rc=%d\n", rc); - rc = v42bis_decompress_flush(rx_state); - rc_sum += rc; - printf("v42bis_decompress_flush() rc=%d\n", rc); - rc_sum += rc; - - /* Check results */ - printf("Mode: %i\n", mode); - - printf("uncompressed_original= %s ASCII:", - osmo_hexdump_nospc(uncompressed_original, len)); - show_packet(uncompressed_original, len); - printf("uncompressed= %s ASCII:", - osmo_hexdump_nospc(uncompressed_data.buf, - uncompressed_data.len)); - show_packet(uncompressed_data.buf, uncompressed_data.len); - printf("compressed= %s ASCII:", - osmo_hexdump_nospc(compressed_data.buf, compressed_data.len)); - show_packet(compressed_data.buf, compressed_data.len); - - rc = memcmp(uncompressed, uncompressed_original, len); - printf("memcmp() rc=%d\n", rc); - rc_sum += rc; - OSMO_ASSERT(rc_sum == 0); - - /* Free buffers and exit */ - v42bis_free(tx_state); - v42bis_free(rx_state); - talloc_free(uncompressed_original); - talloc_free(compressed); - talloc_free(uncompressed); - printf("\n"); -} - -/* Test V.42bis compression and decompression with generated data*/ -static void test_v42bis(const void *ctx) -{ - printf("Testing compression/decompression with generated data:\n"); - uint8_t testvec[1024]; - int len = sizeof(testvec); - gen_test_pattern(testvec, len); - v42bis(ctx, V42BIS_COMPRESSION_MODE_DYNAMIC, testvec, len); - v42bis(ctx, V42BIS_COMPRESSION_MODE_ALWAYS, testvec, len); - v42bis(ctx, V42BIS_COMPRESSION_MODE_NEVER, testvec, len); -} - -/* Test V.42bis compression and decompression with some TCP/IP packets */ -static void test_v42bis_tcpip(const void *ctx, int packet_id) -{ - uint8_t *testvec; - int len; - printf - ("Testing compression/decompression with realistic TCP/IP packets:\n"); - printf("Packet No.: %i\n", packet_id); - len = strlen(uncompr_packets[packet_id]); - testvec = talloc_zero_size(ctx, len); - len = osmo_hexparse(uncompr_packets[packet_id], testvec, len); - OSMO_ASSERT(len > 0); - v42bis(ctx, V42BIS_COMPRESSION_MODE_DYNAMIC, testvec, len); - v42bis(ctx, V42BIS_COMPRESSION_MODE_ALWAYS, testvec, len); - v42bis(ctx, V42BIS_COMPRESSION_MODE_NEVER, testvec, len); - talloc_free(testvec); -} - -/* Test V.42bis decompression with real, sniffed packets */ -static void test_v42bis_tcpip_decompress(const void *ctx, int packet_id) -{ - uint8_t *compressed; - int compressed_len; - uint8_t *uncompressed; - v42bis_state_t *rx_state; - int rc; - int rc_sum = 0; - int len; - struct v42bis_output_buffer uncompressed_data; - - printf - ("Testing decompression with sniffed compressed TCP/IP packets:\n"); - printf("Packet No.: %i\n", packet_id); - len = strlen(compr_packets[packet_id]); - - uncompressed = talloc_zero_size(ctx, len); - compressed = talloc_zero_size(ctx, len); - - /* Initalize */ - rx_state = - v42bis_init(ctx, NULL, P0, P1, P2, - &rx_v42bis_frame_handler, NULL, MAX_BLOCK_SIZE, - &rx_v42bis_data_handler, NULL, MAX_BLOCK_SIZE); - OSMO_ASSERT(rx_state); - - /* Setup input data */ - compressed_len = - osmo_hexparse(compr_packets[packet_id], compressed, len); - - /* Decompress */ - uncompressed_data.buf = uncompressed; - uncompressed_data.buf_pointer = uncompressed; - uncompressed_data.len = 0; - rx_state->decompress.user_data = (&uncompressed_data); - rc = v42bis_decompress_flush(rx_state); - printf("v42bis_decompress_flush() rc=%d\n", rc); - rc_sum += rc; - rc = v42bis_decompress(rx_state, compressed, compressed_len); - printf("v42bis_decompress() rc=%d\n", rc); - rc_sum += rc; - rc = v42bis_decompress_flush(rx_state); - printf("v42bis_decompress_flush() rc=%d\n", rc); - rc_sum += rc; - - /* Check results */ - printf("compressed= %s ASCII:", - osmo_hexdump_nospc(compressed, compressed_len)); - show_packet(compressed, compressed_len); - printf("uncompressed= %s ASCII:", - osmo_hexdump_nospc(uncompressed_data.buf, - uncompressed_data.len)); - show_packet(uncompressed_data.buf, uncompressed_data.len); - - OSMO_ASSERT(calc_ip_csum(uncompressed_data.buf, 20) == 0); - OSMO_ASSERT(calc_tcpip_csum(ctx, uncompressed_data.buf, - uncompressed_data.len) == 0); - - /* Free buffers and exit */ - v42bis_free(rx_state); - talloc_free(uncompressed); - talloc_free(compressed); - printf("\n"); -} - -static struct log_info_cat gprs_categories[] = { - [DV42BIS] = { - .name = "DV42BIS", - .description = "V.42bis data compression (SNDCP)", - .enabled = 1,.loglevel = LOGL_DEBUG, - } -}; - -static struct log_info info = { - .cat = gprs_categories, - .num_cat = ARRAY_SIZE(gprs_categories), -}; - -int main(int argc, char **argv) -{ - void *v42bis_ctx; - int i; - - osmo_init_logging(&info); - - v42bis_ctx = talloc_named_const(NULL, 0, "v42bis_ctx"); - - test_v42bis(v42bis_ctx); - - for (i = 0; i < UNCOMPR_PACKETS_LEN; i++) - test_v42bis_tcpip(v42bis_ctx, i); - - for (i = 0; i < COMPR_PACKETS_LEN; i++) - test_v42bis_tcpip_decompress(v42bis_ctx, i); - - printf("Done\n"); - talloc_report_full(v42bis_ctx, stderr); - OSMO_ASSERT(talloc_total_blocks(v42bis_ctx) == 1); - return 0; -} - -/* stubs */ -struct osmo_prim_hdr; -int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) -{ - abort(); -} diff --git a/tests/v42bis/v42bis_test.ok b/tests/v42bis/v42bis_test.ok deleted file mode 100644 index 070767473..000000000 --- a/tests/v42bis/v42bis_test.ok +++ /dev/null @@ -1,648 +0,0 @@ -Testing compression/decompression with generated data: -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 00000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0 ASCII:................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................ -uncompressed= 00000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0 ASCII:................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................ -compressed= 000100000000000000003300040b4e9870f020428409478c58b89021c38633663c7c081162c42143264ea448b1e29429172f62c49871cc988d1b3972ec3867cec78f2041861c3468e44892244b4e9a74f2244a9429478d5ab99225cb96b366bd7c091366cc61c366cea449b3e6b469376fe2c49973dcb89d3b79f2ec396fdecf9f4081062d587028c184098d226cd83029c388119942ac58f129c58c19a562ecd8b12ac79021b1822c59722bc99429bda26cd9322ccb9831c9c2ac59f32ccd9c39d5e2ecd9b32dcfa041e102254ad4e0d1a348952a5ddab4a953a850a34e9d4ad5aad5ab59b36ae5cab5ebd7af60c58a1d5bb6ac59b468d3ae5dcbd6addbb771e3ca9d3b7740ddba07efde5d9837efc3bd7b27f6ed7bf1efdf8d81037f1c3c7864e1c2270f1f5e9938f1cbc58b67366e7cf3f1e39d9123ff0c00 ASCII:..........3...N.p. B..G.X..!..3f<|..b.!C&N.H...)./b..q....9r.8g... A..4h.H.$KN.t.$J.)G.Z..%...f.|..f.a.f..I...i7o...s...;y..9o...@..-Xp(...."l.0)....B.X.)....b...*..!..,Yr+..)..l.2,..1...Y.,..9.....-..A..%J....H.*]...S.P.N.J....Y.j......`...[..Y.h..].....q...;w@.....].7...{'..{..........wb.......8....G..|.......\.xf..7.?..9... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 00000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0 ASCII:................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................ -uncompressed= 00000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0 ASCII:................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................ -compressed= 0001000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f000000000000000000000000000000000101010101010101010101010101010102020202020202020202020202020202030303030303030303030303030303030404040404040404040404040404040405050505050505050505050505050505060606060606060606060606060606060707070707070707070707070707070708080808080808080808080808080808090909090909090909090909090909090a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0 ASCII:................................. 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................................................ 0000000000000000@@@@@@@@@@@@@@@@PPPPPPPPPPPPPPPP````````````````pppppppppppppppp................................................................................................................................ -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 0 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 45000236000700004006cf2cc0a80002550d93d7400000501e200da7c0c95a70801840002e3700000101080a000174140853d489474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..6....@..,....U...@..P. ....Zp..@..7........t..S..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... -uncompressed= 45000236000700004006cf2cc0a80002550d93d7400000501e200da7c0c95a70801840002e3700000101080a000174140853d489474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..6....@..,....U...@..P. ....Zp..@..7........t..S..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... -compressed= 4500010236000700004006cf2cc0a80002550d93d7400000501e200da7c0c95a70801840002e3700000101080a000174140853d489474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c6963330062d990358b562ddb3d6beec079e3620f61bb5dbf861d5b36f0e0c287df68bd8366cfd4b369d7ce518b78440b192d820e2d7a1486913551eda0413a02cf9d343076687d1d9b460ead6cecc891bd03070f183472ef0e3e23c78d1c30f098b103a386562b6bd8a4b923a609132b5a8bb05183633451a377603c2113470d1e326ad024451327e81e189b61cca923270d9b37eb4794107c674e0f193236c7d81d870f9a3a60ed288c61460e1c195888d0b72fc3c98e1933d854a931c3a7e4124197c8b1d35a8f1e3d31fac831e34622c5a05856d78141447d9cd656c8f241e290b9c28e1fd9c8105964441534f9c9ac9601256a701bce3fea1851a4be1e9c32a2b04e52bfa70c1b316c8c9852ff7efebb4c8e4c711e63c6082364ef9faf23960d5919469e1c31123c068da0a5e3c44163666c9ca44ed018d5f9350f9aef458fc2401267e21936e6939e4193e68d58345ad5f4791a346800 ASCII:E...6....@..,....U...@..P. ....Zp..@..7........t..S..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, applic3.b..5.V-.=k..y.b.a.]...[6.....h..f...i..Q.xD..-..-z...5Q..A:...40vh}..F..l........4r..>#...0......V+k...#...+Z..Q.c4Q.w`r...H1(..u`.Q.....|.8d...G62D..Q.M~2.e@......:F......(....).F..#.......#S...1.......eCV..'G...A#h.8q....'..4Fu~...{..0...x....g..y#..V5}..... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 45000236000700004006cf2cc0a80002550d93d7400000501e200da7c0c95a70801840002e3700000101080a000174140853d489474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..6....@..,....U...@..P. ....Zp..@..7........t..S..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... -uncompressed= 45000236000700004006cf2cc0a80002550d93d7400000501e200da7c0c95a70801840002e3700000101080a000174140853d489474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..6....@..,....U...@..P. ....Zp..@..7........t..S..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... -compressed= 4500010236000700004006cf2cc0a80002550d93d7400000501e200da7c0c95a70801840002e3700000101080a000174140853d489474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d3133012d323030372042726f777365722f4e657446726f6e742f332e332050726f6601696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E...6....@..,....U...@..P. ....Zp..@..7........t..S..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13.-2007 Browser/NetFront/3.3 Prof.ile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 1 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 ASCII:E..@F.@.@.....dn..dd...........M....*.........G....^..... ..#..' -uncompressed= 4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 ASCII:E..@F.@.@.....dn..dd...........M....*.........G....^..... ..#..' -compressed= 451000014046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 ASCII:E...@F.@.@.....dn..dd...........M....*.........G....^..... ..#..' -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 ASCII:E..@F.@.@.....dn..dd...........M....*.........G....^..... ..#..' -uncompressed= 4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 ASCII:E..@F.@.@.....dn..dd...........M....*.........G....^..... ..#..' -compressed= 45000013060c49026e48c104ac540d5b75268ec33367066880e588d0260203ecbdda0465d08601e65a641830800081050d062450122e013561610402dc5073444d1335550400 ASCII:E.....I.nH...T.[u&..3g.h....&......e....Zd.0......$P...5aa...PsDM.5U.. -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 ASCII:E..@F.@.@.....dn..dd...........M....*.........G....^..... ..#..' -uncompressed= 4510004046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 ASCII:E..@F.@.@.....dn..dd...........M....*.........G....^..... ..#..' -compressed= 451000014046dd40004006a9a7c0a8646ec0a864640017ad8b81980100f3ac984d801800e32a1600000101080a000647de06d1bf5efffd18fffd20fffd23fffd27 ASCII:E...@F.@.@.....dn..dd...........M....*.........G....^..... ..#..' -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 2 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 ASCII:E..[F.@.@.....dn..dd...........M.....u........G....a........!.."..... .....#.....'......... -uncompressed= 4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 ASCII:E..[F.@.@.....dn..dd...........M.....u........G....a........!.."..... .....#.....'......... -compressed= 451000015b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 ASCII:E...[F.@.@.....dn..dd...........M.....u........G....a........!.."..... .....#.....'......... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 ASCII:E..[F.@.@.....dn..dd...........M.....u........G....a........!.."..... .....#.....'......... -uncompressed= 4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 ASCII:E..[F.@.@.....dn..dd...........M.....u........G....a........!.."..... .....#.....'......... -compressed= 45000013067849126ec880210958391ab6ea4c9c8767ce0cd000cb11a14d041ed87bb509caa00d03cc25c233600001020b1a0c48a0445c026ac2c808f467402040113949080c58c2260281fd461010386fa809a348fba9583a74c3d200 ASCII:E....xI.n..!.X9...L..g.......M...{.......%.3`......H.D\.j....g@ @.9I..X.&...F..8o...H..X:t... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 ASCII:E..[F.@.@.....dn..dd...........M.....u........G....a........!.."..... .....#.....'......... -uncompressed= 4510005b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 ASCII:E..[F.@.@.....dn..dd...........M.....u........G....a........!.."..... .....#.....'......... -compressed= 451000015b46de40004006a98bc0a8646ec0a864640017ad8b8198010cf3ac984d801800e3867500000101080a000647df06d1bf61fffb03fffd1ffffd21fffe22fffb05fffa2001fff0fffa2301fff0fffa2701fff0fffa1801fff0 ASCII:E...[F.@.@.....dn..dd...........M.....u........G....a........!.."..... .....#.....'......... -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 3 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 ASCII:E..7F.@.@.....dn..dd.......3........_.........G....c... -uncompressed= 4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 ASCII:E..7F.@.@.....dn..dd.......3........_.........G....c... -compressed= 451000013746df40004006a9aec0a8646ec0a864640017ad8b8198013301f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 ASCII:E...7F.@.@.....dn..dd.......3........._.........G....c... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 ASCII:E..7F.@.@.....dn..dd.......3........_.........G....c... -uncompressed= 4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 ASCII:E..7F.@.@.....dn..dd.......3........_.........G....c... -compressed= 4500001306e848226ec880210958c51ab6ea4c9c8767ce0cd000cb11a14d046cd87bb549d4a00d03cc89d136600001020b1a0c48a0845c026ac2cc0804482000 ASCII:E.....H"n..!.X....L..g.......M.l.{.I.......6`......H..\.j....H . -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 ASCII:E..7F.@.@.....dn..dd.......3........_.........G....c... -uncompressed= 4510003746df40004006a9aec0a8646ec0a864640017ad8b81980133f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 ASCII:E..7F.@.@.....dn..dd.......3........_.........G....c... -compressed= 451000013746df40004006a9aec0a8646ec0a864640017ad8b8198013301f3ac989f801800e35fd700000101080a000647e106d1bf63fffd01 ASCII:E...7F.@.@.....dn..dd.......3........._.........G....c... -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 4 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 ASCII:E..7F.@.@.....dn..dd.......6........_.........G....d... -uncompressed= 4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 ASCII:E..7F.@.@.....dn..dd.......6........_.........G....d... -compressed= 451000013746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 ASCII:E...7F.@.@.....dn..dd.......6........_.........G....d... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 ASCII:E..7F.@.@.....dn..dd.......6........_.........G....d... -uncompressed= 4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 ASCII:E..7F.@.@.....dn..dd.......6........_.........G....d... -compressed= 4500001306e848326ec880210958c11ab6ea4c9c8767ce0cd000cb11a14d0472d87bb5a9d4a00d03cc89a936600001020b1a0c48a0845c026ac2ce08f4472000 ASCII:E.....H2n..!.X....L..g.......M.r.{.........6`......H..\.j....G . -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 ASCII:E..7F.@.@.....dn..dd.......6........_.........G....d... -uncompressed= 4510003746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 ASCII:E..7F.@.@.....dn..dd.......6........_.........G....d... -compressed= 451000013746e040004006a9adc0a8646ec0a864640017ad8b81980136f3ac98a2801800e35fd200000101080a000647e106d1bf64fffb01 ASCII:E...7F.@.@.....dn..dd.......6........_.........G....d... -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 5 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a ASCII:E..tF.@.@..o..dn..dd.......9........{.........G....d..------------------..Wellcome to pollux..------------------.... -uncompressed= 4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a ASCII:E..tF.@.@..o..dn..dd.......9........{.........G....d..------------------..Wellcome to pollux..------------------.... -compressed= 451000017446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d3300386d6a41f3e68d193970d08cb82367c41c3940f1ecb1b97327549e0d6c0600 ASCII:E...tF.@.@..o..dn..dd.......9........{.........G....d..----------------3.8mjA....9p...#g..9@....s'T..l.. -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a ASCII:E..tF.@.@..o..dn..dd.......9........{.........G....d..------------------..Wellcome to pollux..------------------.... -uncompressed= 4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a ASCII:E..tF.@.@..o..dn..dd.......9........{.........G....d..------------------..Wellcome to pollux..------------------.... -compressed= 4500001306dc49426ec880210958c919b6ea4c9c8767ce0cd000cb11a14d0478d87bb509d5a00d03ccf9f134600001020b1a0c48a0a45c026ac2ce40680003064e9c3973eac469530b9a376fccc8818366c41d3923e6c8018a678fcd9d3ba1f26c603300 ASCII:E.....IBn..!.X....L..g.......M.x.{.........4`......H..\.j..@h...N.9s..iS..7o....f..9#....g...;..l`3. -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a ASCII:E..tF.@.@..o..dn..dd.......9........{.........G....d..------------------..Wellcome to pollux..------------------.... -uncompressed= 4510007446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a ASCII:E..tF.@.@..o..dn..dd.......9........{.........G....d..------------------..Wellcome to pollux..------------------.... -compressed= 451000017446e140004006a96fc0a8646ec0a864640017ad8b81980139f3ac98a5801800e37b9b00000101080a000647e206d1bf640d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a57656c6c636f6d6520746f20706f6c6c75780d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a ASCII:E...tF.@.@..o..dn..dd.......9........{.........G....d..------------------..Wellcome to pollux..------------------.... -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 6 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 ASCII:E..BF.@.@.....dn..dd.......y..................G....opollux login: -uncompressed= 4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 ASCII:E..BF.@.@.....dn..dd.......y..................G....opollux login: -compressed= 451000014246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 ASCII:E...BF.@.@.....dn..dd.......y..................G....opollux login: -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 ASCII:E..BF.@.@.....dn..dd.......y..................G....opollux login: -uncompressed= 4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 ASCII:E..BF.@.@.....dn..dd.......y..................G....opollux login: -compressed= 45000013061449526ec8802109588d1ab6ea4c9c8767ce0cd000cb11a14d04f8d87bb509d5a00d03cc759b35600001020b1a0c48a0e45d026ac2e4cc91f3e60d9e3d23dec851c3264e8f110100 ASCII:E.....IRn..!.X....L..g.......M...{.......u.5`......H..].j........=#..Q.&N.... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 ASCII:E..BF.@.@.....dn..dd.......y..................G....opollux login: -uncompressed= 4510004246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 ASCII:E..BF.@.@.....dn..dd.......y..................G....opollux login: -compressed= 451000014246e240004006a9a0c0a8646ec0a864640017ad8b81980179f3ac98a5801800e3dab000000101080a000647ec06d1bf6f706f6c6c7578206c6f67696e3a20 ASCII:E...BF.@.@.....dn..dd.......y..................G....opollux login: -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 7 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 450001a0b41140004006b8e80a0901abc0a800021f904002d5b860b5bab240ae501900ed861d0000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205475652c2033302041756720323031362030393a34333a303720474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a3c21444f43545950452068746d6c205055424c494320222d2f2f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e6720666f72202f3c2f7469746c653e0a3c626f64793e0a3c68323e4469726563746f7279206c697374696e6720666f72202f3c2f68323e0a3c68723e0a3c756c3e0a3c6c693e3c6120687265663d2272656470686f6e652e706e67223e72656470686f6e652e706e673c2f613e0a3c2f756c3e0a3c68723e0a3c2f626f64793e0a3c2f68746d6c3e0a ASCII:E.....@.@.............@...`...@.P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Tue, 30 Aug 2016 09:43:07 GMT..Content-type: text/html; charset=UTF-8..Content-Length: 222.....Directory listing for /..

Directory listing for /

.
..
... -uncompressed= 450001a0b41140004006b8e80a0901abc0a800021f904002d5b860b5bab240ae501900ed861d0000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205475652c2033302041756720323031362030393a34333a303720474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a3c21444f43545950452068746d6c205055424c494320222d2f2f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e6720666f72202f3c2f7469746c653e0a3c626f64793e0a3c68323e4469726563746f7279206c697374696e6720666f72202f3c2f68323e0a3c68723e0a3c756c3e0a3c6c693e3c6120687265663d2272656470686f6e652e706e67223e72656470686f6e652e706e673c2f613e0a3c2f756c3e0a3c68723e0a3c2f626f64793e0a3c2f68746d6c3e0a ASCII:E.....@.@.............@...`...@.P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Tue, 30 Aug 2016 09:43:07 GMT..Content-type: text/html; charset=UTF-8..Content-Length: 222.....Directory listing for /..

Directory listing for /

.
..
... -compressed= 45000101a0b41140004006b8e80a0901abc0a800021f904002d5b860b5bab240ae501900ed861d0000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205475652c203301302041756720323031362030393a34333a303720474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a206600356ad4c899f3078923528c5ce13205c908c58c9d6229f2848991112560c890a1050033432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e672066016f72202f3c2f7469746c990068bcff2823e70c9fff6b6a943f9f7e7dfbf7f1e7d7bf9f3fb1c2ef6beafcc7d3fd3b7ced6468a34f03a404fa3373a4c64113630efdec27534e7509538d7e32ff657044a8f1bb0c82067f72f71e00 ASCII:E......@.@.............@...`...@.P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Tue, 3.0 Aug 2016 09:43:07 GMT..Content-type: text/html; charset=UTF-8..Content-Length: f.5j......#R.\.2......b).....%`.....3C//DTD HTML 3.2 Final//EN">.Directory listing f.or /</titl..h..(#....kj.?.~}.......?...k.....;|.dh.O....3s..A.c...'SNu.S.~2.epD.......r... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 450001a0b41140004006b8e80a0901abc0a800021f904002d5b860b5bab240ae501900ed861d0000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205475652c2033302041756720323031362030393a34333a303720474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a3c21444f43545950452068746d6c205055424c494320222d2f2f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e6720666f72202f3c2f7469746c653e0a3c626f64793e0a3c68323e4469726563746f7279206c697374696e6720666f72202f3c2f68323e0a3c68723e0a3c756c3e0a3c6c693e3c6120687265663d2272656470686f6e652e706e67223e72656470686f6e652e706e673c2f613e0a3c2f756c3e0a3c68723e0a3c2f626f64793e0a3c2f68746d6c3e0a ASCII:E.....@.@.............@...`...@.P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Tue, 30 Aug 2016 09:43:07 GMT..Content-type: text/html; charset=UTF-8..Content-Length: 222....<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>.<title>Directory listing for /..

Directory listing for /

.
..
... -uncompressed= 450001a0b41140004006b8e80a0901abc0a800021f904002d5b860b5bab240ae501900ed861d0000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205475652c2033302041756720323031362030393a34333a303720474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a3c21444f43545950452068746d6c205055424c494320222d2f2f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e6720666f72202f3c2f7469746c653e0a3c626f64793e0a3c68323e4469726563746f7279206c697374696e6720666f72202f3c2f68323e0a3c68723e0a3c756c3e0a3c6c693e3c6120687265663d2272656470686f6e652e706e67223e72656470686f6e652e706e673c2f613e0a3c2f756c3e0a3c68723e0a3c2f626f64793e0a3c2f68746d6c3e0a ASCII:E.....@.@.............@...`...@.P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Tue, 30 Aug 2016 09:43:07 GMT..Content-type: text/html; charset=UTF-8..Content-Length: 222.....Directory listing for /..

Directory listing for /

.
..
... -compressed= 45000003088cba4561c880210976ad6bc08080ab61ab061410316948016cbbc6e0ea556b48ac291c06c04b0462c0802557ae4c914123c68c113566c894e20442032b68eae4e1d96384153670e6bc41b3b2a58c1931728c98c2e7ce1a397164d488a18369ce2364eea0017a050f9a17236cc8248247cdcc19349acee0d1e3868d1e33748c5002e54a4e2353bbc6b903e30e9f395e4774dd7347c69a3b70def81861660d993a76d0dc0182e54a12183bf4f245e317c693cf6aa202ad51a346ce9c3f481c9162e40a972948462866ec144b91274c8c8c280143860c2d368c003f72e5c88895509e908d516344123671c8bc018e244a89203f6abf09d2e0c71d36778c0639c2a60e1a3377e4d4e133e20d1b3be1e3a44dc37e848c1f32c28f47e3fd47193967f8fc5f53a3fcf9f4ebdbbf8f3fbffefdfc89157e5f53e73f9eeedfe16b27431b7d1a2025d09f9923350e9a1873e8673f9972aa4b986af493f92f8323428ddf651034f893bbf700 ASCII:E......Ea..!.v.k....a....1iH.l....UkH.)...K.b..%W.L.A#...5f....B.+h....c..6p..A.....1r......9qd....i.#d...z....#l.$.G...4........3t.P..JN#S.......9^Gt.sG..;p...af..:v.....J..;..E.....j...Q.F..?H..b...)HF(f..K.'L..(.C..-6..?r....P...QcD.6q....$J. ?j......6w..9....3w...3...;...M.~...2..G..G.9g.._S........?......~_S.?....k'C.}. %...#5...s.g?.r.K.j.../.#B..e.4..... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 450001a0b41140004006b8e80a0901abc0a800021f904002d5b860b5bab240ae501900ed861d0000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205475652c2033302041756720323031362030393a34333a303720474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a3c21444f43545950452068746d6c205055424c494320222d2f2f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e6720666f72202f3c2f7469746c653e0a3c626f64793e0a3c68323e4469726563746f7279206c697374696e6720666f72202f3c2f68323e0a3c68723e0a3c756c3e0a3c6c693e3c6120687265663d2272656470686f6e652e706e67223e72656470686f6e652e706e673c2f613e0a3c2f756c3e0a3c68723e0a3c2f626f64793e0a3c2f68746d6c3e0a ASCII:E.....@.@.............@...`...@.P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Tue, 30 Aug 2016 09:43:07 GMT..Content-type: text/html; charset=UTF-8..Content-Length: 222.....Directory listing for /..

Directory listing for /

.
..
... -uncompressed= 450001a0b41140004006b8e80a0901abc0a800021f904002d5b860b5bab240ae501900ed861d0000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205475652c2033302041756720323031362030393a34333a303720474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a3c21444f43545950452068746d6c205055424c494320222d2f2f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e6720666f72202f3c2f7469746c653e0a3c626f64793e0a3c68323e4469726563746f7279206c697374696e6720666f72202f3c2f68323e0a3c68723e0a3c756c3e0a3c6c693e3c6120687265663d2272656470686f6e652e706e67223e72656470686f6e652e706e673c2f613e0a3c2f756c3e0a3c68723e0a3c2f626f64793e0a3c2f68746d6c3e0a ASCII:E.....@.@.............@...`...@.P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Tue, 30 Aug 2016 09:43:07 GMT..Content-type: text/html; charset=UTF-8..Content-Length: 222.....Directory listing for /..

Directory listing for /

.
..
... -compressed= 45000101a0b41140004006b8e80a0901abc0a800021f904002d5b860b5bab240ae501900ed861d0000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205475652c203301302041756720323031362030393a34333a303720474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a3c21444f43545950452068746d6c205055424c494320222d2f2f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e672066016f72202f3c2f7469746c653e0a3c626f64793e0a3c68323e4469726563746f7279206c697374696e6720666f72202f3c2f68323e0a3c68723e0a3c756c3e0a3c6c693e3c6120687265663d2272656470686f6e652e706e67223e72656470686f6e652e706e673c2f613e0a3c2f756c3e0a3c68723e0a3c2f626f64793e0a3c2f68746d6c3e0a ASCII:E......@.@.............@...`...@.P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Tue, 3.0 Aug 2016 09:43:07 GMT..Content-type: text/html; charset=UTF-8..Content-Length: 222.....Directory listing f.or /..

Directory listing for /

.
..
... -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 8 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 450000e2971b40003706026c550d93d7c0a8000200504047217f5922c903759c8018007c4fb400000101080a1153ce39002cf6e8485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613134392d3436652d34323736386138656338656330220d0a0d0a ASCII:E.....@.7..lU........P@G!.Y"..u....|O........S.9.,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a149-46e-42768a8ec8ec0".... -uncompressed= 450000e2971b40003706026c550d93d7c0a8000200504047217f5922c903759c8018007c4fb400000101080a1153ce39002cf6e8485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613134392d3436652d34323736386138656338656330220d0a0d0a ASCII:E.....@.7..lU........P@G!.Y"..u....|O........S.9.,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a149-46e-42768a8ec8ec0".... -compressed= 45000100e2971b40003706026c550d93d7c0a8000200504047217f5922c903759c8018007c4fb400000101080a1153ce39002cf6e8485454502f312e312033013034204e6f74204d6f646966016965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613134392d3436652d3432373638613865633865990066669478fa3400 ASCII:E......@.7..lU........P@G!.Y"..u....|O........S.9.,..HTTP/1.1 3.04 Not Modif.ied..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a149-46e-42768a8ec8e..ff.x.4. -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 450000e2971b40003706026c550d93d7c0a8000200504047217f5922c903759c8018007c4fb400000101080a1153ce39002cf6e8485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613134392d3436652d34323736386138656338656330220d0a0d0a ASCII:E.....@.7..lU........P@G!.Y"..u....|O........S.9.,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a149-46e-42768a8ec8ec0".... -uncompressed= 450000e2971b40003706026c550d93d7c0a8000200504047217f5922c903759c8018007c4fb400000101080a1153ce39002cf6e8485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613134392d3436652d34323736386138656338656330220d0a0d0a ASCII:E.....@.7..lU........P@G!.Y"..u....|O........S.9.,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a149-46e-42768a8ec8ec0".... -compressed= 450000030694d3e461c8001d090abcc102c192b661ab061418306588121282b894606600cfa7411b06fc91728b2001020b1a50b0128dc78017f9d62db972658a0c1a31688cb031e3c6882872ee8c8022e70c9b346cd09c81d0e008993b687a8cb88207cd0b9f334610c1a366448d1934728c20dbc3468e1e37b82a8172e5a9153475f2ccad4a640e19336bd03c3522274e1c3466eeb0015cd5091a3473601079c3a6eed3c48b1b3fae5bb5301c3472f0dc0152432b1c327b80d0983163c6532457c8a8a95ae286991d6468dce001e3460e34b76be8c8217bc760e066669478fa3400 ASCII:E.......a...........a....0e......`f...A....r. ....P........-.re...1h..1...(r..."...4l.......;hz.......3F...fD..4r. ..F..7.*.r...4u...Jd..3k.<5"'N.4f...\...4s`.y.......?.[.0.4r...RC+.2{...1c.S$W...Z....dh....F.4.k..!{.`.ff.x.4. -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 450000e2971b40003706026c550d93d7c0a8000200504047217f5922c903759c8018007c4fb400000101080a1153ce39002cf6e8485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613134392d3436652d34323736386138656338656330220d0a0d0a ASCII:E.....@.7..lU........P@G!.Y"..u....|O........S.9.,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a149-46e-42768a8ec8ec0".... -uncompressed= 450000e2971b40003706026c550d93d7c0a8000200504047217f5922c903759c8018007c4fb400000101080a1153ce39002cf6e8485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613134392d3436652d34323736386138656338656330220d0a0d0a ASCII:E.....@.7..lU........P@G!.Y"..u....|O........S.9.,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a149-46e-42768a8ec8ec0".... -compressed= 45000100e2971b40003706026c550d93d7c0a8000200504047217f5922c903759c8018007c4fb400000101080a1153ce39002cf6e8485454502f312e312033013034204e6f74204d6f646966016965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613134392d3436652d34323736386138656338656330220d0a0d0a ASCII:E......@.7..lU........P@G!.Y"..u....|O........S.9.,..HTTP/1.1 3.04 Not Modif.ied..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a149-46e-42768a8ec8ec0".... -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 9 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 450000e224f1400037067496550d93d7c0a80002005040489387ebf0c904389f8018007cec5700000101080a1153cf01002cf8fc485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613338302d3861362d34323736383761323236383830220d0a0d0a ASCII:E...$.@.7.t.U........P@H......8....|.W.......S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a380-8a6-427687a226880".... -uncompressed= 450000e224f1400037067496550d93d7c0a80002005040489387ebf0c904389f8018007cec5700000101080a1153cf01002cf8fc485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613338302d3861362d34323736383761323236383830220d0a0d0a ASCII:E...$.@.7.t.U........P@H......8....|.W.......S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a380-8a6-427687a226880".... -compressed= 45000100e224f1400037067496550d93d7c0a80002005040489387ebf0c904389f8018007cec5700000101080a1153cf01002cf8fc485454502f312e312033013034204e6f74204d6f646966016965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613338302d3861362d34323736383761323236383830220d0a0d0a ASCII:E....$.@.7.t.U........P@H......8....|.W.......S...,..HTTP/1.1 3.04 Not Modif.ied..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a380-8a6-427687a226880".... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 450000e224f1400037067496550d93d7c0a80002005040489387ebf0c904389f8018007cec5700000101080a1153cf01002cf8fc485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613338302d3861362d34323736383761323236383830220d0a0d0a ASCII:E...$.@.7.t.U........P@H......8....|.W.......S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a380-8a6-427687a226880".... -uncompressed= 450000e224f1400037067496550d93d7c0a80002005040489387ebf0c904389f8018007cec5700000101080a1153cf01002cf8fc485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613338302d3861362d34323736383761323236383830220d0a0d0a ASCII:E...$.@.7.t.U........P@H......8....|.W.......S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a380-8a6-427687a226880".... -compressed= 4500000306943b416fc8001d09ee64c202c192b661ab0614183065c8124b8adccd63766087a8411b06fc79a7852001020b1a50b0228dc08017fbfe2db972658a0c1a31688cb031e3c6882872ee8c8022e70c9b346cd09c81d0e008993b687a8cb88207cd0b9f334610c1a366448d1934728c20dbc3468e1e37b82a8172e5a9153475f2ccad4a640e19336bd03c3522274e1c3466eeb0015cd5091a3473601079c3a6eed3c48b1b3fae5bb5301c3472f0dc0152432b1c327b80d0983163c6532457c8a8a95ae286991d646cec980143760e18376ae8c8b14307991a357cd72ef1f46900 ASCII:E.....;Ao.....d.....a....0e..K...cv`..A...y.. ....P."......-.re...1h..1...(r..."...4l.......;hz.......3F...fD..4r. ..F..7.*.r...4u...Jd..3k.<5"'N.4f...\...4s`.y.......?.[.0.4r...RC+.2{...1c.S$W...Z....dl...Cv..7j...C...5|....i. -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 450000e224f1400037067496550d93d7c0a80002005040489387ebf0c904389f8018007cec5700000101080a1153cf01002cf8fc485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613338302d3861362d34323736383761323236383830220d0a0d0a ASCII:E...$.@.7.t.U........P@H......8....|.W.......S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a380-8a6-427687a226880".... -uncompressed= 450000e224f1400037067496550d93d7c0a80002005040489387ebf0c904389f8018007cec5700000101080a1153cf01002cf8fc485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613338302d3861362d34323736383761323236383830220d0a0d0a ASCII:E...$.@.7.t.U........P@H......8....|.W.......S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a380-8a6-427687a226880".... -compressed= 45000100e224f1400037067496550d93d7c0a80002005040489387ebf0c904389f8018007cec5700000101080a1153cf01002cf8fc485454502f312e312033013034204e6f74204d6f646966016965640d0a446174653a205475652c2033302041756720323031362031363a33363a343020474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338613338302d3861362d34323736383761323236383830220d0a0d0a ASCII:E....$.@.7.t.U........P@H......8....|.W.......S...,..HTTP/1.1 3.04 Not Modif.ied..Date: Tue, 30 Aug 2016 16:36:40 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8a380-8a6-427687a226880".... -memcmp() rc=0 - -Testing compression/decompression with realistic TCP/IP packets: -Packet No.: 10 -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 0 -uncompressed_original= 450000e2b66140003706e325550d93d7c0a8000200504049fbb679bcc9051ea48018007cebea00000101080a1153cfdc002cfdb4485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343120474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338313336642d3138642d34353832306530393638303430220d0a0d0a ASCII:E....a@.7..%U........P@I..y........|.........S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:41 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8136d-18d-45820e0968040".... -uncompressed= 450000e2b66140003706e325550d93d7c0a8000200504049fbb679bcc9051ea48018007cebea00000101080a1153cfdc002cfdb4485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343120474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338313336642d3138642d34353832306530393638303430220d0a0d0a ASCII:E....a@.7..%U........P@I..y........|.........S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:41 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8136d-18d-45820e0968040".... -compressed= 45000100e2b66140003706e325550d93d7c0a8000200504049fbb679bcc9051ea48018007cebea00000101080a1153cfdc002cfdb4485454502f312e312033013034204e6f74204d6f646966016965640d0a446174653a205475652c2033302041756720323031362031363a33363a343120474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338313336642d3138642d34353832306530393638303430220d0a0d0a ASCII:E.....a@.7..%U........P@I..y........|.........S...,..HTTP/1.1 3.04 Not Modif.ied..Date: Tue, 30 Aug 2016 16:36:41 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8136d-18d-45820e0968040".... -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 1 -uncompressed_original= 450000e2b66140003706e325550d93d7c0a8000200504049fbb679bcc9051ea48018007cebea00000101080a1153cfdc002cfdb4485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343120474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338313336642d3138642d34353832306530393638303430220d0a0d0a ASCII:E....a@.7..%U........P@I..y........|.........S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:41 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8136d-18d-45820e0968040".... -uncompressed= 450000e2b66140003706e325550d93d7c0a8000200504049fbb679bcc9051ea48018007cebea00000101080a1153cfdc002cfdb4485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343120474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338313336642d3138642d34353832306530393638303430220d0a0d0a ASCII:E....a@.7..%U........P@I..y........|.........S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:41 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8136d-18d-45820e0968040".... -compressed= 450000030694cb4566c8001d09cca1c002c192b661ab061418306508137fb9f8fc628620c4a9411b06fc71d78e2001020b1a50b022eddb8017006f2db972658a0c1a31688cb031e3c6882872ee8c8022e70c9b346cd09c81d0e008993b687a8cb88207cd0b9f334610c1a366448d1934728c20dbc3468e1e377a2a8172e5a9153475f2ccad4a640e19336bd03c3522274e1c3466eeb0015cd5091a3473601079c3a6eed3c48b1b3fae5bb5301c3472f0dc0152432b1c327b80d0983163c6532457c8a8a95ae286991d34d29e81416347ed1b387688453383478e1d40679478fa3400 ASCII:E......Ef...........a....0e......b. ..A...q.. ....P.".....o-.re...1h..1...(r..."...4l.......;hz.......3F...fD..4r. ..F..7z*.r...4u...Jd..3k.<5"'N.4f...\...4s`.y.......?.[.0.4r...RC+.2{...1c.S$W...Z....4...AcG..8v.E3.G..@g.x.4. -memcmp() rc=0 - -v42bis_compress() rc=0 -v42bis_compress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -Mode: 2 -uncompressed_original= 450000e2b66140003706e325550d93d7c0a8000200504049fbb679bcc9051ea48018007cebea00000101080a1153cfdc002cfdb4485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343120474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338313336642d3138642d34353832306530393638303430220d0a0d0a ASCII:E....a@.7..%U........P@I..y........|.........S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:41 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8136d-18d-45820e0968040".... -uncompressed= 450000e2b66140003706e325550d93d7c0a8000200504049fbb679bcc9051ea48018007cebea00000101080a1153cfdc002cfdb4485454502f312e3120333034204e6f74204d6f6469666965640d0a446174653a205475652c2033302041756720323031362031363a33363a343120474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338313336642d3138642d34353832306530393638303430220d0a0d0a ASCII:E....a@.7..%U........P@I..y........|.........S...,..HTTP/1.1 304 Not Modified..Date: Tue, 30 Aug 2016 16:36:41 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8136d-18d-45820e0968040".... -compressed= 45000100e2b66140003706e325550d93d7c0a8000200504049fbb679bcc9051ea48018007cebea00000101080a1153cfdc002cfdb4485454502f312e312033013034204e6f74204d6f646966016965640d0a446174653a205475652c2033302041756720323031362031363a33363a343120474d540d0a5365727665723a204170616368650d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4b6565702d416c6976653a2074696d656f75743d322c206d61783d313030300d0a455461673a2022346338313336642d3138642d34353832306530393638303430220d0a0d0a ASCII:E.....a@.7..%U........P@I..y........|.........S...,..HTTP/1.1 3.04 Not Modif.ied..Date: Tue, 30 Aug 2016 16:36:41 GMT..Server: Apache..Connection: Keep-Alive..Keep-Alive: timeout=2, max=1000..ETag: "4c8136d-18d-45820e0968040".... -memcmp() rc=0 - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 0 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010268000700004006cefac0a80002550d93d740000050462c7ba7e4d1753a80184000aad500000101080a0001a670084dafb4474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005ab97a052b960d59b368d5b2ddb3e60e9c372ef610b6dbf56bd8b165030f2e7cf88dd63b68f64c3d9b76ed1cb58847b490d122e8d0a24761185913d50e1aa423f0dc49036387d6d7b169e4d0cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a68b5b2864d9a3b629a30b1a2b5081b35384613357a07c6133271d4e021a3064d52347182ee81b119c69c3a72d2b079b37e4409c177e6f4902163738cdd71f8a0a903d68ec21866e4c0918185087dfb329cec9831834d951a337c4a2e1174891c3badf5e8d113a38f1c336e24520c8a65751d1844d4c7696d852c1f240e992becf8918d0c9145465441939fcc6a1950a206b7e1fca38e1145eaebc129230aeb24f57bcab011c3c68829f5efe7bfcbe4c814e731668c3042f6fef93a62d9909561e4c91123c163d0085a3a4e1c3466c6c649ea048d519d5ff3a0f95ef4280c2471269e61633ee9193469de8845a3554d9fa74199c48622e7fa7dac30ac602f9af40a9ef0236a54268247cd7f923946d0a8d1c3c68d1e35788c5002e54ad0a00100 ASCII:E...h....@.......U...@..PF,{...u:..@............p.M..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed3.Z.z.+..Y.h.......7......k..e...|...;h.L=.v....G..."...Ga.Y.....#..I.c....i.......;p..A#...3r......;0jh...M.;b.0.....58F.5z...2q..!..MR4q.......:r..y.~D..w...!cs..q........f......}.2...1.M..3|J..t..;........3n$R..eu..D..im.,.$..+......EFTA...j.P........E...)#..$.{......).........1f.0B...:b...a...#.c..Z:N.4f..I...Q._...^.(.$q&.ac>..4i..E.UM..A..."..}.0.`/.....#jT&.G...9F.......5x.P..J.... -uncompressed= 45000268000700004006cefac0a80002550d93d740000050462c7ba7e4d1753a80184000aad500000101080a0001a670084dafb4474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a49662d4d6f6469666965642d53696e63653a205475652c2032332041756720323031362031323a33343a323920474d540d0a0d0a ASCII:E..h....@.......U...@..PF,{...u:..@............p.M..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..If-Modified-Since: Tue, 23 Aug 2016 12:34:29 GMT.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 1 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010268000900004006cef8c0a80002550d93d740000050462c7ba7e4d1753a801840007e7f00000101080a0001d1cc084db0ae474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005ab97a052b960d59b368d5b2ddb3e60e9c372ef610b6dbf56bd8b165030f2e7cf88dd63b68f64c3d9b76ed1cb58847b490d122e8d0a24761185913d50e1aa423f0dc49036387d6d7b169e4d0cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a68b5b2864d9a3b629a30b1a2b5081b35384613357a07c6133271d4e021a3064d52347182ee81b119c69c3a72d2b079b37e4409c177e6f4902163738cdd71f8a0a903d68ec21866e4c0918185087dfb329cec9831834d951a337c4a2e1174891c3badf5e8d113a38f1c336e24520c8a65751d1844d4c7696d852c1f240e992becf8918d0c9145465441939fcc6a1950a206b7e1fca38e1145eaebc129230aeb24f57bcab011c3c68829f5efe7bfcbe4c814e731668c3042f6fef93a62d9909561e4c91123c163d0085a3a4e1c3466c6c649ea048d519d5ff3a0f95ef4280c2471269e61633ee9193469de8845a3554d9fa74199c48622e7fa7dac30ac602f9af40a9ef0236a54268247cd7f923946d0a8d1c3c68d1e35788c5002e54ad0a00100 ASCII:E...h....@.......U...@..PF,{...u:..@.~............M..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed3.Z.z.+..Y.h.......7......k..e...|...;h.L=.v....G..."...Ga.Y.....#..I.c....i.......;p..A#...3r......;0jh...M.;b.0.....58F.5z...2q..!..MR4q.......:r..y.~D..w...!cs..q........f......}.2...1.M..3|J..t..;........3n$R..eu..D..im.,.$..+......EFTA...j.P........E...)#..$.{......).........1f.0B...:b...a...#.c..Z:N.4f..I...Q._...^.(.$q&.ac>..4i..E.UM..A..."..}.0.`/.....#jT&.G...9F.......5x.P..J.... -uncompressed= 45000268000900004006cef8c0a80002550d93d740000050462c7ba7e4d1753a801840007e7f00000101080a0001d1cc084db0ae474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a49662d4d6f6469666965642d53696e63653a205475652c2032332041756720323031362031323a33343a323920474d540d0a0d0a ASCII:E..h....@.......U...@..PF,{...u:..@.~............M..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..If-Modified-Since: Tue, 23 Aug 2016 12:34:29 GMT.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 2 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010268000b00004006cef6c0a80002550d93d740000050462c7ba7e4d1753b80193fff131c00000101080a00022884084dc558474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005ab97a052b960d59b368d5b2ddb3e60e9c372ef610b6dbf56bd8b165030f2e7cf88dd63b68f64c3d9b76ed1cb58847b490d122e8d0a24761185913d50e1aa423f0dc49036387d6d7b169e4d0cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a68b5b2864d9a3b629a30b1a2b5081b35384613357a07c6133271d4e021a3064d52347182ee81b119c69c3a72d2b079b37e4409c177e6f4902163738cdd71f8a0a903d68ec21866e4c0918185087dfb329cec9831834d951a337c4a2e1174891c3badf5e8d113a38f1c336e24520c8a65751d1844d4c7696d852c1f240e992be4e8918d8c9045465441939fcc6a1950a206b7e1dca38e1145eaebb929230aeb24f579cab011c3c68829f5efe7afcbe4c814e731668c3042f6fef93a62d9909561e4c91123c163d0084a3a4e1c3466c6c649ea048dd19c5ff3a0f95ef4280c2471269e61633ee9193469de8845a3554d9fa74199c48622c7fa7dac30ac5c2f9af40a1ef0236a502682478dff913946d0a8d1c3c68d1e35788c5002e54ad0a00100 ASCII:E...h....@.......U...@..PF,{...u;..?...........(..M.XGET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed3.Z.z.+..Y.h.......7......k..e...|...;h.L=.v....G..."...Ga.Y.....#..I.c....i.......;p..A#...3r......;0jh...M.;b.0.....58F.5z...2q..!..MR4q.......:r..y.~D..w...!cs..q........f......}.2...1.M..3|J..t..;........3n$R..eu..D..im.,.$..+......EFTA...j.P........E...)#..$.y......).........1f.0B...:b...a...#.c..J:N.4f..I....._...^.(.$q&.ac>..4i..E.UM..A..."..}.0.\/.....#jP&.G...9F.......5x.P..J.... -uncompressed= 45000268000b00004006cef6c0a80002550d93d740000050462c7ba7e4d1753b80193fff131c00000101080a00022884084dc558474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a49662d4d6f6469666965642d53696e63653a205475652c2032332041756720323031362031323a33343a323920474d540d0a0d0a ASCII:E..h....@.......U...@..PF,{...u;..?...........(..M.XGET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..If-Modified-Since: Tue, 23 Aug 2016 12:34:29 GMT.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 3 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010268000c00004006cef5c0a80002550d93d740000050462c7ba7e4d1753b80193fff65ab00000101080a0002d5f4084dc558474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005ab97a052b960d59b368d5b2ddb3e60e9c372ef610b6dbf56bd8b165030f2e7cf88dd63b68f64c3d9b76ed1cb58847b490d122e8d0a24761185913d50e1aa423f0dc49036387d6d7b169e4d0cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a68b5b2864d9a3b629a30b1a2b5081b35384613357a07c6133271d4e021a3064d52347182ee81b119c69c3a72d2b079b37e4409c177e6f4902163738cdd71f8a0a903d68ec21866e4c0918185087dfb329cec9831834d951a337c4a2e1174891c3badf5e8d113a38f1c336e24520c8a65751d1844d4c7696d852c1f240e992be4e8918d8c9045465441939fcc6a1950a206b7e1dca38e1145eaebb929230aeb24f579cab011c3c68829f5efe7afcbe4c814e731668c3042f6fef93a62d9909561e4c91123c163d0084a3a4e1c3466c6c649ea048dd19c5ff3a0f95ef4280c2471269e61633ee9193469de8845a3554d9fa74199c48622c7fa7dac30ac5c2f9af40a1ef0236a502682478dff913946d0a8d1c3c68d1e35788c5002e54ad0a00100 ASCII:E...h....@.......U...@..PF,{...u;..?.e............M.XGET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed3.Z.z.+..Y.h.......7......k..e...|...;h.L=.v....G..."...Ga.Y.....#..I.c....i.......;p..A#...3r......;0jh...M.;b.0.....58F.5z...2q..!..MR4q.......:r..y.~D..w...!cs..q........f......}.2...1.M..3|J..t..;........3n$R..eu..D..im.,.$..+......EFTA...j.P........E...)#..$.y......).........1f.0B...:b...a...#.c..J:N.4f..I....._...^.(.$q&.ac>..4i..E.UM..A..."..}.0.\/.....#jP&.G...9F.......5x.P..J.... -uncompressed= 45000268000c00004006cef5c0a80002550d93d740000050462c7ba7e4d1753b80193fff65ab00000101080a0002d5f4084dc558474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a49662d4d6f6469666965642d53696e63653a205475652c2032332041756720323031362031323a33343a323920474d540d0a0d0a ASCII:E..h....@.......U...@..PF,{...u;..?.e............M.XGET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..If-Modified-Since: Tue, 23 Aug 2016 12:34:29 GMT.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 4 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 450001022d000f00004006ac5ec0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00 ASCII:E...-....@..^........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application3.\....g..8o\...vj..Y........w..I..k.9`..h!....;{.0....4>G........O......9.w........g......3v`..je..4w.4ab.j.6jpd.....'d...CF...h....#2.9u..a.&...x...!CF.....AS....1...#.....e8.1c..*5f.D\...9vF....G..:h..H.&..u`...g...|...._"E62...Q..{2.e@9z..q.:F.Y....(....).F..#..o..-.#S...1......`e.U..'G...y.s.8h.d......1..AS}gO.H. <....3h.......>Eo... -uncompressed= 4500022d000f00004006ac5ec0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a2031302e392e312e3137313a383030300d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..-....@..^........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: 10.9.1.171:8000..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 5 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 450001022d001000004006ac5dc0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00 ASCII:E...-....@..]........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application3.\....g..8o\...vj..Y........w..I..k.9`..h!....;{.0....4>G........O......9.w........g......3v`..je..4w.4ab.j.6jpd.....'d...CF...h....#2.9u..a.&...x...!CF.....AS....1...#.....e8.1c..*5f.D\...9vF....G..:h..H.&..u`...g...|...._"E62...Q..{2.e@9z..q.:F.Y....(....).F..#..o..-.#S...1......`e.U..'G...y.s.8h.d......1..AS}gO.H. <....3h.......>Eo... -uncompressed= 4500022d001000004006ac5dc0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a2031302e392e312e3137313a383030300d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..-....@..]........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: 10.9.1.171:8000..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 6 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 450001022d001100004006ac5cc0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00 ASCII:E...-....@..\........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application3.\....g..8o\...vj..Y........w..I..k.9`..h!....;{.0....4>G........O......9.w........g......3v`..je..4w.4ab.j.6jpd.....'d...CF...h....#2.9u..a.&...x...!CF.....AS....1...#.....e8.1c..*5f.D\...9vF....G..:h..H.&..u`...g...|...._"E62...Q..{2.e@9z..q.:F.Y....(....).F..#..o..-.#S...1......`e.U..'G...y.s.8h.d......1..AS}gO.H. <....3h.......>Eo... -uncompressed= 4500022d001100004006ac5cc0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a2031302e392e312e3137313a383030300d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..-....@..\........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: 10.9.1.171:8000..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 7 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 450001022d001200004006ac5bc0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00 ASCII:E...-....@..[........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application3.\....g..8o\...vj..Y........w..I..k.9`..h!....;{.0....4>G........O......9.w........g......3v`..je..4w.4ab.j.6jpd.....'d...CF...h....#2.9u..a.&...x...!CF.....AS....1...#.....e8.1c..*5f.D\...9vF....G..:h..H.&..u`...g...|...._"E62...Q..{2.e@9z..q.:F.Y....(....).F..#..o..-.#S...1......`e.U..'G...y.s.8h.d......1..AS}gO.H. <....3h.......>Eo... -uncompressed= 4500022d001200004006ac5bc0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a2031302e392e312e3137313a383030300d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..-....@..[........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: 10.9.1.171:8000..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 8 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010268001300004006ceeec0a80002550d93d740000050462c7ba7e4d1753b80193fff7b4a00000101080a0003c054084dc558474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d6978656433005bbb7e0d3b964dd9b369d7b6ddb3e60e9c372ef614beeb15ac58b2660513368cf8cdd63b68f65045ab96ed9cb58947b490d1422851a34861185923d50e9aa423f0dc490363c756d8b269e4d8cac68e9cd93b70f0804143376fe13372dcc801038f193b306a6cb5b2864d9a3b629a30b1b2b5081b353848173d7a07c6133271d4e021a3068d52347184ee81c119c69c3a72d2b079c37e4489c177e6f4902183730cde71f8a0a913d6cec21866e4c091818548fdfb329cec9831834d951a337e4e2e2174891c3baef5e8d113a38f1c336e2656148a85751d1844d6c7716da52c1f240f9b2fecf8918d0c9145465441a39f0c6b1950a40ab7f1fca38e1145ecebc129234aeb24f67bcab011c3c68829f6f1ebb7cbe4c894e731668c3052163ffa3a63d9949561e4c91123c263d0105a3a4e1c3466c8c651ea04cd519d60f3a0016f14290c2471289e61735ee9193469de8c45b3554d1fa84299c88622e73afeac30ac6037aaf40a9ef0236a54268247cd7f923946d0a8d1c3c68d1e35788c5002e58a50a10100 ASCII:E...h....@.......U...@..PF,{...u;..?.{J.........T.M.XGET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed3.[.~.;.M..i.......7.......X.f..6....;h.PE......G...B(Q.Ha.Y#....#..I.c.V..i.......;p..AC7o.3r......;0jl...M.;b.0.....58H.=z...2q..!...R4q.......:r..y.~D..w...!.s..q........f.....H..2...1.M..3~N.!t..;........3n&V...u..D..qm.,.$../......EFTA...k.P........E...)#J.$.{......).........1f.0R.?.:c...a...#.c..Z:N.4f..Q...Q.`...o.).$q(.as^..4i..E.UM..B...".:..0.`7.....#jT&.G...9F.......5x.P...P... -uncompressed= 45000268001300004006ceeec0a80002550d93d740000050462c7ba7e4d1753b80193fff7b4a00000101080a0003c054084dc558474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a49662d4d6f6469666965642d53696e63653a205475652c2032332041756720323031362031323a33343a323920474d540d0a0d0a ASCII:E..h....@.......U...@..PF,{...u;..?.{J.........T.M.XGET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..If-Modified-Since: Tue, 23 Aug 2016 12:34:29 GMT.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 9 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 450001022d001400004006ac59c0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00 ASCII:E...-....@..Y........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application3.\....g..8o\...vj..Y........w..I..k.9`..h!....;{.0....4>G........O......9.w........g......3v`..je..4w.4ab.j.6jpd.....'d...CF...h....#2.9u..a.&...x...!CF.....AS....1...#.....e8.1c..*5f.D\...9vF....G..:h..H.&..u`...g...|...._"E62...Q..{2.e@9z..q.:F.Y....(....).F..#..o..-.#S...1......`e.U..'G...y.s.8h.d......1..AS}gO.H. <....3h.......>Eo... -uncompressed= 4500022d001400004006ac59c0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a2031302e392e312e3137313a383030300d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..-....@..Y........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: 10.9.1.171:8000..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 10 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 450001022d001500004006ac58c0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e33005cbd8215bb67cd1d386f5cecd1cb766ad5ab59b7decdbbb7ef1ba877d0ec49daf56bd83960fd8e6821a3c5cd9c3b7bc230b2e6a81d343e47e0b99306c60ea8a54fd3c801958d1d39a877e0e00183c6ebd8b767e4b89103061e337660d4806a650d9b3477c4346162056a11366a7064d6c9f30e8c2764e2a8c143460d9a9f68e2dcdc0323328c3975e4a461f326fc881278efcce9214346e418b1e3f04153c7aa9dfd31ccc88123030b11f5ec6538d93163069b2a3566d0445ce2e612397646d398118347cd9a3a68f49848f12696d0756010011f67b415ad7c90fc17be5f224536322e16195105cd7b32a16540397adb06718a3a461459afe7a58c28a293acb729c3460c1b23a6ac6ffffe2d93235388c79831c288d6f6ddeb6065a355869127478cdcae79b3739c3868cc648df3d3091a9e31abe641537d674f1848e2203cc386fbcf3368d2bcc18a06aa9a3e456fde0c00 ASCII:E...-....@..X........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application3.\....g..8o\...vj..Y........w..I..k.9`..h!....;{.0....4>G........O......9.w........g......3v`..je..4w.4ab.j.6jpd.....'d...CF...h....#2.9u..a.&...x...!CF.....AS....1...#.....e8.1c..*5f.D\...9vF....G..:h..H.&..u`...g...|...._"E62...Q..{2.e@9z..q.:F.Y....(....).F..#..o..-.#S...1......`e.U..'G...y.s.8h.d......1..AS}gO.H. <....3h.......>Eo... -uncompressed= 4500022d001500004006ac58c0a800020a0901ab40011f4046a2f5a8e0a618025018400093480000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a2031302e392e312e3137313a383030300d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..-....@..X........@..@F.......P.@..H..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: 10.9.1.171:8000..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 11 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010239000500004006ac5cc0a800020a0901ab40001f90c286afa741a348cb801840007fcb0000050a41a348dc41a34a440000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d69786564330057b36eedfa954dd8b165cfa6ddb3e60e9c372ef6049eab95ab57b062fd02164cf8cdd53b68f640256b16ed9cb38547b490d1e22791a043efc030b2c6a91d344547e0b99306c68eabad5fd3c871958d1d39b077e0e00183c6eddcbf67e4b89103061e337660d4b86a650d9b3477c4346162e56a11366a7080164d14c6133271d4e021a3068d5134717eee818119c69c3a72d2b079837e4489bf77e6f4902103738cdc71f8a0a9d3d58ec11866e4c091818548fcf9329cec9831834d951a33783e2ef173891c3bab69cc88c1a3674f1d347a6cdcf8134bea3a30889c8fb3da4a583e48162a37a891231b19208b8ca882c63e99d432a038fd6d8339471d238ac8d793534614d549e40b956123868d1153e4d3b77f97c99129cc63cc1861242c7df275beb2092bc3c89323467ef7fc693a4e1c3466c0c631ea04cdd09d5cf3a0e96e66e81d1848e2403cc366bcd13368d2bcf98ae6aa9a3e4c7ffe0c00 ASCII:E...9....@..\........@.......A.H...@.......A.H.A.JD..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed3.W.n...M..e.......7.......W.b...L...;h.@%k.....G....'..C..0....4EG........_..q...9.w........g......3v`..je..4w.4ab.j.6jp..M...2q..!...Q4q~......:r..y.~D..w...!.s..q........f.....H..2...1.M..3x>..s..;.i....gO.4zl...K.:0.....JX>H.*7..#.. .....>..2.8.m.9G.#....SF..I...a#...S.......).c..a$,}.u...+...#F~..i:N.4f..1.....\...nf...H.@<.f..3h.......>L.... -uncompressed= 45000239000500004006ac5cc0a800020a0901ab40001f90c286afa741a348cb801840007fcb0000050a41a348dc41a34a440000474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a2031302e392e312e3137313a383038300d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..9....@..\........@.......A.H...@.......A.H.A.JD..GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: 10.9.1.171:8080..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 12 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 450001025b000a00004006ac35c0a800020a0901ab40011f90c293b0a8af5e58be5018400072a60000474554202f72656470686f6e652e706e6720485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c33005cbd82154b368e59b46ad9ee597307ce1b177b066fedfa35ec583665010b266cf8cdd63b68f6543d9b76ed1cb58747b490d16268d1a34961185933d50e1aa523f0dc490363c7d6d7b169e4d8cac68e1cd93b70f0804123f7eee03372dcc801038f193b306a6cb5b2864d9a3b629a30b1b2b5081b3538461b457a07c6133238f190518366299a3843f7c0d80c634e1d3969d8bc513fa244e03b737ac890b139c6ee387cd0d4096b07610c3372e0c8c042647e7d194e76cc98c1a64a8d1940259718ba448e9dd63466c4e01134a80e1a3d38721c8a65751d1844d2c7696d65261f240d9923dcd8918d0c9045465441839fcc6a1950a606b7e1bca38e1145e8ebd929230aeb24f485cab011c3c68829f4ede3d7cbe4c814e731668c3032d3be1a3c75c6b2296be4c91123c1830e451d270e1a3364e32c758206694fb079d07c3f9a1406923812cfb0c1b9f40c9a346fc6a2d9aaa64fd4a175d33064b894bfff812b5bc2a421b3e60c8e32860e0d00 ASCII:E...[....@..5........@........^X.P.@.r...GET /redphone.png HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed,3.\...K6.Y.j..Ys....{.o..5.X6e..&l...;h.T=.v....G...bh..Ia.Y3....#..I.c....i.......;p..A#...3r......;0jl...M.;b.0.....58F.Ez...28..Q.f).8C....cN.9i..Q?.D.;sz...9..8|...k.a.3r...Bd~}.Nv....J..@%...D...4f...4...=8r..eu..D..ime&.$..#......EFTA...j.P........E...)#..$........).........1f.02.......;h.TM......G...bh..Ia.Y3....#..I.c....i.......;p..Acw..3r......;0jp...M.;b.0.....58J.Ez...2q..!...R4q.......:r..y.~D..w...!.s..q...#....f......}.2...1.M..3.R.1t..;........3n(Z...u..D..ym.,.$..3......EFTA..Lk.P........E...)#..$.}......).........1f.0b6..:d...a...#.c..j:N.4f..Y.....a....4).$q*.a.~..4i..E.UM..C... -uncompressed= 45000236003000004006cf03c0a80002550d93d740020050c30e84a9441d06ac80184000c2f400000101080a00052df410fc31bd474554202f20485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a0d0a ASCII:E..6.0..@.......U...@..P....D.....@...........-...1.GET / HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 15 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010260004500004006cec4c0a80002550d93d740030050c3134faac89c8b2980184000578d00000101080a000535c010fc34c8474554202f6e697276616e612e63737320485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d33006fcede41b3072c5dbb78e7dcad3ca2858c164ea14aa50ac3c81aaf76d0541d81e74e1a183bcef2f64d23c7593676e4fcde8183070c1ac6913b9f91e3460e187884c2a871d6ca1a3669ee8869c2c4cad9226cd4e0801d75ea1d184f7caac143460d1aab68e238dd0303358c3975e4a461f3c6fe88128fefcce9214306ea18c8e3f04153a7edd0b841e5c0918185c87f83329cec9831834d951a33967e2ee174891c3bbaf5e8d113a38f1c336e3ac2718a05771d1844eac7d16d252e1f241985563489928d8c954546544193900c6e1950bc3ab7a11da58e11450aea292a234aee240595cab011c3c68829050f2624cce4c814ed31668c3012f7a0fc3a6fd9c49561e4c91123ce63d0702a3b4e1c3466e0c6b1ea04cdd4a36cf3a0592f952a0c2471ccc839c3268e1aab67d0a479f316cd59357db83af59b062346ab0d1f46b47933e7ce9e329c3a0d00 ASCII:E...`.E..@.......U...@..P..O....)..@.W.........5...4.GET /nirvana.css HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xm3.o..A..,].x...<....N.J......v.T...N..;...M#.Y6v..........;...F..x...q...6i..i...."l....u...O|..CF...h.8...5.9u..a.........!C......AS....A........2...1.M..3.~..t..;........3n:.q..w..D...m%..$..V4.....EFTA...n.P.:......E..)*#J.$........)..&$.....1f.0....:o...a...#.c.p*;N.4f........l..Y/.*.$q..9.&...g..y...Y5}.:...#F...F.y3...2.:.. -uncompressed= 45000260004500004006cec4c0a80002550d93d740030050c3134faac89c8b2980184000578d00000101080a000535c010fc34c8474554202f6e697276616e612e63737320485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..`.E..@.......U...@..P..O....)..@.W.........5...4.GET /nirvana.css HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 16 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010264004600004006cebfc0a80002550d93d740040050c3135bab2189da61801840008f2d00000101080a000535c410fc34dc474554202f382d4269742f4c6162656c2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300952fbf517b07cd1e9f77f3ee9da317f38816325a48a56a152b0c236bc4da419375049e3b6960ec50fb3b388d1c6ad9d891237c070e1e3068245f1e7d468e1b3960e0316307460db556d6b04973474c132656d4f254836376d5ab7760008da3060f193568b4a28923750f8cd530e6d4919386cd9bfc234a48be33a7870c19ab632c8fc3074d1db87630c63023078e0c2c440c2294e164c78c196caad498f1547409a94be4d8e9ad478f9e187de498710352a4542cbbebc020823f4e6f2b74f920e1c81da34a966c64bc2c32a20a1a866476cb802236ba0def2c758c2872500f521951782739d854868d1836464c39a89061612647a6788f31638411ba0aebd791cb86ae0c234f8e18891e838654da71e2a03133378e562768ae2a7d9b078d7bab5861208913f20c1bfa5acfa049f3462e1ab56afa80950a38cdc68d5a214aa4a873e74fa144474a951a00 ASCII:E...d.F..@.......U...@..P..[.!..a..@..-........5...4.GET /8-Bit/Label.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtm3../.Q{....w........2ZH.j.+.#k..A.u..;i`.P.;8..j...#|...0h$_.}F..9`.1c.F..V..IsGL.&V..T.cv..w`......5h...#u...0........#JH.3.....c,...M..v0.0#...,D."..d...l....Tt..K....G...}..q.R.T,... .?No+t. ....J.ld.,2....dv.."6...,u.(rP.R.Qx'9.T...6FL9..aa&G.x.1c...........#O......T.q..137.V'h.*}...{.Xa ......Z..I.F...j....8...Z!J..s.O.DGJ... -uncompressed= 45000264004600004006cebfc0a80002550d93d740040050c3135bab2189da61801840008f2d00000101080a000535c410fc34dc474554202f382d4269742f4c6162656c2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..d.F..@.......U...@..P..[.!..a..@..-........5...4.GET /8-Bit/Label.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 17 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010264005800004006ceadc0a80002550d93d740050050c31389acaf7b26538018400075c900000101080a000537d010fc354a474554202f382d4269742f41636f726e2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300942dbf497b07cd1e9f76f1ea9d93f7f28816325a48a56af50e0c236bc2da418375049e3b6960ec48eb1b388d1c69d9d891137c070e1e306820570e7d468e1b3960e0316307468db456d6b04973474c132656d2f2548343b699aa57613c2113470d1e326ad064451347ea1e18aa61cca923270d9b37f94794887c674e0f193254c7501e870f9a3a6fed608c11148e0c2c440c2294e164c78c196caad498f1347409a94be4d8e1ad478f9e187de4987103520e1ca95874d78141047f1cde56e6f241c2713bc6942bd9c87059644415340cc9e89601252c741bdd57ea1851e4a09ea432a2ec4e72d0a90c1b316c8c9872502143c34c8e4ce91e63c608237315d6af1397cd5c19469e1c31023d060da9b4e3c44163466e9cac4ed0585dea360f9af6efefc0401227e81936f4b39e4193e64d5c3469d5f4f92a15709a8d1bb342944831a7ce9e42898a942a3500 ASCII:E...d.X..@.......U...@..P.....{&S..@.u.........7...5JGET /8-Bit/Acorn.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtm3..-.I{....v........2ZH.j...#k..A.u..;i`.H..8..i....|...0h W.}F..9`.1c.F..V..IsGL.&V..T.C...Wa#...0......Z+k...#...+kw..A.*.;0.......5h...3u...0........#JP.3.....c0...M..v6.0#...,D.2..d...l.....t..K....G...}..q3..T,... .?.o+u. ..}c..ld.,2....dx..2V.../u.(.P.S.Qz'Q(U...6FLQ..ab&G.|.1c...........#O........q..1C7.V'h.:......Ya .C....[..I.f...j...:8.G.['V....P.HMN... -uncompressed= 45000266007600004006ce8dc0a80002550d93d740060050c31431ada11fa06780184000f08e00000101080a00053b3c10fc35ef474554202f382d4269742f416d73747261642e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..f.v..@.......U...@..P..1....g..@...........;<..5.GET /8-Bit/Amstrad.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 19 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010264007700004006ce8ec0a80002550d93d740040050c3135ddb2189e0108018400060d600000101080a00053b4010fc35e7474554202f382d4269742f41746172692e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300932bbf497b07cd1e9f76f1ea9d93d7f28816325a48a56a152b0c236b84da419375049e3b6960ec48dbfb378d1c69d9d891037c070e1e30681c4ffe7c468e1b3960e0316307468db456d6b04973474c132656d2f254832376d5ab77603c2113470d1e326ad068451347ea1e18a961cca923270d9b37f84794807c674e0f193252c7481e870f9aa1da2fc63023078e0c2c440a1e94e164c78c196caad498f1147409a94be4d8d9ad478f9e187de49871e311a4542cb9ebc020723fce6e2b73f920d968e7224a956c64b42c32a20a9a856472cb8022f4b90dee2a758c286250cf511951742731c854868d1836464c31887061612647a6708f31638491b908e9d789cb66ae0c234f8e18791e8386d4d971e2a03123378e562768ae26759b070d7bab58612089f3f10c9bf95acfa049f3262e9ab46afa8095fa378d468d5a1f469c8833e7ce9f41434a951a00 ASCII:E...d.w..@.......U...@..P..].!.....@.`.........;@..5.GET /8-Bit/Atari.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtm3..+.I{....v........2ZH.j.+.#k..A.u..;i`.H..7..i....|...0h.O.|F..9`.1c.F..V..IsGL.&V..T.#v..w`4..6.GET /8-Bit/Apple.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtm3..-.Q{....v........2ZH.j.+.#k..A.u..;i`.P..7..j....|...0h.O.|F..9`.1c.F..V..IsGL.&V..T.#v..w`4..6.GET /8-Bit/Apple.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 21 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010265007d00004006ce87c0a80002550d93d740050050c3138bdcaf7b296780183cec0de600000101080a00053e3410fc368e474554202f382d4269742f447261676f6e2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d33009631bf597b07cd1e9f8df5f2d59379440b192da656bd9a1586913563eda0d13a02cf9d343076ac052e9c468eb56cecc819be03070f18349433973e23c78d1c30f098b103a3c65a2b6bd8a4b923a609132b6b79aac141db2ad63b309e9089a3068f50345bd1c499ba07c6631873eac849c3e68dfe112526df99d343868cc73198c7e183a64e5c3b1963989103470616220715ca70b263c60c36556acc804abac4d42572ecf8d6a3474f8c3e72ccb80939722a16de75601051c3dfb715a27c9074ec9e71654b363260161951054d4332bc6540192bddc6f7963a461441a847a98c28bd93208ce3d3460c1b23a6205cd89030932353bec79831c208d185f7ebcc6553d7c8932346a4c7a03175769c3868ccd08db3d5091aac4ce1e641f3fe6a561848e2883cc3c6fed63368d2bc998b66ad9a3e61a7fe4dc391e3d688132beeec0974a8519253a70600 ASCII:E...e.}..@.......U...@..P.....{)g..<...........>4..6.GET /8-Bit/Dragon.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtm3..1.Y{.........yD..-.V.....5c...:...40v....F..l........4.3.>#...0......Z+k...#...+ky..A.*.;0......P4[......c.s..I.....%&...C...1.....N\;.c...G.."...p.c..6Uj..J...%r....GO.>r...9r*..u`.Q.....|.t..qeK62`..Q.MC2.e@.+....:F.A.G..(.. ...F..#. \..0.#S...1.......eS...#F...1uv.8h........L..A..jV.H..<....3h....f..>a..M......+...t.Q.S... -uncompressed= 45000265007d00004006ce87c0a80002550d93d740050050c3138bdcaf7b296780183cec0de600000101080a00053e3410fc368e474554202f382d4269742f447261676f6e2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..e.}..@.......U...@..P.....{)g..<...........>4..6.GET /8-Bit/Dragon.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 22 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010269008000004006ce80c0a80002550d93d740060050c3143301dfa11fa3de80183c892b5d00000101080a0005412c10fc3761474554202f382d4269742f456e74657270726973652e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f6600952f67defcc66dd03d3df7f6fd3bc72fe7112d64b4b08a552b571846d6983dda75049e3b6960ec701b7c388d1c6e8dca21be03070f183496db694e63468e1b3960e0316307460db756d6b04973474c132656dcee5483c376d6ad77603c2113470d1e326ad0784513c7ea1e18ae6110959386cd1bfe234a58be33a7870c19ae63548fc347285d3b1b63989103470616220ad3c870b263c60c36556acc986aba84d52572ecfcd6a3474f8c3e72ccb81149d22a96a3756010d91fe7b715bc7c90d4f9b891a54b36326216195105cd4332476540312bdd0678973a4614a923478f531951d0dc49d299aa0c1b316c8c98d2b9e143c64c8e4c011f63c60823781be2af63970d5e19469e1c31223d060dabbce3c44163e66e1caf4ed06c853a370f1af85ab9c2401267e41936f7bd9e4193e68d5d346ed5f4216bd5701aa142bd4eac78d1e7cfa1489596b46a3500 ASCII:E...i....@.......U...@..P..3........<.+]........A,..7aGET /8-Bit/Enterprise.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/f../g...m.==...;./..-d...U+W.F..=.u..;i`.p.|8..n..!.....4..iNcF..9`.1c.F..V..IsGL.&V..T..v..w`r...I.*..u`.......|......K62b..Q..C2Ge@1+..x.:F..#G.S.Q..I.....1l.....C.L.L..c..#x...c..^.F..1"=......Ac.n..N.l.:7...Z..@.g..6...A...]4n..!k.p..B.N.x....H...j5. -uncompressed= 45000269008000004006ce80c0a80002550d93d740060050c31433dfa11fa3de80183c892b5d00000101080a0005412c10fc3761474554202f382d4269742f456e74657270726973652e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..i....@.......U...@..P..3.......<.+]........A,..7aGET /8-Bit/Enterprise.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 23 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010268008100004006ce80c0a80002550d93d740040050c313600b2189e30280183d0e896b00000101080a000541d810fc379d474554202f382d4269742f436f6d6d6f646f72652e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f3300952f67defcc6ed1d347b7ceeedfb778e5fce235ac8686115ab56ae308cac316b074dd71178eea481b1c3edf0e23472b86563478ef11d3878c0a0d1fc79f519396ee48081c78c1d1835dc5a59c326cd1d314d985871cb530d8edb59b7de81f1844c1c3578c8a841e3154d1cab7b60bc8631a78e9c346cdef81f51c2f29d393d64c8781de3791c3e68ead0b5d3318699a032b01061e85086931d3366b0a95263c654d325ac2e916327b81e3d7a62f49163c64dc9a056b1fcae038348ff38c1ade0e5832424f88e2e61b29131b3c8882a682292f92d038ad9ea36c4c3d431a248433d4c6544019ea46154193662d81831a5e1c38889991c99223ec68c1146f03ed45fc72e1bbc328c3c3962a47a0c1a5671c78983c6ccdd385e9da0d9ea746e1e34f2b5728581248ec9336cf27b3d8326cd1bbb68dcaae943d62ae13420417aad78312350a1448d228523c3aad500 ASCII:E...h....@.......U...@..P..`.!.....=..k........A...7.GET /8-Bit/Commodore.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/3../g.....4{|...w._.#Z.ha..V.0..1k.M..x........4r.ecG...8x....y..9n.......5.ZY.&..1M.Xq.S...Y.....L.5x..A..M..{`..1...4l...Q...9=d.x..y.>h....1...2..a.P...3f..Rc.T.%...c'..=zb..c.M..V.....H.8.....$$...a..1...*h"..-....6...1.HC=LeD...aT.6b..1........">...F.>._....2.<9b.z..Vq......8^....tn.4..r..$..3l.{=.&...h...C.*.4 Az.x1#P.D.".#.... -uncompressed= 45000268008100004006ce80c0a80002550d93d740040050c313600b2189e30280183d0e896b00000101080a000541d810fc379d474554202f382d4269742f436f6d6d6f646f72652e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..h....@.......U...@..P..`.!.....=..k........A...7.GET /8-Bit/Commodore.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 24 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010263008200004006ce84c0a80002550d93d740050050c3138e0daf7b2cf180183962cb2f00000101080a000542b410fc3822474554202f382d4269742f454143412e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b330096dfa4bd83668f4fbb78f5cec97b79440b192da24ead7a1586913561eda0c13a02cf9d343076a4f50d9c468eb46cecc809be03070f1834902b873e23c78d1c30f098b103a3465a2b6bd8a4b923a609132b6979aac1219baad53b309e9089a3060f193568b2a28913750f0cd530e6d4919386cd9bfc234a44be33a7870c19aa63288fc3074d9db77630c63023078e0c2c440c2294e164c78c196caad498e1347489a84be4d8e1ad478f9e187de49871035264542cbaebc020823f0e6f2b73f920e1b81da34a966c64bc2c32a20a1a866474cb801216ba8dee2c758c287250cf511951762739c854868d1836464c39a89021612647a6748f31638491b90aebd789cb66ae0c234f8e18811e8346d4d971e2a03123374e562768ac26759b074dfbaa5761208913f20c1bfa59cfa049f3262e9ab46afa7c8dfa37cdc68d59214aa4a873e7cfa04347468d1a00 ASCII:E...c....@.......U...@..P.....{,...9b./........B...8"GET /8-Bit/EACA.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+3......f.O.x...{yD..-.N.z...5a...:...40v....F..l........4.+.>#...0.....FZ+k...#...+iy..!...;0.......5h....u...0........#JD.3.....c(...M..v0.0#...,D."..d...l....4t..K....G...}..q.RdT,... .?.o+s. ....J.ld.,2....dt.......,u.(rP.Q.Qv'9.T...6FL9..!a&G.t.1c........f..#O.....F..q..1#7NV'h.&u..M..Wa ......Y..I.&...j.|..7...Y!J..s...CGF... -uncompressed= 45000263008200004006ce84c0a80002550d93d740050050c3138e0daf7b2cf180183962cb2f00000101080a000542b410fc3822474554202f382d4269742f454143412e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..c....@.......U...@..P.....{,...9b./........B...8"GET /8-Bit/EACA.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 25 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010262008500004006ce82c0a80002550d93d740070050c314f5defa37d29b80183c168b6100000101080a000542c810fc37e5474554202f382d4269742f4d53582e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b330095dfa0bd83668fcfba77f3cec16b79440b192da04aa56a1586913560eda0b93a02cf9d343076a0edfd9b460eb46cecc801be03070f18348e277f3e23c78d1c30f098b103a3065a2b6bd8a4b923a609132b6879aac1117b6ad53b309e9089a3060f193568b0a28903750f8cd430e6d4919386cd1bfc234a40be33a7870c19a963248fc3074d1db7762ec63023078e0c2c440a1e94e164c78c196caad498d1147409a84be4d8d9ad478f9e187de49871f33124542cb9ebc020723fce6e2b72f920d9a8fd62ca956c64b82c32a20a9a856472cb8002f6b90dee2b758c2862508f511951742731b854868d1836464c318870e1602647a6708f31638411b908e9d781cb46ae0c234f8e18791e830654d971e2a03113370e562768aa226d9b070d7baa5661208903f20c9bf958cfa049f3062e1ab46afa7885ea378d468d581f469c9853674fa0424542851a00 ASCII:E...b....@.......U...@..P.....7....<..a........B...7.GET /8-Bit/MSX.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+3......f...w...kyD..-.J.j...5`...:...40v....F..l........4.'.>#...0......Z+k...#...+hy...{j.;0.......5h....u...0........#J@.3.....c$...M..v..0#...,D....d...l.....t..K....G...}..q.1$T,... r?.n+r. ...b..ld.,2....dr.......+u.(bP.Q.Qt'1.T...6FL1.p.`&G.p.1c........F..#O..y...T.q..1.7.V'h."m...{.Va ......X..I.....j.x..7.F.X.F..SgO.BEB... -uncompressed= 45000262008500004006ce82c0a80002550d93d740070050c314f5defa37d29b80183c168b6100000101080a000542c810fc37e5474554202f382d4269742f4d53582e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..b....@.......U...@..P.....7....<..a........B...7.GET /8-Bit/MSX.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 26 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010265009400004006ce70c0a80002550d93d740060050c3143614a11fa986801836e1f43c00000101080a000545b010fc38b7474554202f382d4269742f4d617474656c2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d3300942dbf512b744fcfbb79f7ced17b79440b192da452b58a1586913562eda0c93a02cf9d343076a8edfd9b460eb56cecc801be03070f18348e277f3e23c78d1c30f098b103a3865a2b6bd8a4b923a609132b6a77aac111bbead53b309e9089a3060f193568b4a28923750f8cd430e6d4919386cd1bfc234a44be33a7870c19a963248fc3074d1db87630c63023078e0c2c440a1e94e164c78c196caad498f1347409a94be4d8d9ad478f9e187de498710352a4542cb9ebc020723fce6e2b74f920e1a81da34a966c64bc2c32a20a1a866472cb8022f6b90dee2c758c2862504f521951742731e854868d1836464c31889021612647a6708f31638411ba08e9d791bbd8c89323469ec7a02195769c3868cc7ca5abd5099aab4bdfe641c3de2a561848e2843cc366bed63368d2bc018a46ad9a3e60a5fe4db371a356881229eae4f97368d19152a50600 ASCII:E...e....@..p....U...@..P..6.......6..<........E...8.GET /8-Bit/Mattel.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtm3..-.Q+tO..y...{yD..-.R.....5b...:...40v....F..l........4.'.>#...0......Z+k...#...+jw......;0.......5h...#u...0........#JD.3.....c$...M..v0.0#...,D....d...l....4t..K....G...}..q.R.T,... r?.n+t. ....J.ld.,2....dr.."....,u.(bPOR.Qt'1.T...6FL1..!a&G.p.1c...........#F...!.v.8h.|......K..A..*V.H..<.f..3h....F..>`..M.q.V..)...sh..R... -uncompressed= 45000265009400004006ce70c0a80002550d93d740060050c3143614a11fa986801836e1f43c00000101080a000545b010fc38b7474554202f382d4269742f4d617474656c2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..e....@..p....U...@..P..6.......6..<........E...8.GET /8-Bit/Mattel.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 27 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010263009900004006ce6dc0a80002550d93d740040050c313623f2189e66b801839a5739a00000101080a0005464c10fc38f3474554202f382d4269742f4f7269632e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b330095dfa4bd83668f4fc578f5eab13ca2858c1651a756bd0ac3c89ab076d0601d81e74e1a183bd2fa064e23475a3676e404df8183070c1ac895439f91e3460e1878ccd8815123ad95356cd2dc11d3848995b43cd5e0904dd5ea1d184fc8c45183878c1a3459d1c489ba0706631873eac849c3e64dfe112520df99d343860cc63194c7e18326e8768c31ccc88123030b1183086538d93163069b2a356638155d22ea12397678ebd1a327461f3966dc7c0c19158bee3a3088e08fc3db8a5c3e4838dac19872251b192e8b8ca882862119dd32a084856ea3fb4a1d238a1cd483544694dd490e36956123868d11530e2a642898c99129dd63cc186144aec2fa75e0b2912bc3c8932346a0c7a01135769c3868ccc48d93d5091aab4adde641d3beea551848e2803cc3867ed63368d2bc818b26ad9a3e5fa3f64db3716356881229e6d4d91328519151a30600 ASCII:E...c....@..m....U...@..P..b?!..k..9.s.........FL..8.GET /8-Bit/Oric.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+3......f.O.x...<....Q.V......v.`...N..;...N#GZ6v..........C...F..x...Q#..5l........<...M....O..Q....4Y......c.s..I..M..% ...C...1....&.v.1...#.....e8.1c..*5f8.]"..9vx...'F.9f.|.....:0......\>H8...r%........!..2...n..J.#....TF..I.6.a#...S.*d(...).c..aD...u...+...#F....5v.8h........J..A...U.H..<..~.3h....&..>_..M.qcV..)....(Q.Q... -uncompressed= 45000263009900004006ce6dc0a80002550d93d740040050c313623f2189e66b801839a5739a00000101080a0005464c10fc38f3474554202f382d4269742f4f7269632e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..c....@..m....U...@..P..b?!..k..9.s.........FL..8.GET /8-Bit/Oric.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 28 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 4500010269009e00004006ce62c0a80002550d93d740060050c3143845a11fab60801840003c1c00000101080a000547d810fc38b7474554202f382d4269742f526164696f536861636b2e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f330096316be6fcc6ed1d347b7a46f60b584fe7112d64b4b08a552b5718468ad6b183a6eb083c77d2c0d8e17678711a39dcb2b123c7f80e1c3c60d068febcfa8c1c3772c0c063c60e8c1a6e89b24973474c132656dcee5483e376d6ad77603c2113470d1e326ad0784513c7ea1e189361cca923270d9b37fd4794b87c674e0f193226c7781e870f9a3a74ed748c61460e1c195888307428c3c98e1933d854a93163eae9125697c8b1135c8f1e3d31fac831e3a6e449ab587ed78141847f9ce056f0f24112127cc79731d9c8a0596444153411c9fc9601c56c751be263ea1851a4a19ea732a2004fd2b0aa0c1b316c8c98d2f061c4c54c8e4c111f63c60823781fe6af6357685e234f8e18a91e838655dd71e2a03173378e572768b6469d9b074d7cad5c61208963f20c1bfc5ecfa049f3c62e1ab76afa90b55a380d48905e2b5ecc1874e8d1a44b515ab51a00 ASCII:E...i....@..b....U...@..P..8E...`..@.<.........G...8.GET /8-Bit/RadioShack.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/3..1k.....4{zF..XO..-d...U+W.F.......#...0......Z+A........<...}5...O..Q....4\......c.s..I#4.......!C......AS....1...#.....e8.1c..*5fD.]...9vz...'F.9f.|.I...:0......]>H6r..r%..........2.e@......:F.9.G..(...|*.F..#..T(.0.#S...1..]....eCW..'G.D.A...8q.......4Y.....=V.0...y..}.g..y#..Z5}.R..F.F..#N...'P.".R.. -uncompressed= 45000266009f00004006ce64c0a80002550d93d740050050c313903caf7b2f9580183d5ce4ef00000101080a0005481810fc3934474554202f382d4269742f5068696c6970732e47494620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d6c2b786d6c2c20746578742f766e642e7761702e776d6c2c202a2f2a0d0a4163636570742d436861727365743a207574662d382c207574662d31362c2069736f2d383835392d312c2069736f2d31303634362d7563732d322c2053686966745f4a49532c20426967350d0a4163636570742d4c616e67756167653a20656e0d0a782d7761702d70726f66696c653a2022687474703a2f2f7761702e736f6e796572696373736f6e2e636f6d2f554170726f662f4b38303069523230312e786d6c220d0a486f73743a207777772e7a6f636b2e636f6d0d0a557365722d4167656e743a20536f6e794572696373736f6e4b383030692f5232422052656c656173652f4d61722d31332d323030372042726f777365722f4e657446726f6e742f332e332050726f66696c652f4d4944502d322e3020436f6e66696775726174696f6e2f434c44432d312e310d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a4163636570742d456e636f64696e673a206465666c6174652c20677a69700d0a526566657265723a20687474703a2f2f7777772e7a6f636b2e636f6d2f0d0a0d0a ASCII:E..f....@..d....U...@..P...<.{/...=\..........H...94GET /8-Bit/Philips.GIF HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/vnd.wap.wml, */*..Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, Shift_JIS, Big5..Accept-Language: en..x-wap-profile: "http://wap.sonyericsson.com/UAprof/K800iR201.xml"..Host: www.zock.com..User-Agent: SonyEricssonK800i/R2B Release/Mar-13-2007 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1..Connection: Keep-Alive..Accept-Encoding: deflate, gzip..Referer: http://www.zock.com/.... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 30 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 450001049b00ae00004006cc20c0a80002550d93d740050050c31396ceaf7b396e801840009ad400000101080a0005611010fc3d6b474554202f382d4269742f6d72776f6e672e67696620485454502f312e310d0a4163636570743a206d756c7469706172742f6d697865642c206170706c69636174696f6e2f766e642e7761702e6d756c7469706172742e6d697865642c206170706c69636174696f6e2f766e642e7761702e7868746d6c2b786d6c2c206170706c69636174696f6e2f7868746d33009733bf617b07cd9e9f8ef7f6d5a379440b192da85ac5aa1586913564eda0d93a02cf9d343076b00d3e9c460eb66cecc821be03070f183496379f3e23c78d1c30f098b103a3065b2b6b92de11d3848915b63dd5e0a87d35eb1d184fc814c543460d1aae68e250dd0303328c3975e4a461f346ff881294efcce9214306e418cde3f0415347ae1d8c31ccc88123030b1183086538d93163069b2a3566442d5d82ea1239767eebd1a327461f3966dc801449154bef3a3088e48ff3db0a513e48387ac7a892251b192f8b8ca882862199de32a0909d6e033c4b1d238a1cd4a3544614df490e3e956123868d11530e2a644898c99129e063cc186184a8423578ead06563d7c8932346a6c7a04175769c3868ccd48dc3d5099aac4ce3e641f31eab561848e2843cc3a628d73368d2bca18b86ad9a3e62a9fe4db3712357881229eadce933e8d09154a92a417265848c1d307afec489074e198678e6108d31a7e8882557ae4c9111357903abdf7f7b052b96ec4f3868d51e7e1b77ae74198ef7f63d1a76ce52bf50cf4c9d7355b7ddb290634cae7cb9b4dec05f135b76c178c41d347b7e16eeabc732db16325a74cf7a07869135647bff0e3e7c075bdad3732c6f4e7c070e1ed37dcb993e23c78d1c30f07807cfd6ca1a3669ee8869c2c40adb9e6a70a8d60ae30999a278c8e4e78a260ed53d3020c33088900d43ae25204aa46818239f8d6cbc631c3a120b11ff6964a864c9e6e58ca8a54b505d220727579d3b7d06bd48158b52a6f99f72b542940f923a13ed600c39838d8c974546fc6548a63761b2d36d8067a96344913a72f428951105cd9d248a9fcab011c3c688298ad30c444398c99129e063cc18313bce683578eae8b66be4c91123d363246f003b0e1a33d2b93a41939569dc3c68d6df8181248e193967d814e57a064d9a3774d1b055d387cd1caa7fd36cdcc835618f853a63d07473510655aa0100 ASCII:E........@.. ....U...@..P.....{9n..@...........a...=kGET /8-Bit/mrwong.gif HTTP/1.1..Accept: multipart/mixed, application/vnd.wap.multipart.mixed, application/vnd.wap.xhtml+xml, application/xhtm3..3.a{.........yD..-.Z.....5d...:...40v..>.F..l..!.....4.7.>#...0......[+k........=...}5...O...CF...h.P...2.9u..a.F.......!C......ASG...1...#.....e8.1c..*5fD-]...9v~...'F.9f...I.K.:0......Q>H8z...%../.....!..2...n..a#...S.*dH...).c..a..B5x..ec...#F...Auv.8h........L..A...V.H..<..(.3h.......>b..M.q#W..)...3...T.*Are...0z....N..x...1...%W.L..5y....{.+..O8h..~.w.t....=.v.R.P.L.sU....cL.|...._.[v.x..4{~....2..2Zt.z...5d{..>|.[..s,oN|....}..>#...0.x.....6i..i.....jp.......x....&..=0 .0...C.% J.h.#..l.c.:....id.d......KP]".'W.;}..H..R...r.B...:..`.9....EF.eH.7a..m.g.cD.:r.(.....$........)...DC...).c..1;.h5x...k...#.c$o.;..3..:A..i.Directory listing f.or /.Directory listing for /..

Directory listing for /

.
..
... - -Testing decompression with sniffed compressed TCP/IP packets: -Packet No.: 32 -v42bis_decompress_flush() rc=0 -v42bis_decompress() rc=0 -v42bis_decompress_flush() rc=0 -compressed= 45000101a0e9a54000400683540a0901abc0a800021f904004437442f17a4ab3b1501900ed04900000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205765642c203301312041756720323031362030393a32373a353520474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a66003f481c9162e40a97294800002068746d6c20506600588a3c6162644409183200002f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e672066016f72202f3c2f7469746c990068beff2823e70c9f816b6a9847af9ebd7bf8f2e9dbc7af5ff142f06bea0cc4e31d7cfced646aa74f03a444fa3373a4c64113634e7ded28554e7d1953cd7e320365744cb811bc8c82078376ff1e00 ASCII:E......@.@..T..........@.CtB.zJ..P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Wed, 3.1 Aug 2016 09:27:55 GMT..Content-type: text/html; charset=UTF-8..Content-Length: 222....f.?H..b...)H.. html Pf.X..Directory listing f.or /</titl..h..(#....kj.G...{......_.B.k.....|..dj.O..D.3s..A.cN}.(UN}.S.~2.etL.......v... -uncompressed= 450001a0e9a54000400683540a0901abc0a800021f904004437442f17a4ab3b1501900ed04900000485454502f312e3020323030204f4b0d0a5365727665723a2053696d706c65485454502f302e3620507974686f6e2f322e372e360d0a446174653a205765642c2033312041756720323031362030393a32373a353520474d540d0a436f6e74656e742d747970653a20746578742f68746d6c3b20636861727365743d5554462d380d0a436f6e74656e742d4c656e6774683a203232320d0a0d0a3c21444f43545950452068746d6c205055424c494320222d2f2f5733432f2f4454442048544d4c20332e322046696e616c2f2f454e223e3c68746d6c3e0a3c7469746c653e4469726563746f7279206c697374696e6720666f72202f3c2f7469746c653e0a3c626f64793e0a3c68323e4469726563746f7279206c697374696e6720666f72202f3c2f68323e0a3c68723e0a3c756c3e0a3c6c693e3c6120687265663d2272656470686f6e652e706e67223e72656470686f6e652e706e673c2f613e0a3c2f756c3e0a3c68723e0a3c2f626f64793e0a3c2f68746d6c3e0a ASCII:E.....@.@..T..........@.CtB.zJ..P.......HTTP/1.0 200 OK..Server: SimpleHTTP/0.6 Python/2.7.6..Date: Wed, 31 Aug 2016 09:27:55 GMT..Content-type: text/html; charset=UTF-8..Content-Length: 222....<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>.<title>Directory listing for /..

Directory listing for /

.
..
... - -Done diff --git a/tests/vty_test_runner.py b/tests/vty_test_runner.py index c4a3c8fbc..1727e5308 100644 --- a/tests/vty_test_runner.py +++ b/tests/vty_test_runner.py @@ -108,182 +108,6 @@ class TestVTYGenericBSC(TestVTYBase): self.assertTrue(self.vty.verify("exit",[''])) self.assertTrue(self.vty.node() is None) -class TestVTYMSC(TestVTYBase): - - def vty_command(self): - return ["./src/osmo-msc/osmo-msc", "-c", - "doc/examples/osmo-msc/osmo-msc.cfg"] - - def vty_app(self): - return (4254, "./src/osmo-msc/osmo-msc", "OsmoMSC", "msc") - - def testConfigNetworkTree(self, include_bsc_items=True): - self.vty.enable() - self.assertTrue(self.vty.verify("configure terminal",[''])) - self.assertEquals(self.vty.node(), 'config') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify("network",[''])) - self.assertEquals(self.vty.node(), 'config-net') - self.checkForEndAndExit() - self.vty.command("write terminal") - self.assertTrue(self.vty.verify("exit",[''])) - self.assertEquals(self.vty.node(), 'config') - self.assertTrue(self.vty.verify("exit",[''])) - self.assertTrue(self.vty.node() is None) - - def checkForSmpp(self): - """SMPP is not always enabled, check if it is""" - res = self.vty.command("list") - return "smpp" in res - - def testSmppFirst(self): - # enable the configuration - self.vty.enable() - self.vty.command("configure terminal") - - if not self.checkForSmpp(): - return - - self.vty.command("smpp") - - # check the default - res = self.vty.command("write terminal") - self.assert_(res.find(' no smpp-first') > 0) - - self.vty.verify("smpp-first", ['']) - res = self.vty.command("write terminal") - self.assert_(res.find(' smpp-first') > 0) - self.assertEquals(res.find('no smpp-first'), -1) - - self.vty.verify("no smpp-first", ['']) - res = self.vty.command("write terminal") - self.assert_(res.find('no smpp-first') > 0) - - def testVtyTree(self): - self.vty.enable() - self.assertTrue(self.vty.verify("configure terminal", [''])) - self.assertEquals(self.vty.node(), 'config') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify('mncc-int', [''])) - self.assertEquals(self.vty.node(), 'config-mncc-int') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify('exit', [''])) - - if self.checkForSmpp(): - self.assertEquals(self.vty.node(), 'config') - self.assertTrue(self.vty.verify('smpp', [''])) - self.assertEquals(self.vty.node(), 'config-smpp') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify("exit", [''])) - - self.assertEquals(self.vty.node(), 'config') - self.assertTrue(self.vty.verify("exit", [''])) - self.assertTrue(self.vty.node() is None) - - # Check searching for outer node's commands - self.vty.command("configure terminal") - self.vty.command('mncc-int') - - if self.checkForSmpp(): - self.vty.command('smpp') - self.assertEquals(self.vty.node(), 'config-smpp') - self.vty.command('mncc-int') - - self.assertEquals(self.vty.node(), 'config-mncc-int') - - def testVtyAuthorization(self): - self.vty.enable() - self.vty.command("configure terminal") - self.vty.command("network") - self.assertTrue(self.vty.verify("auth policy closed", [''])) - self.assertTrue(self.vty.verify("auth policy regexp", [''])) - self.assertTrue(self.vty.verify("authorized-regexp ^001", [''])) - self.assertTrue(self.vty.verify("authorized-regexp 02$", [''])) - self.assertTrue(self.vty.verify("authorized-regexp *123.*", [''])) - self.vty.command("end") - - def testSi2Q(self): - self.vty.enable() - self.vty.command("configure terminal") - self.vty.command("network") - self.vty.command("bts 0") - before = self.vty.command("show running-config") - self.vty.command("si2quater neighbor-list add earfcn 1911 threshold 11 2") - self.vty.command("si2quater neighbor-list add earfcn 1924 threshold 11 3") - self.vty.command("si2quater neighbor-list add earfcn 2111 threshold 11") - self.vty.command("si2quater neighbor-list del earfcn 1911") - self.vty.command("si2quater neighbor-list del earfcn 1924") - self.vty.command("si2quater neighbor-list del earfcn 2111") - self.assertEquals(before, self.vty.command("show running-config")) - self.vty.command("si2quater neighbor-list add uarfcn 1976 13 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 38 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 44 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 120 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 140 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 163 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 166 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 217 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 224 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 225 1") - self.vty.command("si2quater neighbor-list add uarfcn 1976 226 1") - self.vty.command("si2quater neighbor-list del uarfcn 1976 13") - self.vty.command("si2quater neighbor-list del uarfcn 1976 38") - self.vty.command("si2quater neighbor-list del uarfcn 1976 44") - self.vty.command("si2quater neighbor-list del uarfcn 1976 120") - self.vty.command("si2quater neighbor-list del uarfcn 1976 140") - self.vty.command("si2quater neighbor-list del uarfcn 1976 163") - self.vty.command("si2quater neighbor-list del uarfcn 1976 166") - self.vty.command("si2quater neighbor-list del uarfcn 1976 217") - self.vty.command("si2quater neighbor-list del uarfcn 1976 224") - self.vty.command("si2quater neighbor-list del uarfcn 1976 225") - self.vty.command("si2quater neighbor-list del uarfcn 1976 226") - self.assertEquals(before, self.vty.command("show running-config")) - - def testEnableDisablePeriodicLU(self): - self.vty.enable() - self.vty.command("configure terminal") - self.vty.command("network") - self.vty.command("bts 0") - - # Test invalid input - self.vty.verify("periodic location update 0", ['% Unknown command.']) - self.vty.verify("periodic location update 5", ['% Unknown command.']) - self.vty.verify("periodic location update 1531", ['% Unknown command.']) - - # Enable periodic lu.. - self.vty.verify("periodic location update 60", ['']) - res = self.vty.command("write terminal") - self.assert_(res.find('periodic location update 60') > 0) - self.assertEquals(res.find('no periodic location update'), -1) - - # Now disable it.. - self.vty.verify("no periodic location update", ['']) - res = self.vty.command("write terminal") - self.assertEquals(res.find('periodic location update 60'), -1) - self.assert_(res.find('no periodic location update') > 0) - - def testShowNetwork(self): - res = self.vty.command("show network") - self.assert_(res.startswith('BSC is on Country Code') >= 0) - - def testMeasurementFeed(self): - self.vty.enable() - self.vty.command("configure terminal") - self.vty.command("mncc-int") - - res = self.vty.command("write terminal") - self.assertEquals(res.find('meas-feed scenario'), -1) - - self.vty.command("meas-feed scenario bla") - res = self.vty.command("write terminal") - self.assert_(res.find('meas-feed scenario bla') > 0) - - self.vty.command("meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890") - res = self.vty.command("write terminal") - self.assertEquals(res.find('meas-feed scenario abcdefghijklmnopqrstuvwxyz01234567890'), -1) - self.assertEquals(res.find('meas-feed scenario abcdefghijklmnopqrstuvwxyz012345'), -1) - self.assert_(res.find('meas-feed scenario abcdefghijklmnopqrstuvwxyz01234') > 0) - class TestVTYBSC(TestVTYGenericBSC): @@ -719,205 +543,6 @@ class TestVTYNAT(TestVTYGenericBSC): asserted = True self.assert_(asserted) -class TestVTYGbproxy(TestVTYGenericBSC): - - def vty_command(self): - return ["./src/gprs/osmo-gbproxy", "-c", - "doc/examples/osmo-gbproxy/osmo-gbproxy.cfg"] - - def vty_app(self): - return (4246, "./src/gprs/osmo-gbproxy", "OsmoGbProxy", "bsc") - - def testVtyTree(self): - self.vty.enable() - self.assertTrue(self.vty.verify('configure terminal', [''])) - self.assertEquals(self.vty.node(), 'config') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify('ns', [''])) - self.assertEquals(self.vty.node(), 'config-ns') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify('exit', [''])) - self.assertEquals(self.vty.node(), 'config') - self.assertTrue(self.vty.verify('gbproxy', [''])) - self.assertEquals(self.vty.node(), 'config-gbproxy') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify('exit', [''])) - self.assertEquals(self.vty.node(), 'config') - - def testVtyShow(self): - res = self.vty.command("show ns") - self.assert_(res.find('Encapsulation NS-UDP-IP') >= 0) - - res = self.vty.command("show gbproxy stats") - self.assert_(res.find('GBProxy Global Statistics') >= 0) - - def testVtyDeletePeer(self): - self.vty.enable() - self.assertTrue(self.vty.verify('delete-gbproxy-peer 9999 bvci 7777', ['BVC not found'])) - res = self.vty.command("delete-gbproxy-peer 9999 all dry-run") - self.assert_(res.find('Not Deleted 0 BVC') >= 0) - self.assert_(res.find('Not Deleted 0 NS-VC') >= 0) - res = self.vty.command("delete-gbproxy-peer 9999 only-bvc dry-run") - self.assert_(res.find('Not Deleted 0 BVC') >= 0) - self.assert_(res.find('Not Deleted 0 NS-VC') < 0) - res = self.vty.command("delete-gbproxy-peer 9999 only-nsvc dry-run") - self.assert_(res.find('Not Deleted 0 BVC') < 0) - self.assert_(res.find('Not Deleted 0 NS-VC') >= 0) - res = self.vty.command("delete-gbproxy-peer 9999 all") - self.assert_(res.find('Deleted 0 BVC') >= 0) - self.assert_(res.find('Deleted 0 NS-VC') >= 0) - -class TestVTYSGSN(TestVTYGenericBSC): - - def vty_command(self): - return ["./src/gprs/osmo-sgsn", "-c", - "doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg"] - - def vty_app(self): - return (4245, "./src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn") - - def testVtyTree(self): - self.vty.enable() - self.assertTrue(self.vty.verify('configure terminal', [''])) - self.assertEquals(self.vty.node(), 'config') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify('ns', [''])) - self.assertEquals(self.vty.node(), 'config-ns') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify('exit', [''])) - self.assertEquals(self.vty.node(), 'config') - self.assertTrue(self.vty.verify('sgsn', [''])) - self.assertEquals(self.vty.node(), 'config-sgsn') - self.checkForEndAndExit() - self.assertTrue(self.vty.verify('exit', [''])) - self.assertEquals(self.vty.node(), 'config') - - def testVtyShow(self): - res = self.vty.command("show ns") - self.assert_(res.find('Encapsulation NS-UDP-IP') >= 0) - self.assertTrue(self.vty.verify('show bssgp', [''])) - self.assertTrue(self.vty.verify('show bssgp stats', [''])) - # TODO: uncomment when the command does not segfault anymore - # self.assertTrue(self.vty.verify('show bssgp nsei 123', [''])) - # self.assertTrue(self.vty.verify('show bssgp nsei 123 stats', [''])) - - self.assertTrue(self.vty.verify('show sgsn', [''])) - self.assertTrue(self.vty.verify('show mm-context all', [''])) - self.assertTrue(self.vty.verify('show mm-context imsi 000001234567', ['No MM context for IMSI 000001234567'])) - self.assertTrue(self.vty.verify('show pdp-context all', [''])) - - res = self.vty.command("show sndcp") - self.assert_(res.find('State of SNDCP Entities') >= 0) - - res = self.vty.command("show llc") - self.assert_(res.find('State of LLC Entities') >= 0) - - def testVtyAuth(self): - self.vty.enable() - self.assertTrue(self.vty.verify('configure terminal', [''])) - self.assertEquals(self.vty.node(), 'config') - self.assertTrue(self.vty.verify('sgsn', [''])) - self.assertEquals(self.vty.node(), 'config-sgsn') - self.assertTrue(self.vty.verify('auth-policy accept-all', [''])) - res = self.vty.command("show running-config") - self.assert_(res.find('auth-policy accept-all') > 0) - self.assertTrue(self.vty.verify('auth-policy acl-only', [''])) - res = self.vty.command("show running-config") - self.assert_(res.find('auth-policy acl-only') > 0) - self.assertTrue(self.vty.verify('auth-policy closed', [''])) - res = self.vty.command("show running-config") - self.assert_(res.find('auth-policy closed') > 0) - self.assertTrue(self.vty.verify('gsup remote-ip 127.0.0.4', [''])) - self.assertTrue(self.vty.verify('gsup remote-port 2222', [''])) - self.assertTrue(self.vty.verify('auth-policy remote', [''])) - res = self.vty.command("show running-config") - self.assert_(res.find('auth-policy remote') > 0) - - def testVtySubscriber(self): - self.vty.enable() - res = self.vty.command('show subscriber cache') - self.assert_(res.find('1234567890') < 0) - self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 create', [''])) - res = self.vty.command('show subscriber cache') - self.assert_(res.find('1234567890') >= 0) - self.assert_(res.find('Authorized: 0') >= 0) - self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 update-location-result ok', [''])) - res = self.vty.command('show subscriber cache') - self.assert_(res.find('1234567890') >= 0) - self.assert_(res.find('Authorized: 1') >= 0) - self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 cancel update-procedure', [''])) - res = self.vty.command('show subscriber cache') - self.assert_(res.find('1234567890') >= 0) - self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 destroy', [''])) - res = self.vty.command('show subscriber cache') - self.assert_(res.find('1234567890') < 0) - - def testVtyGgsn(self): - self.vty.enable() - self.assertTrue(self.vty.verify('configure terminal', [''])) - self.assertEquals(self.vty.node(), 'config') - self.assertTrue(self.vty.verify('sgsn', [''])) - self.assertEquals(self.vty.node(), 'config-sgsn') - self.assertTrue(self.vty.verify('ggsn 0 remote-ip 127.99.99.99', [''])) - self.assertTrue(self.vty.verify('ggsn 0 gtp-version 1', [''])) - self.assertTrue(self.vty.verify('apn * ggsn 0', [''])) - self.assertTrue(self.vty.verify('apn apn1.test ggsn 0', [''])) - self.assertTrue(self.vty.verify('apn apn1.test ggsn 1', ['% a GGSN with id 1 has not been defined'])) - self.assertTrue(self.vty.verify('apn apn1.test imsi-prefix 123456 ggsn 0', [''])) - self.assertTrue(self.vty.verify('apn apn2.test imsi-prefix 123456 ggsn 0', [''])) - res = self.vty.command("show running-config") - self.assert_(res.find('ggsn 0 remote-ip 127.99.99.99') >= 0) - self.assert_(res.find('ggsn 0 gtp-version 1') >= 0) - self.assert_(res.find('apn * ggsn 0') >= 0) - self.assert_(res.find('apn apn1.test ggsn 0') >= 0) - self.assert_(res.find('apn apn1.test imsi-prefix 123456 ggsn 0') >= 0) - self.assert_(res.find('apn apn2.test imsi-prefix 123456 ggsn 0') >= 0) - - def testVtyEasyAPN(self): - self.vty.enable() - self.assertTrue(self.vty.verify('configure terminal', [''])) - self.assertEquals(self.vty.node(), 'config') - self.assertTrue(self.vty.verify('sgsn', [''])) - self.assertEquals(self.vty.node(), 'config-sgsn') - - res = self.vty.command("show running-config") - self.assertEquals(res.find("apn internet"), -1) - - self.assertTrue(self.vty.verify("access-point-name internet.apn", [''])) - res = self.vty.command("show running-config") - self.assert_(res.find("apn internet.apn ggsn 0") >= 0) - - self.assertTrue(self.vty.verify("no access-point-name internet.apn", [''])) - res = self.vty.command("show running-config") - self.assertEquals(res.find("apn internet"), -1) - - def testVtyCDR(self): - self.vty.enable() - self.assertTrue(self.vty.verify('configure terminal', [''])) - self.assertEquals(self.vty.node(), 'config') - self.assertTrue(self.vty.verify('sgsn', [''])) - self.assertEquals(self.vty.node(), 'config-sgsn') - - res = self.vty.command("show running-config") - self.assert_(res.find("no cdr filename") > 0) - - self.vty.command("cdr filename bla.cdr") - res = self.vty.command("show running-config") - self.assertEquals(res.find("no cdr filename"), -1) - self.assert_(res.find(" cdr filename bla.cdr") > 0) - - self.vty.command("no cdr filename") - res = self.vty.command("show running-config") - self.assert_(res.find("no cdr filename") > 0) - self.assertEquals(res.find(" cdr filename bla.cdr"), -1) - - res = self.vty.command("show running-config") - self.assert_(res.find(" cdr interval 600") > 0) - - self.vty.command("cdr interval 900") - res = self.vty.command("show running-config") - self.assert_(res.find(" cdr interval 900") > 0) - self.assertEquals(res.find(" cdr interval 600"), -1) def add_nat_test(suite, workdir): if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc_nat/osmo-bsc_nat")): @@ -1050,20 +675,6 @@ def add_bsc_test(suite, workdir): test = unittest.TestLoader().loadTestsFromTestCase(TestVTYBSC) suite.addTest(test) -def add_gbproxy_test(suite, workdir): - if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-gbproxy")): - print("Skipping the Gb-Proxy test") - return - test = unittest.TestLoader().loadTestsFromTestCase(TestVTYGbproxy) - suite.addTest(test) - -def add_sgsn_test(suite, workdir): - if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-sgsn")): - print("Skipping the SGSN test") - return - test = unittest.TestLoader().loadTestsFromTestCase(TestVTYSGSN) - suite.addTest(test) - if __name__ == '__main__': import argparse import sys @@ -1094,11 +705,8 @@ if __name__ == '__main__': os.chdir(workdir) print "Running tests for specific VTY commands" suite = unittest.TestSuite() - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestVTYMSC)) add_bsc_test(suite, workdir) add_nat_test(suite, workdir) - add_gbproxy_test(suite, workdir) - add_sgsn_test(suite, workdir) if args.test_name: osmoutil.pick_tests(suite, *args.test_name) diff --git a/tests/xid/Makefile.am b/tests/xid/Makefile.am deleted file mode 100644 index aaf17edf2..000000000 --- a/tests/xid/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBCARES_CFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - xid_test.ok \ - $(NULL) - -noinst_PROGRAMS = \ - xid_test \ - $(NULL) - -xid_test_SOURCES = \ - xid_test.c \ - $(NULL) - -xid_test_LDADD = \ - $(top_builddir)/src/gprs/gprs_llc_xid.o \ - $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOABIS_LIBS) \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOGB_LIBS) \ - $(LIBCARES_LIBS) \ - $(LIBCRYPTO_LIBS) \ - $(LIBGTP_LIBS) \ - -lrt \ - -lm \ - $(NULL) - diff --git a/tests/xid/xid_test.c b/tests/xid/xid_test.c deleted file mode 100644 index b77a4ae85..000000000 --- a/tests/xid/xid_test.c +++ /dev/null @@ -1,164 +0,0 @@ -/* Test LLC-XID Encoding/Decoding */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 Affero 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 . - */ - -#include -#include - -#include -#include - -#include - -#include -#include - -/* Test XID encoding */ -static void test_xid_encode(const void *ctx) -{ - struct gprs_llc_xid_field xid_field_1; - struct gprs_llc_xid_field xid_field_2; - struct gprs_llc_xid_field xid_field_3; - struct gprs_llc_xid_field xid_field_4; - LLIST_HEAD(xid_fields); - uint8_t xid[255]; - uint8_t xid_expected[] = - { 0x10, 0x8c, 0x14, 0x43, 0x43, 0x43, 0x43, 0x43, 0x0b, 0x42, 0x42, - 0x42, 0x05, 0x41 }; - int rc; - - printf("Testing LLC XID-Encoder\n"); - - /* Setup some simple XID data */ - xid_field_1.type = 1; - xid_field_2.type = 2; - xid_field_3.type = 3; - xid_field_4.type = 4; - - xid_field_1.data = (uint8_t *) "A"; - xid_field_2.data = (uint8_t *) "BBB"; - xid_field_3.data = (uint8_t *) "CCCCC"; - xid_field_4.data = NULL; - - xid_field_1.data_len = 1; - xid_field_2.data_len = 3; - xid_field_3.data_len = 5; - xid_field_4.data_len = 0; - - llist_add(&xid_field_4.list, &xid_fields); - llist_add(&xid_field_3.list, &xid_fields); - llist_add(&xid_field_2.list, &xid_fields); - llist_add(&xid_field_1.list, &xid_fields); - - printf("Data to encode:\n"); - gprs_llc_dump_xid_fields(&xid_fields, DSNDCP); - - /* Encode data */ - rc = gprs_llc_compile_xid(xid, sizeof(xid), &xid_fields); - OSMO_ASSERT(rc == 14); - printf("Encoded: %s (%i bytes)\n", osmo_hexdump_nospc(xid, rc), rc); - printf("Expected: %s (%i bytes)\n", - osmo_hexdump_nospc(xid_expected, sizeof(xid_expected)), - (int)sizeof(xid_expected)); - - OSMO_ASSERT(memcmp(xid_expected, xid, sizeof(xid_expected)) == 0); - - printf("\n"); -} - -/* Test XID decoding */ -static void test_xid_decode(const void *ctx) -{ - struct llist_head *xid_fields; - int rc; - - printf("Testing LLC XID-Decoder/Encoder\n"); - - /* Example of a real world LLC-XID message */ - uint8_t xid[] = - { 0x01, 0x00, 0x16, 0x05, 0xf0, 0x1a, 0x05, 0xf0, 0xac, 0xd8, 0x00, - 0x01, 0x00, 0x02, 0x31, 0x82, 0x02, 0x27, 0x89, 0xff, 0xe0, 0x00, 0x0f, - 0x00, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x01, 0x02, - 0x00, 0x03, 0x01, 0x03, 0x00, 0x04, 0x01, 0x04, 0x00, 0x05, 0x01, 0x05, - 0x00, 0x06, 0x00, 0x07, 0x01, 0x07, 0x00, 0x08, 0x01, 0x08, 0x80, 0x00, - 0x04, 0x12, 0x00, 0x40, 0x07 }; - - uint8_t xid_r[512]; - - /* Decode and display XID fields */ - xid_fields = gprs_llc_parse_xid(ctx, xid, sizeof(xid)); - OSMO_ASSERT(xid_fields); - - printf("Decoded:\n"); - gprs_llc_dump_xid_fields(xid_fields, DSNDCP); - - - /* Encode xid-fields again */ - rc = gprs_llc_compile_xid(xid_r, sizeof(xid_r), xid_fields); - printf("Result length=%i\n",rc); - printf("Encoded: %s\n", osmo_hexdump_nospc(xid, sizeof(xid))); - printf("Rencoded: %s\n", osmo_hexdump_nospc(xid_r, rc)); - - OSMO_ASSERT(rc == 64); - OSMO_ASSERT(memcmp(xid, xid_r, sizeof(xid)) == 0); - - /* Free xid fields */ - talloc_free(xid_fields); - - printf("\n"); -} - -static struct log_info_cat gprs_categories[] = { - [DSNDCP] = { - .name = "DSNDCP", - .description = - "GPRS Sub-Network Dependent Control Protocol (SNDCP)", - .enabled = 1,.loglevel = LOGL_DEBUG, - } -}; - -static struct log_info info = { - .cat = gprs_categories, - .num_cat = ARRAY_SIZE(gprs_categories), -}; - -int main(int argc, char **argv) -{ - void *xid_ctx; - - osmo_init_logging(&info); - - xid_ctx = talloc_named_const(NULL, 0, "xid_ctx"); - - test_xid_decode(xid_ctx); - test_xid_encode(xid_ctx); - printf("Done\n"); - - talloc_report_full(xid_ctx, stderr); - OSMO_ASSERT(talloc_total_blocks(xid_ctx) == 1); - return 0; -} - -/* stubs */ -struct osmo_prim_hdr; -int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) -{ - abort(); -} diff --git a/tests/xid/xid_test.ok b/tests/xid/xid_test.ok deleted file mode 100644 index 4cf825ca5..000000000 --- a/tests/xid/xid_test.ok +++ /dev/null @@ -1,12 +0,0 @@ -Testing LLC XID-Decoder/Encoder -Decoded: -Result length=64 -Encoded: 01001605f01a05f0acd8000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 -Rencoded: 01001605f01a05f0acd8000100023182022789ffe0000f00a8000000010101000201020003010300040104000501050006000701070008010880000412004007 - -Testing LLC XID-Encoder -Data to encode: -Encoded: 108c1443434343430b4242420541 (14 bytes) -Expected: 108c1443434343430b4242420541 (14 bytes) - -Done -- cgit v1.2.3