aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO-RELEASE1
-rw-r--r--configure.ac14
-rwxr-xr-xcontrib/jenkins.sh1
-rw-r--r--contrib/osmo-sgsn.spec.in1
-rw-r--r--debian/copyright3
-rw-r--r--debian/osmo-gbproxy.install1
-rw-r--r--doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg12
-rw-r--r--doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg32
-rw-r--r--doc/examples/osmo-gbproxy/osmo-gbproxy.cfg17
-rw-r--r--doc/manuals/chapters/gbproxy-configuration.adoc26
-rw-r--r--include/osmocom/sgsn/debug.h15
-rw-r--r--include/osmocom/sgsn/gb_proxy.h434
-rw-r--r--include/osmocom/sgsn/gprs_gb.h6
-rw-r--r--include/osmocom/sgsn/gprs_gb_parse.h2
-rw-r--r--include/osmocom/sgsn/sgsn.h7
-rw-r--r--osmoappdesc.py3
-rw-r--r--src/gbproxy/Makefile.am2
-rw-r--r--src/gbproxy/gb_proxy.c2224
-rw-r--r--src/gbproxy/gb_proxy_ctrl.c73
-rw-r--r--src/gbproxy/gb_proxy_main.c128
-rw-r--r--src/gbproxy/gb_proxy_patch.c463
-rw-r--r--src/gbproxy/gb_proxy_peer.c777
-rw-r--r--src/gbproxy/gb_proxy_tlli.c725
-rw-r--r--src/gbproxy/gb_proxy_vty.c1109
-rw-r--r--src/gprs/gprs_gb_parse.c41
-rw-r--r--src/gprs/gprs_utils.c2
-rw-r--r--src/gprs/sgsn_ares.c8
-rw-r--r--src/gtphub/gtphub_main.c52
-rw-r--r--src/sgsn/gprs_gb.c83
-rw-r--r--src/sgsn/gprs_gmm.c18
-rw-r--r--src/sgsn/gprs_mm_state_gb_fsm.c5
-rw-r--r--src/sgsn/gprs_ranap.c1
-rw-r--r--src/sgsn/gprs_sgsn.c2
-rw-r--r--src/sgsn/gprs_subscriber.c6
-rw-r--r--src/sgsn/sgsn_main.c130
-rw-r--r--src/sgsn/sgsn_vty.c6
-rw-r--r--tests/Makefile.am15
-rw-r--r--tests/gbproxy/Makefile.am51
-rw-r--r--tests/gbproxy/gbproxy_test.c5082
-rw-r--r--tests/gbproxy/gbproxy_test.ok7492
-rw-r--r--tests/osmo-gbproxy-pool_test-nodes.vty35
-rw-r--r--tests/osmo-gbproxy_test-nodes.vty32
-rw-r--r--tests/osmo-sgsn_test-nodes.vty (renamed from tests/test_nodes.vty)0
-rw-r--r--tests/sgsn/sgsn_test.c5
-rw-r--r--tests/testsuite.at6
-rwxr-xr-xtests/vty_test_runner.py16
46 files changed, 2943 insertions, 16221 deletions
diff --git a/TODO-RELEASE b/TODO-RELEASE
index 6b29a879..1e409b59 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -1,2 +1,3 @@
#component what description / commit summary line
manual needs common chapter cs7-config.adoc, vty_cpu_sched.adoc from osmo-gsm-manuals > 0.3.0
+configure.ac libosmocore depend on next released libosmocore after 1.4.x with hashtable support
diff --git a/configure.ac b/configure.ac
index 12af7e64..f1a4ed48 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,6 +39,9 @@ m4_ifdef([AX_CHECK_COMPILE_FLAG], [], [
AC_MSG_ERROR([Please install autoconf-archive; re-run 'autoreconf -fi' for it to take effect.])
])
+dnl use a defined standard across all builds and don't depend on compiler default
+CFLAGS="$CFLAGS -std=gnu11"
+
dnl checks for libraries
AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""])
AC_SUBST(LIBRARY_DL)
@@ -118,8 +121,8 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])],
CFLAGS="$saved_CFLAGS"
AC_SUBST(SYMBOL_VISIBILITY)
-CPPFLAGS="$CPPFLAGS -Wall"
-CFLAGS="$CFLAGS -Wall"
+CPPFLAGS="$CPPFLAGS -Wall -Wno-trigraphs"
+CFLAGS="$CFLAGS -Wall -Wno-trigraphs"
AX_CHECK_COMPILE_FLAG([-Werror=implicit], [CFLAGS="$CFLAGS -Werror=implicit"])
AX_CHECK_COMPILE_FLAG([-Werror=maybe-uninitialized], [CFLAGS="$CFLAGS -Werror=maybe-uninitialized"])
@@ -172,9 +175,9 @@ 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
- AC_CHECK_PROG(PYTHON2_AVAIL,python2,yes)
- if test "x$PYTHON2_AVAIL" != "xyes" ; then
- AC_MSG_ERROR([Please install python2 to run the VTY/CTRL tests.])
+ AC_CHECK_PROG(PYTHON3_AVAIL,python3,yes)
+ if test "x$PYTHON3_AVAIL" != "xyes" ; then
+ AC_MSG_ERROR([Please install python3 to run the VTY/CTRL tests.])
fi
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
@@ -261,7 +264,6 @@ AC_OUTPUT(
tests/Makefile
tests/atlocal
tests/gprs/Makefile
- tests/gbproxy/Makefile
tests/sgsn/Makefile
tests/gtphub/Makefile
tests/xid/Makefile
diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh
index 87d86015..2325897a 100755
--- a/contrib/jenkins.sh
+++ b/contrib/jenkins.sh
@@ -50,7 +50,6 @@ fi
# Additional configure options and depends
CONFIG=""
if [ "$WITH_MANUALS" = "1" ]; then
- osmo-build-dep.sh osmo-gsm-manuals
CONFIG="--enable-manuals"
fi
diff --git a/contrib/osmo-sgsn.spec.in b/contrib/osmo-sgsn.spec.in
index d6a80789..ca66e2ea 100644
--- a/contrib/osmo-sgsn.spec.in
+++ b/contrib/osmo-sgsn.spec.in
@@ -131,7 +131,6 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
%files -n osmo-gbproxy
%dir %{_docdir}/%{name}/examples
%dir %{_docdir}/%{name}/examples/osmo-gbproxy
-%{_docdir}/%{name}/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
%{_docdir}/%{name}/examples/osmo-gbproxy/osmo-gbproxy.cfg
%{_bindir}/osmo-gbproxy
%dir %{_sysconfdir}/osmocom
diff --git a/debian/copyright b/debian/copyright
index fa7405fe..5bc764d6 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -24,7 +24,6 @@ Files: .gitignore
contrib/twisted_ipa.py
doc/Makefile.am
doc/examples/Makefile.am
- doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
doc/examples/osmo-gtphub/gtphub-example.txt
doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg
@@ -88,9 +87,7 @@ Files: include/osmocom/sgsn/a_reset.h
src/gprs/sgsn_ares.c
src/gbproxy/gb_proxy.c
src/gbproxy/gb_proxy_main.c
- src/gbproxy/gb_proxy_patch.c
src/gbproxy/gb_proxy_peer.c
- src/gbproxy/gb_proxy_tlli.c
src/gbproxy/gb_proxy_vty.c
src/gtphub/gtphub.c
src/gtphub/gtphub_main.c
diff --git a/debian/osmo-gbproxy.install b/debian/osmo-gbproxy.install
index a8c0dadd..1cb91d5d 100644
--- a/debian/osmo-gbproxy.install
+++ b/debian/osmo-gbproxy.install
@@ -1,5 +1,4 @@
etc/osmocom/osmo-gbproxy.cfg
lib/systemd/system/osmo-gbproxy.service
usr/bin/osmo-gbproxy
-usr/share/doc/osmo-sgsn/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg usr/share/doc/osmo-gbproxy/examples
usr/share/doc/osmo-sgsn/examples/osmo-gbproxy/osmo-gbproxy.cfg usr/share/doc/osmo-gbproxy/examples
diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
index c471c38b..e30b9f7f 100644
--- a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
+++ b/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
@@ -22,11 +22,11 @@ line vty
no login
!
ns
- nse 666 nsvci 666
- nse 666 remote-role sgsn
-! nse 666 encapsulation framerelay-gre
-! nse 666 remote-ip 172.16.1.70
-! nse 666 fr-dlci 666
+ bind udp local
+ listen 127.0.0.1 23000
+ accept-ipaccess
+ nse 666
+ nsvc ipa local 127.0.0.1 23001 nsvci 666
timer tns-block 3
timer tns-block-retries 3
timer tns-reset 3
@@ -34,8 +34,6 @@ ns
timer tns-test 30
timer tns-alive 3
timer tns-alive-retries 10
- encapsulation udp local-port 23000
-! encapsulation framerelay-gre enabled 1
gbproxy
sgsn nsei 666
core-mobile-country-code 666
diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg
new file mode 100644
index 00000000..bbc8a1b7
--- /dev/null
+++ b/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg
@@ -0,0 +1,32 @@
+!
+! Osmocom Gb Proxy (0.9.0.404-6463) configuration saved from vty
+!!
+!
+line vty
+ no login
+!
+gbproxy
+ nri bitlen 4
+ nri null add 0 4
+sgsn nsei 101
+ name main
+ nri add 1
+ nri add 11
+sgsn nsei 102
+ nri add 2
+ nri add 12
+ns
+ bind udp local
+ listen 127.0.0.100 23000
+ accept-ipaccess
+ nse 101
+ nsvc ipa local 192.168.100.239 7777 nsvci 101
+ nse 102
+ nsvc ipa local 192.168.100.239 7778 nsvci 102
+ 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
diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
index 29f698f3..777d0b0f 100644
--- a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
+++ b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
@@ -6,13 +6,14 @@ line vty
no login
!
gbproxy
- sgsn nsei 101
+sgsn nsei 101
+ name main
ns
- nse 101 nsvci 101
- nse 101 remote-role sgsn
- nse 101 encapsulation udp
- nse 101 remote-ip 192.168.100.239
- nse 101 remote-port 7777
+ bind udp local
+ listen 127.0.0.100 23000
+ accept-ipaccess
+ nse 101
+ nsvc ipa local 192.168.100.239 7777 nsvci 101
timer tns-block 3
timer tns-block-retries 3
timer tns-reset 3
@@ -20,7 +21,3 @@ ns
timer tns-test 30
timer tns-alive 3
timer tns-alive-retries 10
- encapsulation framerelay-gre enabled 0
- encapsulation framerelay-gre local-ip 0.0.0.0
- encapsulation udp local-ip 127.0.0.100
- encapsulation udp local-port 23000
diff --git a/doc/manuals/chapters/gbproxy-configuration.adoc b/doc/manuals/chapters/gbproxy-configuration.adoc
index 599b3f7b..e61af48b 100644
--- a/doc/manuals/chapters/gbproxy-configuration.adoc
+++ b/doc/manuals/chapters/gbproxy-configuration.adoc
@@ -4,3 +4,29 @@ TBD. Unfortunately this chapter of the manual still needs to be written.
Osmocom has very limited funding and support resources; Feel free to help
us completing this documentation by contributing with code, documentation
or by supporting the developers financially.
+
+
+=== SGSN pool support
+
+In a SGSN pool, osmo-gbproxy is facing the problem of dividing the downlink
+capacity of a cell towards the SGSN. The BSS advertises the per-BVC capacity
+by means of the BSSGP FLOW-CONTROL-BVC messages, but as there are multiple
+SGSN in a pool, they all have to share / divide that total capacity.
+
+By default, osmo-gbproxy advertises the full capacity to _each_ of the SGSN
+pool members, which results in significant over-provisioning and can lead to
+overload situations.
+
+The administrator can configure the _percentage_ of the overall BSS-advertised
+capacity that shall be reported to each pool member SGSN using the
+`pool bvc-flow-control-ratio <1-100>` configuration command.
+
+A setting of 100 means that each pool member is informed of 100% of the
+BSS side capacity.
+
+A setting of 25 means that each pool member is informed of 25% of the
+BSS side capacity. This would make most sense in a set-up with four
+SGSN of equal share.
+
+More complex capacity division schemes are so far not supported by
+osmo-gbproxy.
diff --git a/include/osmocom/sgsn/debug.h b/include/osmocom/sgsn/debug.h
index 29d500da..9a686cb6 100644
--- a/include/osmocom/sgsn/debug.h
+++ b/include/osmocom/sgsn/debug.h
@@ -8,38 +8,25 @@
/* Debug Areas of the code */
enum {
- DRLL,
- DCC,
DMM,
- DRR,
- DRSL,
- DNM,
- DMNCC,
DPAG,
DMEAS,
- DSCCP,
- DMSC,
- DHO,
- DDB,
DREF,
DGPRS,
DNS,
- DBSSGP,
DLLC,
DSNDCP,
DSLHC,
- DNAT,
DCTRL,
DFILTER,
DGTPHUB,
DRANAP,
DSUA,
DV42BIS,
- DPCU,
- DVLR,
DIUCS,
DSIGTRAN,
DGTP,
+ DOBJ,
Debug_LastEntry,
};
diff --git a/include/osmocom/sgsn/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h
index 1e8fb253..d988cae7 100644
--- a/include/osmocom/sgsn/gb_proxy.h
+++ b/include/osmocom/sgsn/gb_proxy.h
@@ -3,9 +3,14 @@
#include <osmocom/core/msgb.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/hashtable.h>
#include <osmocom/gsm/gsm23003.h>
+#include <osmocom/gsm/gsm23236.h>
+#include <osmocom/gsm/protocol/gsm_23_003.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/vty/command.h>
#include <sys/types.h>
@@ -13,6 +18,10 @@
#include <stdbool.h>
#define GBPROXY_INIT_VU_GEN_TX 256
+#define GBPROXY_MAX_NR_SGSN 16
+
+/* BVCI uses 16 bits */
+#define BVC_LOG_CTX_FLAG (1<<17)
struct rate_ctr_group;
struct gprs_gb_parse_context;
@@ -30,198 +39,196 @@ enum gbproxy_global_ctr {
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 {
+enum gbproxy_bvc_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, /* don't ever keep TLLI/IMSI state of de-registered subscribers */
- GBPROX_KEEP_REATTACH, /* keep if re-attach has been requested by SGSN */
- GBPROX_KEEP_IDENTIFIED, /* keep if we had resolved an IMSI */
- GBPROX_KEEP_ALWAYS, /* always keep */
-};
-
-enum gbproxy_match_id {
- GBPROX_MATCH_PATCHING, /* match rule on whether or not we should patch */
- GBPROX_MATCH_ROUTING, /* match rule on whether or not we should route (2-SGSN) */
- GBPROX_MATCH_LAST
-};
-
-struct gbproxy_match {
- bool enable; /* is this match enabled? */
- char *re_str; /* regular expression (for IMSI) in string format */
- regex_t re_comp; /* compiled regular expression (for IMSI) */
-};
-
/* global gb-proxy configuration */
struct gbproxy_config {
- /* parsed from config file */
- uint16_t nsip_sgsn_nsei;
-
/* NS instance of libosmogb */
- struct gprs_ns_inst *nsi;
-
- /* Linked list of all Gb peers (except SGSN) */
- struct llist_head bts_peers;
+ struct gprs_ns2_inst *nsi;
+
+ struct {
+ /* percentage of BVC flow control advertised to each SGSN in the pool */
+ uint8_t bvc_fc_ratio;
+ /* NRI bitlen and usable NULL-NRI ranges */
+ uint8_t nri_bitlen;
+ struct osmo_nri_ranges *null_nri_ranges;
+
+ /* Used for testing: If not NULL then this SGSN is returned by
+ * gbproxy_sgsn_by_tlli() */
+ struct gbproxy_sgsn *nsf_override;
+ } pool;
+
+ /* hash table of all BSS side Gb peers */
+ DECLARE_HASHTABLE(bss_nses, 8);
+
+ /* hash table of all SGSN-side Gb peers */
+ DECLARE_HASHTABLE(sgsn_nses, 8);
+
+ /* hash table of all gbproxy_cell */
+ DECLARE_HASHTABLE(cells, 8);
+
+ /* tlli<->nse cache used to map SUSPEND/RESUME (N)ACKS */
+ struct {
+ DECLARE_HASHTABLE(entries, 10);
+ struct osmo_timer_list timer;
+ /* Time in seconds that the entries should be valid */
+ uint8_t timeout;
+ } tlli_cache;
+
+ /* imsi<->nse cache used for PAGING REJECT */
+ struct {
+ DECLARE_HASHTABLE(entries, 10);
+ struct osmo_timer_list timer;
+ /* Time in seconds that the entries should be valid */
+ uint8_t timeout;
+ } imsi_cache;
+
+ /* List of all SGSNs */
+ struct llist_head sgsns;
/* Counter */
struct rate_ctr_group *ctrg;
-
- /* MCC/MNC to be patched into RA-ID on the way from BSS to SGSN? */
- struct osmo_plmn_id core_plmn;
-
- /* APN to be patched into PDP CTX ACT REQ on the way from BSS to SGSN */
- uint8_t* core_apn;
- size_t core_apn_size;
-
- /* Frequency (sec) at which timer to clean stale links is fired (0 disabled) */
- unsigned int clean_stale_timer_freq;
- /* If !0, Max age to consider a struct gbproxy_link_info as stale */
- int tlli_max_age;
- /* If !0, Max len of gbproxy_peer->list (list of struct gbproxy_link_info) */
- int tlli_max_len;
- /* If !0, Max len of gbproxy_link_info->stored_msgs (list of msgb) */
- uint32_t stored_msgs_max_len;
-
- /* Should the P-TMSI be patched on the fly (required for 2-SGSN config) */
- bool patch_ptmsi;
- /* Should the IMSI be acquired by the proxy (required for 2-SGSN config) */
- bool acquire_imsi;
- /* Should we route subscribers to two different SGSNs? */
- bool route_to_sgsn2;
- /* NSEI of the second SGSN */
- uint16_t nsip_sgsn2_nsei;
- /* should we keep a cache of per-subscriber state even after de-registration? */
- enum gbproxy_keep_mode keep_link_infos;
-
- /* IMSI checking/matching for 2-SGSN routing and patching */
- struct gbproxy_match matches[GBPROX_MATCH_LAST];
};
-struct gbproxy_patch_state {
- struct osmo_plmn_id local_plmn;
-
- /* List of TLLIs for which patching is enabled */
- struct llist_head logical_links;
- int logical_link_count;
-};
-
-/* one peer at NS level that we interact with (BSS/PCU) */
-struct gbproxy_peer {
- /* linked to gbproxy_config.bts_peers */
- struct llist_head list;
+/* One Cell within the BSS: Links BSS-side BVC to SGSN-side BVCs */
+struct gbproxy_cell {
+ /* linked to gbproxy_config.cells hashtable */
+ struct hlist_node list;
/* point back to the config */
struct gbproxy_config *cfg;
- /* NSEI of the peer entity */
- uint16_t nsei;
+ /* BVCI of PTP BVCs associated to this cell */
+ uint16_t bvci;
+
+ /* Routing Area that this BVC is part of (raw 04.08 encoding) */
+ uint8_t ra[6];
- /* BVCI used for Point-to-Point to this peer */
+ /* pointer to the BSS-side BVC */
+ struct gbproxy_bvc *bss_bvc;
+
+ /* pointers to SGSN-side BVC (one for each pool member) */
+ struct gbproxy_bvc *sgsn_bvc[GBPROXY_MAX_NR_SGSN];
+};
+
+/* One BVC inside an NSE */
+struct gbproxy_bvc {
+ /* linked to gbproxy_nse.bvcs */
+ struct hlist_node list;
+
+ /* The NSE this BVC belongs to */
+ struct gbproxy_nse *nse;
+
+ /* PTP BVCI of this BVC */
uint16_t bvci;
- bool blocked;
- /* Routeing Area that this peer is part of (raw 04.08 encoding) */
+ /* Routing Area that this BVC is part of (raw 04.08 encoding) */
uint8_t ra[6];
/* Counter */
struct rate_ctr_group *ctrg;
- /* State related to on-the-fly patching of certain messages */
- struct gbproxy_patch_state patch_state;
+ /* the cell to which this BVC belongs */
+ struct gbproxy_cell *cell;
- /* Fired periodically to clean up stale links from list */
- struct osmo_timer_list clean_stale_timer;
+ /* per-BVC FSM instance */
+ struct osmo_fsm_inst *fi;
};
-struct gbproxy_tlli_state {
- /* currently active TLLI */
- uint32_t current;
- /* newly-assigned TLLI (e.g. during P-TMSI allocation procedure) */
- uint32_t assigned;
- /* has the BSS side validated (confirmed) the new TLLI? */
- bool bss_validated;
- /* has the SGSN side validated (confirmed) the new TLLI? */
- bool net_validated;
- /* NOTE: once both are validated, we set current = assigned and assigned = 0 */
-
- /* The P-TMSI for this subscriber */
- uint32_t ptmsi;
-};
+/* one NS Entity that we interact with (BSS/PCU) */
+struct gbproxy_nse {
+ /* linked to gbproxy_config.bss_nses */
+ struct hlist_node list;
-/* One TLLI (= UE, = Subscriber) served via this proxy */
-struct gbproxy_link_info {
- /* link to gbproxy_peer.patch_state.logical_links */
- struct llist_head list;
+ /* point back to the config */
+ struct gbproxy_config *cfg;
- /* TLLI on the BSS/PCU side */
- struct gbproxy_tlli_state tlli;
- /* TLLI on the SGSN side (can be different in case of P-TMSI patching) */
- struct gbproxy_tlli_state sgsn_tlli;
- /* NSEI of the SGSN serving this link */
- uint32_t sgsn_nsei;
+ /* NSEI of the NSE */
+ uint16_t nsei;
+
+ /* Are we facing towards a SGSN (true) or BSS (false) */
+ bool sgsn_facing;
- /* timestamp when we last had any contact with this UE */
- time_t timestamp;
+ /* List of all BVCs in this NSE */
+ DECLARE_HASHTABLE(bvcs, 10);
+};
- /* IMSI of the subscriber (if/once known) */
- uint8_t *imsi;
- size_t imsi_len;
+/* SGSN configuration such as pool options (only for NSE where sgsn_facing == true) */
+struct gbproxy_sgsn {
+ /* linked to gbproxy_config.sgsns */
+ struct llist_head list;
- /* is the IMSI acquisition still pending? */
- bool imsi_acq_pending;
+ /* The NSE belonging to this SGSN */
+ struct gbproxy_nse *nse;
- /* queue of stored UL messages (until IMSI acquisition completes and we can
- * determine which of the SGSNs we should route this to */
- struct llist_head stored_msgs;
- uint32_t stored_msgs_len;
+ /* Name of the SGSN */
+ char *name;
- /* generated N(U) we use (required due to IMSI acquisition */
- unsigned vu_gen_tx_bss;
+ /* Pool configuration for the sgsn (only valid if sgsn_facing == true) */
+ struct {
+ bool allow_attach;
+ struct osmo_nri_ranges *nri_ranges;
+ } pool;
+};
- /* is this subscriber deregistered (TLLI invalidated)? */
- bool is_deregistered;
+/* TLLI cache */
+struct gbproxy_tlli_cache_entry {
+ /* linked to gbproxy_config.tlli_cache.entries */
+ struct hlist_node list;
+
+ /* TLLI of the entry */
+ uint32_t tlli;
+ /* When was this entry last seen */
+ time_t tstamp;
+ /* The Cell this TLLI was last seen */
+ struct gbproxy_nse *nse;
+};
- /* does this link match either the (2-SGSN) routing or the patching rule? */
- bool is_matching[GBPROX_MATCH_LAST];
+/* IMSI cache */
+struct gbproxy_imsi_cache_entry {
+ /* linked to gbproxy_config.imsi_cache.entries */
+ struct hlist_node list;
+
+ /* IMSI of the entry */
+ char imsi[OSMO_IMSI_BUF_SIZE];
+ /* When was this entry last seen */
+ time_t tstamp;
+ /* The SGSN where the request came from */
+ struct gbproxy_nse *nse;
};
+/* Convenience logging macros for NSE/BVC */
+#define LOGPNSE_CAT(NSE, SUBSYS, LEVEL, FMT, ARGS...) \
+ LOGP(SUBSYS, LEVEL, "NSE(%05u/%s) " FMT, (NSE)->nsei, \
+ (NSE)->sgsn_facing ? "SGSN" : "BSS", ## ARGS)
+#define LOGPNSE(NSE, LEVEL, FMT, ARGS...) \
+ LOGPNSE_CAT(NSE, DGPRS, LEVEL, FMT, ## ARGS)
+
+#define LOGPBVC_CAT(BVC, SUBSYS, LEVEL, FMT, ARGS...) \
+ LOGP(SUBSYS, LEVEL, "NSE(%05u/%s)-BVC(%05u/%s) " FMT, (BVC)->nse->nsei, \
+ (BVC)->nse->sgsn_facing ? "SGSN" : "BSS", (BVC)->bvci, \
+ osmo_fsm_inst_state_name((BVC)->fi), ## ARGS)
+#define LOGPBVC(BVC, LEVEL, FMT, ARGS...) \
+ LOGPBVC_CAT(BVC, DGPRS, LEVEL, FMT, ## ARGS)
+
+#define LOGPCELL_CAT(CELL, SUBSYS, LEVEL, FMT, ARGS...) \
+ LOGP(SUBSYS, LEVEL, "CELL(%05u) " FMT, (CELL)->bvci, ## ARGS)
+#define LOGPCELL(CELL, LEVEL, FMT, ARGS...) \
+ LOGPCELL_CAT(CELL, DGPRS, LEVEL, FMT, ## ARGS)
+
+#define LOGPSGSN_CAT(SGSN, SUBSYS, LEVEL, FMT, ARGS...) \
+ LOGP(SUBSYS, LEVEL, "NSE(%05u)-SGSN(%s) " FMT, (SGSN)->nse->nsei, (SGSN)->name, ## ARGS)
+#define LOGPSGSN(SGSN, LEVEL, FMT, ARGS...) \
+ LOGPSGSN_CAT(SGSN, DGPRS, LEVEL, FMT, ## ARGS)
/* gb_proxy_vty .c */
@@ -236,99 +243,56 @@ int gb_ctrl_cmds_install(void);
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_rcvmsg(void *ctx, struct msgb *msg);
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);
+int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
-/* 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);
+void gbprox_reset(struct gbproxy_config *cfg);
/* 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);
+#define NSE_F_SGSN 0x0001
+#define NSE_F_BSS 0x0002
+
+struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_nse *nse, uint16_t bvci);
+struct gbproxy_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci);
+void gbproxy_bvc_free(struct gbproxy_bvc *bvc);
+int gbproxy_cleanup_bvcs(struct gbproxy_nse *nse, uint16_t bvci);
+
+struct gbproxy_cell *gbproxy_cell_alloc(struct gbproxy_config *cfg, uint16_t bvci);
+struct gbproxy_cell *gbproxy_cell_by_bvci(struct gbproxy_config *cfg, uint16_t bvci);
+void gbproxy_cell_free(struct gbproxy_cell *cell);
+bool gbproxy_cell_add_sgsn_bvc(struct gbproxy_cell *cell, struct gbproxy_bvc *bvc);
+
+/* NSE handling */
+struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing);
+void gbproxy_nse_free(struct gbproxy_nse *nse);
+struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei, uint32_t flags);
+struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing);
+struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli);
+struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi);
+
+/* TLLI cache */
+void gbproxy_tlli_cache_update(struct gbproxy_nse *nse, uint32_t tlli);
+void gbproxy_tlli_cache_remove(struct gbproxy_config *cfg, uint32_t tlli);
+int gbproxy_tlli_cache_cleanup(struct gbproxy_config *cfg);
+
+/* IMSI cache */
+void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi);
+void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi);
+int gbproxy_imsi_cache_cleanup(struct gbproxy_config *cfg);
+
+/* SGSN handling */
+struct gbproxy_sgsn *gbproxy_sgsn_alloc(struct gbproxy_config *cfg, uint16_t nsei, const char *name);
+void gbproxy_sgsn_free(struct gbproxy_sgsn *sgsn);
+struct gbproxy_sgsn *gbproxy_sgsn_by_name(struct gbproxy_config *cfg, const char *name);
+struct gbproxy_sgsn *gbproxy_sgsn_by_nsei(struct gbproxy_config *cfg, uint16_t nsei);
+struct gbproxy_sgsn *gbproxy_sgsn_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei);
+struct gbproxy_sgsn *gbproxy_sgsn_by_nri(struct gbproxy_config *cfg, uint16_t nri, bool *null_nri);
+struct gbproxy_sgsn *gbproxy_sgsn_by_tlli(struct gbproxy_config *cfg, struct gbproxy_sgsn *sgsn_avoid,
+ uint32_t tlli);
#endif
diff --git a/include/osmocom/sgsn/gprs_gb.h b/include/osmocom/sgsn/gprs_gb.h
index 461eee31..c98dd344 100644
--- a/include/osmocom/sgsn/gprs_gb.h
+++ b/include/osmocom/sgsn/gprs_gb.h
@@ -12,3 +12,9 @@ void gprs_gb_recv_pdu(struct sgsn_mm_ctx *mmctx);
/* page a MS in its routing area */
int gprs_gb_page_ps_ra(struct sgsn_mm_ctx *mmctx);
+
+/* called by the bssgp layer to send NS PDUs */
+int gprs_gb_send_cb(void *ctx, struct msgb *msg);
+
+/* called by the ns layer */
+int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
diff --git a/include/osmocom/sgsn/gprs_gb_parse.h b/include/osmocom/sgsn/gprs_gb_parse.h
index 9f43faed..58de17f8 100644
--- a/include/osmocom/sgsn/gprs_gb_parse.h
+++ b/include/osmocom/sgsn/gprs_gb_parse.h
@@ -51,6 +51,8 @@ int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len,
int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len,
struct gprs_gb_parse_context *parse_ctx);
+int gprs_gb_parse_tlli(const uint8_t *bssgp, size_t bssgp_len, uint32_t *tlli);
+
const char *gprs_gb_message_name(const struct gprs_gb_parse_context *parse_ctx,
const char *default_msg_name);
diff --git a/include/osmocom/sgsn/sgsn.h b/include/osmocom/sgsn/sgsn.h
index f5ff524d..d9ef938f 100644
--- a/include/osmocom/sgsn/sgsn.h
+++ b/include/osmocom/sgsn/sgsn.h
@@ -3,8 +3,9 @@
#include <osmocom/core/msgb.h>
+#include <osmocom/core/select.h>
#include <osmocom/crypt/gprs_cipher.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/sgsn/gprs_sgsn.h>
#include <osmocom/gsm/oap_client.h>
#include <osmocom/gsupclient/gsup_client.h>
@@ -69,7 +70,7 @@ struct sgsn_config {
struct sockaddr_in gtp_listenaddr;
/* misc */
- struct gprs_ns_inst *nsi;
+ struct gprs_ns2_inst *nsi;
enum sgsn_auth_policy auth_policy;
enum gprs_ciph_algo cipher;
@@ -157,7 +158,7 @@ char *sgsn_gtp_ntoa(struct ul16_t *ul);
/* sgsn.c */
/* Main input function for Gb proxy */
-int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
+int sgsn_rcvmsg(struct msgb *msg, struct gprs_ns2_vc *nsvc, uint16_t ns_bvci);
/* sgsn_libgtp.c */
struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
diff --git a/osmoappdesc.py b/osmoappdesc.py
index e91043f9..1fccafd7 100644
--- a/osmoappdesc.py
+++ b/osmoappdesc.py
@@ -16,8 +16,7 @@
app_configs = {
- "gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg",
- "doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg"],
+ "gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg"],
"sgsn": ["doc/examples/osmo-sgsn/osmo-sgsn.cfg"],
"gtphub": ["doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg"]
}
diff --git a/src/gbproxy/Makefile.am b/src/gbproxy/Makefile.am
index 6876f68a..f8a87732 100644
--- a/src/gbproxy/Makefile.am
+++ b/src/gbproxy/Makefile.am
@@ -27,8 +27,6 @@ osmo_gbproxy_SOURCES = \
gb_proxy_main.c \
gb_proxy_vty.c \
gb_proxy_ctrl.c \
- gb_proxy_patch.c \
- gb_proxy_tlli.c \
gb_proxy_peer.c \
$(NULL)
osmo_gbproxy_LDADD = \
diff --git a/src/gbproxy/gb_proxy.c b/src/gbproxy/gb_proxy.c
index 3f471ff8..1dc3114b 100644
--- a/src/gbproxy/gb_proxy.c
+++ b/src/gbproxy/gb_proxy.c
@@ -1,6 +1,6 @@
/* NS-over-IP proxy */
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
+/* (C) 2010-2020 by Harald Welte <laforge@gnumonks.org>
* (C) 2010-2013 by On-Waves
* (C) 2013 by Holger Hans Peter Freyther
* All Rights Reserved
@@ -31,14 +31,22 @@
#include <arpa/inet.h>
#include <time.h>
+#include <osmocom/core/hashtable.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/linuxlist.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
+#include <osmocom/core/utils.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
+#include <osmocom/gprs/gprs_bssgp2.h>
+#include <osmocom/gprs/gprs_bssgp_bss.h>
+#include <osmocom/gprs/bssgp_bvc_fsm.h>
+#include <osmocom/gsm/gsm23236.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/sgsn/signal.h>
@@ -75,23 +83,22 @@ static const struct rate_ctr_group_desc global_ctrg_desc = {
.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 gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_bvc *bvc,
+ uint16_t ns_bvci);
+
-static int check_peer_nsei(struct gbproxy_peer *peer, uint16_t nsei)
+/* generate BVC-STATUS message with cause value derived from TLV-parser error */
+static int tx_status_from_tlvp(enum osmo_tlv_parser_error tlv_p_err, struct msgb *orig_msg)
{
- 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;
+ uint8_t bssgp_cause;
+ switch (tlv_p_err) {
+ case OSMO_TLVP_ERR_MAND_IE_MISSING:
+ bssgp_cause = BSSGP_CAUSE_MISSING_MAND_IE;
+ break;
+ default:
+ bssgp_cause = BSSGP_CAUSE_PROTO_ERR_UNSPEC;
}
-
- return 1;
+ return bssgp_tx_status(bssgp_cause, NULL, orig_msg);
}
/* strip off the NS header */
@@ -101,1145 +108,1107 @@ static void strip_ns_hdr(struct msgb *msg)
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)
+#if 0
+/* feed a message down the NS-VC associated with the specified bvc */
+static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,
+ uint16_t ns_bvci, uint16_t sgsn_nsei)
{
- 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;
-}
+ /* create a copy of the message so the old one can
+ * be free()d safely when we return from gbprox_rcvmsg() */
+ struct gprs_ns2_inst *nsi = cfg->nsi;
+ struct osmo_gprs_ns2_prim nsp = {};
+ struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2sgsn");
+ int rc;
-/* 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;
+ DEBUGP(DGPRS, "NSE(%05u/BSS)-BVC(%05u) proxying BTS->SGSN NSE(%05u/SGSN)\n",
+ msgb_nsei(msg), ns_bvci, sgsn_nsei);
- 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 */
-}
+ nsp.bvci = ns_bvci;
+ nsp.nsei = sgsn_nsei;
-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);
+ strip_ns_hdr(msg);
+ osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA,
+ PRIM_OP_REQUEST, msg);
+ rc = gprs_ns2_recv_prim(nsi, &nsp.oph);
+ if (rc < 0)
+ rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_TX_ERR_SGSN]);
+ return rc;
}
+#endif
-static void gprs_push_bssgp_dl_unitdata(struct msgb *msg,
- uint32_t tlli)
+/* feed a message down the NSE */
+static int gbprox_relay2nse(struct msgb *old_msg, struct gbproxy_nse *nse,
+ uint16_t ns_bvci)
{
- 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);
+ OSMO_ASSERT(nse);
+ OSMO_ASSERT(nse->cfg);
- 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));
+ /* create a copy of the message so the old one can
+ * be free()d safely when we return from gbprox_rcvmsg() */
+ struct gprs_ns2_inst *nsi = nse->cfg->nsi;
+ struct osmo_gprs_ns2_prim nsp = {};
+ struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2nse");
+ uint32_t tlli;
+ int rc;
- ie = budh->data;
- tvlv_put(ie, BSSGP_IE_PDU_LIFETIME, sizeof(lifetime), lifetime);
- ie += TVLV_GROSS_LEN(sizeof(lifetime));
+ DEBUGP(DGPRS, "NSE(%05u/%s)-BVC(%05u/??) proxying to NSE(%05u/%s)\n", msgb_nsei(msg),
+ !nse->sgsn_facing ? "SGSN" : "BSS", ns_bvci, nse->nsei, nse->sgsn_facing ? "SGSN" : "BSS");
- /* Note: Add alignment before the LLC IE if inserting other IE */
+ nsp.bvci = ns_bvci;
+ nsp.nsei = nse->nsei;
- *(ie++) = BSSGP_IE_LLC_PDU;
- *(ie++) = llc_size / 256;
- *(ie++) = llc_size % 256;
+ /* Strip the old NS header, it will be replaced with a new one */
+ strip_ns_hdr(msg);
- OSMO_ASSERT(ie == llc);
+ /* TS 48.018 Section 5.4.2: The link selector parameter is
+ * defined in 3GPP TS 48.016. At one side of the Gb interface,
+ * all BSSGP UNITDATA PDUs related to an MS shall be passed with
+ * the same LSP, e.g. the LSP contains the MS's TLLI, to the
+ * underlying network service. */
+ if (gprs_gb_parse_tlli(msgb_data(msg), msgb_length(msg), &tlli) == 1)
+ nsp.u.unitdata.link_selector = tlli;
+
+ osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA,
+ PRIM_OP_REQUEST, msg);
+ rc = gprs_ns2_recv_prim(nsi, &nsp.oph);
+ /* FIXME: We need a counter group for gbproxy_nse */
+ //if (rc < 0)
+ // rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_TX_ERR]);
- msgb_bssgph(msg) = (uint8_t *)budh;
- msgb_tlli(msg) = tlli;
+ return rc;
}
-/* 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)
+/* feed a message down the NS-VC associated with the specified bvc */
+static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_bvc *bvc,
+ uint16_t ns_bvci)
{
- struct gbproxy_patch_state *state = &peer->patch_state;
- const struct osmo_plmn_id old_plmn = state->local_plmn;
- struct gprs_ra_id raid;
+ int rc;
+ struct gbproxy_nse *nse = bvc->nse;
+ OSMO_ASSERT(nse);
- if (!raid_enc)
- return;
+ rc = gbprox_relay2nse(old_msg, nse, ns_bvci);
+ if (rc < 0)
+ rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_TX_ERR]);
- gsm48_parse_ra(&raid, raid_enc);
+ return rc;
+}
- /* save source side MCC/MNC */
- if (!peer->cfg->core_plmn.mcc || raid.mcc == peer->cfg->core_plmn.mcc) {
- state->local_plmn.mcc = 0;
- } else {
- state->local_plmn.mcc = raid.mcc;
- }
+int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ return 0;
+}
- if (!peer->cfg->core_plmn.mnc
- || !osmo_mnc_cmp(raid.mnc, raid.mnc_3_digits,
- peer->cfg->core_plmn.mnc, peer->cfg->core_plmn.mnc_3_digits)) {
- state->local_plmn.mnc = 0;
- state->local_plmn.mnc_3_digits = false;
- } else {
- state->local_plmn.mnc = raid.mnc;
- state->local_plmn.mnc_3_digits = raid.mnc_3_digits;
- }
- if (osmo_plmn_cmp(&old_plmn, &state->local_plmn))
- LOGP(DGPRS, LOGL_NOTICE,
- "Patching RAID %sactivated, msg: %s, "
- "local: %s, core: %s\n",
- state->local_plmn.mcc || state->local_plmn.mnc ?
- "" : "de",
- log_text,
- osmo_plmn_name(&state->local_plmn),
- osmo_plmn_name2(&peer->cfg->core_plmn));
-}
+/***********************************************************************
+ * PTP BVC handling
+ ***********************************************************************/
-uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer,
- uint32_t sgsn_ptmsi)
+/* FIXME: Handle the tlli NULL case correctly,
+ * This function should take a generic selector
+ * and choose an sgsn based on that
+ */
+static struct gbproxy_sgsn *gbproxy_select_sgsn(struct gbproxy_config *cfg, const uint32_t *tlli)
{
- uint32_t bss_ptmsi;
- int max_retries = 23, rc = 0;
- if (!peer->cfg->patch_ptmsi) {
- bss_ptmsi = sgsn_ptmsi;
- } else {
- do {
- rc = osmo_get_rand_id((uint8_t *) &bss_ptmsi, sizeof(bss_ptmsi));
- if (rc < 0) {
- bss_ptmsi = GSM_RESERVED_TMSI;
- break;
- }
+ struct gbproxy_sgsn *sgsn = NULL;
+ struct gbproxy_sgsn *sgsn_avoid = NULL;
- bss_ptmsi = bss_ptmsi | GSM23003_TMSI_SGSN_MASK;
+ int tlli_type;
+ int16_t nri;
+ bool null_nri = false;
- if (gbproxy_link_info_by_ptmsi(peer, bss_ptmsi))
- bss_ptmsi = GSM_RESERVED_TMSI;
- } while (bss_ptmsi == GSM_RESERVED_TMSI && max_retries--);
+ if (!tlli) {
+ sgsn = llist_first_entry(&cfg->sgsns, struct gbproxy_sgsn, list);
+ if (!sgsn) {
+ return NULL;
+ }
+ LOGPSGSN(sgsn, LOGL_INFO, "Could not get TLLI, using first SGSN\n");
+ return sgsn;
}
- if (bss_ptmsi == GSM_RESERVED_TMSI)
- LOGP(DGPRS, LOGL_ERROR, "Failed to allocate a BSS P-TMSI: %d (%s)\n", rc, strerror(-rc));
-
- return bss_ptmsi;
-}
+ if (cfg->pool.nri_bitlen == 0) {
+ /* Pooling is disabled */
+ sgsn = llist_first_entry(&cfg->sgsns, struct gbproxy_sgsn, list);
+ if (!sgsn) {
+ return NULL;
+ }
-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, rc = 0;
- 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);
+ LOGPSGSN(sgsn, LOGL_INFO, "Pooling disabled, using first configured SGSN\n");
} else {
- do {
- /* create random TLLI, 0b01111xxx... */
- rc = osmo_get_rand_id((uint8_t *) &sgsn_tlli, sizeof(sgsn_tlli));
- if (rc < 0) {
- sgsn_tlli = 0;
- break;
+ /* Pooling is enabled, try to use the NRI for routing to an SGSN
+ * See 3GPP TS 23.236 Ch. 5.3.2 */
+ tlli_type = gprs_tlli_type(*tlli);
+ if (tlli_type == TLLI_LOCAL || tlli_type == TLLI_FOREIGN) {
+ /* Only get/use the NRI if tlli type is local */
+ osmo_tmsi_nri_v_get(&nri, *tlli, cfg->pool.nri_bitlen);
+ if (nri >= 0) {
+ /* Get the SGSN for the NRI */
+ sgsn = gbproxy_sgsn_by_nri(cfg, nri, &null_nri);
+ if (sgsn && !null_nri)
+ return sgsn;
+ /* If the NRI is the null NRI, we need to avoid the chosen SGSN */
+ if (null_nri && sgsn) {
+ sgsn_avoid = sgsn;
+ }
+ } else {
+ /* We couldn't get the NRI from the TLLI */
+ LOGP(DGPRS, LOGL_ERROR, "Could not extract NRI from local TLLI %08x\n", *tlli);
}
-
- 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--);
+ } else {
+ LOGP(DGPRS, LOGL_INFO, "TLLI %08x is neither local nor foreign, not routing by NRI\n", *tlli);
+ }
}
- if (!sgsn_tlli)
- LOGP(DGPRS, LOGL_ERROR, "Failed to allocate an SGSN TLLI: %d (%s)\n", rc, strerror(-rc));
-
- return sgsn_tlli;
-}
+ /* If we haven't found an SGSN yet we need to choose one, but avoid the one in sgsn_avoid
+ * NOTE: This function is not stable if the number of SGSNs or allow_attach changes
+ * We could implement TLLI tracking here, but 3GPP TS 23.236 Ch. 5.3.2 (see NOTE) argues that
+ * we can just wait for the MS to reattempt the procedure.
+ */
+ if (!sgsn)
+ sgsn = gbproxy_sgsn_by_tlli(cfg, sgsn_avoid, *tlli);
+
+ if (!sgsn) {
+ LOGP(DGPRS, LOGL_ERROR, "No suitable SGSN found for TLLI %u\n", *tlli);
+ return NULL;
+ }
-void gbproxy_reset_link(struct gbproxy_link_info *link_info)
-{
- gbproxy_reset_imsi_acquisition(link_info);
+ return sgsn;
}
-/* Returns != 0 iff IMSI acquisition was in progress */
-static int gbproxy_restart_imsi_acquisition(struct gbproxy_link_info* link_info)
+/*! Find the correct gbproxy_bvc given a cell and an SGSN
+ * \param[in] cfg The gbproxy configuration
+ * \param[in] cell The cell the message belongs to
+ * \param[in] tlli An optional TLLI used for tracking
+ * \return Returns 0 on success, otherwise a negative value
+ */
+static struct gbproxy_bvc *gbproxy_select_sgsn_bvc(struct gbproxy_config *cfg, struct gbproxy_cell *cell, const uint32_t *tlli)
{
- int in_progress = 0;
- if (!link_info)
- return 0;
-
- if (link_info->imsi_acq_pending)
- in_progress = 1;
+ struct gbproxy_sgsn *sgsn;
+ struct gbproxy_bvc *sgsn_bvc = NULL;
+ int i;
+
+ sgsn = gbproxy_select_sgsn(cfg, tlli);
+ if (!sgsn) {
+ LOGPCELL(cell, LOGL_ERROR, "Could not find any SGSN, dropping message!\n");
+ return NULL;
+ }
- gbproxy_link_info_discard_messages(link_info);
- link_info->imsi_acq_pending = false;
+ /* Get the BVC for this SGSN/NSE */
+ for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
+ sgsn_bvc = cell->sgsn_bvc[i];
+ if (!sgsn_bvc)
+ continue;
+ if (sgsn->nse != sgsn_bvc->nse)
+ continue;
- return in_progress;
-}
+ return sgsn_bvc;
+ }
-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;
+ /* This shouldn't happen */
+ LOGPCELL(cell, LOGL_ERROR, "Could not find matching BVC for SGSN %s, dropping message!\n", sgsn->name);
+ return NULL;
}
-/* Got identity response with IMSI, assuming the request had
- * been generated by the gbproxy */
-static int gbproxy_flush_stored_messages(struct gbproxy_peer *peer,
- time_t now,
- struct gbproxy_link_info* link_info)
+/*! Send a message to the next SGSN, possibly ignoring the null SGSN
+ * route an uplink message on a PTP-BVC to a SGSN using the TLLI
+ * \param[in] cell The cell the message belongs to
+ * \param[in] msg The BSSGP message
+ * \param[in] null_sgsn If not NULL then avoid this SGSN (because this message contains its null NRI)
+ * \param[in] tlli An optional TLLI used for tracking
+ * \return Returns 0 on success, otherwise a negative value
+ */
+static int gbprox_bss2sgsn_tlli(struct gbproxy_cell *cell, struct msgb *msg, const uint32_t *tlli,
+ bool sig_bvci)
{
- int rc;
- struct msgb *stored_msg;
-
- /* Patch and flush stored messages towards the SGSN */
- while ((stored_msg = msgb_dequeue_count(&link_info->stored_msgs,
- &link_info->stored_msgs_len))) {
- 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(stored_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;
- }
+ struct gbproxy_config *cfg = cell->cfg;
+ struct gbproxy_bvc *sgsn_bvc;
- rc = gbprox_relay2sgsn(peer->cfg, stored_msg,
- msgb_bvci(stored_msg), link_info->sgsn_nsei);
-
- if (rc < 0)
- LOGP(DLLC, LOGL_ERROR,
- "NSEI=%d(BSS) failed to send stored message "
- "(%s)\n",
- tmp_parse_ctx.peer_nsei,
- tmp_parse_ctx.llc_msg_name ?
- tmp_parse_ctx.llc_msg_name : "BSSGP");
- msgb_free(stored_msg);
+ sgsn_bvc = gbproxy_select_sgsn_bvc(cfg, cell, tlli);
+ if (!sgsn_bvc) {
+ LOGPCELL(cell, LOGL_NOTICE, "Could not find any SGSN for TLLI %u, dropping message!\n", *tlli);
+ return -EINVAL;
}
- return 0;
+ return gbprox_relay2peer(msg, sgsn_bvc, sig_bvci ? 0 : sgsn_bvc->bvci);
}
-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 */)
+/* Receive an incoming PTP message from a BSS-side NS-VC */
+static int gbprox_rx_ptp_from_bss(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci)
{
+ struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
+ const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type);
+ struct gbproxy_bvc *bss_bvc;
+ struct tlv_parsed tp;
+ char log_pfx[32];
+ uint32_t tlli;
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;
+ snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/BSS)-BVC(%05u/??)", nse->nsei, ns_bvci);
- /* 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;
- }
+ LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name);
- 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;
-
- LOGP(DLLC, LOGL_DEBUG,
- "NSEI=%d(BSS) IMSI acquisition succeeded, "
- "flushing stored messages\n",
- msgb_nsei(msg));
- /* 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, now, link_info) < 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;
+ if (ns_bvci == 0 || ns_bvci == 1) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s BVCI=%05u is not PTP\n", log_pfx, ns_bvci);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
}
- /* The message cannot be processed since the IMSI is still missing */
+ if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_PTP)) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in PTP BVC\n", log_pfx, pdut_name);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
+ }
- /* If queue is getting too large, drop oldest msgb before adding new one */
- if (peer->cfg->stored_msgs_max_len > 0) {
- int exceeded_max_len = link_info->stored_msgs_len
- + 1 - peer->cfg->stored_msgs_max_len;
+ if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_UL)) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in uplink direction\n", log_pfx, pdut_name);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
+ }
- for (; exceeded_max_len > 0; exceeded_max_len--) {
- struct msgb *msgb_drop;
- msgb_drop = msgb_dequeue_count(&link_info->stored_msgs,
- &link_info->stored_msgs_len);
- LOGP(DLLC, LOGL_INFO,
- "NSEI=%d(BSS) Dropping stored msgb from list "
- "(!acq imsi, length %d, max_len exceeded)\n",
- msgb_nsei(msgb_drop), link_info->stored_msgs_len);
+ bss_bvc = gbproxy_bvc_by_bvci(nse, ns_bvci);
+ if (!bss_bvc) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s - Didn't find BVC for PTP message, discarding\n",
+ log_pfx, pdut_name);
+ return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &ns_bvci, msg);
+ }
- msgb_free(msgb_drop);
+ /* UL_UNITDATA has a different header than all other uplink PDUs */
+ if (bgph->pdu_type == BSSGP_PDUT_UL_UNITDATA) {
+ const struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg);
+ if (msgb_bssgp_len(msg) < sizeof(*budh))
+ return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
+ rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, budh->data,
+ msgb_bssgp_len(msg) - sizeof(*budh), 0, 0, DGPRS, log_pfx);
+ /* populate TLLI from the fixed headser into the TLV-parsed array so later code
+ * doesn't have to worry where the TLLI came from */
+ tp.lv[BSSGP_IE_TLLI].len = 4;
+ tp.lv[BSSGP_IE_TLLI].val = (const uint8_t *) &budh->tlli;
+ } else {
+ rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, bgph->data,
+ msgb_bssgp_len(msg) - sizeof(*bgph), 0, 0, DGPRS, log_pfx);
+ }
+ if (rc < 0) {
+ rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]);
+ return tx_status_from_tlvp(rc, msg);
+ }
+ /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */
+ msgb_bcid(msg) = (void *)&tp;
+
+ switch (bgph->pdu_type) {
+ case BSSGP_PDUT_UL_UNITDATA:
+ case BSSGP_PDUT_RA_CAPA_UPDATE:
+ case BSSGP_PDUT_FLOW_CONTROL_MS:
+ case BSSGP_PDUT_DOWNLOAD_BSS_PFC:
+ case BSSGP_PDUT_CREATE_BSS_PFC_ACK:
+ case BSSGP_PDUT_CREATE_BSS_PFC_NACK:
+ case BSSGP_PDUT_MODIFY_BSS_PFC_ACK:
+ case BSSGP_PDUT_DELETE_BSS_PFC_ACK:
+ case BSSGP_PDUT_FLOW_CONTROL_PFC:
+ case BSSGP_PDUT_DELETE_BSS_PFC_REQ:
+ case BSSGP_PDUT_PS_HO_REQUIRED:
+ case BSSGP_PDUT_PS_HO_REQUEST_ACK:
+ case BSSGP_PDUT_PS_HO_REQUEST_NACK:
+ case BSSGP_PDUT_PS_HO_COMPLETE:
+ case BSSGP_PDUT_PS_HO_CANCEL:
+ /* We can route based on TLLI-NRI */
+ tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
+ rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, &tlli, false);
+ break;
+ case BSSGP_PDUT_RADIO_STATUS:
+ if (TLVP_PRESENT(&tp, BSSGP_IE_TLLI)) {
+ tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
+ rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, &tlli, false);
+ } else if (TLVP_PRESENT(&tp, BSSGP_IE_TMSI)) {
+ /* we treat the TMSI like a TLLI and extract the NRI from it */
+ tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TMSI));
+ /* Convert the TMSI into a FOREIGN TLLI so it is routed appropriately */
+ tlli = gprs_tmsi2tlli(tlli, TLLI_FOREIGN);
+ rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, &tlli, false);
+ } else if (TLVP_PRESENT(&tp, BSSGP_IE_IMSI)) {
+ /* FIXME: Use the IMSI as selector? */
+ rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, NULL, false);
+ /* rc = gbprox_bss2sgsn_hashed(bss_bvc->cell, msg, NULL); */
+ } else
+ LOGPBVC(bss_bvc, LOGL_ERROR, "Rx RADIO-STATUS without any of the conditional IEs\n");
+ break;
+ case BSSGP_PDUT_DUMMY_PAGING_PS_RESP:
+ case BSSGP_PDUT_PAGING_PS_REJECT:
+ {
+ /* Route according to IMSI<->NSE cache entry */
+ struct osmo_mobile_identity mi;
+ const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
+ uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
+ osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
+ nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi);
+ if (nse) {
+ OSMO_ASSERT(nse->sgsn_facing);
+ rc = gbprox_relay2nse(msg, nse, ns_bvci);
+ } else {
+ LOGPBVC(bss_bvc, LOGL_ERROR, "Rx unmatched %s with IMSI %s\n", pdut_name, mi.imsi);
}
+ break;
}
-
- /* 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 = bssgp_msgb_copy(msg, "process_bssgp_ul");
- msgb_enqueue_count(&link_info->stored_msgs, stored_msg,
- &link_info->stored_msgs_len);
-
- 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 = true;
+ case BSSGP_PDUT_FLOW_CONTROL_BVC:
+ osmo_fsm_inst_dispatch(bss_bvc->fi, BSSGP_BVCFSM_E_RX_FC_BVC, msg);
+ break;
+ case BSSGP_PDUT_STATUS:
+ /* TODO: Implement by inspecting the contained PDU */
+ if (!TLVP_PRESENT(&tp, BSSGP_IE_PDU_IN_ERROR))
+ break;
+ LOGPBVC(bss_bvc, LOGL_ERROR, "Rx %s: Implementation missing\n", pdut_name);
+ break;
}
return 0;
}
-struct gbproxy_peer *gbproxy_find_peer(struct gbproxy_config *cfg,
- struct msgb *msg,
- struct gprs_gb_parse_context *parse_ctx)
+/* Receive an incoming PTP message from a SGSN-side NS-VC */
+static int gbprox_rx_ptp_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci)
{
- struct gbproxy_peer *peer = NULL;
-
- if (msgb_bvci(msg) >= 2)
- peer = gbproxy_peer_by_bvci(cfg, msgb_bvci(msg));
+ struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
+ const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type);
+ struct gbproxy_bvc *sgsn_bvc, *bss_bvc;
+ struct tlv_parsed tp;
+ char log_pfx[32];
+ int rc;
- if (!peer && !parse_ctx->to_bss)
- peer = gbproxy_peer_by_nsei(cfg, msgb_nsei(msg));
+ snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/SGSN)-BVC(%05u/??)", nse->nsei, ns_bvci);
- if (!peer)
- peer = gbproxy_peer_by_bssgp_tlv(cfg, &parse_ctx->bssgp_tp);
+ LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name);
- 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]);
+ if (ns_bvci == 0 || ns_bvci == 1) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s BVCI is not PTP\n", log_pfx);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
}
- 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_plmn.mcc && !cfg->core_plmn.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;
+ if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_PTP)) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in PTP BVC\n", log_pfx, pdut_name);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
}
- /* Get peer */
- if (!peer)
- peer = gbproxy_find_peer(cfg, msg, &parse_ctx);
-
- if (!peer)
- return 0;
-
-
- osmo_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 (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_DL)) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in downlink direction\n", log_pfx, pdut_name);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
}
- 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;
+ sgsn_bvc = gbproxy_bvc_by_bvci(nse, ns_bvci);
+ if (!sgsn_bvc) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s - Didn't find BVC for for PTP message, discarding\n",
+ log_pfx, pdut_name);
+ rate_ctr_inc(&nse->cfg->ctrg-> ctr[GBPROX_GLOB_CTR_INV_BVCI]);
+ return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &ns_bvci, msg);
}
- 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;
+ if (!bssgp_bvc_fsm_is_unblocked(sgsn_bvc->fi)) {
+ LOGPBVC(sgsn_bvc, LOGL_NOTICE, "Rx %s: Dropping on blocked BVC\n", pdut_name);
+ rate_ctr_inc(&sgsn_bvc->ctrg->ctr[GBPROX_PEER_CTR_DROPPED]);
+ return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, &ns_bvci, msg);
}
- gbproxy_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg),
- peer, link_info, &len_change, &parse_ctx);
+ /* DL_UNITDATA has a different header than all other uplink PDUs */
+ if (bgph->pdu_type == BSSGP_PDUT_DL_UNITDATA) {
+ const struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg);
+ if (msgb_bssgp_len(msg) < sizeof(*budh))
+ return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
+ rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, budh->data,
+ msgb_bssgp_len(msg) - sizeof(*budh), 0, 0, DGPRS, log_pfx);
+ /* populate TLLI from the fixed headser into the TLV-parsed array so later code
+ * doesn't have to worry where the TLLI came from */
+ tp.lv[BSSGP_IE_TLLI].len = 4;
+ tp.lv[BSSGP_IE_TLLI].val = (const uint8_t *) &budh->tlli;
+ } else {
+ rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, bgph->data,
+ msgb_bssgp_len(msg) - sizeof(*bgph), 0, 0, DGPRS, log_pfx);
+ }
+ if (rc < 0) {
+ rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]);
+ return tx_status_from_tlvp(rc, msg);
+ }
+ /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */
+ msgb_bcid(msg) = (void *)&tp;
- gbproxy_update_link_state_after(peer, link_info, now, &parse_ctx);
+ OSMO_ASSERT(sgsn_bvc->cell);
+ bss_bvc = sgsn_bvc->cell->bss_bvc;
- 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;
+ switch (bgph->pdu_type) {
+ case BSSGP_PDUT_FLOW_CONTROL_BVC_ACK:
+ return osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_FC_BVC_ACK, msg);
+ case BSSGP_PDUT_DUMMY_PAGING_PS:
+ case BSSGP_PDUT_PAGING_PS:
+ {
+ /* Cache the IMSI<->NSE to route PAGING REJECT */
+ struct osmo_mobile_identity mi;
+ const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
+ uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
+ osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
+ gbproxy_imsi_cache_update(nse, mi.imsi);
+ break;
}
+ default:
+ break;
+ }
+ return gbprox_relay2peer(msg, bss_bvc, bss_bvc->bvci);
- return 1;
}
-/* patch BSSGP message to use core_plmn.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;
+/***********************************************************************
+ * BVC FSM call-backs
+ ***********************************************************************/
- if (!cfg->core_plmn.mcc && !cfg->core_plmn.mnc && !cfg->core_apn &&
- !cfg->acquire_imsi && !cfg->patch_ptmsi && !cfg->route_to_sgsn2)
- return;
+/* helper function to dispatch a FSM event to all SGSN-side BVC FSMs of a cell */
+static void dispatch_to_all_sgsn_bvc(struct gbproxy_cell *cell, uint32_t event, void *priv)
+{
+ unsigned int i;
- parse_ctx.to_bss = 1;
- parse_ctx.peer_nsei = msgb_nsei(msg);
+ for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
+ struct gbproxy_bvc *sgsn_bvc = cell->sgsn_bvc[i];
+ if (!sgsn_bvc)
+ continue;
+ osmo_fsm_inst_dispatch(sgsn_bvc->fi, event, priv);
+ }
+}
- rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),
- &parse_ctx);
+/* BVC FSM informs us about a BSS-side reset of the signaling BVC */
+static void bss_sig_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
+ uint16_t cell_id, uint8_t cause, void *priv)
+{
+ struct gbproxy_bvc *sig_bvc = priv;
+ struct gbproxy_nse *nse = sig_bvc->nse;
+ struct gbproxy_bvc *ptp_bvc;
+ unsigned int i;
+
+ /* BLOCK all SGSN-side PTP BVC within this NSE */
+ hash_for_each(nse->bvcs, i, ptp_bvc, list) {
+ if (ptp_bvc == sig_bvc)
+ continue;
+ OSMO_ASSERT(ptp_bvc->cell);
- 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;
+ dispatch_to_all_sgsn_bvc(ptp_bvc->cell, BSSGP_BVCFSM_E_REQ_BLOCK, &cause);
}
- /* Get peer */
- if (!peer)
- peer = gbproxy_find_peer(cfg, msg, &parse_ctx);
+ /* Delete all BSS-side PTP BVC within this NSE */
+ gbproxy_cleanup_bvcs(nse, 0);
- if (!peer)
- return;
+ /* TODO: we keep the "CELL" around for now, re-connecting it to
+ * any (later) new PTP-BVC for that BVCI. Not sure if that's the
+ * best idea ? */
+}
- osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
- now = ts.tv_sec;
+/* forward declaration */
+static const struct bssgp_bvc_fsm_ops sgsn_ptp_bvc_fsm_ops;
- 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;
+static const struct bssgp_bvc_fsm_ops bss_sig_bvc_fsm_ops = {
+ .reset_notification = bss_sig_bvc_reset_notif,
+};
- default:
- break;
+/* BVC FSM informs us about a BSS-side reset of a PTP BVC */
+static void bss_ptp_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
+ uint16_t cell_id, uint8_t cause, void *priv)
+{
+ struct gbproxy_bvc *bvc = priv;
+ struct gbproxy_config *cfg = bvc->nse->cfg;
+ struct gbproxy_nse *sgsn_nse;
+ unsigned int i;
+
+ OSMO_ASSERT(bvci != 0);
+
+ if (!bvc->cell) {
+ /* see if we have a CELL dangling around */
+ bvc->cell = gbproxy_cell_by_bvci(cfg, bvci);
+ if (bvc->cell) {
+ /* the CELL already exists. This means either it * was created before at an
+ * earlier PTP BVC-RESET, or that there are non-unique BVCIs and hence a
+ * malconfiguration */
+ if (bvc->cell->bss_bvc) {
+ LOGPBVC(bvc, LOGL_NOTICE, "Rx BVC-RESET via this NSE, but CELL already "
+ "has BVC on NSEI=%05u\n", bvc->cell->bss_bvc->nse->nsei);
+ LOGPBVC(bvc->cell->bss_bvc, LOGL_NOTICE, "Destroying due to conflicting "
+ "BVCI configuration (new NSEI=%05u)!\n", bvc->nse->nsei);
+ gbproxy_bvc_free(bvc->cell->bss_bvc);
+ }
+ bvc->cell->bss_bvc = bvc;
}
}
- 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);
+ if (!bvc->cell) {
+ /* if we end up here, it means this is the first time we received a BVC-RESET
+ * for this BVC. We need to create the 'cell' data structure and the SGSN-side
+ * BVC counterparts */
- gbproxy_update_link_state_after(peer, link_info, now, &parse_ctx);
+ bvc->cell = gbproxy_cell_alloc(cfg, bvci);
+ OSMO_ASSERT(bvc->cell);
+ memcpy(bvc->cell->ra, bvc->ra, sizeof(bvc->cell->ra));
- 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 = bssgp_msgb_copy(old_msg, "msgb_relay2sgsn");
- int rc;
+ /* link us to the cell and vice-versa */
+ bvc->cell->bss_bvc = bvc;
+ }
- DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n",
- msgb_nsei(msg), ns_bvci, sgsn_nsei);
+ /* allocate (any missing) SGSN-side BVCs within the cell, and reset them */
+ hash_for_each(cfg->sgsn_nses, i, sgsn_nse, list) {
+ struct gbproxy_bvc *sgsn_bvc = gbproxy_bvc_by_bvci(sgsn_nse, bvci);
+ if (sgsn_bvc)
+ OSMO_ASSERT(sgsn_bvc->cell == bvc->cell || !sgsn_bvc->cell);
- msgb_bvci(msg) = ns_bvci;
- msgb_nsei(msg) = sgsn_nsei;
+ if (!sgsn_bvc) {
+ sgsn_bvc = gbproxy_bvc_alloc(sgsn_nse, bvci);
+ OSMO_ASSERT(sgsn_bvc);
- strip_ns_hdr(msg);
+ sgsn_bvc->cell = bvc->cell;
+ memcpy(sgsn_bvc->ra, bvc->cell->ra, sizeof(sgsn_bvc->ra));
+ sgsn_bvc->fi = bssgp_bvc_fsm_alloc_ptp_bss(sgsn_bvc, cfg->nsi, sgsn_nse->nsei,
+ bvci, ra_id, cell_id);
+ OSMO_ASSERT(sgsn_bvc->fi);
+ bssgp_bvc_fsm_set_ops(sgsn_bvc->fi, &sgsn_ptp_bvc_fsm_ops, sgsn_bvc);
- rc = gprs_ns_sendmsg(bssgp_nsi, msg);
- if (rc < 0)
- rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_TX_ERR_SGSN]);
+ gbproxy_cell_add_sgsn_bvc(bvc->cell, sgsn_bvc);
+ }
+ }
- return rc;
+ /* Trigger outbound BVC-RESET procedure toward each SGSN */
+ dispatch_to_all_sgsn_bvc(bvc->cell, BSSGP_BVCFSM_E_REQ_RESET, &cause);
}
-/* 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)
+/* BVC FSM informs us about a BSS-side FSM state change */
+static void bss_ptp_bvc_state_chg_notif(uint16_t nsei, uint16_t bvci, int old_state, int state, void *priv)
{
- /* create a copy of the message so the old one can
- * be free()d safely when we return from gbprox_rcvmsg() */
- struct msgb *msg = bssgp_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]);
+ struct gbproxy_bvc *bvc = priv;
+ struct gbproxy_cell *cell = bvc->cell;
+ uint8_t cause = bssgp_bvc_fsm_get_block_cause(bvc->fi);
- 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;
- }
+ /* we have just been created but due to callback ordering the cell is not associated */
+ if (!cell)
+ return;
- switch (pdu_type) {
- case BSSGP_PDUT_BVC_BLOCK_ACK:
- peer->blocked = true;
- rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_BLOCKED]);
+ switch (state) {
+ case BSSGP_BVCFSM_S_BLOCKED:
+ /* block the corresponding SGSN-side PTP BVCs */
+ dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_BLOCK, &cause);
break;
- case BSSGP_PDUT_BVC_UNBLOCK_ACK:
- peer->blocked = false;
- rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_UNBLOCKED]);
- break;
- default:
+ case BSSGP_BVCFSM_S_UNBLOCKED:
+ /* unblock the corresponding SGSN-side PTP BVCs */
+ dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_UNBLOCK, NULL);
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)
+/* BVC FSM informs us about BVC-FC PDU receive */
+static void bss_ptp_bvc_fc_bvc(uint16_t nsei, uint16_t bvci, const struct bssgp2_flow_ctrl *fc, void *priv)
{
- 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;
- }
+ struct bssgp2_flow_ctrl fc_reduced;
+ struct gbproxy_bvc *bss_bvc = priv;
+ struct gbproxy_cell *cell;
+ struct gbproxy_config *cfg;
- return gbprox_relay2peer(msg, peer, ns_bvci);
-}
+ OSMO_ASSERT(bss_bvc);
+ OSMO_ASSERT(fc);
-int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
-{
- return 0;
-}
+ cell = bss_bvc->cell;
+ if (!cell)
+ return;
-/* 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;
+ cfg = cell->cfg;
- 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);
- }
+ /* reduce / scale according to configuration to make sure we only advertise a fraction
+ * of the capacity to each of the SGSNs in the pool */
+ fc_reduced = *fc;
+ fc_reduced.bucket_size_max = (fc->bucket_size_max * cfg->pool.bvc_fc_ratio) / 100;
+ fc_reduced.bucket_leak_rate = (fc->bucket_leak_rate * cfg->pool.bvc_fc_ratio) / 100;
+ /* we don't modify the per-MS related values as any single MS is only served by one SGSN */
- check_peer_nsei(peer, nsei);
+ dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_FC_BVC, (void *) &fc_reduced);
+}
- rc = gbprox_process_bssgp_ul(cfg, msg, peer);
- if (!rc)
- return 0;
+static const struct bssgp_bvc_fsm_ops bss_ptp_bvc_fsm_ops = {
+ .reset_notification = bss_ptp_bvc_reset_notif,
+ .state_chg_notification = bss_ptp_bvc_state_chg_notif,
+ .rx_fc_bvc = bss_ptp_bvc_fc_bvc,
+};
- switch (pdu_type) {
- case BSSGP_PDUT_FLOW_CONTROL_BVC:
- if (!cfg->route_to_sgsn2)
- break;
+/* BVC FSM informs us about a SGSN-side reset of a PTP BVC */
+static void sgsn_ptp_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
+ uint16_t cell_id, uint8_t cause, void *priv)
+{
+ struct gbproxy_bvc *bvc = priv;
- /* Send a copy to the secondary SGSN */
- gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn2_nsei);
- break;
- default:
- break;
+ if (!bvc->cell) {
+ LOGPBVC(bvc, LOGL_ERROR, "RESET of PTP BVC on SGSN side for which we have no BSS?\n");
+ return;
}
+ OSMO_ASSERT(bvc->cell->bss_bvc);
- return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei);
+ /* request reset of BSS-facing PTP-BVC */
+ osmo_fsm_inst_dispatch(bvc->cell->bss_bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause);
}
-/* 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)
+static const struct bssgp_bvc_fsm_ops sgsn_ptp_bvc_fsm_ops = {
+ .reset_notification = sgsn_ptp_bvc_reset_notif,
+};
+
+/* BVC FSM informs us about a SGSN-side reset of the signaling BVC */
+static void sgsn_sig_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
+ uint16_t cell_id, uint8_t cause, void *priv)
{
- struct gbproxy_peer *peer;
- struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
- uint8_t pdu_type = bgph->pdu_type;
+ struct gbproxy_bvc *bvc = priv;
+ struct gbproxy_config *cfg = bvc->nse->cfg;
+ struct gbproxy_nse *bss_nse;
+ unsigned int i;
+
+ /* delete all SGSN-side PTP BVC for this SGSN */
+ gbproxy_cleanup_bvcs(bvc->nse, 0);
+ /* FIXME: what to do about the cells? */
+ /* FIXME: do we really want to RESET all signaling BVC on the BSS and affect all other SGSN? */
+
+ /* we need to trigger generating a reset procedure towards each BSS side signaling BVC */
+ hash_for_each(cfg->bss_nses, i, bss_nse, list) {
+ struct gbproxy_bvc *bss_bvc = gbproxy_bvc_by_bvci(bss_nse, 0);
+ if (!bss_bvc) {
+ LOGPNSE(bss_nse, LOGL_ERROR, "Doesn't have BVC with BVCI=0 ?!?\n");
+ continue;
+ }
+ osmo_fsm_inst_dispatch(bss_bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause);
+ }
+}
- peer = gbproxy_peer_by_bvci(cfg, ns_bvci);
+const struct bssgp_bvc_fsm_ops sgsn_sig_bvc_fsm_ops = {
+ .reset_notification = sgsn_sig_bvc_reset_notif,
+};
- /* Send status messages before patching */
+/***********************************************************************
+ * Signaling BVC handling
+ ***********************************************************************/
- 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);
- }
+/* process a BVC-RESET message from the BSS side */
+static int rx_bvc_reset_from_bss(struct gbproxy_nse *nse, struct msgb *msg, struct tlv_parsed *tp)
+{
+ struct gbproxy_bvc *from_bvc = NULL;
+ uint16_t bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
+ uint32_t features = 0; // FIXME: make configurable
- 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);
- }
+ LOGPNSE(nse, LOGL_INFO, "Rx BVC-RESET (BVCI=%05u)\n", bvci);
- 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;
- }
+ if (bvci == 0) {
+ /* 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) */
- /* Optionally patch the message */
- gbprox_process_bssgp_dl(cfg, msg, peer);
+ from_bvc = gbproxy_bvc_by_bvci(nse, 0);
+ if (!from_bvc) {
+ from_bvc = gbproxy_bvc_alloc(nse, 0);
+ OSMO_ASSERT(from_bvc);
+ from_bvc->fi = bssgp_bvc_fsm_alloc_sig_sgsn(from_bvc, nse->cfg->nsi, nse->nsei, features);
+ if (!from_bvc->fi) {
+ LOGPNSE(nse, LOGL_ERROR, "Cannot allocate SIG-BVC FSM\n");
+ gbproxy_bvc_free(from_bvc);
+ return -ENOMEM;
+ }
+ bssgp_bvc_fsm_set_ops(from_bvc->fi, &bss_sig_bvc_fsm_ops, from_bvc);
+ }
+ } else {
+ from_bvc = gbproxy_bvc_by_bvci(nse, bvci);
+ if (!from_bvc) {
+ /* if a PTP-BVC is reset, and we don't know that
+ * PTP-BVCI yet, we should allocate a new bvc */
+ from_bvc = gbproxy_bvc_alloc(nse, bvci);
+ OSMO_ASSERT(from_bvc);
+ from_bvc->fi = bssgp_bvc_fsm_alloc_ptp_sgsn(from_bvc, nse->cfg->nsi,
+ nse->nsei, bvci);
+ if (!from_bvc->fi) {
+ LOGPNSE(nse, LOGL_ERROR, "Cannot allocate SIG-BVC FSM\n");
+ gbproxy_bvc_free(from_bvc);
+ return -ENOMEM;
+ }
+ bssgp_bvc_fsm_set_ops(from_bvc->fi, &bss_ptp_bvc_fsm_ops, from_bvc);
+ }
+#if 0
+ /* Could have moved to a different NSE */
+ if (!check_bvc_nsei(from_bvc, nsei)) {
+ LOGPBVC(from_bvc, LOGL_NOTICE, "moving bvc to NSE(%05u)\n", nsei);
+
+ struct gbproxy_nse *nse_new = gbproxy_nse_by_nsei(cfg, nsei, false);
+ if (!nse_new) {
+ LOGP(DGPRS, LOGL_NOTICE, "NSE(%05u) Got PtP BVC reset before signalling reset for "
+ "BVCI=%05u\n", bvci, nsei);
+ bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_STATE, NULL, msg);
+ return 0;
+ }
- return gbprox_relay2peer(msg, peer, ns_bvci);
+ /* Move bvc to different NSE */
+ gbproxy_bvc_move(from_bvc, nse_new);
+ }
+#endif
+ /* FIXME: do we need this, if it happens within FSM? */
+ if (TLVP_PRES_LEN(tp, BSSGP_IE_CELL_ID, 8)) {
+ 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_bvc->ra, TLVP_VAL(tp, BSSGP_IE_CELL_ID), sizeof(from_bvc->ra));
+ gsm48_parse_ra(&raid, from_bvc->ra);
+ LOGPBVC(from_bvc, LOGL_INFO, "Cell ID %s\n", osmo_rai_name(&raid));
+ }
+ }
+ /* hand into FSM for further processing */
+ osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET, msg);
+ return 0;
}
/* 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)
+static int gbprox_rx_sig_from_bss(struct gbproxy_nse *nse, struct msgb *msg, 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;
+ const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type);
+ struct tlv_parsed tp;
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;
+ struct gbproxy_bvc *from_bvc = NULL;
+ char log_pfx[32];
+ uint16_t ptp_bvci;
+ uint32_t tlli;
int rc;
+ snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/BSS)-BVC(%05u/??)", nse->nsei, ns_bvci);
+
+ LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name);
+
if (ns_bvci != 0 && ns_bvci != 1) {
- LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u BVCI=%u is not signalling\n",
- nsei, ns_bvci);
- return -EINVAL;
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s BVCI=%05u is not signalling\n", log_pfx, pdut_name, ns_bvci);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
}
- /* 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;
+ if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_SIG)) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in signalling BVC\n", log_pfx, pdut_name);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
}
- bssgp_tlv_parse(&tp, bgph->data, data_len);
+ if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_UL)) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in uplink direction\n", log_pfx, pdut_name);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
+ }
+ rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, pdu_type, bgph->data, data_len, 0, 0,
+ DGPRS, log_pfx);
+ if (rc < 0) {
+ rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]);
+ return tx_status_from_tlvp(rc, msg);
+ }
+ /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */
+ msgb_bcid(msg) = (void *)&tp;
+
+ /* special case handling for some PDU types */
switch (pdu_type) {
+ case BSSGP_PDUT_BVC_RESET:
+ /* resolve or create gbproxy_bvc + handlei n BVC-FSM */
+ return rx_bvc_reset_from_bss(nse, msg, &tp);
+ case BSSGP_PDUT_BVC_RESET_ACK:
+ ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
+ from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
+ if (!from_bvc)
+ goto err_no_bvc;
+ return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET_ACK, msg);
+ case BSSGP_PDUT_BVC_BLOCK:
+ ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
+ from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
+ if (!from_bvc)
+ goto err_no_bvc;
+ return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_BLOCK, msg);
+ case BSSGP_PDUT_BVC_UNBLOCK:
+ ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
+ from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
+ if (!from_bvc)
+ goto err_no_bvc;
+ return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_UNBLOCK, msg);
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 %s behind BVCI=%u\n",
- nsei, osmo_rai_name(&raid), 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);
- OSMO_ASSERT(from_peer);
- from_peer->nsei = nsei;
- }
+ {
+ struct gbproxy_sgsn *sgsn;
+
+ tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
+ sgsn = gbproxy_select_sgsn(nse->cfg, &tlli);
+ if (!sgsn) {
+ LOGP(DGPRS, LOGL_ERROR, "Could not find any SGSN for TLLI, dropping message!\n");
+ rc = -EINVAL;
+ break;
+ }
- 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 %s\n",
- nsei, bvci, osmo_rai_name(&raid));
- }
- if (cfg->route_to_sgsn2)
- copy_to_sgsn2 = 1;
+ gbproxy_tlli_cache_update(nse, tlli);
+
+ rc = gbprox_relay2nse(msg, sgsn->nse, 0);
+#if 0
+ /* TODO: Validate the RAI for consistency with the RAI
+ * we expect for any of the BVC within this BSS side NSE */
+ memcpy(ra, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA), sizeof(from_bvc->ra));
+ gsm48_parse_ra(&raid, from_bvc->ra);
+#endif
+ break;
+ }
+ case BSSGP_PDUT_STATUS:
+ /* FIXME: inspect the erroneous PDU IE (if any) and check
+ * if we can extract a TLLI/RNI to route it to the correct SGSN */
+ break;
+ case BSSGP_PDUT_RAN_INFO:
+ case BSSGP_PDUT_RAN_INFO_REQ:
+ case BSSGP_PDUT_RAN_INFO_ACK:
+ case BSSGP_PDUT_RAN_INFO_ERROR:
+ case BSSGP_PDUT_RAN_INFO_APP_ERROR:
+ /* FIXME: route based in RIM Routing IE */
+ rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg);
+ break;
+ case BSSGP_PDUT_LLC_DISCARD:
+ case BSSGP_PDUT_FLUSH_LL_ACK:
+ /* route based on BVCI + TLLI */
+ ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
+ tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
+ from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
+ if (!from_bvc)
+ goto err_no_bvc;
+ gbprox_bss2sgsn_tlli(from_bvc->cell, msg, &tlli, true);
+ break;
+ case BSSGP_PDUT_PAGING_PS_REJECT:
+ case BSSGP_PDUT_DUMMY_PAGING_PS_RESP:
+ {
+ /* Route according to IMSI<->NSE cache entry */
+ struct osmo_mobile_identity mi;
+ const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
+ uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
+ osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
+ nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi);
+ if (!nse) {
+ return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
}
+ OSMO_ASSERT(nse->sgsn_facing);
+ rc = gbprox_relay2nse(msg, nse, 0);
+ break;
+ }
+ default:
+ LOGPNSE(nse, LOGL_ERROR, "Rx %s: Implementation missing\n", pdut_name);
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 rc;
+err_no_bvc:
+ LOGPNSE(nse, LOGL_ERROR, "Rx %s: cannot find BVC for BVCI=%05u\n", pdut_name, ptp_bvci);
+ rate_ctr_inc(&nse->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)
+static int gbprox_rx_paging(struct gbproxy_nse *sgsn_nse, struct msgb *msg, const char *pdut_name,
+ struct tlv_parsed *tp, uint16_t ns_bvci, bool broadcast)
{
- struct gbproxy_peer *peer = NULL;
+ struct gbproxy_config *cfg = sgsn_nse->cfg;
+ struct gbproxy_bvc *sgsn_bvc, *bss_bvc;
+ struct gbproxy_nse *nse;
+ unsigned int n_nses = 0;
int errctr = GBPROX_GLOB_CTR_PROTO_ERR_SGSN;
+ int i, j;
- LOGP(DGPRS, LOGL_INFO, "NSEI=%u(SGSN) BSSGP PAGING ",
- nsei);
- if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) {
+ /* FIXME: Handle paging logic to only page each matching NSE */
+
+ if (TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2)) {
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);
+ sgsn_bvc = gbproxy_bvc_by_bvci(sgsn_nse, bvci);
+ if (!sgsn_bvc) {
+ LOGPNSE(sgsn_nse, LOGL_NOTICE, "Rx %s: unable to route: BVCI=%05u unknown\n",
+ pdut_name, bvci);
+ rate_ctr_inc(&cfg->ctrg->ctr[errctr]);
+ return -EINVAL;
+ }
+ LOGPBVC(sgsn_bvc, LOGL_INFO, "Rx %s: routing by BVCI\n", pdut_name);
+ return gbprox_relay2peer(msg, sgsn_bvc->cell->bss_bvc, ns_bvci);
+ } else if (TLVP_PRES_LEN(tp, BSSGP_IE_ROUTEING_AREA, 6)) {
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);
+ /* iterate over all bvcs and dispatch the paging to each matching one */
+ hash_for_each(cfg->bss_nses, i, nse, list) {
+ hash_for_each(nse->bvcs, j, bss_bvc, list) {
+ if (!memcmp(bss_bvc->ra, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA), 6)) {
+ LOGPNSE(nse, LOGL_INFO, "Rx %s: routing to NSE (RAI match)\n",
+ pdut_name);
+ gbprox_relay2peer(msg, bss_bvc, ns_bvci);
+ n_nses++;
+ /* Only send it once to each NSE */
+ break;
+ }
+ }
+ }
+ } else if (TLVP_PRES_LEN(tp, BSSGP_IE_LOCATION_AREA, 5)) {
errctr = GBPROX_GLOB_CTR_INV_LAI;
- } else
- LOGPC(DGPRS, LOGL_INFO, "\n");
+ /* iterate over all bvcs and dispatch the paging to each matching one */
+ hash_for_each(cfg->bss_nses, i, nse, list) {
+ hash_for_each(nse->bvcs, j, bss_bvc, list) {
+ if (!memcmp(bss_bvc->ra, TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA), 5)) {
+ LOGPNSE(nse, LOGL_INFO, "Rx %s: routing to NSE (LAI match)\n",
+ pdut_name);
+ gbprox_relay2peer(msg, bss_bvc, ns_bvci);
+ n_nses++;
+ /* Only send it once to each NSE */
+ break;
+ }
+ }
+ }
+ } else if (TLVP_PRES_LEN(tp, BSSGP_IE_BSS_AREA_ID, 1) || broadcast) {
+ /* iterate over all bvcs and dispatch the paging to each matching one */
+ hash_for_each(cfg->bss_nses, i, nse, list) {
+ hash_for_each(nse->bvcs, j, bss_bvc, list) {
+ LOGPNSE(nse, LOGL_INFO, "Rx %s:routing to NSE (broadcast)\n", pdut_name);
+ gbprox_relay2peer(msg, bss_bvc, ns_bvci);
+ n_nses++;
+ /* Only send it once to each NSE */
+ break;
+ }
+ }
+ } else {
+ LOGPNSE(sgsn_nse, LOGL_ERROR, "BSSGP PAGING: unable to route, missing IE\n");
+ rate_ctr_inc(&cfg->ctrg->ctr[errctr]);
+ }
- if (!peer) {
- LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(SGSN) BSSGP PAGING: "
- "unable to route, missing IE\n", nsei);
+ if (n_nses == 0) {
+ LOGPNSE(sgsn_nse, LOGL_ERROR, "BSSGP PAGING: unable to route, no destination found\n");
rate_ctr_inc(&cfg->ctrg->ctr[errctr]);
return -EINVAL;
}
- return gbprox_relay2peer(msg, peer, ns_bvci);
+ return 0;
}
/* 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)
+static int rx_bvc_reset_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, struct tlv_parsed *tp,
+ uint16_t ns_bvci)
{
- struct gbproxy_peer *peer;
- uint16_t ptp_bvci;
+ uint16_t ptp_bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
+ struct gbproxy_bvc *from_bvc;
- 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);
+ LOGPNSE(nse, LOGL_INFO, "Rx BVC-RESET (BVCI=%05u)\n", ptp_bvci);
+
+ if (ptp_bvci == 0) {
+ from_bvc = gbproxy_bvc_by_bvci(nse, 0);
+ OSMO_ASSERT(from_bvc);
+ osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET, msg);
+ } else {
+ from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci);
+ if (!from_bvc) {
+ LOGPNSE(nse, LOGL_ERROR, "Rx BVC-RESET BVCI=%05u: Cannot find BVC\n", ptp_bvci);
+ rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_BVCI]);
+ return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &ptp_bvci, msg);
}
- return gbprox_relay2peer(msg, peer, ns_bvci);
+ osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET, msg);
}
- /* 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)
+static int gbprox_rx_sig_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci)
{
- struct bssgp_normal_hdr *bgph =
- (struct bssgp_normal_hdr *) msgb_bssgph(orig_msg);
- struct tlv_parsed tp;
+ struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
uint8_t pdu_type = bgph->pdu_type;
+ const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type);
+ struct gbproxy_config *cfg = nse->cfg;
+ struct gbproxy_bvc *sgsn_bvc;
+ struct tlv_parsed tp;
int data_len;
- struct gbproxy_peer *peer;
uint16_t bvci;
- struct msgb *msg;
+ char log_pfx[32];
int rc = 0;
int cause;
+ int i;
+ bool paging_bc = false;
+
+ snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/SGSN)-BVC(%05u/??)", nse->nsei, ns_bvci);
+
+ LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name);
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;
+ LOGP(DGPRS, LOGL_NOTICE, "%s BVCI=%05u is not signalling\n", log_pfx, ns_bvci);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
+ }
+
+ if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_SIG)) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in signalling BVC\n", log_pfx, pdut_name);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
}
- /* 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);
+ if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_DL)) {
+ LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in downlink direction\n", log_pfx, pdut_name);
+ return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
}
- msg = bssgp_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);
+ data_len = msgb_bssgp_len(msg) - sizeof(*bgph);
+
+ rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, pdu_type, bgph->data, data_len, 0, 0,
+ DGPRS, log_pfx);
+ if (rc < 0) {
+ rc = tx_status_from_tlvp(rc, msg);
+ rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]);
+ return rc;
+ }
+ /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */
+ msgb_bcid(msg) = (void *)&tp;
switch (pdu_type) {
case BSSGP_PDUT_BVC_RESET:
- rc = rx_reset_from_sgsn(cfg, msg, orig_msg, &tp, nsei, ns_bvci);
+ /* resolve or create ggbproxy_bvc + handle in BVC-FSM */
+ bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
+ rc = rx_bvc_reset_from_sgsn(nse, msg, &tp, ns_bvci);
break;
case BSSGP_PDUT_BVC_RESET_ACK:
- if (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei)
- break;
- /* fall through */
+ bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
+ sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
+ if (!sgsn_bvc)
+ goto err_no_bvc;
+ rc = osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_RESET_ACK, msg);
+ break;
+ case BSSGP_PDUT_BVC_BLOCK_ACK:
+ bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
+ sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
+ if (!sgsn_bvc)
+ goto err_no_bvc;
+ rc = osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_BLOCK_ACK, msg);
+ break;
+ case BSSGP_PDUT_BVC_UNBLOCK_ACK:
+ bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI));
+ sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
+ if (!sgsn_bvc)
+ goto err_no_bvc;
+ rc = osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_UNBLOCK_ACK, msg);
+ break;
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);
+ sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
+ if (!sgsn_bvc)
+ goto err_no_bvc;
+ if (sgsn_bvc->cell && sgsn_bvc->cell->bss_bvc)
+ rc = gbprox_relay2peer(msg, sgsn_bvc->cell->bss_bvc, ns_bvci);
break;
+ case BSSGP_PDUT_DUMMY_PAGING_PS:
+ /* Routing area is optional in dummy paging and we have nothing else to go by
+ * so in case it is missing we need to broadcast the paging */
+ paging_bc = true;
+ /* fall through */
case BSSGP_PDUT_PAGING_PS:
+ {
+ /* Cache the IMSI<->NSE to route PAGING REJECT */
+ struct osmo_mobile_identity mi;
+ const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI);
+ uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI);
+ osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
+ gbproxy_imsi_cache_update(nse, mi.imsi);
+ /* fall through */
+ }
case BSSGP_PDUT_PAGING_CS:
/* process the paging request (LAI/RAI lookup) */
- rc = gbprox_rx_paging(cfg, msg, &tp, nsei, ns_bvci);
+ rc = gbprox_rx_paging(nse, msg, pdut_name, &tp, ns_bvci, paging_bc);
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),
+ LOGPNSE(nse, LOGL_NOTICE, "Rx STATUS cause=0x%02x(%s) ", cause,
bssgp_cause_str(cause));
- if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) {
+ if (TLVP_PRES_LEN(&tp, BSSGP_IE_BVCI, 2)) {
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);
+ LOGPC(DGPRS, LOGL_NOTICE, "BVCI=%05u\n", bvci);
+ sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci);
+ /* don't send STATUS in response to STATUS if !bvc */
+ if (sgsn_bvc && sgsn_bvc->cell && sgsn_bvc->cell->bss_bvc)
+ rc = gbprox_relay2peer(msg, sgsn_bvc->cell->bss_bvc, ns_bvci);
} else
LOGPC(DGPRS, LOGL_NOTICE, "\n");
break;
@@ -1248,207 +1217,292 @@ static int gbprox_rx_sig_from_sgsn(struct gbproxy_config *cfg,
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);
+ {
+ struct gbproxy_nse *nse_peer;
+ uint32_t tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
+
+ nse_peer = gbproxy_nse_by_tlli(cfg, tlli);
+ if (!nse_peer) {
+ LOGPNSE(nse, LOGL_ERROR, "Rx %s: Cannot find NSE\n", pdut_name);
+ /* TODO: Counter */
+ return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
}
- rc = gbprox_relay2bvci(cfg, msg, bvci, ns_bvci);
+ /* Delete the entry after we're done */
+ gbproxy_tlli_cache_remove(cfg, tlli);
+ LOGPNSE(nse_peer, LOGL_DEBUG, "Rx %s: forwarding\n", pdut_name);
+ gbprox_relay2nse(msg, nse_peer, 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);
+ case BSSGP_PDUT_OVERLOAD:
+ LOGPNSE(nse, LOGL_DEBUG, "Rx %s: broadcasting\n", pdut_name);
+ /* broadcast to all BSS-side bvcs */
+ hash_for_each(cfg->bss_nses, i, nse, list) {
+ gbprox_relay2nse(msg, nse, 0);
+ }
+ break;
+ case BSSGP_PDUT_RAN_INFO:
+ case BSSGP_PDUT_RAN_INFO_REQ:
+ case BSSGP_PDUT_RAN_INFO_ACK:
+ case BSSGP_PDUT_RAN_INFO_ERROR:
+ case BSSGP_PDUT_RAN_INFO_APP_ERROR:
+ /* FIXME: route based in RIM Routing IE */
+ rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, 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);
+ LOGPNSE(nse, LOGL_NOTICE, "Rx %s: Not supported\n", pdut_name);
+ rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]);
+ rc = bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, 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);
+
+err_no_bvc:
+ LOGPNSE(nse, LOGL_ERROR, "Rx %s: Cannot find BVC\n", pdut_name);
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);
+ return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, 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)
+/***********************************************************************
+ * libosmogb NS/BSSGP integration
+ ***********************************************************************/
+
+int gbprox_bssgp_send_cb(void *ctx, struct msgb *msg)
{
int rc;
- int remote_end_is_sgsn = gbproxy_is_sgsn_nsei(cfg, nsei);
+ struct gbproxy_config *cfg = (struct gbproxy_config *) ctx;
+ struct gprs_ns2_inst *nsi = cfg->nsi;
+ struct osmo_gprs_ns2_prim nsp = {};
- /* 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);
- }
+ nsp.bvci = msgb_bvci(msg);
+ nsp.nsei = msgb_nsei(msg);
+
+ osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA, PRIM_OP_REQUEST, msg);
+ rc = gprs_ns2_recv_prim(nsi, &nsp.oph);
return rc;
}
-int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi)
+/* Main input function for Gb proxy */
+int gbprox_rcvmsg(void *ctx, struct msgb *msg)
{
- struct gprs_nsvc *nsvc;
+ struct gbproxy_config *cfg = (struct gbproxy_config *) ctx;
+ uint16_t ns_bvci = msgb_bvci(msg);
+ uint16_t nsei = msgb_nsei(msg);
+ struct gbproxy_nse *nse;
+
+ /* ensure minimum length to decode PCU type */
+ if (msgb_bssgp_len(msg) < sizeof(struct bssgp_normal_hdr))
+ return bssgp_tx_status(BSSGP_CAUSE_SEM_INCORR_PDU, NULL, msg);
+
+ nse = gbproxy_nse_by_nsei(cfg, nsei, NSE_F_SGSN);
+ if (nse) {
+ if (ns_bvci == 0 || ns_bvci == 1)
+ return gbprox_rx_sig_from_sgsn(nse, msg, ns_bvci);
+ else
+ return gbprox_rx_ptp_from_sgsn(nse, msg, ns_bvci);
+ }
- llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
- if (!nsvc->persistent)
- continue;
- gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION);
+ nse = gbproxy_nse_by_nsei(cfg, nsei, NSE_F_BSS);
+ if (!nse) {
+ LOGP(DGPRS, LOGL_NOTICE, "NSE(%05u/BSS) not known -> allocating\n", nsei);
+ nse = gbproxy_nse_alloc(cfg, nsei, false);
+ }
+ if (nse) {
+ if (ns_bvci == 0 || ns_bvci == 1)
+ return gbprox_rx_sig_from_bss(nse, msg, ns_bvci);
+ else
+ return gbprox_rx_ptp_from_bss(nse, msg, ns_bvci);
}
+
return 0;
}
-/* Signal handler for signals from NS layer */
-int gbprox_signal(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
+/* TODO: What about handling:
+ * NS_AFF_CAUSE_VC_FAILURE,
+ NS_AFF_CAUSE_VC_RECOVERY,
+ NS_AFF_CAUSE_FAILURE,
+ NS_AFF_CAUSE_RECOVERY,
+ osmocom own causes
+ NS_AFF_CAUSE_SNS_CONFIGURED,
+ NS_AFF_CAUSE_SNS_FAILURE,
+ */
+
+void gprs_ns_prim_status_cb(struct gbproxy_config *cfg, struct osmo_gprs_ns2_prim *nsp)
{
- 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);
+ /* TODO: bss nsei available/unavailable bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, nsvc->nsei, bvc->bvci, 0);
+ * TODO: sgsn nsei available/unavailable
+ */
- if (subsys != SS_L_NS)
- return 0;
+ struct gbproxy_bvc *bvc;
+ struct gbproxy_nse *sgsn_nse;
- 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);
- }
+ switch (nsp->u.status.cause) {
+ case NS_AFF_CAUSE_SNS_FAILURE:
+ case NS_AFF_CAUSE_SNS_CONFIGURED:
+ break;
- 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;
+ case NS_AFF_CAUSE_RECOVERY:
+ LOGP(DGPRS, LOGL_NOTICE, "NS-NSE %d became available\n", nsp->nsei);
+ sgsn_nse = gbproxy_nse_by_nsei(cfg, nsp->nsei, NSE_F_SGSN);
+ if (sgsn_nse) {
+ uint8_t cause = BSSGP_CAUSE_OML_INTERV;
+ bvc = gbproxy_bvc_by_bvci(sgsn_nse, 0);
+ if (bvc)
+ osmo_fsm_inst_dispatch(bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause);
}
- 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 NS_AFF_CAUSE_FAILURE:
+#if 0
+ if (gbproxy_is_sgsn_nsei(cfg, nsp->nsei)) {
+ /* sgsn */
+ /* TODO: BSVC: block all PtP towards bss */
+ rate_ctr_inc(&cfg->ctrg->
+ ctr[GBPROX_GLOB_CTR_RESTART_RESET_SGSN]);
+ } else {
+ /* bss became unavailable
+ * TODO: Block all BVC belonging to that NSE */
+ bvc = gbproxy_bvc_by_nsei(cfg, nsp->nsei);
+ if (!bvc) {
+ /* TODO: use primitive name + status cause name */
+ LOGP(DGPRS, LOGL_NOTICE, "Received ns2 primitive %d for unknown bvc NSEI=%u\n",
+ nsp->u.status.cause, nsp->nsei);
break;
- case S_NS_UNBLOCK:
- gprs_ns_tx_unblock(next_nsvc);
+ }
+
+ if (!bvc->blocked)
break;
+ hash_for_each(cfg->sgsn_nses, _sgsn, sgsn_nse, list) {
+ bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, sgsn_nse->nsei, bvc->bvci, 0);
}
}
+#endif
+ LOGP(DGPRS, LOGL_NOTICE, "NS-NSE %d became unavailable\n", nsp->nsei);
+ break;
+ default:
+ LOGP(DGPRS, LOGL_NOTICE, "NS: Unknown NS-STATUS.ind cause=%s from NS\n",
+ gprs_ns2_aff_cause_prim_str(nsp->u.status.cause));
+ break;
}
- return 0;
+}
+
+/* called by the ns layer */
+int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_gprs_ns2_prim *nsp;
+ struct gbproxy_config *cfg = (struct gbproxy_config *) ctx;
+ uintptr_t bvci;
+ int rc = 0;
+
+ if (oph->sap != SAP_NS)
+ return 0;
+
+ nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph);
+
+ if (oph->operation != PRIM_OP_INDICATION) {
+ LOGP(DGPRS, LOGL_NOTICE, "NS: Unexpected primitive operation %s from NS\n",
+ get_value_string(osmo_prim_op_names, oph->operation));
+ return 0;
+ }
+
+ switch (oph->primitive) {
+ case PRIM_NS_UNIT_DATA:
+
+ /* hand the message into the BSSGP implementation */
+ msgb_bssgph(oph->msg) = oph->msg->l3h;
+ msgb_bvci(oph->msg) = nsp->bvci;
+ msgb_nsei(oph->msg) = nsp->nsei;
+ bvci = nsp->bvci | BVC_LOG_CTX_FLAG;
+
+ log_set_context(LOG_CTX_GB_BVC, (void *)bvci);
+ rc = gbprox_rcvmsg(cfg, oph->msg);
+ msgb_free(oph->msg);
+ break;
+ case PRIM_NS_STATUS:
+ gprs_ns_prim_status_cb(cfg, nsp);
+ break;
+ default:
+ LOGP(DGPRS, LOGL_NOTICE, "NS: Unknown prim %s %s from NS\n",
+ gprs_ns2_prim_str(oph->primitive),
+ get_value_string(osmo_prim_op_names, oph->operation));
+ break;
+ }
+
+ return rc;
}
void gbprox_reset(struct gbproxy_config *cfg)
{
- struct gbproxy_peer *peer, *tmp;
+ struct gbproxy_nse *nse;
+ struct hlist_node *ntmp;
+ int i, j;
+
+ hash_for_each_safe(cfg->bss_nses, i, ntmp, nse, list) {
+ struct gbproxy_bvc *bvc;
+ struct hlist_node *tmp;
+ hash_for_each_safe(nse->bvcs, j, tmp, bvc, list)
+ gbproxy_bvc_free(bvc);
- llist_for_each_entry_safe(peer, tmp, &cfg->bts_peers, list)
- gbproxy_peer_free(peer);
+ gbproxy_nse_free(nse);
+ }
+ /* FIXME: cells */
+ /* FIXME: SGSN side BVCs (except signaling) */
rate_ctr_group_free(cfg->ctrg);
gbproxy_init_config(cfg);
}
+static void tlli_cache_cleanup(void *data)
+{
+ struct gbproxy_config *cfg = data;
+ gbproxy_tlli_cache_cleanup(cfg);
+
+ /* TODO: Disable timer when cache is empty */
+ osmo_timer_schedule(&cfg->tlli_cache.timer, 2, 0);
+}
+
+static void imsi_cache_cleanup(void *data)
+{
+ struct gbproxy_config *cfg = data;
+ gbproxy_imsi_cache_cleanup(cfg);
+
+ /* TODO: Disable timer when cache is empty */
+ osmo_timer_schedule(&cfg->imsi_cache.timer, 2, 0);
+}
+
int gbproxy_init_config(struct gbproxy_config *cfg)
{
struct timespec tp;
- INIT_LLIST_HEAD(&cfg->bts_peers);
+ /* by default we advertise 100% of the BSS-side capacity to _each_ SGSN */
+ cfg->pool.bvc_fc_ratio = 100;
+ cfg->pool.null_nri_ranges = osmo_nri_ranges_alloc(cfg);
+ /* TODO: Make configurable */
+ cfg->tlli_cache.timeout = 10;
+ cfg->imsi_cache.timeout = 10;
+
+ hash_init(cfg->bss_nses);
+ hash_init(cfg->sgsn_nses);
+ hash_init(cfg->cells);
+ hash_init(cfg->tlli_cache.entries);
+ INIT_LLIST_HEAD(&cfg->sgsns);
+
+ osmo_timer_setup(&cfg->tlli_cache.timer, tlli_cache_cleanup, cfg);
+ osmo_timer_schedule(&cfg->tlli_cache.timer, 2, 0);
+
+ /* We could also combine both timers */
+ osmo_timer_setup(&cfg->imsi_cache.timer, imsi_cache_cleanup, cfg);
+ osmo_timer_schedule(&cfg->imsi_cache.timer, 2, 0);
+
cfg->ctrg = rate_ctr_group_alloc(tall_sgsn_ctx, &global_ctrg_desc, 0);
if (!cfg->ctrg) {
LOGP(DGPRS, LOGL_ERROR, "Cannot allocate global counter group!\n");
return -1;
}
osmo_clock_gettime(CLOCK_REALTIME, &tp);
+ osmo_fsm_log_timeouts(true);
return 0;
-}
+} \ No newline at end of file
diff --git a/src/gbproxy/gb_proxy_ctrl.c b/src/gbproxy/gb_proxy_ctrl.c
index 4b7c2f43..45616346 100644
--- a/src/gbproxy/gb_proxy_ctrl.c
+++ b/src/gbproxy/gb_proxy_ctrl.c
@@ -33,19 +33,45 @@
extern vector ctrl_node_vec;
+struct nsvc_cb_data {
+ struct ctrl_cmd *cmd;
+ uint16_t nsei;
+ bool is_sgsn;
+};
+
+static int ctrl_nsvc_state_cb(struct gprs_ns2_vc *nsvc, void *ctx) {
+ struct nsvc_cb_data *data = (struct nsvc_cb_data *)ctx;
+ struct ctrl_cmd *cmd = (struct ctrl_cmd *)data->cmd;
+
+ cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%s,%s,%s\n",
+ data->nsei, gprs_ns2_ll_str(nsvc), gprs_ns2_nsvc_state_name(nsvc),
+ data->is_sgsn ? "SGSN" : "BSS" );
+
+ return 0;
+}
+
static int get_nsvc_state(struct ctrl_cmd *cmd, void *data)
{
struct gbproxy_config *cfg = data;
- struct gprs_ns_inst *nsi = cfg->nsi;
- struct gprs_nsvc *nsvc;
+ struct gprs_ns2_inst *nsi = cfg->nsi;
+ struct gprs_ns2_nse *nse;
+ struct gbproxy_nse *nse_peer;
+ int i;
cmd->reply = talloc_strdup(cmd, "");
- llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
- if (nsvc == nsi->unknown_nsvc)
- continue;
+ /* NS-VCs for SGSN */
+ hash_for_each(cfg->sgsn_nses, i, nse_peer, list) {
+ nse = gprs_ns2_nse_by_nsei(nsi, nse_peer->nsei);
+ if (nse)
+ gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
+ }
- cmd->reply = gprs_nsvc_state_append(cmd->reply, nsvc);
+ /* NS-VCs for BSS peers */
+ hash_for_each(cfg->bss_nses, i, nse_peer, list) {
+ nse = gprs_ns2_nse_by_nsei(nsi, nse_peer->nsei);
+ if (nse)
+ gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
}
return CTRL_CMD_REPLY;
@@ -56,19 +82,23 @@ CTRL_CMD_DEFINE_RO(nsvc_state, "nsvc-state");
static int get_gbproxy_state(struct ctrl_cmd *cmd, void *data)
{
struct gbproxy_config *cfg = data;
- struct gbproxy_peer *peer;
+ struct gbproxy_nse *nse_peer;
+ int i, j;
cmd->reply = talloc_strdup(cmd, "");
- llist_for_each_entry(peer, &cfg->bts_peers, list) {
- struct gprs_ra_id raid;
- gsm48_parse_ra(&raid, peer->ra);
-
- cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%u,%u,%u,%u,%u,%s\n",
- peer->nsei, peer->bvci,
- raid.mcc, raid.mnc,
- raid.lac, raid.rac,
- peer->blocked ? "BLOCKED" : "UNBLOCKED");
+ hash_for_each(cfg->bss_nses, i, nse_peer, list) {
+ struct gbproxy_bvc *bvc;
+ hash_for_each(nse_peer->bvcs, j, bvc, list) {
+ struct gprs_ra_id raid;
+ gsm48_parse_ra(&raid, bvc->ra);
+
+ cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%u,%u,%u,%u,%u,%s\n",
+ nse_peer->nsei, bvc->bvci,
+ raid.mcc, raid.mnc,
+ raid.lac, raid.rac,
+ osmo_fsm_inst_state_name(bvc->fi));
+ }
}
return CTRL_CMD_REPLY;
@@ -79,9 +109,18 @@ CTRL_CMD_DEFINE_RO(gbproxy_state, "gbproxy-state");
static int get_num_peers(struct ctrl_cmd *cmd, void *data)
{
struct gbproxy_config *cfg = data;
+ struct gbproxy_nse *nse_peer;
+ struct gbproxy_bvc *bvc;
+ uint32_t count = 0;
+ int i, j;
+
+ hash_for_each(cfg->bss_nses, i, nse_peer, list) {
+ hash_for_each(nse_peer->bvcs, j, bvc, list)
+ count++;
+ }
cmd->reply = talloc_strdup(cmd, "");
- cmd->reply = talloc_asprintf_append(cmd->reply, "%u", llist_count(&cfg->bts_peers));
+ cmd->reply = talloc_asprintf_append(cmd->reply, "%u", count);
return CTRL_CMD_REPLY;
}
diff --git a/src/gbproxy/gb_proxy_main.c b/src/gbproxy/gb_proxy_main.c
index 8c839804..37afb5e7 100644
--- a/src/gbproxy/gb_proxy_main.c
+++ b/src/gbproxy/gb_proxy_main.c
@@ -38,7 +38,7 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/sgsn/signal.h>
@@ -80,31 +80,11 @@ 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)
+static void signal_handler(int signum)
{
- int rc = 0;
+ fprintf(stdout, "signal %u received\n", signum);
- 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) {
+ switch (signum) {
case SIGINT:
case SIGTERM:
osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
@@ -112,8 +92,17 @@ static void signal_handler(int signal)
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 */
+ /* in case of abort, we want to obtain a talloc report and
+ * then run default SIGABRT handler, who will generate coredump
+ * and abort the process. abort() should do this for us after we
+ * return, but program wouldn't exit if an external SIGABRT is
+ * received.
+ */
+ talloc_report(tall_vty_ctx, stderr);
+ talloc_report_full(tall_sgsn_ctx, stderr);
+ signal(SIGABRT, SIG_DFL);
+ raise(SIGABRT);
+ break;
case SIGUSR1:
talloc_report(tall_vty_ctx, stderr);
talloc_report_full(tall_sgsn_ctx, stderr);
@@ -203,39 +192,9 @@ static void handle_options(int argc, char **argv)
}
}
-int gbproxy_vty_is_config_node(struct vty *vty, int node)
-{
- switch (node) {
- /* add items that are not config */
- case CONFIG_NODE:
- return 0;
-
- default:
- return 1;
- }
-}
-
-int gbproxy_vty_go_parent(struct vty *vty)
-{
- switch (vty->node) {
- case GBPROXY_NODE:
- default:
- if (gbproxy_vty_is_config_node(vty, vty->node))
- vty->node = CONFIG_NODE;
- else
- vty->node = ENABLE_NODE;
-
- vty->index = NULL;
- }
-
- return vty->node;
-}
-
static struct vty_app_info vty_info = {
.name = "OsmoGbProxy",
.version = PACKAGE_VERSION,
- .go_parent_cb = gbproxy_vty_go_parent,
- .is_config_node = gbproxy_vty_is_config_node,
};
/* default categories */
@@ -250,10 +209,11 @@ static struct log_info_cat gprs_categories[] = {
.description = "GPRS Network Service (NS)",
.enabled = 1, .loglevel = LOGL_INFO,
},
- [DBSSGP] = {
- .name = "DBSSGP",
- .description = "GPRS BSS Gateway Protocol (BSSGP)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
+ [DOBJ] = {
+ .name = "DOBJ",
+ .description = "GbProxy object allocation/release",
+ .enabled = 1,
+ .color = "\033[38;5;121m"
},
};
@@ -269,6 +229,8 @@ static bool file_exists(const char *path)
return stat(path, &sb) ? false : true;
}
+int gbprox_bssgp_send_cb(void *ctx, struct msgb *msg);
+
int main(int argc, char **argv)
{
int rc;
@@ -292,6 +254,7 @@ int main(int argc, char **argv)
logging_vty_add_cmds();
osmo_talloc_vty_add_cmds();
osmo_stats_vty_add_cmds();
+ osmo_fsm_vty_add_cmds();
gbproxy_vty_init();
handle_options(argc, argv);
@@ -314,23 +277,23 @@ int main(int argc, char **argv)
rate_ctr_init(tall_sgsn_ctx);
osmo_stats_init(tall_sgsn_ctx);
- bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb, tall_sgsn_ctx);
- if (!bssgp_nsi) {
- LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
- exit(1);
- }
-
gbcfg = talloc_zero(tall_sgsn_ctx, struct gbproxy_config);
if (!gbcfg) {
LOGP(DGPRS, LOGL_FATAL, "Unable to allocate config\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);
+ gbcfg->nsi = gprs_ns2_instantiate(tall_sgsn_ctx, gprs_ns2_prim_cb, gbcfg);
+ if (!gbcfg->nsi) {
+ LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
+ exit(1);
+ }
+
+ gprs_ns2_vty2_init(gbcfg->nsi);
+ logging_vty_add_deprecated_subsys(tall_sgsn_ctx, "bssgp");
+ gprs_ns2_dynamic_create_nse(gbcfg->nsi, true);
+
+ bssgp_set_bssgp_callback(gbprox_bssgp_send_cb, gbcfg);
rc = gbproxy_parse_config(config_file, gbcfg);
if (rc < 0) {
@@ -357,26 +320,6 @@ int main(int argc, char **argv)
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) {
@@ -385,9 +328,6 @@ int main(int argc, char **argv)
}
}
- /* 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)
diff --git a/src/gbproxy/gb_proxy_patch.c b/src/gbproxy/gb_proxy_patch.c
deleted file mode 100644
index 2bc3b4b7..00000000
--- a/src/gbproxy/gb_proxy_patch.c
+++ /dev/null
@@ -1,463 +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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <osmocom/sgsn/gb_proxy.h>
-
-#include <osmocom/sgsn/gprs_utils.h>
-#include <osmocom/sgsn/gprs_gb_parse.h>
-
-#include <osmocom/sgsn/debug.h>
-
-#include <osmocom/gprs/protocol/gsm_08_18.h>
-#include <osmocom/core/rate_ctr.h>
-#include <osmocom/gsm/apn.h>
-
-extern void *tall_sgsn_ctx;
-
-/* patch RA identifier in place */
-static void gbproxy_patch_raid(struct gsm48_ra_id *raid_enc, struct gbproxy_peer *peer,
- int to_bss, const char *log_text)
-{
- struct gbproxy_patch_state *state = &peer->patch_state;
- struct osmo_plmn_id old_plmn;
- 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_plmn.mcc || !state->local_plmn.mnc)
- return;
-
- gsm48_parse_ra(&raid, (uint8_t *)raid_enc);
-
- old_plmn = (struct osmo_plmn_id){
- .mcc = raid.mcc,
- .mnc = raid.mnc,
- .mnc_3_digits = raid.mnc_3_digits,
- };
-
- if (!to_bss) {
- /* BSS -> SGSN */
- if (state->local_plmn.mcc)
- raid.mcc = peer->cfg->core_plmn.mcc;
-
- if (state->local_plmn.mnc) {
- raid.mnc = peer->cfg->core_plmn.mnc;
- raid.mnc_3_digits = peer->cfg->core_plmn.mnc_3_digits;
- }
- } else {
- /* SGSN -> BSS */
- if (state->local_plmn.mcc)
- raid.mcc = state->local_plmn.mcc;
-
- if (state->local_plmn.mnc) {
- raid.mnc = state->local_plmn.mnc;
- raid.mnc_3_digits = state->local_plmn.mnc_3_digits;
- }
- }
-
- LOGP(DGPRS, LOGL_DEBUG,
- "Patching %s to %s: "
- "%s-%d-%d -> %s\n",
- log_text,
- to_bss ? "BSS" : "SGSN",
- osmo_plmn_name(&old_plmn), raid.lac, raid.rac,
- osmo_rai_name(&raid));
-
- gsm48_encode_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;
- 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;
- 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((struct gsm48_ra_id *)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((struct gsm48_ra_id *)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_plmn.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((struct gsm48_ra_id *)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 = false;
- }
- 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 = true;
- match->re_str = talloc_strdup(tall_sgsn_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)
-{
- int rc;
- struct osmo_mobile_identity mi;
-
- if (!match->enable)
- return 1;
-
- rc = osmo_mobile_identity_decode(&mi, imsi, imsi_len, false);
- if (rc || mi.type != GSM_MI_TYPE_IMSI) {
- 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.imsi, rc);
-
- rc = regexec(&match->re_comp, mi.imsi, 0, NULL, 0);
- if (rc == REG_NOMATCH) {
- LOGP(DGPRS, LOGL_INFO,
- "IMSI '%s' doesn't match pattern '%s'\n",
- mi.imsi, match->re_str);
- return 0;
- }
-
- return 1;
-}
diff --git a/src/gbproxy/gb_proxy_peer.c b/src/gbproxy/gb_proxy_peer.c
index 48482b6a..7d6ba864 100644
--- a/src/gbproxy/gb_proxy_peer.c
+++ b/src/gbproxy/gb_proxy_peer.c
@@ -25,216 +25,735 @@
#include <osmocom/sgsn/debug.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
+#include <osmocom/core/crc16.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/linuxlist.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
#include <osmocom/gsm/tlv.h>
#include <string.h>
extern void *tall_sgsn_ctx;
-static const struct rate_ctr_desc peer_ctr_description[] = {
+static const struct rate_ctr_desc bvc_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);
+osmo_static_assert(ARRAY_SIZE(bvc_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described);
-static const struct rate_ctr_group_desc peer_ctrg_desc = {
+static const struct rate_ctr_group_desc bvc_ctrg_desc = {
.group_name_prefix = "gbproxy:peer",
.group_description = "GBProxy Peer Statistics",
- .num_ctr = ARRAY_SIZE(peer_ctr_description),
- .ctr_desc = peer_ctr_description,
+ .num_ctr = ARRAY_SIZE(bvc_ctr_description),
+ .ctr_desc = bvc_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)
+/* Find the gbproxy_bvc by its BVCI. There can only be one match */
+struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_nse *nse, uint16_t bvci)
{
- struct gbproxy_peer *peer;
- llist_for_each_entry(peer, &cfg->bts_peers, list) {
- if (peer->bvci == bvci)
- return peer;
+ struct gbproxy_bvc *bvc;
+ hash_for_each_possible(nse->bvcs, bvc, list, bvci) {
+ if (bvc->bvci == bvci)
+ return bvc;
}
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_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci)
{
- struct gbproxy_peer *peer;
- llist_for_each_entry(peer, &cfg->bts_peers, list) {
- if (peer->nsei == nsei)
- return peer;
+ struct gbproxy_bvc *bvc;
+ OSMO_ASSERT(nse);
+ struct gbproxy_config *cfg = nse->cfg;
+ OSMO_ASSERT(cfg);
+
+ bvc = talloc_zero(tall_sgsn_ctx, struct gbproxy_bvc);
+ if (!bvc)
+ return NULL;
+
+ bvc->bvci = bvci;
+ bvc->ctrg = rate_ctr_group_alloc(bvc, &bvc_ctrg_desc, (nse->nsei << 16) | bvci);
+ if (!bvc->ctrg) {
+ talloc_free(bvc);
+ return NULL;
}
- return NULL;
+ bvc->nse = nse;
+
+ hash_add(nse->bvcs, &bvc->list, bvc->bvci);
+
+ LOGPBVC_CAT(bvc, DOBJ, LOGL_INFO, "BVC Created\n");
+
+ /* We leave allocating the bvc->fi to the caller, as the FSM details depend
+ * on the type of BVC (SIG/PTP) and role (SGSN/BSS) */
+
+ return bvc;
}
-/* 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)
+void gbproxy_bvc_free(struct gbproxy_bvc *bvc)
{
- struct gbproxy_peer *peer;
- llist_for_each_entry(peer, &cfg->bts_peers, list) {
- if (!memcmp(peer->ra, ra, 6))
- return peer;
+ struct gbproxy_cell *cell;
+
+ if (!bvc)
+ return;
+
+ LOGPBVC_CAT(bvc, DOBJ, LOGL_INFO, "BVC Destroying\n");
+
+ hash_del(&bvc->list);
+
+ rate_ctr_group_free(bvc->ctrg);
+ bvc->ctrg = NULL;
+
+ osmo_fsm_inst_free(bvc->fi);
+
+ cell = bvc->cell;
+ if (cell) {
+ int i;
+
+ if (cell->bss_bvc == bvc)
+ cell->bss_bvc = NULL;
+
+ /* we could also be a SGSN-side BVC */
+ for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
+ if (cell->sgsn_bvc[i] == bvc)
+ cell->sgsn_bvc[i] = NULL;
+ }
+ bvc->cell = NULL;
}
- return NULL;
+
+ talloc_free(bvc);
+}
+
+/*! remove BVCs on NSE specified by NSEI.
+ * \param[in] cfg proxy in which we operate
+ * \param[in] nsei NS entity in which we should clean up
+ * \param[in] bvci if 0: remove all PTP BVCs; if != 0: BVCI of the single BVC to clean up */
+int gbproxy_cleanup_bvcs(struct gbproxy_nse *nse, uint16_t bvci)
+{
+ struct hlist_node *btmp;
+ struct gbproxy_bvc *bvc;
+ int j, counter = 0;
+
+ if (!nse)
+ return 0;
+
+ hash_for_each_safe(nse->bvcs, j, btmp, bvc, list) {
+ if (bvci && bvc->bvci != bvci)
+ continue;
+ if (bvci == 0 && bvc->bvci == 0)
+ continue;
+
+ gbproxy_bvc_free(bvc);
+ counter += 1;
+ }
+
+ return counter;
+}
+
+
+/***********************************************************************
+ * CELL
+ ***********************************************************************/
+
+/* Allocate a new 'cell' object */
+struct gbproxy_cell *gbproxy_cell_alloc(struct gbproxy_config *cfg, uint16_t bvci)
+{
+ struct gbproxy_cell *cell;
+ OSMO_ASSERT(cfg);
+
+ cell = talloc_zero(cfg, struct gbproxy_cell);
+ if (!cell)
+ return NULL;
+
+ cell->cfg = cfg;
+ cell->bvci = bvci;
+
+ hash_add(cfg->cells, &cell->list, cell->bvci);
+
+ LOGPCELL_CAT(cell, DOBJ, LOGL_INFO, "CELL Created\n");
+
+ return cell;
}
-/* 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)
+/* Find cell by BVCI */
+struct gbproxy_cell *gbproxy_cell_by_bvci(struct gbproxy_config *cfg, uint16_t bvci)
{
- struct gbproxy_peer *peer;
- llist_for_each_entry(peer, &cfg->bts_peers, list) {
- if (!memcmp(peer->ra, la, 5))
- return peer;
+ struct gbproxy_cell *cell;
+
+ hash_for_each_possible(cfg->cells, cell, list, bvci) {
+ if (cell->bvci == bvci)
+ return cell;
}
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_cell *gbproxy_cell_by_bvci_or_new(struct gbproxy_config *cfg, uint16_t bvci)
+{
+ struct gbproxy_cell *cell;
+ OSMO_ASSERT(cfg);
+
+ cell = gbproxy_cell_by_bvci(cfg, bvci);
+ if (!cell)
+ cell = gbproxy_cell_alloc(cfg, bvci);
+
+ return cell;
+}
+
+void gbproxy_cell_free(struct gbproxy_cell *cell)
{
- struct gbproxy_peer *peer;
- llist_for_each_entry(peer, &cfg->bts_peers, list) {
- if (!memcmp(peer->ra + 3, la + 3, 2))
- return peer;
+ unsigned int i;
+
+ if (!cell)
+ return;
+
+ LOGPCELL_CAT(cell, DOBJ, LOGL_INFO, "CELL Destroying\n");
+
+ /* remove from cfg.cells */
+ hash_del(&cell->list);
+
+ /* remove back-pointers from the BSS side */
+ if (cell->bss_bvc && cell->bss_bvc->cell)
+ cell->bss_bvc->cell = NULL;
+
+ /* remove back-pointers from the SGSN side */
+ for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
+ if (!cell->sgsn_bvc[i])
+ continue;
+ if (cell->sgsn_bvc[i]->cell)
+ cell->sgsn_bvc[i]->cell = NULL;
+ }
+
+ talloc_free(cell);
+}
+
+bool gbproxy_cell_add_sgsn_bvc(struct gbproxy_cell *cell, struct gbproxy_bvc *bvc)
+{
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
+ if (!cell->sgsn_bvc[i]) {
+ cell->sgsn_bvc[i] = bvc;
+ LOGPCELL_CAT(cell, DOBJ, LOGL_DEBUG, "CELL linked to SGSN\n");
+ LOGPBVC_CAT(bvc, DOBJ, LOGL_DEBUG, "BVC linked to CELL\n");
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/***********************************************************************
+ * TLLI cache
+ ***********************************************************************/
+
+static inline struct gbproxy_tlli_cache_entry *_get_tlli_entry(struct gbproxy_config *cfg, uint32_t tlli)
+{
+ struct gbproxy_tlli_cache_entry *cache_entry;
+
+ hash_for_each_possible(cfg->tlli_cache.entries, cache_entry, list, tlli) {
+ if (cache_entry->tlli == tlli)
+ return cache_entry;
}
return NULL;
}
-struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(struct gbproxy_config *cfg,
- struct tlv_parsed *tp)
+void gbproxy_tlli_cache_update(struct gbproxy_nse *nse, uint32_t tlli)
{
- if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) {
- uint16_t bvci;
+ struct gbproxy_config *cfg = nse->cfg;
+ struct timespec now;
+ struct gbproxy_tlli_cache_entry *cache_entry = _get_tlli_entry(cfg, tlli);
- bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
- if (bvci >= 2)
- return gbproxy_peer_by_bvci(cfg, bvci);
+ osmo_clock_gettime(CLOCK_MONOTONIC, &now);
+
+ if (cache_entry) {
+ /* Update the entry if it already exists */
+ cache_entry->nse = nse;
+ cache_entry->tstamp = now.tv_sec;
+ return;
+ }
+
+ cache_entry = talloc_zero(cfg, struct gbproxy_tlli_cache_entry);
+ cache_entry->tlli = tlli;
+ cache_entry->nse = nse;
+ cache_entry->tstamp = now.tv_sec;
+ hash_add(cfg->tlli_cache.entries, &cache_entry->list, cache_entry->tlli);
+}
+
+static void _tlli_cache_remove_nse(struct gbproxy_nse *nse) {
+ uint i;
+ struct gbproxy_config *cfg = nse->cfg;
+ struct gbproxy_tlli_cache_entry *tlli_cache;
+ struct hlist_node *tmp;
+
+ hash_for_each_safe(cfg->tlli_cache.entries, i, tmp, tlli_cache, list) {
+ if (tlli_cache->nse == nse) {
+ hash_del(&tlli_cache->list);
+ talloc_free(tlli_cache);
+ }
}
+}
- 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);
+void gbproxy_tlli_cache_remove(struct gbproxy_config *cfg, uint32_t tlli)
+{
+ struct gbproxy_tlli_cache_entry *tlli_cache;
+ struct hlist_node *tmp;
+
+ hash_for_each_possible_safe(cfg->tlli_cache.entries, tlli_cache, tmp, list, tlli) {
+ if (tlli_cache->tlli == tlli) {
+ hash_del(&tlli_cache->list);
+ talloc_free(tlli_cache);
+ return;
+ }
}
+}
- 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);
+int gbproxy_tlli_cache_cleanup(struct gbproxy_config *cfg)
+{
+ int i, count = 0;
+ struct gbproxy_tlli_cache_entry *tlli_cache;
+ struct hlist_node *tmp;
+ struct timespec now;
+ time_t expiry;
+
+ osmo_clock_gettime(CLOCK_MONOTONIC, &now);
+ expiry = now.tv_sec - cfg->tlli_cache.timeout;
+
+ hash_for_each_safe(cfg->tlli_cache.entries, i, tmp, tlli_cache, list) {
+ if (tlli_cache->tstamp < expiry) {
+ count++;
+ LOGP(DGPRS, LOGL_NOTICE, "Cache entry for TLLI %08x expired, removing\n", tlli_cache->tlli);
+ hash_del(&tlli_cache->list);
+ talloc_free(tlli_cache);
+ }
}
+ return count;
+
+}
+/***********************************************************************
+ * IMSI cache
+ ***********************************************************************/
+static inline uint16_t _checksum_imsi(const char *imsi)
+{
+ size_t len = strlen(imsi);
+ return osmo_crc16(0, (const uint8_t *)imsi, len);
+}
+
+static inline struct gbproxy_imsi_cache_entry *_get_imsi_entry(struct gbproxy_config *cfg, const char *imsi)
+{
+ struct gbproxy_imsi_cache_entry *cache_entry;
+ uint16_t imsi_hash = _checksum_imsi(imsi);
+ hash_for_each_possible(cfg->imsi_cache.entries, cache_entry, list, imsi_hash) {
+ if (!strncmp(cache_entry->imsi, imsi, sizeof(cache_entry->imsi)))
+ return cache_entry;
+ }
return NULL;
}
-static void clean_stale_timer_cb(void *data)
+void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi)
+{
+ struct gbproxy_config *cfg = nse->cfg;
+ struct timespec now;
+ struct gbproxy_imsi_cache_entry *cache_entry = _get_imsi_entry(cfg, imsi);
+ uint16_t imsi_hash = _checksum_imsi(imsi);
+
+ osmo_clock_gettime(CLOCK_MONOTONIC, &now);
+
+ if (cache_entry) {
+ /* Update the entry if it already exists */
+ cache_entry->nse = nse;
+ cache_entry->tstamp = now.tv_sec;
+ return;
+ }
+
+ cache_entry = talloc_zero(cfg, struct gbproxy_imsi_cache_entry);
+ OSMO_STRLCPY_ARRAY(cache_entry->imsi, imsi);
+ cache_entry->nse = nse;
+ cache_entry->tstamp = now.tv_sec;
+ hash_add(cfg->imsi_cache.entries, &cache_entry->list, imsi_hash);
+}
+
+static void _imsi_cache_remove_nse(struct gbproxy_nse *nse) {
+ uint i;
+ struct gbproxy_config *cfg = nse->cfg;
+ struct gbproxy_imsi_cache_entry *imsi_cache;
+ struct hlist_node *tmp;
+
+ hash_for_each_safe(cfg->imsi_cache.entries, i, tmp, imsi_cache, list) {
+ if (imsi_cache->nse == nse) {
+ hash_del(&imsi_cache->list);
+ talloc_free(imsi_cache);
+ }
+ }
+}
+
+void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi)
{
- time_t now;
- struct timespec ts = {0,};
- struct gbproxy_peer *peer = (struct gbproxy_peer *) data;
+ struct gbproxy_imsi_cache_entry *imsi_cache;
+ struct hlist_node *tmp;
+ uint16_t imsi_hash = _checksum_imsi(imsi);
+
+ hash_for_each_possible_safe(cfg->imsi_cache.entries, imsi_cache, tmp, list, imsi_hash) {
+ if (!(strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi)))) {
+ hash_del(&imsi_cache->list);
+ talloc_free(imsi_cache);
+ return;
+ }
+ }
+}
- osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
- now = ts.tv_sec;
- gbproxy_remove_stale_link_infos(peer, now);
- if (peer->cfg->clean_stale_timer_freq != 0)
- osmo_timer_schedule(&peer->clean_stale_timer,
- peer->cfg->clean_stale_timer_freq, 0);
+int gbproxy_imsi_cache_cleanup(struct gbproxy_config *cfg)
+{
+ int i, count = 0;
+ struct gbproxy_imsi_cache_entry *imsi_cache;
+ struct hlist_node *tmp;
+ struct timespec now;
+ time_t expiry;
+
+ osmo_clock_gettime(CLOCK_MONOTONIC, &now);
+ expiry = now.tv_sec - cfg->imsi_cache.timeout;
+
+ hash_for_each_safe(cfg->imsi_cache.entries, i, tmp, imsi_cache, list) {
+ if (imsi_cache->tstamp < expiry) {
+ count++;
+ LOGP(DGPRS, LOGL_NOTICE, "Cache entry for IMSI %s expired, removing\n", imsi_cache->imsi);
+ hash_del(&imsi_cache->list);
+ talloc_free(imsi_cache);
+ }
+ }
+ return count;
}
-struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci)
+/***********************************************************************
+ * NSE - NS Entity
+ ***********************************************************************/
+
+struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing)
{
- struct gbproxy_peer *peer;
+ struct gbproxy_nse *nse;
+ OSMO_ASSERT(cfg);
- peer = talloc_zero(tall_sgsn_ctx, struct gbproxy_peer);
- if (!peer)
+ nse = talloc_zero(tall_sgsn_ctx, struct gbproxy_nse);
+ if (!nse)
return NULL;
- peer->bvci = bvci;
- peer->ctrg = rate_ctr_group_alloc(peer, &peer_ctrg_desc, bvci);
- if (!peer->ctrg) {
- talloc_free(peer);
+ nse->nsei = nsei;
+ nse->cfg = cfg;
+ nse->sgsn_facing = sgsn_facing;
+
+ if (sgsn_facing)
+ hash_add(cfg->sgsn_nses, &nse->list, nsei);
+ else
+ hash_add(cfg->bss_nses, &nse->list, nsei);
+
+ hash_init(nse->bvcs);
+
+ LOGPNSE_CAT(nse, DOBJ, LOGL_INFO, "NSE Created\n");
+
+ return nse;
+}
+
+static void _nse_free(struct gbproxy_nse *nse)
+{
+ struct gbproxy_bvc *bvc;
+ struct hlist_node *tmp;
+ int i;
+
+ if (!nse)
+ return;
+
+ LOGPNSE_CAT(nse, DOBJ, LOGL_INFO, "NSE Destroying\n");
+
+ hash_del(&nse->list);
+ /* Clear the cache entries of this NSE */
+ _tlli_cache_remove_nse(nse);
+ _imsi_cache_remove_nse(nse);
+
+ hash_for_each_safe(nse->bvcs, i, tmp, bvc, list)
+ gbproxy_bvc_free(bvc);
+
+ talloc_free(nse);
+}
+static void _sgsn_free(struct gbproxy_sgsn *sgsn);
+
+void gbproxy_nse_free(struct gbproxy_nse *nse)
+{
+ if (!nse)
+ return;
+ OSMO_ASSERT(nse->cfg);
+
+ if (nse->sgsn_facing) {
+ struct gbproxy_sgsn *sgsn = gbproxy_sgsn_by_nsei(nse->cfg, nse->nsei);
+ OSMO_ASSERT(sgsn);
+ _sgsn_free(sgsn);
+ }
+
+ _nse_free(nse);
+}
+
+struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei, uint32_t flags)
+{
+ struct gbproxy_nse *nse;
+ OSMO_ASSERT(cfg);
+
+ if (flags & NSE_F_SGSN) {
+ hash_for_each_possible(cfg->sgsn_nses, nse, list, nsei) {
+ if (nse->nsei == nsei)
+ return nse;
+ }
+ }
+
+ if (flags & NSE_F_BSS) {
+ hash_for_each_possible(cfg->bss_nses, nse, list, nsei) {
+ if (nse->nsei == nsei)
+ return nse;
+ }
+ }
+
+ return NULL;
+}
+
+struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing)
+{
+ struct gbproxy_nse *nse;
+ OSMO_ASSERT(cfg);
+
+ nse = gbproxy_nse_by_nsei(cfg, nsei, sgsn_facing ? NSE_F_SGSN : NSE_F_BSS);
+ if (!nse)
+ nse = gbproxy_nse_alloc(cfg, nsei, sgsn_facing);
+
+ return nse;
+}
+
+struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli)
+{
+ struct gbproxy_tlli_cache_entry *tlli_cache;
+
+ hash_for_each_possible(cfg->tlli_cache.entries, tlli_cache, list, tlli) {
+ if (tlli_cache->tlli == tlli)
+ return tlli_cache->nse;
+ }
+ return NULL;
+}
+
+struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi)
+{
+ struct gbproxy_imsi_cache_entry *imsi_cache;
+ uint16_t imsi_hash = _checksum_imsi(imsi);
+
+ hash_for_each_possible(cfg->imsi_cache.entries, imsi_cache, list, imsi_hash) {
+ if (!strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi)))
+ return imsi_cache->nse;
+ }
+ return NULL;
+}
+
+/***********************************************************************
+ * SGSN - Serving GPRS Support Node
+ ***********************************************************************/
+
+/*! Allocate a new SGSN. This ensures the corresponding gbproxy_nse is allocated as well
+ * \param[in] cfg The gbproxy configuration
+ * \param[in] nsei The nsei where the SGSN can be reached
+ * \param[in] name A name to give the SGSN
+ * \return The SGSN, NULL if it couldn't be allocated
+ */
+struct gbproxy_sgsn *gbproxy_sgsn_alloc(struct gbproxy_config *cfg, uint16_t nsei, const char *name)
+{
+ struct gbproxy_sgsn *sgsn;
+ OSMO_ASSERT(cfg);
+
+ sgsn = talloc_zero(tall_sgsn_ctx, struct gbproxy_sgsn);
+ if (!sgsn)
return NULL;
+
+ sgsn->nse = gbproxy_nse_alloc(cfg, nsei, true);
+ if (!sgsn->nse) {
+ LOGP(DOBJ, LOGL_ERROR, "Could not allocate NSE(%05u) for SGSN(%s)\n",
+ nsei, sgsn->name);
+ goto free_sgsn;
}
- peer->cfg = cfg;
- llist_add(&peer->list, &cfg->bts_peers);
+ if (name)
+ sgsn->name = talloc_strdup(sgsn, name);
+ else
+ sgsn->name = talloc_asprintf(sgsn, "NSE(%05u)", sgsn->nse->nsei);
+ if (!sgsn->name)
+ goto free_sgsn;
- INIT_LLIST_HEAD(&peer->patch_state.logical_links);
+ sgsn->pool.allow_attach = true;
+ sgsn->pool.nri_ranges = osmo_nri_ranges_alloc(sgsn);
- osmo_timer_setup(&peer->clean_stale_timer, clean_stale_timer_cb, peer);
- if (peer->cfg->clean_stale_timer_freq != 0)
- osmo_timer_schedule(&peer->clean_stale_timer,
- peer->cfg->clean_stale_timer_freq, 0);
+ llist_add_tail(&sgsn->list, &cfg->sgsns);
+ LOGPSGSN_CAT(sgsn, DOBJ, LOGL_INFO, "SGSN Created\n");
+ return sgsn;
- return peer;
+free_sgsn:
+ talloc_free(sgsn);
+ return NULL;
+}
+
+/* Only free gbproxy_sgsn, sgsn can't be NULL */
+static void _sgsn_free(struct gbproxy_sgsn *sgsn) {
+ struct gbproxy_config *cfg;
+
+ OSMO_ASSERT(sgsn->nse);
+ cfg = sgsn->nse->cfg;
+ OSMO_ASSERT(cfg);
+
+ LOGPSGSN_CAT(sgsn, DOBJ, LOGL_INFO, "SGSN Destroying\n");
+ llist_del(&sgsn->list);
+ /* talloc will free ->name and ->pool.nri_ranges */
+ talloc_free(sgsn);
}
-void gbproxy_peer_free(struct gbproxy_peer *peer)
+/*! Free the SGSN. This ensures the corresponding gbproxy_nse is freed as well
+ * \param[in] sgsn The SGSN
+ */
+void gbproxy_sgsn_free(struct gbproxy_sgsn *sgsn)
{
- llist_del(&peer->list);
- osmo_timer_del(&peer->clean_stale_timer);
- gbproxy_delete_link_infos(peer);
+ if (!sgsn)
+ return;
- rate_ctr_group_free(peer->ctrg);
- peer->ctrg = NULL;
+ OSMO_ASSERT(sgsn->nse)
- talloc_free(peer);
+ _nse_free(sgsn->nse);
+ _sgsn_free(sgsn);
}
-int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci)
+/*! Return the SGSN for a given NSEI
+ * \param[in] cfg The gbproxy configuration
+ * \param[in] nsei The nsei where the SGSN can be reached
+ * \return Returns the matching SGSN or NULL if it couldn't be found
+ */
+struct gbproxy_sgsn *gbproxy_sgsn_by_name(struct gbproxy_config *cfg, const char *name)
{
- int counter = 0;
- struct gbproxy_peer *peer, *tmp;
+ struct gbproxy_sgsn *sgsn;
+ OSMO_ASSERT(cfg);
- llist_for_each_entry_safe(peer, tmp, &cfg->bts_peers, list) {
- if (peer->nsei != nsei)
- continue;
- if (bvci && peer->bvci != bvci)
- continue;
+ llist_for_each_entry(sgsn, &cfg->sgsns, list) {
+ if (!strcmp(sgsn->name, name))
+ return sgsn;
+ }
- gbproxy_peer_free(peer);
- counter += 1;
+ return NULL;
+}
+
+/*! Return the SGSN for a given NSEI
+ * \param[in] cfg The gbproxy configuration
+ * \param[in] nsei The nsei where the SGSN can be reached
+ * \return Returns the matching SGSN or NULL if it couldn't be found
+ */
+struct gbproxy_sgsn *gbproxy_sgsn_by_nsei(struct gbproxy_config *cfg, uint16_t nsei)
+{
+ struct gbproxy_sgsn *sgsn;
+ OSMO_ASSERT(cfg);
+
+ llist_for_each_entry(sgsn, &cfg->sgsns, list) {
+ if (sgsn->nse->nsei == nsei)
+ return sgsn;
}
- return counter;
+ return NULL;
+}
+
+/*! Return the SGSN for a given NSEI, creating a new one if none exists
+ * \param[in] cfg The gbproxy configuration
+ * \param[in] nsei The nsei where the SGSN can be reached
+ * \return Returns the SGSN
+ */
+struct gbproxy_sgsn *gbproxy_sgsn_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei)
+{
+ struct gbproxy_sgsn *sgsn;
+ OSMO_ASSERT(cfg);
+
+ sgsn = gbproxy_sgsn_by_nsei(cfg, nsei);
+ if (!sgsn)
+ sgsn = gbproxy_sgsn_alloc(cfg, nsei, NULL);
+
+ return sgsn;
+}
+
+/*! Return the gbproxy_sgsn matching that NRI
+ * \param[in] cfg proxy in which we operate
+ * \param[in] nri NRI to look for
+ * \param[out] null_nri If not NULL this indicates whether the NRI is a null NRI
+ * \return The SGSN this NRI has been added to, NULL if no matching SGSN could be found
+ */
+struct gbproxy_sgsn *gbproxy_sgsn_by_nri(struct gbproxy_config *cfg, uint16_t nri, bool *null_nri)
+{
+ struct gbproxy_sgsn *sgsn;
+ OSMO_ASSERT(cfg);
+
+ llist_for_each_entry(sgsn, &cfg->sgsns, list) {
+ if (osmo_nri_v_matches_ranges(nri, sgsn->pool.nri_ranges)) {
+ /* Also check if the NRI we're looking for is a NULL NRI */
+ if (null_nri) {
+ if (osmo_nri_v_matches_ranges(nri, cfg->pool.null_nri_ranges))
+ *null_nri = true;
+ else
+ *null_nri = false;
+ }
+ return sgsn;
+ }
+ }
+
+ return NULL;
+}
+
+/*! Seleect a pseudo-random SGSN for a given TLLI, ignoring any SGSN that is not accepting connections
+ * \param[in] cfg The gbproxy configuration
+ * \param[in] sgsn_avoid If not NULL then avoid this SGSN when selecting a new one. Use for load redistribution
+ * \param[in] tlli The tlli to choose an SGSN for. The same tlli will map to the same SGSN as long as no SGSN is
+ * added/removed or allow_attach changes.
+ * \return Returns the sgsn on success, NULL if no SGSN that allows new connections could be found
+ */
+struct gbproxy_sgsn *gbproxy_sgsn_by_tlli(struct gbproxy_config *cfg, struct gbproxy_sgsn *sgsn_avoid,
+ uint32_t tlli)
+{
+ uint32_t i = 0;
+ uint32_t index, num_sgsns;
+ OSMO_ASSERT(cfg);
+
+ struct gbproxy_sgsn *sgsn = cfg->pool.nsf_override;
+
+ if (sgsn) {
+ LOGPSGSN(sgsn, LOGL_DEBUG, "Node selection function is overridden by config\n");
+ return sgsn;
+ }
+
+ /* TODO: We should keep track of count in cfg */
+ num_sgsns = llist_count(&cfg->sgsns);
+
+ if (num_sgsns == 0)
+ return NULL;
+
+ /* FIXME: 256 SGSNs ought to be enough for everyone */
+ index = hash_32(tlli, 8) % num_sgsns;
+
+ /* Get the first enabled SGSN after index */
+ llist_for_each_entry(sgsn, &cfg->sgsns, list) {
+ if (i >= index && sgsn->pool.allow_attach) {
+ return sgsn;
+ }
+ i++;
+ }
+ /* Start again from the beginning */
+ i = 0;
+ llist_for_each_entry(sgsn, &cfg->sgsns, list) {
+ if (i >= index) {
+ break;
+ } else if (sgsn->pool.allow_attach) {
+ return sgsn;
+ }
+ i++;
+ }
+
+ return NULL;
}
diff --git a/src/gbproxy/gb_proxy_tlli.c b/src/gbproxy/gb_proxy_tlli.c
deleted file mode 100644
index e9271c22..00000000
--- a/src/gbproxy/gb_proxy_tlli.c
+++ /dev/null
@@ -1,725 +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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <osmocom/gsm/gsm48.h>
-
-#include <osmocom/sgsn/gb_proxy.h>
-
-#include <osmocom/sgsn/gprs_utils.h>
-#include <osmocom/sgsn/gprs_gb_parse.h>
-
-#include <osmocom/sgsn/debug.h>
-
-#include <osmocom/gsm/gsm_utils.h>
-
-#include <osmocom/core/rate_ctr.h>
-#include <osmocom/core/talloc.h>
-
-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 = false;
- tlli_state->net_validated = false;
-}
-
-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 = true;
- else
- tlli_state->bss_validated = true;
-
- 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 = true;
-
- 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];
-}
-
-static 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) {
- struct osmo_mobile_identity mi;
- if (osmo_mobile_identity_decode(&mi, parse_ctx->imsi, parse_ctx->imsi_len, false)
- || mi.type != GSM_MI_TYPE_IMSI) {
- LOGP(DGPRS, LOGL_ERROR, "Failed to decode Mobile Identity\n");
- } else {
- LOGP(DGPRS, LOGL_INFO,
- "Removing TLLI %08x from list (IMSI %s re-used)\n",
- other_link_info->tlli.current, mi.imsi);
- 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 ? true : false;
- }
-}
-
-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 = false;
-
- 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 = false;
-
- 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/gbproxy/gb_proxy_vty.c b/src/gbproxy/gb_proxy_vty.c
index 355b23fb..7ae65d20 100644
--- a/src/gbproxy/gb_proxy_vty.c
+++ b/src/gbproxy/gb_proxy_vty.c
@@ -25,12 +25,18 @@
#include <time.h>
#include <inttypes.h>
+#include <osmocom/core/hashtable.h>
#include <osmocom/core/talloc.h>
+#include <osmocom/core/timer.h>
#include <osmocom/core/rate_ctr.h>
-#include <osmocom/gsm/gsm48.h>
+#include <osmocom/core/utils.h>
+
+#include <osmocom/gprs/gprs_ns2.h>
+#include <osmocom/gprs/bssgp_bvc_fsm.h>
-#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gsm/apn.h>
+#include <osmocom/gsm/gsm23236.h>
+#include <osmocom/gsm/gsm48.h>
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/gb_proxy.h>
@@ -38,9 +44,23 @@
#include <osmocom/sgsn/vty.h>
#include <osmocom/vty/command.h>
+#include <osmocom/vty/logging.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/misc.h>
+#define GBPROXY_STR "Display information about the Gb proxy\n"
+#define NRI_STR "Mapping of Network Resource Indicators to this SGSN, for SGSN pooling\n"
+#define NULL_NRI_STR "Define NULL-NRI values that cause re-assignment of an MS to a different SGSN, for SGSN pooling.\n"
+#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \
+ "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \
+ " first value; if omitted, apply only the first value.\n"
+#define NRI_ARGS_TO_STR_FMT "%s%s%s"
+#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""
+#define NRI_WARN(SGSN, FORMAT, args...) do { \
+ vty_out(vty, "%% Warning: NSE(%05d/SGSN): " FORMAT "%s", (SGSN)->nse->nsei, ##args, VTY_NEWLINE); \
+ LOGP(DLBSSGP, LOGL_ERROR, "NSE(%05d/SGSN): " FORMAT "\n", (SGSN)->nse->nsei, ##args); \
+ } while (0)
+
static struct gbproxy_config *g_cfg = NULL;
/*
@@ -52,91 +72,77 @@ static struct cmd_node gbproxy_node = {
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 void gbprox_vty_print_bvc(struct vty *vty, struct gbproxy_bvc *bvc)
+{
-static const struct value_string match_ids[] = {
- {GBPROX_MATCH_PATCHING, "patching"},
- {GBPROX_MATCH_ROUTING, "routing"},
- {0, NULL}
-};
+ if (bvc->bvci == 0) {
+ vty_out(vty, "NSEI %5u, SIG-BVCI %5u [%s]%s", bvc->nse->nsei, bvc->bvci,
+ osmo_fsm_inst_state_name(bvc->fi), VTY_NEWLINE);
+ } else {
+ struct gprs_ra_id raid;
+ gsm48_parse_ra(&raid, bvc->ra);
+ vty_out(vty, "NSEI %5u, PTP-BVCI %5u, RAI %s [%s]%s", bvc->nse->nsei, bvc->bvci,
+ osmo_rai_name(&raid), osmo_fsm_inst_state_name(bvc->fi), VTY_NEWLINE);
+ }
+}
-static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer)
+static void gbproxy_vty_print_nse(struct vty *vty, struct gbproxy_nse *nse, bool show_stats)
{
- struct gprs_ra_id raid;
- gsm48_parse_ra(&raid, peer->ra);
+ struct gbproxy_bvc *bvc;
+ int j;
- vty_out(vty, "NSEI %5u, PTP-BVCI %5u, "
- "RAI %s", peer->nsei, peer->bvci, osmo_rai_name(&raid));
- if (peer->blocked)
- vty_out(vty, " [BVC-BLOCKED]");
+ hash_for_each(nse->bvcs, j, bvc, list) {
+ gbprox_vty_print_bvc(vty, bvc);
- vty_out(vty, "%s", VTY_NEWLINE);
+ if (show_stats)
+ vty_out_rate_ctr_group(vty, " ", bvc->ctrg);
+ }
}
-static int config_write_gbproxy(struct vty *vty)
+static void gbproxy_vty_print_cell(struct vty *vty, struct gbproxy_cell *cell, bool show_stats)
{
- enum gbproxy_match_id match_id;
+ struct gprs_ra_id raid;
+ gsm48_parse_ra(&raid, cell->ra);
+ unsigned int num_sgsn_bvc = 0;
+ unsigned int i;
- vty_out(vty, "gbproxy%s", VTY_NEWLINE);
+ vty_out(vty, "BVCI %5u RAI %s: ", cell->bvci, osmo_rai_name(&raid));
+ if (cell->bss_bvc)
+ vty_out(vty, "BSS NSEI %5u, SGSN NSEI ", cell->bss_bvc->nse->nsei);
+ else
+ vty_out(vty, "BSS NSEI <none>, SGSN NSEI ");
- vty_out(vty, " sgsn nsei %u%s", g_cfg->nsip_sgsn_nsei,
- VTY_NEWLINE);
-
- if (g_cfg->core_plmn.mcc > 0)
- vty_out(vty, " core-mobile-country-code %s%s",
- osmo_mcc_name(g_cfg->core_plmn.mcc), VTY_NEWLINE);
- if (g_cfg->core_plmn.mnc > 0)
- vty_out(vty, " core-mobile-network-code %s%s",
- osmo_mnc_name(g_cfg->core_plmn.mnc, g_cfg->core_plmn.mnc_3_digits), 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);
+ for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) {
+ struct gbproxy_bvc *sgsn_bvc = cell->sgsn_bvc[i];
+ if (sgsn_bvc) {
+ vty_out(vty, "%5u ", sgsn_bvc->nse->nsei);
+ num_sgsn_bvc++;
+ }
}
+ if (num_sgsn_bvc)
+ vty_out(vty, "%s", VTY_NEWLINE);
+ else
+ vty_out(vty, "<none>%s", 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);
- }
- }
+static int config_write_gbproxy(struct vty *vty)
+{
+ struct osmo_nri_range *r;
- if (g_cfg->route_to_sgsn2)
- vty_out(vty, " secondary-sgsn nsei %u%s", g_cfg->nsip_sgsn2_nsei,
- VTY_NEWLINE);
+ vty_out(vty, "gbproxy%s", VTY_NEWLINE);
- if (g_cfg->clean_stale_timer_freq > 0)
- vty_out(vty, " link-list clean-stale-timer %u%s",
- g_cfg->clean_stale_timer_freq, 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);
- if (g_cfg->stored_msgs_max_len > 0)
- vty_out(vty, " link stored-msgs-max-length %"PRIu32"%s",
- g_cfg->stored_msgs_max_len, VTY_NEWLINE);
+ if (g_cfg->pool.bvc_fc_ratio != 100)
+ vty_out(vty, " pool bvc-flow-control-ratio %u%s", g_cfg->pool.bvc_fc_ratio, VTY_NEWLINE);
+ if (g_cfg->pool.nri_bitlen != OSMO_NRI_BITLEN_DEFAULT)
+ vty_out(vty, " nri bitlen %u%s", g_cfg->pool.nri_bitlen, VTY_NEWLINE);
+ llist_for_each_entry(r, &g_cfg->pool.null_nri_ranges->entries, entry) {
+ vty_out(vty, " nri null add %d", r->first);
+ if (r->first != r->last)
+ vty_out(vty, " %d", r->last);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
return CMD_SUCCESS;
}
@@ -149,470 +155,471 @@ DEFUN(cfg_gbproxy,
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]);
+/* VTY code for SGSN (pool) configuration */
+extern const struct bssgp_bvc_fsm_ops sgsn_sig_bvc_fsm_ops;
+#include <osmocom/gprs/protocol/gsm_08_18.h>
- 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;
- }
+static struct cmd_node sgsn_node = {
+ SGSN_NODE,
+ "%s(config-sgsn)# ",
+ 1,
+};
- g_cfg->nsip_sgsn_nsei = nsei;
- return CMD_SUCCESS;
-}
+static void sgsn_write_nri(struct vty *vty, struct gbproxy_sgsn *sgsn, bool verbose)
+{
+ struct osmo_nri_range *r;
-#define GBPROXY_CORE_MNC_STR "Use this network code for the core network\n"
+ if (verbose) {
+ vty_out(vty, "sgsn nsei %d%s", sgsn->nse->nsei, VTY_NEWLINE);
+ if (llist_empty(&sgsn->pool.nri_ranges->entries)) {
+ vty_out(vty, " %% no NRI mappings%s", VTY_NEWLINE);
+ return;
+ }
+ }
-DEFUN(cfg_gbproxy_core_mnc,
- cfg_gbproxy_core_mnc_cmd,
- "core-mobile-network-code <1-999>",
- GBPROXY_CORE_MNC_STR "NCC value\n")
-{
- uint16_t mnc;
- bool mnc_3_digits;
- if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
- vty_out(vty, "%% Invalid MNC: %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
+ llist_for_each_entry(r, &sgsn->pool.nri_ranges->entries, entry) {
+ if (osmo_nri_range_validate(r, 255))
+ vty_out(vty, " %% INVALID RANGE:");
+ vty_out(vty, " nri add %d", r->first);
+ if (r->first != r->last)
+ vty_out(vty, " %d", r->last);
+ vty_out(vty, "%s", VTY_NEWLINE);
}
- g_cfg->core_plmn.mnc = mnc;
- g_cfg->core_plmn.mnc_3_digits = mnc_3_digits;
- 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)
+static void write_sgsn(struct vty *vty, struct gbproxy_sgsn *sgsn)
{
- g_cfg->core_plmn.mnc = 0;
- g_cfg->core_plmn.mnc_3_digits = false;
- return CMD_SUCCESS;
+ vty_out(vty, "sgsn nsei %u%s", sgsn->nse->nsei, VTY_NEWLINE);
+ vty_out(vty, " name %s%s", sgsn->name, VTY_NEWLINE);
+ vty_out(vty, " %sallow-attach%s", sgsn->pool.allow_attach ? "" : "no ", VTY_NEWLINE);
+ sgsn_write_nri(vty, sgsn, false);
}
-#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")
+static int config_write_sgsn(struct vty *vty)
{
- g_cfg->core_plmn.mcc = atoi(argv[0]);
- return CMD_SUCCESS;
-}
+ struct gbproxy_sgsn *sgsn;
+
+ llist_for_each_entry(sgsn, &g_cfg->sgsns, list)
+ write_sgsn(vty, sgsn);
-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_plmn.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")
+DEFUN(cfg_sgsn_nsei,
+ cfg_sgsn_nsei_cmd,
+ "sgsn nsei <0-65534>",
+ "Configure the SGSN\n"
+ "NSEI to be used in the connection with the SGSN\n"
+ "The NSEI\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);
+ uint32_t features = 0; // FIXME: make configurable
+ unsigned int nsei = atoi(argv[0]);
+ unsigned int num_sgsn = llist_count(&g_cfg->sgsns);
+ struct gbproxy_sgsn *sgsn;
+ struct gbproxy_nse *nse;
+ struct gbproxy_bvc *bvc;
+
+ if (num_sgsn >= GBPROXY_MAX_NR_SGSN) {
+ vty_out(vty, "%% Too many SGSN NSE defined (%d), increase GBPROXY_MAX_NR_SGSN%s",
+ num_sgsn, VTY_NEWLINE);
return CMD_WARNING;
}
- g_cfg->acquire_imsi = true;
+ /* This will have created the gbproxy_nse as well */
+ sgsn = gbproxy_sgsn_by_nsei_or_new(g_cfg, nsei);
+ if (!sgsn)
+ goto free_nothing;
+ nse = sgsn->nse;
+ if (num_sgsn > 1 && g_cfg->pool.nri_bitlen == 0)
+ vty_out(vty, "%% Multiple SGSNs defined, but no pooling enabled%s", VTY_NEWLINE);
+
+
+ if (!gbproxy_bvc_by_bvci(nse, 0)) {
+ uint8_t cause = BSSGP_CAUSE_OML_INTERV;
+ bvc = gbproxy_bvc_alloc(nse, 0);
+ if (!bvc)
+ goto free_sgsn;
+ bvc->fi = bssgp_bvc_fsm_alloc_sig_bss(bvc, nse->cfg->nsi, nsei, features);
+ if (!bvc->fi)
+ goto free_bvc;
+ bssgp_bvc_fsm_set_ops(bvc->fi, &sgsn_sig_bvc_fsm_ops, bvc);
+ osmo_fsm_inst_dispatch(bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause);
+ }
+ vty->node = SGSN_NODE;
+ vty->index = sgsn;
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 = false;
-
- return CMD_SUCCESS;
+free_bvc:
+ gbproxy_bvc_free(bvc);
+free_sgsn:
+ gbproxy_sgsn_free(sgsn);
+free_nothing:
+ vty_out(vty, "%% Unable to create NSE for NSEI=%05u%s", nsei, VTY_NEWLINE);
+ return CMD_WARNING;
}
-#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)
+DEFUN(cfg_sgsn_name,
+ cfg_sgsn_name_cmd,
+ "name NAME",
+ "Configure the SGSN\n"
+ "Name the SGSN\n"
+ "The name\n")
{
- int apn_len;
+ struct gbproxy_sgsn *sgsn = vty->index;
+ const char *name = argv[0];
- 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);
+ osmo_talloc_replace_string(sgsn, &sgsn->name, name);
+ if (!sgsn->name) {
+ vty_out(vty, "%% Unable to set name for SGSN with nsei %05u%s", sgsn->nse->nsei, 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)
+DEFUN_ATTR(cfg_sgsn_nri_add, cfg_sgsn_nri_add_cmd,
+ "nri add <0-32767> [<0-32767>]",
+ NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR,
+ CMD_ATTR_IMMEDIATE)
{
- return set_core_apn(vty, NULL);
-}
+ struct gbproxy_sgsn *sgsn = vty->index;
+ struct gbproxy_sgsn *other_sgsn;
+ bool before;
+ int rc;
+ const char *message;
+ struct osmo_nri_range add_range;
-/* 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"
+ rc = osmo_nri_ranges_vty_add(&message, &add_range, sgsn->pool.nri_ranges, argc, argv, g_cfg->pool.nri_bitlen);
+ if (message) {
+ NRI_WARN(sgsn, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
-DEFUN(cfg_gbproxy_patch_ptmsi,
- cfg_gbproxy_patch_ptmsi_cmd,
- "patch-ptmsi",
- GBPROXY_PATCH_PTMSI_STR)
-{
- g_cfg->patch_ptmsi = true;
+ /* Issue a warning about NRI range overlaps (but still allow them).
+ * Overlapping ranges will map to whichever SGSN comes fist in the gbproxy_config->sgsns llist,
+ * which should be the first one defined in the config */
+ before = true;
+ llist_for_each_entry(other_sgsn, &g_cfg->sgsns, list) {
+ if (other_sgsn == sgsn) {
+ before = false;
+ continue;
+ }
+ if (osmo_nri_range_overlaps_ranges(&add_range, other_sgsn->pool.nri_ranges)) {
+ uint16_t nsei = sgsn->nse->nsei;
+ uint16_t other_nsei = other_sgsn->nse->nsei;
+ NRI_WARN(sgsn, "NRI range [%d..%d] overlaps between NSE %05d and NSE %05d."
+ " For overlaps, NSE %05d has higher priority than NSE %05d",
+ add_range.first, add_range.last, nsei, other_nsei,
+ before ? other_nsei : nsei, before ? nsei : other_nsei);
+ }
+ }
return CMD_SUCCESS;
}
-DEFUN(cfg_gbproxy_no_patch_ptmsi,
- cfg_gbproxy_no_patch_ptmsi_cmd,
- "no patch-ptmsi",
- NO_STR GBPROXY_PATCH_PTMSI_STR)
+DEFUN_ATTR(cfg_sgsn_nri_del, cfg_sgsn_nri_del_cmd,
+ "nri del <0-32767> [<0-32767>]",
+ NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR,
+ CMD_ATTR_IMMEDIATE)
{
- g_cfg->patch_ptmsi = false;
+ struct gbproxy_sgsn *sgsn = vty->index;
+ int rc;
+ const char *message;
+ rc = osmo_nri_ranges_vty_del(&message, NULL, sgsn->pool.nri_ranges, argc, argv);
+ if (message) {
+ NRI_WARN(sgsn, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
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)
+DEFUN_ATTR(cfg_sgsn_allow_attach, cfg_sgsn_allow_attach_cmd,
+ "allow-attach",
+ "Allow this SGSN to attach new subscribers (default).\n",
+ CMD_ATTR_IMMEDIATE)
{
- g_cfg->acquire_imsi = true;
-
+ struct gbproxy_sgsn *sgsn = vty->index;
+ sgsn->pool.allow_attach = true;
return CMD_SUCCESS;
}
-DEFUN(cfg_gbproxy_no_acquire_imsi,
- cfg_gbproxy_no_acquire_imsi_cmd,
- "no acquire-imsi",
- NO_STR GBPROXY_ACQUIRE_IMSI_STR)
+DEFUN_ATTR(cfg_sgsn_no_allow_attach, cfg_sgsn_no_allow_attach_cmd,
+ "no allow-attach",
+ NO_STR
+ "Do not assign new subscribers to this MSC."
+ " Useful if an MSC in an MSC pool is configured to off-load subscribers."
+ " The MSC will still be operational for already IMSI-Attached subscribers,"
+ " but the NAS node selection function will skip this MSC for new subscribers\n",
+ CMD_ATTR_IMMEDIATE)
{
- g_cfg->acquire_imsi = false;
-
+ struct gbproxy_sgsn *sgsn = vty->index;
+ sgsn->pool.allow_attach = false;
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")
+DEFUN(sgsn_show_nri_all, show_nri_all_cmd,
+ "show nri all",
+ SHOW_STR NRI_STR "Show all SGSNs\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 = true;
- g_cfg->nsip_sgsn2_nsei = nsei;
+ struct gbproxy_sgsn *sgsn;
- g_cfg->patch_ptmsi = true;
+ llist_for_each_entry(sgsn, &g_cfg->sgsns, list)
+ sgsn_write_nri(vty, sgsn, true);
return CMD_SUCCESS;
}
-DEFUN(cfg_gbproxy_no_secondary_sgsn,
- cfg_gbproxy_no_secondary_sgsn_cmd,
- "no secondary-sgsn",
- NO_STR GBPROXY_SECOND_SGSN_STR)
+DEFUN(show_nri_nsei, show_nri_nsei_cmd,
+ "show nri nsei <0-65535>",
+ SHOW_STR NRI_STR "Identify SGSN by NSEI\n"
+ "NSEI of the SGSN\n")
{
- g_cfg->route_to_sgsn2 = false;
- g_cfg->nsip_sgsn2_nsei = 0xFFFF;
+ struct gbproxy_sgsn *sgsn;
+ int nsei = atoi(argv[0]);
- g_cfg->patch_ptmsi = false;
+ sgsn = gbproxy_sgsn_by_nsei(g_cfg, nsei);
+ if (!sgsn) {
+ vty_out(vty, "%% No SGSN with found for NSEI %05d%s", nsei, VTY_NEWLINE);
+ return CMD_SUCCESS;
+ }
+ sgsn_write_nri(vty, sgsn, true);
return CMD_SUCCESS;
}
-#define GBPROXY_LINK_LIST_STR "Set TLLI list parameters\n"
-#define GBPROXY_LINK_STR "Set TLLI parameters\n"
-
-#define GBPROXY_CLEAN_STALE_TIMER_STR "Periodic timer to clean stale links\n"
-
-DEFUN(cfg_gbproxy_link_list_clean_stale_timer,
- cfg_gbproxy_link_list_clean_stale_timer_cmd,
- "link-list clean-stale-timer <1-999999>",
- GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR
- "Frequency at which the periodic timer is fired (in seconds)\n")
+DEFUN(cfg_pool_bvc_fc_ratio,
+ cfg_pool_bvc_fc_ratio_cmd,
+ "pool bvc-flow-control-ratio <1-100>",
+ "SGSN Pool related configuration\n"
+ "Ratio of BSS-advertised bucket size + leak rate advertised to each SGSN\n"
+ "Ratio of BSS-advertised bucket size + leak rate advertised to each SGSN (Percent)\n")
{
- struct gbproxy_peer *peer;
- g_cfg->clean_stale_timer_freq = (unsigned int) atoi(argv[0]);
-
- /* Re-schedule running timers soon in case prev frequency was really big
- and new frequency is desired to be lower. After initial run, periodic
- time is used. Use random() to avoid firing timers for all peers at
- the same time */
- llist_for_each_entry(peer, &g_cfg->bts_peers, list)
- osmo_timer_schedule(&peer->clean_stale_timer,
- random() % 5, random() % 1000000);
-
+ g_cfg->pool.bvc_fc_ratio = atoi(argv[0]);
return CMD_SUCCESS;
}
-
-DEFUN(cfg_gbproxy_link_list_no_clean_stale_timer,
- cfg_gbproxy_link_list_no_clean_stale_timer_cmd,
- "no link-list clean-stale-timer",
- NO_STR GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR)
-
+DEFUN_ATTR(cfg_gbproxy_nri_bitlen,
+ cfg_gbproxy_nri_bitlen_cmd,
+ "nri bitlen <0-15>",
+ NRI_STR
+ "Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet).\n"
+ "bit count (0 disables) pooling)\n",
+ CMD_ATTR_IMMEDIATE)
{
- struct gbproxy_peer *peer;
- g_cfg->clean_stale_timer_freq = 0;
+ g_cfg->pool.nri_bitlen = atoi(argv[0]);
+
+ if (llist_count(&g_cfg->sgsns) > 1 && g_cfg->pool.nri_bitlen == 0)
+ vty_out(vty, "%% Pooling disabled, but multiple SGSNs defined%s", VTY_NEWLINE);
- llist_for_each_entry(peer, &g_cfg->bts_peers, list)
- osmo_timer_del(&peer->clean_stale_timer);
+ /* TODO: Verify all nri ranges and warn on mismatch */
return CMD_SUCCESS;
}
-#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")
+DEFUN_ATTR(cfg_gbproxy_nri_null_add,
+ cfg_gbproxy_nri_null_add_cmd,
+ "nri null add <0-32767> [<0-32767>]",
+ NRI_STR NULL_NRI_STR "Add NULL-NRI value (or range)\n"
+ NRI_FIRST_LAST_STR,
+ CMD_ATTR_IMMEDIATE)
{
- g_cfg->tlli_max_age = atoi(argv[0]);
+ int rc;
+ const char *message;
+ rc = osmo_nri_ranges_vty_add(&message, NULL, g_cfg->pool.null_nri_ranges, argc, argv,
+ g_cfg->pool.nri_bitlen);
+ if (message) {
+ vty_out(vty, "%% nri null add: %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv),
+ VTY_NEWLINE);
+ vty_out(vty, "%s: \n" NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
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)
+DEFUN_ATTR(cfg_gbproxy_nri_null_del,
+ cfg_gbproxy_nri_null_del_cmd,
+ "nri null del <0-32767> [<0-32767>]",
+ NRI_STR NULL_NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR,
+ CMD_ATTR_IMMEDIATE)
{
- g_cfg->tlli_max_age = 0;
-
+ int rc;
+ const char *message;
+ rc = osmo_nri_ranges_vty_del(&message, NULL, g_cfg->pool.null_nri_ranges, argc, argv);
+ if (message) {
+ vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv),
+ VTY_NEWLINE);
+ }
+ if (rc < 0)
+ return CMD_WARNING;
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")
+static void log_set_bvc_filter(struct log_target *target,
+ const uint16_t *bvci)
{
- g_cfg->tlli_max_len = atoi(argv[0]);
-
- return CMD_SUCCESS;
+ if (bvci) {
+ uintptr_t bvci_filter = *bvci | BVC_LOG_CTX_FLAG;
+ target->filter_map |= (1 << LOG_FLT_GB_BVC);
+ target->filter_data[LOG_FLT_GB_BVC] = (void *)bvci_filter;
+ } else if (target->filter_data[LOG_FLT_GB_BVC]) {
+ target->filter_map = ~(1 << LOG_FLT_GB_BVC);
+ target->filter_data[LOG_FLT_GB_BVC] = NULL;
+ }
}
-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)
+DEFUN(logging_fltr_bvc,
+ logging_fltr_bvc_cmd,
+ "logging filter bvc bvci <0-65535>",
+ LOGGING_STR FILTER_STR
+ "Filter based on BSSGP VC\n"
+ "Identify BVC by BVCI\n"
+ "Numeric identifier\n")
{
- g_cfg->tlli_max_len = 0;
+ struct log_target *tgt;
+ uint16_t id = atoi(argv[0]);
+
+ log_tgt_mutex_lock();
+ tgt = osmo_log_vty2tgt(vty);
+ if (!tgt) {
+ log_tgt_mutex_unlock();
+ return CMD_WARNING;
+ }
+ log_set_bvc_filter(tgt, &id);
+ log_tgt_mutex_unlock();
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")
+DEFUN(show_gbproxy_bvc, show_gbproxy_bvc_cmd, "show gbproxy bvc (bss|sgsn) [stats]",
+ SHOW_STR GBPROXY_STR
+ "Show BSSGP Virtual Connections\n"
+ "Display BSS-side BVCs\n"
+ "Display SGSN-side BVCs\n"
+ "Show statistics\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;
+ struct gbproxy_nse *nse;
+ bool show_stats = argc >= 2;
+ int i;
+
+ if (show_stats)
+ vty_out_rate_ctr_group(vty, "", g_cfg->ctrg);
+ if (!strcmp(argv[0], "bss")) {
+ hash_for_each(g_cfg->bss_nses, i, nse, list)
+ gbproxy_vty_print_nse(vty, nse, show_stats);
+ } else {
+ hash_for_each(g_cfg->sgsn_nses, i, nse, list)
+ gbproxy_vty_print_nse(vty, nse, show_stats);
+ }
return CMD_SUCCESS;
}
-DEFUN(cfg_gbproxy_link_stored_msgs_max_len,
- cfg_gbproxy_link_stored_msgs_max_len_cmd,
- "link stored-msgs-max-length <1-99999>",
- GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR
- "Maximum number of msgb stored in the logical link waiting to acquire its IMSI\n")
+DEFUN(show_gbproxy_cell, show_gbproxy_cell_cmd, "show gbproxy cell [stats]",
+ SHOW_STR GBPROXY_STR
+ "Show GPRS Cell Information\n"
+ "Show statistics\n")
{
- g_cfg->stored_msgs_max_len = (uint32_t) atoi(argv[0]);
+ struct gbproxy_cell *cell;
+ bool show_stats = argc >= 1;
+ int i;
+
+ hash_for_each(g_cfg->cells, i, cell, list)
+ gbproxy_vty_print_cell(vty, cell, show_stats);
return CMD_SUCCESS;
}
-DEFUN(cfg_gbproxy_link_no_stored_msgs_max_len,
- cfg_gbproxy_link_no_stored_msgs_max_len_cmd,
- "no link stored-msgs-max-length",
- NO_STR GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR)
+DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
+ SHOW_STR GBPROXY_STR "Show logical links\n")
{
- g_cfg->stored_msgs_max_len = 0;
+ struct gbproxy_nse *nse;
+ int i, j;
+ hash_for_each(g_cfg->bss_nses, i, nse, list) {
+ struct gbproxy_bvc *bvc;
+ hash_for_each(nse->bvcs, j, bvc, list) {
+ gbprox_vty_print_bvc(vty, bvc);
+ }
+ }
return CMD_SUCCESS;
}
-
-DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]",
- SHOW_STR "Display information about the Gb proxy\n" "Show statistics\n")
+DEFUN(show_gbproxy_tlli_cache, show_gbproxy_tlli_cache_cmd,
+ "show gbproxy tlli-cache",
+ SHOW_STR GBPROXY_STR "Show TLLI cache entries\n")
{
- struct gbproxy_peer *peer;
- int show_stats = argc >= 1;
+ struct gbproxy_tlli_cache_entry *entry;
+ struct timespec now;
+ time_t expiry;
+ int i, count = 0;
- if (show_stats)
- vty_out_rate_ctr_group(vty, "", g_cfg->ctrg);
+ osmo_clock_gettime(CLOCK_MONOTONIC, &now);
+ expiry = now.tv_sec - g_cfg->tlli_cache.timeout;
- llist_for_each_entry(peer, &g_cfg->bts_peers, list) {
- gbprox_vty_print_peer(vty, peer);
+ vty_out(vty, "TLLI cache timeout %us%s", g_cfg->tlli_cache.timeout, VTY_NEWLINE);
+ hash_for_each(g_cfg->tlli_cache.entries, i, entry, list) {
+ time_t valid = entry->tstamp - expiry;
+ struct gbproxy_nse *nse = entry->nse;
- if (show_stats)
- vty_out_rate_ctr_group(vty, " ", peer->ctrg);
+ vty_out(vty, " TLLI %08x -> NSE(%05u/%s) valid %lds%s", entry->tlli, nse->nsei,
+ nse->sgsn_facing ? "SGSN" : "BSS", valid, VTY_NEWLINE);
+ count++;
}
+ vty_out(vty, "TLLI cache contains %u entries%s", count, VTY_NEWLINE);
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;
- time_t now;
- struct timespec ts = {0,};
-
- osmo_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;
- struct osmo_mobile_identity mi;
- const char *imsi_str;
-
- if (link_info->imsi > 0) {
- if (osmo_mobile_identity_decode(&mi, link_info->imsi, link_info->imsi_len, false)
- || mi.type != GSM_MI_TYPE_IMSI)
- imsi_str = "(invalid)";
- else
- imsi_str = mi.imsi;
- } else {
- imsi_str = "(none)";
- }
- vty_out(vty, " TLLI %08x, IMSI %s, AGE %d",
- link_info->tlli.current, imsi_str, (int)age);
-
- if (link_info->stored_msgs_len)
- vty_out(vty, ", STORED %"PRIu32"/%"PRIu32,
- link_info->stored_msgs_len,
- g_cfg->stored_msgs_max_len);
-
- if (g_cfg->route_to_sgsn2)
- vty_out(vty, ", SGSN NSEI %d",
- link_info->sgsn_nsei);
+DEFUN(show_gbproxy_imsi_cache, show_gbproxy_imsi_cache_cmd,
+ "show gbproxy imsi-cache",
+ SHOW_STR GBPROXY_STR "Show IMSI cache entries\n")
+{
+ struct gbproxy_imsi_cache_entry *entry;
+ struct timespec now;
+ time_t expiry;
+ int i, count = 0;
- if (link_info->is_deregistered)
- vty_out(vty, ", DE-REGISTERED");
+ osmo_clock_gettime(CLOCK_MONOTONIC, &now);
+ expiry = now.tv_sec - g_cfg->imsi_cache.timeout;
- vty_out(vty, "%s", VTY_NEWLINE);
- }
+ vty_out(vty, "IMSI cache timeout %us%s", g_cfg->imsi_cache.timeout, VTY_NEWLINE);
+ hash_for_each(g_cfg->imsi_cache.entries, i, entry, list) {
+ time_t valid = entry->tstamp - expiry;
+ struct gbproxy_nse *nse = entry->nse;
+ vty_out(vty, " IMSI %s -> NSE(%05u/%s): valid %lds%s", entry->imsi, nse->nsei,
+ nse->sgsn_facing ? "SGSN" : "BSS", valid, VTY_NEWLINE);
+ count++;
}
+ vty_out(vty, "IMSI cache contains %u entries%s", count, 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"
+ "Delete a GBProxy bvc by NSEI and optionally BVCI\n"
"NSEI number\n"
- "Only delete peer with a matching BVCI\n"
+ "Only delete bvc with a matching BVCI\n"
"BVCI number\n")
{
const uint16_t nsei = atoi(argv[0]);
const uint16_t bvci = atoi(argv[1]);
+ struct gbproxy_nse *nse = gbproxy_nse_by_nsei(g_cfg, nsei, NSE_F_BSS);
int counter;
- counter = gbproxy_cleanup_peers(g_cfg, nsei, bvci);
+ if (!nse) {
+ vty_out(vty, "NSE not found%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ counter = gbproxy_cleanup_bvcs(nse, bvci);
if (counter == 0) {
vty_out(vty, "BVC not found%s", VTY_NEWLINE);
@@ -624,7 +631,7 @@ DEFUN(delete_gb_bvci, delete_gb_bvci_cmd,
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"
+ "Delete a GBProxy bvc by NSEI and optionally BVCI\n"
"NSEI number\n"
"Only delete BSSGP connections (BVC)\n"
"Only delete dynamic NS connections (NS-VC)\n"
@@ -647,18 +654,23 @@ DEFUN(delete_gb_nsei, delete_gb_nsei_cmd,
delete_bvc = delete_nsvc = 1;
if (delete_bvc) {
- if (!dry_run)
- counter = gbproxy_cleanup_peers(g_cfg, nsei, 0);
- else {
- struct gbproxy_peer *peer;
+ if (!dry_run) {
+ struct gbproxy_nse *nse = gbproxy_nse_by_nsei(g_cfg, nsei, NSE_F_BSS);
+ counter = gbproxy_cleanup_bvcs(nse, 0);
+ gbproxy_nse_free(nse);
+ } else {
+ struct gbproxy_nse *nse;
+ struct gbproxy_bvc *bvc;
+ int i, j;
counter = 0;
- llist_for_each_entry(peer, &g_cfg->bts_peers, list) {
- if (peer->nsei != nsei)
+ hash_for_each(g_cfg->bss_nses, i, nse, list) {
+ if (nse->nsei != nsei)
continue;
-
- vty_out(vty, "BVC: ");
- gbprox_vty_print_peer(vty, peer);
- counter += 1;
+ hash_for_each(nse->bvcs, j, bvc, list) {
+ vty_out(vty, "BVC: ");
+ gbprox_vty_print_bvc(vty, bvc);
+ counter += 1;
+ }
}
}
vty_out(vty, "%sDeleted %d BVC%s",
@@ -666,248 +678,87 @@ DEFUN(delete_gb_nsei, delete_gb_nsei_cmd,
}
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);
- }
+ struct gprs_ns2_inst *nsi = g_cfg->nsi;
+ struct gprs_ns2_nse *nse;
- 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;
- 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) {
- struct osmo_mobile_identity mi;
-
- 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;
- if (osmo_mobile_identity_decode(&mi, link_info->imsi, link_info->imsi_len, false)
- || mi.type != GSM_MI_TYPE_IMSI)
- continue;
- if (strcmp(mi.imsi, imsi) != 0)
- continue;
- break;
+ nse = gprs_ns2_nse_by_nsei(nsi, nsei);
+ if (!nse) {
+ vty_out(vty, "NSEI not found%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
- vty_out(vty, "Deleting link with TLLI %08x%s", link_info->tlli.current,
- VTY_NEWLINE);
- gbproxy_delete_link_info(peer, link_info);
- found += 1;
- }
+ /* TODO: We should NOT delete a persistent NSEI/NSVC as soon as we can check for these */
+ if (!dry_run)
+ gprs_ns2_free_nse(nse);
- if (!found && argc >= 2) {
- vty_out(vty, "Didn't find link entry with %s %s%s",
- argv[1], argv[2], VTY_NEWLINE);
+ vty_out(vty, "%sDeleted NS-VCs for NSEI %d%s",
+ dry_run ? "Not " : "", nsei, 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")
+/* Only for ttcn3 testing */
+DEFUN_HIDDEN(sgsn_pool_nsf_fixed, sgsn_pool_nsf_fixed_cmd,
+ "sgsn-pool nsf fixed NAME",
+ "SGSN pooling: load balancing across multiple SGSNs.\n"
+ "Customize the Network Selection Function.\n"
+ "Set a fixed SGSN to use (for testing).\n"
+ "The name of the SGSN to use.\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;
+ const char *name = argv[0];
+ struct gbproxy_sgsn *sgsn = gbproxy_sgsn_by_name(g_cfg, name);
- 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);
+ if (!sgsn) {
+ vty_out(vty, "%% Could not find SGSN with name %s%s", name, VTY_NEWLINE);
return CMD_WARNING;
}
- state = &peer->patch_state;
-
- osmo_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);
-
+ g_cfg->pool.nsf_override = sgsn;
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 = true;
-
- 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")
+DEFUN_HIDDEN(sgsn_pool_nsf_normal, sgsn_pool_nsf_normal_cmd,
+ "sgsn-pool nsf normal",
+ "SGSN pooling: load balancing across multiple SGSNs.\n"
+ "Customize the Network Selection Function.\n"
+ "Reset the NSF back to regular operation (for testing).\n")
{
- g_cfg->tlli_max_len = atoi(argv[0]);
-
+ g_cfg->pool.nsf_override = NULL;
return CMD_SUCCESS;
}
int gbproxy_vty_init(void)
{
- install_element_ve(&show_gbproxy_cmd);
+ install_element_ve(&show_gbproxy_bvc_cmd);
+ install_element_ve(&show_gbproxy_cell_cmd);
install_element_ve(&show_gbproxy_links_cmd);
+ install_element_ve(&show_gbproxy_tlli_cache_cmd);
+ install_element_ve(&show_gbproxy_imsi_cache_cmd);
+ install_element_ve(&show_nri_all_cmd);
+ install_element_ve(&show_nri_nsei_cmd);
+ install_element_ve(&logging_fltr_bvc_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(ENABLE_NODE, &sgsn_pool_nsf_fixed_cmd);
+ install_element(ENABLE_NODE, &sgsn_pool_nsf_normal_cmd);
install_element(CONFIG_NODE, &cfg_gbproxy_cmd);
install_node(&gbproxy_node, config_write_gbproxy);
- 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_clean_stale_timer_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_link_stored_msgs_max_len_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_clean_stale_timer_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);
- install_element(GBPROXY_NODE, &cfg_gbproxy_link_no_stored_msgs_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);
+ install_element(GBPROXY_NODE, &cfg_pool_bvc_fc_ratio_cmd);
+ install_element(GBPROXY_NODE, &cfg_gbproxy_nri_bitlen_cmd);
+ install_element(GBPROXY_NODE, &cfg_gbproxy_nri_null_add_cmd);
+ install_element(GBPROXY_NODE, &cfg_gbproxy_nri_null_del_cmd);
+
+ install_element(CONFIG_NODE, &cfg_sgsn_nsei_cmd);
+ install_node(&sgsn_node, config_write_sgsn);
+ install_element(SGSN_NODE, &cfg_sgsn_name_cmd);
+ install_element(SGSN_NODE, &cfg_sgsn_allow_attach_cmd);
+ install_element(SGSN_NODE, &cfg_sgsn_no_allow_attach_cmd);
+ install_element(SGSN_NODE, &cfg_sgsn_nri_add_cmd);
+ install_element(SGSN_NODE, &cfg_sgsn_nri_del_cmd);
+
return 0;
}
diff --git a/src/gprs/gprs_gb_parse.c b/src/gprs/gprs_gb_parse.c
index e5de4d4c..e6a82acb 100644
--- a/src/gprs/gprs_gb_parse.c
+++ b/src/gprs/gprs_gb_parse.c
@@ -437,6 +437,47 @@ int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len,
return gprs_gb_parse_dtap(ghp->data, ghp->data_len, parse_ctx);
}
+/*! Determine the TLLI from the given BSSGP message.
+ * \param[in] bssgp pointer to start of BSSGP header
+ * \param[in] bssgp_len length of BSSGP message in octets
+ * \param[out] tlli TLLI (if any) in host byte order
+ * \returns 1 if TLLI found; 0 if none found; negative on parse error */
+int gprs_gb_parse_tlli(const uint8_t *bssgp, size_t bssgp_len, uint32_t *tlli)
+{
+ const struct bssgp_normal_hdr *bgph;
+ uint8_t pdu_type;
+
+ if (bssgp_len < sizeof(struct bssgp_normal_hdr))
+ return -EINVAL;
+
+ bgph = (struct bssgp_normal_hdr *)bssgp;
+ pdu_type = bgph->pdu_type;
+
+ if (pdu_type == BSSGP_PDUT_UL_UNITDATA ||
+ pdu_type == BSSGP_PDUT_DL_UNITDATA) {
+ const struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *)bssgp;
+ if (bssgp_len < sizeof(struct bssgp_ud_hdr))
+ return -EINVAL;
+ *tlli = osmo_load32be((const uint8_t *)&budh->tlli);
+ return 1;
+ } else {
+ const uint8_t *data = bgph->data;
+ size_t data_len = bssgp_len - sizeof(*bgph);
+ struct tlv_parsed tp;
+
+ if (bssgp_tlv_parse(&tp, data, data_len) < 0)
+ return -EINVAL;
+
+ if (TLVP_PRESENT(&tp, BSSGP_IE_TLLI)) {
+ *tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI));
+ return 1;
+ }
+ }
+
+ /* No TLLI present in message */
+ return 0;
+}
+
int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len,
struct gprs_gb_parse_context *parse_ctx)
{
diff --git a/src/gprs/gprs_utils.c b/src/gprs/gprs_utils.c
index 13641c1e..632718aa 100644
--- a/src/gprs/gprs_utils.c
+++ b/src/gprs/gprs_utils.c
@@ -22,7 +22,7 @@
#include <osmocom/sgsn/gprs_utils.h>
#include <osmocom/core/msgb.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
diff --git a/src/gprs/sgsn_ares.c b/src/gprs/sgsn_ares.c
index 38e31e13..87314f11 100644
--- a/src/gprs/sgsn_ares.c
+++ b/src/gprs/sgsn_ares.c
@@ -120,14 +120,14 @@ static void setup_ares_osmo_fd(void *data, int fd, int read, int write)
update_fd:
if (read)
- ufd->fd.when |= OSMO_FD_READ;
+ osmo_fd_read_enable(&ufd->fd);
else
- ufd->fd.when &= ~OSMO_FD_READ;
+ osmo_fd_read_disable(&ufd->fd);
if (write)
- ufd->fd.when |= OSMO_FD_WRITE;
+ osmo_fd_write_enable(&ufd->fd);
else
- ufd->fd.when &= ~OSMO_FD_WRITE;
+ osmo_fd_write_disable(&ufd->fd);
osmo_ares_reschedule(sgsn);
}
diff --git a/src/gtphub/gtphub_main.c b/src/gtphub/gtphub_main.c
index 664c801e..a9a7529c 100644
--- a/src/gtphub/gtphub_main.c
+++ b/src/gtphub/gtphub_main.c
@@ -95,11 +95,11 @@ void log_cfg(struct gtphub_cfg *cfg)
}
}
-static void signal_handler(int signal)
+static void signal_handler(int signum)
{
- fprintf(stdout, "signal %d received\n", signal);
+ fprintf(stdout, "signal %d received\n", signum);
- switch (signal) {
+ switch (signum) {
case SIGINT:
case SIGTERM:
osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
@@ -107,8 +107,16 @@ static void signal_handler(int signal)
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 */
+ /* in case of abort, we want to obtain a talloc report and
+ * then run default SIGABRT handler, who will generate coredump
+ * and abort the process. abort() should do this for us after we
+ * return, but program wouldn't exit if an external SIGABRT is
+ * received.
+ */
+ talloc_report_full(osmo_gtphub_ctx, stderr);
+ signal(SIGABRT, SIG_DFL);
+ raise(SIGABRT);
+ break;
case SIGUSR1:
case SIGUSR2:
talloc_report_full(osmo_gtphub_ctx, stderr);
@@ -118,44 +126,12 @@ static void signal_handler(int signal)
}
}
-#if BUILD_IU
-int gtphub_vty_go_parent(struct vty *vty)
-{
- switch (vty->node) {
- default:
- osmo_ss7_vty_go_parent(vty);
- }
-
- return vty->node;
-}
-#endif
-
-int gtphub_vty_is_config_node(struct vty *vty, int node)
-{
- /* Check if libosmo-sccp declares the node in
- * question as config node */
-#if BUILD_IU
- if (osmo_ss7_is_config_node(vty, node))
- return 1;
-#endif
-
- switch (node) {
- /* add items that are not config */
- case CONFIG_NODE:
- return 0;
-
- default:
- return 1;
- }
-}
-
static struct vty_app_info vty_info = {
.name = "OsmoGTPhub",
.version = PACKAGE_VERSION,
#if BUILD_IU
- .go_parent_cb = gtphub_vty_go_parent,
+ .go_parent_cb = osmo_ss7_vty_go_parent,
#endif
- .is_config_node = gtphub_vty_is_config_node,
};
struct cmdline_cfg {
diff --git a/src/sgsn/gprs_gb.c b/src/sgsn/gprs_gb.c
index d470cfab..c7d5c28b 100644
--- a/src/sgsn/gprs_gb.c
+++ b/src/sgsn/gprs_gb.c
@@ -25,6 +25,9 @@
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_bssgp.h>
+#include <osmocom/gprs/gprs_ns2.h>
+#include <osmocom/gprs/gprs_bssgp_bss.h>
+#include <osmocom/sgsn/gprs_llc.h>
#include "bscconfig.h"
@@ -103,3 +106,83 @@ int gprs_gb_page_ps_ra(struct sgsn_mm_ctx *mmctx)
return rc;
}
+
+/* called by the bssgp layer to send NS PDUs */
+int gprs_gb_send_cb(void *ctx, struct msgb *msg)
+{
+ struct gprs_ns2_inst *nsi = (struct gprs_ns2_inst *) ctx;
+ struct osmo_gprs_ns2_prim nsp = {};
+ nsp.nsei = msgb_nsei(msg);
+ nsp.bvci = msgb_bvci(msg);
+ osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA, PRIM_OP_REQUEST, msg);
+ return gprs_ns2_recv_prim(nsi, &nsp.oph);
+}
+
+void gprs_ns_prim_status_cb(struct osmo_gprs_ns2_prim *nsp)
+{
+ switch (nsp->u.status.cause) {
+ case NS_AFF_CAUSE_SNS_CONFIGURED:
+ LOGP(DGPRS, LOGL_NOTICE, "NS-E %d SNS configured.\n", nsp->nsei);
+ break;
+ case NS_AFF_CAUSE_RECOVERY:
+ LOGP(DGPRS, LOGL_NOTICE, "NS-E %d became available\n", nsp->nsei);
+ /* workaround for broken BSS which doesn't respond correct to BSSGP status message.
+ * Sent a BSSGP Reset when a persistent NSVC comes up for the first time. */
+ if (nsp->u.status.first && nsp->u.status.persistent) {
+ struct bssgp_bvc_ctx bctx = {
+ .nsei = nsp->nsei,
+ };
+ bssgp_tx_bvc_reset2(&bctx, BVCI_SIGNALLING, BSSGP_CAUSE_EQUIP_FAIL, false);
+ }
+ break;
+ case NS_AFF_CAUSE_FAILURE:
+ LOGP(DGPRS, LOGL_NOTICE, "NS-E %d became unavailable\n", nsp->nsei);
+ break;
+ default:
+ LOGP(DGPRS, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",
+ get_value_string(osmo_prim_op_names, nsp->oph.operation), nsp->oph.primitive);
+ break;
+ }
+}
+
+/* call-back function for the NS protocol */
+int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ struct osmo_gprs_ns2_prim *nsp;
+ int rc = 0;
+
+ if (oph->sap != SAP_NS)
+ return 0;
+
+ nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph);
+
+ if (oph->operation != PRIM_OP_INDICATION) {
+ LOGP(DGPRS, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",
+ get_value_string(osmo_prim_op_names, oph->operation),
+ oph->operation);
+ return 0;
+ }
+
+ switch (oph->primitive) {
+ case PRIM_NS_UNIT_DATA:
+ /* hand the message into the BSSGP implementation */
+ /* add required msg fields for Gb layer */
+ msgb_bssgph(oph->msg) = oph->msg->l3h;
+ msgb_bvci(oph->msg) = nsp->bvci;
+ msgb_nsei(oph->msg) = nsp->nsei;
+ rc = bssgp_rcvmsg(oph->msg);
+ break;
+ case PRIM_NS_STATUS:
+ gprs_ns_prim_status_cb(nsp);
+ break;
+ default:
+ LOGP(DGPRS, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",
+ get_value_string(osmo_prim_op_names, oph->operation), oph->primitive);
+ break;
+ }
+
+ if (oph->msg)
+ msgb_free(oph->msg);
+
+ return rc;
+}
diff --git a/src/sgsn/gprs_gmm.c b/src/sgsn/gprs_gmm.c
index 0ad60037..2367338a 100644
--- a/src/sgsn/gprs_gmm.c
+++ b/src/sgsn/gprs_gmm.c
@@ -281,9 +281,11 @@ int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
struct gsm48_hdr *gh;
struct gsm48_attach_ack *aa;
unsigned long t;
+#ifdef PTMSI_ALLOC
struct osmo_mobile_identity mi;
uint8_t *l;
int rc;
+#endif
#if 0
uint8_t *ptsig;
#endif
@@ -340,6 +342,9 @@ int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
/* Optional: MS-identity (combined attach) */
/* Optional: GMM cause (partial attach result for combined attach) */
+ /* Optional: Network feature support 10.5.5.23 */
+ /* msgb_v_put(msg, GSM48_IE_GMM_NET_FEAT_SUPPORT | 0x00);*/
+
return gsm48_gmm_sendmsg(msg, 0, mm, true);
}
@@ -922,9 +927,9 @@ int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
ctx->t3350_mode = GMM_T3350_MODE_ATT;
#else
memset(&sig_data, 0, sizeof(sig_data));
- sig_data.mm = mmctx;
+ sig_data.mm = ctx;
osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data);
- osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
+ osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
#endif
return gsm48_tx_gmm_att_ack(ctx);
@@ -1438,9 +1443,11 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm)
struct gsm48_hdr *gh;
struct gsm48_ra_upd_ack *rua;
unsigned long t;
+#ifdef PTMSI_ALLOC
uint8_t *l;
int rc;
struct osmo_mobile_identity mi;
+#endif
rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_ACKED]);
LOGMMCTXP(LOGL_INFO, mm, "<- ROUTING AREA UPDATE ACCEPT\n");
@@ -1533,7 +1540,10 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx,
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);
+ if (pdp->ggsn)
+ sgsn_delete_pdp_ctx(pdp);
+ else /* GTP side already detached, freeing */
+ sgsn_pdp_ctx_free(pdp);
}
}
@@ -1724,7 +1734,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
mmctx_timer_start(mmctx, 3350);
#else
/* Make sure we are NORMAL (i.e. not SUSPENDED anymore) */
- osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
memset(&sig_data, 0, sizeof(sig_data));
sig_data.mm = mmctx;
diff --git a/src/sgsn/gprs_mm_state_gb_fsm.c b/src/sgsn/gprs_mm_state_gb_fsm.c
index 811f0c2f..d3f2ea32 100644
--- a/src/sgsn/gprs_mm_state_gb_fsm.c
+++ b/src/sgsn/gprs_mm_state_gb_fsm.c
@@ -68,6 +68,9 @@ static void st_mm_standby(struct osmo_fsm_inst *fi, uint32_t event, void *data)
case E_MM_PDU_RECEPTION:
mm_state_gb_fsm_state_chg(fi, ST_MM_READY);
break;
+ case E_MM_IMPLICIT_DETACH:
+ mm_state_gb_fsm_state_chg(fi, ST_MM_IDLE);
+ break;
}
}
@@ -86,7 +89,7 @@ static struct osmo_fsm_state mm_state_gb_fsm_states[] = {
.action = st_mm_ready,
},
[ST_MM_STANDBY] = {
- .in_event_mask = X(E_MM_PDU_RECEPTION),
+ .in_event_mask = X(E_MM_PDU_RECEPTION) | X(E_MM_IMPLICIT_DETACH),
.out_state_mask = X(ST_MM_IDLE) | X(ST_MM_READY),
.name = "Standby",
.action = st_mm_standby,
diff --git a/src/sgsn/gprs_ranap.c b/src/sgsn/gprs_ranap.c
index 7a334919..1f8ed97d 100644
--- a/src/sgsn/gprs_ranap.c
+++ b/src/sgsn/gprs_ranap.c
@@ -26,6 +26,7 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/tdef.h>
+#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/ranap/ranap_common.h>
diff --git a/src/sgsn/gprs_sgsn.c b/src/sgsn/gprs_sgsn.c
index 0b7c21e9..d4bc554c 100644
--- a/src/sgsn/gprs_sgsn.c
+++ b/src/sgsn/gprs_sgsn.c
@@ -27,7 +27,7 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/core/backtrace.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/apn.h>
diff --git a/src/sgsn/gprs_subscriber.c b/src/sgsn/gprs_subscriber.c
index c23b332f..943fbc3d 100644
--- a/src/sgsn/gprs_subscriber.c
+++ b/src/sgsn/gprs_subscriber.c
@@ -870,6 +870,8 @@ struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx(struct sgsn_mm_ctx *mmctx
if (!subscr) {
subscr = gprs_subscr_get_or_create(mmctx->imsi);
+ if (!subscr)
+ return NULL;
subscr->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
subscr->flags &= ~GPRS_SUBSCRIBER_ENABLE_PURGE;
}
@@ -893,6 +895,8 @@ int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx)
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n");
subscr = gprs_subscr_get_or_create_by_mmctx(mmctx);
+ if (!subscr)
+ return -ENOMEM;
subscr->flags |= GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING;
@@ -918,6 +922,8 @@ int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx,
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber authentication info\n");
subscr = gprs_subscr_get_or_create_by_mmctx(mmctx);
+ if (!subscr)
+ return -ENOMEM;
subscr->flags |= GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING;
diff --git a/src/sgsn/sgsn_main.c b/src/sgsn/sgsn_main.c
index 3044f95e..19039f69 100644
--- a/src/sgsn/sgsn_main.c
+++ b/src/sgsn/sgsn_main.c
@@ -39,8 +39,9 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/stats.h>
+#include <osmocom/core/sockaddr_str.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
@@ -60,6 +61,7 @@
#include <osmocom/sgsn/gprs_llc.h>
#include <osmocom/sgsn/gprs_gmm.h>
#include <osmocom/sgsn/gprs_ranap.h>
+#include <osmocom/sgsn/gprs_gb.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/ports.h>
@@ -80,7 +82,7 @@
void *tall_sgsn_ctx;
struct ctrl_handle *g_ctrlh;
-struct gprs_ns_inst *sgsn_nsi;
+struct gprs_ns2_inst *sgsn_nsi;
static int daemonize = 0;
const char *openbsc_copyright =
"Copyright (C) 2010 Harald Welte and On-Waves\r\n"
@@ -94,27 +96,6 @@ const char *openbsc_copyright =
struct sgsn_instance *sgsn;
-/* 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)
{
@@ -143,11 +124,11 @@ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
return 0;
}
-static void signal_handler(int signal)
+static void signal_handler(int signum)
{
- fprintf(stdout, "signal %u received\n", signal);
+ fprintf(stdout, "signal %u received\n", signum);
- switch (signal) {
+ switch (signum) {
case SIGINT:
case SIGTERM:
osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
@@ -155,8 +136,17 @@ static void signal_handler(int signal)
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 */
+ /* in case of abort, we want to obtain a talloc report and
+ * then run default SIGABRT handler, who will generate coredump
+ * and abort the process. abort() should do this for us after we
+ * return, but program wouldn't exit if an external SIGABRT is
+ * received.
+ */
+ talloc_report(tall_vty_ctx, stderr);
+ talloc_report_full(tall_sgsn_ctx, stderr);
+ signal(SIGABRT, SIG_DFL);
+ raise(SIGABRT);
+ break;
case SIGUSR1:
talloc_report(tall_vty_ctx, stderr);
talloc_report_full(tall_sgsn_ctx, stderr);
@@ -172,57 +162,12 @@ static void signal_handler(int signal)
/* NSI that BSSGP uses when transmitting on NS */
extern struct gprs_ns_inst *bssgp_nsi;
-int sgsn_vty_is_config_node(struct vty *vty, int node)
-{
- /* So far the SGSN has no nested nodes that need parent node
- * declaration, except for the ss7 vty nodes. */
- switch (node) {
- case SGSN_NODE:
- return 1;
- default:
-#if BUILD_IU
- return osmo_ss7_is_config_node(vty, node);
-#else
- return 0;
-#endif
- }
-}
-
-int sgsn_vty_go_parent(struct vty *vty)
-{
- /* So far the SGSN has no nested nodes that need parent node
- * declaration, except for the ss7 vty nodes. */
-#if BUILD_IU
- return osmo_ss7_vty_go_parent(vty);
-#else
- vty->node = CONFIG_NODE;
- vty->index = NULL;
- return 0;
-#endif
-}
-
-static void bvc_reset_persistent_nsvcs(void)
-{
- /* Send BVC-RESET on all persistent NSVCs */
- struct gprs_nsvc *nsvc;
-
- llist_for_each_entry(nsvc, &sgsn_nsi->gprs_nsvcs, list) {
- struct bssgp_bvc_ctx bctx = {
- .nsei = nsvc->nsei,
- };
- if (!nsvc->persistent)
- continue;
- /* if it is not marked ALIVE, we cannot send any data over it. */
- nsvc->state |= NSE_S_ALIVE;
- bssgp_tx_bvc_reset2(&bctx, BVCI_SIGNALLING, BSSGP_CAUSE_EQUIP_FAIL, false);
- }
-}
-
static struct vty_app_info vty_info = {
.name = "OsmoSGSN",
.version = PACKAGE_VERSION,
- .go_parent_cb = sgsn_vty_go_parent,
- .is_config_node = sgsn_vty_is_config_node,
+#if BUILD_IU
+ .go_parent_cb = osmo_ss7_vty_go_parent,
+#endif
};
static void print_help(void)
@@ -331,11 +276,6 @@ static struct log_info_cat gprs_categories[] = {
.description = "GPRS Network Service (NS)",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
- [DBSSGP] = {
- .name = "DBSSGP",
- .description = "GPRS BSS Gateway Protocol (BSSGP)",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
[DLLC] = {
.name = "DLLC",
.description = "GPRS Logical Link Control Protocol (LLC)",
@@ -388,6 +328,11 @@ static bool file_exists(const char *path)
int main(int argc, char **argv)
{
int rc;
+ struct osmo_sockaddr_str bind_address = {
+ .af = AF_INET,
+ .ip = "0.0.0.0",
+ .port = 23000,
+ };
#if BUILD_IU
struct osmo_sccp_instance *sccp;
#endif
@@ -442,27 +387,27 @@ int main(int argc, char **argv)
rate_ctr_init(tall_sgsn_ctx);
- gprs_ns_set_log_ss(DNS);
- bssgp_set_log_ss(DBSSGP);
+ logging_vty_add_deprecated_subsys(tall_sgsn_ctx, "bssgp");
- sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb, tall_sgsn_ctx);
+ sgsn_nsi = gprs_ns2_instantiate(tall_sgsn_ctx, &gprs_ns_prim_cb, NULL);
if (!sgsn_nsi) {
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
exit(1);
}
- bssgp_nsi = sgsn->cfg.nsi = sgsn_nsi;
+ sgsn->cfg.nsi = sgsn_nsi;
+ bssgp_set_bssgp_callback(gprs_gb_send_cb, sgsn_nsi);
gprs_llc_init("/usr/local/lib/osmocom/crypt/");
sgsn_rate_ctr_init();
sgsn_inst_init(sgsn);
- gprs_ns_vty_init(bssgp_nsi);
+
+ gprs_ns2_vty_init(sgsn_nsi, &bind_address);
bssgp_vty_init();
gprs_llc_vty_init();
gprs_sndcp_vty_init();
sgsn_auth_init(sgsn);
sgsn_cdr_init(sgsn);
- /* FIXME: register signal handler for SS_L_NS */
rc = sgsn_parse_config(sgsn->config_file);
if (rc < 0) {
@@ -504,18 +449,13 @@ int main(int argc, char **argv)
exit(2);
}
- rc = gprs_ns_nsip_listen(sgsn_nsi);
+ rc = gprs_ns2_vty_create();
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);
- }
+ gprs_ns2_dynamic_create_nse(sgsn_nsi, true);
if (sgsn->cfg.dynamic_lookup) {
if (sgsn_ares_init(sgsn) != 0) {
@@ -542,8 +482,6 @@ int main(int argc, char **argv)
ranap_iu_init(tall_sgsn_ctx, DRANAP, "OsmoSGSN-IuPS", sccp, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event);
#endif
- bvc_reset_persistent_nsvcs();
-
if (daemonize) {
rc = osmo_daemonize();
if (rc < 0) {
diff --git a/src/sgsn/sgsn_vty.c b/src/sgsn/sgsn_vty.c
index 33a652c9..d7584bcb 100644
--- a/src/sgsn/sgsn_vty.c
+++ b/src/sgsn/sgsn_vty.c
@@ -34,7 +34,7 @@
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/sgsn.h>
-#include <osmocom/gprs/gprs_ns.h>
+#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/sgsn/gprs_gmm.h>
#include <osmocom/sgsn/gprs_sgsn.h>
#include <osmocom/sgsn/vty.h>
@@ -1020,6 +1020,10 @@ DEFUN(update_subscr_create, update_subscr_create_cmd,
}
subscr = gprs_subscr_get_or_create(imsi);
+ if (!subscr) {
+ vty_out(vty, "Can not create subscriber. Out of memory.%s", imsi);
+ return CMD_WARNING;
+ }
subscr->keep_in_ram = 1;
gprs_subscr_put(subscr);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a23d9317..32ed4725 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,6 +1,5 @@
SUBDIRS = \
gprs \
- gbproxy \
gtphub \
sgsn \
xid \
@@ -33,7 +32,9 @@ EXTRA_DIST = \
$(TESTSUITE) \
vty_test_runner.py \
ctrl_test_runner.py \
- test_nodes.vty \
+ osmo-sgsn_test-nodes.vty \
+ osmo-gbproxy_test-nodes.vty \
+ osmo-gbproxy-pool_test-nodes.vty \
$(NULL)
TESTSUITE = $(srcdir)/testsuite
@@ -62,9 +63,17 @@ vty-python-test: $(BUILT_SOURCES)
# make vty-transcript-test U=-u
vty-transcript-test:
osmo_verify_transcript_vty.py -v \
+ -n OsmoGbProxy -p 4246 \
+ -r "$(top_builddir)/src/gbproxy/osmo-gbproxy -c $(top_srcdir)/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg" \
+ $(U) $${T:-$(srcdir)/osmo-gbproxy_test-nodes.vty}
+ osmo_verify_transcript_vty.py -v \
+ -n OsmoGbProxy -p 4246 \
+ -r "$(top_builddir)/src/gbproxy/osmo-gbproxy -c $(top_srcdir)/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg" \
+ $(U) $${T:-$(srcdir)/osmo-gbproxy-pool_test-nodes.vty}
+ osmo_verify_transcript_vty.py -v \
-n OsmoSGSN -p 4245 \
-r "$(top_builddir)/src/sgsn/osmo-sgsn -c $(top_srcdir)/doc/examples/osmo-sgsn/osmo-sgsn.cfg" \
- $(U) $${T:-$(srcdir)/*.vty}
+ $(U) $${T:-$(srcdir)/osmo-sgsn*.vty}
rm -f $(builddir)/sms.db $(builddir)/gsn_restart
# don't run multiple tests concurrently so that the ports don't conflict
diff --git a/tests/gbproxy/Makefile.am b/tests/gbproxy/Makefile.am
deleted file mode 100644
index b9585acc..00000000
--- a/tests/gbproxy/Makefile.am
+++ /dev/null
@@ -1,51 +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=osmo_get_rand_id \
- $(NULL)
-
-gbproxy_test_LDADD = \
- $(top_builddir)/src/gbproxy/gb_proxy.o \
- $(top_builddir)/src/gbproxy/gb_proxy_patch.o \
- $(top_builddir)/src/gbproxy/gb_proxy_peer.o \
- $(top_builddir)/src/gbproxy/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 \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGB_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(LIBOSMOVTY_LIBS) \
- $(LIBOSMOABIS_LIBS) \
- $(LIBRARY_DL) \
- $(LIBRARY_DLSYM) \
- -lrt \
- $(NULL)
diff --git a/tests/gbproxy/gbproxy_test.c b/tests/gbproxy/gbproxy_test.c
deleted file mode 100644
index 6433eb60..00000000
--- a/tests/gbproxy/gbproxy_test.c
+++ /dev/null
@@ -1,5082 +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 <jerlbeck@sysmocom.de>
- */
-
-#undef _GNU_SOURCE
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <getopt.h>
-#include <dlfcn.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/application.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/signal.h>
-#include <osmocom/core/rate_ctr.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
-#include <osmocom/gprs/gprs_msgb.h>
-#include <osmocom/gprs/gprs_ns.h>
-#include <osmocom/gprs/gprs_bssgp.h>
-
-#include <osmocom/sgsn/gb_proxy.h>
-#include <osmocom/sgsn/gprs_utils.h>
-#include <osmocom/sgsn/gprs_llc.h>
-#include <osmocom/sgsn/gprs_gb_parse.h>
-#include <osmocom/sgsn/debug.h>
-
-#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)
-
-void *tall_sgsn_ctx = NULL;
-
-struct gbproxy_config gbcfg = {0};
-
-struct llist_head *received_messages = NULL;
-
-/* override, requires '-Wl,--wrap=osmo_get_rand_id' */
-int __real_osmo_get_rand_id(uint8_t *data, size_t len);
-int mock_osmo_get_rand_id(uint8_t *data, size_t len);
-int (*osmo_get_rand_id_cb)(uint8_t *, size_t) =
- &mock_osmo_get_rand_id;
-
-int __wrap_osmo_get_rand_id(uint8_t *buf, size_t num)
-{
- return (*osmo_get_rand_id_cb)(buf, num);
-}
-
-static int rand_seq_num = 0;
-int mock_osmo_get_rand_id(uint8_t *buf, size_t num)
-{
- uint32_t val;
-
- OSMO_ASSERT(num == sizeof(val));
-
- 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 %s\n",
- indent, "",
- peer->nsei, peer->bvci,
- peer->blocked ? "" : "not ",
- osmo_rai_name(&raid));
-
- 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) {
- struct osmo_mobile_identity mi;
- const char *imsi_str;
- 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 > 0) {
- if (osmo_mobile_identity_decode(&mi, link_info->imsi, link_info->imsi_len, false)
- || mi.type != GSM_MI_TYPE_IMSI)
- imsi_str = "(invalid)";
- else
- imsi_str = mi.imsi;
- } else {
- imsi_str = "(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",
- imsi_str, (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 struct gsm48_ra_id r;
- gsm48_encode_ra(&r, raid);
- return (const uint8_t *)&r;
-}
-
-/* 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,
- 0xf8, 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, 0xf8
-};
-
-/* DTAP - Identity Response, IMSI 2 */
-static const unsigned char dtap_identity2_resp[] = {
- 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
- 0x16, 0x17, 0xf8
-};
-
-/* DTAP - Identity Response, IMSI 3 */
-static const unsigned char dtap_identity3_resp[] = {
- 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
- 0x26, 0x27, 0xf8
-};
-
-/* 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_encode_ra((struct gsm48_ra_id *)(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_encode_ra((struct gsm48_ra_id *)(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_encode_ra((struct gsm48_ra_id *)(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_encode_ra((struct gsm48_ra_id *)(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 = bssgp_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);
-
- /* gprs_ns_rcvmsg() in old libosmocore returns "number of bytes
- * transmitted by any response PDU we sent as a result of the
- * received message", while modern libosmocore simply retunrs '0'
- * for any successfully received message. Let's make sure any
- * non-negative responses lead to a reproducible test output
- * with both old and new libosmocore. */
- printf("result (%s) = %d\n\n", text, ret < 0 ? ret : 0);
-
- 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, tall_sgsn_ctx);
- 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, tall_sgsn_ctx);
- 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, tall_sgsn_ctx);
- 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, 0xf8};
- 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_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
- gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 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;
-
- talloc_free(gbcfg.core_apn);
- gbcfg.core_apn = 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, tall_sgsn_ctx);
- 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, 0xf8};
- const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0xf8};
-
- 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_plmn = (struct osmo_plmn_id){};
- gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 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);
-
- talloc_free(gbcfg.core_apn);
- gbcfg.core_apn = NULL;
-
- 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, tall_sgsn_ctx);
- 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, 0xf8};
- 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_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
- gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 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);
-
- talloc_free(gbcfg.core_apn);
- gbcfg.core_apn = NULL;
-
- 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, tall_sgsn_ctx);
- 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, 0xf8};
- 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_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
- gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 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);
-
- talloc_free(gbcfg.core_apn);
- gbcfg.core_apn = NULL;
-
- 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, tall_sgsn_ctx);
- 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, 0xf8};
- 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_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
- gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 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);
-
- talloc_free(gbcfg.core_apn);
- gbcfg.core_apn = NULL;
-
- 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, tall_sgsn_ctx);
- 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, 0xf8};
- const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0xf8};
- const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0xf8};
- 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_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
- gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 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);
-
- talloc_free(gbcfg.core_apn);
- gbcfg.core_apn = NULL;
-
- 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, tall_sgsn_ctx);
- 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, 0xf8};
- 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_plmn = (struct osmo_plmn_id){};
- 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);
-
- talloc_free(gbcfg.core_apn);
- gbcfg.core_apn = NULL;
-
- 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, 0xf6 };
- const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0xf9 };
- 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);
- /* gbprox_reset() frees the rate_ctr, but re-allocates it again. */
- rate_ctr_group_free(cfg.ctrg);
-
- 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);
- OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == -1);
- 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)) == -1);
- 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, tall_sgsn_ctx);
- 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_plmn = (struct osmo_plmn_id){};
- gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 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);
-
- talloc_free(gbcfg.core_apn);
- gbcfg.core_apn = NULL;
-
- gbprox_reset(&gbcfg);
- gprs_ns_destroy(nsi);
- nsi = NULL;
-
- cleanup_test();
-}
-
-/* See OS#3178 "gbproxy: failed to parse invalid BSSGP-UNITDATA message" */
-static void test_gbproxy_parse_bssgp_unitdata()
-{
- const char *hex = "0000239401e155cfea000004088872f4801018009c4000800e000601c0416c4338";
- struct msgb *msg = msgb_alloc(1034, "bssgp_unitdata");
- struct gprs_gb_parse_context parse_ctx;
- int rc;
-
- memset(&parse_ctx, 0, sizeof(parse_ctx));
-
- OSMO_ASSERT(msg);
- msgb_bssgph(msg) = msg->head;
- msgb_put(msg, osmo_hexparse(hex, msg->head, msgb_tailroom(msg)));
-
- parse_ctx.to_bss = 0;
- parse_ctx.peer_nsei = msgb_nsei(msg);
-
- rc = gprs_gb_parse_bssgp(msg->data, msg->len, &parse_ctx);
- if (!rc)
- fprintf(stderr, "%s: Test passed; Failed to parse invalid message %s\n", __func__, msgb_hexdump(msg));
- else
- fprintf(stderr, "%s: Test failed; invalid message was accepted by parser: %s\n", __func__, msgb_hexdump(msg));
-
- OSMO_ASSERT(!rc);
-
- /* Manually decoded message according to:
- ETSI TS 148 018 V10.6.0 (2012 07) 96
- 3GPP TS 48.018 version 10.6.0 Release 10
- Table 10.2.2: UL-UNITDATA PDU content
-
- 00 - PDU type UL-UNITDATA (ok)
-
- 11.3.35 Temporary logical link Identity (TLLI)
- 00 - TLLI[0]
- 23 - TLLI[1]
- 94 - TLLI[2]
- 01 - TLLI[3]
- TLLI == "00239401"
-
- e1 - QOS[0] (bit rate MSB)
- 55 - QOS[1] (bit rate LSB)
- bit rate = "57685" (57685*100000 bit/s per PBRG)
- cf - QOS[2] PBRG = 11 (bit rate is expressed in 100000 bit/s increments),
- C/R 0 (contains LLC ACK/SACK),
- T 0 (contains signalling),
- A 1 (radio if uses MAC/UNITDATA,
- Precedence 111 (reserved value)
-
- ea - CELL_ID[0] (TLV IEI: wrong, should be 0x08)
- 00 - CELL_ID[1] (length 1)
- 00 - CELL_ID[2] (length 2)
- lenth == 0
- 04 -- CELL_ID[3]
- 08 -- CELL_ID[4]
- 88 -- CELL_ID[5]
- 72 -- CELL_ID[6]
- f4 -- CELL_ID[7]
- 80 -- CELL_ID[8]
- 10 -- CELL_DI[9]
-
- 18 -- QOSP[0] OoS Profile IEI
- not allowed in BSSGP Userdata
- 00 -- QOSP[1]
- 9c -- QOSP[2]
- 40 -- QOSP[3]
- 00 -- QOSP[4]
-
- 80 -- IEI for "E-UTRAN Inter RAT Handover Info"
- not allowed in BSSGP Userdata
- 0e -- length (14 bytes -- only 8 bytes remain)
- 00 06 01 c0 41 6c 43 38 */
-
- msgb_free(msg);
-
- 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)
-{
- talloc_enable_leak_report();
- tall_sgsn_ctx = talloc_named_const(NULL, 0, "gbproxy_test");
- void *log_ctx = talloc_named_const(tall_sgsn_ctx, 0, "log");
-
- msgb_talloc_ctx_init(tall_sgsn_ctx, 0);
-
- osmo_init_logging2(log_ctx, &info);
- log_set_use_color(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
- osmo_signal_register_handler(SS_L_NS, &test_signal, &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(tall_sgsn_ctx);
-
- 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();
- test_gbproxy_parse_bssgp_unitdata();
- gbprox_reset(&gbcfg);
- /* gbprox_reset() frees the rate_ctr, but re-allocates it again. */
- rate_ctr_group_free(gbcfg.ctrg);
- printf("===== GbProxy test END\n\n");
-
- talloc_free(log_ctx);
- /* expecting root and msgb ctx, empty */
- OSMO_ASSERT(talloc_total_blocks(tall_sgsn_ctx) == 2);
- talloc_free(tall_sgsn_ctx);
-
- return 0;
-}
diff --git a/tests/gbproxy/gbproxy_test.ok b/tests/gbproxy/gbproxy_test.ok
deleted file mode 100644
index 03de12e4..00000000
--- a/tests/gbproxy/gbproxy_test.ok
+++ /dev/null
@@ -1,7492 +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) = 0
-
-PROCESSING ALIVE_ACK from 0x05060708:32000
-0b
-
-MESSAGE to SGSN at 0x05060708:32000, msg length 1
-06
-
-result (ALIVE_ACK) = 0
-
-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) = 0
-
-Current NS-VCIs:
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 4
- Packets at NS Level (Out): 4
- Bytes at NS Level ( In): 12
- Bytes at NS Level (Out): 15
- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-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) = 0
-
-Current NS-VCIs:
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 4
- Bytes at NS Level ( In): 37
- Bytes at NS Level (Out): 12
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 4
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 12
- Bytes at NS Level (Out): 37
- 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) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:2222
-0a
-
-MESSAGE to BSS at 0x01020304:2222, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:2222
-06
-
-MESSAGE to BSS at 0x01020304:2222, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:2222
-
-result (UNBLOCK) = 0
-
-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) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 4
- Bytes at NS Level ( In): 37
- Bytes at NS Level (Out): 12
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 37
- Bytes at NS Level (Out): 21
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 6
- Bytes at NS Level ( In): 21
- Bytes at NS Level (Out): 59
- 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) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:3333
-0a
-
-MESSAGE to BSS at 0x01020304:3333, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:3333
-06
-
-MESSAGE to BSS at 0x01020304:3333, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:3333
-
-result (UNBLOCK) = 0
-
-PROCESSING ALIVE_ACK from 0x01020304:3333
-0b
-
-result (ALIVE_ACK) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 37
- Bytes at NS Level (Out): 21
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333
- Packets at NS Level ( In): 9
- Packets at NS Level (Out): 9
- Bytes at NS Level ( In): 52
- Bytes at NS Level (Out): 33
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 6
- Packets at NS Level (Out): 6
- Bytes at NS Level ( In): 30
- Bytes at NS Level (Out): 59
- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-PROCESSING ALIVE_ACK from 0x01020304:1111
-0b
-
-result (ALIVE_ACK) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
- Packets at NS Level ( In): 9
- Packets at NS Level (Out): 9
- Bytes at NS Level ( In): 52
- Bytes at NS Level (Out): 33
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333
- Packets at NS Level ( In): 9
- Packets at NS Level (Out): 9
- Bytes at NS Level ( In): 52
- Bytes at NS Level (Out): 33
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 6
- Packets at NS Level (Out): 6
- Bytes at NS Level ( In): 30
- Bytes at NS Level (Out): 59
- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-PROCESSING ALIVE_ACK from 0x01020304:1111
-0b
-
-result (ALIVE_ACK) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
- Packets at NS Level ( In): 13
- Packets at NS Level (Out): 13
- Bytes at NS Level ( In): 67
- Bytes at NS Level (Out): 45
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333
- Packets at NS Level ( In): 9
- Packets at NS Level (Out): 9
- Bytes at NS Level ( In): 52
- Bytes at NS Level (Out): 33
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 6
- Packets at NS Level (Out): 6
- Bytes at NS Level ( In): 30
- Bytes at NS Level (Out): 59
- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:4444
-0a
-
-MESSAGE to BSS at 0x01020304:4444, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:4444
-06
-
-MESSAGE to BSS at 0x01020304:4444, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:4444
-
-result (UNBLOCK) = 0
-
-PROCESSING ALIVE_ACK from 0x01020304:4444
-0b
-
-result (ALIVE_ACK) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:4444
- Packets at NS Level ( In): 17
- Packets at NS Level (Out): 17
- Bytes at NS Level ( In): 82
- Bytes at NS Level (Out): 57
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333
- Packets at NS Level ( In): 9
- Packets at NS Level (Out): 9
- Bytes at NS Level ( In): 52
- Bytes at NS Level (Out): 33
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 6
- Packets at NS Level (Out): 6
- Bytes at NS Level ( In): 30
- Bytes at NS Level (Out): 59
- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:3333
-0a
-
-MESSAGE to BSS at 0x01020304:3333, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:3333
-06
-
-MESSAGE to BSS at 0x01020304:3333, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:3333
-
-result (UNBLOCK) = 0
-
-PROCESSING ALIVE_ACK from 0x01020304:3333
-0b
-
-result (ALIVE_ACK) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
- Packets at NS Level ( In): 20
- Packets at NS Level (Out): 21
- Bytes at NS Level ( In): 85
- Bytes at NS Level (Out): 69
- NS-VC replaced other count: 1
- VCI 0x1001, NSEI 0x1000, peer 0x00000000:0
- Packets at NS Level ( In): 10
- Packets at NS Level (Out): 9
- Bytes at NS Level ( In): 64
- Bytes at NS Level (Out): 33
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 6
- Packets at NS Level (Out): 6
- Bytes at NS Level ( In): 30
- Bytes at NS Level (Out): 59
- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-PROCESSING ALIVE_ACK from 0x01020304:1111
-0b
-
-result (ALIVE_ACK) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
- Packets at NS Level ( In): 20
- Packets at NS Level (Out): 21
- Bytes at NS Level ( In): 85
- Bytes at NS Level (Out): 69
- NS-VC replaced other count: 1
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 14
- Packets at NS Level (Out): 13
- Bytes at NS Level ( In): 79
- Bytes at NS Level (Out): 45
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 6
- Packets at NS Level (Out): 6
- Bytes at NS Level ( In): 30
- Bytes at NS Level (Out): 59
- 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) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
- Packets at NS Level ( In): 20
- Packets at NS Level (Out): 21
- Bytes at NS Level ( In): 85
- Bytes at NS Level (Out): 69
- NS-VC replaced other count: 1
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 15
- Packets at NS Level (Out): 13
- Bytes at NS Level ( In): 101
- Bytes at NS Level (Out): 45
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 6
- Packets at NS Level (Out): 7
- Bytes at NS Level ( In): 30
- Bytes at NS Level (Out): 81
- 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) = 0
-
---- 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) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
- Packets at NS Level ( In): 20
- Packets at NS Level (Out): 21
- Bytes at NS Level ( In): 85
- Bytes at NS Level (Out): 69
- NS-VC replaced other count: 1
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 16
- Packets at NS Level (Out): 14
- Bytes at NS Level ( In): 123
- Bytes at NS Level (Out): 54
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 7
- Packets at NS Level (Out): 8
- Bytes at NS Level ( In): 39
- Bytes at NS Level (Out): 103
- 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) = 0
-
---- 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) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
- Packets at NS Level ( In): 20
- Packets at NS Level (Out): 21
- Bytes at NS Level ( In): 85
- Bytes at NS Level (Out): 69
- NS-VC replaced other count: 1
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 17
- Packets at NS Level (Out): 15
- Bytes at NS Level ( In): 145
- Bytes at NS Level (Out): 63
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 8
- Packets at NS Level (Out): 9
- Bytes at NS Level ( In): 48
- Bytes at NS Level (Out): 125
- 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) = 0
-
---- 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) = 0
-
---- 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) = 0
-
---- 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) = 0
-
---- 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) = 0
-
---- 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) = 0
-
---- 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) = 0
-
---- 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) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
- Packets at NS Level ( In): 21
- Packets at NS Level (Out): 22
- Bytes at NS Level ( In): 107
- Bytes at NS Level (Out): 73
- NS-VC replaced other count: 1
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 20
- Packets at NS Level (Out): 18
- Bytes at NS Level ( In): 157
- Bytes at NS Level (Out): 80
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 12
- Packets at NS Level (Out): 13
- Bytes at NS Level ( In): 69
- Bytes at NS Level (Out): 159
- 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) = 0
-
---- 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) = 0
-
---- 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) = 0
-
---- 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) = 0
-
-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) = 0
-
-PROCESSING ALIVE_ACK from 0x05060708:32000
-0b
-
-MESSAGE to SGSN at 0x05060708:32000, msg length 1
-06
-
-result (ALIVE_ACK) = 0
-
-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) = 0
-
-Current NS-VCIs:
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 4
- Packets at NS Level (Out): 4
- Bytes at NS Level ( In): 12
- Bytes at NS Level (Out): 15
- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-PROCESSING ALIVE_ACK from 0x01020304:1111
-0b
-
-result (ALIVE_ACK) = 0
-
-Current NS-VCIs:
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 4
- Packets at NS Level (Out): 4
- Bytes at NS Level ( In): 15
- Bytes at NS Level (Out): 12
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 4
- Packets at NS Level (Out): 4
- Bytes at NS Level ( In): 12
- Bytes at NS Level (Out): 15
- 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) = 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) = 0
-
-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) = 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:1111, msg length 9
-00 00 00 00 23 04 82 20 02
-
-result (BVC_RESET_ACK) = 0
-
-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) = 0
-
-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) = 0
-
---- 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) = 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)
-MESSAGE to BSS at 0x01020304:1111, msg length 4
-00 00 20 02
-
-result (UNITDATA) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-PROCESSING ALIVE_ACK from 0x01020304:1111
-0b
-
-result (ALIVE_ACK) = 0
-
-Current NS-VCIs:
- VCI 0x1001, NSEI 0x2000, peer 0x01020304:1111
- Packets at NS Level ( In): 12
- Packets at NS Level (Out): 12
- Bytes at NS Level ( In): 82
- Bytes at NS Level (Out): 50
- NS-VC changed NSEI count : 1
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 8
- Packets at NS Level (Out): 8
- Bytes at NS Level ( In): 38
- Bytes at NS Level (Out): 67
- 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) = 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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
---- 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) = 0
-
-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) = 0
-
-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) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-PROCESSING ALIVE_ACK from 0x01020304:1111
-0b
-
-result (ALIVE_ACK) = 0
-
-Current NS-VCIs:
- VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
- Packets at NS Level ( In): 3
- Packets at NS Level (Out): 4
- Bytes at NS Level ( In): 3
- Bytes at NS Level (Out): 12
- NS-VC replaced other count: 1
- VCI 0x1001, NSEI 0x2000, peer 0x00000000:0
- Packets at NS Level ( In): 18
- Packets at NS Level (Out): 16
- Bytes at NS Level ( In): 150
- Bytes at NS Level (Out): 76
- NS-VC changed NSEI count : 1
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 13
- Packets at NS Level (Out): 13
- Bytes at NS Level ( In): 68
- Bytes at NS Level (Out): 123
- 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) = 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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
---- 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) = 0
-
-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) = 0
-
-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) = 0
-
---- 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) = 0
-
-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) = 0
-
-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) = 0
-
-PROCESSING ALIVE_ACK from 0x05060708:32000
-0b
-
-MESSAGE to SGSN at 0x05060708:32000, msg length 1
-06
-
-result (ALIVE_ACK) = 0
-
-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) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-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) = 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) = 0
-
-Current NS-VCIs:
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 37
- Bytes at NS Level (Out): 21
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 21
- Bytes at NS Level (Out): 37
- 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) = 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
-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) = 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
-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 f8 07 e1 ae
-
-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 f8 07 e1 ae
-
-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 f8 07 e1 ae
-
-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 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 f8 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 f8 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 f8 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) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-
-result (GMM INFO) = 0
-
-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) = 0
-
-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) = 0
-
-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 f8 15 36 87
-
-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 f8 15 36 87
-
-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 f8 15 36 87
-
-result (IDENT RESPONSE) = 0
-
-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 f8 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 f8 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 f8 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) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6
-
-result (GMM INFO) = 0
-
-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) = 0
-
-PROCESSING ALIVE_ACK from 0x05060708:32000
-0b
-
-MESSAGE to SGSN at 0x05060708:32000, msg length 1
-06
-
-result (ALIVE_ACK) = 0
-
-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) = 0
-
-Current NS-VCIs:
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 4
- Packets at NS Level (Out): 4
- Bytes at NS Level ( In): 12
- Bytes at NS Level (Out): 15
- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-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) = 0
-
-Current NS-VCIs:
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 4
- Bytes at NS Level ( In): 37
- Bytes at NS Level (Out): 12
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 4
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 12
- Bytes at NS Level (Out): 37
- 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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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 f8 1d ff 1c
-
-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 f8 1d ff 1c
-
-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 f8 1d ff 1c
-
-result (IDENT RESPONSE) = 0
-
-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 f8 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 f8 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 f8 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) = 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 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) = 0
-
-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)) = 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 f8 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 f8 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 f8 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-
-result (GMM INFO) = 0
-
-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)) = 0
-
-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)) = 0
-
-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) = 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 f8 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 f8 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 f8 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0
-
-result (DETACH ACC) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 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) = 0
-
-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)) = 0
-
-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)) = 0
-
-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)) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-PROCESSING ALIVE_ACK from 0x05060708:32000
-0b
-
-MESSAGE to SGSN at 0x05060708:32000, msg length 1
-06
-
-result (ALIVE_ACK) = 0
-
-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) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-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) = 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) = 0
-
-Current NS-VCIs:
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 37
- Bytes at NS Level (Out): 21
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 21
- Bytes at NS Level (Out): 37
- 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) = 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 (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) = 0
-
-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 f8 07 e1 ae
-
-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 f8 07 e1 ae
-
-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 f8 07 e1 ae
-
-result (IDENT RESPONSE) = 0
-
-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 f8 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 f8 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 f8 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) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-
-result (GMM INFO) = 0
-
-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)) = 0
-
-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)) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
-
-result (XID (DL)) = 0
-
-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)) = 0
-
-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 f8 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 f8 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 f8 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)) = 0
-
-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)) = 0
-
-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 f8 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 f8 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 f8 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)) = 0
-
-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)) = 0
-
-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 f8 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 f8 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 f8 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)) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6
-
-result (GMM INFO) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b
-
-result (GMM INFO) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 89 41 c0 19 08 06 00 04 ff 52
-
-result (DETACH ACC) = 0
-
-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) = 0
-
-PROCESSING ALIVE_ACK from 0x05060708:32000
-0b
-
-MESSAGE to SGSN at 0x05060708:32000, msg length 1
-06
-
-result (ALIVE_ACK) = 0
-
-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) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-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) = 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) = 0
-
-Current NS-VCIs:
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 37
- Bytes at NS Level (Out): 21
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 21
- Bytes at NS Level (Out): 37
- 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) = 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 (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) = 0
-
-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 f8 07 e1 ae
-
-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 f8 07 e1 ae
-
-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 f8 07 e1 ae
-
-result (IDENT RESPONSE) = 0
-
-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 f8 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 f8 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 f8 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) = 0
-
-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 f8 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 f8 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 f8 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)) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b
-
-result (GMM INFO) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 89 41 c0 11 08 06 00 cf 8a 58
-
-result (DETACH ACC) = 0
-
-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) = 0
-
-PROCESSING ALIVE_ACK from 0x05060708:32000
-0b
-
-MESSAGE to SGSN at 0x05060708:32000, msg length 1
-06
-
-result (ALIVE_ACK) = 0
-
-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) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-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) = 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) = 0
-
-Current NS-VCIs:
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 37
- Bytes at NS Level (Out): 21
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 21
- Bytes at NS Level (Out): 37
- 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 f8 07 e1 ae
-
-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 f8 07 e1 ae
-
-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) = 0
-
-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 f8 10 f0 45
-
-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 f8 10 f0 45
-
-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 f8 10 f0 45
-
-result (IDENT RESPONSE) = 0
-
-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 f8 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 f8 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 f8 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) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-
-result (GMM INFO) = 0
-
-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)) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
-
-result (XID (DL)) = 0
-
-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)) = 0
-
-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 f8 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 f8 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 f8 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)) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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) = 0
-
-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 f8 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 f8 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 f8 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee
-
-result (DETACH ACC) = 0
-
-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 f8 9f c7 7a
-
-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 f8 9f c7 7a
-
-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 f8 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 f8 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 f8 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) = 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 : 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 f8 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 f8 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 f8 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0
-
-result (DETACH ACC) = 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 : 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) = 0
-
-PROCESSING ALIVE_ACK from 0x05060708:32000
-0b
-
-MESSAGE to SGSN at 0x05060708:32000, msg length 1
-06
-
-result (ALIVE_ACK) = 0
-
-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) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE_ACK from 0x15161718:32001
-0b
-
-MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1
-06
-
-result (ALIVE_ACK) = 0
-
-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) = 0
-
---- 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) = 0
-
-PROCESSING ALIVE from 0x01020304:1111
-0a
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-0b
-
-result (ALIVE) = 0
-
-PROCESSING UNBLOCK from 0x01020304:1111
-06
-
-MESSAGE to BSS at 0x01020304:1111, msg length 1
-07
-
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
-result (UNBLOCK) = 0
-
-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) = 0
-
-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) = 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) = 0
-
-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) = 0
-
-Current NS-VCIs:
- VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
- Packets at NS Level ( In): 6
- Packets at NS Level (Out): 6
- Bytes at NS Level ( In): 59
- Bytes at NS Level (Out): 30
- VCI 0x0103, NSEI 0x0102, peer 0x15161718:32001
- Packets at NS Level ( In): 5
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 21
- Bytes at NS Level (Out): 37
- NS-VC Block count : 1
- VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
- Packets at NS Level ( In): 6
- Packets at NS Level (Out): 5
- Bytes at NS Level ( In): 30
- Bytes at NS Level (Out): 37
- 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) = 0
-
-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) = 0
-
-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 f8 07 e1 ae
-
-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 f8 07 e1 ae
-
-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) = 0
-
-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 f8 10 f0 45
-
-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 f8 10 f0 45
-
-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 f8 10 f0 45
-
-result (IDENT RESPONSE) = 0
-
-Peers:
- NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
- RAID patched (BSS ): 3
- TLLI patched (BSS ): 2