Compare commits

..

93 Commits

Author SHA1 Message Date
Ivan Kluchnikov
0e883ba6d4 debian: Update changelog to 0.15.1-fw.3 2017-02-16 22:12:52 +03:00
Ivan Kluchnikov
b6e37efb91 debian: Add openbsc-dev package to control, it is required for osmo-bts-trx packaging 2017-02-16 22:09:52 +03:00
Ivan Kluchnikov
6984250742 debian: Update changelog to 0.15.1-fw.2 2017-02-16 12:59:48 +03:00
Ivan Kluchnikov
683e60db73 debian: Add libcdk5-dev and libsqlite3-dev packages to dependencies, because they are required for building osmo-meas-utils 2017-02-16 12:31:15 +03:00
Ivan Kluchnikov
785e8b8533 fix: Include headers which were lost during rebase 2017-02-15 21:17:43 +03:00
Ivan Kluchnikov
bd6784dbe8 debian: Update changelog to 0.15.1-fw.1 2017-02-15 19:54:56 +03:00
Ivan Klyuchnikov
5788904242 gsup: Update code after rebase to updated gsup implementation 2017-02-07 19:01:13 +03:00
Ivan Kluchnikov
362a757f56 osmo-nitb: Send purge ms to reg-proxy and handle response 2017-02-07 18:59:56 +03:00
Ivan Kluchnikov
444a9b9304 reg-proxy: Implement purge ms forwarding and handling 2017-02-07 18:59:56 +03:00
Ivan Kluchnikov
8d8bedff4c gsm_04_08: Change reject cause for not "attached" subscribers from "destination out of order" to "no user responding" 2017-02-07 18:59:56 +03:00
Ivan Kluchnikov
084a35588f reg-proxy: fix osip transactions releasing procedure
* implement nict_trans_free function for checking list of osip_nict_transactions and releasing transactions in terminated state
* call nict_trans_free function in main loop
* transactions should not be released in message callback functions, so remove osip_transaction_free and osip_message_free from sip_cb_rcv2xx function
2017-02-07 18:59:56 +03:00
Ivan Kluchnikov
03bf40f6a5 reg-proxy: use osip_strdup function, because we should allocate memory for scheme and host values to be used in osip_uri_set_ functions 2017-02-07 18:59:56 +03:00
Ivan Kluchnikov
842e599c5c reg-proxy: we shouldn't free call_id_num and seq_num_str, because they are used in osip_message and will be freed by osip_message_free function 2017-02-07 18:59:56 +03:00
Ivan Kluchnikov
16e9c4a70f reg-proxy: free allocated ipa control messages in ipa_sock_server_cb function 2017-02-07 18:59:56 +03:00
Ivan Kluchnikov
fdee81b35f reg-proxy: free all allocated osip elements, messages and transactions 2017-02-07 18:59:56 +03:00
Ivan Kluchnikov
582242d2f5 gsm_sup: check connection before use it, because it can be already closed 2017-02-07 18:59:56 +03:00
Sergey.Kostanbaev
fb5a18db4b ussd_proxy: fix decoding GSM7 to latin1 2017-02-07 18:59:56 +03:00
Sergey Kostanbaev
8a8703e06c fix incorrect autorebase 2017-02-07 18:59:56 +03:00
Sergey Kostanbaev
d68abba3d0 fixup after rebase 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
bbd3c7cd46 reg-proxy: Implement handling LU responses without msisdn
If we receive 200 ok response with imsi instead of msisdn in sip contact header, we should send LU response message to osmo-nitb without msisdn.
2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
0a2a92a4f5 gsm_sup: Update subscriber info in database only if msisdn is received in LU response 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
a52726dae8 msc: Increase value of location update timer to 10 sec
We should increase this timer, because LU procedure can take more than 5 sec, if 'remote' auth policy is used.
2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
8af593e4e4 sms: Route all sms from/to subscribers with extension length = 5 to local smsc 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
fb11fc1a7a sup: pass subscriber group parameter to subscr_get_by_extension function
Subscriber group parameter should be set for subscriber in subscr_get_by_extension function, because it is used in connection_for_subscr function.
2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
0904c1de19 sms: Use gsm411_rp_hdr structure instead of manual parsing of RP messages 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
c301ef4ea7 sms: MO RP ACK and RP ERROR should be also forwarded to the sms socket 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
59dc70462b sms: In case of receiving MO RP-DATA, we should assign RP message reference value to transaction variable 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
e7dc282b51 sup: Fix RP header offset and RP data length calculations 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
45fdb6a728 vty: Install sms_destination_cmd element as NITB_NODE 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
32906636f1 sms: Add functions for forwarding/handling SMS in RP format to/from external application 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
b314380065 sms: Add new socket for forwarding/receiving SMS in RP format to/from external application 2017-02-07 18:59:55 +03:00
Ivan Kluchnikov
8bb11c90fc trans: Add new parameter message reference for SMS and function for finding transaction by this reference 2017-02-07 18:59:55 +03:00
Sergey Kostanbaev
933de8cb48 send actual message in facility op (not initial) 2017-02-07 18:59:55 +03:00
Kirill Zakharenko
1bcfaa7119 debian: use --enable-ussd-proxy with ./configure 2017-02-07 18:59:55 +03:00
Kirill Zakharenko
6c079bb981 reg-proxy, ussd-proxy: don't use realtime priority 2017-02-07 18:59:55 +03:00
Sergey.Kostanbaev
c572ac8733 add test for registerSS 2017-02-07 18:59:55 +03:00
Sergey.Kostanbaev
53d1a9186c set transaction_id from transaction data 2017-02-07 18:59:55 +03:00
Sergey Kostanbaev
2f749ef103 emulation for SS 2017-02-07 18:59:55 +03:00
Sergey Kostanbaev
17276417ef various bugs in ss reply 2017-02-07 18:59:55 +03:00
Sergey.Kostanbaev
234f6714a7 add generation of src/ussd-proxy/Makefile 2017-02-07 18:59:54 +03:00
Sergey.Kostanbaev
3e7a48c475 add forgotten files 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
9d53708f58 add forgotten file 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
da8c96e097 recovery latin1 USSD message, probably bad rebase 2017-02-07 18:59:54 +03:00
Sergey.Kostanbaev
d4839fe14a manual merge SS from sup-ussd-on-master-ss-wip 2017-02-07 18:59:54 +03:00
Ivan Kluchnikov
db0e216845 msc: Implement 'remote-closed' authentication policy
This mode is modified version of 'remote' policy.
Osmo-nitb uses remote subscription data only if the MS is activated in local HLR, otherwise osmo-nitb rejects subscriber.
2017-02-07 18:59:54 +03:00
Ivan Kluchnikov
2d9f39ec43 reg-proxy: Added configuration parameter for setting registration expiry time 2017-02-07 18:59:54 +03:00
Ivan Kluchnikov
e5e251c396 sup: fix handling update location result message
If LUR procedure timed out, we should just skip update location result message.
2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
991691f8df ussd_proxy: add content-type sip tag in bye for 3rd party software workaround 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
955d8800e5 ussd_proxy: add -x proxy option 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
9a4936a234 ussd_proxy: add -7 option to force latin1 convertion to gsm 7-bit 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
012c9203e4 ussd: handle UCS-2 coding 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
5087f994fd libmsc: set proper length field in ASN.1 format for USSD internals 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
420e4d445c libmsc: fix no return and use after free 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
a8f56961be ussd_proxy: handle reject from sup and send BYE to sip 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
b2679b822e ussd: send reject to sup 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
0ce3516a47 ussd_proxy: add debug output when session is destroyed 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
2b5eb8ddb0 libmsc: use message type as an entry point and handle release complete message 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
fd245fcfa8 ussd_proxy: fix reject after resultLast 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
9f24671589 ussd_proxy: add -l parameter to set loglevel in sip sofia 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
acddb2a632 ussd_proxy: remove dead code 2017-02-07 18:59:54 +03:00
Kirill Zakharenko
800369d258 debian: new package for reg-proxy & ussd-proxy 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
236d81fa0c ussd_proxy: detailed help 2017-02-07 18:59:54 +03:00
Sergey Kostanbaev
8e58f575e7 ussd_proxy: handle multiple USSD sessions 2017-02-07 18:59:53 +03:00
Sergey Kostanbaev
da0864dfde ussd_proxy: handle session timeout 2017-02-07 18:59:53 +03:00
Sergey Kostanbaev
fc969503e1 ussd_proxy: handle error callback 2017-02-07 18:59:53 +03:00
Sergey Kostanbaev
1e4a954c73 ussd_proxy: handle USSD dialogs into sip INFO messages 2017-02-07 18:59:53 +03:00
Sergey Kostanbaev
2f4878a90f ussd_proxy: handle basic errors to release channel 2017-02-07 18:59:53 +03:00
Sergey Kostanbaev
70e6f2ec74 ussd_proxy: properly set To and From SIP headers 2017-02-07 18:59:53 +03:00
Sergey Kostanbaev
be9419881c Add forgotten Makefile 2017-02-07 18:59:53 +03:00
Sergey Kostanbaev
a363aa3fc0 add standalone ussd_proxy utility based on sip sofia 2017-02-07 18:59:53 +03:00
Kirill Zakharenko
9cddaeafd5 debian: added libosip2 to build dependencies 2017-02-07 18:59:53 +03:00
Alexander Chemeris
9fe68b0fbc libmsc: Add a comment to the HLR SUP socket creation. 2017-02-07 18:59:53 +03:00
Alexander Chemeris
1c30463e76 libmsc: Create a separate SUP socket for USSD. 2017-02-07 18:59:53 +03:00
Alexander Chemeris
bcc2567579 libmsc: Fix comment style. 2017-02-07 18:59:53 +03:00
Alexander Chemeris
924292977f libmsc: Remove sup_init() to make SUP socket initialiaton generic. 2017-02-07 18:59:53 +03:00
Alexander Chemeris
a317e334c2 libmsc: Make internal functions 'static' in gsm_sup. 2017-02-07 18:59:53 +03:00
Alexander Chemeris
76c7cec298 libmsc: Whitespace fix in gsm_sup.c, no code changes. 2017-02-07 18:59:53 +03:00
Alexander Chemeris
c70110945a libmsc: Rename sup_client to hlr_sup_client in preparation for multiple SUP clients. 2017-02-07 18:59:53 +03:00
Sergey Kostanbaev
f5fe345dbb USSD MAP external interface over SUP 2017-02-07 18:59:53 +03:00
Ivan Klyuchnikov
07a5b120e9 Revert "ussd: Add band-aid for interrogationSS"
This reverts commit 5085e0bf4c.
2017-02-07 18:59:53 +03:00
Ivan Kluchnikov
dfeabbbff6 reg-proxy: add application which allows translate SUP to SIP and SIP to SUP 2017-02-07 18:59:53 +03:00
Ivan Kluchnikov
1371303689 sup: Fix msisdn decoding 2017-02-07 18:59:53 +03:00
Ivan Kluchnikov
f7cb56572a sup: Change status of waiting_for_remote_accept before checking subscriber 2017-02-07 18:59:53 +03:00
Ivan Kluchnikov
014316f514 nitb: Integrate the SUP client into the osmo-nitb 2017-02-07 18:59:53 +03:00
Ivan Kluchnikov
b96f1912da msc: Implement 'remote' authentication policy
- All location update requests should be send to the remote HLR and accepted.
- Authentication info should be also received from remote HLR.
- SUP is used for sending/handling subscription data to/from remote HLR.
2017-02-07 18:59:52 +03:00
Ivan Kluchnikov
adc681331e sup: Add functions to create/handle SUP messages
- Add functions to send location update request and handle responses.
- Add functions to query auth info and handle responses.
2017-02-07 18:57:31 +03:00
Ivan Kluchnikov
8516d533db debug: Add DSUP debug category for subscriber update protocol 2017-02-07 18:57:31 +03:00
Ivan Kluchnikov
c6e735fd00 debian: Add osmocom-meas-utils package 2017-02-07 18:57:31 +03:00
Ivan Kluchnikov
cc75a7f014 debian: build only osmo-nitb package - enable smpp support - disable the gbproxy test (failing) 2017-02-07 18:57:30 +03:00
Alexander Chemeris
1c33b89886 utils: Support new fields in the v1 of meas_feed in meas_json. 2017-02-07 18:53:38 +03:00
Alexander Chemeris
077e62cded utils: 'meas_json' utility to convert measurement feed into a JSON feed. 2017-02-07 18:53:38 +03:00
Alexander Chemeris
a78396dcb3 libbsc: Update a BTS's SIs when ms_max_power is changed from VTY.
Otherwise you have to restart BTS or at least break the RSL connection
to apply the change.
2017-02-07 18:53:38 +03:00
Alexander Chemeris
e9c81d2581 libmsc: Update 'max_power_red' VTY command.
Changes:
 * Apply change even if the supplied value is odd, just warn that it is rounded.
 * Apply change even if the supplied value is higher than the 24dB maximum
   suggested by the standard, just warn about this.
 * Apply change to the BTS over OML immediately.
2017-02-07 18:53:38 +03:00
245 changed files with 11504 additions and 28288 deletions

20
debian/changelog vendored
View File

@@ -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
View File

@@ -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
View 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
View 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
View File

@@ -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
View 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
View File

@@ -0,0 +1 @@
../sv/reg-proxy

1
etc/service/ussd-proxy Symbolic link
View File

@@ -0,0 +1 @@
../sv/ussd-proxy/

4
etc/sv/reg-proxy/log/run Executable file
View 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
View 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
View 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
View 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
View 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
View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 \

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -1,6 +0,0 @@
#pragma once
enum nsap_addr_enc {
NSAP_ADDR_ENC_X213,
NSAP_ADDR_ENC_V4RAW,
};

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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__)

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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 */

View 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 */

View 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 */

View 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 */

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View 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 */

View 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);

View 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 */

View 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 */

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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();

View File

@@ -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);

View File

@@ -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)

View File

@@ -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:

View File

@@ -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;
}

View File

@@ -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(&gtphub_log_info);
gtphub_vty_init(hub, cfg);
rate_ctr_init(osmo_gtphub_ctx);

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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 \

View File

@@ -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) |

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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) \

View File

@@ -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;

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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