mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 21:13:44 +00:00
Compare commits
93 Commits
sysmocom/i
...
fairwaves/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e883ba6d4 | ||
|
|
b6e37efb91 | ||
|
|
6984250742 | ||
|
|
683e60db73 | ||
|
|
785e8b8533 | ||
|
|
bd6784dbe8 | ||
|
|
5788904242 | ||
|
|
362a757f56 | ||
|
|
444a9b9304 | ||
|
|
8d8bedff4c | ||
|
|
084a35588f | ||
|
|
03bf40f6a5 | ||
|
|
842e599c5c | ||
|
|
16e9c4a70f | ||
|
|
fdee81b35f | ||
|
|
582242d2f5 | ||
|
|
fb5a18db4b | ||
|
|
8a8703e06c | ||
|
|
d68abba3d0 | ||
|
|
bbd3c7cd46 | ||
|
|
0a2a92a4f5 | ||
|
|
a52726dae8 | ||
|
|
8af593e4e4 | ||
|
|
fb11fc1a7a | ||
|
|
0904c1de19 | ||
|
|
c301ef4ea7 | ||
|
|
59dc70462b | ||
|
|
e7dc282b51 | ||
|
|
45fdb6a728 | ||
|
|
32906636f1 | ||
|
|
b314380065 | ||
|
|
8bb11c90fc | ||
|
|
933de8cb48 | ||
|
|
1bcfaa7119 | ||
|
|
6c079bb981 | ||
|
|
c572ac8733 | ||
|
|
53d1a9186c | ||
|
|
2f749ef103 | ||
|
|
17276417ef | ||
|
|
234f6714a7 | ||
|
|
3e7a48c475 | ||
|
|
9d53708f58 | ||
|
|
da8c96e097 | ||
|
|
d4839fe14a | ||
|
|
db0e216845 | ||
|
|
2d9f39ec43 | ||
|
|
e5e251c396 | ||
|
|
991691f8df | ||
|
|
955d8800e5 | ||
|
|
9a4936a234 | ||
|
|
012c9203e4 | ||
|
|
5087f994fd | ||
|
|
420e4d445c | ||
|
|
a8f56961be | ||
|
|
b2679b822e | ||
|
|
0ce3516a47 | ||
|
|
2b5eb8ddb0 | ||
|
|
fd245fcfa8 | ||
|
|
9f24671589 | ||
|
|
acddb2a632 | ||
|
|
800369d258 | ||
|
|
236d81fa0c | ||
|
|
8e58f575e7 | ||
|
|
da0864dfde | ||
|
|
fc969503e1 | ||
|
|
1e4a954c73 | ||
|
|
2f4878a90f | ||
|
|
70e6f2ec74 | ||
|
|
be9419881c | ||
|
|
a363aa3fc0 | ||
|
|
9cddaeafd5 | ||
|
|
9fe68b0fbc | ||
|
|
1c30463e76 | ||
|
|
bcc2567579 | ||
|
|
924292977f | ||
|
|
a317e334c2 | ||
|
|
76c7cec298 | ||
|
|
c70110945a | ||
|
|
f5fe345dbb | ||
|
|
07a5b120e9 | ||
|
|
dfeabbbff6 | ||
|
|
1371303689 | ||
|
|
f7cb56572a | ||
|
|
014316f514 | ||
|
|
b96f1912da | ||
|
|
adc681331e | ||
|
|
8516d533db | ||
|
|
c6e735fd00 | ||
|
|
cc75a7f014 | ||
|
|
1c33b89886 | ||
|
|
077e62cded | ||
|
|
a78396dcb3 | ||
|
|
e9c81d2581 |
20
debian/changelog
vendored
20
debian/changelog
vendored
@@ -1,3 +1,23 @@
|
||||
openbsc (0.15.1-fw.3) UNRELEASED; urgency=medium
|
||||
|
||||
* Added openbsc-dev package.
|
||||
* New release of openbsc for fairwaves build.
|
||||
|
||||
-- Ivan Klyuchnikov <kluchnikovi@gmail.com> Wed, 15 Feb 2017 21:11:04 +0200
|
||||
|
||||
openbsc (0.15.1-fw.2) UNRELEASED; urgency=medium
|
||||
|
||||
* Fixed rebase issues.
|
||||
* New release of openbsc for fairwaves build.
|
||||
|
||||
-- Ivan Klyuchnikov <kluchnikovi@gmail.com> Wed, 15 Feb 2017 17:03:24 +0200
|
||||
|
||||
openbsc (0.15.1-fw.1) UNRELEASED; urgency=medium
|
||||
|
||||
* New release of openbsc for fairwaves build.
|
||||
|
||||
-- Ivan Klyuchnikov <kluchnikovi@gmail.com> Tue, 14 Feb 2017 15:12:30 +0200
|
||||
|
||||
openbsc (0.15.1) UNRELEASED; urgency=medium
|
||||
|
||||
* Move forward toward a new release.
|
||||
|
||||
144
debian/control
vendored
144
debian/control
vendored
@@ -6,7 +6,6 @@ Build-Depends: debhelper (>= 9),
|
||||
autotools-dev,
|
||||
autoconf-archive,
|
||||
pkg-config,
|
||||
libgtp-dev,
|
||||
libosmocore-dev,
|
||||
libosmo-sccp-dev,
|
||||
libdbi0-dev,
|
||||
@@ -17,23 +16,16 @@ Build-Depends: debhelper (>= 9),
|
||||
libpcap-dev,
|
||||
libssl-dev,
|
||||
libc-ares-dev,
|
||||
libsmpp34-dev
|
||||
libsmpp34-dev,
|
||||
libcdk5-dev,
|
||||
libsqlite3-dev,
|
||||
libosip2-dev,
|
||||
libsofia-sip-ua-dev
|
||||
Standards-Version: 3.9.8
|
||||
Vcs-Git: git://bs11-abis.gnumonks.org/openbsc.git
|
||||
Vcs-Browser: http://openbsc.osmocom.org/trac/browser
|
||||
Homepage: https://projects.osmocom.org/projects/openbsc
|
||||
|
||||
Package: osmocom-bsc
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Description: GSM Base Station Controller
|
||||
This is the BSC-only version of OpenBSC. It requires a Mobile Switching Center
|
||||
(MSC) to operate.
|
||||
.
|
||||
You might rather prefer to use osmocom-nitb which is considered a
|
||||
"GSM Network-in-a-Box" and does not depend on a MSC.
|
||||
|
||||
Package: osmocom-nitb
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
@@ -44,61 +36,6 @@ Description: GSM Network-in-a-Box, implements BSC, MSC, SMSC, HLR, VLR
|
||||
components bundled together. When using osmocom-nitb, there is no need for a
|
||||
Mobile Switching Center (MSC) which is needed when using osmocom-bsc.
|
||||
|
||||
Package: osmocom-ipaccess-utils
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Description: Command line utilities for ip.access nanoBTS
|
||||
This package contains utilities that are specific for nanoBTS when being used
|
||||
together with OpenBSC. It contains mainly three tools: ipaccess-find,
|
||||
ipaccess-config and ipaccess-proxy.
|
||||
|
||||
Package: osmocom-bs11-utils
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Description: Command line utilities for Siemens BS-11 BTS
|
||||
There is a tool in this package for configuring the Siemens BS-11 BTS.
|
||||
Additionally, it contains one tool for making use of an ISDN-card and the
|
||||
public telephone network as frequency standard for the E1 line.
|
||||
|
||||
Package: osmocom-sgsn
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Suggests: osmocom-bsc
|
||||
Description: Osmocom Serving GPRS Support Node
|
||||
This is an implementation of the GPRS Serving GPRS Support Node (SGSN). As
|
||||
such it implements the GPRS Mobility Management (GMM) and SM (Session
|
||||
Management).
|
||||
.
|
||||
The SGSN connects via the Gb-interface to the BSS (like the osmo-pcu or an
|
||||
ip.access nanoBTS), and it connects via the GTP protocol to a Gateway GPRS
|
||||
Support Node (GGSN) like openggsn.
|
||||
|
||||
Package: osmocom-gbproxy
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Recommends: osmocom-sgsn
|
||||
Description: Osmocom GPRS Gb Interface Proxy
|
||||
The purpose of the Gb proxy is to aggregate the Gb links of multiple
|
||||
BSS's and present them in one Gb link to the SGSN.
|
||||
.
|
||||
This package is part of OpenBSC and closely related to osmocom-sgsn.
|
||||
|
||||
Package: osmocom-bsc-nat
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Recommends: osmocom-bsc
|
||||
Description: Osmocom Base Station Controller Network Address Translation
|
||||
This NAT is useful for masquerading multiple BSCs behind one. It listens
|
||||
for incoming BSCs on port 5000 and connects to a specified Mobile Switching
|
||||
Center (MSC).
|
||||
.
|
||||
This package is part of OpenBSC and closely related to osmocom-bsc.
|
||||
|
||||
Package: openbsc-dev
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}
|
||||
@@ -110,72 +47,45 @@ Description: Header file needed by tools tightly integrated
|
||||
The directory structure is copied after the structure in the repository
|
||||
and the header and .c file are installed into /usr/src/osmocom/openbsc/.
|
||||
|
||||
Package: osmo-gtphub
|
||||
Package: osmocom-meas-utils
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: Osmocom GTP Hub
|
||||
Proxy for comms between multiple SGSNs and GGSNs.
|
||||
|
||||
Package: osmocom-bsc-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmocom-bsc (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC BSC
|
||||
Make debugging possible
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
libcdk5,
|
||||
sqlite3
|
||||
Description: Measurement utilities for the OpenBSC
|
||||
Measurement utilities for the OpenBSC.
|
||||
|
||||
Package: osmocom-nitb-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmocom-nitb (= ${binary:Version}), ${misc:Depends}
|
||||
Depends: osmocom-nitb (= ${binary:Version}),
|
||||
${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC NITB
|
||||
Make debugging possible
|
||||
|
||||
Package: osmocom-ipaccess-utils-dbg
|
||||
Package: osmocom-meas-utils-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmocom-ipaccess-utils (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC ip.access utils
|
||||
Depends: osmocom-meas-utils (= ${binary:Version}),
|
||||
${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC measurement utilities
|
||||
Make debugging possible
|
||||
|
||||
Package: osmocom-bs11-utils-dbg
|
||||
Package: osmocom-proxy
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmocom-bs11-utils (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC BS11 utils
|
||||
Make debugging possible
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Description: GSM Network-in-a-Box, implements BSC, MSC, SMSC, HLR, VLR
|
||||
reg and ussd proxies
|
||||
|
||||
Package: osmocom-sgsn-dbg
|
||||
Package: osmocom-proxy-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmocom-sgsn (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC Serving GPRS Support Node
|
||||
Make debugging possible
|
||||
|
||||
Package: osmocom-gbproxy-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmocom-gbproxy (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC GPRS GBProxy
|
||||
Make debugging possible
|
||||
|
||||
Package: osmocom-bsc-nat-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmocom-bsc-nat (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC Network Address Translation
|
||||
Make debugging possible
|
||||
|
||||
Package: osmo-gtphub-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmo-gtphub (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for Osmocom GTP Hub
|
||||
Depends: osmocom-nitb (= ${binary:Version}),
|
||||
${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC Proxies
|
||||
Make debugging possible
|
||||
|
||||
4
debian/osmocom-meas-utils.install
vendored
Normal file
4
debian/osmocom-meas-utils.install
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/usr/bin/osmo-meas-udp2db
|
||||
/usr/bin/osmo-meas-pcap2db
|
||||
/usr/bin/meas_vis
|
||||
/usr/bin/meas_json
|
||||
9
debian/osmocom-proxy.install
vendored
Normal file
9
debian/osmocom-proxy.install
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
usr/bin/reg-proxy
|
||||
etc/sv/reg-proxy
|
||||
etc/service/reg-proxy
|
||||
etc/reg-proxy.config
|
||||
|
||||
usr/bin/ussd-proxy
|
||||
etc/sv/ussd-proxy
|
||||
etc/service/ussd-proxy
|
||||
etc/ussd-proxy.config
|
||||
12
debian/rules
vendored
12
debian/rules
vendored
@@ -17,16 +17,10 @@ override_dh_autoreconf:
|
||||
cd openbsc && autoreconf --install --force
|
||||
|
||||
override_dh_strip:
|
||||
dh_strip -posmocom-bsc --dbg-package=osmocom-bsc-dbg
|
||||
dh_strip -posmocom-nitb --dbg-package=osmocom-nitb-dbg
|
||||
dh_strip -posmocom-ipaccess-utils --dbg-package=osmocom-ipaccess-utils-dbg
|
||||
dh_strip -posmocom-bs11-utils --dbg-package=osmocom-bs11-utils-dbg
|
||||
dh_strip -posmocom-sgsn --dbg-package=osmocom-sgsn-dbg
|
||||
dh_strip -posmocom-gbproxy --dbg-package=osmocom-gbproxy-dbg
|
||||
dh_strip -posmocom-bsc-nat --dbg-package=osmocom-bsc-nat-dbg
|
||||
dh_strip -posmo-gtphub --dbg-package=osmo-gtphub-dbg
|
||||
dh_strip -posmocom-meas-utils --dbg-package=osmocom-meas-utils-dbg
|
||||
dh_strip -posmocom-proxy --dbg-package=osmocom-proxy-dbg
|
||||
|
||||
override_dh_auto_configure:
|
||||
echo $(VERSION) > openbsc/.tarball-version
|
||||
dh_auto_configure --sourcedirectory=openbsc -- --enable-nat --enable-osmo-bsc --enable-smpp
|
||||
|
||||
dh_auto_configure --sourcedirectory=openbsc -- --enable-smpp --enable-ussd-proxy
|
||||
|
||||
3
etc/reg-proxy.config
Normal file
3
etc/reg-proxy.config
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
COMMAND_LINE="-S 172.31.0.16 -s 5040 -D 172.31.0.10 -d 5040"
|
||||
1
etc/service/reg-proxy
Symbolic link
1
etc/service/reg-proxy
Symbolic link
@@ -0,0 +1 @@
|
||||
../sv/reg-proxy
|
||||
1
etc/service/ussd-proxy
Symbolic link
1
etc/service/ussd-proxy
Symbolic link
@@ -0,0 +1 @@
|
||||
../sv/ussd-proxy/
|
||||
4
etc/sv/reg-proxy/log/run
Executable file
4
etc/sv/reg-proxy/log/run
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
LOG_FOLDER=/var/log/reg-proxy
|
||||
mkdir -p $LOG_FOLDER
|
||||
exec svlogd -tt $LOG_FOLDER
|
||||
6
etc/sv/reg-proxy/run
Executable file
6
etc/sv/reg-proxy/run
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. /etc/reg-proxy.config
|
||||
exec 2>&1
|
||||
echo "reg-proxy restart" | /usr/bin/ts >> /var/log/runsv.log
|
||||
exec reg-proxy $COMMAND_LINE
|
||||
4
etc/sv/ussd-proxy/log/run
Executable file
4
etc/sv/ussd-proxy/log/run
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
LOG_FOLDER=/var/log/ussd-proxy
|
||||
mkdir -p $LOG_FOLDER
|
||||
exec svlogd -tt $LOG_FOLDER
|
||||
6
etc/sv/ussd-proxy/run
Executable file
6
etc/sv/ussd-proxy/run
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. /etc/ussd-proxy.config
|
||||
exec 2>&1
|
||||
echo "ussd-proxy restart" | /usr/bin/ts >> /var/log/runsv.log
|
||||
exec ussd-proxy $COMMAND_LINE
|
||||
3
etc/ussd-proxy.config
Normal file
3
etc/ussd-proxy.config
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
COMMAND_LINE="-t sip:172.31.0.6:5060 -u sip:172.31.0.29:5090 -l8"
|
||||
11
openbsc/.gitignore
vendored
11
openbsc/.gitignore
vendored
@@ -56,7 +56,6 @@ src/gprs/osmo-gbproxy
|
||||
src/gprs/osmo-gtphub
|
||||
src/osmo-bsc_nat/osmo-bsc_nat
|
||||
src/libcommon/gsup_test_client
|
||||
src/osmo-msc/osmo-msc
|
||||
|
||||
#tests
|
||||
tests/testsuite.dir
|
||||
@@ -80,7 +79,6 @@ tests/trau/trau_test
|
||||
tests/mgcp/mgcp_transcoding_test
|
||||
tests/sgsn/sgsn_test
|
||||
tests/subscr/subscr_test
|
||||
tests/subscr/bsc_subscr_test
|
||||
tests/oap/oap_test
|
||||
tests/gtphub/gtphub_test
|
||||
tests/mm_auth/mm_auth_test
|
||||
@@ -89,15 +87,6 @@ tests/sndcp_xid/sndcp_xid_test
|
||||
tests/slhc/slhc_test
|
||||
tests/v42bis/v42bis_test
|
||||
tests/nanobts_omlattr/nanobts_omlattr_test
|
||||
tests/msc_vlr/msc_vlr_test_no_authen
|
||||
tests/msc_vlr/msc_vlr_test_gsm_authen
|
||||
tests/msc_vlr/msc_vlr_test_gsm_ciph
|
||||
tests/msc_vlr/msc_vlr_test_umts_authen
|
||||
tests/msc_vlr/msc_vlr_test_hlr_reject
|
||||
tests/msc_vlr/msc_vlr_test_hlr_timeout
|
||||
tests/msc_vlr/msc_vlr_test_ms_timeout
|
||||
tests/msc_vlr/msc_vlr_test_reject_concurrency
|
||||
tests/msc_vlr/msc_vlr_test_rest
|
||||
|
||||
tests/atconfig
|
||||
tests/atlocal
|
||||
|
||||
@@ -9,7 +9,7 @@ implementing protocol stacks and functional elements, including
|
||||
* OsmoBSC - a pure GSM BSC, speaking Abis/IP to the BTS and A/IP to the MSC
|
||||
* OsmoBSC-MGCP - MGCP helper to the OsmoBSC software
|
||||
* OsmoNITB - a BSC+MSC+VLR+HLR+SMSC "Network in the box".
|
||||
* OsmoMSC - a voice CN with A/IP and IuCS/IP towards the BSC and/or HNB-GW
|
||||
* OsmoCSCN - a voice CN with A/IP and IuCS/IP towards the BSC and/or HNB-GW
|
||||
* OsmoSGSN - a GPRS SGSN with Gb/IP and IuPS/IP towards the PCU and/or HNB-GW
|
||||
* Osmo-GbProxy - a Proxy to aggregate many Gb links as one Gb link to the SGSN
|
||||
* OsmoBSCNAT - a gateway aggregating many A links as one A link to the MSC
|
||||
|
||||
@@ -62,7 +62,7 @@ fi
|
||||
AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
|
||||
AC_SUBST(osmo_ac_build_bsc)
|
||||
|
||||
# Enable/disable smpp support in the msc?
|
||||
# Enable/disable smpp support in the nitb?
|
||||
AC_ARG_ENABLE([smpp], [AS_HELP_STRING([--enable-smpp], [Build the SMPP interface])],
|
||||
[osmo_ac_build_smpp="$enableval"],[osmo_ac_build_smpp="no"])
|
||||
if test "$osmo_ac_build_smpp" = "yes" ; then
|
||||
@@ -211,6 +211,18 @@ AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
|
||||
AC_MSG_RESULT([$enable_ext_tests])
|
||||
AM_CONDITIONAL(ENABLE_EXT_TESTS, test "x$enable_ext_tests" = "xyes")
|
||||
|
||||
|
||||
# Enable/disable ussd_proxy utility
|
||||
AC_ARG_ENABLE([ussd_proxy], [AS_HELP_STRING([--enable-ussd-proxy], [Build the USSD MAP SUP to SIP proxy])],
|
||||
[osmo_ac_build_ussd_proxy="$enableval"],[osmo_ac_build_ussd_proxy="no"])
|
||||
if test "$osmo_ac_build_ussd_proxy" = "yes" ; then
|
||||
PKG_CHECK_MODULES(LIBSOFIA_SIP_UA, sofia-sip-ua >= 1.10)
|
||||
AC_DEFINE(BUILD_USSD_PROXY, 1, [Define if we want to build ussd_proxy])
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_USSD_PROXY, test "x$osmo_ac_build_ussd_proxy" = "xyes")
|
||||
AC_SUBST(osmo_ac_build_smpp)
|
||||
|
||||
|
||||
dnl Generate the output
|
||||
AM_CONFIG_HEADER(bscconfig.h)
|
||||
|
||||
@@ -222,23 +234,24 @@ AC_OUTPUT(
|
||||
src/libtrau/Makefile
|
||||
src/libbsc/Makefile
|
||||
src/libmsc/Makefile
|
||||
src/libvlr/Makefile
|
||||
src/libmgcp/Makefile
|
||||
src/libcommon/Makefile
|
||||
src/libfilter/Makefile
|
||||
src/libiu/Makefile
|
||||
src/libcommon-cs/Makefile
|
||||
src/osmo-msc/Makefile
|
||||
src/osmo-nitb/Makefile
|
||||
src/osmo-bsc/Makefile
|
||||
src/osmo-bsc_nat/Makefile
|
||||
src/osmo-bsc_mgcp/Makefile
|
||||
src/ipaccess/Makefile
|
||||
src/utils/Makefile
|
||||
src/gprs/Makefile
|
||||
src/reg-proxy/Makefile
|
||||
src/ussd-proxy/Makefile
|
||||
tests/Makefile
|
||||
tests/atlocal
|
||||
tests/libiudummy/Makefile
|
||||
tests/gsm0408/Makefile
|
||||
tests/db/Makefile
|
||||
tests/channel/Makefile
|
||||
tests/bsc/Makefile
|
||||
tests/bsc-nat/Makefile
|
||||
@@ -259,9 +272,7 @@ AC_OUTPUT(
|
||||
tests/slhc/Makefile
|
||||
tests/v42bis/Makefile
|
||||
tests/nanobts_omlattr/Makefile
|
||||
tests/vlr/Makefile
|
||||
tests/msc_vlr/Makefile
|
||||
tests/sms_queue/Makefile
|
||||
tests/ussd/Makefile
|
||||
doc/Makefile
|
||||
doc/examples/Makefile
|
||||
Makefile)
|
||||
|
||||
@@ -1,26 +1,5 @@
|
||||
#!/usr/bin/python
|
||||
# -*- mode: python-mode; py-indent-tabs-mode: nil -*-
|
||||
"""
|
||||
/*
|
||||
* Copyright (C) 2016 sysmocom s.f.m.c. GmbH
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
"""
|
||||
|
||||
from optparse import OptionParser
|
||||
from ipa import Ctrl
|
||||
|
||||
@@ -6,7 +6,7 @@ log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging timestamp 0
|
||||
logging level all debug
|
||||
logging level all everything
|
||||
logging level rll notice
|
||||
logging level cc notice
|
||||
logging level mm notice
|
||||
@@ -22,14 +22,14 @@ log stderr
|
||||
logging level ho notice
|
||||
logging level db notice
|
||||
logging level ref notice
|
||||
logging level gprs debug
|
||||
logging level gprs everything
|
||||
logging level ns info
|
||||
logging level bssgp debug
|
||||
logging level llc debug
|
||||
logging level sndcp debug
|
||||
logging level bssgp everything
|
||||
logging level llc everything
|
||||
logging level sndcp everything
|
||||
logging level nat notice
|
||||
logging level ctrl notice
|
||||
logging level smpp debug
|
||||
logging level smpp everything
|
||||
logging level lglobal notice
|
||||
logging level llapd notice
|
||||
logging level linp notice
|
||||
|
||||
@@ -6,7 +6,7 @@ log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging timestamp 0
|
||||
logging level all debug
|
||||
logging level all everything
|
||||
logging level gprs debug
|
||||
logging level ns info
|
||||
logging level bssgp debug
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
!
|
||||
! OsmoMSC configuration saved from vty
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
network
|
||||
network country code 1
|
||||
mobile network code 1
|
||||
short name OsmoMSC
|
||||
long name OsmoMSC
|
||||
auth policy closed
|
||||
location updating reject cause 13
|
||||
encryption a5 0
|
||||
rrlp mode none
|
||||
mm info 1
|
||||
msc
|
||||
assign-tmsi
|
||||
@@ -10,11 +10,9 @@ noinst_HEADERS = \
|
||||
bsc_nat_callstats.h \
|
||||
bsc_nat_sccp.h \
|
||||
bsc_rll.h \
|
||||
bsc_subscriber.h \
|
||||
bss.h \
|
||||
bts_ipaccess_nanobts_omlattr.h \
|
||||
chan_alloc.h \
|
||||
common.h \
|
||||
common_bsc.h \
|
||||
common_cs.h \
|
||||
crc24.h \
|
||||
@@ -33,7 +31,6 @@ noinst_HEADERS = \
|
||||
gprs_sndcp_dcomp.h \
|
||||
gprs_sndcp_pcomp.h \
|
||||
gprs_sndcp_xid.h \
|
||||
gprs_subscriber.h \
|
||||
gprs_utils.h \
|
||||
gsm_04_08.h \
|
||||
gsm_04_11.h \
|
||||
@@ -47,18 +44,14 @@ noinst_HEADERS = \
|
||||
handover_decision.h \
|
||||
ipaccess.h \
|
||||
iu.h \
|
||||
iucs.h \
|
||||
iucs_ranap.h \
|
||||
meas_feed.h \
|
||||
meas_rep.h \
|
||||
mgcp.h \
|
||||
mgcp_internal.h \
|
||||
mgcp_transcode.h \
|
||||
mgcpgw_client.h \
|
||||
misdn.h \
|
||||
mncc.h \
|
||||
mncc_int.h \
|
||||
msc_ifaces.h \
|
||||
nat_rewrite_trie.h \
|
||||
network_listen.h \
|
||||
oap_client.h \
|
||||
@@ -67,7 +60,7 @@ noinst_HEADERS = \
|
||||
osmo_bsc_grace.h \
|
||||
osmo_bsc_rf.h \
|
||||
osmo_msc.h \
|
||||
bsc_msc_data.h \
|
||||
osmo_msc_data.h \
|
||||
osmux.h \
|
||||
paging.h \
|
||||
rest_octets.h \
|
||||
@@ -87,7 +80,6 @@ noinst_HEADERS = \
|
||||
trau_mux.h \
|
||||
trau_upqueue.h \
|
||||
ussd.h \
|
||||
vlr.h \
|
||||
vty.h \
|
||||
v42bis.h \
|
||||
v42bis_private.h \
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
struct gsm_bts;
|
||||
struct gsm_lchan;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_bts_trx_ts;
|
||||
|
||||
#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#define _AUTH_H
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
struct gsm_auth_tuple;
|
||||
struct gsm_subscriber;
|
||||
|
||||
enum auth_action {
|
||||
AUTH_ERROR = -1, /* Internal error */
|
||||
@@ -19,4 +21,8 @@ static inline const char *auth_action_str(enum auth_action a)
|
||||
return get_value_string(auth_action_names, a);
|
||||
}
|
||||
|
||||
int auth_get_tuple_for_subscr(enum gsm_auth_policy auth_policy,
|
||||
struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr, int key_seq);
|
||||
|
||||
#endif /* _AUTH_H */
|
||||
|
||||
@@ -41,9 +41,6 @@ struct bsc_api {
|
||||
*/
|
||||
void (*mr_config)(struct gsm_subscriber_connection *conn,
|
||||
struct gsm_lchan *lchan, int full_rate);
|
||||
|
||||
/** Callback for additional actions during conn cleanup */
|
||||
void (*conn_cleanup)(struct gsm_subscriber_connection *conn);
|
||||
};
|
||||
|
||||
int bsc_api_init(struct gsm_network *network, struct bsc_api *api);
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/* GSM subscriber details for use in BSC land */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
|
||||
struct log_target;
|
||||
|
||||
struct bsc_subscr {
|
||||
struct llist_head entry;
|
||||
int use_count;
|
||||
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
uint32_t tmsi;
|
||||
uint16_t lac;
|
||||
};
|
||||
|
||||
const char *bsc_subscr_name(struct bsc_subscr *bsub);
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list,
|
||||
const char *imsi);
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct llist_head *list,
|
||||
uint32_t tmsi);
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
|
||||
const char *imsi);
|
||||
struct bsc_subscr *bsc_subscr_find_by_tmsi(struct llist_head *list,
|
||||
uint32_t tmsi);
|
||||
|
||||
void bsc_subscr_set_imsi(struct bsc_subscr *bsub, const char *imsi);
|
||||
|
||||
struct bsc_subscr *_bsc_subscr_get(struct bsc_subscr *bsub,
|
||||
const char *file, int line);
|
||||
struct bsc_subscr *_bsc_subscr_put(struct bsc_subscr *bsub,
|
||||
const char *file, int line);
|
||||
#define bsc_subscr_get(bsub) _bsc_subscr_get(bsub, __BASE_FILE__, __LINE__)
|
||||
#define bsc_subscr_put(bsub) _bsc_subscr_put(bsub, __BASE_FILE__, __LINE__)
|
||||
|
||||
void log_set_filter_bsc_subscr(struct log_target *target,
|
||||
struct bsc_subscr *bsub);
|
||||
@@ -25,7 +25,7 @@
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
/* Find an allocated channel for a specified subscriber */
|
||||
struct gsm_subscriber_connection *connection_for_subscr(struct vlr_subscr *vsub);
|
||||
struct gsm_subscriber_connection *connection_for_subscr(struct gsm_subscriber *subscr);
|
||||
|
||||
/* Allocate a logical channel (SDCCH, TCH, ...) */
|
||||
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type, int allow_bigger);
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
enum nsap_addr_enc {
|
||||
NSAP_ADDR_ENC_X213,
|
||||
NSAP_ADDR_ENC_V4RAW,
|
||||
};
|
||||
@@ -29,26 +29,53 @@ struct gsm_network;
|
||||
struct gsm_auth_info;
|
||||
struct gsm_auth_tuple;
|
||||
struct gsm_sms;
|
||||
struct gsm_subscriber;
|
||||
|
||||
/* one time initialisation */
|
||||
int db_init(const char *name);
|
||||
int db_prepare(void);
|
||||
int db_fini(void);
|
||||
|
||||
/* subscriber management */
|
||||
struct gsm_subscriber *db_create_subscriber(const char *imsi, uint64_t smin,
|
||||
uint64_t smax, bool alloc_exten);
|
||||
struct gsm_subscriber *db_get_subscriber(enum gsm_subscriber_field field,
|
||||
const char *subscr);
|
||||
int db_sync_subscriber(struct gsm_subscriber *subscriber);
|
||||
int db_subscriber_expire(void *priv, void (*callback)(void *priv, long long unsigned int id));
|
||||
int db_subscriber_alloc_tmsi(struct gsm_subscriber *subscriber);
|
||||
int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber, uint64_t smin,
|
||||
uint64_t smax);
|
||||
int db_subscriber_alloc_token(struct gsm_subscriber *subscriber, uint32_t* token);
|
||||
int db_subscriber_assoc_imei(struct gsm_subscriber *subscriber, char *imei);
|
||||
int db_subscriber_delete(struct gsm_subscriber *subscriber);
|
||||
int db_sync_equipment(struct gsm_equipment *equip);
|
||||
int db_subscriber_update(struct gsm_subscriber *subscriber);
|
||||
int db_subscriber_list_active(void (*list_cb)(struct gsm_subscriber*,void*), void*);
|
||||
|
||||
/* auth info */
|
||||
int db_get_authinfo_for_subscr(struct gsm_auth_info *ainfo,
|
||||
struct gsm_subscriber *subscr);
|
||||
int db_sync_authinfo_for_subscr(struct gsm_auth_info *ainfo,
|
||||
struct gsm_subscriber *subscr);
|
||||
int db_get_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr);
|
||||
int db_sync_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr);
|
||||
|
||||
/* SMS store-and-forward */
|
||||
int db_sms_store(struct gsm_sms *sms);
|
||||
struct gsm_sms *db_sms_get(struct gsm_network *net, unsigned long long id);
|
||||
struct gsm_sms *db_sms_get_next_unsent(struct gsm_network *net,
|
||||
unsigned long long min_sms_id,
|
||||
unsigned int max_failed);
|
||||
struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net,
|
||||
const char *last_msisdn,
|
||||
unsigned int max_failed);
|
||||
struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub,
|
||||
unsigned int max_failed);
|
||||
struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, unsigned long long min_id);
|
||||
struct gsm_sms *db_sms_get_unsent_by_subscr(struct gsm_network *net, unsigned long long min_subscr_id, unsigned int failed);
|
||||
struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr);
|
||||
int db_sms_mark_delivered(struct gsm_sms *sms);
|
||||
int db_sms_inc_deliver_attempts(struct gsm_sms *sms);
|
||||
int db_sms_delete_by_msisdn(const char *msisdn);
|
||||
|
||||
/* APDU blob storage */
|
||||
int db_apdu_blob_store(struct gsm_subscriber *subscr,
|
||||
uint8_t apdu_id_flags, uint8_t len,
|
||||
uint8_t *apdu);
|
||||
|
||||
/* Statistics counter storage */
|
||||
struct osmo_counter;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef _DEBUG_H
|
||||
#define _DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
@@ -37,9 +38,37 @@ enum {
|
||||
DRANAP,
|
||||
DSUA,
|
||||
DV42BIS,
|
||||
DVLR,
|
||||
DIUCS,
|
||||
DSUP,
|
||||
DSS,
|
||||
Debug_LastEntry,
|
||||
};
|
||||
|
||||
/* context */
|
||||
#define BSC_CTX_LCHAN 0
|
||||
#define BSC_CTX_SUBSCR 1
|
||||
#define BSC_CTX_BTS 2
|
||||
#define BSC_CTX_SCCP 3
|
||||
|
||||
/* target */
|
||||
|
||||
enum {
|
||||
//DEBUG_FILTER_ALL = 1 << 0,
|
||||
LOG_FILTER_IMSI = 1 << 1,
|
||||
LOG_FILTER_NSVC = 1 << 2,
|
||||
LOG_FILTER_BVC = 1 << 3,
|
||||
};
|
||||
|
||||
/* we don't need a header dependency for this... */
|
||||
struct gprs_nsvc;
|
||||
struct bssgp_bvc_ctx;
|
||||
struct gsm_subscriber;
|
||||
|
||||
void log_set_imsi_filter(struct log_target *target, struct gsm_subscriber *subscr);
|
||||
void log_set_nsvc_filter(struct log_target *target,
|
||||
struct gprs_nsvc *nsvc);
|
||||
void log_set_bvc_filter(struct log_target *target,
|
||||
struct bssgp_bvc_ctx *bctx);
|
||||
|
||||
extern const struct log_info log_info;
|
||||
|
||||
#endif /* _DEBUG_H */
|
||||
|
||||
@@ -30,6 +30,6 @@ int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
|
||||
|
||||
time_t gprs_max_time_to_idle(void);
|
||||
|
||||
int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp);
|
||||
int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp, bool use_x213_nsap);
|
||||
|
||||
#endif /* _GPRS_GMM_H */
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
struct gprs_llc_lle;
|
||||
struct ctrl_handle;
|
||||
struct gprs_subscr;
|
||||
struct gsm_subscriber;
|
||||
|
||||
enum gsm48_gsm_cause;
|
||||
|
||||
@@ -73,7 +73,6 @@ enum gprs_t3350_mode {
|
||||
enum sgsn_auth_state {
|
||||
SGSN_AUTH_UNKNOWN,
|
||||
SGSN_AUTH_AUTHENTICATE,
|
||||
SGSN_AUTH_UMTS_RESYNC,
|
||||
SGSN_AUTH_ACCEPTED,
|
||||
SGSN_AUTH_REJECTED
|
||||
};
|
||||
@@ -226,7 +225,7 @@ struct sgsn_mm_ctx {
|
||||
/* the current GGSN look-up operation */
|
||||
struct sgsn_ggsn_lookup *ggsn_lookup;
|
||||
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
};
|
||||
|
||||
#define LOGMMCTXP(level, mm, fmt, args...) \
|
||||
@@ -434,7 +433,6 @@ struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx,
|
||||
/*
|
||||
* GPRS subscriber data
|
||||
*/
|
||||
#define GPRS_SUBSCRIBER_FIRST_CONTACT 0x00000001
|
||||
#define GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING (1 << 16)
|
||||
#define GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING (1 << 17)
|
||||
#define GPRS_SUBSCRIBER_CANCELLED (1 << 18)
|
||||
@@ -447,18 +445,14 @@ struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx,
|
||||
|
||||
int gprs_subscr_init(struct sgsn_instance *sgi);
|
||||
int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
|
||||
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx,
|
||||
const uint8_t *auts,
|
||||
const uint8_t *auts_rand);
|
||||
int gprs_subscr_auth_sync(struct gprs_subscr *subscr,
|
||||
const uint8_t *auts, const uint8_t *auts_rand);
|
||||
void gprs_subscr_cleanup(struct gprs_subscr *subscr);
|
||||
struct gprs_subscr *gprs_subscr_get_or_create(const char *imsi);
|
||||
struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx( struct sgsn_mm_ctx *mmctx);
|
||||
struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi);
|
||||
void gprs_subscr_cancel(struct gprs_subscr *subscr);
|
||||
void gprs_subscr_update(struct gprs_subscr *subscr);
|
||||
void gprs_subscr_update_auth_info(struct gprs_subscr *subscr);
|
||||
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
|
||||
void gprs_subscr_cleanup(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi);
|
||||
struct gsm_subscriber *gprs_subscr_get_or_create_by_mmctx( struct sgsn_mm_ctx *mmctx);
|
||||
struct gsm_subscriber *gprs_subscr_get_by_imsi(const char *imsi);
|
||||
void gprs_subscr_cancel(struct gsm_subscriber *subscr);
|
||||
void gprs_subscr_update(struct gsm_subscriber *subscr);
|
||||
void gprs_subscr_update_auth_info(struct gsm_subscriber *subscr);
|
||||
int gprs_subscr_rx_gsup_message(struct msgb *msg);
|
||||
|
||||
/* Called on subscriber data updates */
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/* GPRS subscriber details for use in SGSN land */
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
|
||||
extern struct llist_head * const gprs_subscribers;
|
||||
|
||||
struct gprs_subscr {
|
||||
struct llist_head entry;
|
||||
int use_count;
|
||||
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
uint32_t tmsi;
|
||||
char imei[GSM23003_IMEISV_NUM_DIGITS+1];
|
||||
bool authorized;
|
||||
bool keep_in_ram;
|
||||
uint32_t flags;
|
||||
uint16_t lac;
|
||||
|
||||
struct sgsn_subscriber_data *sgsn_data;
|
||||
};
|
||||
|
||||
struct gprs_subscr *_gprs_subscr_get(struct gprs_subscr *gsub,
|
||||
const char *file, int line);
|
||||
struct gprs_subscr *_gprs_subscr_put(struct gprs_subscr *gsub,
|
||||
const char *file, int line);
|
||||
#define gprs_subscr_get(gsub) _gprs_subscr_get(gsub, __BASE_FILE__, __LINE__)
|
||||
#define gprs_subscr_put(gsub) _gprs_subscr_put(gsub, __BASE_FILE__, __LINE__)
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
struct msgb;
|
||||
struct gsm_bts;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_network;
|
||||
struct gsm_trans;
|
||||
struct gsm_subscriber_connection;
|
||||
struct amr_multirate_conf;
|
||||
struct amr_mode;
|
||||
struct bsc_subscr;
|
||||
|
||||
#define GSM48_ALLOC_SIZE 2048
|
||||
#define GSM48_ALLOC_HEADROOM 256
|
||||
@@ -39,9 +39,6 @@ static inline void set_radio_link_timeout(struct gsm48_cell_options *cell_option
|
||||
cell_options->radio_link_timeout = (value >> 2) - 1;
|
||||
}
|
||||
|
||||
void cm_service_request_concludes(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg);
|
||||
|
||||
/* config options controlling the behaviour of the lower leves */
|
||||
void gsm0408_allow_everyone(int allow);
|
||||
void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
|
||||
@@ -49,6 +46,7 @@ void gsm0408_clear_all_trans(struct gsm_network *net, int protocol);
|
||||
int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id);
|
||||
int gsm0408_new_conn(struct gsm_subscriber_connection *conn);
|
||||
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *bts, uint8_t ra);
|
||||
/* don't use "enum gsm_chreq_reason_t" to avoid circular dependency */
|
||||
int get_reason_by_chreq(uint8_t ra, int neci);
|
||||
@@ -80,10 +78,7 @@ int decode_bcd_number(char *output, int output_len, const uint8_t *bcd_lv,
|
||||
int send_siemens_mrpci(struct gsm_lchan *lchan, uint8_t *classmark2_lv);
|
||||
int gsm48_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type);
|
||||
int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, uint8_t *mi_type);
|
||||
|
||||
/* TODO MSCSPLIT remove gsm48_handle_paging_resp() */
|
||||
int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg, struct bsc_subscr *bsub);
|
||||
int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, struct msgb *msg, struct gsm_subscriber *subscr);
|
||||
|
||||
int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t lchan_mode);
|
||||
int gsm48_rx_rr_modif_ack(struct msgb *msg);
|
||||
@@ -99,4 +94,8 @@ void allocate_security_operation(struct gsm_subscriber_connection *conn);
|
||||
|
||||
int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, struct amr_mode *modes);
|
||||
|
||||
int gsm0408_authorize(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause);
|
||||
void release_loc_updating_req(struct gsm_subscriber_connection *conn, int release);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
#include <osmocom/gsm/protocol/gsm_04_11.h>
|
||||
|
||||
struct vlr_subscr;
|
||||
struct gsm_subscriber_connection;
|
||||
struct gsm_trans;
|
||||
|
||||
#define UM_SAPI_SMS 3 /* See GSM 04.05/04.06 */
|
||||
|
||||
/* SMS deliver PDU */
|
||||
@@ -33,16 +29,17 @@ int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
struct gsm_sms *sms_alloc(void);
|
||||
void sms_free(struct gsm_sms *sms);
|
||||
struct gsm_sms *sms_from_text(struct vlr_subscr *receiver,
|
||||
struct vlr_subscr *sender,
|
||||
int dcs, const char *text);
|
||||
struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, struct gsm_subscriber *sender, int dcs, const char *text);
|
||||
|
||||
void _gsm411_sms_trans_free(struct gsm_trans *trans);
|
||||
int gsm411_send_sms_subscr(struct vlr_subscr *vsub,
|
||||
int gsm411_send_sms_subscr(struct gsm_subscriber *subscr,
|
||||
struct gsm_sms *sms);
|
||||
int gsm411_send_sms(struct gsm_subscriber_connection *conn,
|
||||
struct gsm_sms *sms);
|
||||
void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn);
|
||||
|
||||
int gsm411_send_rp_msg_subscr(struct gsm_subscriber *subscr,
|
||||
struct msgb *rp);
|
||||
|
||||
uint8_t sms_next_rp_msg_ref(uint8_t *next_rp_ref);
|
||||
#endif
|
||||
|
||||
@@ -7,12 +7,17 @@
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
|
||||
const struct msgb *in_msg, const char* response_text,
|
||||
const struct ss_request *req);
|
||||
int gsm0480_send_component(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg,
|
||||
struct ss_header* reqhdr);
|
||||
|
||||
int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
|
||||
const struct msgb *msg,
|
||||
const struct ss_request *request);
|
||||
uint8_t invoke_id,
|
||||
uint8_t transaction_id);
|
||||
|
||||
struct msgb *gsm0480_compose_ussd_component(struct ss_request* req);
|
||||
|
||||
|
||||
|
||||
int msc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level,
|
||||
const char *text);
|
||||
|
||||
@@ -13,10 +13,9 @@
|
||||
|
||||
#include <osmocom/crypt/auth.h>
|
||||
|
||||
#include <openbsc/common.h>
|
||||
#include <openbsc/rest_octets.h>
|
||||
#include <openbsc/common_cs.h>
|
||||
#include <openbsc/mgcpgw_client.h>
|
||||
#include <openbsc/gsup_client.h>
|
||||
|
||||
/** annotations for msgb ownership */
|
||||
#define __uses
|
||||
@@ -25,15 +24,9 @@
|
||||
|
||||
struct mncc_sock_state;
|
||||
struct gsm_subscriber_group;
|
||||
struct bsc_subscr;
|
||||
struct vlr_instance;
|
||||
struct vlr_subscr;
|
||||
struct ue_conn_ctx;
|
||||
|
||||
#define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3]
|
||||
|
||||
#define tmsi_from_string(str) strtoul(str, NULL, 10)
|
||||
|
||||
enum gsm_security_event {
|
||||
GSM_SECURITY_NOAVAIL,
|
||||
GSM_SECURITY_AUTH_FAILED,
|
||||
@@ -67,6 +60,21 @@ struct gsm_auth_tuple {
|
||||
};
|
||||
#define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */
|
||||
|
||||
/*
|
||||
* LOCATION UPDATING REQUEST state
|
||||
*
|
||||
* Our current operation is:
|
||||
* - Get imei/tmsi
|
||||
* - Accept/Reject according to global policy
|
||||
*/
|
||||
struct gsm_loc_updating_operation {
|
||||
struct osmo_timer_list updating_timer;
|
||||
unsigned int waiting_for_imsi : 1;
|
||||
unsigned int waiting_for_imei : 1;
|
||||
unsigned int waiting_for_remote_accept : 1;
|
||||
unsigned int key_seq : 4;
|
||||
};
|
||||
|
||||
/*
|
||||
* AUTHENTICATION/CIPHERING state
|
||||
*/
|
||||
@@ -98,49 +106,12 @@ struct neigh_meas_proc {
|
||||
uint8_t last_seen_nr;
|
||||
};
|
||||
|
||||
enum ran_type {
|
||||
RAN_UNKNOWN,
|
||||
RAN_GERAN_A, /* 2G / A-interface */
|
||||
RAN_UTRAN_IU, /* 3G / Iu-interface (IuCS or IuPS) */
|
||||
};
|
||||
|
||||
extern const struct value_string ran_type_names[];
|
||||
static inline const char *ran_type_name(enum ran_type val)
|
||||
{ return get_value_string(ran_type_names, val); }
|
||||
|
||||
struct gsm_classmark {
|
||||
bool classmark1_set;
|
||||
struct gsm48_classmark1 classmark1;
|
||||
uint8_t classmark2_len;
|
||||
uint8_t classmark2[3];
|
||||
uint8_t classmark3_len;
|
||||
uint8_t classmark3[14];
|
||||
};
|
||||
|
||||
enum integrity_protection_state {
|
||||
INTEGRITY_PROTECTION_NONE = 0,
|
||||
INTEGRITY_PROTECTION_IK = 1,
|
||||
INTEGRITY_PROTECTION_IK_CK = 2,
|
||||
};
|
||||
|
||||
/* active radio connection of a mobile subscriber */
|
||||
struct gsm_subscriber_connection {
|
||||
/* global linked list of subscriber_connections */
|
||||
struct llist_head entry;
|
||||
|
||||
/* usage count. If this drops to zero, we start the release
|
||||
* towards A/Iu */
|
||||
uint32_t use_count;
|
||||
|
||||
/* The MS has opened the conn with a CM Service Request, and we shall
|
||||
* keep it open for an actual request (or until timeout). */
|
||||
bool received_cm_service_request;
|
||||
|
||||
/* libbsc subscriber information (if available) */
|
||||
struct bsc_subscr *bsub;
|
||||
|
||||
/* libmsc/libvlr subscriber information (if available) */
|
||||
struct vlr_subscr *vsub;
|
||||
/* To whom we are allocated at the moment */
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
/* LU expiration handling */
|
||||
uint8_t expire_timer_stopped;
|
||||
@@ -150,11 +121,10 @@ struct gsm_subscriber_connection {
|
||||
/*
|
||||
* Operations that have a state and might be pending
|
||||
*/
|
||||
struct gsm_loc_updating_operation *loc_operation;
|
||||
struct gsm_security_operation *sec_operation;
|
||||
struct gsm_anchor_operation *anch_operation;
|
||||
|
||||
struct osmo_fsm_inst *conn_fsm;
|
||||
|
||||
/* Are we part of a special "silent" call */
|
||||
int silent_call;
|
||||
|
||||
@@ -169,7 +139,7 @@ struct gsm_subscriber_connection {
|
||||
/* back pointers */
|
||||
struct gsm_network *network;
|
||||
|
||||
bool in_release;
|
||||
int in_release;
|
||||
struct gsm_lchan *lchan; /* BSC */
|
||||
struct gsm_lchan *ho_lchan; /* BSC */
|
||||
struct gsm_bts *bts; /* BSC */
|
||||
@@ -178,23 +148,6 @@ struct gsm_subscriber_connection {
|
||||
struct osmo_timer_list T10; /* BSC */
|
||||
struct gsm_lchan *secondary_lchan; /* BSC */
|
||||
|
||||
/* connected via 2G or 3G? */
|
||||
enum ran_type via_ran;
|
||||
|
||||
struct gsm_classmark classmark;
|
||||
|
||||
uint16_t lac;
|
||||
struct gsm_encr encr;
|
||||
|
||||
/* which Iu-CS connection, if any. */
|
||||
struct {
|
||||
struct ue_conn_ctx *ue_ctx;
|
||||
int integrity_protection;
|
||||
unsigned int mgcp_rtp_endpoint;
|
||||
uint16_t mgcp_rtp_port_ue;
|
||||
uint16_t mgcp_rtp_port_cn;
|
||||
uint8_t rab_id;
|
||||
} iu;
|
||||
};
|
||||
|
||||
|
||||
@@ -253,8 +206,8 @@ enum {
|
||||
MSC_CTR_LOC_UPDATE_TYPE_NORMAL,
|
||||
MSC_CTR_LOC_UPDATE_TYPE_PERIODIC,
|
||||
MSC_CTR_LOC_UPDATE_TYPE_DETACH,
|
||||
MSC_CTR_LOC_UPDATE_FAILED,
|
||||
MSC_CTR_LOC_UPDATE_COMPLETED,
|
||||
MSC_CTR_LOC_UPDATE_RESP_REJECT,
|
||||
MSC_CTR_LOC_UPDATE_RESP_ACCEPT,
|
||||
MSC_CTR_SMS_SUBMITTED,
|
||||
MSC_CTR_SMS_NO_RECEIVER,
|
||||
MSC_CTR_SMS_DELIVERED,
|
||||
@@ -275,8 +228,8 @@ static const struct rate_ctr_desc msc_ctr_description[] = {
|
||||
[MSC_CTR_LOC_UPDATE_TYPE_NORMAL] = {"loc_update_type.normal", "Received location update normal requests."},
|
||||
[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC] = {"loc_update_type.periodic", "Received location update periodic requests."},
|
||||
[MSC_CTR_LOC_UPDATE_TYPE_DETACH] = {"loc_update_type.detach", "Received location update detach indication."},
|
||||
[MSC_CTR_LOC_UPDATE_FAILED] = {"loc_update_resp.failed", "Rejected location updates."},
|
||||
[MSC_CTR_LOC_UPDATE_COMPLETED] = {"loc_update_resp.completed", "Successful location updates."},
|
||||
[MSC_CTR_LOC_UPDATE_RESP_REJECT] = {"loc_update_resp.reject", "Sent location update reject responses."},
|
||||
[MSC_CTR_LOC_UPDATE_RESP_ACCEPT] = {"loc_update_resp.accept", "Sent location update accept responses."},
|
||||
[MSC_CTR_SMS_SUBMITTED] = {"sms.submitted", "Received a RPDU from a MS (MO)."},
|
||||
[MSC_CTR_SMS_NO_RECEIVER] = {"sms.no_receiver", "Counts SMS which couldn't routed because no receiver found."},
|
||||
[MSC_CTR_SMS_DELIVERED] = {"sms.delivered", "Global SMS Deliver attempts."},
|
||||
@@ -315,6 +268,8 @@ enum gsm_auth_policy {
|
||||
GSM_AUTH_POLICY_ACCEPT_ALL, /* accept everyone, even if not authorized in DB */
|
||||
GSM_AUTH_POLICY_TOKEN, /* accept first, send token per sms, then revoke authorization */
|
||||
GSM_AUTH_POLICY_REGEXP, /* accept IMSIs matching given regexp */
|
||||
GSM_AUTH_POLICY_REMOTE,
|
||||
GSM_AUTH_POLICY_REMOTE_CLOSED
|
||||
};
|
||||
|
||||
#define GSM_T3101_DEFAULT 10
|
||||
@@ -330,12 +285,6 @@ struct gsm_tz {
|
||||
};
|
||||
|
||||
struct gsm_network {
|
||||
/* TODO MSCSPLIT the gsm_network struct is basically a kitchen sink for
|
||||
* global settings and variables, "madly" mixing BSC and MSC stuff. Split
|
||||
* this in e.g. struct osmo_bsc and struct osmo_msc, with the things
|
||||
* these have in common, like country and network code, put in yet
|
||||
* separate structs and placed as members in osmo_bsc and osmo_msc. */
|
||||
|
||||
/* global parameters */
|
||||
uint16_t country_code;
|
||||
uint16_t network_code;
|
||||
@@ -346,7 +295,6 @@ struct gsm_network {
|
||||
char *authorized_reg_str;
|
||||
enum gsm48_reject_value reject_cause;
|
||||
int a5_encryption;
|
||||
bool authentication_required;
|
||||
int neci;
|
||||
int send_mm_info;
|
||||
struct {
|
||||
@@ -374,13 +322,11 @@ struct gsm_network {
|
||||
struct mncc_sock_state *mncc_state;
|
||||
mncc_recv_cb_t mncc_recv;
|
||||
struct llist_head upqueue;
|
||||
/*
|
||||
* TODO: Move the trans_list into the subscriber connection and
|
||||
* create a pending list for MT transactions. These exist before
|
||||
* we have a subscriber connection.
|
||||
*/
|
||||
struct llist_head trans_list;
|
||||
struct bsc_api *bsc_api;
|
||||
struct gsup_client *hlr_sup_client;
|
||||
struct gsup_client *ussd_sup_client;
|
||||
struct gsup_client *sms_client;
|
||||
|
||||
unsigned int num_bts;
|
||||
struct llist_head bts_list;
|
||||
@@ -407,7 +353,7 @@ struct gsm_network {
|
||||
enum rrlp_mode mode;
|
||||
} rrlp;
|
||||
|
||||
enum gsm_chan_t ctype_by_chreq[18];
|
||||
enum gsm_chan_t ctype_by_chreq[16];
|
||||
|
||||
/* Use a TCH for handling requests of type paging any */
|
||||
int pag_any_tch;
|
||||
@@ -420,8 +366,12 @@ struct gsm_network {
|
||||
bool auto_assign_exten;
|
||||
uint64_t ext_min;
|
||||
uint64_t ext_max;
|
||||
struct gsm_subscriber_group *subscr_group;
|
||||
struct gsm_sms_queue *sms_queue;
|
||||
|
||||
/* nitb related control */
|
||||
int avoid_tmsi;
|
||||
|
||||
/* control interface */
|
||||
struct ctrl_handle *ctrl;
|
||||
|
||||
@@ -436,34 +386,8 @@ struct gsm_network {
|
||||
* contexts. */
|
||||
/* TODO: in OsmoNITB, tz-override used to be BTS-specific. To enable
|
||||
* BTS|RNC specific timezone overrides for multi-tz networks in
|
||||
* OsmoMSC, this should be tied to the location area code (LAC). */
|
||||
* OsmoCSCN, this should be tied to the location area code (LAC). */
|
||||
struct gsm_tz tz;
|
||||
|
||||
/* List of all struct bsc_subscr used in libbsc. This llist_head is
|
||||
* allocated so that the llist_head pointer itself can serve as a
|
||||
* talloc context (useful to not have to pass the entire gsm_network
|
||||
* struct to the bsc_subscr_* API, and for bsc_susbscr unit tests to
|
||||
* not require gsm_data.h). In an MSC-without-BSC environment, this
|
||||
* pointer is NULL to indicate absence of a bsc_subscribers list. */
|
||||
struct llist_head *bsc_subscribers;
|
||||
|
||||
/* MSC: GSUP server address of the HLR */
|
||||
const char *gsup_server_addr_str;
|
||||
uint16_t gsup_server_port;
|
||||
|
||||
struct vlr_instance *vlr;
|
||||
|
||||
/* Periodic location update default value */
|
||||
uint8_t t3212;
|
||||
|
||||
struct {
|
||||
struct mgcpgw_client_conf conf;
|
||||
struct mgcpgw_client *client;
|
||||
} mgcpgw;
|
||||
|
||||
struct {
|
||||
enum nsap_addr_enc rab_assign_addr_enc;
|
||||
} iu;
|
||||
};
|
||||
|
||||
struct osmo_esme;
|
||||
@@ -486,7 +410,7 @@ struct gsm_sms_addr {
|
||||
|
||||
struct gsm_sms {
|
||||
unsigned long long id;
|
||||
struct vlr_subscr *receiver;
|
||||
struct gsm_subscriber *receiver;
|
||||
struct gsm_sms_addr src, dst;
|
||||
enum gsm_sms_source_id source;
|
||||
|
||||
@@ -514,6 +438,10 @@ extern void talloc_ctx_init(void *ctx_root);
|
||||
|
||||
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
|
||||
|
||||
/* Get reference to a neighbor cell on a given BCCH ARFCN */
|
||||
struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
|
||||
uint16_t arfcn, uint8_t bsic);
|
||||
|
||||
enum gsm_bts_type parse_btstype(const char *arg);
|
||||
const char *btstype2str(enum gsm_bts_type type);
|
||||
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
|
||||
@@ -596,6 +524,7 @@ int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);
|
||||
|
||||
int gsm48_ra_id_by_bts(uint8_t *buf, struct gsm_bts *bts);
|
||||
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
|
||||
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
|
||||
|
||||
int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat);
|
||||
int gsm_bts_model_register(struct gsm_bts_model *model);
|
||||
@@ -627,7 +556,7 @@ extern const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1];
|
||||
|
||||
/* control interface handling */
|
||||
int bsc_base_ctrl_cmds_install(void);
|
||||
int msc_ctrl_cmds_install(struct gsm_network *net);
|
||||
int msc_ctrl_cmds_install(void);
|
||||
|
||||
/* dependency handling */
|
||||
void bts_depend_mark(struct gsm_bts *bts, int dep);
|
||||
@@ -635,6 +564,4 @@ void bts_depend_clear(struct gsm_bts *bts, int dep);
|
||||
int bts_depend_check(struct gsm_bts *bts);
|
||||
int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other);
|
||||
|
||||
bool classmark_is_r99(struct gsm_classmark *cm);
|
||||
|
||||
#endif /* _GSM_DATA_H */
|
||||
|
||||
@@ -46,7 +46,6 @@ enum gsm_chreq_reason_t {
|
||||
GSM_CHREQ_REASON_CALL,
|
||||
GSM_CHREQ_REASON_LOCATION_UPD,
|
||||
GSM_CHREQ_REASON_OTHER,
|
||||
GSM_CHREQ_REASON_PDCH,
|
||||
};
|
||||
|
||||
/* lchans 0..3 are SDCCH in combined channel configuration,
|
||||
@@ -84,6 +83,7 @@ enum bts_gprs_mode {
|
||||
};
|
||||
|
||||
struct gsm_lchan;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_mncc;
|
||||
struct osmo_rtp_socket;
|
||||
struct rtp_socket;
|
||||
@@ -327,12 +327,6 @@ struct gsm_lchan {
|
||||
uint8_t last_cmr;
|
||||
uint32_t last_fn;
|
||||
} tch;
|
||||
|
||||
/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
|
||||
int16_t ms_t_offs;
|
||||
/* 3GPP TS 45.010 § 1.2 round trip propagation delay (in symbols) or -1 */
|
||||
int16_t p_offs;
|
||||
|
||||
/* BTS-side ciphering state (rx only, bi-directional, ...) */
|
||||
uint8_t ciph_state;
|
||||
uint8_t ciph_ns;
|
||||
|
||||
@@ -16,9 +16,67 @@
|
||||
|
||||
#define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001
|
||||
/* gprs_sgsn.h defines additional flags including and above bit 16 (0x10000) */
|
||||
#define tmsi_from_string(str) strtoul(str, NULL, 10)
|
||||
|
||||
#define GSM_SUBSCRIBER_NO_EXPIRATION 0x0
|
||||
|
||||
struct vty;
|
||||
struct sgsn_mm_ctx;
|
||||
struct sgsn_subscriber_data;
|
||||
|
||||
struct subscr_request;
|
||||
|
||||
struct gsm_subscriber_group {
|
||||
struct gsm_network *net;
|
||||
|
||||
int keep_subscr;
|
||||
};
|
||||
|
||||
struct gsm_equipment {
|
||||
long long unsigned int id;
|
||||
char imei[GSM23003_IMEISV_NUM_DIGITS+1];
|
||||
char name[GSM_NAME_LENGTH];
|
||||
|
||||
struct gsm48_classmark1 classmark1;
|
||||
uint8_t classmark2_len;
|
||||
uint8_t classmark2[3];
|
||||
uint8_t classmark3_len;
|
||||
uint8_t classmark3[14];
|
||||
};
|
||||
|
||||
struct gsm_subscriber {
|
||||
struct gsm_subscriber_group *group;
|
||||
long long unsigned int id;
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
uint32_t tmsi;
|
||||
uint16_t lac;
|
||||
char name[GSM_NAME_LENGTH];
|
||||
char extension[GSM_EXTENSION_LENGTH];
|
||||
int authorized;
|
||||
time_t expire_lu;
|
||||
|
||||
/* Don't delete subscribers even if group->keep_subscr is not set */
|
||||
int keep_in_ram;
|
||||
|
||||
/* Temporary field which is not stored in the DB/HLR */
|
||||
uint32_t flags;
|
||||
|
||||
/* Every user can only have one equipment in use at any given
|
||||
* point in time */
|
||||
struct gsm_equipment equipment;
|
||||
|
||||
/* for internal management */
|
||||
int use_count;
|
||||
struct llist_head entry;
|
||||
|
||||
/* pending requests */
|
||||
int is_paging;
|
||||
struct llist_head requests;
|
||||
|
||||
/* GPRS/SGSN related fields */
|
||||
struct sgsn_subscriber_data *sgsn_data;
|
||||
};
|
||||
|
||||
enum gsm_subscriber_field {
|
||||
GSM_SUBSCRIBER_IMSI,
|
||||
GSM_SUBSCRIBER_TMSI,
|
||||
@@ -32,37 +90,42 @@ enum gsm_subscriber_update_reason {
|
||||
GSM_SUBSCRIBER_UPDATE_EQUIPMENT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct for pending channel requests. This is managed in the
|
||||
* llist_head requests of each subscriber. The reference counting
|
||||
* should work in such a way that a subscriber with a pending request
|
||||
* remains in memory.
|
||||
*/
|
||||
struct subscr_request {
|
||||
struct llist_head entry;
|
||||
struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp,
|
||||
const char *imsi);
|
||||
struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_subscriber_group *sgrp,
|
||||
uint32_t tmsi);
|
||||
struct gsm_subscriber *subscr_get_by_imsi(struct gsm_subscriber_group *sgrp,
|
||||
const char *imsi);
|
||||
struct gsm_subscriber *subscr_get_by_extension(struct gsm_subscriber_group *sgrp,
|
||||
const char *ext);
|
||||
struct gsm_subscriber *subscr_get_by_id(struct gsm_subscriber_group *sgrp,
|
||||
unsigned long long id);
|
||||
struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
|
||||
const char *imsi);
|
||||
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
|
||||
struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
|
||||
uint32_t tmsi);
|
||||
struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
|
||||
const char *imsi);
|
||||
|
||||
/* human readable label to be able to log pending request kinds */
|
||||
const char *label;
|
||||
char *subscr_name(struct gsm_subscriber *subscr);
|
||||
|
||||
/* the callback data */
|
||||
gsm_cbfn *cbfn;
|
||||
void *param;
|
||||
};
|
||||
|
||||
int subscr_update(struct vlr_subscr *vsub, int reason);
|
||||
int subscr_purge_inactive(struct gsm_subscriber_group *sgrp);
|
||||
void subscr_update_from_db(struct gsm_subscriber *subscr);
|
||||
void subscr_expire(struct gsm_subscriber_group *sgrp);
|
||||
int subscr_update_expire_lu(struct gsm_subscriber *subscr, struct gsm_bts *bts);
|
||||
|
||||
/*
|
||||
* Paging handling with authentication
|
||||
*/
|
||||
struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub,
|
||||
gsm_cbfn *cbfn, void *param,
|
||||
const char *label);
|
||||
|
||||
struct subscr_request *subscr_request_channel(struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *param);
|
||||
void subscr_remove_request(struct subscr_request *req);
|
||||
int subscr_rx_paging_response(struct msgb *msg,
|
||||
struct gsm_subscriber_connection *conn);
|
||||
|
||||
int subscr_paging_dispatch(unsigned int hooknum, unsigned int event,
|
||||
struct msgb *msg, void *data, void *param);
|
||||
/* internal */
|
||||
struct gsm_subscriber *subscr_alloc(void);
|
||||
extern struct llist_head active_subscribers;
|
||||
|
||||
#endif /* _GSM_SUBSCR_H */
|
||||
|
||||
26
openbsc/include/openbsc/gsm_sup.h
Normal file
26
openbsc/include/openbsc/gsm_sup.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef _GSM_SUP_H
|
||||
#define _GSM_SUP_H
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <osmocom/gsm/gsm0480.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_11.h>
|
||||
|
||||
#define LOGGSUBSCRP(level, subscr, fmt, args...) \
|
||||
LOGP(DSUP, level, "SUBSCR(%s) " fmt, \
|
||||
(subscr) ? (subscr)->imsi : "---", \
|
||||
## args)
|
||||
|
||||
/* Callback for both HLR/auth and USSD SUP sockets */
|
||||
int sup_read_cb(struct gsup_client *sup_client, struct msgb *msg);
|
||||
|
||||
/*
|
||||
int subscr_query_auth_info(struct gsm_subscriber *subscr);
|
||||
*/
|
||||
int subscr_location_update(struct gsm_subscriber *subscr);
|
||||
int subscr_purge_ms(struct gsm_subscriber *subscr);
|
||||
|
||||
int subscr_tx_sms_message(struct gsm_subscriber *subscr,
|
||||
struct gsm411_rp_hdr *rph);
|
||||
|
||||
#endif /* _GSM_SUP_H */
|
||||
14
openbsc/include/openbsc/gsm_ussd_map.h
Normal file
14
openbsc/include/openbsc/gsm_ussd_map.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _GSM_USSD_MAP_H
|
||||
#define _GSM_USSD_MAP_H
|
||||
|
||||
#include <openbsc/gsup_client.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/gsm_ussd_map_proto.h>
|
||||
|
||||
int ussd_map_read_cb(struct gsup_client *sup_client,
|
||||
struct msgb *msg);
|
||||
|
||||
int ussd_map_tx_message(struct gsm_network *net, struct ss_header *req,
|
||||
const char *extension, uint32_t ref, const uint8_t *component_data);
|
||||
|
||||
#endif /* _GSM_USSD_MAP_H */
|
||||
25
openbsc/include/openbsc/gsm_ussd_map_proto.h
Normal file
25
openbsc/include/openbsc/gsm_ussd_map_proto.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef _GSM_USSD_MAP_PROTO_H
|
||||
#define _GSM_USSD_MAP_PROTO_H
|
||||
|
||||
#include <osmocom/gsm/gsm0480.h>
|
||||
|
||||
|
||||
enum {
|
||||
FMAP_MSISDN = 0x80
|
||||
};
|
||||
|
||||
int subscr_uss_message(struct msgb *msg,
|
||||
struct ss_header *req,
|
||||
const char* extension,
|
||||
uint32_t ref,
|
||||
const uint8_t *component_data);
|
||||
|
||||
int rx_uss_message_parse(const uint8_t* data,
|
||||
size_t len,
|
||||
struct ss_header *ss,
|
||||
uint32_t *ref,
|
||||
char* extention,
|
||||
size_t extention_len);
|
||||
|
||||
|
||||
#endif /* _GSM_USSD_MAP_PROTO_H */
|
||||
@@ -37,8 +37,6 @@ typedef int (*gsup_client_read_cb_t)(struct gsup_client *gsupc,
|
||||
struct msgb *msg);
|
||||
|
||||
struct gsup_client {
|
||||
const char *unit_name;
|
||||
|
||||
struct ipa_client_conn *link;
|
||||
gsup_client_read_cb_t read_cb;
|
||||
void *data;
|
||||
@@ -49,13 +47,13 @@ struct gsup_client {
|
||||
struct osmo_timer_list connect_timer;
|
||||
int is_connected;
|
||||
int got_ipa_pong;
|
||||
struct gsm_network *net;
|
||||
};
|
||||
|
||||
struct gsup_client *gsup_client_create(const char *unit_name,
|
||||
const char *ip_addr,
|
||||
struct gsup_client *gsup_client_create(const char *ip_addr,
|
||||
unsigned int tcp_port,
|
||||
gsup_client_read_cb_t read_cb,
|
||||
struct oap_client_config *oapc_config);
|
||||
struct oap_client_config *oap_config);
|
||||
|
||||
void gsup_client_destroy(struct gsup_client *gsupc);
|
||||
int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg);
|
||||
|
||||
@@ -1,25 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
|
||||
#include <openbsc/common.h>
|
||||
|
||||
struct sgsn_pdp_ctx;
|
||||
struct msgb;
|
||||
struct osmo_sccp_link;
|
||||
struct gsm_auth_tuple;
|
||||
struct gprs_ra_id;
|
||||
|
||||
struct RANAP_RAB_SetupOrModifiedItemIEs_s;
|
||||
struct RANAP_GlobalRNC_ID;
|
||||
struct RANAP_Cause;
|
||||
|
||||
/* Debugging switches from asn1c and osmo-iuh */
|
||||
extern int asn_debug;
|
||||
extern int asn1_xer_print;
|
||||
|
||||
struct ue_conn_ctx {
|
||||
struct llist_head list;
|
||||
@@ -27,7 +15,6 @@ struct ue_conn_ctx {
|
||||
uint32_t conn_id;
|
||||
int integrity_active;
|
||||
struct gprs_ra_id ra_id;
|
||||
enum nsap_addr_enc rab_assign_addr_enc;
|
||||
};
|
||||
|
||||
enum iu_event_type {
|
||||
@@ -71,8 +58,5 @@ int iu_rab_act(struct ue_conn_ctx *ue_ctx, struct msgb *msg);
|
||||
int iu_rab_deact(struct ue_conn_ctx *ue_ctx, uint8_t rab_id);
|
||||
int iu_tx_sec_mode_cmd(struct ue_conn_ctx *uectx, struct gsm_auth_tuple *tp,
|
||||
int send_ck, int new_key);
|
||||
int iu_tx_common_id(struct ue_conn_ctx *ue_ctx, const char *imsi);
|
||||
int iu_tx_release(struct ue_conn_ctx *ctx, const struct RANAP_Cause *cause);
|
||||
|
||||
void iu_vty_init(int iu_parent_node, enum nsap_addr_enc *rab_assign_addr_enc);
|
||||
int iu_vty_config_write(struct vty *vty, const char *indent);
|
||||
void iu_vty_init(int *asn_debug_p);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg,
|
||||
uint16_t *lac);
|
||||
|
||||
struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network,
|
||||
struct ue_conn_ctx *ue);
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
struct gsm_network;
|
||||
struct ue_conn_ctx;
|
||||
|
||||
int iucs_rx_ranap_event(struct gsm_network *network,
|
||||
struct ue_conn_ctx *ue_ctx, int type, void *data);
|
||||
@@ -170,21 +170,6 @@ enum mgcp_role {
|
||||
MGCP_BSC_NAT,
|
||||
};
|
||||
|
||||
enum mgcp_connection_mode {
|
||||
MGCP_CONN_NONE = 0,
|
||||
MGCP_CONN_RECV_ONLY = 1,
|
||||
MGCP_CONN_SEND_ONLY = 2,
|
||||
MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
|
||||
MGCP_CONN_LOOPBACK = 4 | MGCP_CONN_RECV_SEND,
|
||||
};
|
||||
|
||||
extern const struct value_string mgcp_connection_mode_strs[];
|
||||
|
||||
static inline const char *mgcp_cmode_name(enum mgcp_connection_mode mode)
|
||||
{
|
||||
return get_value_string(mgcp_connection_mode_strs, mode);
|
||||
}
|
||||
|
||||
struct mgcp_config {
|
||||
int source_port;
|
||||
char *local_ip;
|
||||
|
||||
@@ -28,6 +28,14 @@
|
||||
|
||||
#define CI_UNUSED 0
|
||||
|
||||
enum mgcp_connection_mode {
|
||||
MGCP_CONN_NONE = 0,
|
||||
MGCP_CONN_RECV_ONLY = 1,
|
||||
MGCP_CONN_SEND_ONLY = 2,
|
||||
MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
|
||||
MGCP_CONN_LOOPBACK = 4 | MGCP_CONN_RECV_SEND,
|
||||
};
|
||||
|
||||
enum mgcp_trunk_type {
|
||||
MGCP_TRUNK_VIRTUAL,
|
||||
MGCP_TRUNK_E1,
|
||||
@@ -64,7 +72,6 @@ struct mgcp_rtp_state {
|
||||
uint32_t stats_jitter;
|
||||
int32_t stats_transit;
|
||||
int stats_cycles;
|
||||
bool patched_first_rtp_payload;
|
||||
};
|
||||
|
||||
struct mgcp_rtp_codec {
|
||||
@@ -333,5 +340,3 @@ static inline const char *mgcp_bts_src_addr(struct mgcp_endpoint *endp)
|
||||
return endp->cfg->bts_ports.bind_addr;
|
||||
return endp->cfg->source_addr;
|
||||
}
|
||||
|
||||
int mgcp_msg_terminate_nul(struct msgb *msg);
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
enum mgcp_connection_mode;
|
||||
|
||||
struct msgb;
|
||||
struct mgcpgw_client;
|
||||
struct vty;
|
||||
|
||||
#define MGCPGW_CLIENT_LOCAL_ADDR_DEFAULT "0.0.0.0"
|
||||
#define MGCPGW_CLIENT_LOCAL_PORT_DEFAULT 0
|
||||
#define MGCPGW_CLIENT_REMOTE_ADDR_DEFAULT "127.0.0.1"
|
||||
#define MGCPGW_CLIENT_REMOTE_PORT_DEFAULT 2427
|
||||
|
||||
#define MSGB_CB_MGCP_TRANS_ID 0
|
||||
|
||||
typedef unsigned int mgcp_trans_id_t;
|
||||
|
||||
struct mgcpgw_client_conf {
|
||||
const char *local_addr;
|
||||
int local_port;
|
||||
const char *remote_addr;
|
||||
int remote_port;
|
||||
};
|
||||
|
||||
struct mgcp_response_head {
|
||||
int response_code;
|
||||
mgcp_trans_id_t trans_id;
|
||||
const char *comment;
|
||||
};
|
||||
|
||||
struct mgcp_response {
|
||||
char *body;
|
||||
struct mgcp_response_head head;
|
||||
uint16_t audio_port;
|
||||
};
|
||||
|
||||
/* Invoked when an MGCP response is received or sending failed. When the
|
||||
* response is passed as NULL, this indicates failure during transmission. */
|
||||
typedef void (* mgcp_response_cb_t )(struct mgcp_response *response, void *priv);
|
||||
|
||||
struct mgcp_response_pending {
|
||||
struct llist_head entry;
|
||||
|
||||
mgcp_trans_id_t trans_id;
|
||||
mgcp_response_cb_t response_cb;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
|
||||
void mgcpgw_client_conf_init(struct mgcpgw_client_conf *conf);
|
||||
|
||||
struct mgcpgw_client *mgcpgw_client_init(void *ctx,
|
||||
struct mgcpgw_client_conf *conf);
|
||||
int mgcpgw_client_connect(struct mgcpgw_client *mgcp);
|
||||
|
||||
const char *mgcpgw_client_remote_addr_str(struct mgcpgw_client *mgcp);
|
||||
uint16_t mgcpgw_client_remote_port(struct mgcpgw_client *mgcp);
|
||||
uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp);
|
||||
|
||||
unsigned int mgcpgw_client_next_endpoint(struct mgcpgw_client *client);
|
||||
|
||||
int mgcp_response_parse_params(struct mgcp_response *r);
|
||||
|
||||
int mgcpgw_client_tx(struct mgcpgw_client *mgcp, struct msgb *msg,
|
||||
mgcp_response_cb_t response_cb, void *priv);
|
||||
|
||||
struct msgb *mgcp_msg_crcx(struct mgcpgw_client *mgcp,
|
||||
uint16_t rtp_endpoint, unsigned int call_id,
|
||||
enum mgcp_connection_mode mode);
|
||||
|
||||
struct msgb *mgcp_msg_mdcx(struct mgcpgw_client *mgcp,
|
||||
uint16_t rtp_endpoint, const char *rtp_conn_addr,
|
||||
uint16_t rtp_port, enum mgcp_connection_mode mode);
|
||||
|
||||
void mgcpgw_client_vty_init(int node, struct mgcpgw_client_conf *conf);
|
||||
int mgcpgw_client_config_write(struct vty *vty, const char *indent);
|
||||
|
||||
struct mgcp_response_pending * mgcpgw_client_pending_add(
|
||||
struct mgcpgw_client *mgcp,
|
||||
mgcp_trans_id_t trans_id,
|
||||
mgcp_response_cb_t response_cb,
|
||||
void *priv);
|
||||
int mgcpgw_client_rx(struct mgcpgw_client *mgcp, struct msgb *msg);
|
||||
@@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
/* These are the interfaces of the MSC layer towards (from?) the BSC and RNC,
|
||||
* i.e. in the direction towards the mobile device (MS aka UE).
|
||||
*
|
||||
* 2G will use the A-interface,
|
||||
* 3G aka UMTS will use the Iu-interface (for the MSC, it's IuCS).
|
||||
*
|
||||
* To allow linking parts of the MSC code without having to include entire
|
||||
* infrastructures of external libraries, the core transmitting and receiving
|
||||
* functions are left unimplemented. For example, a unit test does not need to
|
||||
* link against external ASN1 libraries if it is never going to encode actual
|
||||
* outgoing messages. It is up to each building scope to implement real world
|
||||
* functions or to plug mere dummy implementations.
|
||||
*
|
||||
* For example, msc_tx_dtap(conn, msg), depending on conn->via_iface, will call
|
||||
* either iu_tx() or a_tx() [note: at time of writing, the A-interface is not
|
||||
* yet implemented]. When you try to link against libmsc, you will find that
|
||||
* the compiler complains about an undefined reference to iu_tx(). If you,
|
||||
* however, link against libiu as well as the osmo-iuh libs (etc.), iu_tx() is
|
||||
* available. A unit test may instead simply implement a dummy iu_tx() function
|
||||
* and not link against osmo-iuh, see tests/libiudummy/.
|
||||
*/
|
||||
|
||||
/* Each main linkage must implement this function (see comment above). */
|
||||
extern int iu_tx(struct msgb *msg, uint8_t sapi);
|
||||
|
||||
/* So far this is a dummy implemented in libmsc/a_iface.c. When A-interface
|
||||
* gets implemented, it should be in a separate lib (like libiu), this function
|
||||
* should move there, and the following comment should remain here: "
|
||||
* Each main linkage must implement this function (see comment above).
|
||||
* " */
|
||||
extern int a_tx(struct msgb *msg);
|
||||
|
||||
/* So far this is a dummy implemented in libmsc/a_iface.c. When A-interface
|
||||
* gets implemented, it should be in a separate lib (like libiu), this function
|
||||
* should move there, and the following comment should remain here: "
|
||||
* Each main linkage must implement this function (see comment above).
|
||||
* " */
|
||||
extern int a_page(const char *imsi, uint32_t tmsi, uint16_t lac);
|
||||
|
||||
int msc_tx_dtap(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg);
|
||||
|
||||
int msc_gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn);
|
||||
int msc_gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn,
|
||||
enum gsm48_reject_value value);
|
||||
|
||||
/* TODO: specific to A interface, move this away */
|
||||
int msc_gsm0808_tx_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
|
||||
const uint8_t *key, int len, int include_imeisv);
|
||||
|
||||
int msc_tx_common_id(struct gsm_subscriber_connection *conn);
|
||||
int msc_call_assignment(struct gsm_trans *trans);
|
||||
int msc_call_bridge(struct gsm_trans *trans1, struct gsm_trans *trans2);
|
||||
@@ -16,7 +16,7 @@ enum bsc_con {
|
||||
};
|
||||
|
||||
struct sccp_connection;
|
||||
struct bsc_msc_data;
|
||||
struct osmo_msc_data;
|
||||
struct bsc_msc_connection;
|
||||
|
||||
struct osmo_bsc_sccp_con {
|
||||
@@ -33,7 +33,7 @@ struct osmo_bsc_sccp_con {
|
||||
|
||||
/* SCCP connection realted */
|
||||
struct sccp_connection *sccp;
|
||||
struct bsc_msc_data *msc;
|
||||
struct osmo_msc_data *msc;
|
||||
struct osmo_timer_list sccp_it_timeout;
|
||||
struct osmo_timer_list sccp_cc_timeout;
|
||||
|
||||
@@ -51,15 +51,15 @@ struct bsc_api *osmo_bsc_api();
|
||||
int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg);
|
||||
int bsc_open_connection(struct osmo_bsc_sccp_con *sccp, struct msgb *msg);
|
||||
enum bsc_con bsc_create_new_connection(struct gsm_subscriber_connection *conn,
|
||||
struct bsc_msc_data *msc, int send_ping);
|
||||
struct osmo_msc_data *msc, int send_ping);
|
||||
int bsc_delete_connection(struct osmo_bsc_sccp_con *sccp);
|
||||
|
||||
struct bsc_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn, struct msgb *);
|
||||
struct osmo_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn, struct msgb *);
|
||||
int bsc_scan_bts_msg(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
int bsc_send_welcome_ussd(struct gsm_subscriber_connection *conn);
|
||||
|
||||
int bsc_handle_udt(struct bsc_msc_data *msc, struct msgb *msg, unsigned int length);
|
||||
int bsc_handle_udt(struct osmo_msc_data *msc, struct msgb *msg, unsigned int length);
|
||||
int bsc_handle_dt1(struct osmo_bsc_sccp_con *conn, struct msgb *msg, unsigned int len);
|
||||
|
||||
int bsc_ctrl_cmds_install();
|
||||
|
||||
@@ -22,14 +22,10 @@
|
||||
#define OSMO_BSC_GRACE_H
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/signal.h>
|
||||
|
||||
struct bsc_msc_data;
|
||||
struct osmo_msc_data;
|
||||
|
||||
int bsc_grace_allow_new_connection(struct gsm_network *net, struct gsm_bts *bts);
|
||||
int bsc_grace_paging_request(enum signal_rf rf_policy,
|
||||
struct bsc_subscr *subscr,
|
||||
int chan_needed,
|
||||
struct bsc_msc_data *msc);
|
||||
int bsc_grace_paging_request(struct gsm_subscriber *sub, int type, struct osmo_msc_data *msc);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,88 +3,9 @@
|
||||
#ifndef OSMO_MSC_H
|
||||
#define OSMO_MSC_H
|
||||
|
||||
#include <osmocom/core/fsm.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
#include "bsc_api.h"
|
||||
|
||||
#define MSC_HLR_REMOTE_IP_DEFAULT "127.0.0.1"
|
||||
#define MSC_HLR_REMOTE_PORT_DEFAULT 2222
|
||||
|
||||
enum subscr_conn_fsm_event {
|
||||
/* Mark 0 as invalid to catch uninitialized vars */
|
||||
SUBSCR_CONN_E_INVALID = 0,
|
||||
/* Timeout on connection establishment starts */
|
||||
SUBSCR_CONN_E_START,
|
||||
/* LU or Process Access FSM has determined that this conn is good */
|
||||
SUBSCR_CONN_E_ACCEPTED,
|
||||
/* received first reply from MS in "real" CC, SMS, USSD communication */
|
||||
SUBSCR_CONN_E_COMMUNICATING,
|
||||
/* Some async action has completed, check again whether all is done */
|
||||
SUBSCR_CONN_E_BUMP,
|
||||
/* MS/BTS/BSC originated close request */
|
||||
SUBSCR_CONN_E_MO_CLOSE,
|
||||
/* MSC originated close request, e.g. failed authentication */
|
||||
SUBSCR_CONN_E_CN_CLOSE,
|
||||
};
|
||||
|
||||
enum subscr_conn_fsm_state {
|
||||
SUBSCR_CONN_S_INIT,
|
||||
SUBSCR_CONN_S_NEW,
|
||||
SUBSCR_CONN_S_ACCEPTED,
|
||||
SUBSCR_CONN_S_COMMUNICATING,
|
||||
SUBSCR_CONN_S_RELEASED,
|
||||
};
|
||||
|
||||
enum subscr_conn_from {
|
||||
SUBSCR_CONN_FROM_INVALID,
|
||||
SUBSCR_CONN_FROM_LU,
|
||||
SUBSCR_CONN_FROM_CM_SERVICE_REQ,
|
||||
SUBSCR_CONN_FROM_PAGING_RESP,
|
||||
};
|
||||
|
||||
extern const struct value_string subscr_conn_from_names[];
|
||||
static inline const char *subscr_conn_from_name(enum subscr_conn_from val)
|
||||
{
|
||||
return get_value_string(subscr_conn_from_names, val);
|
||||
}
|
||||
|
||||
enum msc_compl_l3_rc {
|
||||
MSC_CONN_ACCEPT = 0,
|
||||
MSC_CONN_REJECT = 1,
|
||||
};
|
||||
|
||||
void msc_subscr_conn_init(void);
|
||||
|
||||
struct bsc_api *msc_bsc_api();
|
||||
|
||||
#define msc_conn_get(conn) _msc_conn_get(conn, __BASE_FILE__, __LINE__)
|
||||
struct gsm_subscriber_connection *
|
||||
_msc_conn_get(struct gsm_subscriber_connection *conn,
|
||||
const char *file, int line);
|
||||
#define msc_conn_put(conn) _msc_conn_put(conn, __BASE_FILE__, __LINE__)
|
||||
void _msc_conn_put(struct gsm_subscriber_connection *conn, const char *file,
|
||||
int line);
|
||||
|
||||
int msc_create_conn_fsm(struct gsm_subscriber_connection *conn, const char *id);
|
||||
|
||||
int msc_vlr_alloc(struct gsm_network *net);
|
||||
int msc_vlr_start(struct gsm_network *net);
|
||||
|
||||
int msc_compl_l3(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg, uint16_t chosen_channel);
|
||||
void msc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg);
|
||||
void msc_cipher_mode_compl(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg, uint8_t alg_id);
|
||||
void msc_rx_sec_mode_compl(struct gsm_subscriber_connection *conn);
|
||||
void msc_conn_close(struct gsm_subscriber_connection *conn, uint32_t cause);
|
||||
|
||||
bool msc_subscr_conn_is_accepted(struct gsm_subscriber_connection *conn);
|
||||
void msc_subscr_conn_communicating(struct gsm_subscriber_connection *conn);
|
||||
|
||||
void msc_release_anchor(struct gsm_subscriber_connection *conn);
|
||||
|
||||
void msc_stop_paging(struct vlr_subscr *vsub);
|
||||
void msc_release_connection(struct gsm_subscriber_connection *conn);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,10 +20,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: This is about a *remote* MSC for OsmoBSC and is not part of libmsc.
|
||||
*/
|
||||
|
||||
#ifndef _OSMO_MSC_DATA_H
|
||||
#define _OSMO_MSC_DATA_H
|
||||
|
||||
@@ -47,9 +43,7 @@ enum {
|
||||
MSC_CON_TYPE_LOCAL,
|
||||
};
|
||||
|
||||
/*! /brief Information on a remote MSC for libbsc.
|
||||
*/
|
||||
struct bsc_msc_data {
|
||||
struct osmo_msc_data {
|
||||
struct llist_head entry;
|
||||
|
||||
/* Back pointer */
|
||||
@@ -128,15 +122,15 @@ struct osmo_bsc_data {
|
||||
};
|
||||
|
||||
|
||||
int osmo_bsc_msc_init(struct bsc_msc_data *msc);
|
||||
int osmo_bsc_msc_init(struct osmo_msc_data *msc);
|
||||
int osmo_bsc_sccp_init(struct gsm_network *gsmnet);
|
||||
int msc_queue_write(struct bsc_msc_connection *conn, struct msgb *msg, int proto);
|
||||
int msc_queue_write_with_ping(struct bsc_msc_connection *, struct msgb *msg, int proto);
|
||||
|
||||
int osmo_bsc_audio_init(struct gsm_network *network);
|
||||
|
||||
struct bsc_msc_data *osmo_msc_data_find(struct gsm_network *, int);
|
||||
struct bsc_msc_data *osmo_msc_data_alloc(struct gsm_network *, int);
|
||||
struct osmo_msc_data *osmo_msc_data_find(struct gsm_network *, int);
|
||||
struct osmo_msc_data *osmo_msc_data_alloc(struct gsm_network *, int);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/bsc_subscriber.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
|
||||
/**
|
||||
* A pending paging request
|
||||
@@ -36,8 +36,8 @@ struct gsm_paging_request {
|
||||
/* list_head for list of all paging requests */
|
||||
struct llist_head entry;
|
||||
/* the subscriber which we're paging. Later gsm_paging_request
|
||||
* should probably become a part of the bsc_subsrc struct? */
|
||||
struct bsc_subscr *bsub;
|
||||
* should probably become a part of the gsm_subscriber struct? */
|
||||
struct gsm_subscriber *subscr;
|
||||
/* back-pointer to the BTS on which we are paging */
|
||||
struct gsm_bts *bts;
|
||||
/* what kind of channel type do we ask the MS to establish */
|
||||
@@ -55,14 +55,13 @@ struct gsm_paging_request {
|
||||
};
|
||||
|
||||
/* schedule paging request */
|
||||
int paging_request(struct gsm_network *network, struct bsc_subscr *bsub,
|
||||
int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *data);
|
||||
int paging_request_bts(struct gsm_bts *bts, struct bsc_subscr *bsub,
|
||||
int type, gsm_cbfn *cbfn, void *data);
|
||||
int paging_request_bts(struct gsm_bts *bts, struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *data);
|
||||
|
||||
/* stop paging requests */
|
||||
void paging_request_stop(struct llist_head *bts_list,
|
||||
struct gsm_bts *_bts, struct bsc_subscr *bsub,
|
||||
void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr,
|
||||
struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg);
|
||||
|
||||
@@ -72,6 +71,6 @@ void paging_update_buffer_space(struct gsm_bts *bts, uint16_t);
|
||||
/* pending paging requests */
|
||||
unsigned int paging_pending_requests_nr(struct gsm_bts *bts);
|
||||
|
||||
void *paging_get_data(struct gsm_bts *bts, struct bsc_subscr *bsub);
|
||||
void *paging_get_data(struct gsm_bts *bts, struct gsm_subscriber *subscr);
|
||||
|
||||
#endif
|
||||
|
||||
15
openbsc/include/openbsc/reg_proxy.h
Normal file
15
openbsc/include/openbsc/reg_proxy.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef _REG_PROXY_H
|
||||
#define _REG_PROXY_H
|
||||
|
||||
#include <openbsc/sup_server.h>
|
||||
#include <openbsc/sip_client.h>
|
||||
#include <osip2/osip.h>
|
||||
void *tall_reg_ctx;
|
||||
|
||||
struct reg_proxy {
|
||||
struct gsm_sup_server *sup_server;
|
||||
struct sip_client *sip_client;
|
||||
osip_t *osip;
|
||||
};
|
||||
|
||||
#endif /* _REG_PROXY_H */
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <osmocom/gprs/gprs_ns.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
#include <openbsc/oap_client.h>
|
||||
#include <openbsc/common.h>
|
||||
|
||||
#include <ares.h>
|
||||
|
||||
@@ -110,10 +109,6 @@ struct sgsn_config {
|
||||
int p1;
|
||||
int p2;
|
||||
} dcomp_v42bis;
|
||||
|
||||
struct {
|
||||
enum nsap_addr_enc rab_assign_addr_enc;
|
||||
} iu;
|
||||
};
|
||||
|
||||
struct sgsn_instance {
|
||||
@@ -145,8 +140,8 @@ extern struct sgsn_instance *sgsn;
|
||||
|
||||
/* sgsn_vty.c */
|
||||
|
||||
int sgsn_vty_init(struct sgsn_config *cfg);
|
||||
int sgsn_parse_config(const char *config_file);
|
||||
int sgsn_vty_init(void);
|
||||
int sgsn_parse_config(const char *config_file, struct sgsn_config *cfg);
|
||||
|
||||
/* sgsn.c */
|
||||
|
||||
|
||||
@@ -138,8 +138,10 @@ enum signal_rf {
|
||||
S_RF_GRACE,
|
||||
};
|
||||
|
||||
struct gsm_subscriber;
|
||||
|
||||
struct paging_signal_data {
|
||||
struct vlr_subscr *vsub;
|
||||
struct gsm_subscriber *subscr;
|
||||
struct gsm_bts *bts;
|
||||
|
||||
int paging_result;
|
||||
@@ -149,6 +151,7 @@ struct paging_signal_data {
|
||||
};
|
||||
|
||||
struct scall_signal_data {
|
||||
struct gsm_subscriber *subscr;
|
||||
struct gsm_subscriber_connection *conn;
|
||||
void *data;
|
||||
};
|
||||
@@ -220,9 +223,9 @@ enum signal_msc {
|
||||
S_MSC_AUTHENTICATED,
|
||||
};
|
||||
|
||||
struct bsc_msc_data;
|
||||
struct osmo_msc_data;
|
||||
struct msc_signal_data {
|
||||
struct bsc_msc_data *data;
|
||||
struct osmo_msc_data *data;
|
||||
};
|
||||
|
||||
/* SS_CCCH signals */
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
extern int gsm_silent_call_start(struct vlr_subscr *vsub,
|
||||
extern int gsm_silent_call_start(struct gsm_subscriber *subscr,
|
||||
void *data, int type);
|
||||
extern int gsm_silent_call_stop(struct vlr_subscr *vsub);
|
||||
|
||||
#if 0
|
||||
extern int gsm_silent_call_stop(struct gsm_subscriber *subscr);
|
||||
extern int silent_call_rx(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
extern int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
#endif
|
||||
|
||||
#endif /* _SILENT_CALL_H */
|
||||
|
||||
16
openbsc/include/openbsc/sip.h
Normal file
16
openbsc/include/openbsc/sip.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef _SIP_H
|
||||
#define _SIP_H
|
||||
|
||||
#include <openbsc/sip_client.h>
|
||||
#include <openbsc/reg_proxy.h>
|
||||
#include <osip2/osip.h>
|
||||
#include <osmocom/gsm/gsm0480.h>
|
||||
|
||||
int tx_ss_handle(struct sip_client *sip_client, osip_t *osip, struct ss_request *ss,
|
||||
const char *extention);
|
||||
|
||||
int tx_sip_register(struct sip_client *sip_client, osip_t *osip, char *imsi, int expires_time);
|
||||
|
||||
int sip_client_init(struct reg_proxy *reg, const char *src_ip, u_int16_t src_port,
|
||||
const char *dst_ip, u_int16_t dst_port, int expires_time);
|
||||
#endif /* _SIP_H */
|
||||
36
openbsc/include/openbsc/sip_client.h
Normal file
36
openbsc/include/openbsc/sip_client.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
#define SIP_RECONNECT_INTERVAL 10
|
||||
|
||||
struct msgb;
|
||||
struct ipa_client_conn;
|
||||
struct sip_client;
|
||||
|
||||
/* Expects message in msg->l2h */
|
||||
typedef int (*sip_read_cb_t)(struct sip_client *sip_client, struct msgb *msg);
|
||||
|
||||
struct sip_client {
|
||||
struct tcp_client_conn *link;
|
||||
sip_read_cb_t read_cb;
|
||||
void *data;
|
||||
|
||||
struct osmo_timer_list connect_timer;
|
||||
int is_connected;
|
||||
|
||||
char *src_ip;
|
||||
char *dst_ip;
|
||||
u_int16_t src_port;
|
||||
u_int16_t dst_port;
|
||||
int expires_time;
|
||||
};
|
||||
|
||||
struct sip_client *sip_client_create(const char *src_ip, u_int16_t src_port,
|
||||
const char *dst_ip, u_int16_t dst_port,
|
||||
int expires_time, sip_read_cb_t read_cb,
|
||||
void *data);
|
||||
|
||||
void sip_client_destroy(struct sip_client *sip_client);
|
||||
int sip_client_send(struct sip_client *sip_client, struct msgb *msg);
|
||||
struct msgb *sip_msgb_alloc(void);
|
||||
19
openbsc/include/openbsc/sup.h
Normal file
19
openbsc/include/openbsc/sup.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef _SUP_H
|
||||
#define _SUP_H
|
||||
|
||||
#include <openbsc/reg_proxy.h>
|
||||
|
||||
#define LOGGSUPP(level, sup, fmt, args...) \
|
||||
LOGP(DGPRS, level, "SUP(%s) " fmt, \
|
||||
(sup)->imsi, \
|
||||
## args)
|
||||
|
||||
int sup_server_init(struct reg_proxy *reg);
|
||||
|
||||
int handle_location_update_result(struct gsm_sup_server *sup_server,
|
||||
char *imsi, char *msisdn);
|
||||
|
||||
int handle_purge_ms_result(struct gsm_sup_server *sup_server,
|
||||
char *imsi);
|
||||
|
||||
#endif /* _SUP_H */
|
||||
29
openbsc/include/openbsc/sup_server.h
Normal file
29
openbsc/include/openbsc/sup_server.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef _SUP_SERVER_H
|
||||
#define _SUP_SERVER_H
|
||||
|
||||
#include <osmocom/abis/ipa.h>
|
||||
|
||||
//struct msgb;
|
||||
struct ipa_server_conn;
|
||||
struct gsm_sup_server;
|
||||
|
||||
/* Expects message in msg->l2h */
|
||||
typedef int (*sup_read_cb_t)(struct gsm_sup_server *sup_server, struct msgb *msg);
|
||||
|
||||
struct gsm_sup_server {
|
||||
struct ipa_server_link *link;
|
||||
sup_read_cb_t read_cb;
|
||||
void *data;
|
||||
struct osmo_fd fd;
|
||||
struct ipa_server_conn *server_conn;
|
||||
void *app;
|
||||
};
|
||||
|
||||
struct gsm_sup_server *sup_server_create(const char *ip_addr,
|
||||
unsigned int tcp_port,
|
||||
sup_read_cb_t read_cb,
|
||||
void *app);
|
||||
|
||||
int sup_server_send(struct gsm_sup_server *sup_server, struct msgb *msg);
|
||||
|
||||
#endif /* _SUP_SERVER_H */
|
||||
51
openbsc/include/openbsc/tcp_client.h
Normal file
51
openbsc/include/openbsc/tcp_client.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef _TCP_CLIENT_H_
|
||||
#define _TCP_CLIENT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/select.h>
|
||||
|
||||
|
||||
struct msgb;
|
||||
|
||||
enum tcp_client_conn_state {
|
||||
TCP_CLIENT_LINK_STATE_NONE = 0,
|
||||
TCP_CLIENT_LINK_STATE_CONNECTING = 1,
|
||||
TCP_CLIENT_LINK_STATE_CONNECTED = 2,
|
||||
TCP_CLIENT_LINK_STATE_MAX
|
||||
};
|
||||
|
||||
struct tcp_client_conn {
|
||||
struct osmo_fd *ofd;
|
||||
struct llist_head tx_queue;
|
||||
struct osmo_timer_list timer;
|
||||
enum tcp_client_conn_state state;
|
||||
const char *src_addr;
|
||||
uint16_t src_port;
|
||||
const char *dst_addr;
|
||||
uint16_t dst_port;
|
||||
void (*updown_cb)(struct tcp_client_conn *link, int up);
|
||||
int (*read_cb)(struct tcp_client_conn *link, struct msgb *msg);
|
||||
int (*write_cb)(struct tcp_client_conn *link);
|
||||
void *data;
|
||||
struct msgb *pending_msg;
|
||||
};
|
||||
|
||||
struct tcp_client_conn *
|
||||
tcp_client_conn_create(void *ctx, int priv_nr,
|
||||
const char *dst_addr, uint16_t dst_port,
|
||||
const char *src_addr, uint16_t src_port,
|
||||
void (*updown)(struct tcp_client_conn *link, int),
|
||||
int (*read_cb)(struct tcp_client_conn *link, struct msgb *msgb),
|
||||
int (*write_cb)(struct tcp_client_conn *link),
|
||||
void *data);
|
||||
void tcp_client_conn_destroy(struct tcp_client_conn *link);
|
||||
|
||||
int tcp_client_conn_open(struct tcp_client_conn *link);
|
||||
void tcp_client_conn_close(struct tcp_client_conn *link);
|
||||
|
||||
void tcp_client_conn_send(struct tcp_client_conn *link, struct msgb *msg);
|
||||
size_t tcp_client_conn_clear_queue(struct tcp_client_conn *link);
|
||||
|
||||
#endif
|
||||
@@ -9,14 +9,6 @@
|
||||
#include <osmocom/gsm/gsm0411_smc.h>
|
||||
#include <osmocom/gsm/gsm0411_smr.h>
|
||||
|
||||
enum bridge_state {
|
||||
BRIDGE_STATE_NONE,
|
||||
BRIDGE_STATE_LOOPBACK_PENDING,
|
||||
BRIDGE_STATE_LOOPBACK_ESTABLISHED,
|
||||
BRIDGE_STATE_BRIDGE_PENDING,
|
||||
BRIDGE_STATE_BRIDGE_ESTABLISHED,
|
||||
};
|
||||
|
||||
/* One transaction */
|
||||
struct gsm_trans {
|
||||
/* Entry in list of all transactions */
|
||||
@@ -32,7 +24,7 @@ struct gsm_trans {
|
||||
uint8_t transaction_id;
|
||||
|
||||
/* To whom we belong, unique identifier of remote MM entity */
|
||||
struct vlr_subscr *vsub;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
/* The associated connection we are using to transmit messages */
|
||||
struct gsm_subscriber_connection *conn;
|
||||
@@ -40,6 +32,11 @@ struct gsm_trans {
|
||||
/* reference from MNCC or other application */
|
||||
uint32_t callref;
|
||||
|
||||
/* SMS RP message reference */
|
||||
uint8_t msg_ref;
|
||||
/* handle SMS local */
|
||||
uint8_t sms_local;
|
||||
|
||||
/* if traffic channel receive was requested */
|
||||
int tch_recv;
|
||||
|
||||
@@ -64,12 +61,12 @@ struct gsm_trans {
|
||||
|
||||
struct gsm_sms *sms;
|
||||
} sms;
|
||||
struct {
|
||||
uint8_t invoke_id;
|
||||
uint8_t mo;
|
||||
uint8_t dirty;
|
||||
} ss;
|
||||
};
|
||||
|
||||
struct {
|
||||
struct gsm_trans *peer;
|
||||
enum bridge_state state;
|
||||
} bridge;
|
||||
};
|
||||
|
||||
|
||||
@@ -78,16 +75,17 @@ struct gsm_trans *trans_find_by_id(struct gsm_subscriber_connection *conn,
|
||||
uint8_t proto, uint8_t trans_id);
|
||||
struct gsm_trans *trans_find_by_callref(struct gsm_network *net,
|
||||
uint32_t callref);
|
||||
struct gsm_trans *trans_find_by_msgref(struct gsm_subscriber_connection *conn,
|
||||
uint8_t msg_ref);
|
||||
|
||||
struct gsm_trans *trans_alloc(struct gsm_network *net,
|
||||
struct vlr_subscr *vsub,
|
||||
struct gsm_subscriber *subscr,
|
||||
uint8_t protocol, uint8_t trans_id,
|
||||
uint32_t callref);
|
||||
void trans_free(struct gsm_trans *trans);
|
||||
|
||||
int trans_assign_trans_id(struct gsm_network *net, struct vlr_subscr *vsub,
|
||||
int trans_assign_trans_id(struct gsm_network *net, struct gsm_subscriber *subscr,
|
||||
uint8_t protocol, uint8_t ti_flag);
|
||||
struct gsm_trans *trans_has_conn(const struct gsm_subscriber_connection *conn);
|
||||
void trans_conn_closed(struct gsm_subscriber_connection *conn);
|
||||
int trans_has_conn(const struct gsm_subscriber_connection *conn);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,19 @@
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
|
||||
#define USSD_MO 1
|
||||
#define USSD_MT 0
|
||||
|
||||
int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
|
||||
int on_ussd_response(struct gsm_network *net,
|
||||
uint32_t ref,
|
||||
struct ss_header *reqhdr,
|
||||
const uint8_t *component,
|
||||
const char* extention);
|
||||
|
||||
|
||||
void _ussd_trans_free(struct gsm_trans *trans);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,415 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/fsm.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
#include <osmocom/gsm/gsm23003.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
// for GSM_NAME_LENGTH
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
|
||||
struct log_target;
|
||||
|
||||
/* from 3s to 10s */
|
||||
#define GSM_29002_TIMER_S 10
|
||||
/* from 15s to 30s */
|
||||
#define GSM_29002_TIMER_M 30
|
||||
/* from 1min to 10min */
|
||||
#define GSM_29002_TIMER_ML (10*60)
|
||||
/* from 28h to 38h */
|
||||
#define GSM_29002_TIMER_L (32*60*60)
|
||||
|
||||
/* VLR subscriber authentication state */
|
||||
enum vlr_subscr_auth_state {
|
||||
/* subscriber needs to be autenticated */
|
||||
VLR_SUB_AS_NEEDS_AUTH,
|
||||
/* waiting for AuthInfo from HLR/AUC */
|
||||
VLR_SUB_AS_NEEDS_AUTH_WAIT_AI,
|
||||
/* waiting for response from subscriber */
|
||||
VLR_SUB_AS_WAIT_RESP,
|
||||
/* successfully authenticated */
|
||||
VLR_SUB_AS_AUTHENTICATED,
|
||||
/* subscriber needs re-sync */
|
||||
VLR_SUB_AS_NEEDS_RESYNC,
|
||||
/* waiting for AuthInfo with ReSync */
|
||||
VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC,
|
||||
/* waiting for response from subscr, resync case */
|
||||
VLR_SUB_AS_WAIT_RESP_RESYNC,
|
||||
/* waiting for IMSI from subscriber */
|
||||
VLR_SUB_AS_WAIT_ID_IMSI,
|
||||
/* authentication has failed */
|
||||
VLR_SUB_AS_AUTH_FAILED,
|
||||
};
|
||||
|
||||
enum vlr_lu_event {
|
||||
VLR_ULA_E_UPDATE_LA, /* Initial trigger (LU from MS) */
|
||||
VLR_ULA_E_SEND_ID_ACK, /* Result of Send-ID from PVLR */
|
||||
VLR_ULA_E_SEND_ID_NACK, /* Result of Send-ID from PVLR */
|
||||
VLR_ULA_E_AUTH_RES, /* Result of auth procedure */
|
||||
VLR_ULA_E_CIPH_RES, /* Result of Ciphering Mode Command */
|
||||
VLR_ULA_E_ID_IMSI, /* IMSI recieved from MS */
|
||||
VLR_ULA_E_ID_IMEI, /* IMEI received from MS */
|
||||
VLR_ULA_E_ID_IMEISV, /* IMEISV received from MS */
|
||||
VLR_ULA_E_HLR_LU_RES, /* HLR UpdateLocation result */
|
||||
VLR_ULA_E_UPD_HLR_COMPL,/* UpdatE_HLR_VLR result */
|
||||
VLR_ULA_E_LU_COMPL_SUCCESS,/* Location_Update_Completion_VLR result */
|
||||
VLR_ULA_E_LU_COMPL_FAILURE,/* Location_Update_Completion_VLR result */
|
||||
VLR_ULA_E_NEW_TMSI_ACK, /* TMSI Reallocation Complete */
|
||||
};
|
||||
|
||||
enum vlr_ciph_result_cause {
|
||||
VLR_CIPH_REJECT, /* ? */
|
||||
VLR_CIPH_COMPL,
|
||||
};
|
||||
|
||||
struct vlr_ciph_result {
|
||||
enum vlr_ciph_result_cause cause;
|
||||
const char *imeisv;
|
||||
};
|
||||
|
||||
enum vlr_subscr_security_context {
|
||||
VLR_SEC_CTX_NONE,
|
||||
VLR_SEC_CTX_GSM,
|
||||
VLR_SEC_CTX_UMTS,
|
||||
};
|
||||
|
||||
enum vlr_lu_type {
|
||||
VLR_LU_TYPE_PERIODIC,
|
||||
VLR_LU_TYPE_IMSI_ATTACH,
|
||||
VLR_LU_TYPE_REGULAR,
|
||||
};
|
||||
|
||||
#define OSMO_LBUF_DECL(name, xlen) \
|
||||
struct { \
|
||||
uint8_t buf[xlen]; \
|
||||
size_t len; \
|
||||
} name
|
||||
|
||||
struct sgsn_mm_ctx;
|
||||
struct vlr_instance;
|
||||
|
||||
/* The VLR subscriber is the part of the GSM subscriber state in VLR (CS) or
|
||||
* SGSN (PS), particularly while interacting with the HLR via GSUP */
|
||||
struct vlr_subscr {
|
||||
struct llist_head list;
|
||||
struct vlr_instance *vlr;
|
||||
|
||||
/* TODO either populate from HLR or drop this completely? */
|
||||
long long unsigned int id;
|
||||
|
||||
/* Data from HLR */ /* 3GPP TS 23.008 */
|
||||
/* Always use vlr_subscr_set_imsi() to write to imsi[] */
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1]; /* 2.1.1.1 */
|
||||
char msisdn[GSM_EXTENSION_LENGTH+1]; /* 2.1.2 */
|
||||
char name[GSM_NAME_LENGTH+1]; /* proprietary */
|
||||
OSMO_LBUF_DECL(hlr, 16); /* 2.4.7 */
|
||||
uint32_t periodic_lu_timer; /* 2.4.24 */
|
||||
uint32_t age_indicator; /* 2.17.1 */
|
||||
|
||||
/* Authentication Data */
|
||||
struct gsm_auth_tuple auth_tuples[5]; /* 2.3.1-2.3.4 */
|
||||
struct gsm_auth_tuple *last_tuple;
|
||||
enum vlr_subscr_security_context sec_ctx;
|
||||
|
||||
/* Data local to VLR is below */
|
||||
uint32_t tmsi; /* 2.1.4 */
|
||||
/* Newly allocated TMSI that was not yet acked by MS */
|
||||
uint32_t tmsi_new;
|
||||
|
||||
/* some redundancy in information below? */
|
||||
struct osmo_cell_global_id cgi; /* 2.4.16 */
|
||||
uint16_t lac; /* 2.4.2 */
|
||||
|
||||
char imeisv[GSM23003_IMEISV_NUM_DIGITS+1]; /* 2.2.3 */
|
||||
char imei[GSM23003_IMEISV_NUM_DIGITS+1]; /* 2.1.9 */
|
||||
bool imsi_detached_flag; /* 2.7.1 */
|
||||
bool conf_by_radio_contact_ind; /* 2.7.4.1 */
|
||||
bool sub_dataconf_by_hlr_ind; /* 2.7.4.2 */
|
||||
bool loc_conf_in_hlr_ind; /* 2.7.4.3 */
|
||||
bool dormant_ind; /* 2.7.8 */
|
||||
bool cancel_loc_rx; /* 2.7.8A */
|
||||
bool ms_not_reachable_flag; /* 2.10.2 (MNRF) */
|
||||
bool la_allowed;
|
||||
|
||||
int use_count;
|
||||
time_t expire_lu; /* FIXME: overlap with periodic_lu_timer/age_indicator */
|
||||
|
||||
struct osmo_fsm_inst *lu_fsm;
|
||||
struct osmo_fsm_inst *auth_fsm;
|
||||
struct osmo_fsm_inst *proc_arq_fsm;
|
||||
|
||||
bool lu_complete;
|
||||
|
||||
void *msc_conn_ref;
|
||||
|
||||
/* PS (SGSN) specific parts */
|
||||
struct {
|
||||
struct llist_head pdp_list;
|
||||
uint8_t rac;
|
||||
uint8_t sac;
|
||||
struct gprs_mm_ctx *mmctx;
|
||||
} ps;
|
||||
/* CS (NITB/CSCN) specific parts */
|
||||
struct {
|
||||
/* pending requests */
|
||||
bool is_paging;
|
||||
/* list of struct subscr_request */
|
||||
struct llist_head requests;
|
||||
uint8_t lac;
|
||||
enum ran_type attached_via_ran;
|
||||
} cs;
|
||||
};
|
||||
|
||||
enum vlr_proc_arq_result;
|
||||
|
||||
enum vlr_ciph {
|
||||
VLR_CIPH_NONE, /*< A5/0, no encryption */
|
||||
VLR_CIPH_A5_1, /*< A5/1, encryption */
|
||||
VLR_CIPH_A5_2, /*< A5/2, deprecated export-grade encryption */
|
||||
VLR_CIPH_A5_3, /*< A5/3, 'new secure' encryption */
|
||||
};
|
||||
|
||||
struct vlr_ops {
|
||||
/* encode + transmit an AUTH REQ towards the MS.
|
||||
* \param[in] at auth tuple providing rand, key_seq and autn.
|
||||
* \param[in] send_autn True to send AUTN, for r99 UMTS auth.
|
||||
*/
|
||||
int (*tx_auth_req)(void *msc_conn_ref, struct gsm_auth_tuple *at,
|
||||
bool send_autn);
|
||||
/* encode + transmit an AUTH REJECT towards the MS */
|
||||
int (*tx_auth_rej)(void *msc_conn_ref);
|
||||
|
||||
/* encode + transmit an IDENTITY REQUEST towards the MS */
|
||||
int (*tx_id_req)(void *msc_conn_ref, uint8_t mi_type);
|
||||
|
||||
int (*tx_lu_acc)(void *msc_conn_ref, uint32_t send_tmsi);
|
||||
int (*tx_lu_rej)(void *msc_conn_ref, uint8_t cause);
|
||||
int (*tx_cm_serv_acc)(void *msc_conn_ref);
|
||||
int (*tx_cm_serv_rej)(void *msc_conn_ref, enum vlr_proc_arq_result result);
|
||||
|
||||
int (*set_ciph_mode)(void *msc_conn_ref, enum vlr_ciph ciph_mode,
|
||||
bool retrieve_imeisv);
|
||||
|
||||
/* UTRAN: send Common Id (when auth+ciph are complete) */
|
||||
int (*tx_common_id)(void *msc_conn_ref);
|
||||
|
||||
|
||||
/* notify MSC/SGSN that the subscriber data in VLR has been updated */
|
||||
void (*subscr_update)(struct vlr_subscr *vsub);
|
||||
/* notify MSC/SGSN that the given subscriber has been associated
|
||||
* with this msc_conn_ref */
|
||||
void (*subscr_assoc)(void *msc_conn_ref, struct vlr_subscr *vsub);
|
||||
};
|
||||
|
||||
enum vlr_timer {
|
||||
VLR_T_3250,
|
||||
VLR_T_3260,
|
||||
VLR_T_3270,
|
||||
_NUM_VLR_TIMERS
|
||||
};
|
||||
|
||||
/* An instance of the VLR codebase */
|
||||
struct vlr_instance {
|
||||
struct llist_head subscribers;
|
||||
struct llist_head operations;
|
||||
struct gsup_client *gsup_client;
|
||||
struct vlr_ops ops;
|
||||
struct {
|
||||
bool retrieve_imeisv;
|
||||
bool assign_tmsi;
|
||||
bool check_imei_rqd;
|
||||
int auth_tuple_max_use_count;
|
||||
bool auth_reuse_old_sets_on_error;
|
||||
bool parq_retrieve_imsi;
|
||||
bool is_ps;
|
||||
uint32_t timer[_NUM_VLR_TIMERS];
|
||||
} cfg;
|
||||
/* A free-form pointer for use by the caller */
|
||||
void *user_ctx;
|
||||
};
|
||||
|
||||
extern const struct value_string vlr_ciph_names[];
|
||||
static inline const char *vlr_ciph_name(enum vlr_ciph val)
|
||||
{
|
||||
return get_value_string(vlr_ciph_names, val);
|
||||
}
|
||||
|
||||
/* Location Updating request */
|
||||
struct osmo_fsm_inst *
|
||||
vlr_loc_update(struct osmo_fsm_inst *parent,
|
||||
uint32_t parent_event_success,
|
||||
uint32_t parent_event_failure,
|
||||
void *parent_event_data,
|
||||
struct vlr_instance *vlr, void *msc_conn_ref,
|
||||
enum vlr_lu_type type, uint32_t tmsi, const char *imsi,
|
||||
const struct osmo_location_area_id *old_lai,
|
||||
const struct osmo_location_area_id *new_lai,
|
||||
bool authentication_required,
|
||||
enum vlr_ciph ciphering_required,
|
||||
bool is_r99, bool is_utran,
|
||||
bool assign_tmsi);
|
||||
|
||||
void vlr_loc_update_conn_timeout(struct osmo_fsm_inst *fi);
|
||||
|
||||
/* tell the VLR that the subscriber connection is gone */
|
||||
int vlr_subscr_disconnected(struct vlr_subscr *vsub);
|
||||
|
||||
int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const uint8_t *mi, size_t mi_len);
|
||||
int vlr_subscr_rx_auth_resp(struct vlr_subscr *vsub, bool is_r99, bool is_utran,
|
||||
const uint8_t *res, uint8_t res_len);
|
||||
int vlr_subscr_rx_auth_fail(struct vlr_subscr *vsub, const uint8_t *auts);
|
||||
int vlr_subscr_tx_auth_fail_rep(struct vlr_subscr *vsub);
|
||||
void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, struct vlr_ciph_result *res);
|
||||
int vlr_subscr_rx_tmsi_reall_compl(struct vlr_subscr *vsub);
|
||||
int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub);
|
||||
void vlr_subscr_conn_timeout(struct vlr_subscr *vsub);
|
||||
|
||||
struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops);
|
||||
int vlr_start(const char *gsup_unit_name, struct vlr_instance *vlr,
|
||||
const char *gsup_server_addr_str, uint16_t gsup_server_port);
|
||||
|
||||
/* internal use only */
|
||||
|
||||
struct osmo_fsm_inst *sub_pres_vlr_fsm_start(struct osmo_fsm_inst *parent,
|
||||
struct vlr_subscr *vsub,
|
||||
uint32_t term_event);
|
||||
struct osmo_fsm_inst *
|
||||
upd_hlr_vlr_proc_start(struct osmo_fsm_inst *parent,
|
||||
struct vlr_subscr *vsub,
|
||||
uint32_t parent_event);
|
||||
|
||||
struct osmo_fsm_inst *
|
||||
lu_compl_vlr_proc_start(struct osmo_fsm_inst *parent,
|
||||
struct vlr_subscr *vsub,
|
||||
void *msc_conn_ref,
|
||||
uint32_t parent_event_success,
|
||||
uint32_t parent_event_failure);
|
||||
|
||||
|
||||
const char *vlr_subscr_name(struct vlr_subscr *vsub);
|
||||
const char *vlr_subscr_msisdn_or_name(struct vlr_subscr *vsub);
|
||||
|
||||
#define vlr_subscr_find_by_imsi(vlr, imsi) \
|
||||
_vlr_subscr_find_by_imsi(vlr, imsi, __BASE_FILE__, __LINE__)
|
||||
#define vlr_subscr_find_or_create_by_imsi(vlr, imsi, created) \
|
||||
_vlr_subscr_find_or_create_by_imsi(vlr, imsi, created, \
|
||||
__BASE_FILE__, __LINE__)
|
||||
|
||||
#define vlr_subscr_find_by_tmsi(vlr, tmsi) \
|
||||
_vlr_subscr_find_by_tmsi(vlr, tmsi, __BASE_FILE__, __LINE__)
|
||||
#define vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created) \
|
||||
_vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created, \
|
||||
__BASE_FILE__, __LINE__)
|
||||
|
||||
#define vlr_subscr_find_by_msisdn(vlr, msisdn) \
|
||||
_vlr_subscr_find_by_msisdn(vlr, msisdn, __BASE_FILE__, __LINE__)
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
|
||||
const char *imsi,
|
||||
const char *file, int line);
|
||||
struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr,
|
||||
const char *imsi,
|
||||
bool *created,
|
||||
const char *file,
|
||||
int line);
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr,
|
||||
uint32_t tmsi,
|
||||
const char *file, int line);
|
||||
struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr,
|
||||
uint32_t tmsi,
|
||||
bool *created,
|
||||
const char *file,
|
||||
int line);
|
||||
|
||||
struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
|
||||
const char *msisdn,
|
||||
const char *file, int line);
|
||||
|
||||
#define vlr_subscr_get(sub) _vlr_subscr_get(sub, __BASE_FILE__, __LINE__)
|
||||
#define vlr_subscr_put(sub) _vlr_subscr_put(sub, __BASE_FILE__, __LINE__)
|
||||
struct vlr_subscr *_vlr_subscr_get(struct vlr_subscr *sub, const char *file, int line);
|
||||
struct vlr_subscr *_vlr_subscr_put(struct vlr_subscr *sub, const char *file, int line);
|
||||
|
||||
struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr);
|
||||
void vlr_subscr_free(struct vlr_subscr *vsub);
|
||||
int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub);
|
||||
|
||||
void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi);
|
||||
void vlr_subscr_set_imei(struct vlr_subscr *vsub, const char *imei);
|
||||
void vlr_subscr_set_imeisv(struct vlr_subscr *vsub, const char *imeisv);
|
||||
void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn);
|
||||
|
||||
uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer);
|
||||
|
||||
int vlr_subscr_changed(struct vlr_subscr *vsub);
|
||||
int vlr_subscr_purge(struct vlr_subscr *vsub);
|
||||
void vlr_subscr_cancel(struct vlr_subscr *vsub, enum gsm48_gmm_cause cause);
|
||||
|
||||
|
||||
/* Process Acccess Request FSM */
|
||||
|
||||
enum vlr_proc_arq_result {
|
||||
VLR_PR_ARQ_RES_NONE,
|
||||
VLR_PR_ARQ_RES_SYSTEM_FAILURE,
|
||||
VLR_PR_ARQ_RES_ILLEGAL_SUBSCR,
|
||||
VLR_PR_ARQ_RES_UNIDENT_SUBSCR,
|
||||
VLR_PR_ARQ_RES_ROAMING_NOTALLOWED,
|
||||
VLR_PR_ARQ_RES_ILLEGAL_EQUIP,
|
||||
VLR_PR_ARQ_RES_UNKNOWN_ERROR,
|
||||
VLR_PR_ARQ_RES_TIMEOUT,
|
||||
VLR_PR_ARQ_RES_PASSED,
|
||||
};
|
||||
|
||||
extern const struct value_string vlr_proc_arq_result_names[];
|
||||
static inline const char *vlr_proc_arq_result_name(enum vlr_proc_arq_result res)
|
||||
{
|
||||
return get_value_string(vlr_proc_arq_result_names, res);
|
||||
}
|
||||
|
||||
enum proc_arq_vlr_event {
|
||||
PR_ARQ_E_START,
|
||||
PR_ARQ_E_ID_IMSI,
|
||||
PR_ARQ_E_AUTH_RES,
|
||||
PR_ARQ_E_CIPH_RES,
|
||||
PR_ARQ_E_UPD_LOC_RES,
|
||||
PR_ARQ_E_TRACE_RES,
|
||||
PR_ARQ_E_IMEI_RES,
|
||||
PR_ARQ_E_PRES_RES,
|
||||
PR_ARQ_E_TMSI_ACK,
|
||||
};
|
||||
|
||||
enum vlr_parq_type {
|
||||
VLR_PR_ARQ_T_INVALID = 0, /* to guard against unset vars */
|
||||
VLR_PR_ARQ_T_CM_SERV_REQ,
|
||||
VLR_PR_ARQ_T_PAGING_RESP,
|
||||
/* FIXME: differentiate between services of 24.008 10.5.3.3 */
|
||||
};
|
||||
|
||||
/* Process Access Request (CM SERV REQ / PAGING RESP) */
|
||||
void
|
||||
vlr_proc_acc_req(struct osmo_fsm_inst *parent,
|
||||
uint32_t parent_event_success,
|
||||
uint32_t parent_event_failure,
|
||||
void *parent_event_data,
|
||||
struct vlr_instance *vlr, void *msc_conn_ref,
|
||||
enum vlr_parq_type type, const uint8_t *mi_lv,
|
||||
const struct osmo_location_area_id *lai,
|
||||
bool authentication_required,
|
||||
enum vlr_ciph ciphering_required,
|
||||
bool is_r99, bool is_utran);
|
||||
|
||||
void vlr_parq_conn_timeout(struct osmo_fsm_inst *fi);
|
||||
|
||||
void vlr_parq_fsm_init(void);
|
||||
|
||||
int vlr_set_ciph_mode(struct vlr_instance *vlr,
|
||||
struct osmo_fsm_inst *fi,
|
||||
void *msc_conn_ref,
|
||||
enum vlr_ciph ciph_mode,
|
||||
bool retrieve_imeisv);
|
||||
|
||||
void log_set_filter_vlr_subscr(struct log_target *target,
|
||||
struct vlr_subscr *vlr_subscr);
|
||||
@@ -38,18 +38,15 @@ enum bsc_vty_node {
|
||||
SMPP_NODE,
|
||||
SMPP_ESME_NODE,
|
||||
GTPHUB_NODE,
|
||||
HLR_NODE,
|
||||
};
|
||||
|
||||
extern int bsc_vty_is_config_node(struct vty *vty, int node);
|
||||
extern void bsc_replace_string(void *ctx, char **dst, const char *newstr);
|
||||
|
||||
struct log_info;
|
||||
int bsc_vty_init(struct gsm_network *network);
|
||||
int bsc_vty_init(const struct log_info *cat, struct gsm_network *network);
|
||||
int bsc_vty_init_extra(void);
|
||||
|
||||
void msc_vty_init(struct gsm_network *msc_network);
|
||||
|
||||
struct gsm_network *gsmnet_from_vty(struct vty *vty);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,8 @@ app_configs = {
|
||||
"gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg",
|
||||
"doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg"],
|
||||
"sgsn": ["doc/examples/osmo-sgsn/osmo-sgsn.cfg"],
|
||||
"msc": ["doc/examples/osmo-msc/osmo-msc.cfg"],
|
||||
"nitb": ["doc/examples/osmo-nitb/nanobts/openbsc-multitrx.cfg",
|
||||
"doc/examples/osmo-nitb/nanobts/openbsc.cfg"],
|
||||
"gtphub": ["doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg"]
|
||||
}
|
||||
|
||||
@@ -44,11 +45,11 @@ apps = [(4242, "src/osmo-bsc/osmo-bsc", "OsmoBSC", "osmo-bsc"),
|
||||
(4243, "src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "mgcp"),
|
||||
(4246, "src/gprs/osmo-gbproxy", "OsmoGbProxy", "gbproxy"),
|
||||
(4245, "src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn"),
|
||||
(4254, "src/osmo-msc/osmo-msc", "OsmoMSC", "msc"),
|
||||
(4242, "src/osmo-nitb/osmo-nitb", "OpenBSC", "nitb"),
|
||||
(4253, "src/gprs/osmo-gtphub", "OsmoGTPhub", "gtphub")
|
||||
]
|
||||
|
||||
vty_command = ["./src/osmo-msc/osmo-msc", "-c",
|
||||
"doc/examples/osmo-msc/osmo-msc.cfg"]
|
||||
vty_command = ["./src/osmo-nitb/osmo-nitb", "-c",
|
||||
"doc/examples/osmo-nitb/nanobts/openbsc.cfg"]
|
||||
|
||||
vty_app = apps[5] # reference apps[] entry for osmo-nitb
|
||||
|
||||
@@ -22,7 +22,6 @@ AM_LDFLAGS = \
|
||||
# Libraries
|
||||
SUBDIRS = \
|
||||
libcommon \
|
||||
libvlr \
|
||||
libmgcp \
|
||||
libbsc \
|
||||
libmsc \
|
||||
@@ -40,11 +39,13 @@ endif
|
||||
|
||||
# Programs
|
||||
SUBDIRS += \
|
||||
osmo-msc \
|
||||
osmo-nitb \
|
||||
osmo-bsc_mgcp \
|
||||
utils \
|
||||
ipaccess \
|
||||
gprs \
|
||||
reg-proxy \
|
||||
ussd-proxy \
|
||||
$(NULL)
|
||||
|
||||
# Conditional Programs
|
||||
|
||||
@@ -241,7 +241,7 @@ int main(int argc, char **argv)
|
||||
|
||||
vty_info.copyright = openbsc_copyright;
|
||||
vty_init(&vty_info);
|
||||
logging_vty_add_cmds(NULL);
|
||||
logging_vty_add_cmds(&gprs_log_info);
|
||||
osmo_stats_vty_add_cmds(&gprs_log_info);
|
||||
gbproxy_vty_init();
|
||||
|
||||
|
||||
@@ -64,11 +64,9 @@
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
#include <openbsc/gprs_gmm.h>
|
||||
#include <openbsc/gprs_utils.h>
|
||||
#include <openbsc/gprs_subscriber.h>
|
||||
#include <openbsc/sgsn.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/iu.h>
|
||||
#include <openbsc/gprs_sndcp.h>
|
||||
|
||||
#include <pdp.h>
|
||||
|
||||
@@ -84,8 +82,6 @@ static const struct tlv_definition gsm48_gmm_att_tlvdef = {
|
||||
[GSM48_IE_GMM_PTMSI_SIG] = { TLV_TYPE_FIXED, 3 },
|
||||
[GSM48_IE_GMM_AUTH_RAND] = { TLV_TYPE_FIXED, 16 },
|
||||
[GSM48_IE_GMM_AUTH_SRES] = { TLV_TYPE_FIXED, 4 },
|
||||
[GSM48_IE_GMM_AUTH_RES_EXT] = { TLV_TYPE_TLV, 0 },
|
||||
[GSM48_IE_GMM_AUTH_FAIL_PAR] = { TLV_TYPE_TLV, 0 },
|
||||
[GSM48_IE_GMM_IMEISV] = { TLV_TYPE_TLV, 0 },
|
||||
[GSM48_IE_GMM_DRX_PARAM] = { TLV_TYPE_FIXED, 2 },
|
||||
[GSM48_IE_GMM_MS_NET_CAPA] = { TLV_TYPE_TLV, 0 },
|
||||
@@ -116,7 +112,6 @@ static const struct value_string gprs_pmm_state_names[] = {
|
||||
{ MM_IDLE, "MM IDLE" },
|
||||
{ MM_READY, "MM READY" },
|
||||
{ MM_STANDBY, "MM STANDBY" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx);
|
||||
@@ -180,33 +175,25 @@ int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *
|
||||
int rc = -1;
|
||||
|
||||
mm = sgsn_mm_ctx_by_ue_ctx(ctx);
|
||||
|
||||
#define REQUIRE_MM \
|
||||
if (!mm) { \
|
||||
LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %i!\n", type); \
|
||||
return rc; \
|
||||
if (!mm) {
|
||||
LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %i!\n", type);
|
||||
return rc;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case IU_EVENT_RAB_ASSIGN:
|
||||
REQUIRE_MM
|
||||
rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data);
|
||||
break;
|
||||
case IU_EVENT_IU_RELEASE:
|
||||
/* fall thru */
|
||||
case IU_EVENT_LINK_INVALIDATED:
|
||||
/* Clean up ue_conn_ctx here */
|
||||
if (mm)
|
||||
LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
|
||||
else
|
||||
LOGMMCTXP(LOGL_INFO, mm, "IU release for UE conn 0x%x\n",
|
||||
ctx->conn_id);
|
||||
if (mm && mm->pmm_state == PMM_CONNECTED)
|
||||
LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
|
||||
if (mm->pmm_state == PMM_CONNECTED)
|
||||
mmctx_set_pmm_state(mm, PMM_IDLE);
|
||||
rc = 0;
|
||||
break;
|
||||
case IU_EVENT_SECURITY_MODE_COMPLETE:
|
||||
REQUIRE_MM
|
||||
/* Continue authentication here */
|
||||
mm->iu.ue_ctx->integrity_active = 1;
|
||||
rc = gsm48_gmm_authorize(mm);
|
||||
@@ -297,10 +284,6 @@ static void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg)
|
||||
mm->gb.nsei = msgb_nsei(msg);
|
||||
/* In case a Iu connection is reconnected we need to update the ue ctx */
|
||||
mm->iu.ue_ctx = msg->dst;
|
||||
if (mm->ran_type == MM_CTX_T_UTRAN_Iu
|
||||
&& mm->iu.ue_ctx)
|
||||
mm->iu.ue_ctx->rab_assign_addr_enc =
|
||||
sgsn->cfg.iu.rab_assign_addr_enc;
|
||||
}
|
||||
|
||||
/* Store BVCI/NSEI in MM context */
|
||||
@@ -570,19 +553,8 @@ static int gsm48_tx_gmm_id_req(struct sgsn_mm_ctx *mm, uint8_t id_type)
|
||||
return gsm48_gmm_sendmsg(msg, 1, mm, false);
|
||||
}
|
||||
|
||||
/* determine if the MS/UE supports R99 or later */
|
||||
static bool mmctx_is_r99(const struct sgsn_mm_ctx *mm)
|
||||
{
|
||||
if (mm->ms_network_capa.len < 1)
|
||||
return false;
|
||||
if (mm->ms_network_capa.buf[0] & 0x01)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 3GPP TS 24.008 Section 9.4.9: Authentication and Ciphering Request */
|
||||
static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
|
||||
const struct osmo_auth_vector *vec,
|
||||
static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm, uint8_t *rnd,
|
||||
uint8_t key_seq, bool force_standby)
|
||||
{
|
||||
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH CIPH REQ");
|
||||
@@ -590,14 +562,8 @@ static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
|
||||
struct gsm48_auth_ciph_req *acreq;
|
||||
uint8_t *m_rand, *m_cksn, rbyte;
|
||||
|
||||
LOGMMCTXP(LOGL_INFO, mm, "<- GPRS AUTH AND CIPHERING REQ (rand = %s",
|
||||
osmo_hexdump(vec->rand, sizeof(vec->rand)));
|
||||
if (mmctx_is_r99(mm) && vec
|
||||
&& (vec->auth_types & OSMO_AUTH_TYPE_UMTS)) {
|
||||
LOGPC(DMM, LOGL_INFO, ", autn = %s)\n",
|
||||
osmo_hexdump(vec->autn, sizeof(vec->autn)));
|
||||
} else
|
||||
LOGPC(DMM, LOGL_INFO, ")\n");
|
||||
LOGMMCTXP(LOGL_INFO, mm, "<- GPRS AUTH AND CIPHERING REQ (rand = %s)\n",
|
||||
osmo_hexdump(rnd, 16));
|
||||
|
||||
mmctx2msgid(msg, mm);
|
||||
|
||||
@@ -621,25 +587,16 @@ static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
|
||||
mm->ac_ref_nr_used = acreq->ac_ref_nr;
|
||||
|
||||
/* Only if authentication is requested we need to set RAND + CKSN */
|
||||
if (vec) {
|
||||
m_rand = msgb_put(msg, sizeof(vec->rand) + 1);
|
||||
if (rnd) {
|
||||
m_rand = msgb_put(msg, 16+1);
|
||||
m_rand[0] = GSM48_IE_GMM_AUTH_RAND;
|
||||
memcpy(m_rand + 1, vec->rand, sizeof(vec->rand));
|
||||
|
||||
memcpy(m_rand + 1, rnd, 16);
|
||||
/* § 10.5.1.2: */
|
||||
m_cksn = msgb_put(msg, 1);
|
||||
m_cksn[0] = (GSM48_IE_GMM_CIPH_CKSN << 4) | (key_seq & 0x07);
|
||||
|
||||
/* A Release99 or higher MS/UE must be able to handle
|
||||
* the optional AUTN IE. If a classic GSM SIM is
|
||||
* inserted, it will simply ignore AUTN and just use
|
||||
* RAND */
|
||||
if (mmctx_is_r99(mm) &&
|
||||
(vec->auth_types & OSMO_AUTH_TYPE_UMTS)) {
|
||||
msgb_tlv_put(msg, GSM48_IE_GMM_AUTN,
|
||||
sizeof(vec->autn), vec->autn);
|
||||
}
|
||||
}
|
||||
/* FIXME: add AUTN for 3g auth according to 3GPP TS 24.008 § 10.5.3.1.1 */
|
||||
/* FIXME: make sure we don't send any other messages to the MS */
|
||||
|
||||
return gsm48_gmm_sendmsg(msg, 1, mm, false);
|
||||
}
|
||||
@@ -661,62 +618,6 @@ static int gsm48_tx_gmm_auth_ciph_rej(struct sgsn_mm_ctx *mm)
|
||||
return gsm48_gmm_sendmsg(msg, 0, mm, false);
|
||||
}
|
||||
|
||||
/* check if the received authentication response matches */
|
||||
static bool check_auth_resp(struct sgsn_mm_ctx *ctx,
|
||||
bool is_utran,
|
||||
const struct osmo_auth_vector *vec,
|
||||
const uint8_t *res, uint8_t res_len)
|
||||
{
|
||||
const uint8_t *expect_res;
|
||||
uint8_t expect_res_len;
|
||||
enum osmo_sub_auth_type expect_type;
|
||||
const char *expect_str;
|
||||
|
||||
if (!vec)
|
||||
return true; /* really!? */
|
||||
|
||||
/* On UTRAN (3G) we always expect UMTS AKA. On GERAN (2G) we sent AUTN
|
||||
* and expect UMTS AKA if there is R99 capability and our vector
|
||||
* supports UMTS AKA, otherwise we expect GSM AKA. */
|
||||
if (is_utran
|
||||
|| (mmctx_is_r99(ctx) && (vec->auth_types & OSMO_AUTH_TYPE_UMTS))) {
|
||||
expect_type = OSMO_AUTH_TYPE_UMTS;
|
||||
expect_str = "UMTS RES";
|
||||
expect_res = vec->res;
|
||||
expect_res_len = vec->res_len;
|
||||
} else {
|
||||
expect_type = OSMO_AUTH_TYPE_GSM;
|
||||
expect_str = "GSM SRES";
|
||||
expect_res = vec->sres;
|
||||
expect_res_len = sizeof(vec->sres);
|
||||
}
|
||||
|
||||
if (!(vec->auth_types & expect_type)) {
|
||||
LOGMMCTXP(LOGL_ERROR, ctx, "Auth error: auth vector does"
|
||||
" not provide the expected auth type:"
|
||||
" expected %s = 0x%x, auth_types are 0x%x\n",
|
||||
expect_str, expect_type, vec->auth_types);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!res)
|
||||
goto auth_mismatch;
|
||||
|
||||
if (res_len != expect_res_len)
|
||||
goto auth_mismatch;
|
||||
|
||||
if (memcmp(res, expect_res, res_len) != 0)
|
||||
goto auth_mismatch;
|
||||
|
||||
/* Authorized! */
|
||||
return true;
|
||||
|
||||
auth_mismatch:
|
||||
LOGMMCTXP(LOGL_ERROR, ctx, "Auth mismatch: expected %s = %s\n",
|
||||
expect_str, osmo_hexdump_nospc(expect_res, expect_res_len));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Section 9.4.10: Authentication and Ciphering Response */
|
||||
static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx,
|
||||
struct msgb *msg)
|
||||
@@ -725,9 +626,6 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx,
|
||||
struct gsm48_auth_ciph_resp *acr = (struct gsm48_auth_ciph_resp *)gh->data;
|
||||
struct tlv_parsed tp;
|
||||
struct gsm_auth_tuple *at;
|
||||
const char *res_name = "(no response)";
|
||||
uint8_t res[16];
|
||||
uint8_t res_len;
|
||||
int rc;
|
||||
|
||||
LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS AUTH AND CIPH RESPONSE\n");
|
||||
@@ -752,34 +650,26 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx,
|
||||
(msg->data + msg->len) - acr->data, 0, 0);
|
||||
|
||||
if (!TLVP_PRESENT(&tp, GSM48_IE_GMM_AUTH_SRES) ||
|
||||
!TLVP_PRESENT(&tp, GSM48_IE_GMM_IMEISV) ||
|
||||
TLVP_LEN(&tp,GSM48_IE_GMM_AUTH_SRES) != 4) {
|
||||
!TLVP_PRESENT(&tp, GSM48_IE_GMM_IMEISV)) {
|
||||
/* TODO: missing mandatory IE, return STATUS or REJ? */
|
||||
LOGMMCTXP(LOGL_ERROR, ctx, "Missing mandantory IE\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Start with the good old 4-byte SRES */
|
||||
memcpy(res, TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), 4);
|
||||
res_len = 4;
|
||||
res_name = "GSM SRES";
|
||||
|
||||
/* Append extended RES as part of UMTS AKA, if any */
|
||||
if (TLVP_PRESENT(&tp, GSM48_IE_GMM_AUTH_RES_EXT)) {
|
||||
unsigned int l = TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_RES_EXT);
|
||||
if (l > sizeof(res)-4)
|
||||
l = sizeof(res)-4;
|
||||
memcpy(res+4, TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_RES_EXT), l);
|
||||
res_len += l;
|
||||
res_name = "UMTS RES";
|
||||
}
|
||||
/* Compare SRES with what we expected */
|
||||
LOGMMCTXP(LOGL_DEBUG, ctx, "checking received auth info, SRES = %s\n",
|
||||
osmo_hexdump(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES),
|
||||
TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES)));
|
||||
|
||||
at = &ctx->auth_triplet;
|
||||
|
||||
LOGMMCTXP(LOGL_DEBUG, ctx, "checking auth: received %s = %s\n",
|
||||
res_name, osmo_hexdump(res, res_len));
|
||||
rc = check_auth_resp(ctx, false, &at->vec, res, res_len);
|
||||
if (!rc) {
|
||||
if (TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES) != sizeof(at->vec.sres) ||
|
||||
memcmp(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), at->vec.sres,
|
||||
sizeof(at->vec.sres)) != 0) {
|
||||
|
||||
LOGMMCTXP(LOGL_NOTICE, ctx, "Received SRES doesn't match "
|
||||
"expected RES %s\n", osmo_hexdump(at->vec.sres,
|
||||
sizeof(at->vec.sres)));
|
||||
rc = gsm48_tx_gmm_auth_ciph_rej(ctx);
|
||||
mm_ctx_cleanup_free(ctx, "GPRS AUTH AND CIPH REJECT");
|
||||
return rc;
|
||||
@@ -796,60 +686,6 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx,
|
||||
return gsm48_gmm_authorize(ctx);
|
||||
}
|
||||
|
||||
/* Section 9.4.10: Authentication and Ciphering Failure */
|
||||
static int gsm48_rx_gmm_auth_ciph_fail(struct sgsn_mm_ctx *ctx,
|
||||
struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
|
||||
struct tlv_parsed tp;
|
||||
const uint8_t gmm_cause = gh->data[0];
|
||||
const uint8_t *auts;
|
||||
int rc;
|
||||
|
||||
LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS AUTH AND CIPH FAILURE (cause = %s)\n",
|
||||
get_value_string(gsm48_gmm_cause_names, gmm_cause));
|
||||
|
||||
tlv_parse(&tp, &gsm48_gmm_att_tlvdef, gh->data+1, msg->len - 1, 0, 0);
|
||||
|
||||
/* Only if GMM cause is present and the AUTS is provided, we can
|
||||
* start re-sync procedure */
|
||||
if (gmm_cause == GMM_CAUSE_SYNC_FAIL &&
|
||||
TLVP_PRESENT(&tp, GSM48_IE_GMM_AUTH_FAIL_PAR)) {
|
||||
if (TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_FAIL_PAR) != 14) {
|
||||
LOGMMCTXP(LOGL_ERROR, ctx, "AUTS IE has wrong size:"
|
||||
" expected %d, got %u\n", 14,
|
||||
TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_FAIL_PAR));
|
||||
return -EINVAL;
|
||||
}
|
||||
auts = TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_FAIL_PAR);
|
||||
|
||||
LOGMMCTXP(LOGL_INFO, ctx,
|
||||
"R99 AUTHENTICATION SYNCH (AUTS = %s)\n",
|
||||
osmo_hexdump_nospc(auts, 14));
|
||||
|
||||
/* make sure we'll refresh the auth_triplet in
|
||||
* sgsn_auth_update() */
|
||||
ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
|
||||
|
||||
/* make sure we'll retry authentication after the resync */
|
||||
ctx->auth_state = SGSN_AUTH_UMTS_RESYNC;
|
||||
|
||||
/* Send AUTS to HLR and wait for new Auth Info Result */
|
||||
rc = gprs_subscr_request_auth_info(ctx, auts,
|
||||
ctx->auth_triplet.vec.rand);
|
||||
if (!rc)
|
||||
return 0;
|
||||
/* on error, fall through to send a reject */
|
||||
LOGMMCTXP(LOGL_ERROR, ctx,
|
||||
"Sending AUTS to HLR failed (rc = %d)\n", rc);
|
||||
}
|
||||
|
||||
LOGMMCTXP(LOGL_NOTICE, ctx, "Authentication failed\n");
|
||||
rc = gsm48_tx_gmm_auth_ciph_rej(ctx);
|
||||
mm_ctx_cleanup_free(ctx, "GPRS AUTH FAILURE");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx)
|
||||
{
|
||||
struct gsm_mncc_number called;
|
||||
@@ -977,14 +813,12 @@ static int gsm48_tx_gmm_service_rej(struct sgsn_mm_ctx *mm,
|
||||
static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm);
|
||||
|
||||
#ifdef BUILD_IU
|
||||
/* Send RAB activation requests for all PDP contexts */
|
||||
void activate_pdp_rabs(struct sgsn_mm_ctx *ctx)
|
||||
{
|
||||
/* Send RAB activation requests for all PDP contexts */
|
||||
struct sgsn_pdp_ctx *pdp;
|
||||
if (ctx->ran_type != MM_CTX_T_UTRAN_Iu)
|
||||
return;
|
||||
llist_for_each_entry(pdp, &ctx->pdp_list, list) {
|
||||
iu_rab_act_ps(pdp->nsapi, pdp);
|
||||
iu_rab_act_ps(pdp->nsapi, pdp, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1030,8 +864,8 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
|
||||
struct gsm_auth_tuple *at = &ctx->auth_triplet;
|
||||
|
||||
mmctx_timer_start(ctx, 3360, sgsn->cfg.timers.T3360);
|
||||
return gsm48_tx_gmm_auth_ciph_req(ctx, &at->vec, at->key_seq,
|
||||
false);
|
||||
return gsm48_tx_gmm_auth_ciph_req(ctx, at->vec.rand,
|
||||
at->key_seq, false);
|
||||
}
|
||||
|
||||
if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && ctx->is_authenticated &&
|
||||
@@ -1370,6 +1204,33 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
|
||||
ctx->ra = ra_id;
|
||||
if (ctx->ran_type == MM_CTX_T_GERAN_Gb)
|
||||
ctx->gb.cell_id = cid;
|
||||
else if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) {
|
||||
/* DEVELOPMENT HACK: Our current HLR does not support 3G
|
||||
* authentication tokens. A new HLR/VLR implementation is being
|
||||
* developed. Until it is ready and actual milenage
|
||||
* authentication is properly supported, we are hardcoding a
|
||||
* fixed Ki and use 2G auth. */
|
||||
unsigned char tmp_rand[16];
|
||||
/* Ki 000102030405060708090a0b0c0d0e0f */
|
||||
struct osmo_sub_auth_data auth = {
|
||||
.type = OSMO_AUTH_TYPE_GSM,
|
||||
.algo = OSMO_AUTH_ALG_COMP128v1,
|
||||
.u.gsm.ki = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
|
||||
0x0e, 0x0f
|
||||
},
|
||||
};
|
||||
/* XXX: Hack to make 3G auth work with special SIM card */
|
||||
ctx->auth_state = SGSN_AUTH_AUTHENTICATE;
|
||||
|
||||
RAND_bytes(tmp_rand, 16);
|
||||
|
||||
memset(&ctx->auth_triplet.vec, 0, sizeof(ctx->auth_triplet.vec));
|
||||
osmo_auth_gen_vec(&ctx->auth_triplet.vec, &auth, tmp_rand);
|
||||
|
||||
ctx->auth_triplet.key_seq = 0;
|
||||
}
|
||||
|
||||
/* Update MM Context with other data */
|
||||
ctx->drx_parms = drx_par;
|
||||
@@ -2049,9 +1910,6 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
|
||||
goto null_mmctx;
|
||||
rc = gsm48_rx_gmm_auth_ciph_resp(mmctx, msg);
|
||||
break;
|
||||
case GSM48_MT_GMM_AUTH_CIPH_FAIL:
|
||||
rc = gsm48_rx_gmm_auth_ciph_fail(mmctx, msg);
|
||||
break;
|
||||
default:
|
||||
LOGMMCTXP(LOGL_NOTICE, mmctx, "Unknown GSM 04.08 GMM msg type 0x%02x\n",
|
||||
gh->msg_type);
|
||||
@@ -2120,7 +1978,7 @@ static void mmctx_timer_cb(void *_mm)
|
||||
}
|
||||
at = &mm->auth_triplet;
|
||||
|
||||
gsm48_tx_gmm_auth_ciph_req(mm, &at->vec, at->key_seq, false);
|
||||
gsm48_tx_gmm_auth_ciph_req(mm, at->vec.rand, at->key_seq, false);
|
||||
osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3360, 0);
|
||||
break;
|
||||
case 3370: /* waiting for IDENTITY RESPONSE */
|
||||
@@ -2427,7 +2285,6 @@ static int do_act_pdp_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, bool *del
|
||||
char apn_str[GSM_APN_LENGTH] = { 0, };
|
||||
char *hostname;
|
||||
int rc;
|
||||
struct gprs_llc_lle *lle;
|
||||
|
||||
LOGMMCTXP(LOGL_INFO, mmctx, "-> ACTIVATE PDP CONTEXT REQ: SAPI=%u NSAPI=%u ",
|
||||
act_req->req_llc_sapi, act_req->req_nsapi);
|
||||
@@ -2503,19 +2360,7 @@ static int do_act_pdp_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, bool *del
|
||||
pdp->ti == transaction_id) {
|
||||
/* This apparently is a re-transmission of a PDP CTX
|
||||
* ACT REQ (our ACT ACK must have got dropped) */
|
||||
rc = gsm48_tx_gsm_act_pdp_acc(pdp);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
|
||||
/* Also re-transmit the SNDCP XID message */
|
||||
lle = &pdp->mm->gb.llme->lle[pdp->sapi];
|
||||
rc = sndcp_sn_xid_req(lle,pdp->nsapi);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return gsm48_tx_gsm_act_pdp_acc(pdp);
|
||||
}
|
||||
|
||||
/* Send reject with GSM_CAUSE_NSAPI_IN_USE */
|
||||
@@ -2905,16 +2750,14 @@ int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
|
||||
}
|
||||
|
||||
#ifdef BUILD_IU
|
||||
int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp)
|
||||
int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp, bool use_x213_nsap)
|
||||
{
|
||||
struct msgb *msg;
|
||||
struct sgsn_mm_ctx *mm = pdp->mm;
|
||||
struct ue_conn_ctx *uectx;
|
||||
uint32_t ggsn_ip;
|
||||
bool use_x213_nsap;
|
||||
|
||||
uectx = mm->iu.ue_ctx;
|
||||
use_x213_nsap = (uectx->rab_assign_addr_enc == NSAP_ADDR_ENC_X213);
|
||||
|
||||
/* Get the IP address for ggsn user plane */
|
||||
memcpy(&ggsn_ip, pdp->lib->gsnru.v, pdp->lib->gsnru.l);
|
||||
|
||||
@@ -48,7 +48,6 @@ struct value_string gprs_llc_state_strs[] = {
|
||||
{ GPRS_LLES_ABM, "Asynchronous Balanced Mode" },
|
||||
{ GPRS_LLES_LOCAL_REL, "Local Release" },
|
||||
{ GPRS_LLES_TIMER_REC, "Timer Recovery" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static void vty_dump_lle(struct vty *vty, struct gprs_llc_lle *lle)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <osmocom/gprs/gprs_bssgp.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
|
||||
#include <openbsc/gprs_subscriber.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
#include <openbsc/sgsn.h>
|
||||
@@ -247,7 +247,6 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx)
|
||||
|
||||
ctx->ran_type = MM_CTX_T_UTRAN_Iu;
|
||||
ctx->iu.ue_ctx = uectx;
|
||||
ctx->iu.ue_ctx->rab_assign_addr_enc = sgsn->cfg.iu.rab_assign_addr_enc;
|
||||
ctx->iu.new_key = 1;
|
||||
ctx->gmm_state = GMM_DEREGISTERED;
|
||||
ctx->pmm_state = PMM_DETACHED;
|
||||
@@ -322,9 +321,9 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
|
||||
|
||||
/* Detach from subscriber which is possibly freed then */
|
||||
if (mm->subscr) {
|
||||
struct gprs_subscr *subscr = gprs_subscr_get(mm->subscr);
|
||||
struct gsm_subscriber *subscr = subscr_get(mm->subscr);
|
||||
gprs_subscr_cleanup(subscr);
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
}
|
||||
|
||||
sgsn_mm_ctx_free(mm);
|
||||
@@ -612,7 +611,7 @@ struct apn_ctx *sgsn_apn_ctx_find_alloc(const char *name, const char *imsi_prefi
|
||||
uint32_t sgsn_alloc_ptmsi(void)
|
||||
{
|
||||
struct sgsn_mm_ctx *mm;
|
||||
uint32_t ptmsi = 0xdeadbeef;
|
||||
uint32_t ptmsi;
|
||||
int max_retries = 100;
|
||||
|
||||
restart:
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
#include <osmocom/gsm/gsup.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <openbsc/gprs_subscriber.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/gsup_client.h>
|
||||
|
||||
#include <openbsc/sgsn.h>
|
||||
@@ -36,7 +35,6 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define SGSN_SUBSCR_MAX_RETRIES 3
|
||||
#define SGSN_SUBSCR_RETRY_INTERVAL 10
|
||||
@@ -48,9 +46,6 @@
|
||||
|
||||
extern void *tall_bsc_ctx;
|
||||
|
||||
LLIST_HEAD(_gprs_subscribers);
|
||||
struct llist_head * const gprs_subscribers = &_gprs_subscribers;
|
||||
|
||||
static int gsup_read_cb(struct gsup_client *gsupc, struct msgb *msg);
|
||||
|
||||
/* TODO: Some functions are specific to the SGSN, but this file is more general
|
||||
@@ -69,7 +64,6 @@ int gprs_subscr_init(struct sgsn_instance *sgi)
|
||||
addr_str = inet_ntoa(sgi->cfg.gsup_server_addr.sin_addr);
|
||||
|
||||
sgi->gsup_client = gsup_client_create(
|
||||
"SGSN",
|
||||
addr_str, sgi->cfg.gsup_server_port,
|
||||
&gsup_read_cb,
|
||||
&sgi->cfg.oap);
|
||||
@@ -92,7 +86,7 @@ static int gsup_read_cb(struct gsup_client *gsupc, struct msgb *msg)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int gprs_subscr_purge(struct gprs_subscr *subscr);
|
||||
int gprs_subscr_purge(struct gsm_subscriber *subscr);
|
||||
|
||||
static struct sgsn_subscriber_data *sgsn_subscriber_data_alloc(void *ctx)
|
||||
{
|
||||
@@ -123,53 +117,28 @@ struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
|
||||
return pdata;
|
||||
}
|
||||
|
||||
struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi)
|
||||
struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi)
|
||||
{
|
||||
struct gprs_subscr *gsub;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
if (!imsi || !*imsi)
|
||||
subscr = subscr_get_or_create(NULL, imsi);
|
||||
if (!subscr)
|
||||
return NULL;
|
||||
|
||||
llist_for_each_entry(gsub, gprs_subscribers, entry) {
|
||||
if (!strcmp(gsub->imsi, imsi))
|
||||
return gprs_subscr_get(gsub);
|
||||
}
|
||||
return NULL;
|
||||
if (!subscr->sgsn_data)
|
||||
subscr->sgsn_data = sgsn_subscriber_data_alloc(subscr);
|
||||
return subscr;
|
||||
}
|
||||
|
||||
static struct gprs_subscr *gprs_subscr_alloc(void)
|
||||
struct gsm_subscriber *gprs_subscr_get_by_imsi(const char *imsi)
|
||||
{
|
||||
struct gprs_subscr *gsub;
|
||||
gsub = talloc_zero(tall_bsc_ctx, struct gprs_subscr);
|
||||
if (!gsub)
|
||||
return NULL;
|
||||
llist_add_tail(&gsub->entry, gprs_subscribers);
|
||||
gsub->use_count = 1;
|
||||
gsub->tmsi = GSM_RESERVED_TMSI;
|
||||
return gsub;
|
||||
return subscr_active_by_imsi(NULL, imsi);
|
||||
}
|
||||
|
||||
struct gprs_subscr *gprs_subscr_get_or_create(const char *imsi)
|
||||
{
|
||||
struct gprs_subscr *gsub;
|
||||
|
||||
gsub = gprs_subscr_get_by_imsi(imsi);
|
||||
if (!gsub) {
|
||||
gsub = gprs_subscr_alloc();
|
||||
if (!gsub)
|
||||
return NULL;
|
||||
strncpy(gsub->imsi, imsi, sizeof(gsub->imsi));
|
||||
}
|
||||
|
||||
if (!gsub->sgsn_data)
|
||||
gsub->sgsn_data = sgsn_subscriber_data_alloc(gsub);
|
||||
return gsub;
|
||||
}
|
||||
|
||||
void gprs_subscr_cleanup(struct gprs_subscr *subscr)
|
||||
void gprs_subscr_cleanup(struct gsm_subscriber *subscr)
|
||||
{
|
||||
if (subscr->sgsn_data->mm) {
|
||||
gprs_subscr_put(subscr->sgsn_data->mm->subscr);
|
||||
subscr_put(subscr->sgsn_data->mm->subscr);
|
||||
subscr->sgsn_data->mm->subscr = NULL;
|
||||
subscr->sgsn_data->mm = NULL;
|
||||
}
|
||||
@@ -180,7 +149,7 @@ void gprs_subscr_cleanup(struct gprs_subscr *subscr)
|
||||
}
|
||||
}
|
||||
|
||||
void gprs_subscr_cancel(struct gprs_subscr *subscr)
|
||||
void gprs_subscr_cancel(struct gsm_subscriber *subscr)
|
||||
{
|
||||
subscr->authorized = 0;
|
||||
subscr->flags |= GPRS_SUBSCRIBER_CANCELLED;
|
||||
@@ -190,7 +159,7 @@ void gprs_subscr_cancel(struct gprs_subscr *subscr)
|
||||
gprs_subscr_cleanup(subscr);
|
||||
}
|
||||
|
||||
static int gprs_subscr_tx_gsup_message(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_tx_gsup_message(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
struct msgb *msg = gsup_client_msgb_alloc();
|
||||
@@ -212,7 +181,7 @@ static int gprs_subscr_tx_gsup_message(struct gprs_subscr *subscr,
|
||||
return gsup_client_send(sgsn->gsup_client, msg);
|
||||
}
|
||||
|
||||
static int gprs_subscr_tx_gsup_error_reply(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_tx_gsup_error_reply(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_orig,
|
||||
enum gsm48_gmm_cause cause)
|
||||
{
|
||||
@@ -227,7 +196,7 @@ static int gprs_subscr_tx_gsup_error_reply(struct gprs_subscr *subscr,
|
||||
return gprs_subscr_tx_gsup_message(subscr, &gsup_reply);
|
||||
}
|
||||
|
||||
static int gprs_subscr_handle_gsup_auth_res(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_handle_gsup_auth_res(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
unsigned idx;
|
||||
@@ -266,7 +235,7 @@ static int gprs_subscr_handle_gsup_auth_res(struct gprs_subscr *subscr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gprs_subscr_pdp_data_clear(struct gprs_subscr *subscr)
|
||||
static int gprs_subscr_pdp_data_clear(struct gsm_subscriber *subscr)
|
||||
{
|
||||
struct sgsn_subscriber_pdp_data *pdp, *pdp2;
|
||||
int count = 0;
|
||||
@@ -281,7 +250,7 @@ static int gprs_subscr_pdp_data_clear(struct gprs_subscr *subscr)
|
||||
}
|
||||
|
||||
static struct sgsn_subscriber_pdp_data *gprs_subscr_pdp_data_get_by_id(
|
||||
struct gprs_subscr *subscr, unsigned context_id)
|
||||
struct gsm_subscriber *subscr, unsigned context_id)
|
||||
{
|
||||
struct sgsn_subscriber_pdp_data *pdp;
|
||||
|
||||
@@ -294,7 +263,7 @@ static struct sgsn_subscriber_pdp_data *gprs_subscr_pdp_data_get_by_id(
|
||||
}
|
||||
|
||||
|
||||
static void gprs_subscr_gsup_insert_data(struct gprs_subscr *subscr,
|
||||
static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
struct sgsn_subscriber_data *sdata = subscr->sgsn_data;
|
||||
@@ -371,7 +340,7 @@ static void gprs_subscr_gsup_insert_data(struct gprs_subscr *subscr,
|
||||
}
|
||||
}
|
||||
|
||||
static int gprs_subscr_handle_gsup_upd_loc_res(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_handle_gsup_upd_loc_res(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
/* contrary to MAP, we allow piggy-backing subscriber data onto
|
||||
@@ -388,27 +357,7 @@ static int gprs_subscr_handle_gsup_upd_loc_res(struct gprs_subscr *subscr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gprs_subscr_handle_gsup_dsd_req(struct gprs_subscr *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
struct osmo_gsup_message gsup_reply = {0};
|
||||
|
||||
if (gsup_msg->cn_domain != OSMO_GSUP_CN_DOMAIN_PS) {
|
||||
LOGGSUBSCRP(LOGL_ERROR, subscr,
|
||||
"Rx GSUP message %s not supported for CS\n",
|
||||
osmo_gsup_message_type_name(gsup_msg->message_type));
|
||||
gsup_reply.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
|
||||
gsup_reply.message_type = OSMO_GSUP_MSGT_DELETE_DATA_ERROR;
|
||||
} else {
|
||||
gsm0408_gprs_access_cancelled(subscr->sgsn_data->mm,
|
||||
GMM_CAUSE_GPRS_NOTALLOWED);
|
||||
gsup_reply.message_type = OSMO_GSUP_MSGT_DELETE_DATA_RESULT;
|
||||
}
|
||||
|
||||
return gprs_subscr_tx_gsup_message(subscr, &gsup_reply);
|
||||
}
|
||||
|
||||
static int gprs_subscr_handle_gsup_isd_req(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_handle_gsup_isd_req(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
struct osmo_gsup_message gsup_reply = {0};
|
||||
@@ -440,7 +389,7 @@ static int check_cause(int cause)
|
||||
}
|
||||
}
|
||||
|
||||
static int gprs_subscr_handle_gsup_auth_err(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_handle_gsup_auth_err(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
unsigned idx;
|
||||
@@ -493,7 +442,7 @@ static int gprs_subscr_handle_gsup_auth_err(struct gprs_subscr *subscr,
|
||||
return -gsup_msg->cause;
|
||||
}
|
||||
|
||||
static int gprs_subscr_handle_gsup_upd_loc_err(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_handle_gsup_upd_loc_err(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
int cause_err;
|
||||
@@ -554,7 +503,7 @@ static int gprs_subscr_handle_gsup_purge_no_subscr(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gprs_subscr_handle_gsup_purge_res(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_handle_gsup_purge_res(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
LOGGSUBSCRP(LOGL_INFO, subscr, "Completing purge MS\n");
|
||||
@@ -566,7 +515,7 @@ static int gprs_subscr_handle_gsup_purge_res(struct gprs_subscr *subscr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gprs_subscr_handle_gsup_purge_err(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_handle_gsup_purge_err(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
LOGGSUBSCRP(LOGL_NOTICE, subscr,
|
||||
@@ -599,7 +548,7 @@ static int gprs_subscr_handle_gsup_purge_err(struct gprs_subscr *subscr,
|
||||
return -gsup_msg->cause;
|
||||
}
|
||||
|
||||
static int gprs_subscr_handle_loc_cancel_req(struct gprs_subscr *subscr,
|
||||
static int gprs_subscr_handle_loc_cancel_req(struct gsm_subscriber *subscr,
|
||||
struct osmo_gsup_message *gsup_msg)
|
||||
{
|
||||
struct osmo_gsup_message gsup_reply = {0};
|
||||
@@ -660,7 +609,7 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg)
|
||||
int rc = 0;
|
||||
|
||||
struct osmo_gsup_message gsup_msg = {0};
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
rc = osmo_gsup_decode(data, data_len, &gsup_msg);
|
||||
if (rc < 0) {
|
||||
@@ -695,8 +644,7 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg)
|
||||
}
|
||||
|
||||
LOGGSUBSCRP(LOGL_INFO, subscr,
|
||||
"Received GSUP message %s\n",
|
||||
osmo_gsup_message_type_name(gsup_msg.message_type));
|
||||
"Received GSUP message of type 0x%02x\n", gsup_msg.message_type);
|
||||
|
||||
switch (gsup_msg.message_type) {
|
||||
case OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST:
|
||||
@@ -732,13 +680,18 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg)
|
||||
break;
|
||||
|
||||
case OSMO_GSUP_MSGT_DELETE_DATA_REQUEST:
|
||||
rc = gprs_subscr_handle_gsup_dsd_req(subscr, &gsup_msg);
|
||||
LOGGSUBSCRP(LOGL_ERROR, subscr,
|
||||
"Rx GSUP message type %d not yet implemented\n",
|
||||
gsup_msg.message_type);
|
||||
gprs_subscr_tx_gsup_error_reply(subscr, &gsup_msg,
|
||||
GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
|
||||
rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGGSUBSCRP(LOGL_ERROR, subscr,
|
||||
"Rx GSUP message %s not valid at SGSN\n",
|
||||
osmo_gsup_message_type_name(gsup_msg.message_type));
|
||||
"Rx GSUP message type %d not valid at SGSN\n",
|
||||
gsup_msg.message_type);
|
||||
if (OSMO_GSUP_IS_MSGT_REQUEST(gsup_msg.message_type))
|
||||
gprs_subscr_tx_gsup_error_reply(
|
||||
subscr, &gsup_msg, GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
|
||||
@@ -746,12 +699,12 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg)
|
||||
break;
|
||||
};
|
||||
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int gprs_subscr_purge(struct gprs_subscr *subscr)
|
||||
int gprs_subscr_purge(struct gsm_subscriber *subscr)
|
||||
{
|
||||
struct sgsn_subscriber_data *sdata = subscr->sgsn_data;
|
||||
struct osmo_gsup_message gsup_msg = {0};
|
||||
@@ -767,25 +720,18 @@ int gprs_subscr_purge(struct gprs_subscr *subscr)
|
||||
return gprs_subscr_tx_gsup_message(subscr, &gsup_msg);
|
||||
}
|
||||
|
||||
static int gprs_subscr_query_auth_info(struct gprs_subscr *subscr,
|
||||
const uint8_t *auts,
|
||||
const uint8_t *auts_rand)
|
||||
int gprs_subscr_query_auth_info(struct gsm_subscriber *subscr)
|
||||
{
|
||||
struct osmo_gsup_message gsup_msg = {0};
|
||||
|
||||
/* Make sure we have a complete resync or clearly no resync. */
|
||||
OSMO_ASSERT((auts != NULL) == (auts_rand != NULL));
|
||||
|
||||
LOGGSUBSCRP(LOGL_INFO, subscr, "requesting auth info%s\n",
|
||||
auts ? " with AUTS (UMTS Resynch)" : "");
|
||||
LOGGSUBSCRP(LOGL_INFO, subscr,
|
||||
"subscriber auth info is not available\n");
|
||||
|
||||
gsup_msg.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST;
|
||||
gsup_msg.auts = auts;
|
||||
gsup_msg.rand = auts_rand;
|
||||
return gprs_subscr_tx_gsup_message(subscr, &gsup_msg);
|
||||
}
|
||||
|
||||
int gprs_subscr_location_update(struct gprs_subscr *subscr)
|
||||
int gprs_subscr_location_update(struct gsm_subscriber *subscr)
|
||||
{
|
||||
struct osmo_gsup_message gsup_msg = {0};
|
||||
|
||||
@@ -796,59 +742,60 @@ int gprs_subscr_location_update(struct gprs_subscr *subscr)
|
||||
return gprs_subscr_tx_gsup_message(subscr, &gsup_msg);
|
||||
}
|
||||
|
||||
void gprs_subscr_update(struct gprs_subscr *subscr)
|
||||
void gprs_subscr_update(struct gsm_subscriber *subscr)
|
||||
{
|
||||
LOGGSUBSCRP(LOGL_DEBUG, subscr, "Updating subscriber data\n");
|
||||
|
||||
subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING;
|
||||
subscr->flags &= ~GPRS_SUBSCRIBER_FIRST_CONTACT;
|
||||
subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT;
|
||||
|
||||
if (subscr->sgsn_data->mm)
|
||||
sgsn_update_subscriber_data(subscr->sgsn_data->mm);
|
||||
}
|
||||
|
||||
void gprs_subscr_update_auth_info(struct gprs_subscr *subscr)
|
||||
void gprs_subscr_update_auth_info(struct gsm_subscriber *subscr)
|
||||
{
|
||||
LOGGSUBSCRP(LOGL_DEBUG, subscr,
|
||||
"Updating subscriber authentication info\n");
|
||||
|
||||
subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING;
|
||||
subscr->flags &= ~GPRS_SUBSCRIBER_FIRST_CONTACT;
|
||||
subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT;
|
||||
|
||||
if (subscr->sgsn_data->mm)
|
||||
sgsn_update_subscriber_data(subscr->sgsn_data->mm);
|
||||
}
|
||||
|
||||
struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx(struct sgsn_mm_ctx *mmctx)
|
||||
struct gsm_subscriber *gprs_subscr_get_or_create_by_mmctx(struct sgsn_mm_ctx *mmctx)
|
||||
{
|
||||
struct gprs_subscr *subscr = NULL;
|
||||
struct gsm_subscriber *subscr = NULL;
|
||||
|
||||
if (mmctx->subscr)
|
||||
return gprs_subscr_get(mmctx->subscr);
|
||||
return subscr_get(mmctx->subscr);
|
||||
|
||||
if (mmctx->imsi[0])
|
||||
subscr = gprs_subscr_get_by_imsi(mmctx->imsi);
|
||||
|
||||
if (!subscr) {
|
||||
subscr = gprs_subscr_get_or_create(mmctx->imsi);
|
||||
subscr->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
|
||||
subscr->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
|
||||
subscr->flags &= ~GPRS_SUBSCRIBER_ENABLE_PURGE;
|
||||
}
|
||||
|
||||
osmo_strlcpy(subscr->imei, mmctx->imei, sizeof(subscr->imei));
|
||||
osmo_strlcpy(subscr->equipment.imei, mmctx->imei,
|
||||
sizeof(subscr->equipment.imei));
|
||||
|
||||
if (subscr->lac != mmctx->ra.lac)
|
||||
subscr->lac = mmctx->ra.lac;
|
||||
|
||||
subscr->sgsn_data->mm = mmctx;
|
||||
mmctx->subscr = gprs_subscr_get(subscr);
|
||||
mmctx->subscr = subscr_get(subscr);
|
||||
|
||||
return subscr;
|
||||
}
|
||||
|
||||
int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx)
|
||||
{
|
||||
struct gprs_subscr *subscr = NULL;
|
||||
struct gsm_subscriber *subscr = NULL;
|
||||
int rc;
|
||||
|
||||
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n");
|
||||
@@ -858,22 +805,13 @@ int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx)
|
||||
subscr->flags |= GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING;
|
||||
|
||||
rc = gprs_subscr_location_update(subscr);
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*! \brief Send Update Auth Info request via GSUP, with or without resync.
|
||||
* \param[in] mmctx MM context to request authentication tuples for.
|
||||
* \param[in] auts 14 octet AUTS token for UMTS resync, or NULL.
|
||||
* \param[in] auts_rand 16 octet Random token for UMTS resync, or NULL.
|
||||
* In case of normal Authentication Info request, both \a auts and \a auts_rand
|
||||
* must be NULL. For resync, both must be non-NULL.
|
||||
*/
|
||||
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx,
|
||||
const uint8_t *auts,
|
||||
const uint8_t *auts_rand)
|
||||
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx)
|
||||
{
|
||||
struct gprs_subscr *subscr = NULL;
|
||||
struct gsm_subscriber *subscr = NULL;
|
||||
int rc;
|
||||
|
||||
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber authentication info\n");
|
||||
@@ -882,41 +820,7 @@ int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx,
|
||||
|
||||
subscr->flags |= GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING;
|
||||
|
||||
rc = gprs_subscr_query_auth_info(subscr, auts, auts_rand);
|
||||
gprs_subscr_put(subscr);
|
||||
rc = gprs_subscr_query_auth_info(subscr);
|
||||
subscr_put(subscr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void gprs_subscr_free(struct gprs_subscr *gsub)
|
||||
{
|
||||
llist_del(&gsub->entry);
|
||||
talloc_free(gsub);
|
||||
}
|
||||
|
||||
struct gprs_subscr *_gprs_subscr_get(struct gprs_subscr *gsub,
|
||||
const char *file, int line)
|
||||
{
|
||||
OSMO_ASSERT(gsub->use_count < INT_MAX);
|
||||
gsub->use_count++;
|
||||
LOGPSRC(DREF, LOGL_DEBUG, file, line,
|
||||
"subscr %s usage increases to: %d\n",
|
||||
gsub->imsi, gsub->use_count);
|
||||
return gsub;
|
||||
}
|
||||
|
||||
struct gprs_subscr *_gprs_subscr_put(struct gprs_subscr *gsub,
|
||||
const char *file, int line)
|
||||
{
|
||||
gsub->use_count--;
|
||||
LOGPSRC(DREF, gsub->use_count >= 0? LOGL_DEBUG : LOGL_ERROR,
|
||||
file, line,
|
||||
"subscr %s usage decreases to: %d%s\n",
|
||||
gsub->imsi, gsub->use_count,
|
||||
gsub->keep_in_ram? ", keep-in-ram flag is set" : "");
|
||||
if (gsub->use_count > 0)
|
||||
return gsub;
|
||||
if (gsub->keep_in_ram)
|
||||
return gsub;
|
||||
gprs_subscr_free(gsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ int main(int argc, char **argv)
|
||||
|
||||
vty_info.copyright = gtphub_copyright;
|
||||
vty_init(&vty_info);
|
||||
logging_vty_add_cmds(NULL);
|
||||
logging_vty_add_cmds(>phub_log_info);
|
||||
gtphub_vty_init(hub, cfg);
|
||||
|
||||
rate_ctr_init(osmo_gtphub_ctx);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <openbsc/sgsn.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
#include <openbsc/gprs_gmm.h>
|
||||
#include <openbsc/gprs_subscriber.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
const struct value_string auth_state_names[] = {
|
||||
@@ -32,7 +32,6 @@ const struct value_string auth_state_names[] = {
|
||||
{ SGSN_AUTH_REJECTED, "rejected"},
|
||||
{ SGSN_AUTH_UNKNOWN, "unknown"},
|
||||
{ SGSN_AUTH_AUTHENTICATE, "authenticate" },
|
||||
{ SGSN_AUTH_UMTS_RESYNC, "UMTS-resync" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
@@ -152,7 +151,7 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx)
|
||||
*/
|
||||
int sgsn_auth_request(struct sgsn_mm_ctx *mmctx)
|
||||
{
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
struct gsm_auth_tuple *at;
|
||||
int need_update_location;
|
||||
int rc;
|
||||
@@ -170,7 +169,7 @@ int sgsn_auth_request(struct sgsn_mm_ctx *mmctx)
|
||||
|
||||
/* This has the side effect of registering the subscr with the mmctx */
|
||||
subscr = gprs_subscr_get_or_create_by_mmctx(mmctx);
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
|
||||
OSMO_ASSERT(mmctx->subscr != NULL);
|
||||
|
||||
@@ -183,7 +182,7 @@ int sgsn_auth_request(struct sgsn_mm_ctx *mmctx)
|
||||
mmctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
|
||||
LOGMMCTXP(LOGL_INFO, mmctx,
|
||||
"Requesting authentication tuples\n");
|
||||
rc = gprs_subscr_request_auth_info(mmctx, NULL, NULL);
|
||||
rc = gprs_subscr_request_auth_info(mmctx);
|
||||
if (rc >= 0)
|
||||
return 0;
|
||||
|
||||
@@ -208,7 +207,7 @@ int sgsn_auth_request(struct sgsn_mm_ctx *mmctx)
|
||||
void sgsn_auth_update(struct sgsn_mm_ctx *mmctx)
|
||||
{
|
||||
enum sgsn_auth_state auth_state;
|
||||
struct gprs_subscr *subscr = mmctx->subscr;
|
||||
struct gsm_subscriber *subscr = mmctx->subscr;
|
||||
struct gsm_auth_tuple *at;
|
||||
int gmm_cause;
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#include <openbsc/gprs_llc.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
#include <openbsc/gprs_gmm.h>
|
||||
#include <openbsc/gprs_subscriber.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/gprs_sndcp.h>
|
||||
|
||||
#ifdef BUILD_IU
|
||||
@@ -247,8 +247,12 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
|
||||
memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr.sin_addr,
|
||||
sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
|
||||
|
||||
/* Routing Area Identifier with LAC and RAC fixed values, as
|
||||
* requested in 29.006 7.3.1 */
|
||||
/* Assume we are a GERAN system */
|
||||
pdp->rattype.l = 1;
|
||||
pdp->rattype.v[0] = 2;
|
||||
pdp->rattype_given = 1;
|
||||
|
||||
/* Include RAI and ULI all the time */
|
||||
pdp->rai_given = 1;
|
||||
pdp->rai.l = 6;
|
||||
raid = mmctx->ra;
|
||||
@@ -256,24 +260,10 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
|
||||
raid.rac = 0xFF;
|
||||
gsm48_construct_ra(pdp->rai.v, &raid);
|
||||
|
||||
pdp->rattype.l = 1;
|
||||
pdp->rattype_given = 1;
|
||||
|
||||
switch (mmctx->ran_type) {
|
||||
case MM_CTX_T_GERAN_Gb:
|
||||
case MM_CTX_T_GERAN_Iu:
|
||||
pdp->rattype.v[0] = 2;
|
||||
/* User Location Information */
|
||||
pdp->userloc_given = 1;
|
||||
pdp->userloc.l = 8;
|
||||
pdp->userloc.v[0] = 0; /* CGI for GERAN */
|
||||
bssgp_create_cell_id(&pdp->userloc.v[1], &mmctx->ra, mmctx->gb.cell_id);
|
||||
break;
|
||||
case MM_CTX_T_UTRAN_Iu:
|
||||
pdp->rattype.v[0] = 1;
|
||||
/* FIXME: Optional User Location Information with SAI */
|
||||
break;
|
||||
}
|
||||
pdp->userloc_given = 1;
|
||||
pdp->userloc.l = 8;
|
||||
pdp->userloc.v[0] = 0; /* CGI for GERAN */
|
||||
bssgp_create_cell_id(&pdp->userloc.v[1], &mmctx->ra, mmctx->gb.cell_id);
|
||||
|
||||
/* include the IMEI(SV) */
|
||||
pdp->imeisv_given = 1;
|
||||
@@ -407,7 +397,7 @@ static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
|
||||
} else if (pctx->mm->ran_type == MM_CTX_T_UTRAN_Iu) {
|
||||
#ifdef BUILD_IU
|
||||
/* Activate a radio bearer */
|
||||
iu_rab_act_ps(pdp->nsapi, pctx);
|
||||
iu_rab_act_ps(pdp->nsapi, pctx, 1);
|
||||
return 0;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
@@ -651,6 +641,8 @@ static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len)
|
||||
struct msgb *msg;
|
||||
uint8_t *ud;
|
||||
|
||||
DEBUGP(DGPRS, "GTP DATA IND from GGSN, length=%u\n", len);
|
||||
|
||||
pdp = lib->priv;
|
||||
if (!pdp) {
|
||||
LOGP(DGPRS, LOGL_NOTICE,
|
||||
@@ -660,14 +652,10 @@ static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len)
|
||||
mm = pdp->mm;
|
||||
if (!mm) {
|
||||
LOGP(DGPRS, LOGL_ERROR,
|
||||
"PDP context (address=%u) without MM context!\n",
|
||||
pdp->address);
|
||||
"PDP context (imsi=%s) without MM context!\n", mm->imsi);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
DEBUGP(DGPRS, "GTP DATA IND from GGSN for %s, length=%u\n", mm->imsi,
|
||||
len);
|
||||
|
||||
if (mm->ran_type == MM_CTX_T_UTRAN_Iu) {
|
||||
#ifdef BUILD_IU
|
||||
/* Ignore the packet for now and page the UE to get the RAB
|
||||
|
||||
@@ -195,12 +195,11 @@ static void handle_options(int argc, char **argv)
|
||||
{"config-file", 1, 0, 'c'},
|
||||
{"disable-color", 0, 0, 's'},
|
||||
{"timestamp", 0, 0, 'T'},
|
||||
{ "version", 0, 0, 'V' },
|
||||
{"log-level", 1, 0, 'e'},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hd:Dc:sTVe:",
|
||||
c = getopt_long(argc, argv, "hd:Dc:sTe:",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
@@ -225,10 +224,6 @@ static void handle_options(int argc, char **argv)
|
||||
case 'T':
|
||||
log_set_print_timestamp(osmo_stderr_target, 1);
|
||||
break;
|
||||
case 'V':
|
||||
print_version(1);
|
||||
exit(0);
|
||||
break;
|
||||
case 'e':
|
||||
log_set_log_level(osmo_stderr_target, atoi(optarg));
|
||||
break;
|
||||
@@ -316,6 +311,12 @@ static const struct log_info gprs_log_info = {
|
||||
.num_cat = ARRAY_SIZE(gprs_categories),
|
||||
};
|
||||
|
||||
/* Implement the extern asn_debug from libasn1c to indicate whether the ASN.1
|
||||
* binary code decoded and encoded during Iu communication should be logged to
|
||||
* stderr. See osmocom's libasn1c, asn_internal.h, at "if (asn_debug)":
|
||||
* http://git.osmocom.org/libasn1c/tree/include/asn1c/asn_internal.h */
|
||||
int asn_debug = 0;
|
||||
|
||||
int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@@ -339,10 +340,13 @@ int main(int argc, char **argv)
|
||||
|
||||
vty_info.copyright = openbsc_copyright;
|
||||
vty_init(&vty_info);
|
||||
logging_vty_add_cmds(NULL);
|
||||
logging_vty_add_cmds(&gprs_log_info);
|
||||
osmo_stats_vty_add_cmds(&gprs_log_info);
|
||||
sgsn_vty_init(&sgsn_inst.cfg);
|
||||
sgsn_vty_init();
|
||||
ctrl_vty_init(tall_bsc_ctx);
|
||||
#ifdef BUILD_IU
|
||||
iu_vty_init(&asn_debug);
|
||||
#endif
|
||||
|
||||
handle_options(argc, argv);
|
||||
|
||||
@@ -370,9 +374,9 @@ int main(int argc, char **argv)
|
||||
sgsn_cdr_init(&sgsn_inst);
|
||||
/* FIXME: register signal handler for SS_L_NS */
|
||||
|
||||
rc = sgsn_parse_config(sgsn_inst.config_file);
|
||||
rc = sgsn_parse_config(sgsn_inst.config_file, &sgsn_inst.cfg);
|
||||
if (rc < 0) {
|
||||
LOGP(DGPRS, LOGL_FATAL, "Error in config file\n");
|
||||
LOGP(DGPRS, LOGL_FATAL, "Cannot parse config file\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,12 +44,6 @@
|
||||
|
||||
#include <pdp.h>
|
||||
|
||||
#include "../../bscconfig.h"
|
||||
|
||||
#ifdef BUILD_IU
|
||||
#include <openbsc/iu.h>
|
||||
#endif
|
||||
|
||||
static struct sgsn_config *g_cfg = NULL;
|
||||
|
||||
const struct value_string sgsn_auth_pol_strs[] = {
|
||||
@@ -303,8 +297,6 @@ static int config_write_sgsn(struct vty *vty)
|
||||
} else
|
||||
vty_out(vty, " no compression v42bis%s", VTY_NEWLINE);
|
||||
|
||||
iu_vty_config_write(vty, " ");
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -594,20 +586,10 @@ DEFUN(imsi_acl, cfg_imsi_acl_cmd,
|
||||
"Remove IMSI from ACL\n"
|
||||
"IMSI of subscriber\n")
|
||||
{
|
||||
char imsi_sanitized[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
const char *op = argv[0];
|
||||
const char *imsi = imsi_sanitized;
|
||||
const char *imsi = argv[1];
|
||||
int rc;
|
||||
|
||||
/* Sanitize IMSI */
|
||||
if (strlen(argv[1]) > GSM23003_IMSI_MAX_DIGITS) {
|
||||
vty_out(vty, "%% IMSI (%s) too long -- ignored!%s",
|
||||
argv[1], VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
memset(imsi_sanitized, '0', sizeof(imsi_sanitized));
|
||||
strcpy(imsi_sanitized+GSM23003_IMSI_MAX_DIGITS-strlen(argv[1]),argv[1]);
|
||||
|
||||
if (!strcmp(op, "add"))
|
||||
rc = sgsn_acl_add(imsi, g_cfg);
|
||||
else
|
||||
@@ -615,6 +597,7 @@ DEFUN(imsi_acl, cfg_imsi_acl_cmd,
|
||||
|
||||
if (rc < 0) {
|
||||
vty_out(vty, "%% unable to %s ACL%s", op, VTY_NEWLINE);
|
||||
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
@@ -655,6 +638,17 @@ DEFUN(cfg_auth_policy, cfg_auth_policy_cmd,
|
||||
{
|
||||
int val = get_string_value(sgsn_auth_pol_strs, argv[0]);
|
||||
OSMO_ASSERT(val >= SGSN_AUTH_POLICY_OPEN && val <= SGSN_AUTH_POLICY_REMOTE);
|
||||
if (val == SGSN_AUTH_POLICY_REMOTE) {
|
||||
const char *err = "%% auth-policy remote requires";
|
||||
if (!g_cfg->gsup_server_addr.sin_addr.s_addr) {
|
||||
vty_out(vty, "%s 'gsup remote-ip'%s", err, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
if (!g_cfg->gsup_server_port) {
|
||||
vty_out(vty, "%s 'gsup remote-port'%s", err, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
}
|
||||
g_cfg->auth_policy = val;
|
||||
g_cfg->require_authentication = (val == SGSN_AUTH_POLICY_REMOTE);
|
||||
g_cfg->require_update_location = (val == SGSN_AUTH_POLICY_REMOTE);
|
||||
@@ -663,37 +657,40 @@ DEFUN(cfg_auth_policy, cfg_auth_policy_cmd,
|
||||
}
|
||||
|
||||
/* Subscriber */
|
||||
#include <openbsc/gprs_subscriber.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
|
||||
static void subscr_dump_full_vty(struct vty *vty, struct gprs_subscr *gsub, int pending)
|
||||
static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, int pending)
|
||||
{
|
||||
#if 0
|
||||
char expire_time[200];
|
||||
#endif
|
||||
struct gsm_auth_tuple *at;
|
||||
int at_idx;
|
||||
struct sgsn_subscriber_pdp_data *pdp;
|
||||
|
||||
vty_out(vty, " Authorized: %d%s",
|
||||
gsub->authorized, VTY_NEWLINE);
|
||||
vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id,
|
||||
subscr->authorized, VTY_NEWLINE);
|
||||
if (strlen(subscr->name))
|
||||
vty_out(vty, " Name: '%s'%s", subscr->name, VTY_NEWLINE);
|
||||
if (strlen(subscr->extension))
|
||||
vty_out(vty, " Extension: %s%s", subscr->extension,
|
||||
VTY_NEWLINE);
|
||||
vty_out(vty, " LAC: %d/0x%x%s",
|
||||
gsub->lac, gsub->lac, VTY_NEWLINE);
|
||||
vty_out(vty, " IMSI: %s%s", gsub->imsi, VTY_NEWLINE);
|
||||
if (gsub->tmsi != GSM_RESERVED_TMSI)
|
||||
vty_out(vty, " TMSI: %08X%s", gsub->tmsi,
|
||||
subscr->lac, subscr->lac, VTY_NEWLINE);
|
||||
vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE);
|
||||
if (subscr->tmsi != GSM_RESERVED_TMSI)
|
||||
vty_out(vty, " TMSI: %08X%s", subscr->tmsi,
|
||||
VTY_NEWLINE);
|
||||
if (gsub->sgsn_data->msisdn_len > 0)
|
||||
if (subscr->sgsn_data->msisdn_len > 0)
|
||||
vty_out(vty, " MSISDN (BCD): %s%s",
|
||||
osmo_hexdump(gsub->sgsn_data->msisdn,
|
||||
gsub->sgsn_data->msisdn_len),
|
||||
osmo_hexdump(subscr->sgsn_data->msisdn,
|
||||
subscr->sgsn_data->msisdn_len),
|
||||
VTY_NEWLINE);
|
||||
|
||||
if (strlen(gsub->imei) > 0)
|
||||
vty_out(vty, " IMEI: %s%s", gsub->imei, VTY_NEWLINE);
|
||||
if (strlen(subscr->equipment.imei) > 0)
|
||||
vty_out(vty, " IMEI: %s%s", subscr->equipment.imei, VTY_NEWLINE);
|
||||
|
||||
for (at_idx = 0; at_idx < ARRAY_SIZE(gsub->sgsn_data->auth_triplets);
|
||||
for (at_idx = 0; at_idx < ARRAY_SIZE(subscr->sgsn_data->auth_triplets);
|
||||
at_idx++) {
|
||||
at = &gsub->sgsn_data->auth_triplets[at_idx];
|
||||
at = &subscr->sgsn_data->auth_triplets[at_idx];
|
||||
if (at->key_seq == GSM_KEY_SEQ_INVAL)
|
||||
continue;
|
||||
|
||||
@@ -725,38 +722,36 @@ static void subscr_dump_full_vty(struct vty *vty, struct gprs_subscr *gsub, int
|
||||
}
|
||||
}
|
||||
|
||||
llist_for_each_entry(pdp, &gsub->sgsn_data->pdp_list, list) {
|
||||
llist_for_each_entry(pdp, &subscr->sgsn_data->pdp_list, list) {
|
||||
vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s' QoS: %s%s",
|
||||
pdp->context_id, pdp->pdp_type, pdp->apn_str,
|
||||
osmo_hexdump(pdp->qos_subscribed, pdp->qos_subscribed_len),
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* print the expiration time of a subscriber */
|
||||
if (gsub->expire_lu) {
|
||||
if (subscr->expire_lu) {
|
||||
strftime(expire_time, sizeof(expire_time),
|
||||
"%a, %d %b %Y %T %z", localtime(&gsub->expire_lu));
|
||||
"%a, %d %b %Y %T %z", localtime(&subscr->expire_lu));
|
||||
expire_time[sizeof(expire_time) - 1] = '\0';
|
||||
vty_out(vty, " Expiration Time: %s%s", expire_time, VTY_NEWLINE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gsub->flags)
|
||||
if (subscr->flags)
|
||||
vty_out(vty, " Flags: %s%s%s%s%s%s",
|
||||
gsub->flags & GPRS_SUBSCRIBER_FIRST_CONTACT ?
|
||||
subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT ?
|
||||
"FIRST_CONTACT " : "",
|
||||
gsub->flags & GPRS_SUBSCRIBER_CANCELLED ?
|
||||
subscr->flags & GPRS_SUBSCRIBER_CANCELLED ?
|
||||
"CANCELLED " : "",
|
||||
gsub->flags & GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING ?
|
||||
subscr->flags & GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING ?
|
||||
"UPDATE_LOCATION_PENDING " : "",
|
||||
gsub->flags & GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING ?
|
||||
subscr->flags & GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING ?
|
||||
"AUTH_INFO_PENDING " : "",
|
||||
gsub->flags & GPRS_SUBSCRIBER_ENABLE_PURGE ?
|
||||
subscr->flags & GPRS_SUBSCRIBER_ENABLE_PURGE ?
|
||||
"ENABLE_PURGE " : "",
|
||||
VTY_NEWLINE);
|
||||
|
||||
vty_out(vty, " Use count: %u%s", gsub->use_count, VTY_NEWLINE);
|
||||
vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
DEFUN(show_subscr_cache,
|
||||
@@ -765,9 +760,9 @@ DEFUN(show_subscr_cache,
|
||||
SHOW_STR "Show information about subscribers\n"
|
||||
"Display contents of subscriber cache\n")
|
||||
{
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
llist_for_each_entry(subscr, gprs_subscribers, entry) {
|
||||
llist_for_each_entry(subscr, &active_subscribers, entry) {
|
||||
vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
|
||||
subscr_dump_full_vty(vty, subscr, 0);
|
||||
}
|
||||
@@ -799,7 +794,7 @@ DEFUN(update_subscr_insert_auth_triplet, update_subscr_insert_auth_triplet_cmd,
|
||||
const char *kc_str = argv[4];
|
||||
struct gsm_auth_tuple at = {0,};
|
||||
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
subscr = gprs_subscr_get_by_imsi(imsi);
|
||||
if (!subscr) {
|
||||
@@ -830,12 +825,12 @@ DEFUN(update_subscr_insert_auth_triplet, update_subscr_insert_auth_triplet_cmd,
|
||||
subscr->sgsn_data->auth_triplets[cksn] = at;
|
||||
subscr->sgsn_data->auth_triplets_updated = 1;
|
||||
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
||||
failed:
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -849,7 +844,7 @@ DEFUN(update_subscr_cancel, update_subscr_cancel_cmd,
|
||||
const char *imsi = argv[0];
|
||||
const char *cancel_type = argv[1];
|
||||
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
subscr = gprs_subscr_get_by_imsi(imsi);
|
||||
if (!subscr) {
|
||||
@@ -864,7 +859,7 @@ DEFUN(update_subscr_cancel, update_subscr_cancel_cmd,
|
||||
subscr->sgsn_data->error_cause = GMM_CAUSE_IMPL_DETACHED;
|
||||
|
||||
gprs_subscr_cancel(subscr);
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -876,7 +871,7 @@ DEFUN(update_subscr_create, update_subscr_create_cmd,
|
||||
{
|
||||
const char *imsi = argv[0];
|
||||
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
subscr = gprs_subscr_get_by_imsi(imsi);
|
||||
if (subscr) {
|
||||
@@ -887,7 +882,7 @@ DEFUN(update_subscr_create, update_subscr_create_cmd,
|
||||
|
||||
subscr = gprs_subscr_get_or_create(imsi);
|
||||
subscr->keep_in_ram = 1;
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -899,7 +894,7 @@ DEFUN(update_subscr_destroy, update_subscr_destroy_cmd,
|
||||
{
|
||||
const char *imsi = argv[0];
|
||||
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
subscr = gprs_subscr_get_by_imsi(imsi);
|
||||
if (!subscr) {
|
||||
@@ -914,7 +909,7 @@ DEFUN(update_subscr_destroy, update_subscr_destroy_cmd,
|
||||
if (subscr->use_count > 1)
|
||||
vty_out(vty, "%% subscriber is still in use%s",
|
||||
VTY_NEWLINE);
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -939,7 +934,7 @@ DEFUN(update_subscr_update_location_result, update_subscr_update_location_result
|
||||
const char *imsi = argv[0];
|
||||
const char *ret_code_str = argv[1];
|
||||
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
const struct value_string cause_mapping[] = {
|
||||
{ GMM_CAUSE_NET_FAIL, "system-failure" },
|
||||
@@ -968,7 +963,7 @@ DEFUN(update_subscr_update_location_result, update_subscr_update_location_result
|
||||
|
||||
gprs_subscr_update(subscr);
|
||||
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -980,7 +975,7 @@ DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd,
|
||||
{
|
||||
const char *imsi = argv[0];
|
||||
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
subscr = gprs_subscr_get_by_imsi(imsi);
|
||||
if (!subscr) {
|
||||
@@ -991,7 +986,7 @@ DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd,
|
||||
|
||||
gprs_subscr_update_auth_info(subscr);
|
||||
|
||||
gprs_subscr_put(subscr);
|
||||
subscr_put(subscr);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -1229,10 +1224,8 @@ DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int sgsn_vty_init(struct sgsn_config *cfg)
|
||||
int sgsn_vty_init(void)
|
||||
{
|
||||
g_cfg = cfg;
|
||||
|
||||
install_element_ve(&show_sgsn_cmd);
|
||||
//install_element_ve(&show_mmctx_tlli_cmd);
|
||||
install_element_ve(&show_mmctx_imsi_cmd);
|
||||
@@ -1291,19 +1284,14 @@ int sgsn_vty_init(struct sgsn_config *cfg)
|
||||
install_element(SGSN_NODE, &cfg_no_comp_v42bis_cmd);
|
||||
install_element(SGSN_NODE, &cfg_comp_v42bis_cmd);
|
||||
install_element(SGSN_NODE, &cfg_comp_v42bisp_cmd);
|
||||
|
||||
#ifdef BUILD_IU
|
||||
iu_vty_init(SGSN_NODE, &g_cfg->iu.rab_assign_addr_enc);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sgsn_parse_config(const char *config_file)
|
||||
int sgsn_parse_config(const char *config_file, struct sgsn_config *cfg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* make sure sgsn_vty_init() was called before this */
|
||||
OSMO_ASSERT(g_cfg);
|
||||
g_cfg = cfg;
|
||||
|
||||
g_cfg->timers.T3312 = GSM0408_T3312_SECS;
|
||||
g_cfg->timers.T3322 = GSM0408_T3322_SECS;
|
||||
@@ -1324,14 +1312,5 @@ int sgsn_parse_config(const char *config_file)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (g_cfg->auth_policy == SGSN_AUTH_POLICY_REMOTE
|
||||
&& !(g_cfg->gsup_server_addr.sin_addr.s_addr
|
||||
&& g_cfg->gsup_server_port)) {
|
||||
fprintf(stderr, "Configuration error:"
|
||||
" 'auth-policy remote' requires both"
|
||||
" 'gsup remote-ip' and 'gsup remote-port'\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ libbsc_a_SOURCES = \
|
||||
abis_om2000_vty.c \
|
||||
abis_rsl.c \
|
||||
bsc_rll.c \
|
||||
bsc_subscriber.c \
|
||||
paging.c \
|
||||
bts_ericsson_rbs2000.c \
|
||||
bts_ipaccess_nanobts.c \
|
||||
|
||||
@@ -835,13 +835,11 @@ mo2nm_state(struct gsm_bts *bts, const struct abis_om2k_mo *mo)
|
||||
trx = gsm_bts_trx_num(bts, mo->inst);
|
||||
if (!trx)
|
||||
return NULL;
|
||||
/* FIXME */
|
||||
break;
|
||||
case OM2K_MO_CLS_RX:
|
||||
trx = gsm_bts_trx_num(bts, mo->inst);
|
||||
if (!trx)
|
||||
return NULL;
|
||||
/* FIXME */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2157,19 +2155,18 @@ static void om2k_bts_s_wait_cf(struct osmo_fsm_inst *fi, uint32_t event, void *d
|
||||
struct gsm_bts *bts = obfp->bts;
|
||||
|
||||
OSMO_ASSERT(event == OM2K_BTS_EVT_CF_DONE);
|
||||
/* TF can take a long time to initialize, wait for 10min */
|
||||
osmo_fsm_inst_state_chg(fi, OM2K_BTS_S_WAIT_TF, 600, 0);
|
||||
om2k_mo_fsm_start(fi, OM2K_BTS_EVT_TF_DONE, bts->c0,
|
||||
&bts->rbs2000.tf.om2k_mo);
|
||||
osmo_fsm_inst_state_chg(fi, OM2K_BTS_S_WAIT_IS,
|
||||
BTS_FSM_TIMEOUT, 0);
|
||||
om2k_mo_fsm_start(fi, OM2K_BTS_EVT_IS_DONE, bts->c0,
|
||||
&bts->rbs2000.is.om2k_mo);
|
||||
}
|
||||
|
||||
static void om2k_bts_s_wait_tf(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
static void om2k_bts_s_wait_is(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
struct om2k_bts_fsm_priv *obfp = fi->priv;
|
||||
struct gsm_bts *bts = obfp->bts;
|
||||
|
||||
OSMO_ASSERT(event == OM2K_BTS_EVT_TF_DONE);
|
||||
|
||||
OSMO_ASSERT(event == OM2K_BTS_EVT_IS_DONE);
|
||||
osmo_fsm_inst_state_chg(fi, OM2K_BTS_S_WAIT_CON,
|
||||
BTS_FSM_TIMEOUT, 0);
|
||||
om2k_mo_fsm_start(fi, OM2K_BTS_EVT_CON_DONE, bts->c0,
|
||||
@@ -2182,19 +2179,18 @@ static void om2k_bts_s_wait_con(struct osmo_fsm_inst *fi, uint32_t event, void *
|
||||
struct gsm_bts *bts = obfp->bts;
|
||||
|
||||
OSMO_ASSERT(event == OM2K_BTS_EVT_CON_DONE);
|
||||
|
||||
osmo_fsm_inst_state_chg(fi, OM2K_BTS_S_WAIT_IS,
|
||||
BTS_FSM_TIMEOUT, 0);
|
||||
om2k_mo_fsm_start(fi, OM2K_BTS_EVT_IS_DONE, bts->c0,
|
||||
&bts->rbs2000.is.om2k_mo);
|
||||
/* TF can take a long time to initialize, wait for 10min */
|
||||
osmo_fsm_inst_state_chg(fi, OM2K_BTS_S_WAIT_TF, 600, 0);
|
||||
om2k_mo_fsm_start(fi, OM2K_BTS_EVT_TF_DONE, bts->c0,
|
||||
&bts->rbs2000.tf.om2k_mo);
|
||||
}
|
||||
|
||||
static void om2k_bts_s_wait_is(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
static void om2k_bts_s_wait_tf(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
struct om2k_bts_fsm_priv *obfp = fi->priv;
|
||||
struct gsm_bts_trx *trx;
|
||||
|
||||
OSMO_ASSERT(event == OM2K_BTS_EVT_IS_DONE);
|
||||
OSMO_ASSERT(event == OM2K_BTS_EVT_TF_DONE);
|
||||
|
||||
osmo_fsm_inst_state_chg(fi, OM2K_BTS_S_WAIT_TRX,
|
||||
BTS_FSM_TIMEOUT, 0);
|
||||
@@ -2233,31 +2229,31 @@ static const struct osmo_fsm_state om2k_bts_states[] = {
|
||||
[OM2K_BTS_S_WAIT_CF] = {
|
||||
.in_event_mask = S(OM2K_BTS_EVT_CF_DONE),
|
||||
.out_state_mask = S(OM2K_BTS_S_ERROR) |
|
||||
S(OM2K_BTS_S_WAIT_TF),
|
||||
S(OM2K_BTS_S_WAIT_IS),
|
||||
.name = "WAIT-CF",
|
||||
.action = om2k_bts_s_wait_cf,
|
||||
},
|
||||
[OM2K_BTS_S_WAIT_TF] = {
|
||||
.in_event_mask = S(OM2K_BTS_EVT_TF_DONE),
|
||||
.out_state_mask = S(OM2K_BTS_S_ERROR) |
|
||||
S(OM2K_BTS_S_WAIT_CON),
|
||||
.name = "WAIT-TF",
|
||||
.action = om2k_bts_s_wait_tf,
|
||||
},
|
||||
[OM2K_BTS_S_WAIT_CON] = {
|
||||
.in_event_mask = S(OM2K_BTS_EVT_CON_DONE),
|
||||
.out_state_mask = S(OM2K_BTS_S_ERROR) |
|
||||
S(OM2K_BTS_S_WAIT_IS),
|
||||
.name = "WAIT-CON",
|
||||
.action = om2k_bts_s_wait_con,
|
||||
},
|
||||
[OM2K_BTS_S_WAIT_IS] = {
|
||||
.in_event_mask = S(OM2K_BTS_EVT_IS_DONE),
|
||||
.out_state_mask = S(OM2K_BTS_S_ERROR) |
|
||||
S(OM2K_BTS_S_WAIT_TRX),
|
||||
S(OM2K_BTS_S_WAIT_CON),
|
||||
.name = "WAIT-IS",
|
||||
.action = om2k_bts_s_wait_is,
|
||||
},
|
||||
[OM2K_BTS_S_WAIT_CON] = {
|
||||
.in_event_mask = S(OM2K_BTS_EVT_CON_DONE),
|
||||
.out_state_mask = S(OM2K_BTS_S_ERROR) |
|
||||
S(OM2K_BTS_S_WAIT_TF),
|
||||
.name = "WAIT-CON",
|
||||
.action = om2k_bts_s_wait_con,
|
||||
},
|
||||
[OM2K_BTS_S_WAIT_TF] = {
|
||||
.in_event_mask = S(OM2K_BTS_EVT_TF_DONE),
|
||||
.out_state_mask = S(OM2K_BTS_S_ERROR) |
|
||||
S(OM2K_BTS_S_WAIT_TRX),
|
||||
.name = "WAIT-TF",
|
||||
.action = om2k_bts_s_wait_tf,
|
||||
},
|
||||
[OM2K_BTS_S_WAIT_TRX] = {
|
||||
.in_event_mask = S(OM2K_BTS_EVT_TRX_DONE),
|
||||
.out_state_mask = S(OM2K_BTS_S_ERROR) |
|
||||
|
||||
@@ -158,8 +158,9 @@ static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
|
||||
LOGP(DRSL, LOGL_ERROR, "%s %smismatching chan_nr=0x%02x\n",
|
||||
gsm_ts_and_pchan_name(lchan->ts), log_name, chan_nr);
|
||||
|
||||
log_set_context(BSC_CTX_LCHAN, lchan);
|
||||
if (lchan->conn)
|
||||
log_set_context(LOG_CTX_VLR_SUBSCR, lchan->conn->vsub);
|
||||
log_set_context(BSC_CTX_SUBSCR, lchan->conn->subscr);
|
||||
|
||||
return lchan;
|
||||
}
|
||||
@@ -180,12 +181,13 @@ static struct msgb *rsl_msgb_alloc(void)
|
||||
"RSL");
|
||||
}
|
||||
|
||||
#define MACBLOCK_SIZE 23
|
||||
static void pad_macblock(uint8_t *out, const uint8_t *in, int len)
|
||||
{
|
||||
memcpy(out, in, len);
|
||||
|
||||
if (len < GSM_MACBLOCK_LEN)
|
||||
memset(out+len, 0x2b, GSM_MACBLOCK_LEN - len);
|
||||
if (len < MACBLOCK_SIZE)
|
||||
memset(out+len, 0x2b, MACBLOCK_SIZE-len);
|
||||
}
|
||||
|
||||
/* Chapter 9.3.7: Encryption Information */
|
||||
@@ -1040,7 +1042,7 @@ int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
|
||||
{
|
||||
struct msgb *msg = rsl_msgb_alloc();
|
||||
struct abis_rsl_dchan_hdr *dh;
|
||||
uint8_t buf[GSM_MACBLOCK_LEN];
|
||||
uint8_t buf[MACBLOCK_SIZE];
|
||||
|
||||
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
|
||||
init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
|
||||
@@ -1053,8 +1055,7 @@ int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
|
||||
default:
|
||||
/* If phase 2, construct a FULL_IMM_ASS_INFO */
|
||||
pad_macblock(buf, val, len);
|
||||
msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, GSM_MACBLOCK_LEN,
|
||||
buf);
|
||||
msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, MACBLOCK_SIZE, buf);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1332,10 +1333,10 @@ static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
|
||||
static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
|
||||
{
|
||||
int i;
|
||||
const char *name = "";
|
||||
char *name = "";
|
||||
|
||||
if (lchan && lchan->conn)
|
||||
name = bsc_subscr_name(lchan->conn->bsub);
|
||||
name = subscr_name(lchan->conn->subscr);
|
||||
|
||||
DEBUGP(DMEAS, "[%s] MEASUREMENT RESULT NR=%d ", name, mr->nr);
|
||||
|
||||
@@ -1373,19 +1374,6 @@ static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
|
||||
}
|
||||
}
|
||||
|
||||
static struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan)
|
||||
{
|
||||
struct gsm_meas_rep *meas_rep;
|
||||
|
||||
meas_rep = &lchan->meas_rep[lchan->meas_rep_idx];
|
||||
memset(meas_rep, 0, sizeof(*meas_rep));
|
||||
meas_rep->lchan = lchan;
|
||||
lchan->meas_rep_idx = (lchan->meas_rep_idx + 1)
|
||||
% ARRAY_SIZE(lchan->meas_rep);
|
||||
|
||||
return meas_rep;
|
||||
}
|
||||
|
||||
static int rsl_rx_meas_res(struct msgb *msg)
|
||||
{
|
||||
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
|
||||
@@ -1671,9 +1659,7 @@ static int abis_rsl_rx_trx(struct msgb *msg)
|
||||
static void t3101_expired(void *data)
|
||||
{
|
||||
struct gsm_lchan *lchan = data;
|
||||
LOGP(DRSL, LOGL_NOTICE,
|
||||
"%s T3101 expired: no response to IMMEDIATE ASSIGN\n",
|
||||
gsm_lchan_name(lchan));
|
||||
|
||||
rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE);
|
||||
}
|
||||
|
||||
@@ -1681,9 +1667,7 @@ static void t3101_expired(void *data)
|
||||
static void t3111_expired(void *data)
|
||||
{
|
||||
struct gsm_lchan *lchan = data;
|
||||
LOGP(DRSL, LOGL_NOTICE,
|
||||
"%s T3111 expired: releasing RF Channel\n",
|
||||
gsm_lchan_name(lchan));
|
||||
|
||||
rsl_rf_chan_release(lchan, 0, SACCH_NONE);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
#include <openbsc/trau_mux.h>
|
||||
#include <openbsc/vlr.h>
|
||||
|
||||
#include <osmocom/gsm/protocol/gsm_08_08.h>
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
@@ -252,7 +251,6 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lcha
|
||||
conn->network = net;
|
||||
conn->lchan = lchan;
|
||||
conn->bts = lchan->ts->trx->bts;
|
||||
conn->via_ran = RAN_GERAN_A;
|
||||
lchan->conn = conn;
|
||||
llist_add_tail(&conn->entry, &net->subscr_conns);
|
||||
return conn;
|
||||
@@ -263,14 +261,13 @@ void bsc_subscr_con_free(struct gsm_subscriber_connection *conn)
|
||||
if (!conn)
|
||||
return;
|
||||
|
||||
if (conn->network->bsc_api->conn_cleanup)
|
||||
conn->network->bsc_api->conn_cleanup(conn);
|
||||
|
||||
if (conn->vsub) {
|
||||
LOGP(DNM, LOGL_ERROR, "conn->vsub should have been cleared.\n");
|
||||
conn->vsub = NULL;
|
||||
if (conn->subscr) {
|
||||
subscr_put(conn->subscr);
|
||||
conn->subscr = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (conn->ho_lchan) {
|
||||
LOGP(DNM, LOGL_ERROR, "The ho_lchan should have been cleared.\n");
|
||||
conn->ho_lchan->conn = NULL;
|
||||
@@ -400,8 +397,7 @@ int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, in
|
||||
handle_mr_config(conn, conn->lchan, full_rate);
|
||||
|
||||
LOGP(DMSC, LOGL_NOTICE,
|
||||
"Sending %s ChanModify for speech: %s on channel %s\n",
|
||||
gsm_lchan_name(conn->lchan),
|
||||
"Sending ChanModify for speech: %s on channel %s\n",
|
||||
get_value_string(gsm48_chan_mode_names, chan_mode),
|
||||
get_value_string(gsm_chan_t_names, conn->lchan->type));
|
||||
gsm48_lchan_modify(conn->lchan, chan_mode);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <openbsc/osmo_bsc_rf.h>
|
||||
#include <openbsc/bsc_msc_data.h>
|
||||
#include <openbsc/osmo_msc_data.h>
|
||||
|
||||
#define CTRL_CMD_VTY_STRING(cmdname, cmdstr, dtype, element) \
|
||||
CTRL_HELPER_GET_STRING(cmdname, dtype, element) \
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <osmocom/gsm/sysinfo.h>
|
||||
#include <openbsc/e1_config.h>
|
||||
#include <openbsc/common_bsc.h>
|
||||
#include <openbsc/osmo_msc.h>
|
||||
|
||||
/* global pointer to the gsm network data structure */
|
||||
extern struct gsm_network *bsc_gsmnet;
|
||||
@@ -436,9 +435,6 @@ static int bootstrap_bts(struct gsm_bts *bts)
|
||||
for (n=0, i=0; i<8; i++)
|
||||
n += bts->c0->ts[i].pchan == GSM_PCHAN_CCCH ? 1 : 0;
|
||||
|
||||
/* Indicate R99 MSC in SI3 */
|
||||
bts->si_common.chan_desc.mscr = 1;
|
||||
|
||||
switch (n) {
|
||||
case 0:
|
||||
bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/bsc_msc_data.h>
|
||||
#include <openbsc/osmo_msc_data.h>
|
||||
#include <openbsc/ipaccess.h>
|
||||
|
||||
#include <osmocom/core/talloc.h>
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
/* GSM subscriber details for use in BSC land */
|
||||
|
||||
/*
|
||||
* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
*
|
||||
* Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
|
||||
*
|
||||
* 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 <talloc.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
#include <openbsc/bsc_subscriber.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
static struct bsc_subscr *bsc_subscr_alloc(struct llist_head *list)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
|
||||
bsub = talloc_zero(list, struct bsc_subscr);
|
||||
if (!bsub)
|
||||
return NULL;
|
||||
|
||||
llist_add_tail(&bsub->entry, list);
|
||||
bsub->use_count = 1;
|
||||
|
||||
return bsub;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
|
||||
const char *imsi)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
|
||||
if (!imsi || !*imsi)
|
||||
return NULL;
|
||||
|
||||
llist_for_each_entry(bsub, list, entry) {
|
||||
if (!strcmp(bsub->imsi, imsi))
|
||||
return bsc_subscr_get(bsub);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_by_tmsi(struct llist_head *list,
|
||||
uint32_t tmsi)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
|
||||
if (tmsi == GSM_RESERVED_TMSI)
|
||||
return NULL;
|
||||
|
||||
llist_for_each_entry(bsub, list, entry) {
|
||||
if (bsub->tmsi == tmsi)
|
||||
return bsc_subscr_get(bsub);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void bsc_subscr_set_imsi(struct bsc_subscr *bsub, const char *imsi)
|
||||
{
|
||||
if (!bsub)
|
||||
return;
|
||||
strncpy(bsub->imsi, imsi, sizeof(bsub->imsi));
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list,
|
||||
const char *imsi)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
bsub = bsc_subscr_find_by_imsi(list, imsi);
|
||||
if (bsub)
|
||||
return bsub;
|
||||
bsub = bsc_subscr_alloc(list);
|
||||
bsc_subscr_set_imsi(bsub, imsi);
|
||||
return bsub;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct llist_head *list,
|
||||
uint32_t tmsi)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
bsub = bsc_subscr_find_by_tmsi(list, tmsi);
|
||||
if (bsub)
|
||||
return bsub;
|
||||
bsub = bsc_subscr_alloc(list);
|
||||
bsub->tmsi = tmsi;
|
||||
return bsub;
|
||||
}
|
||||
|
||||
const char *bsc_subscr_name(struct bsc_subscr *bsub)
|
||||
{
|
||||
static char buf[32];
|
||||
if (!bsub)
|
||||
return "unknown";
|
||||
if (bsub->imsi[0])
|
||||
snprintf(buf, sizeof(buf), "IMSI:%s", bsub->imsi);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "TMSI:0x%08x", bsub->tmsi);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void bsc_subscr_free(struct bsc_subscr *bsub)
|
||||
{
|
||||
llist_del(&bsub->entry);
|
||||
talloc_free(bsub);
|
||||
}
|
||||
|
||||
struct bsc_subscr *_bsc_subscr_get(struct bsc_subscr *bsub,
|
||||
const char *file, int line)
|
||||
{
|
||||
OSMO_ASSERT(bsub->use_count < INT_MAX);
|
||||
bsub->use_count++;
|
||||
LOGPSRC(DREF, LOGL_DEBUG, file, line,
|
||||
"BSC subscr %s usage increases to: %d\n",
|
||||
bsc_subscr_name(bsub), bsub->use_count);
|
||||
return bsub;
|
||||
}
|
||||
|
||||
struct bsc_subscr *_bsc_subscr_put(struct bsc_subscr *bsub,
|
||||
const char *file, int line)
|
||||
{
|
||||
bsub->use_count--;
|
||||
LOGPSRC(DREF, bsub->use_count >= 0? LOGL_DEBUG : LOGL_ERROR,
|
||||
file, line,
|
||||
"BSC subscr %s usage decreases to: %d\n",
|
||||
bsc_subscr_name(bsub), bsub->use_count);
|
||||
if (bsub->use_count <= 0)
|
||||
bsc_subscr_free(bsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void log_set_filter_bsc_subscr(struct log_target *target,
|
||||
struct bsc_subscr *bsc_subscr)
|
||||
{
|
||||
struct bsc_subscr **fsub = (void*)&target->filter_data[LOG_FLT_BSC_SUBSCR];
|
||||
|
||||
/* free the old data */
|
||||
if (*fsub) {
|
||||
bsc_subscr_put(*fsub);
|
||||
*fsub = NULL;
|
||||
}
|
||||
|
||||
if (bsc_subscr) {
|
||||
target->filter_map |= (1 << LOG_FLT_BSC_SUBSCR);
|
||||
*fsub = bsc_subscr_get(bsc_subscr);
|
||||
} else
|
||||
target->filter_map &= ~(1 << LOG_FLT_BSC_SUBSCR);
|
||||
}
|
||||
@@ -51,10 +51,10 @@
|
||||
#include <openbsc/paging.h>
|
||||
#include <openbsc/ipaccess.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/bsc_msc_data.h>
|
||||
#include <openbsc/osmo_msc_data.h>
|
||||
#include <openbsc/osmo_bsc_rf.h>
|
||||
|
||||
#include <openbsc/common_cs.h>
|
||||
#include <openbsc/vlr.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
@@ -541,7 +541,6 @@ static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts,
|
||||
static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
|
||||
{
|
||||
int i;
|
||||
uint8_t tmp;
|
||||
|
||||
vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
|
||||
vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
|
||||
@@ -591,6 +590,13 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
|
||||
(sp->penalty_time*20)+20, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
/* Is periodic LU enabled or disabled? */
|
||||
if (bts->si_common.chan_desc.t3212 == 0)
|
||||
vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
|
||||
else
|
||||
vty_out(vty, " periodic location update %u%s",
|
||||
bts->si_common.chan_desc.t3212 * 6, VTY_NEWLINE);
|
||||
|
||||
vty_out(vty, " radio-link-timeout %d%s",
|
||||
get_radio_link_timeout(&bts->si_common.cell_options),
|
||||
VTY_NEWLINE);
|
||||
@@ -688,23 +694,15 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_EARFCN_LIST; i++) {
|
||||
struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
|
||||
if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
|
||||
vty_out(vty, " si2quater neighbor-list add earfcn %u "
|
||||
"thresh-hi %u", e->arfcn[i], e->thresh_hi);
|
||||
|
||||
vty_out(vty, " thresh-lo %u",
|
||||
e->thresh_lo_valid ? e->thresh_lo : 32);
|
||||
|
||||
vty_out(vty, " prio %u",
|
||||
e->prio_valid ? e->prio : 8);
|
||||
|
||||
vty_out(vty, " qrxlv %u",
|
||||
e->qrxlm_valid ? e->qrxlm : 32);
|
||||
|
||||
tmp = e->meas_bw[i];
|
||||
vty_out(vty, " meas %u",
|
||||
(tmp != OSMO_EARFCN_MEAS_INVALID) ? tmp : 8);
|
||||
if (bts->si_common.si2quater_neigh_list.arfcn[i] !=
|
||||
OSMO_EARFCN_INVALID) {
|
||||
vty_out(vty, " si2quater neighbor-list add earfcn %u threshold %u",
|
||||
bts->si_common.si2quater_neigh_list.arfcn[i],
|
||||
bts->si_common.si2quater_neigh_list.thresh_hi);
|
||||
if (bts->si_common.si2quater_neigh_list.meas_bw[i] !=
|
||||
OSMO_EARFCN_MEAS_INVALID)
|
||||
vty_out(vty, " %u",
|
||||
bts->si_common.si2quater_neigh_list.meas_bw[i]);
|
||||
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
@@ -784,9 +782,6 @@ static int config_write_net(struct vty *vty)
|
||||
vty_out(vty, " location updating reject cause %u%s",
|
||||
gsmnet->reject_cause, VTY_NEWLINE);
|
||||
vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
|
||||
vty_out(vty, " authentication %s%s",
|
||||
gsmnet->authentication_required ? "required" : "optional",
|
||||
VTY_NEWLINE);
|
||||
vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
|
||||
vty_out(vty, " paging any use tch %d%s", gsmnet->pag_any_tch, VTY_NEWLINE);
|
||||
vty_out(vty, " rrlp mode %s%s", rrlp_mode_name(gsmnet->rrlp.mode),
|
||||
@@ -817,11 +812,8 @@ static int config_write_net(struct vty *vty)
|
||||
vty_out(vty, " timer t3119 %u%s", gsmnet->T3119, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3122 %u%s", gsmnet->T3122, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3141 %u%s", gsmnet->T3141, VTY_NEWLINE);
|
||||
/*
|
||||
TODO: add in libvlr?
|
||||
vty_out(vty, " subscriber-keep-in-ram %d%s",
|
||||
gsmnet->subscr_group->keep_subscr, VTY_NEWLINE);
|
||||
*/
|
||||
if (gsmnet->tz.override != 0) {
|
||||
if (gsmnet->tz.dst)
|
||||
vty_out(vty, " timezone %d %d %d%s",
|
||||
@@ -831,11 +823,6 @@ static int config_write_net(struct vty *vty)
|
||||
vty_out(vty, " timezone %d %d%s",
|
||||
gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
|
||||
}
|
||||
if (gsmnet->t3212 == 0)
|
||||
vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
|
||||
else
|
||||
vty_out(vty, " periodic location update %u%s",
|
||||
gsmnet->t3212 * 6, VTY_NEWLINE);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -1010,34 +997,21 @@ DEFUN(show_ts,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void subscr_dump_vty(struct vty *vty, struct vlr_subscr *vsub)
|
||||
static void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr)
|
||||
{
|
||||
OSMO_ASSERT(vsub);
|
||||
if (strlen(vsub->name))
|
||||
vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
|
||||
if (strlen(vsub->msisdn))
|
||||
vty_out(vty, " Extension: %s%s", vsub->msisdn,
|
||||
vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id,
|
||||
subscr->authorized, VTY_NEWLINE);
|
||||
if (strlen(subscr->name))
|
||||
vty_out(vty, " Name: '%s'%s", subscr->name, VTY_NEWLINE);
|
||||
if (strlen(subscr->extension))
|
||||
vty_out(vty, " Extension: %s%s", subscr->extension,
|
||||
VTY_NEWLINE);
|
||||
if (strlen(vsub->imsi))
|
||||
vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
|
||||
if (vsub->tmsi != GSM_RESERVED_TMSI)
|
||||
vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
|
||||
VTY_NEWLINE);
|
||||
if (vsub->tmsi_new != GSM_RESERVED_TMSI)
|
||||
vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
|
||||
vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE);
|
||||
if (subscr->tmsi != GSM_RESERVED_TMSI)
|
||||
vty_out(vty, " TMSI: %08X%s", subscr->tmsi,
|
||||
VTY_NEWLINE);
|
||||
|
||||
vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
|
||||
{
|
||||
if (strlen(bsub->imsi))
|
||||
vty_out(vty, " IMSI: %s%s", bsub->imsi, VTY_NEWLINE);
|
||||
if (bsub->tmsi != GSM_RESERVED_TMSI)
|
||||
vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
|
||||
VTY_NEWLINE);
|
||||
vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
|
||||
vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
static void meas_rep_dump_uni_vty(struct vty *vty,
|
||||
@@ -1156,9 +1130,9 @@ static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
|
||||
vty_out(vty, " Channel Mode / Codec: %s%s",
|
||||
get_value_string(gsm48_cmode_names, lchan->tch_mode),
|
||||
VTY_NEWLINE);
|
||||
if (lchan->conn && lchan->conn->vsub) {
|
||||
if (lchan->conn && lchan->conn->subscr) {
|
||||
vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
|
||||
subscr_dump_vty(vty, lchan->conn->vsub);
|
||||
subscr_dump_vty(vty, lchan->conn->subscr);
|
||||
} else
|
||||
vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
|
||||
if (is_ipaccess_bts(lchan->ts->trx->bts)) {
|
||||
@@ -1335,7 +1309,7 @@ DEFUN(show_lchan_summary,
|
||||
static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
|
||||
{
|
||||
vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
|
||||
bsc_subscr_dump_vty(vty, pag->bsub);
|
||||
subscr_dump_vty(vty, pag->subscr);
|
||||
}
|
||||
|
||||
static void bts_paging_dump_vty(struct vty *vty, struct gsm_bts *bts)
|
||||
@@ -2141,9 +2115,17 @@ DEFUN(cfg_bts_ms_max_power, cfg_bts_ms_max_power_cmd,
|
||||
"Maximum transmit power of the MS in dBm")
|
||||
{
|
||||
struct gsm_bts *bts = vty->index;
|
||||
int rc;
|
||||
|
||||
bts->ms_max_power = atoi(argv[0]);
|
||||
|
||||
/* Apply setting to the BTS */
|
||||
rc = gsm_bts_set_system_infos(bts);
|
||||
if (rc != 0) {
|
||||
vty_out(vty, "%% Failed updating SYSTEM INFORMATION for the BTS%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -2262,6 +2244,34 @@ DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_bts_per_loc_upd, cfg_bts_per_loc_upd_cmd,
|
||||
"periodic location update <6-1530>",
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval in Minutes\n")
|
||||
{
|
||||
struct gsm_bts *bts = vty->index;
|
||||
|
||||
bts->si_common.chan_desc.t3212 = atoi(argv[0]) / 6;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_bts_no_per_loc_upd, cfg_bts_no_per_loc_upd_cmd,
|
||||
"no periodic location update",
|
||||
NO_STR
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval\n")
|
||||
{
|
||||
struct gsm_bts *bts = vty->index;
|
||||
|
||||
bts->si_common.chan_desc.t3212 = 0;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd,
|
||||
"radio-link-timeout <4-64>",
|
||||
"Radio link timeout criterion (BTS side)\n"
|
||||
@@ -2744,73 +2754,42 @@ DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DEFUN(cfg_bts_si2quater_neigh_add, cfg_bts_si2quater_neigh_add_cmd,
|
||||
"si2quater neighbor-list add earfcn <0-65535> thresh-hi <0-31> "
|
||||
"thresh-lo <0-32> prio <0-8> qrxlv <0-32> meas <0-8>",
|
||||
"SI2quater Neighbor List\n" "SI2quater Neighbor List\n"
|
||||
"Add to manual SI2quater neighbor list\n"
|
||||
"EARFCN of neighbor\n" "EARFCN of neighbor\n"
|
||||
"threshold high bits\n" "threshold high bits\n"
|
||||
"threshold low bits\n" "threshold low bits (32 means NA)\n"
|
||||
"priority\n" "priority (8 means NA)\n"
|
||||
"QRXLEVMIN\n" "QRXLEVMIN (32 means NA)\n"
|
||||
"measurement bandwidth\n" "measurement bandwidth (8 means NA)\n")
|
||||
"si2quater neighbor-list add earfcn <0-65535> threshold <0-31> "
|
||||
"[<0-7>]", "SI2quater Neighbor List\n"
|
||||
"SI2quater Neighbor List\n" "Add to manual SI2quater neighbor list\n"
|
||||
"EARFCN of neighbor\n" "EARFCN of neighbor\n" "threshold high bits\n"
|
||||
"threshold high bits\n" "measurement bandwidth\n")
|
||||
{
|
||||
struct gsm_bts *bts = vty->index;
|
||||
struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
|
||||
uint16_t arfcn = atoi(argv[0]);
|
||||
uint8_t thresh_hi = atoi(argv[1]), thresh_lo = atoi(argv[2]),
|
||||
prio = atoi(argv[3]), qrx = atoi(argv[4]), meas = atoi(argv[5]);
|
||||
int r = osmo_earfcn_add(e, arfcn,
|
||||
(meas < 8) ? meas : OSMO_EARFCN_MEAS_INVALID);
|
||||
uint8_t meas = OSMO_EARFCN_MEAS_INVALID, thresh = atoi(argv[1]);
|
||||
int r;
|
||||
|
||||
if (3 == argc)
|
||||
meas = atoi(argv[2]);
|
||||
|
||||
r = osmo_earfcn_add(e, arfcn, meas);
|
||||
|
||||
if (r < 0) {
|
||||
vty_out(vty, "Unable to add ARFCN %u: %s%s", arfcn, strerror(-r),
|
||||
vty_out(vty, "Unable to add arfcn %u: %s%s", arfcn, strerror(-r),
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (e->thresh_hi && thresh_hi != e->thresh_hi)
|
||||
vty_out(vty, "Warning: multiple threshold-high are not "
|
||||
"supported, overriding previous threshold %u%s",
|
||||
e->thresh_hi, VTY_NEWLINE);
|
||||
|
||||
e->thresh_hi = thresh_hi;
|
||||
|
||||
if (thresh_lo != 32) {
|
||||
if (e->thresh_lo_valid && e->thresh_lo != thresh_lo)
|
||||
vty_out(vty, "Warning: multiple threshold-low are not "
|
||||
if (si2q_size_check(bts)) {
|
||||
if (e->thresh_hi && thresh != e->thresh_hi)
|
||||
vty_out(vty, "Warning: multiple thresholds are not "
|
||||
"supported, overriding previous threshold %u%s",
|
||||
e->thresh_lo, VTY_NEWLINE);
|
||||
e->thresh_lo = thresh_lo;
|
||||
e->thresh_lo_valid = true;
|
||||
}
|
||||
e->thresh_hi, VTY_NEWLINE);
|
||||
|
||||
if (qrx != 32) {
|
||||
if (e->qrxlm_valid && e->qrxlm != qrx)
|
||||
vty_out(vty, "Warning: multiple QRXLEVMIN are not "
|
||||
"supported, overriding previous value %u%s",
|
||||
e->qrxlm, VTY_NEWLINE);
|
||||
e->qrxlm = qrx;
|
||||
e->qrxlm_valid = true;
|
||||
}
|
||||
|
||||
if (prio != 8) {
|
||||
if (e->prio_valid && e->prio != prio)
|
||||
vty_out(vty, "Warning: multiple priorities are not "
|
||||
"supported, overriding previous value %u%s",
|
||||
e->prio, VTY_NEWLINE);
|
||||
e->prio = prio;
|
||||
e->prio_valid = true;
|
||||
}
|
||||
|
||||
if (si2q_size_check(bts))
|
||||
e->thresh_hi = thresh;
|
||||
return CMD_SUCCESS;
|
||||
|
||||
vty_out(vty, "Warning: not enough space in SI2quater for a given EARFCN "
|
||||
"%u%s", arfcn, VTY_NEWLINE);
|
||||
}
|
||||
vty_out(vty, "Warning: not enough space in si2quater for a given arfcn%s"
|
||||
, VTY_NEWLINE);
|
||||
osmo_earfcn_del(e, arfcn);
|
||||
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
@@ -3412,27 +3391,42 @@ DEFUN(cfg_trx_max_power_red,
|
||||
"Reduction of maximum BS RF Power (relative to nominal power)\n"
|
||||
"Reduction of maximum BS RF Power in dB\n")
|
||||
{
|
||||
int ret = CMD_SUCCESS;
|
||||
int maxpwr_r = atoi(argv[0]);
|
||||
struct gsm_bts_trx *trx = vty->index;
|
||||
/* FIXME: check if our BTS type supports more than 24 */
|
||||
int upper_limit = 24; /* default 12.21 max power red. */
|
||||
|
||||
/* FIXME: check if our BTS type supports more than 12 */
|
||||
if (maxpwr_r < 0 || maxpwr_r > upper_limit) {
|
||||
vty_out(vty, "%% Power %d dB is not in the valid range%s",
|
||||
if (maxpwr_r < 0) {
|
||||
vty_out(vty, "%% Power %d dB can not be negative%s",
|
||||
maxpwr_r, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
if (maxpwr_r > upper_limit) {
|
||||
vty_out(vty, "%% Power %d dB is more than %d dB maximum power reduction"
|
||||
" defined by GSM 12.21. BTS may not support it.%s",
|
||||
maxpwr_r, upper_limit, VTY_NEWLINE);
|
||||
ret = CMD_WARNING;
|
||||
}
|
||||
if (maxpwr_r & 1) {
|
||||
vty_out(vty, "%% Power %d dB is not an even value%s",
|
||||
maxpwr_r = (maxpwr_r/2)*2;
|
||||
vty_out(vty, "%% Power is not an even value, rounding it to %d dB%s",
|
||||
maxpwr_r, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
ret = CMD_WARNING;
|
||||
}
|
||||
|
||||
trx->max_power_red = maxpwr_r;
|
||||
/* Update the value if it's changed */
|
||||
if (trx->max_power_red != maxpwr_r) {
|
||||
trx->max_power_red = maxpwr_r;
|
||||
vty_out(vty, "%% Updating max_pwr_red to %d dB for %s%s",
|
||||
trx->max_power_red, gsm_trx_name(trx), VTY_NEWLINE);
|
||||
abis_nm_update_max_power_red(trx);
|
||||
} else {
|
||||
vty_out(vty, "%% max_pwr_red is not changed for %s%s",
|
||||
gsm_trx_name(trx), VTY_NEWLINE);
|
||||
}
|
||||
|
||||
/* FIXME: make sure we update this using OML */
|
||||
|
||||
return CMD_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFUN(cfg_trx_rsl_e1,
|
||||
@@ -3880,7 +3874,7 @@ DEFUN(pdch_act, pdch_act_cmd,
|
||||
|
||||
extern int bsc_vty_init_extra(void);
|
||||
|
||||
int bsc_vty_init(struct gsm_network *network)
|
||||
int bsc_vty_init(const struct log_info *cat, struct gsm_network *network)
|
||||
{
|
||||
cfg_ts_pchan_cmd.string =
|
||||
vty_cmd_string_from_valstr(tall_bsc_ctx,
|
||||
@@ -3916,7 +3910,8 @@ int bsc_vty_init(struct gsm_network *network)
|
||||
install_element_ve(&show_paging_cmd);
|
||||
install_element_ve(&show_paging_group_cmd);
|
||||
|
||||
logging_vty_add_cmds(NULL);
|
||||
logging_vty_add_cmds(cat);
|
||||
osmo_stats_vty_add_cmds();
|
||||
|
||||
install_element(GSMNET_NODE, &cfg_net_neci_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_handover_cmd);
|
||||
@@ -3976,6 +3971,8 @@ int bsc_vty_init(struct gsm_network *network)
|
||||
install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_no_per_loc_upd_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
|
||||
|
||||
@@ -141,15 +141,13 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
|
||||
case S_L_INP_LINE_INIT:
|
||||
case S_L_INP_LINE_NOALARM:
|
||||
if (strcasecmp(isd->line->driver->name, "DAHDI")
|
||||
&& strcasecmp(isd->line->driver->name, "MISDN_LAPD")
|
||||
&& strcasecmp(isd->line->driver->name, "UNIXSOCKET"))
|
||||
&& strcasecmp(isd->line->driver->name, "MISDN_LAPD"))
|
||||
break;
|
||||
start_sabm_in_line(isd->line, 1);
|
||||
break;
|
||||
case S_L_INP_LINE_ALARM:
|
||||
if (strcasecmp(isd->line->driver->name, "DAHDI")
|
||||
&& strcasecmp(isd->line->driver->name, "MISDN_LAPD")
|
||||
&& strcasecmp(isd->line->driver->name, "UNIXSOCKET"))
|
||||
&& strcasecmp(isd->line->driver->name, "MISDN_LAPD"))
|
||||
break;
|
||||
start_sabm_in_line(isd->line, 0);
|
||||
break;
|
||||
|
||||
@@ -134,6 +134,7 @@ static int bts_isdn_sign_link(struct msgb *msg)
|
||||
struct e1inp_sign_link *link = msg->dst;
|
||||
struct gsm_bts *bts;
|
||||
|
||||
log_set_context(BSC_CTX_BTS, link->trx->bts);
|
||||
switch (link->type) {
|
||||
case E1INP_SIGN_OML:
|
||||
bts = link->trx->bts;
|
||||
|
||||
@@ -75,11 +75,7 @@ static const struct chreq chreq_type_neci1[] = {
|
||||
{ 0x67, 0xff, CHREQ_T_LMU },
|
||||
{ 0x60, 0xf9, CHREQ_T_RESERVED_SDCCH },
|
||||
{ 0x61, 0xfb, CHREQ_T_RESERVED_SDCCH },
|
||||
{ 0x63, 0xff, CHREQ_T_RESERVED_SDCCH },
|
||||
{ 0x70, 0xf8, CHREQ_T_PDCH_TWO_PHASE },
|
||||
{ 0x78, 0xfc, CHREQ_T_PDCH_ONE_PHASE },
|
||||
{ 0x78, 0xfa, CHREQ_T_PDCH_ONE_PHASE },
|
||||
{ 0x78, 0xf9, CHREQ_T_PDCH_ONE_PHASE },
|
||||
{ 0x63, 0xff, CHREQ_T_RESERVED_SDCCH },
|
||||
{ 0x7f, 0xff, CHREQ_T_RESERVED_IGNORE },
|
||||
};
|
||||
|
||||
@@ -96,11 +92,7 @@ static const struct chreq chreq_type_neci0[] = {
|
||||
{ 0x67, 0xff, CHREQ_T_LMU },
|
||||
{ 0x60, 0xf9, CHREQ_T_RESERVED_SDCCH },
|
||||
{ 0x61, 0xfb, CHREQ_T_RESERVED_SDCCH },
|
||||
{ 0x63, 0xff, CHREQ_T_RESERVED_SDCCH },
|
||||
{ 0x70, 0xf8, CHREQ_T_PDCH_TWO_PHASE },
|
||||
{ 0x78, 0xfc, CHREQ_T_PDCH_ONE_PHASE },
|
||||
{ 0x78, 0xfa, CHREQ_T_PDCH_ONE_PHASE },
|
||||
{ 0x78, 0xf9, CHREQ_T_PDCH_ONE_PHASE },
|
||||
{ 0x63, 0xff, CHREQ_T_RESERVED_SDCCH },
|
||||
{ 0x7f, 0xff, CHREQ_T_RESERVED_IGNORE },
|
||||
};
|
||||
|
||||
@@ -120,8 +112,6 @@ static const enum gsm_chan_t ctype_by_chreq[] = {
|
||||
[CHREQ_T_PAG_R_TCH_FH] = GSM_LCHAN_TCH_F,
|
||||
[CHREQ_T_LMU] = GSM_LCHAN_SDCCH,
|
||||
[CHREQ_T_RESERVED_SDCCH] = GSM_LCHAN_SDCCH,
|
||||
[CHREQ_T_PDCH_ONE_PHASE] = GSM_LCHAN_PDTCH,
|
||||
[CHREQ_T_PDCH_TWO_PHASE] = GSM_LCHAN_PDTCH,
|
||||
[CHREQ_T_RESERVED_IGNORE] = GSM_LCHAN_UNKNOWN,
|
||||
};
|
||||
|
||||
@@ -140,8 +130,6 @@ static const enum gsm_chreq_reason_t reason_by_chreq[] = {
|
||||
[CHREQ_T_PAG_R_TCH_F] = GSM_CHREQ_REASON_PAG,
|
||||
[CHREQ_T_PAG_R_TCH_FH] = GSM_CHREQ_REASON_PAG,
|
||||
[CHREQ_T_LMU] = GSM_CHREQ_REASON_OTHER,
|
||||
[CHREQ_T_PDCH_ONE_PHASE] = GSM_CHREQ_REASON_PDCH,
|
||||
[CHREQ_T_PDCH_TWO_PHASE] = GSM_CHREQ_REASON_PDCH,
|
||||
[CHREQ_T_RESERVED_SDCCH] = GSM_CHREQ_REASON_OTHER,
|
||||
[CHREQ_T_RESERVED_IGNORE] = GSM_CHREQ_REASON_OTHER,
|
||||
};
|
||||
@@ -270,9 +258,32 @@ int send_siemens_mrpci(struct gsm_lchan *lchan,
|
||||
return rsl_siemens_mrpci(lchan, &mrpci);
|
||||
}
|
||||
|
||||
/* TODO MSCSPLIT remove gsm48_handle_paging_resp() */
|
||||
int gsm48_extract_mi(uint8_t *classmark2_lv, int length, char *mi_string, uint8_t *mi_type)
|
||||
{
|
||||
/* Check the size for the classmark */
|
||||
if (length < 1 + *classmark2_lv)
|
||||
return -1;
|
||||
|
||||
uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1;
|
||||
if (length < 2 + *classmark2_lv + mi_lv[0])
|
||||
return -2;
|
||||
|
||||
*mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
|
||||
return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv);
|
||||
}
|
||||
|
||||
int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length,
|
||||
char *mi_string, uint8_t *mi_type)
|
||||
{
|
||||
static const uint32_t classmark_offset =
|
||||
offsetof(struct gsm48_pag_resp, classmark2);
|
||||
uint8_t *classmark2_lv = (uint8_t *) &resp->classmark2;
|
||||
return gsm48_extract_mi(classmark2_lv, length - classmark_offset,
|
||||
mi_string, mi_type);
|
||||
}
|
||||
|
||||
int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg, struct bsc_subscr *bsub)
|
||||
struct msgb *msg, struct gsm_subscriber *subscr)
|
||||
{
|
||||
struct gsm_bts *bts = msg->lchan->ts->trx->bts;
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
@@ -281,24 +292,22 @@ int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn,
|
||||
if (is_siemens_bts(bts))
|
||||
send_siemens_mrpci(msg->lchan, classmark2_lv);
|
||||
|
||||
if (!conn->bsub) {
|
||||
conn->bsub = bsub;
|
||||
} else if (conn->bsub != bsub) {
|
||||
LOGP(DRR, LOGL_ERROR,
|
||||
"<- Channel already owned by someone else?\n");
|
||||
bsc_subscr_put(bsub);
|
||||
if (!conn->subscr) {
|
||||
conn->subscr = subscr;
|
||||
} else if (conn->subscr != subscr) {
|
||||
LOGP(DRR, LOGL_ERROR, "<- Channel already owned by someone else?\n");
|
||||
subscr_put(subscr);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
DEBUGP(DRR, "<- Channel already owned by us\n");
|
||||
bsc_subscr_put(bsub);
|
||||
bsub = conn->bsub;
|
||||
subscr_put(subscr);
|
||||
subscr = conn->subscr;
|
||||
}
|
||||
|
||||
rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_PAGING_COMPLETED]);
|
||||
|
||||
/* Stop paging on the bts we received the paging response */
|
||||
paging_request_stop(&bts->network->bts_list, conn->bts, bsub, conn,
|
||||
msg);
|
||||
paging_request_stop(conn->bts, subscr, conn, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,27 +33,6 @@
|
||||
#include <openbsc/handover.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
|
||||
/* Get reference to a neighbor cell on a given BCCH ARFCN */
|
||||
static struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
|
||||
uint16_t arfcn, uint8_t bsic)
|
||||
{
|
||||
struct gsm_bts *neigh;
|
||||
/* FIXME: use some better heuristics here to determine which cell
|
||||
* using this ARFCN really is closest to the target cell. For
|
||||
* now we simply assume that each ARFCN will only be used by one
|
||||
* cell */
|
||||
|
||||
llist_for_each_entry(neigh, &bts->network->bts_list, list) {
|
||||
/* FIXME: this is probably returning the same bts again!? */
|
||||
if (neigh->c0->arfcn == arfcn &&
|
||||
neigh->bsic == bsic)
|
||||
return neigh;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* issue handover to a cell identified by ARFCN and BSIC */
|
||||
static int handover_to_arfcn_bsic(struct gsm_lchan *lchan,
|
||||
uint16_t arfcn, uint8_t bsic)
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <openbsc/transaction.h>
|
||||
#include <openbsc/trau_mux.h>
|
||||
#include <openbsc/vlr.h>
|
||||
|
||||
struct bsc_handover {
|
||||
struct llist_head list;
|
||||
@@ -262,7 +261,7 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan)
|
||||
|
||||
net = new_lchan->ts->trx->bts->network;
|
||||
LOGP(DHO, LOGL_INFO, "Subscriber %s HO from BTS %u->%u on ARFCN "
|
||||
"%u->%u\n", vlr_subscr_name(ho->old_lchan->conn->vsub),
|
||||
"%u->%u\n", subscr_name(ho->old_lchan->conn->subscr),
|
||||
ho->old_lchan->ts->trx->bts->nr, new_lchan->ts->trx->bts->nr,
|
||||
ho->old_lchan->ts->trx->arfcn, new_lchan->ts->trx->arfcn);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <openbsc/common_cs.h>
|
||||
#include <openbsc/osmo_bsc.h>
|
||||
#include <openbsc/bsc_msc_data.h>
|
||||
#include <openbsc/osmo_msc_data.h>
|
||||
|
||||
struct gsm_network *bsc_network_init(void *ctx,
|
||||
uint16_t country_code,
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
#include <osmocom/gsm/gsm0502.h>
|
||||
|
||||
#include <openbsc/bsc_subscriber.h>
|
||||
#include <openbsc/paging.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/signal.h>
|
||||
@@ -50,27 +49,20 @@
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <openbsc/bsc_api.h>
|
||||
#include <openbsc/vlr.h>
|
||||
|
||||
void *tall_paging_ctx;
|
||||
|
||||
#define PAGING_TIMER 0, 500000
|
||||
|
||||
/*
|
||||
* TODO MSCSPLIT: the paging in libbsc is closely tied to MSC land in that the
|
||||
* MSC realm callback functions used to be invoked from the BSC/BTS level. So
|
||||
* this entire file needs to be rewired for use with an A interface.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Kill one paging request update the internal list...
|
||||
*/
|
||||
static void paging_remove_request(struct gsm_bts_paging_state *paging_bts,
|
||||
struct gsm_paging_request *to_be_deleted)
|
||||
struct gsm_paging_request *to_be_deleted)
|
||||
{
|
||||
osmo_timer_del(&to_be_deleted->T3113);
|
||||
llist_del(&to_be_deleted->entry);
|
||||
bsc_subscr_put(to_be_deleted->bsub);
|
||||
subscr_put(to_be_deleted->subscr);
|
||||
talloc_free(to_be_deleted);
|
||||
}
|
||||
|
||||
@@ -85,21 +77,20 @@ static void page_ms(struct gsm_paging_request *request)
|
||||
if (!bts->oml_link)
|
||||
return;
|
||||
|
||||
log_set_context(LOG_CTX_BSC_SUBSCR, request->bsub);
|
||||
log_set_context(BSC_CTX_SUBSCR, request->subscr);
|
||||
|
||||
LOGP(DPAG, LOGL_INFO, "Going to send paging commands: imsi: %s tmsi: "
|
||||
"0x%08x for ch. type %d (attempt %d)\n", request->bsub->imsi,
|
||||
request->bsub->tmsi, request->chan_type, request->attempts);
|
||||
LOGP(DPAG, LOGL_INFO, "Going to send paging commands: imsi: '%s' tmsi: '0x%x'\n",
|
||||
request->subscr->imsi, request->subscr->tmsi);
|
||||
|
||||
if (request->bsub->tmsi == GSM_RESERVED_TMSI)
|
||||
mi_len = gsm48_generate_mid_from_imsi(mi, request->bsub->imsi);
|
||||
if (request->subscr->tmsi == GSM_RESERVED_TMSI)
|
||||
mi_len = gsm48_generate_mid_from_imsi(mi, request->subscr->imsi);
|
||||
else
|
||||
mi_len = gsm48_generate_mid_from_tmsi(mi, request->bsub->tmsi);
|
||||
mi_len = gsm48_generate_mid_from_tmsi(mi, request->subscr->tmsi);
|
||||
|
||||
page_group = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
|
||||
str_to_imsi(request->bsub->imsi));
|
||||
str_to_imsi(request->subscr->imsi));
|
||||
gsm0808_page(bts, page_group, mi_len, mi, request->chan_type);
|
||||
log_set_context(LOG_CTX_BSC_SUBSCR, NULL);
|
||||
log_set_context(BSC_CTX_SUBSCR, NULL);
|
||||
}
|
||||
|
||||
static void paging_schedule_if_needed(struct gsm_bts_paging_state *paging_bts)
|
||||
@@ -245,12 +236,11 @@ static void paging_init_if_needed(struct gsm_bts *bts)
|
||||
}
|
||||
|
||||
static int paging_pending_request(struct gsm_bts_paging_state *bts,
|
||||
struct bsc_subscr *bsub)
|
||||
{
|
||||
struct gsm_subscriber *subscr) {
|
||||
struct gsm_paging_request *req;
|
||||
|
||||
llist_for_each_entry(req, &bts->pending_requests, entry) {
|
||||
if (bsub == req->bsub)
|
||||
if (subscr == req->subscr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -264,10 +254,10 @@ static void paging_T3113_expired(void *data)
|
||||
gsm_cbfn *cbfn;
|
||||
int msg;
|
||||
|
||||
log_set_context(LOG_CTX_BSC_SUBSCR, req->bsub);
|
||||
log_set_context(BSC_CTX_SUBSCR, req->subscr);
|
||||
|
||||
LOGP(DPAG, LOGL_INFO, "T3113 expired for request %p (%s)\n",
|
||||
req, bsc_subscr_name(req->bsub));
|
||||
req, req->subscr->imsi);
|
||||
|
||||
/* must be destroyed before calling cbfn, to prevent double free */
|
||||
rate_ctr_inc(&req->bts->network->bsc_ctrs->ctr[BSC_CTR_PAGING_EXPIRED]);
|
||||
@@ -286,22 +276,21 @@ static void paging_T3113_expired(void *data)
|
||||
|
||||
}
|
||||
|
||||
static int _paging_request(struct gsm_bts *bts, struct bsc_subscr *bsub,
|
||||
int type, gsm_cbfn *cbfn, void *data)
|
||||
static int _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *data)
|
||||
{
|
||||
struct gsm_bts_paging_state *bts_entry = &bts->paging;
|
||||
struct gsm_paging_request *req;
|
||||
|
||||
if (paging_pending_request(bts_entry, bsub)) {
|
||||
LOGP(DPAG, LOGL_INFO, "Paging request already pending for %s\n",
|
||||
bsc_subscr_name(bsub));
|
||||
if (paging_pending_request(bts_entry, subscr)) {
|
||||
LOGP(DPAG, LOGL_INFO, "Paging request already pending for %s\n", subscr->imsi);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
LOGP(DPAG, LOGL_DEBUG, "Start paging of subscriber %s on bts %d.\n",
|
||||
bsc_subscr_name(bsub), bts->nr);
|
||||
LOGP(DPAG, LOGL_DEBUG, "Start paging of subscriber %llu on bts %d.\n",
|
||||
subscr->id, bts->nr);
|
||||
req = talloc_zero(tall_paging_ctx, struct gsm_paging_request);
|
||||
req->bsub = bsc_subscr_get(bsub);
|
||||
req->subscr = subscr_get(subscr);
|
||||
req->bts = bts;
|
||||
req->chan_type = type;
|
||||
req->cbfn = cbfn;
|
||||
@@ -315,8 +304,8 @@ static int _paging_request(struct gsm_bts *bts, struct bsc_subscr *bsub,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int paging_request_bts(struct gsm_bts *bts, struct bsc_subscr *bsub,
|
||||
int type, gsm_cbfn *cbfn, void *data)
|
||||
int paging_request_bts(struct gsm_bts *bts, struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -327,14 +316,15 @@ int paging_request_bts(struct gsm_bts *bts, struct bsc_subscr *bsub,
|
||||
/* maybe it is the first time we use it */
|
||||
paging_init_if_needed(bts);
|
||||
|
||||
|
||||
/* Trigger paging, pass any error to the caller */
|
||||
rc = _paging_request(bts, bsub, type, cbfn, data);
|
||||
rc = _paging_request(bts, subscr, type, cbfn, data);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int paging_request(struct gsm_network *network, struct bsc_subscr *bsub,
|
||||
int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *data)
|
||||
{
|
||||
struct gsm_bts *bts = NULL;
|
||||
@@ -346,14 +336,13 @@ int paging_request(struct gsm_network *network, struct bsc_subscr *bsub,
|
||||
do {
|
||||
int rc;
|
||||
|
||||
bts = gsm_bts_by_lac(network, bsub->lac, bts);
|
||||
bts = gsm_bts_by_lac(network, subscr->lac, bts);
|
||||
if (!bts)
|
||||
break;
|
||||
|
||||
rc = paging_request_bts(bts, bsub, type, cbfn, data);
|
||||
rc = paging_request_bts(bts, subscr, type, cbfn, data);
|
||||
if (rc < 0) {
|
||||
paging_request_stop(&network->bts_list, NULL, bsub,
|
||||
NULL, NULL);
|
||||
paging_request_stop(NULL, subscr, NULL, NULL);
|
||||
return rc;
|
||||
}
|
||||
num_pages += rc;
|
||||
@@ -367,7 +356,7 @@ int paging_request(struct gsm_network *network, struct bsc_subscr *bsub,
|
||||
|
||||
|
||||
/* we consciously ignore the type of the request here */
|
||||
static void _paging_request_stop(struct gsm_bts *bts, struct bsc_subscr *bsub,
|
||||
static void _paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr,
|
||||
struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg)
|
||||
{
|
||||
@@ -377,8 +366,8 @@ static void _paging_request_stop(struct gsm_bts *bts, struct bsc_subscr *bsub,
|
||||
paging_init_if_needed(bts);
|
||||
|
||||
llist_for_each_entry_safe(req, req2, &bts_entry->pending_requests,
|
||||
entry) {
|
||||
if (req->bsub == bsub) {
|
||||
entry) {
|
||||
if (req->subscr == subscr) {
|
||||
gsm_cbfn *cbfn = req->cbfn;
|
||||
void *param = req->cbfn_param;
|
||||
|
||||
@@ -387,36 +376,35 @@ static void _paging_request_stop(struct gsm_bts *bts, struct bsc_subscr *bsub,
|
||||
req = NULL;
|
||||
|
||||
if (conn && cbfn) {
|
||||
LOGP(DPAG, LOGL_DEBUG, "Stop paging %s on bts %d, calling cbfn.\n", bsub->imsi, bts->nr);
|
||||
LOGP(DPAG, LOGL_DEBUG, "Stop paging on bts %d, calling cbfn.\n", bts->nr);
|
||||
cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_SUCCEEDED,
|
||||
msg, conn, param);
|
||||
msg, conn, param);
|
||||
} else
|
||||
LOGP(DPAG, LOGL_DEBUG, "Stop paging %s on bts %d silently.\n", bsub->imsi, bts->nr);
|
||||
LOGP(DPAG, LOGL_DEBUG, "Stop paging on bts %d silently.\n", bts->nr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop paging on all other bts' */
|
||||
void paging_request_stop(struct llist_head *bts_list,
|
||||
struct gsm_bts *_bts, struct bsc_subscr *bsub,
|
||||
void paging_request_stop(struct gsm_bts *_bts, struct gsm_subscriber *subscr,
|
||||
struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg)
|
||||
{
|
||||
struct gsm_bts *bts;
|
||||
|
||||
log_set_context(LOG_CTX_BSC_SUBSCR, bsub);
|
||||
log_set_context(BSC_CTX_SUBSCR, subscr);
|
||||
|
||||
/* Stop this first and dispatch the request */
|
||||
if (_bts)
|
||||
_paging_request_stop(_bts, bsub, conn, msg);
|
||||
_paging_request_stop(_bts, subscr, conn, msg);
|
||||
|
||||
/* Make sure to cancel this everywhere else */
|
||||
llist_for_each_entry(bts, bts_list, list) {
|
||||
llist_for_each_entry(bts, &subscr->group->net->bts_list, list) {
|
||||
/* Sort of an optimization. */
|
||||
if (bts == _bts)
|
||||
continue;
|
||||
_paging_request_stop(bts, bsub, NULL, NULL);
|
||||
_paging_request_stop(bts, subscr, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,12 +433,12 @@ unsigned int paging_pending_requests_nr(struct gsm_bts *bts)
|
||||
/**
|
||||
* Find any paging data for the given subscriber at the given BTS.
|
||||
*/
|
||||
void *paging_get_data(struct gsm_bts *bts, struct bsc_subscr *bsub)
|
||||
void *paging_get_data(struct gsm_bts *bts, struct gsm_subscriber *subscr)
|
||||
{
|
||||
struct gsm_paging_request *req;
|
||||
|
||||
llist_for_each_entry(req, &bts->paging.pending_requests, entry)
|
||||
if (req->bsub == bsub)
|
||||
if (req->subscr == subscr)
|
||||
return req->cbfn_param;
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -566,8 +566,6 @@ static int append_gprs_mobile_alloc(struct bitvec *bv)
|
||||
|
||||
static int encode_t3192(unsigned int t3192)
|
||||
{
|
||||
/* See also 3GPP TS 44.060
|
||||
Table 12.24.2: GPRS Cell Options information element details */
|
||||
if (t3192 == 0)
|
||||
return 3;
|
||||
else if (t3192 <= 80)
|
||||
@@ -647,11 +645,7 @@ static int append_gprs_cell_opt(struct bitvec *bv,
|
||||
return drx_timer_max;
|
||||
|
||||
bitvec_set_uint(bv, gco->nmo, 2);
|
||||
|
||||
/* See also 3GPP TS 44.060
|
||||
Table 12.24.2: GPRS Cell Options information element details */
|
||||
bitvec_set_uint(bv, gco->t3168 / 500 - 1, 3);
|
||||
|
||||
bitvec_set_uint(bv, gco->t3168 / 500, 3);
|
||||
bitvec_set_uint(bv, t3192, 3);
|
||||
bitvec_set_uint(bv, drx_timer_max, 3);
|
||||
/* ACCESS_BURST_TYPE: Hard-code 8bit */
|
||||
|
||||
@@ -49,26 +49,27 @@ struct gsm_network *gsm_network_init(void *ctx,
|
||||
if (!net)
|
||||
return NULL;
|
||||
|
||||
net->subscr_group = talloc_zero(net, struct gsm_subscriber_group);
|
||||
if (!net->subscr_group) {
|
||||
talloc_free(net);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gsm_parse_reg(net, &net->authorized_regexp, &net->authorized_reg_str, 1,
|
||||
&default_regexp) != 0)
|
||||
return NULL;
|
||||
|
||||
net->subscr_group->net = net;
|
||||
net->auto_create_subscr = true;
|
||||
net->auto_assign_exten = true;
|
||||
|
||||
net->country_code = country_code;
|
||||
net->network_code = network_code;
|
||||
|
||||
/* Use 30 min periodic update interval as sane default */
|
||||
net->t3212 = 5;
|
||||
|
||||
INIT_LLIST_HEAD(&net->trans_list);
|
||||
INIT_LLIST_HEAD(&net->upqueue);
|
||||
INIT_LLIST_HEAD(&net->subscr_conns);
|
||||
|
||||
net->bsc_subscribers = talloc_zero(net, struct llist_head);
|
||||
INIT_LLIST_HEAD(net->bsc_subscribers);
|
||||
|
||||
/* init statistics */
|
||||
net->msc_ctrs = rate_ctr_group_alloc(net, &msc_ctrg_desc, 0);
|
||||
net->active_calls = osmo_counter_alloc("msc.active_calls");
|
||||
@@ -115,30 +116,6 @@ struct msgb *gsm48_create_loc_upd_rej(uint8_t cause)
|
||||
return msg;
|
||||
}
|
||||
|
||||
int gsm48_extract_mi(uint8_t *classmark2_lv, int length, char *mi_string, uint8_t *mi_type)
|
||||
{
|
||||
/* Check the size for the classmark */
|
||||
if (length < 1 + *classmark2_lv)
|
||||
return -1;
|
||||
|
||||
uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1;
|
||||
if (length < 2 + *classmark2_lv + mi_lv[0])
|
||||
return -2;
|
||||
|
||||
*mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
|
||||
return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv);
|
||||
}
|
||||
|
||||
int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length,
|
||||
char *mi_string, uint8_t *mi_type)
|
||||
{
|
||||
static const uint32_t classmark_offset =
|
||||
offsetof(struct gsm48_pag_resp, classmark2);
|
||||
uint8_t *classmark2_lv = (uint8_t *) &resp->classmark2;
|
||||
return gsm48_extract_mi(classmark2_lv, length - classmark_offset,
|
||||
mi_string, mi_type);
|
||||
}
|
||||
|
||||
uint8_t sms_next_rp_msg_ref(uint8_t *next_rp_ref)
|
||||
{
|
||||
const uint8_t rp_msg_ref = *next_rp_ref;
|
||||
|
||||
@@ -105,13 +105,15 @@ DEFUN(cfg_net_name_long,
|
||||
|
||||
DEFUN(cfg_net_auth_policy,
|
||||
cfg_net_auth_policy_cmd,
|
||||
"auth policy (closed|accept-all|regexp|token)",
|
||||
"auth policy (closed|accept-all|regexp|token|remote|remote-closed)",
|
||||
"Authentication (not cryptographic)\n"
|
||||
"Set the GSM network authentication policy\n"
|
||||
"Require the MS to be activated in HLR\n"
|
||||
"Accept all MS, whether in HLR or not\n"
|
||||
"Use regular expression for IMSI authorization decision\n"
|
||||
"Use SMS-token based authentication\n")
|
||||
"Use SMS-token based authentication\n"
|
||||
"Use remote subscription data only (HLR)\n"
|
||||
"Use remote subscription data if the MS is activated in local HLR\n")
|
||||
{
|
||||
enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]);
|
||||
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||
@@ -168,20 +170,6 @@ DEFUN(cfg_net_encryption,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_net_authentication,
|
||||
cfg_net_authentication_cmd,
|
||||
"authentication (optional|required)",
|
||||
"Whether to enforce MS authentication in 2G\n"
|
||||
"Allow MS to attach via 2G BSC without authentication\n"
|
||||
"Always do authentication\n")
|
||||
{
|
||||
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||
|
||||
gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
|
||||
"rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
|
||||
"Radio Resource Location Protocol\n"
|
||||
@@ -217,10 +205,9 @@ DEFUN(cfg_net_subscr_keep,
|
||||
"Keep unused subscribers in RAM.\n"
|
||||
"Delete unused subscribers\n" "Keep unused subscribers\n")
|
||||
{
|
||||
vty_out(vty, "%% subscriber-keep-in-ram is currently not implemented%s",
|
||||
VTY_NEWLINE);
|
||||
/* TODO add a libvlr mechanism to keep vlr_subscrs in RAM? */
|
||||
return CMD_WARNING;
|
||||
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||
gsmnet->subscr_group->keep_subscr = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_net_timezone,
|
||||
@@ -284,34 +271,6 @@ DEFUN(cfg_net_no_timezone,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
|
||||
"periodic location update <6-1530>",
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval in Minutes\n")
|
||||
{
|
||||
struct gsm_network *net = vty->index;
|
||||
|
||||
net->t3212 = atoi(argv[0]) / 6;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
|
||||
"no periodic location update",
|
||||
NO_STR
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval\n"
|
||||
"Periodic Location Updating Interval\n")
|
||||
{
|
||||
struct gsm_network *net = vty->index;
|
||||
|
||||
net->t3212 = 0;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static struct gsm_network *vty_global_gsm_network = NULL;
|
||||
|
||||
/* initialize VTY elements used in both BSC and MSC */
|
||||
@@ -321,8 +280,6 @@ int common_cs_vty_init(struct gsm_network *network,
|
||||
OSMO_ASSERT(vty_global_gsm_network == NULL);
|
||||
vty_global_gsm_network = network;
|
||||
|
||||
osmo_stats_vty_add_cmds();
|
||||
|
||||
install_element(CONFIG_NODE, &cfg_net_cmd);
|
||||
install_node(&net_node, config_write_net);
|
||||
vty_install_default(GSMNET_NODE);
|
||||
@@ -334,15 +291,12 @@ int common_cs_vty_init(struct gsm_network *network,
|
||||
install_element(GSMNET_NODE, &cfg_net_authorize_regexp_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_reject_cause_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_subscr_keep_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/gprs/gprs_msgb.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
/* default categories */
|
||||
@@ -40,74 +41,74 @@ static const struct log_info_cat default_categories[] = {
|
||||
.name = "DRLL",
|
||||
.description = "A-bis Radio Link Layer (RLL)",
|
||||
.color = "\033[1;31m",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DCC] = {
|
||||
.name = "DCC",
|
||||
.description = "Layer3 Call Control (CC)",
|
||||
.color = "\033[1;32m",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMM] = {
|
||||
.name = "DMM",
|
||||
.description = "Layer3 Mobility Management (MM)",
|
||||
.color = "\033[1;33m",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DRR] = {
|
||||
.name = "DRR",
|
||||
.description = "Layer3 Radio Resource (RR)",
|
||||
.color = "\033[1;34m",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DRSL] = {
|
||||
.name = "DRSL",
|
||||
.description = "A-bis Radio Siganlling Link (RSL)",
|
||||
.color = "\033[1;35m",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DNM] = {
|
||||
.name = "DNM",
|
||||
.description = "A-bis Network Management / O&M (NM/OML)",
|
||||
.color = "\033[1;36m",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_INFO,
|
||||
},
|
||||
[DMNCC] = {
|
||||
.name = "DMNCC",
|
||||
.description = "MNCC API for Call Control application",
|
||||
.color = "\033[1;39m",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DPAG] = {
|
||||
.name = "DPAG",
|
||||
.description = "Paging Subsystem",
|
||||
.color = "\033[1;38m",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMEAS] = {
|
||||
.name = "DMEAS",
|
||||
.description = "Radio Measurement Processing",
|
||||
.enabled = 0, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 0, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DSCCP] = {
|
||||
.name = "DSCCP",
|
||||
.description = "SCCP Protocol",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMSC] = {
|
||||
.name = "DMSC",
|
||||
.description = "Mobile Switching Center",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DMGCP] = {
|
||||
.name = "DMGCP",
|
||||
.description = "Media Gateway Control Protocol",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DHO] = {
|
||||
.name = "DHO",
|
||||
.description = "Hand-Over",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DDB] = {
|
||||
.name = "DDB",
|
||||
@@ -117,7 +118,7 @@ static const struct log_info_cat default_categories[] = {
|
||||
[DREF] = {
|
||||
.name = "DREF",
|
||||
.description = "Reference Counting",
|
||||
.enabled = 0, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 0, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DGPRS] = {
|
||||
.name = "DGPRS",
|
||||
@@ -127,7 +128,7 @@ static const struct log_info_cat default_categories[] = {
|
||||
[DNS] = {
|
||||
.name = "DNS",
|
||||
.description = "GPRS Network Service (NS)",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_INFO,
|
||||
},
|
||||
[DBSSGP] = {
|
||||
.name = "DBSSGP",
|
||||
@@ -147,18 +148,23 @@ static const struct log_info_cat default_categories[] = {
|
||||
[DNAT] = {
|
||||
.name = "DNAT",
|
||||
.description = "GSM 08.08 NAT/Multiplexer",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DCTRL] = {
|
||||
.name = "DCTRL",
|
||||
.description = "Control interface",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DSMPP] = {
|
||||
.name = "DSMPP",
|
||||
.description = "SMPP interface for external SMS apps",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
},
|
||||
[DSUP] = {
|
||||
.name = "DSUP",
|
||||
.description = "SUP interface for external HLR",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
},
|
||||
[DFILTER] = {
|
||||
.name = "DFILTER",
|
||||
.description = "BSC/NAT IMSI based filtering",
|
||||
@@ -174,41 +180,34 @@ static const struct log_info_cat default_categories[] = {
|
||||
.description = "SCCP User Adaptation Protocol",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
},
|
||||
[DVLR] = {
|
||||
.name = "DVLR",
|
||||
.description = "Visitor Location Register",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
},
|
||||
[DIUCS] = {
|
||||
.name = "DIUCS",
|
||||
.description = "Iu-CS Protocol",
|
||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
||||
},
|
||||
};
|
||||
|
||||
static int filter_fn(const struct log_context *ctx, struct log_target *tar)
|
||||
enum log_filter {
|
||||
_FLT_ALL = LOG_FILTER_ALL, /* libosmocore */
|
||||
FLT_IMSI = 1,
|
||||
FLT_NSVC = 2,
|
||||
FLT_BVC = 3,
|
||||
};
|
||||
|
||||
static int filter_fn(const struct log_context *ctx,
|
||||
struct log_target *tar)
|
||||
{
|
||||
const struct vlr_subscr *vsub = ctx->ctx[LOG_CTX_VLR_SUBSCR];
|
||||
const struct bsc_subscr *bsub = ctx->ctx[LOG_CTX_BSC_SUBSCR];
|
||||
const struct gprs_nsvc *nsvc = ctx->ctx[LOG_CTX_GB_NSVC];
|
||||
const struct gprs_nsvc *bvc = ctx->ctx[LOG_CTX_GB_BVC];
|
||||
struct gsm_subscriber *subscr = ctx->ctx[BSC_CTX_SUBSCR];
|
||||
const struct gprs_nsvc *nsvc = ctx->ctx[GPRS_CTX_NSVC];
|
||||
const struct gprs_nsvc *bvc = ctx->ctx[GPRS_CTX_BVC];
|
||||
|
||||
if ((tar->filter_map & (1 << LOG_FLT_VLR_SUBSCR)) != 0
|
||||
&& vsub && vsub == tar->filter_data[LOG_FLT_VLR_SUBSCR])
|
||||
return 1;
|
||||
|
||||
if ((tar->filter_map & (1 << LOG_FLT_BSC_SUBSCR)) != 0
|
||||
&& bsub && bsub == tar->filter_data[LOG_FLT_BSC_SUBSCR])
|
||||
if ((tar->filter_map & (1 << FLT_IMSI)) != 0
|
||||
&& subscr && subscr == tar->filter_data[FLT_IMSI])
|
||||
return 1;
|
||||
|
||||
/* Filter on the NS Virtual Connection */
|
||||
if ((tar->filter_map & (1 << LOG_FLT_GB_NSVC)) != 0
|
||||
&& nsvc && (nsvc == tar->filter_data[LOG_FLT_GB_NSVC]))
|
||||
if ((tar->filter_map & (1 << FLT_NSVC)) != 0
|
||||
&& nsvc && (nsvc == tar->filter_data[FLT_NSVC]))
|
||||
return 1;
|
||||
|
||||
/* Filter on the NS Virtual Connection */
|
||||
if ((tar->filter_map & (1 << LOG_FLT_GB_BVC)) != 0
|
||||
&& bvc && (bvc == tar->filter_data[LOG_FLT_GB_BVC]))
|
||||
if ((tar->filter_map & (1 << FLT_BVC)) != 0
|
||||
&& bvc && (bvc == tar->filter_data[FLT_BVC]))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -219,3 +218,19 @@ const struct log_info log_info = {
|
||||
.cat = default_categories,
|
||||
.num_cat = ARRAY_SIZE(default_categories),
|
||||
};
|
||||
|
||||
void log_set_imsi_filter(struct log_target *target, struct gsm_subscriber *subscr)
|
||||
{
|
||||
/* free the old data */
|
||||
if (target->filter_data[FLT_IMSI]) {
|
||||
subscr_put(target->filter_data[FLT_IMSI]);
|
||||
target->filter_data[FLT_IMSI] = NULL;
|
||||
}
|
||||
|
||||
if (subscr) {
|
||||
target->filter_map |= (1 << FLT_IMSI);
|
||||
target->filter_data[FLT_IMSI] = subscr_get(subscr);
|
||||
} else {
|
||||
target->filter_map &= ~(1 << FLT_IMSI);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/bsc_msc_data.h>
|
||||
#include <openbsc/osmo_msc_data.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
|
||||
void *tall_bsc_ctx;
|
||||
@@ -71,6 +71,25 @@ int gsm_bts_model_register(struct gsm_bts_model *model)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get reference to a neighbor cell on a given BCCH ARFCN */
|
||||
struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
|
||||
uint16_t arfcn, uint8_t bsic)
|
||||
{
|
||||
struct gsm_bts *neigh;
|
||||
/* FIXME: use some better heuristics here to determine which cell
|
||||
* using this ARFCN really is closest to the target cell. For
|
||||
* now we simply assume that each ARFCN will only be used by one
|
||||
* cell */
|
||||
|
||||
llist_for_each_entry(neigh, &bts->network->bts_list, list) {
|
||||
if (neigh->c0->arfcn == arfcn &&
|
||||
neigh->bsic == bsic)
|
||||
return neigh;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1] = {
|
||||
{ GSM_BTS_TYPE_UNKNOWN, "unknown" },
|
||||
{ GSM_BTS_TYPE_BS11, "bs11" },
|
||||
@@ -144,6 +163,8 @@ static const struct value_string auth_policy_names[] = {
|
||||
{ GSM_AUTH_POLICY_ACCEPT_ALL, "accept-all" },
|
||||
{ GSM_AUTH_POLICY_TOKEN, "token" },
|
||||
{ GSM_AUTH_POLICY_REGEXP, "regexp" },
|
||||
{ GSM_AUTH_POLICY_REMOTE, "remote" },
|
||||
{ GSM_AUTH_POLICY_REMOTE_CLOSED, "remote-closed" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
@@ -211,6 +232,19 @@ int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode)
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan)
|
||||
{
|
||||
struct gsm_meas_rep *meas_rep;
|
||||
|
||||
meas_rep = &lchan->meas_rep[lchan->meas_rep_idx];
|
||||
memset(meas_rep, 0, sizeof(*meas_rep));
|
||||
meas_rep->lchan = lchan;
|
||||
lchan->meas_rep_idx = (lchan->meas_rep_idx + 1)
|
||||
% ARRAY_SIZE(lchan->meas_rep);
|
||||
|
||||
return meas_rep;
|
||||
}
|
||||
|
||||
int gsm_btsmodel_set_feature(struct gsm_bts_model *bts, enum gsm_bts_features feat)
|
||||
{
|
||||
return bitvec_set_bit_pos(&bts->features, feat, 1);
|
||||
@@ -308,7 +342,7 @@ struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_typ
|
||||
bts->si_common.chan_desc.att = 1; /* attachment required */
|
||||
bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */
|
||||
bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */
|
||||
bts->si_common.chan_desc.t3212 = net->t3212; /* Use network's current value */
|
||||
bts->si_common.chan_desc.t3212 = 5; /* Use 30 min periodic update interval as sane default */
|
||||
set_radio_link_timeout(&bts->si_common.cell_options, 32);
|
||||
/* Use RADIO LINK TIMEOUT of 32 seconds */
|
||||
|
||||
@@ -421,20 +455,3 @@ int bts_depend_check(struct gsm_bts *bts)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool classmark_is_r99(struct gsm_classmark *cm)
|
||||
{
|
||||
int rev_lev = 0;
|
||||
if (cm->classmark1_set)
|
||||
rev_lev = cm->classmark1.rev_lev;
|
||||
else if (cm->classmark2_len > 0)
|
||||
rev_lev = (cm->classmark2[0] >> 5) & 0x3;
|
||||
return rev_lev >= 2;
|
||||
}
|
||||
|
||||
const struct value_string ran_type_names[] = {
|
||||
OSMO_VALUE_STRING(RAN_UNKNOWN),
|
||||
OSMO_VALUE_STRING(RAN_GERAN_A),
|
||||
OSMO_VALUE_STRING(RAN_UTRAN_IU),
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user