mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 13:03:33 +00:00
Compare commits
27 Commits
1.0.1
...
fairwaves/
Author | SHA1 | Date | |
---|---|---|---|
|
e77bfb9e22 | ||
|
3ef203ee0a | ||
|
85a304a4fe | ||
|
8a62c50218 | ||
|
78de2aea7b | ||
|
dc6da14be3 | ||
|
0a8e5f4f86 | ||
|
06d0c6da80 | ||
|
0855c024c4 | ||
|
8543953496 | ||
|
3cc7d2b50d | ||
|
0b19f7af80 | ||
|
3ec78f0d49 | ||
|
a9c6d44035 | ||
|
90459a0507 | ||
|
ade03887bb | ||
|
d38e96df2a | ||
|
8d0f77c8ff | ||
|
4e3a267055 | ||
|
3b1cd6dd81 | ||
|
1a3dd31c3b | ||
|
dfd8d0cde0 | ||
|
f4d336e2c4 | ||
|
ce7437e27c | ||
|
b402dad7f1 | ||
|
39494b8751 | ||
|
bc1aaacf74 |
@@ -1,3 +0,0 @@
|
||||
[gerrit]
|
||||
host=gerrit.osmocom.org
|
||||
project=openbsc
|
12
.mailmap
12
.mailmap
@@ -1,12 +0,0 @@
|
||||
Harald Welte <laforge@gnumonks.org>
|
||||
Harald Welte <laforge@gnumonks.org> <laflocal@hanuman.gnumonks.org>
|
||||
Harald Welte <laforge@gnumonks.org> <laflocal@goeller.de.gnumonks.org>
|
||||
Holger Hans Peter Freyther <holger@moiji-mobile.com> <zecke@selfish.org>
|
||||
Holger Hans Peter Freyther <holger@moiji-mobile.com> <ich@tamarin.(none)>
|
||||
Holger Hans Peter Freyther <holgre@moiji-mobile.com> <holger@freyther.de>
|
||||
Andreas Eversberg <jolly@eversberg.eu>
|
||||
Andreas Eversberg <jolly@eversberg.eu> <Andreas.Eversberg@versatel.de>
|
||||
Andreas Eversberg <jolly@eversberg.eu> <root@nuedel.(none)>
|
||||
Pablo Neira Ayuso <pablo@soleta.eu> <pablo@gnumonks.org>
|
||||
Max Suraev <msuraev@sysmocom.de>
|
||||
Tom Tsou <tom.tsou@ettus.com> <tom@tsou.cc>
|
@@ -1,52 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
base="$PWD"
|
||||
deps="$base/deps"
|
||||
inst="$deps/install"
|
||||
export deps inst
|
||||
|
||||
mkdir "$deps" || true
|
||||
rm -rf "$inst"
|
||||
|
||||
osmo-build-dep.sh libosmocore "" ac_cv_path_DOXYGEN=false
|
||||
|
||||
"$deps"/libosmocore/contrib/verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]")
|
||||
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
if [ "x$IU" = "x--enable-iu" ]; then
|
||||
sccp_branch="old_sua"
|
||||
fi
|
||||
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-netif
|
||||
osmo-build-dep.sh libosmo-sccp $sccp_branch
|
||||
PARALLEL_MAKE="" osmo-build-dep.sh libsmpp34
|
||||
osmo-build-dep.sh openggsn
|
||||
|
||||
if [ "x$IU" = "x--enable-iu" ]; then
|
||||
osmo-build-dep.sh libasn1c
|
||||
#osmo-build-dep.sh asn1c aper-prefix # only needed for make regen in osmo-iuh
|
||||
osmo-build-dep.sh osmo-iuh
|
||||
fi
|
||||
|
||||
set +x
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo " =============================== openbsc ==============================="
|
||||
echo
|
||||
set -x
|
||||
|
||||
cd "$base"
|
||||
cd openbsc
|
||||
autoreconf --install --force
|
||||
./configure --enable-osmo-bsc --enable-nat $SMPP $MGCP $IU --enable-vty-tests --enable-external-tests
|
||||
$MAKE $PARALLEL_MAKE
|
||||
LD_LIBRARY_PATH="$inst/lib" $MAKE check \
|
||||
|| cat-testlogs.sh
|
||||
LD_LIBRARY_PATH="$inst/lib" $MAKE distcheck \
|
||||
|| cat-testlogs.sh
|
17
debian/changelog
vendored
17
debian/changelog
vendored
@@ -1,12 +1,17 @@
|
||||
openbsc (0.15.1) UNRELEASED; urgency=medium
|
||||
openbsc (0.14.0-fw.2) trusty; urgency=low
|
||||
|
||||
* Move forward toward a new release.
|
||||
* Prevent SGSN starting with 'auth-policy remote' when no 'gsup remote-*' are configured.
|
||||
Note: such configs are broken without extra workarounds anyway.
|
||||
* Added a way to always route SMS through SMPP.
|
||||
|
||||
-- Holger Hans Peter Freyther <holger@moiji-mobile.com> Tue, 24 May 2016 23:14:31 +0200
|
||||
-- Ivan Kluchnikov <kluchnikovi@gmail.com> Thu, 20 Aug 2015 20:17:42 +0300
|
||||
|
||||
openbsc (0.14.0) unstable; urgency=low
|
||||
openbsc (0.14.0-fw.1) trusty; urgency=low
|
||||
|
||||
* Added osmocom-meas-utils package.
|
||||
* Others enhancements and fixes.
|
||||
|
||||
-- Ivan Kluchnikov <kluchnikovi@gmail.com> Mon, 27 Jul 2015 13:56:58 +0300
|
||||
|
||||
openbsc (0.14.0) UNRELEASED; urgency=low
|
||||
|
||||
* New upstream tag and additional patches.
|
||||
|
||||
|
2
debian/compat
vendored
2
debian/compat
vendored
@@ -1 +1 @@
|
||||
9
|
||||
7
|
||||
|
169
debian/control
vendored
169
debian/control
vendored
@@ -1,128 +1,24 @@
|
||||
Source: openbsc
|
||||
Maintainer: Harald Welte <laforge@gnumonks.org>
|
||||
Section: net
|
||||
Priority: optional
|
||||
Build-Depends: debhelper (>= 9),
|
||||
autotools-dev,
|
||||
autoconf-archive,
|
||||
pkg-config,
|
||||
libgtp-dev,
|
||||
libosmocore-dev,
|
||||
libosmo-sccp-dev,
|
||||
libdbi0-dev,
|
||||
dh-autoreconf,
|
||||
libosmo-abis-dev,
|
||||
libosmo-netif-dev,
|
||||
libdbd-sqlite3,
|
||||
libpcap-dev,
|
||||
libssl-dev,
|
||||
libc-ares-dev,
|
||||
libsmpp34-dev
|
||||
Standards-Version: 3.9.8
|
||||
Maintainer: Harald Welte <laforge@gnumonks.org>
|
||||
Build-Depends: debhelper (>= 7.0.0~), autotools-dev, pkg-config, libosmocore-dev, libosmo-sccp-dev, libdbi0-dev, dh-autoreconf, libosmo-abis-dev, libosmo-netif-dev, libdbd-sqlite3, libpcap-dev, libsmpp34-dev, libcdk5-dev, libsqlite3-dev
|
||||
Standards-Version: 3.8.4
|
||||
Homepage: http://openbsc.osmocom.org/
|
||||
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},
|
||||
${misc:Depends},
|
||||
libdbd-sqlite3
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libdbd-sqlite3
|
||||
Description: GSM Network-in-a-Box, implements BSC, MSC, SMSC, HLR, VLR
|
||||
This is the Network-in-a-Box version of OpenBSC. It has all the GSM network
|
||||
components bundled together. When using osmocom-nitb, there is no need for a
|
||||
Mobile Switching Center (MSC) which is needed when using osmocom-bsc.
|
||||
All the GSM network components bundled together.
|
||||
|
||||
Package: osmocom-ipaccess-utils
|
||||
Package: osmocom-meas-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}
|
||||
Description: Header file needed by tools tightly integrated
|
||||
Some other programs depend on gsm_data_shared.h and gsm_data_shared.c
|
||||
from OpenBSC. This package installs these files to your file system so
|
||||
that the other packages can build-depend on this package.
|
||||
.
|
||||
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
|
||||
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
|
||||
@@ -132,50 +28,11 @@ 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
|
||||
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
|
||||
|
||||
Package: osmocom-sgsn-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
|
||||
Make debugging possible
|
||||
|
158
debian/copyright
vendored
158
debian/copyright
vendored
@@ -1,137 +1,47 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: OpenBSC
|
||||
Source: http://openbsc.osmocom.org/
|
||||
This work was packaged for Debian by:
|
||||
|
||||
Files: *
|
||||
Copyright: 2008-2015 Harald Welte <laforge@gnumonks.org>
|
||||
2008-2015 Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
2009-2015 On-Waves
|
||||
2008 Jan Luebbe <jluebbe@debian.org>
|
||||
2008,2010-2011 Daniel Willmann <daniel@totalueberwachung.de>
|
||||
2009,2011,2013 Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
||||
2009,2011 Dieter Spaar <spaar@mirider.augusta.de>
|
||||
2009 Mike Haben <michael.haben@btinternet.com>
|
||||
2010 Sylvain Munaut <246tnt@gmail.com>
|
||||
2012-2013 Pablo Neira Ayuso <pablo@gnumonks.org>
|
||||
2013-2015 Sysmocom s.f.m.c. GmbH (Jacob Erlbeck)
|
||||
2014 Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
|
||||
License: AGPL-3+
|
||||
Comment: Contributions by Stefan Schmidt <stefan@datenfreihafen.org> as well
|
||||
Harald Welte <laforge@gnumonks.org> on Tue, 24 Aug 2010 10:55:04 +0200
|
||||
|
||||
Files: wireshark/0001-abis_oml.patch
|
||||
wireshark/0002-ericsson_rbs2409.patch
|
||||
wireshark/0003-lucent-hnb.patch
|
||||
wireshark/0005-rsl-hsl.patch
|
||||
Copyright: 1998 Gerald Combs <gerald@wireshark.org>
|
||||
2007,2011 Anders Broman <anders.broman@ericsson.com>
|
||||
2009 Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
2009-2011 Harald Welte <laforge@gnumonks.org>
|
||||
License: GPL-2+
|
||||
It was downloaded from:
|
||||
|
||||
Files: openbsc/include/mISDNif.h
|
||||
Copyright: 2008 Karsten Keil <kkeil@novell.com>
|
||||
License: LGPL-2.1
|
||||
git://bs11-abis.gnumonks.org/openbsc.git
|
||||
|
||||
Files: openbsc/src/libmgcp/g711common.h
|
||||
Copyright: 2009 Abramo Bagnara <abramo@alsa-project.org>
|
||||
License: GPL-2+
|
||||
Upstream Authors:
|
||||
|
||||
Files: openbsc/git-version-gen
|
||||
Copyright: 2007-2010 Free Software Foundation
|
||||
License: GPL-3+
|
||||
Harald Welte <laforge@gnumonks.org>
|
||||
Dieter Spaar <spaar@mirider.augusta.de>
|
||||
Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
Sylvain Munaut <tnt@246tNt.com>
|
||||
Daniel Willmann <daniel@totalueberwachung.de>
|
||||
Jan Luebbe <jluebbe@debian.org>
|
||||
Mike Haben <michael.haben@btinternet.com>
|
||||
Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
||||
|
||||
Files: openbsc/osmoappdesc.py
|
||||
openbsc/tests/smpp_test_runner.py
|
||||
openbsc/tests/ctrl_test_runner.py
|
||||
openbsc/tests/vty_test_runner.py
|
||||
Copyright: 2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
|
||||
2013 Jacob Erlbeck <jerlbeck@sysmocom.de>
|
||||
2013-2014 Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
License: GPL-3+
|
||||
Copyright:
|
||||
|
||||
Files: openbsc/src/libbsc/bsc_ctrl_lookup.c
|
||||
Copyright: 2010-2011 Daniel Willmann <daniel@totalueberwachung.de>
|
||||
2010-2011 On-Waves
|
||||
License: GPL-2+
|
||||
Copyright (C) 2008-2010 Harald Welte <laforge@gnumonks.org>
|
||||
Copyright (C) 2008-2009 Dieter Spaar <spaar@mirider.augusta.de>
|
||||
Copyright (C) 2008-2010 Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
Copyright (C) 2009-2010 Sylvain Munaut <tnt@246tNt.com>
|
||||
Copyright (C) 2009-2010 On-Waves
|
||||
Copyright (C) 2008 Daniel Willmann <daniel@totalueberwachung.de>
|
||||
Copyright (C) 2008 Jan Luebbe <jluebbe@debian.org>
|
||||
Copyright (C) 2009 by Mike Haben <michael.haben@btinternet.com>
|
||||
Copyright (C) 2009 Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
||||
|
||||
Files: openbsc/src/libmsc/mncc_sock.c
|
||||
openbsc/src/libmsc/mncc_builtin.c
|
||||
Copyright: 2008-2010 Harald Welte <laforge@gnumonks.org>
|
||||
2009 Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
||||
2012 Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
License: GPL-2+
|
||||
License:
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2012-2015 Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
2016 Ruben Undheim <ruben.undheim@gmail.com>
|
||||
License: GPL-2+
|
||||
GNU General Public License, Version 2 or later
|
||||
|
||||
The Debian packaging is:
|
||||
|
||||
License: AGPL-3+
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>
|
||||
|
||||
# Please chose a license for your packaging work. If the program you package
|
||||
# uses a mainstream license, using the same license is the safest choice.
|
||||
# Please avoid to pick license terms that are more restrictive than the
|
||||
# packaged work, as it may make Debian's contributions unacceptable upstream.
|
||||
# If you just want it to be GPL version 3, leave the following lines in.
|
||||
|
||||
License: GPL-2+
|
||||
This package is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or (at
|
||||
your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public
|
||||
License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
|
||||
License: GPL-3+
|
||||
This package is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at
|
||||
your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public
|
||||
License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
|
||||
|
||||
License: LGPL-2.1
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; version
|
||||
2.1 of the License.
|
||||
.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License version 2.1 can be found in
|
||||
"/usr/share/common-licenses/LGPL-2.1".
|
||||
and is licensed under the GPL version 3,
|
||||
see "/usr/share/common-licenses/GPL-3".
|
||||
|
2
debian/docs
vendored
2
debian/docs
vendored
@@ -1 +1 @@
|
||||
openbsc/README
|
||||
README
|
||||
|
4
debian/openbsc-dev.install
vendored
4
debian/openbsc-dev.install
vendored
@@ -1,4 +0,0 @@
|
||||
openbsc/include/openbsc/gsm_data_shared.h usr/src/osmocom/openbsc/openbsc/include/openbsc/
|
||||
openbsc/include/openbsc/common_cs.h usr/src/osmocom/openbsc/openbsc/include/openbsc/
|
||||
openbsc/src/libcommon/gsm_data_shared.c usr/src/osmocom/openbsc/openbsc/src/libcommon/
|
||||
usr/lib/*/pkgconfig/openbsc.pc
|
2
debian/osmo-gtphub.default
vendored
2
debian/osmo-gtphub.default
vendored
@@ -1,2 +0,0 @@
|
||||
CONFIG_FILE="/etc/osmocom/osmo-gtphub.cfg"
|
||||
|
1
debian/osmo-gtphub.examples
vendored
1
debian/osmo-gtphub.examples
vendored
@@ -1 +0,0 @@
|
||||
openbsc/doc/examples/osmo-gtphub
|
150
debian/osmo-gtphub.init
vendored
150
debian/osmo-gtphub.init
vendored
@@ -1,150 +0,0 @@
|
||||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: osmo-gtphub
|
||||
# Required-Start: $network $local_fs
|
||||
# Required-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Osmocom GTP hub
|
||||
# Description: Osmocom GTP hub
|
||||
### END INIT INFO
|
||||
|
||||
# Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
NAME=osmo-gtphub # Introduce the short server's name here
|
||||
DESC="Osmocom GTP hub" # Introduce a short description here
|
||||
DAEMON=/usr/bin/osmo-gtphub # Introduce the server's location here
|
||||
SCRIPTNAME=/etc/init.d/osmo-gtphub
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x $DAEMON ] || exit 0
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/osmo-gtphub ] && . /etc/default/osmo-gtphub
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
DAEMON_ARGS="$DAEMON_ARGS -D -c $CONFIG_FILE"
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --exec $DAEMON -- \
|
||||
$DAEMON_ARGS \
|
||||
|| return 2
|
||||
# Add code here, if necessary, that waits for the process to be ready
|
||||
# to handle requests from services started subsequently which depend
|
||||
# on this one. As a last resort, sleep for some time.
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
1
debian/osmo-gtphub.install
vendored
1
debian/osmo-gtphub.install
vendored
@@ -1 +0,0 @@
|
||||
/usr/bin/osmo-gtphub
|
2
debian/osmocom-ipaccess-utils.install
vendored
2
debian/osmocom-ipaccess-utils.install
vendored
@@ -1,3 +1,3 @@
|
||||
/usr/bin/ipaccess-config
|
||||
/usr/bin/abisip-find
|
||||
/usr/bin/ipaccess-find
|
||||
/usr/bin/ipaccess-proxy
|
||||
|
4
debian/osmocom-meas-utils.install
vendored
Normal file
4
debian/osmocom-meas-utils.install
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/usr/bin/osmo-meas-udp2db
|
||||
/usr/bin/osmo-meas-pcap2db
|
||||
/usr/bin/meas_vis
|
||||
/usr/bin/meas_json
|
1
debian/osmocom-nitb.install
vendored
1
debian/osmocom-nitb.install
vendored
@@ -1,2 +1 @@
|
||||
/usr/bin/osmo-nitb
|
||||
openbsc/contrib/*.py usr/bin/
|
24
debian/rules
vendored
24
debian/rules
vendored
@@ -1,4 +1,14 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
#
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
#
|
||||
# Modified to make a template file for a multi-binary package with separated
|
||||
# build-arch and build-indep targets by Bill Allombert 2001
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
@@ -7,26 +17,20 @@ DEBIAN := $(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2)
|
||||
DEBVERS := $(shell echo '$(DEBIAN)' | cut -d- -f1)
|
||||
VERSION := $(shell echo '$(DEBVERS)' | sed -e 's/[+-].*//' -e 's/~//g')
|
||||
|
||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
export DEB_BUILD_HARDENING=1
|
||||
|
||||
%:
|
||||
dh $@ --sourcedirectory=openbsc --with autoreconf
|
||||
dh --sourcedirectory=openbsc --with autoreconf $@
|
||||
|
||||
# This is needed for debian stable (squeeze)
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
144
linux-kernel/linux-2.6.27.4-misdn-abis.diff
Normal file
144
linux-kernel/linux-2.6.27.4-misdn-abis.diff
Normal file
@@ -0,0 +1,144 @@
|
||||
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c linux-2.6.27.4/drivers/isdn/mISDN/layer2.c
|
||||
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c 2008-10-26 00:05:07.000000000 +0200
|
||||
+++ linux-2.6.27.4/drivers/isdn/mISDN/layer2.c 2008-12-23 16:16:29.000000000 +0100
|
||||
@@ -94,8 +94,10 @@
|
||||
struct layer2 *l2 = fi->userdata;
|
||||
va_list va;
|
||||
|
||||
+#if 0
|
||||
if (!(*debug & DEBUG_L2_FSM))
|
||||
return;
|
||||
+#endif
|
||||
va_start(va, fmt);
|
||||
printk(KERN_DEBUG "l2 (tei %d): ", l2->tei);
|
||||
vprintk(fmt, va);
|
||||
@@ -882,6 +884,8 @@
|
||||
l2->va = 0;
|
||||
l2->vr = 0;
|
||||
l2->sow = 0;
|
||||
+ l2->sapi = skb->data[0] >> 2;
|
||||
+ set_channel_address(&l2->ch, l2->sapi, l2->tei);
|
||||
clear_exception(l2);
|
||||
send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
|
||||
mISDN_FsmChangeState(fi, ST_L2_7);
|
||||
@@ -898,6 +902,7 @@
|
||||
struct layer2 *l2 = fi->userdata;
|
||||
struct sk_buff *skb = arg;
|
||||
|
||||
+ printk(KERN_DEBUG "l2_send_UA()\n");
|
||||
send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
|
||||
}
|
||||
|
||||
@@ -931,6 +936,8 @@
|
||||
l2->va = 0;
|
||||
l2->vr = 0;
|
||||
l2->sow = 0;
|
||||
+ l2->sapi = skb->data[0] >> 2;
|
||||
+ set_channel_address(&l2->ch, l2->sapi, l2->tei);
|
||||
mISDN_FsmChangeState(fi, ST_L2_7);
|
||||
stop_t200(l2, 3);
|
||||
mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
|
||||
@@ -982,6 +989,8 @@
|
||||
} else if (l2->vs != l2->va) {
|
||||
skb_queue_purge(&l2->i_queue);
|
||||
pr = DL_ESTABLISH_IND;
|
||||
+ //l2->sapi = skb->data[0] >> 2;
|
||||
+ //set_channel_address(&l2->ch, l2->sapi, l2->tei);
|
||||
}
|
||||
stop_t200(l2, 5);
|
||||
l2->vr = 0;
|
||||
@@ -1841,11 +1850,14 @@
|
||||
u_int l;
|
||||
int c = 0;
|
||||
|
||||
+ printk(KERN_DEBUG "ph_data_indication 0x%x 0x%x 0x%x\n", datap[0], datap[1], datap[2]);
|
||||
+
|
||||
l = l2addrsize(l2);
|
||||
if (skb->len <= l) {
|
||||
mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
|
||||
return ret;
|
||||
}
|
||||
+#if 0
|
||||
if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
|
||||
psapi = *datap++;
|
||||
ptei = *datap++;
|
||||
@@ -1875,6 +1887,7 @@
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
+#endif
|
||||
datap += l;
|
||||
if (!(*datap & 1)) { /* I-Frame */
|
||||
c = iframe_error(l2, skb);
|
||||
@@ -1890,6 +1903,7 @@
|
||||
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
|
||||
} else if (IsSABME(datap, l2)) {
|
||||
c = unnum_error(l2, skb, CMD);
|
||||
+ printk(KERN_DEBUG "IsSABME() returned true, unnum_error=%d\n", c);
|
||||
if (!c)
|
||||
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
|
||||
} else if (IsUA(datap)) {
|
||||
@@ -2087,7 +2101,7 @@
|
||||
test_and_set_bit(FLG_LAPD, &l2->flag);
|
||||
test_and_set_bit(FLG_LAPD_NET, &l2->flag);
|
||||
test_and_set_bit(FLG_MOD128, &l2->flag);
|
||||
- l2->sapi = 0;
|
||||
+ l2->sapi = 62;
|
||||
l2->maxlen = MAX_DFRAME_LEN;
|
||||
if (test_bit(OPTION_L2_PMX, &options))
|
||||
l2->window = 7;
|
||||
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c linux-2.6.27.4/drivers/isdn/mISDN/tei.c
|
||||
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c 2008-10-26 00:05:07.000000000 +0200
|
||||
+++ linux-2.6.27.4/drivers/isdn/mISDN/tei.c 2008-12-23 16:32:59.000000000 +0100
|
||||
@@ -830,18 +830,29 @@
|
||||
int tei, ri;
|
||||
struct layer2 *l2;
|
||||
|
||||
+ printk(KERN_DEBUG "new tei request: tei=%d\n", dp[3] >> 1);
|
||||
+
|
||||
ri = dp[0] << 8;
|
||||
ri += dp[1];
|
||||
- if (!mgr->up)
|
||||
- goto denied;
|
||||
- tei = get_free_tei(mgr);
|
||||
- if (tei < 0) {
|
||||
- printk(KERN_WARNING "%s:No free tei\n", __func__);
|
||||
+ if (!mgr->up) {
|
||||
+ printk(KERN_DEBUG "mgr->up == NULL\n");
|
||||
goto denied;
|
||||
}
|
||||
+ if (dp[3] != 0xff) {
|
||||
+ /* This is a TEI request according to 3GPP TS 08.56 6.1.11.2 */
|
||||
+ tei = dp[3] >> 1;
|
||||
+ } else {
|
||||
+ tei = get_free_tei(mgr);
|
||||
+ if (tei < 0) {
|
||||
+ printk(KERN_WARNING "%s:No free tei\n", __func__);
|
||||
+ goto denied;
|
||||
+ }
|
||||
+ }
|
||||
l2 = create_new_tei(mgr, tei);
|
||||
- if (!l2)
|
||||
+ if (!l2) {
|
||||
+ printk(KERN_DEBUG "create_new_tei == NULL\n");
|
||||
goto denied;
|
||||
+ }
|
||||
else
|
||||
mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp);
|
||||
return;
|
||||
@@ -1159,12 +1170,14 @@
|
||||
return -ENOTCONN;
|
||||
if (skb->len != 3)
|
||||
return -ENOTCONN;
|
||||
+#if 0
|
||||
if (skb->data[0] != 0)
|
||||
/* only SAPI 0 command */
|
||||
return -ENOTCONN;
|
||||
+#endif
|
||||
if (!(skb->data[1] & 1)) /* invalid EA1 */
|
||||
return -EINVAL;
|
||||
- tei = skb->data[1] >> 0;
|
||||
+ tei = skb->data[1] >> 1;
|
||||
if (tei > 63) /* not a fixed tei */
|
||||
return -ENOTCONN;
|
||||
if ((skb->data[2] & ~0x10) != SABME)
|
486
linux-kernel/linux-2.6.30-hfcmulti-multibts.patch
Normal file
486
linux-kernel/linux-2.6.30-hfcmulti-multibts.patch
Normal file
@@ -0,0 +1,486 @@
|
||||
This experimental patch splits one E1 card into three virtual cards,
|
||||
|
||||
TS 1,2,3,4,5 is card 0
|
||||
TS 6,7,8,9,10 is card 1
|
||||
TS 11,12,13,14 is card 2
|
||||
|
||||
This allows you to run one L2 TEI handler on each of the virtual cards,
|
||||
which is required if you want to run multiple BTS on a single E1 link.
|
||||
|
||||
Thanks to Andreas Eversberg for this patch.
|
||||
|
||||
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
|
||||
index 0c77386..02dd4a1 100644
|
||||
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
|
||||
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
|
||||
@@ -209,14 +209,17 @@ struct hfc_multi {
|
||||
u_long ledstate; /* save last state of leds */
|
||||
int opticalsupport; /* has the e1 board */
|
||||
/* an optical Interface */
|
||||
- int dslot; /* channel # of d-channel (E1) default 16 */
|
||||
+
|
||||
+ u_int bmask[32]; /* bitmask of bchannels for port */
|
||||
+ u_char dnum[32]; /* array of used dchannel numbers for port */
|
||||
+ u_char created[32]; /* what port is created */
|
||||
+ u_int activity[32]; /* if there is any action on this */
|
||||
+ /* port (will be cleared after */
|
||||
+ /* showing led-states) */
|
||||
|
||||
u_long wdcount; /* every 500 ms we need to */
|
||||
/* send the watchdog a signal */
|
||||
u_char wdbyte; /* watchdog toggle byte */
|
||||
- u_int activity[8]; /* if there is any action on this */
|
||||
- /* port (will be cleared after */
|
||||
- /* showing led-states) */
|
||||
int e1_state; /* keep track of last state */
|
||||
int e1_getclock; /* if sync is retrieved from interface */
|
||||
int syncronized; /* keep track of existing sync interface */
|
||||
@@ -233,7 +236,6 @@ struct hfc_multi {
|
||||
* the bch->channel is equvalent to the hfc-channel
|
||||
*/
|
||||
struct hfc_chan chan[32];
|
||||
- u_char created[8]; /* what port is created */
|
||||
signed char slot_owner[256]; /* owner channel of slot */
|
||||
};
|
||||
|
||||
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
|
||||
index e1dab30..4fe2d27 100644
|
||||
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
|
||||
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
|
||||
@@ -1619,8 +1619,8 @@ hfcmulti_leds(struct hfc_multi *hc)
|
||||
* left red: frame sync, but no L1
|
||||
* right green: L2 active
|
||||
*/
|
||||
- if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */
|
||||
- if (hc->chan[hc->dslot].dch->dev.D.protocol
|
||||
+ if (hc->chan[hc->dnum[0]].sync != 2) { /* no frame sync */
|
||||
+ if (hc->chan[hc->dnum[0]].dch->dev.D.protocol
|
||||
!= ISDN_P_NT_E1) {
|
||||
led[0] = 1;
|
||||
led[1] = 1;
|
||||
@@ -2428,55 +2428,56 @@ handle_timer_irq(struct hfc_multi *hc)
|
||||
}
|
||||
}
|
||||
if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
|
||||
- dch = hc->chan[hc->dslot].dch;
|
||||
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
|
||||
+#warning todo: put interface parameters to hc
|
||||
+ dch = hc->chan[hc->dnum[0]].dch;
|
||||
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* LOS */
|
||||
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
|
||||
- if (!temp && hc->chan[hc->dslot].los)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].los)
|
||||
signal_state_up(dch, L1_SIGNAL_LOS_ON,
|
||||
"LOS detected");
|
||||
- if (temp && !hc->chan[hc->dslot].los)
|
||||
+ if (temp && !hc->chan[hc->dnum[0]].los)
|
||||
signal_state_up(dch, L1_SIGNAL_LOS_OFF,
|
||||
"LOS gone");
|
||||
- hc->chan[hc->dslot].los = temp;
|
||||
+ hc->chan[hc->dnum[0]].los = temp;
|
||||
}
|
||||
- if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* AIS */
|
||||
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
|
||||
- if (!temp && hc->chan[hc->dslot].ais)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].ais)
|
||||
signal_state_up(dch, L1_SIGNAL_AIS_ON,
|
||||
"AIS detected");
|
||||
- if (temp && !hc->chan[hc->dslot].ais)
|
||||
+ if (temp && !hc->chan[hc->dnum[0]].ais)
|
||||
signal_state_up(dch, L1_SIGNAL_AIS_OFF,
|
||||
"AIS gone");
|
||||
- hc->chan[hc->dslot].ais = temp;
|
||||
+ hc->chan[hc->dnum[0]].ais = temp;
|
||||
}
|
||||
- if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* SLIP */
|
||||
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
|
||||
- if (!temp && hc->chan[hc->dslot].slip_rx)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].slip_rx)
|
||||
signal_state_up(dch, L1_SIGNAL_SLIP_RX,
|
||||
" bit SLIP detected RX");
|
||||
- hc->chan[hc->dslot].slip_rx = temp;
|
||||
+ hc->chan[hc->dnum[0]].slip_rx = temp;
|
||||
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
|
||||
- if (!temp && hc->chan[hc->dslot].slip_tx)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].slip_tx)
|
||||
signal_state_up(dch, L1_SIGNAL_SLIP_TX,
|
||||
" bit SLIP detected TX");
|
||||
- hc->chan[hc->dslot].slip_tx = temp;
|
||||
+ hc->chan[hc->dnum[0]].slip_tx = temp;
|
||||
}
|
||||
- if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* RDI */
|
||||
temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
|
||||
- if (!temp && hc->chan[hc->dslot].rdi)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].rdi)
|
||||
signal_state_up(dch, L1_SIGNAL_RDI_ON,
|
||||
"RDI detected");
|
||||
- if (temp && !hc->chan[hc->dslot].rdi)
|
||||
+ if (temp && !hc->chan[hc->dnum[0]].rdi)
|
||||
signal_state_up(dch, L1_SIGNAL_RDI_OFF,
|
||||
"RDI gone");
|
||||
- hc->chan[hc->dslot].rdi = temp;
|
||||
+ hc->chan[hc->dnum[0]].rdi = temp;
|
||||
}
|
||||
temp = HFC_inb_nodebug(hc, R_JATT_DIR);
|
||||
- switch (hc->chan[hc->dslot].sync) {
|
||||
+ switch (hc->chan[hc->dnum[0]].sync) {
|
||||
case 0:
|
||||
if ((temp & 0x60) == 0x60) {
|
||||
if (debug & DEBUG_HFCMULTI_SYNC)
|
||||
@@ -2485,10 +2486,10 @@ handle_timer_irq(struct hfc_multi *hc)
|
||||
"in clock sync\n",
|
||||
__func__, hc->id);
|
||||
HFC_outb(hc, R_RX_OFF,
|
||||
- hc->chan[hc->dslot].jitter | V_RX_INIT);
|
||||
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
|
||||
HFC_outb(hc, R_TX_OFF,
|
||||
- hc->chan[hc->dslot].jitter | V_RX_INIT);
|
||||
- hc->chan[hc->dslot].sync = 1;
|
||||
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
|
||||
+ hc->chan[hc->dnum[0]].sync = 1;
|
||||
goto check_framesync;
|
||||
}
|
||||
break;
|
||||
@@ -2499,7 +2500,7 @@ handle_timer_irq(struct hfc_multi *hc)
|
||||
"%s: (id=%d) E1 "
|
||||
"lost clock sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 0;
|
||||
+ hc->chan[hc->dnum[0]].sync = 0;
|
||||
break;
|
||||
}
|
||||
check_framesync:
|
||||
@@ -2510,7 +2511,7 @@ check_framesync:
|
||||
"%s: (id=%d) E1 "
|
||||
"now in frame sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 2;
|
||||
+ hc->chan[hc->dnum[0]].sync = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@@ -2520,7 +2521,7 @@ check_framesync:
|
||||
"%s: (id=%d) E1 lost "
|
||||
"clock & frame sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 0;
|
||||
+ hc->chan[hc->dnum[0]].sync = 0;
|
||||
break;
|
||||
}
|
||||
temp = HFC_inb_nodebug(hc, R_SYNC_STA);
|
||||
@@ -2530,7 +2531,7 @@ check_framesync:
|
||||
"%s: (id=%d) E1 "
|
||||
"lost frame sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 1;
|
||||
+ hc->chan[hc->dnum[0]].sync = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2746,7 +2747,8 @@ hfcmulti_interrupt(int intno, void *dev_id)
|
||||
if (r_irq_misc & V_STA_IRQ) {
|
||||
if (hc->ctype == HFC_TYPE_E1) {
|
||||
/* state machine */
|
||||
- dch = hc->chan[hc->dslot].dch;
|
||||
+#warning todo
|
||||
+ dch = hc->chan[hc->dnum[0]].dch;
|
||||
e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
|
||||
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
|
||||
&& hc->e1_getclock) {
|
||||
@@ -2768,7 +2770,15 @@ hfcmulti_interrupt(int intno, void *dev_id)
|
||||
}
|
||||
dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
|
||||
& 0x7;
|
||||
+#warning todo hack!!! broadcast state change!!!
|
||||
+ dch = hc->chan[hc->dnum[0]].dch;
|
||||
schedule_event(dch, FLG_PHCHANGE);
|
||||
+ dch = hc->chan[hc->dnum[1]].dch;
|
||||
+ dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
|
||||
+ & 0x7;
|
||||
+ schedule_event(dch, FLG_PHCHANGE);
|
||||
+
|
||||
+
|
||||
if (debug & DEBUG_HFCMULTI_STATE)
|
||||
printk(KERN_DEBUG
|
||||
"%s: E1 (id=%d) newstate %x\n",
|
||||
@@ -3851,31 +3861,35 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "%s: entered\n", __func__);
|
||||
|
||||
+ i = dch->slot;
|
||||
+ pt = hc->chan[i].port;
|
||||
if (hc->ctype == HFC_TYPE_E1) {
|
||||
- hc->chan[hc->dslot].slot_tx = -1;
|
||||
- hc->chan[hc->dslot].slot_rx = -1;
|
||||
- hc->chan[hc->dslot].conf = -1;
|
||||
- if (hc->dslot) {
|
||||
- mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,
|
||||
+ /* E1 */
|
||||
+#warning todo: don''t do it if dnum == 0
|
||||
+ hc->chan[hc->dnum[pt]].slot_tx = -1;
|
||||
+ hc->chan[hc->dnum[pt]].slot_rx = -1;
|
||||
+ hc->chan[hc->dnum[pt]].conf = -1;
|
||||
+ if (hc->dnum[pt]) {
|
||||
+ mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
|
||||
-1, 0, -1, 0);
|
||||
dch->timer.function = (void *) hfcmulti_dbusy_timer;
|
||||
dch->timer.data = (long) dch;
|
||||
init_timer(&dch->timer);
|
||||
}
|
||||
for (i = 1; i <= 31; i++) {
|
||||
- if (i == hc->dslot)
|
||||
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
|
||||
continue;
|
||||
hc->chan[i].slot_tx = -1;
|
||||
hc->chan[i].slot_rx = -1;
|
||||
hc->chan[i].conf = -1;
|
||||
mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
|
||||
}
|
||||
- /* E1 */
|
||||
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
|
||||
+#warning todo (global)
|
||||
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[pt]].cfg)) {
|
||||
HFC_outb(hc, R_LOS0, 255); /* 2 ms */
|
||||
HFC_outb(hc, R_LOS1, 255); /* 512 ms */
|
||||
}
|
||||
- if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[pt]].cfg)) {
|
||||
HFC_outb(hc, R_RX0, 0);
|
||||
hc->hw.r_tx0 = 0 | V_OUT_EN;
|
||||
} else {
|
||||
@@ -3888,12 +3902,12 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
HFC_outb(hc, R_TX_FR0, 0x00);
|
||||
HFC_outb(hc, R_TX_FR1, 0xf8);
|
||||
|
||||
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
|
||||
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
|
||||
HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
|
||||
|
||||
HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
|
||||
|
||||
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
|
||||
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
|
||||
HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
|
||||
|
||||
if (dch->dev.D.protocol == ISDN_P_NT_E1) {
|
||||
@@ -3957,7 +3971,7 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
plxsd_checksync(hc, 0);
|
||||
}
|
||||
} else {
|
||||
- i = dch->slot;
|
||||
+ /* ST */
|
||||
hc->chan[i].slot_tx = -1;
|
||||
hc->chan[i].slot_rx = -1;
|
||||
hc->chan[i].conf = -1;
|
||||
@@ -3973,8 +3987,6 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
hc->chan[i - 1].slot_rx = -1;
|
||||
hc->chan[i - 1].conf = -1;
|
||||
mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
|
||||
- /* ST */
|
||||
- pt = hc->chan[i].port;
|
||||
/* select interface */
|
||||
HFC_outb(hc, R_ST_SEL, pt);
|
||||
/* undocumented: delay after R_ST_SEL */
|
||||
@@ -4557,6 +4569,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
|
||||
}
|
||||
/* free channels */
|
||||
for (i = 0; i <= 31; i++) {
|
||||
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
|
||||
+ continue;
|
||||
if (hc->chan[i].bch) {
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG
|
||||
@@ -4680,12 +4694,13 @@ release_card(struct hfc_multi *hc)
|
||||
}
|
||||
|
||||
static int
|
||||
-init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
+init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
|
||||
{
|
||||
struct dchannel *dch;
|
||||
struct bchannel *bch;
|
||||
int ch, ret = 0;
|
||||
char name[MISDN_MAX_IDLEN];
|
||||
+ int bcount = 0;
|
||||
|
||||
dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
|
||||
if (!dch)
|
||||
@@ -4698,13 +4713,12 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
|
||||
dch->dev.D.send = handle_dmsg;
|
||||
dch->dev.D.ctrl = hfcm_dctrl;
|
||||
- dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
|
||||
- dch->slot = hc->dslot;
|
||||
- hc->chan[hc->dslot].dch = dch;
|
||||
- hc->chan[hc->dslot].port = 0;
|
||||
- hc->chan[hc->dslot].nt_timer = -1;
|
||||
+ dch->slot = hc->dnum[pt];
|
||||
+ hc->chan[hc->dnum[pt]].dch = dch;
|
||||
+ hc->chan[hc->dnum[pt]].port = pt;
|
||||
+ hc->chan[hc->dnum[pt]].nt_timer = -1;
|
||||
for (ch = 1; ch <= 31; ch++) {
|
||||
- if (ch == hc->dslot) /* skip dchannel */
|
||||
+ if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
|
||||
continue;
|
||||
bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
|
||||
if (!bch) {
|
||||
@@ -4733,7 +4747,10 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
hc->chan[ch].bch = bch;
|
||||
hc->chan[ch].port = 0;
|
||||
set_channelmap(bch->nr, dch->dev.channelmap);
|
||||
+ bcount++;
|
||||
}
|
||||
+ dch->dev.nrbchan = bcount;
|
||||
+#warning todo: must be set globally, and must be a seperate function
|
||||
/* set optical line type */
|
||||
if (port[Port_cnt] & 0x001) {
|
||||
if (!m->opticalsupport) {
|
||||
@@ -4749,7 +4766,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
__func__,
|
||||
HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_OPTICAL,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
}
|
||||
/* set LOS report */
|
||||
@@ -4759,7 +4776,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"LOS report: card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_LOS,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set AIS report */
|
||||
if (port[Port_cnt] & 0x008) {
|
||||
@@ -4768,7 +4785,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"AIS report: card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_AIS,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set SLIP report */
|
||||
if (port[Port_cnt] & 0x010) {
|
||||
@@ -4778,7 +4795,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_SLIP,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set RDI report */
|
||||
if (port[Port_cnt] & 0x020) {
|
||||
@@ -4788,7 +4805,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_RDI,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set CRC-4 Mode */
|
||||
if (!(port[Port_cnt] & 0x100)) {
|
||||
@@ -4797,7 +4814,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
" card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_CRC4,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
} else {
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "%s: PORT turn off CRC4"
|
||||
@@ -4829,20 +4846,23 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
}
|
||||
/* set elastic jitter buffer */
|
||||
if (port[Port_cnt] & 0x3000) {
|
||||
- hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;
|
||||
+ hc->chan[hc->dnum[pt]].jitter = (port[Port_cnt]>>12) & 0x3;
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG
|
||||
"%s: PORT set elastic "
|
||||
"buffer to %d: card(%d) port(%d)\n",
|
||||
- __func__, hc->chan[hc->dslot].jitter,
|
||||
+ __func__, hc->chan[hc->dnum[pt]].jitter,
|
||||
HFC_cnt + 1, 1);
|
||||
} else
|
||||
- hc->chan[hc->dslot].jitter = 2; /* default */
|
||||
- snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
|
||||
+ hc->chan[hc->dnum[pt]].jitter = 2; /* default */
|
||||
+ if (hc->ports > 1)
|
||||
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d", HFC_cnt + 1, pt+1);
|
||||
+ else
|
||||
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
|
||||
ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
|
||||
if (ret)
|
||||
goto free_chan;
|
||||
- hc->created[0] = 1;
|
||||
+ hc->created[pt] = 1;
|
||||
return ret;
|
||||
free_chan:
|
||||
release_port(hc, dch);
|
||||
@@ -5009,18 +5029,30 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
|
||||
hc->id = HFC_cnt;
|
||||
hc->pcm = pcm[HFC_cnt];
|
||||
hc->io_mode = iomode[HFC_cnt];
|
||||
+#warning todo: rework module parameters for customizing e1 fragments.... yea, let''s call it: fragments
|
||||
if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {
|
||||
- hc->dslot = 0;
|
||||
+ hc->dnum[0] = 0;
|
||||
printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
|
||||
"31 B-channels\n");
|
||||
}
|
||||
if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32
|
||||
&& hc->ctype == HFC_TYPE_E1) {
|
||||
- hc->dslot = dslot[HFC_cnt];
|
||||
+ hc->dnum[0] = dslot[HFC_cnt];
|
||||
printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
|
||||
"time slot %d\n", dslot[HFC_cnt]);
|
||||
} else
|
||||
- hc->dslot = 16;
|
||||
+ hc->dnum[0] = 16;
|
||||
+
|
||||
+#warning todo HACK!!! just a small map of two "fragments"
|
||||
+ if (hc->ctype == HFC_TYPE_E1) {
|
||||
+ hc->dnum[0] = 1;
|
||||
+ hc->bmask[0] = 0x0000003c;
|
||||
+ hc->dnum[1] = 6;
|
||||
+ hc->bmask[1] = 0x00000780;
|
||||
+ hc->dnum[2] = 11;
|
||||
+ hc->bmask[2] = 0x00007800;
|
||||
+ hc->ports = 3;
|
||||
+ }
|
||||
|
||||
/* set chip specific features */
|
||||
hc->masterclk = -1;
|
||||
@@ -5103,7 +5135,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
|
||||
goto free_card;
|
||||
}
|
||||
if (hc->ctype == HFC_TYPE_E1)
|
||||
- ret_err = init_e1_port(hc, m);
|
||||
+ ret_err = init_e1_port(hc, m, pt);
|
||||
else
|
||||
ret_err = init_multi_port(hc, pt);
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
@@ -5115,10 +5147,14 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
|
||||
if (ret_err) {
|
||||
while (pt) { /* release already registered ports */
|
||||
pt--;
|
||||
- release_port(hc, hc->chan[(pt << 2) + 2].dch);
|
||||
+ if (hc->ctype == HFC_TYPE_E1)
|
||||
+ release_port(hc, hc->chan[hc->dnum[pt]].dch);
|
||||
+ else
|
||||
+ release_port(hc, hc->chan[(pt << 2) + 2].dch);
|
||||
}
|
||||
goto free_card;
|
||||
}
|
||||
+#warning todo: count it right, add additional "fragment" counter...
|
||||
Port_cnt++;
|
||||
}
|
||||
|
19
openbsc/.gitignore
vendored
19
openbsc/.gitignore
vendored
@@ -11,7 +11,6 @@ src/osmo-nitb/osmo-nitb
|
||||
src/osmo-bsc_mgcp/osmo-bsc_mgcp
|
||||
src/osmo-bsc/osmo-bsc
|
||||
src/utils/meas_vis
|
||||
src/utils/meas_json
|
||||
src/utils/osmo-meas-pcap2db
|
||||
src/utils/osmo-meas-udp2db
|
||||
src/utils/smpp_mirror
|
||||
@@ -47,16 +46,14 @@ ltmain.sh
|
||||
hlr.sqlite3
|
||||
src/utils/bs11_config
|
||||
src/ipaccess/ipaccess-config
|
||||
src/ipaccess/abisip-find
|
||||
src/ipaccess/ipaccess-find
|
||||
src/ipaccess/ipaccess-firmware
|
||||
src/ipaccess/ipaccess-proxy
|
||||
src/utils/isdnsync
|
||||
src/nat/bsc_nat
|
||||
src/gprs/osmo-sgsn
|
||||
src/gprs/osmo-gbproxy
|
||||
src/gprs/osmo-gtphub
|
||||
src/osmo-bsc_nat/osmo-bsc_nat
|
||||
src/libcommon/gsup_test_client
|
||||
|
||||
#tests
|
||||
tests/testsuite.dir
|
||||
@@ -80,16 +77,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
|
||||
tests/xid/xid_test
|
||||
tests/sndcp_xid/sndcp_xid_test
|
||||
tests/slhc/slhc_test
|
||||
tests/v42bis/v42bis_test
|
||||
tests/nanobts_omlattr/nanobts_omlattr_test
|
||||
tests/oap/oap_client_test
|
||||
|
||||
tests/atconfig
|
||||
tests/atlocal
|
||||
@@ -97,7 +84,5 @@ tests/package.m4
|
||||
tests/testsuite
|
||||
tests/testsuite.log
|
||||
|
||||
gsn_restart
|
||||
|
||||
src/openbsc.cfg*
|
||||
writtenconfig/
|
||||
gtphub_restart_count
|
||||
|
@@ -5,5 +5,3 @@ Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
Daniel Willmann <daniel@totalueberwachung.de>
|
||||
Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
||||
Sylvain Munaut <246tnt@gmail.com>
|
||||
Jacob Erlbeck <jerlbeck@sysmocom.de>
|
||||
Neels Hofmeyr <nhofmeyr@sysmocom.de>
|
||||
|
@@ -1,25 +1,13 @@
|
||||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
|
||||
## FIXME: automake >= 1.13 or autoconf >= 2.70 provide better suited AC_CONFIG_MACRO_DIRS for configure.ac
|
||||
## remove line below when OE toolchain is updated to version which include those
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
AM_CPPFLAGS = \
|
||||
$(all_includes) \
|
||||
-I$(top_srcdir)/include \
|
||||
$(NULL)
|
||||
|
||||
SUBDIRS = \
|
||||
doc \
|
||||
include \
|
||||
src \
|
||||
tests \
|
||||
$(NULL)
|
||||
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
|
||||
SUBDIRS = doc include src tests
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = openbsc.pc
|
||||
|
||||
BUILT_SOURCES = $(top_srcdir)/.version
|
||||
EXTRA_DIST = git-version-gen osmoappdesc.py .version
|
||||
EXTRA_DIST = git-version-gen osmoappdesc.py
|
||||
$(top_srcdir)/.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
dist-hook:
|
||||
|
@@ -1,39 +1,32 @@
|
||||
About OpenBSC
|
||||
=============
|
||||
|
||||
OpenBSC started as a minimalistic all-in-one implementation of the GSM Network,
|
||||
with particular emphasis on the functionality typically provided by the BSC,
|
||||
MSC, HLR, VLR and SMSC. Today it is a growing suite of libraries and programs,
|
||||
implementing protocol stacks and functional elements, including
|
||||
OpenBSC is a minimalistic implementation of the GSM Network, with
|
||||
particular emphasis on the functionality typically provided by the BSC,
|
||||
MSC, HLR, VLR and SMSC.
|
||||
|
||||
* 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
|
||||
* 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
|
||||
* OsmoGTPHUB - a hub aggregating many GTP links (between SGSN and GGSN)
|
||||
* ipaccess-utils - some tools to discover + configure ip.access nanoBTS
|
||||
* bs11_config - a tool to configure the Siemens BS-11 microBTS
|
||||
|
||||
Various interfaces towards the BTS are supported, among which are:
|
||||
Its currently supported interfaces towards the BTS are:
|
||||
|
||||
* Classic A-bis over E1 using a mISDN based E1 interface. In other
|
||||
words, you can connect existing GSM Base Transceiver Station (BTS)
|
||||
through E1 to OpenBSC. So far, we have made it work with the Siemens BS-11,
|
||||
various Ericsson RBS2xxx BTS models and the Nokia MetroSite.
|
||||
through E1 to OpenBSC. So far, we have only tested the Siemens BS-11
|
||||
Test reports with other BTS are much appreciated!
|
||||
|
||||
* A-bis over IP as used by the ip.access nanoBTS product family as well as
|
||||
the Open Source OsmoBTS software (by the same authors as OpenBSC). OsmoBTS
|
||||
in turn supports various transceiver hardware, including the sysmoBTS
|
||||
product family, as well as SDR transceivers supported by OsmoTRX, such as
|
||||
the UmTRX or USRP boardss.
|
||||
* A-bis over IP as used by the ip.access nanoBTS product family
|
||||
|
||||
* IuCS and IuPS over IP towards an HNB-GW (see osmo-iuh) for UMTS (3G)
|
||||
voice and data links.
|
||||
You can find the project documentation at http://openbsc.gnumonks.org/
|
||||
|
||||
Find OpenBSC online at
|
||||
http://openbsc.osmocom.org/
|
||||
This project is still in its early days, and there are lots of areas where it
|
||||
doesn't behave as per GSM spec.
|
||||
|
||||
Harald Welte <laforge@gnumonks.org>
|
||||
|
||||
|
||||
libosmocore
|
||||
===========
|
||||
|
||||
Please note that as of March 2010, OpenBSC has a dependency to a library
|
||||
called "libosmocore". You can obtain that library from
|
||||
|
||||
git://git.osmocom.org/libosmocore.git
|
||||
|
||||
|
@@ -1,11 +0,0 @@
|
||||
To run the configuration parsing and output (VTY) test suite, first install
|
||||
|
||||
git://git.osmocom.org/python/osmo-python-tests
|
||||
|
||||
and pass the following configure options here:
|
||||
|
||||
./configure --enable-vty-tests --enable-external-tests
|
||||
|
||||
The VTY tests are then included in the standard check target:
|
||||
|
||||
make check
|
@@ -3,9 +3,6 @@ AC_INIT([openbsc],
|
||||
m4_esyscmd([./git-version-gen .tarball-version]),
|
||||
[openbsc@lists.osmocom.org])
|
||||
|
||||
dnl *This* is the root dir, even if an install-sh exists in ../ or ../../
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
|
||||
AM_INIT_AUTOMAKE([dist-bzip2])
|
||||
AC_CONFIG_TESTDIR(tests)
|
||||
|
||||
@@ -16,33 +13,22 @@ dnl checks for programs
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
LT_INIT
|
||||
|
||||
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
|
||||
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
|
||||
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
|
||||
AC_MSG_WARN([You need to install pkg-config])
|
||||
fi
|
||||
PKG_PROG_PKG_CONFIG([0.20])
|
||||
|
||||
dnl check for AX_CHECK_COMPILE_FLAG
|
||||
m4_ifdef([AX_CHECK_COMPILE_FLAG], [], [
|
||||
AC_MSG_ERROR([Please install autoconf-archive; re-run 'autoreconf -fi' for it to take effect.])
|
||||
])
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl checks for libraries
|
||||
AC_SEARCH_LIBS(crypt, crypt,
|
||||
[LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
|
||||
AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""])
|
||||
AC_SUBST(LIBRARY_DL)
|
||||
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.9.5)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.6.4)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.9.5)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.2.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 0.6.4)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.1)
|
||||
PKG_CHECK_MODULES(LIBCRYPTO, libcrypto >= 0.9.5)
|
||||
|
||||
# Enabke/disable the NAT?
|
||||
AC_ARG_ENABLE([nat], [AS_HELP_STRING([--enable-nat], [Build the BSC NAT. Requires SCCP])],
|
||||
@@ -78,8 +64,7 @@ AC_ARG_ENABLE([mgcp-transcoding], [AS_HELP_STRING([--enable-mgcp-transcoding], [
|
||||
AC_ARG_WITH([g729], [AS_HELP_STRING([--with-g729], [Enable G.729 encoding/decoding.])], [osmo_ac_with_g729="$withval"],[osmo_ac_with_g729="no"])
|
||||
|
||||
if test "$osmo_ac_mgcp_transcoding" = "yes" ; then
|
||||
AC_SEARCH_LIBS([gsm_create], [gsm], [LIBRARY_GSM="$LIBS";LIBS=""], [AC_MSG_ERROR([--enable-mgcp-transcoding: cannot find usable libgsm])])
|
||||
AC_SUBST(LIBRARY_GSM)
|
||||
AC_SEARCH_LIBS(gsm_create, gsm)
|
||||
if test "$osmo_ac_with_g729" = "yes" ; then
|
||||
PKG_CHECK_MODULES(LIBBCG729, libbcg729 >= 0.1, [AC_DEFINE([HAVE_BCG729], [1], [Use bgc729 decoder/encoder])])
|
||||
fi
|
||||
@@ -88,43 +73,17 @@ fi
|
||||
AM_CONDITIONAL(BUILD_MGCP_TRANSCODING, test "x$osmo_ac_mgcp_transcoding" = "xyes")
|
||||
AC_SUBST(osmo_ac_mgcp_transcoding)
|
||||
|
||||
# Enable/disable 3G aka IuPS + IuCS support?
|
||||
AC_ARG_ENABLE([iu], [AS_HELP_STRING([--enable-iu], [Build 3G support, aka IuPS and IuCS interfaces])],
|
||||
[osmo_ac_iu="$enableval"],[osmo_ac_iu="no"])
|
||||
if test "x$osmo_ac_iu" = "xyes" ; then
|
||||
PKG_CHECK_MODULES(LIBASN1C, libasn1c) # TODO version?
|
||||
PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap) # TODO version?
|
||||
PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran) # TODO version?
|
||||
AC_DEFINE(BUILD_IU, 1, [Define if we want to build IuPS and IuCS interfaces support])
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_IU, test "x$osmo_ac_iu" = "xyes")
|
||||
AC_SUBST(osmo_ac_iu)
|
||||
|
||||
|
||||
found_libgtp=yes
|
||||
PKG_CHECK_MODULES(LIBGTP, libgtp >= 0.92, , found_libgtp=no)
|
||||
PKG_CHECK_MODULES(LIBGTP, libgtp, , found_libgtp=no)
|
||||
AM_CONDITIONAL(HAVE_LIBGTP, test "$found_libgtp" = yes)
|
||||
AC_SUBST(found_libgtp)
|
||||
|
||||
found_libcares=yes
|
||||
PKG_CHECK_MODULES([LIBCARES], [libcares], [], [found_libcares=no])
|
||||
AM_CONDITIONAL(HAVE_LIBCARES, test "$found_libcares" = yes)
|
||||
AC_SUBST(found_libcares)
|
||||
|
||||
found_libgtp_and_libcares=no
|
||||
if test "$found_libgtp" = "yes" -a "$found_libcares" = "yes"; then
|
||||
found_libgtp_and_libcares=yes
|
||||
fi
|
||||
AC_SUBST(found_libgtp_and_libcares)
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(dahdi/user.h,,AC_MSG_WARN(DAHDI input driver will not be built))
|
||||
AC_CHECK_HEADERS(dbi/dbd.h,,AC_MSG_ERROR(DBI library is not installed))
|
||||
|
||||
found_pcap=yes
|
||||
AC_CHECK_HEADERS(pcap/pcap.h,,found_pcap=no)
|
||||
AM_CONDITIONAL(HAVE_PCAP, test "$found_pcap" = yes)
|
||||
|
||||
found_cdk=yes
|
||||
AC_CHECK_HEADERS(cdk/cdk.h,,found_cdk=no)
|
||||
AM_CONDITIONAL(HAVE_LIBCDK, test "$found_cdk" = yes)
|
||||
@@ -148,13 +107,6 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])],
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
AC_SUBST(SYMBOL_VISIBILITY)
|
||||
|
||||
AX_CHECK_COMPILE_FLAG([-Werror=implicit], [CFLAGS="$CFLAGS -Werror=implicit"])
|
||||
AX_CHECK_COMPILE_FLAG([-Werror=maybe-uninitialized], [CFLAGS="$CFLAGS -Werror=maybe-uninitialized"])
|
||||
AX_CHECK_COMPILE_FLAG([-Werror=memset-transposed-args], [CFLAGS="$CFLAGS -Werror=memset-transposed-args"])
|
||||
AX_CHECK_COMPILE_FLAG([-Werror=null-dereference], [CFLAGS="$CFLAGS -Werror=null-dereference"])
|
||||
AX_CHECK_COMPILE_FLAG([-Werror=sizeof-array-argument], [CFLAGS="$CFLAGS -Werror=sizeof-array-argument"])
|
||||
AX_CHECK_COMPILE_FLAG([-Werror=sizeof-pointer-memaccess], [CFLAGS="$CFLAGS -Werror=sizeof-pointer-memaccess"])
|
||||
|
||||
# Coverage build taken from WebKit's configure.in
|
||||
AC_MSG_CHECKING([whether to enable code coverage support])
|
||||
AC_ARG_ENABLE(coverage,
|
||||
@@ -228,8 +180,6 @@ AC_OUTPUT(
|
||||
src/libmgcp/Makefile
|
||||
src/libcommon/Makefile
|
||||
src/libfilter/Makefile
|
||||
src/libiu/Makefile
|
||||
src/libcommon-cs/Makefile
|
||||
src/osmo-nitb/Makefile
|
||||
src/osmo-bsc/Makefile
|
||||
src/osmo-bsc_nat/Makefile
|
||||
@@ -253,14 +203,6 @@ AC_OUTPUT(
|
||||
tests/trau/Makefile
|
||||
tests/sgsn/Makefile
|
||||
tests/subscr/Makefile
|
||||
tests/oap/Makefile
|
||||
tests/gtphub/Makefile
|
||||
tests/mm_auth/Makefile
|
||||
tests/xid/Makefile
|
||||
tests/sndcp_xid/Makefile
|
||||
tests/slhc/Makefile
|
||||
tests/v42bis/Makefile
|
||||
tests/nanobts_omlattr/Makefile
|
||||
doc/Makefile
|
||||
doc/examples/Makefile
|
||||
Makefile)
|
||||
|
@@ -1,120 +1,104 @@
|
||||
#!/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.
|
||||
*/
|
||||
"""
|
||||
|
||||
import sys,os
|
||||
from optparse import OptionParser
|
||||
from ipa import Ctrl
|
||||
import socket
|
||||
import struct
|
||||
|
||||
verbose = False
|
||||
|
||||
def prefix_ipa_ctrl_header(data):
|
||||
return struct.pack(">HBB", len(data)+1, 0xee, 0) + data
|
||||
|
||||
def remove_ipa_ctrl_header(data):
|
||||
if (len(data) < 4):
|
||||
raise BaseException("Answer too short!")
|
||||
(plen, ipa_proto, osmo_proto) = struct.unpack(">HBB", data[:4])
|
||||
if (plen + 3 > len(data)):
|
||||
print "Warning: Wrong payload length (expected %i, got %i)" % (plen, len(data) - 3)
|
||||
if (ipa_proto != 0xee or osmo_proto != 0):
|
||||
raise BaseException("Wrong protocol in answer!")
|
||||
|
||||
return data[4:plen+3], data[plen+3:]
|
||||
|
||||
def connect(host, port):
|
||||
if verbose:
|
||||
print "Connecting to host %s:%i" % (host, port)
|
||||
if verbose:
|
||||
print "Connecting to host %s:%i" % (host, port)
|
||||
|
||||
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sck.setblocking(1)
|
||||
sck.connect((host, port))
|
||||
return sck
|
||||
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sck.setblocking(1)
|
||||
sck.connect((host, port))
|
||||
return sck
|
||||
|
||||
def do_set_get(sck, var, value = None):
|
||||
(r, c) = Ctrl().cmd(var, value)
|
||||
sck.send(c)
|
||||
answer = Ctrl().rem_header(sck.recv(4096))
|
||||
return (answer,) + Ctrl().verify(answer, r, var, value)
|
||||
def send(sck, data):
|
||||
if verbose:
|
||||
print "Sending \"%s\"" %(data)
|
||||
data = prefix_ipa_ctrl_header(data)
|
||||
sck.send(data)
|
||||
|
||||
def set_var(sck, var, val):
|
||||
(a, _, _) = do_set_get(sck, var, val)
|
||||
return a
|
||||
def do_set(var, value, id, sck):
|
||||
setmsg = "SET %s %s %s" %(options.id, var, value)
|
||||
send(sck, setmsg)
|
||||
|
||||
def get_var(sck, var):
|
||||
(_, _, v) = do_set_get(sck, var)
|
||||
return v
|
||||
def do_get(var, id, sck):
|
||||
getmsg = "GET %s %s" %(options.id, var)
|
||||
send(sck, getmsg)
|
||||
|
||||
def _leftovers(sck, fl):
|
||||
"""
|
||||
Read outstanding data if any according to flags
|
||||
"""
|
||||
try:
|
||||
data = sck.recv(1024, fl)
|
||||
except socket.error as (s_errno, strerror):
|
||||
return False
|
||||
if len(data) != 0:
|
||||
tail = data
|
||||
while True:
|
||||
(head, tail) = Ctrl().split_combined(tail)
|
||||
print "Got message:", Ctrl().rem_header(head)
|
||||
if len(tail) == 0:
|
||||
break
|
||||
return True
|
||||
return False
|
||||
parser = OptionParser("Usage: %prog [options] var [value]")
|
||||
parser.add_option("-d", "--host", dest="host",
|
||||
help="connect to HOST", metavar="HOST")
|
||||
parser.add_option("-p", "--port", dest="port", type="int",
|
||||
help="use PORT", metavar="PORT", default=4249)
|
||||
parser.add_option("-g", "--get", action="store_true",
|
||||
dest="cmd_get", help="perform GET operation")
|
||||
parser.add_option("-s", "--set", action="store_true",
|
||||
dest="cmd_set", help="perform SET operation")
|
||||
parser.add_option("-i", "--id", dest="id", default="1",
|
||||
help="set id manually", metavar="ID")
|
||||
parser.add_option("-v", "--verbose", action="store_true",
|
||||
dest="verbose", help="be verbose", default=False)
|
||||
parser.add_option("-m", "--monitor", action="store_true",
|
||||
dest="monitor", help="monitor the connection for traps", default=False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = OptionParser("Usage: %prog [options] var [value]")
|
||||
parser.add_option("-d", "--host", dest="host",
|
||||
help="connect to HOST", metavar="HOST")
|
||||
parser.add_option("-p", "--port", dest="port", type="int",
|
||||
help="use PORT", metavar="PORT", default=4249)
|
||||
parser.add_option("-g", "--get", action="store_true",
|
||||
dest="cmd_get", help="perform GET operation")
|
||||
parser.add_option("-s", "--set", action="store_true",
|
||||
dest="cmd_set", help="perform SET operation")
|
||||
parser.add_option("-v", "--verbose", action="store_true",
|
||||
dest="verbose", help="be verbose", default=False)
|
||||
parser.add_option("-m", "--monitor", action="store_true",
|
||||
dest="monitor", help="monitor the connection for traps", default=False)
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
verbose = options.verbose
|
||||
|
||||
verbose = options.verbose
|
||||
if options.cmd_set and options.cmd_get:
|
||||
parser.error("Get and set options are mutually exclusive!")
|
||||
|
||||
if options.cmd_set and options.cmd_get:
|
||||
parser.error("Get and set options are mutually exclusive!")
|
||||
if not (options.cmd_get or options.cmd_set or options.monitor):
|
||||
parser.error("One of -m, -g, or -s must be set")
|
||||
|
||||
if not (options.cmd_get or options.cmd_set or options.monitor):
|
||||
parser.error("One of -m, -g, or -s must be set")
|
||||
if not (options.host):
|
||||
parser.error("Destination host and port required!")
|
||||
|
||||
if not (options.host):
|
||||
parser.error("Destination host and port required!")
|
||||
sock = connect(options.host, options.port)
|
||||
|
||||
sock = connect(options.host, options.port)
|
||||
if options.cmd_set:
|
||||
if len(args) < 2:
|
||||
parser.error("Set requires var and value arguments")
|
||||
do_set(args[0], ' '.join(args[1:]), options.id, sock)
|
||||
|
||||
if options.cmd_set:
|
||||
if len(args) < 2:
|
||||
parser.error("Set requires var and value arguments")
|
||||
_leftovers(sock, socket.MSG_DONTWAIT)
|
||||
print "Got message:", set_var(sock, args[0], ' '.join(args[1:]))
|
||||
if options.cmd_get:
|
||||
if len(args) != 1:
|
||||
parser.error("Get requires the var argument")
|
||||
do_get(args[0], options.id, sock)
|
||||
|
||||
if options.cmd_get:
|
||||
if len(args) != 1:
|
||||
parser.error("Get requires the var argument")
|
||||
_leftovers(sock, socket.MSG_DONTWAIT)
|
||||
(a, _, _) = do_set_get(sock, args[0])
|
||||
print "Got message:", a
|
||||
data = sock.recv(1024)
|
||||
while (len(data)>0):
|
||||
(answer, data) = remove_ipa_ctrl_header(data)
|
||||
print "Got message:", answer
|
||||
|
||||
if options.monitor:
|
||||
while True:
|
||||
if not _leftovers(sock, 0):
|
||||
print "Connection is gone."
|
||||
break
|
||||
sock.close()
|
||||
if options.monitor:
|
||||
while (True):
|
||||
data = sock.recv(1024)
|
||||
if len(data) == 0:
|
||||
print "Connection is gone."
|
||||
break
|
||||
|
||||
while (len(data)>0):
|
||||
(answer, data) = remove_ipa_ctrl_header(data)
|
||||
print "Got message:", answer
|
||||
|
||||
sock.close()
|
||||
|
@@ -1,147 +0,0 @@
|
||||
#!/usr/bin/python2
|
||||
|
||||
mod_license = '''
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
'''
|
||||
|
||||
import sys, argparse, random, logging, tornado.ioloop, tornado.web, tornado.tcpclient, tornado.httpclient, eventsource, bsc_control
|
||||
from eventsource import listener, request
|
||||
|
||||
'''
|
||||
N. B: this is not an example of building proper REST API or building secure web application.
|
||||
It's only purpose is to illustrate conversion of Osmocom's Control Interface to web-friendly API.
|
||||
Exposing this to Internet while connected to production network might lead to all sorts of mischief and mayhem
|
||||
from NSA' TAO breaking into your network to zombie apocalypse. Do NOT do that.
|
||||
'''
|
||||
|
||||
token = None
|
||||
stream = None
|
||||
url = None
|
||||
|
||||
'''
|
||||
Returns json according to following schema - see http://json-schema.org/documentation.html for details:
|
||||
{
|
||||
"title": "Ctrl Schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"variable": {
|
||||
"type": "string"
|
||||
},
|
||||
"varlue": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["interface", "variable", "value"]
|
||||
}
|
||||
Example validation from command-line:
|
||||
json validate --schema-file=schema.json --document-file=data.json
|
||||
The interface is represented as string because it might look different for IPv4 vs v6.
|
||||
'''
|
||||
|
||||
def read_header(data):
|
||||
t_length = bsc_control.ipa_ctrl_header(data)
|
||||
if (t_length):
|
||||
stream.read_bytes(t_length - 1, callback = read_trap)
|
||||
else:
|
||||
print >> sys.stderr, "protocol error: length missing in %s!" % data
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def read_trap(data):
|
||||
(t, z, v, p) = data.split()
|
||||
if (t != 'TRAP' or int(z) != 0):
|
||||
print >> sys.stderr, "protocol error: TRAP != %s or 0! = %d" % (t, int(z))
|
||||
else:
|
||||
yield tornado.httpclient.AsyncHTTPClient().fetch(tornado.httpclient.HTTPRequest(url = "%s/%s/%s" % (url, "ping", token),
|
||||
method = 'POST',
|
||||
headers = {'Content-Type': 'application/json'},
|
||||
body = tornado.escape.json_encode({ 'variable' : v, 'value' : p })))
|
||||
stream.read_bytes(4, callback = read_header)
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def trap_setup(host, port, target_host, target_port, tk):
|
||||
global stream
|
||||
global url
|
||||
global token
|
||||
token = tk
|
||||
url = "http://%s:%s/sse" % (host, port)
|
||||
stream = yield tornado.tcpclient.TCPClient().connect(target_host, target_port)
|
||||
stream.read_bytes(4, callback = read_header)
|
||||
|
||||
def get_v(s, v):
|
||||
return { 'variable' : v, 'value' : bsc_control.get_var(s, tornado.escape.native_str(v)) }
|
||||
|
||||
class CtrlHandler(tornado.web.RequestHandler):
|
||||
def initialize(self):
|
||||
self.skt = bsc_control.connect(self.settings['ctrl_host'], self.settings['ctrl_port'])
|
||||
|
||||
def get(self, v):
|
||||
self.write(get_v(self.skt, v))
|
||||
|
||||
def post(self):
|
||||
self.write(get_v(self.skt, self.get_argument("variable")))
|
||||
|
||||
class SetCtrl(CtrlHandler):
|
||||
def get(self, var, val):
|
||||
bsc_control.set_var(self.skt, tornado.escape.native_str(var), tornado.escape.native_str(val))
|
||||
super(SetCtrl, self).get(tornado.escape.native_str(var))
|
||||
|
||||
def post(self):
|
||||
bsc_control.set_var(self.skt, tornado.escape.native_str(self.get_argument("variable")), tornado.escape.native_str(self.get_argument("value")))
|
||||
super(SetCtrl, self).post()
|
||||
|
||||
class Slash(tornado.web.RequestHandler):
|
||||
def get(self):
|
||||
self.write('<html><head><title>%s</title></head><body>Using Tornado framework v%s'
|
||||
'<form action="/get" method="POST">'
|
||||
'<input type="text" name="variable">'
|
||||
'<input type="submit" value="GET">'
|
||||
'</form>'
|
||||
'<form action="/set" method="POST">'
|
||||
'<input type="text" name="variable">'
|
||||
'<input type="text" name="value">'
|
||||
'<input type="submit" value="SET">'
|
||||
'</form>'
|
||||
'</body></html>' % ("Osmocom Control Interface Proxy", tornado.version))
|
||||
|
||||
if __name__ == '__main__':
|
||||
p = argparse.ArgumentParser(description='Osmocom Control Interface proxy.')
|
||||
p.add_argument('-c', '--control-port', type = int, default = 4252, help = "Target Control Interface port")
|
||||
p.add_argument('-a', '--control-host', default = 'localhost', help = "Target Control Interface adress")
|
||||
p.add_argument('-b', '--host', default = 'localhost', help = "Adress to bind proxy's web interface")
|
||||
p.add_argument('-p', '--port', type = int, default = 6969, help = "Port to bind proxy's web interface")
|
||||
p.add_argument('-d', '--debug', action='store_true', help = "Activate debugging (default off)")
|
||||
p.add_argument('-t', '--token', default = 'osmocom', help = "Token to be used by SSE client in URL e. g. http://127.0.0.1:8888/poll/osmocom where 'osmocom' is default token value")
|
||||
p.add_argument('-k', '--keepalive', type = int, default = 5000, help = "Timeout betwwen keepalive messages, in milliseconds, defaults to 5000")
|
||||
args = p.parse_args()
|
||||
random.seed()
|
||||
tornado.netutil.Resolver.configure('tornado.netutil.ThreadedResolver') # Use non-blocking resolver
|
||||
logging.basicConfig()
|
||||
application = tornado.web.Application([
|
||||
(r"/", Slash),
|
||||
(r"/get", CtrlHandler),
|
||||
(r"/get/(.*)", CtrlHandler),
|
||||
(r"/set", SetCtrl),
|
||||
(r"/set/(.*)/(.*)", SetCtrl),
|
||||
(r"/sse/(.*)/(.*)", listener.EventSourceHandler, dict(event_class = listener.JSONIdEvent, keepalive = args.keepalive)),
|
||||
], debug = args.debug, ctrl_host = args.control_host, ctrl_port = args.control_port)
|
||||
application.listen(address = args.host, port = args.port)
|
||||
trap_setup(args.host, args.port, application.settings['ctrl_host'], application.settings['ctrl_port'], args.token)
|
||||
tornado.ioloop.IOLoop.instance().start()
|
@@ -1,278 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- 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.
|
||||
*/
|
||||
"""
|
||||
|
||||
import struct, random, sys
|
||||
|
||||
class IPA(object):
|
||||
"""
|
||||
Stateless IPA protocol multiplexer: add/remove/parse (extended) header
|
||||
"""
|
||||
version = "0.0.5"
|
||||
TCP_PORT_OML = 3002
|
||||
TCP_PORT_RSL = 3003
|
||||
# OpenBSC extensions: OSMO, MGCP_OLD
|
||||
PROTO = dict(RSL=0x00, CCM=0xFE, SCCP=0xFD, OML=0xFF, OSMO=0xEE, MGCP_OLD=0xFC)
|
||||
# ...OML Router Control, GSUP GPRS extension, Osmocom Authn Protocol
|
||||
EXT = dict(CTRL=0, MGCP=1, LAC=2, SMSC=3, ORC=4, GSUP=5, OAP=6)
|
||||
# OpenBSC extension: SCCP_OLD
|
||||
MSGT = dict(PING=0x00, PONG=0x01, ID_GET=0x04, ID_RESP=0x05, ID_ACK=0x06, SCCP_OLD=0xFF)
|
||||
_IDTAG = dict(SERNR=0, UNITNAME=1, LOCATION=2, TYPE=3, EQUIPVERS=4, SWVERSION=5, IPADDR=6, MACADDR=7, UNIT=8)
|
||||
CTRL_GET = 'GET'
|
||||
CTRL_SET = 'SET'
|
||||
CTRL_REP = 'REPLY'
|
||||
CTRL_ERR = 'ERR'
|
||||
CTRL_TRAP = 'TRAP'
|
||||
|
||||
def _l(self, d, p):
|
||||
"""
|
||||
Reverse dictionary lookup: return key for a given value
|
||||
"""
|
||||
if p is None:
|
||||
return 'UNKNOWN'
|
||||
return list(d.keys())[list(d.values()).index(p)]
|
||||
|
||||
def _tag(self, t, v):
|
||||
"""
|
||||
Create TAG as TLV data
|
||||
"""
|
||||
return struct.pack(">HB", len(v) + 1, t) + v
|
||||
|
||||
def proto(self, p):
|
||||
"""
|
||||
Lookup protocol name
|
||||
"""
|
||||
return self._l(self.PROTO, p)
|
||||
|
||||
def ext(self, p):
|
||||
"""
|
||||
Lookup protocol extension name
|
||||
"""
|
||||
return self._l(self.EXT, p)
|
||||
|
||||
def msgt(self, p):
|
||||
"""
|
||||
Lookup message type name
|
||||
"""
|
||||
return self._l(self.MSGT, p)
|
||||
|
||||
def idtag(self, p):
|
||||
"""
|
||||
Lookup ID tag name
|
||||
"""
|
||||
return self._l(self._IDTAG, p)
|
||||
|
||||
def ext_name(self, proto, exten):
|
||||
"""
|
||||
Return proper extension byte name depending on the protocol used
|
||||
"""
|
||||
if self.PROTO['CCM'] == proto:
|
||||
return self.msgt(exten)
|
||||
if self.PROTO['OSMO'] == proto:
|
||||
return self.ext(exten)
|
||||
return None
|
||||
|
||||
def add_header(self, data, proto, ext=None):
|
||||
"""
|
||||
Add IPA header (with extension if necessary), data must be represented as bytes
|
||||
"""
|
||||
if ext is None:
|
||||
return struct.pack(">HB", len(data) + 1, proto) + data
|
||||
return struct.pack(">HBB", len(data) + 1, proto, ext) + data
|
||||
|
||||
def del_header(self, data):
|
||||
"""
|
||||
Strip IPA protocol header correctly removing extension if present
|
||||
Returns data length, IPA protocol, extension (or None if not defined for a give protocol) and the data without header
|
||||
"""
|
||||
if not len(data):
|
||||
return None, None, None, None
|
||||
(dlen, proto) = struct.unpack('>HB', data[:3])
|
||||
if self.PROTO['OSMO'] == proto or self.PROTO['CCM'] == proto: # there's extension which we have to unpack
|
||||
return struct.unpack('>HBB', data[:4]) + (data[4:], ) # length, protocol, extension, data
|
||||
return dlen, proto, None, data[3:] # length, protocol, _, data
|
||||
|
||||
def split_combined(self, data):
|
||||
"""
|
||||
Split the data which contains multiple concatenated IPA messages into tuple (first, rest) where rest contains remaining messages, first is the single IPA message
|
||||
"""
|
||||
(length, _, _, _) = self.del_header(data)
|
||||
return data[:(length + 3)], data[(length + 3):]
|
||||
|
||||
def tag_serial(self, data):
|
||||
"""
|
||||
Make TAG for serial number
|
||||
"""
|
||||
return self._tag(self._IDTAG['SERNR'], data)
|
||||
|
||||
def tag_name(self, data):
|
||||
"""
|
||||
Make TAG for unit name
|
||||
"""
|
||||
return self._tag(self._IDTAG['UNITNAME'], data)
|
||||
|
||||
def tag_loc(self, data):
|
||||
"""
|
||||
Make TAG for location
|
||||
"""
|
||||
return self._tag(self._IDTAG['LOCATION'], data)
|
||||
|
||||
def tag_type(self, data):
|
||||
"""
|
||||
Make TAG for unit type
|
||||
"""
|
||||
return self._tag(self._IDTAG['TYPE'], data)
|
||||
|
||||
def tag_equip(self, data):
|
||||
"""
|
||||
Make TAG for equipment version
|
||||
"""
|
||||
return self._tag(self._IDTAG['EQUIPVERS'], data)
|
||||
|
||||
def tag_sw(self, data):
|
||||
"""
|
||||
Make TAG for software version
|
||||
"""
|
||||
return self._tag(self._IDTAG['SWVERSION'], data)
|
||||
|
||||
def tag_ip(self, data):
|
||||
"""
|
||||
Make TAG for IP address
|
||||
"""
|
||||
return self._tag(self._IDTAG['IPADDR'], data)
|
||||
|
||||
def tag_mac(self, data):
|
||||
"""
|
||||
Make TAG for MAC address
|
||||
"""
|
||||
return self._tag(self._IDTAG['MACADDR'], data)
|
||||
|
||||
def tag_unit(self, data):
|
||||
"""
|
||||
Make TAG for unit ID
|
||||
"""
|
||||
return self._tag(self._IDTAG['UNIT'], data)
|
||||
|
||||
def identity(self, unit=b'', mac=b'', location=b'', utype=b'', equip=b'', sw=b'', name=b'', serial=b''):
|
||||
"""
|
||||
Make IPA IDENTITY tag list, by default returns empty concatenated bytes of tag list
|
||||
"""
|
||||
return self.tag_unit(unit) + self.tag_mac(mac) + self.tag_loc(location) + self.tag_type(utype) + self.tag_equip(equip) + self.tag_sw(sw) + self.tag_name(name) + self.tag_serial(serial)
|
||||
|
||||
def ping(self):
|
||||
"""
|
||||
Make PING message
|
||||
"""
|
||||
return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PING'])
|
||||
|
||||
def pong(self):
|
||||
"""
|
||||
Make PONG message
|
||||
"""
|
||||
return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PONG'])
|
||||
|
||||
def id_ack(self):
|
||||
"""
|
||||
Make ID_ACK CCM message
|
||||
"""
|
||||
return self.add_header(b'', self.PROTO['CCM'], self.MSGT['ID_ACK'])
|
||||
|
||||
def id_get(self):
|
||||
"""
|
||||
Make ID_GET CCM message
|
||||
"""
|
||||
return self.add_header(self.identity(), self.PROTO['CCM'], self.MSGT['ID_GET'])
|
||||
|
||||
def id_resp(self, data):
|
||||
"""
|
||||
Make ID_RESP CCM message
|
||||
"""
|
||||
return self.add_header(data, self.PROTO['CCM'], self.MSGT['ID_RESP'])
|
||||
|
||||
class Ctrl(IPA):
|
||||
"""
|
||||
Osmocom CTRL protocol implemented on top of IPA multiplexer
|
||||
"""
|
||||
def __init__(self):
|
||||
random.seed()
|
||||
|
||||
def add_header(self, data):
|
||||
"""
|
||||
Add CTRL header
|
||||
"""
|
||||
return super(Ctrl, self).add_header(data.encode('utf-8'), IPA.PROTO['OSMO'], IPA.EXT['CTRL'])
|
||||
|
||||
def rem_header(self, data):
|
||||
"""
|
||||
Remove CTRL header, check for appropriate protocol and extension
|
||||
"""
|
||||
(_, proto, ext, d) = super(Ctrl, self).del_header(data)
|
||||
if self.PROTO['OSMO'] != proto or self.EXT['CTRL'] != ext:
|
||||
return None
|
||||
return d
|
||||
|
||||
def parse(self, data, op=None):
|
||||
"""
|
||||
Parse Ctrl string returning (var, value) pair
|
||||
var could be None in case of ERROR message
|
||||
value could be None in case of GET message
|
||||
"""
|
||||
(s, i, v) = data.split(' ', 2)
|
||||
if s == self.CTRL_ERR:
|
||||
return None, v
|
||||
if s == self.CTRL_GET:
|
||||
return v, None
|
||||
(s, i, var, val) = data.split(' ', 3)
|
||||
if s == self.CTRL_TRAP and i != '0':
|
||||
return None, '%s with non-zero id %s' % (s, i)
|
||||
if op is not None and i != op:
|
||||
if s == self.CTRL_GET + '_' + self.CTRL_REP or s == self.CTRL_SET + '_' + self.CTRL_REP:
|
||||
return None, '%s with unexpected id %s' % (s, i)
|
||||
return var, val
|
||||
|
||||
def trap(self, var, val):
|
||||
"""
|
||||
Make TRAP message with given (vak, val) pair
|
||||
"""
|
||||
return self.add_header("%s 0 %s %s" % (self.CTRL_TRAP, var, val))
|
||||
|
||||
def cmd(self, var, val=None):
|
||||
"""
|
||||
Make SET/GET command message: returns (r, m) tuple where r is random operation id and m is assembled message
|
||||
"""
|
||||
r = random.randint(1, sys.maxsize)
|
||||
if val is not None:
|
||||
return r, self.add_header("%s %s %s %s" % (self.CTRL_SET, r, var, val))
|
||||
return r, self.add_header("%s %s %s" % (self.CTRL_GET, r, var))
|
||||
|
||||
def verify(self, reply, r, var, val=None):
|
||||
"""
|
||||
Verify reply to SET/GET command: returns (b, v) tuple where v is True/False verification result and v is the variable value
|
||||
"""
|
||||
(k, v) = self.parse(reply)
|
||||
if k != var or (val is not None and v != val):
|
||||
return False, v
|
||||
return True, v
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("IPA multiplexer v%s loaded." % IPA.version)
|
@@ -1,65 +0,0 @@
|
||||
#!/usr/bin/env python2.7
|
||||
|
||||
"""
|
||||
AGPLv3+ 2016 Copyright Holger Hans Peter Freyther
|
||||
|
||||
Example of how to connect to the USSD side-channel and how to respond
|
||||
with a fixed message.
|
||||
"""
|
||||
|
||||
import socket
|
||||
import struct
|
||||
|
||||
ussdSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
ussdSocket.connect(('127.0.0.1', 5001))
|
||||
|
||||
def send_dt1(dstref, data):
|
||||
dlen = struct.pack('B', len(data)).encode('hex')
|
||||
hex = '06' + dstref.encode('hex') + '00' + '01' + dlen + data.encode('hex')
|
||||
pdata = hex.decode('hex')
|
||||
out = struct.pack('>HB', len(pdata), 0xfd) + pdata
|
||||
ussdSocket.send(out)
|
||||
|
||||
def send_rel(srcref, dstref):
|
||||
hex = '04' + dstref.encode('hex') + srcref.encode('hex') + '000100'
|
||||
pdata = hex.decode('hex')
|
||||
out = struct.pack('>HB', len(pdata), 0xfd) + pdata
|
||||
ussdSocket.send(out)
|
||||
|
||||
def recv_one():
|
||||
plen = ussdSocket.recv(3)
|
||||
(plen,ptype) = struct.unpack(">HB", plen)
|
||||
data = ussdSocket.recv(plen)
|
||||
|
||||
return ptype, data
|
||||
|
||||
# Assume this is the ID request
|
||||
data = ussdSocket.recv(4)
|
||||
ussdSocket.send("\x00\x08\xfe\x05\x00" + "\x05\x01" + "ussd")
|
||||
# ^len ^len of tag ... and ignore
|
||||
|
||||
# Expect a fake message. see struct ipac_msgt_sccp_state
|
||||
ptype, data = recv_one()
|
||||
print("%d %s" % (ptype, data.encode('hex')))
|
||||
(srcref, dstref, transid, invokeid) = struct.unpack("<3s3sBB", data[1:9])
|
||||
print("New transID %d invoke %d" % (transid, invokeid))
|
||||
|
||||
# Expect a the invocation.. todo.. extract invoke id
|
||||
ptype, data = recv_one()
|
||||
print("%d %s" % (ptype, data.encode('hex')))
|
||||
|
||||
# Reply with BSSAP + GSM 04.08 + MAP portion
|
||||
# 00 == invoke id 0f == DCS
|
||||
res = "01002a9b2a0802e1901c22a220020100301b02013b301604010f041155e7d2f9bc3a41412894991c06a9c9a713"
|
||||
send_dt1(dstref, res.decode('hex'))
|
||||
|
||||
clear = "000420040109"
|
||||
send_dt1(dstref, clear.decode('hex'))
|
||||
|
||||
# should be the clear complete
|
||||
send_rel(srcref, dstref)
|
||||
|
||||
# Give it some time to handle connection shutdown properly
|
||||
print("Gracefully sleeping")
|
||||
import time
|
||||
time.sleep(3)
|
@@ -1,188 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- 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.
|
||||
*/
|
||||
"""
|
||||
|
||||
__version__ = "v0.7" # bump this on every non-trivial change
|
||||
|
||||
from twisted.internet import defer, reactor
|
||||
from twisted_ipa import CTRL, IPAFactory, __version__ as twisted_ipa_version
|
||||
from ipa import Ctrl
|
||||
from treq import post, collect
|
||||
from suds.client import Client
|
||||
from functools import partial
|
||||
from distutils.version import StrictVersion as V # FIXME: use NormalizedVersion from PEP-386 when available
|
||||
import argparse, datetime, signal, sys, os, logging, logging.handlers
|
||||
|
||||
# we don't support older versions of TwistedIPA module
|
||||
assert V(twisted_ipa_version) > V('0.4')
|
||||
|
||||
# keys from OpenBSC openbsc/src/libbsc/bsc_rf_ctrl.c, values SOAP-specific
|
||||
oper = { 'inoperational' : 0, 'operational' : 1 }
|
||||
admin = { 'locked' : 0, 'unlocked' : 1 }
|
||||
policy = { 'off' : 0, 'on' : 1, 'grace' : 2, 'unknown' : 3 }
|
||||
|
||||
# keys from OpenBSC openbsc/src/libbsc/bsc_vty.c
|
||||
fix = { 'invalid' : 0, 'fix2d' : 1, 'fix3d' : 1 } # SOAP server treats it as boolean but expects int
|
||||
|
||||
|
||||
def handle_reply(p, f, log, r):
|
||||
"""
|
||||
Reply handler: takes function p to process raw SOAP server reply r, function f to run for each command and verbosity flag v
|
||||
"""
|
||||
repl = p(r) # result is expected to have both commands[] array and error string (could be None)
|
||||
bsc_id = repl.commands[0].split()[0].split('.')[3] # we expect 1st command to have net.0.bsc.666.bts.2.trx.1 location prefix format
|
||||
log.info("Received SOAP response for BSC %s with %d commands, error status: %s" % (bsc_id, len(repl.commands), repl.error))
|
||||
log.debug("BSC %s commands: %s" % (bsc_id, repl.commands))
|
||||
for t in repl.commands: # Process OpenBscCommands format from .wsdl
|
||||
(_, m) = Ctrl().cmd(*t.split())
|
||||
f(m)
|
||||
|
||||
|
||||
class Trap(CTRL):
|
||||
"""
|
||||
TRAP handler (agnostic to factory's client object)
|
||||
"""
|
||||
def ctrl_TRAP(self, data, op_id, v):
|
||||
"""
|
||||
Parse CTRL TRAP and dispatch to appropriate handler after normalization
|
||||
"""
|
||||
(l, r) = v.split()
|
||||
loc = l.split('.')
|
||||
t_type = loc[-1]
|
||||
p = partial(lambda a, i: a[i] if len(a) > i else None, loc) # parse helper
|
||||
method = getattr(self, 'handle_' + t_type.replace('-', ''), lambda: "Unhandled %s trap" % t_type)
|
||||
method(p(1), p(3), p(5), p(7), r) # we expect net.0.bsc.666.bts.2.trx.1 format for trap prefix
|
||||
|
||||
def ctrl_SET_REPLY(self, data, _, v):
|
||||
"""
|
||||
Debug log for replies to our commands
|
||||
"""
|
||||
self.factory.log.debug('SET REPLY %s' % v)
|
||||
|
||||
def ctrl_ERROR(self, data, op_id, v):
|
||||
"""
|
||||
We want to know if smth went wrong
|
||||
"""
|
||||
self.factory.log.debug('CTRL ERROR [%s] %s' % (op_id, v))
|
||||
|
||||
def connectionMade(self):
|
||||
"""
|
||||
Logging wrapper, calling super() is necessary not to break reconnection logic
|
||||
"""
|
||||
self.factory.log.info("Connected to CTRL@%s:%d" % (self.factory.host, self.factory.port))
|
||||
super(CTRL, self).connectionMade()
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def handle_locationstate(self, net, bsc, bts, trx, data):
|
||||
"""
|
||||
Handle location-state TRAP: parse trap content, build SOAP context and use treq's routines to post it while setting up async handlers
|
||||
"""
|
||||
(ts, fx, lat, lon, height, opr, adm, pol, mcc, mnc) = data.split(',')
|
||||
tstamp = datetime.datetime.fromtimestamp(float(ts)).isoformat()
|
||||
self.factory.log.debug('location-state@%s.%s.%s.%s (%s) [%s/%s] => %s' % (net, bsc, bts, trx, tstamp, mcc, mnc, data))
|
||||
ctx = self.factory.client.registerSiteLocation(bsc, float(lon), float(lat), fix.get(fx, 0), tstamp, oper.get(opr, 2), admin.get(adm, 2), policy.get(pol, 3))
|
||||
d = post(self.factory.location, ctx.envelope)
|
||||
d.addCallback(collect, partial(handle_reply, ctx.process_reply, self.transport.write, self.factory.log)) # treq's collect helper is handy to get all reply content at once using closure on ctx
|
||||
d.addErrback(lambda e, bsc: self.factory.log.critical("HTTP POST error %s while trying to register BSC %s" % (e, bsc)), bsc) # handle HTTP errors
|
||||
# Ensure that we run only limited number of requests in parallel:
|
||||
yield self.factory.semaphore.acquire()
|
||||
yield d # we end up here only if semaphore is available which means it's ok to fire the request without exceeding the limit
|
||||
self.factory.semaphore.release()
|
||||
|
||||
def handle_notificationrejectionv1(self, net, bsc, bts, trx, data):
|
||||
"""
|
||||
Handle notification-rejection-v1 TRAP: just an example to show how more message types can be handled
|
||||
"""
|
||||
self.factory.log.debug('notification-rejection-v1@bsc-id %s => %s' % (bsc, data))
|
||||
|
||||
|
||||
class TrapFactory(IPAFactory):
|
||||
"""
|
||||
Store SOAP client object so TRAP handler can use it for requests
|
||||
"""
|
||||
location = None
|
||||
log = None
|
||||
semaphore = None
|
||||
client = None
|
||||
host = None
|
||||
port = None
|
||||
def __init__(self, host, port, proto, semaphore, log, wsdl=None, location=None):
|
||||
self.host = host # for logging only,
|
||||
self.port = port # seems to be no way to get it from ReconnectingClientFactory
|
||||
self.log = log
|
||||
self.semaphore = semaphore
|
||||
soap = Client(wsdl, location=location, nosend=True) # make async SOAP client
|
||||
self.location = location.encode() if location else soap.wsdl.services[0].ports[0].location # necessary for dispatching HTTP POST via treq
|
||||
self.client = soap.service
|
||||
level = self.log.getEffectiveLevel()
|
||||
self.log.setLevel(logging.WARNING) # we do not need excessive debug from lower levels
|
||||
super(TrapFactory, self).__init__(proto, self.log)
|
||||
self.log.setLevel(level)
|
||||
self.log.debug("Using IPA %s, SUDS client: %s" % (Ctrl.version, soap))
|
||||
|
||||
|
||||
def reloader(path, script, log, dbg1, dbg2, signum, _):
|
||||
"""
|
||||
Signal handler: we have to use execl() because twisted's reactor is not restartable due to some bug in twisted implementation
|
||||
"""
|
||||
log.info("Received Signal %d - restarting..." % signum)
|
||||
if signum == signal.SIGUSR1 and dbg1 not in sys.argv and dbg2 not in sys.argv:
|
||||
sys.argv.append(dbg1) # enforce debug
|
||||
if signum == signal.SIGUSR2 and (dbg1 in sys.argv or dbg2 in sys.argv): # disable debug
|
||||
if dbg1 in sys.argv:
|
||||
sys.argv.remove(dbg1)
|
||||
if dbg2 in sys.argv:
|
||||
sys.argv.remove(dbg2)
|
||||
os.execl(path, script, *sys.argv[1:])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
p = argparse.ArgumentParser(description='Proxy between given SOAP service and Osmocom CTRL protocol.')
|
||||
p.add_argument('-v', '--version', action='version', version=("%(prog)s " + __version__))
|
||||
p.add_argument('-p', '--port', type=int, default=4250, help="Port to use for CTRL interface, defaults to 4250")
|
||||
p.add_argument('-c', '--ctrl', default='localhost', help="Adress to use for CTRL interface, defaults to localhost")
|
||||
p.add_argument('-w', '--wsdl', required=True, help="WSDL URL for SOAP")
|
||||
p.add_argument('-n', '--num', type=int, default=5, help="Max number of concurrent HTTP requests to SOAP server")
|
||||
p.add_argument('-d', '--debug', action='store_true', help="Enable debug log")
|
||||
p.add_argument('-o', '--output', action='store_true', help="Log to STDOUT in addition to SYSLOG")
|
||||
p.add_argument('-l', '--location', help="Override location found in WSDL file (don't use unless you know what you're doing)")
|
||||
args = p.parse_args()
|
||||
|
||||
log = logging.getLogger('CTRL2SOAP')
|
||||
if args.debug:
|
||||
log.setLevel(logging.DEBUG)
|
||||
else:
|
||||
log.setLevel(logging.INFO)
|
||||
log.addHandler(logging.handlers.SysLogHandler('/dev/log'))
|
||||
if args.output:
|
||||
log.addHandler(logging.StreamHandler(sys.stdout))
|
||||
|
||||
reboot = partial(reloader, os.path.abspath(__file__), os.path.basename(__file__), log, '-d', '--debug') # keep in sync with add_argument() call above
|
||||
signal.signal(signal.SIGHUP, reboot)
|
||||
signal.signal(signal.SIGQUIT, reboot)
|
||||
signal.signal(signal.SIGUSR1, reboot) # restart and enabled debug output
|
||||
signal.signal(signal.SIGUSR2, reboot) # restart and disable debug output
|
||||
|
||||
log.info("SOAP proxy %s starting with PID %d ..." % (__version__, os.getpid()))
|
||||
reactor.connectTCP(args.ctrl, args.port, TrapFactory(args.ctrl, args.port, Trap, defer.DeferredSemaphore(args.num), log, args.wsdl, args.location))
|
||||
reactor.run()
|
@@ -1,12 +0,0 @@
|
||||
[Unit]
|
||||
Description=Osmocom Gb proxy
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/osmo-gbproxy -c /etc/osmocom/osmo-gbproxy.cfg
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
RestartPreventExitStatus=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@@ -1,384 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- 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.
|
||||
*/
|
||||
"""
|
||||
|
||||
__version__ = "0.6" # bump this on every non-trivial change
|
||||
|
||||
from ipa import Ctrl, IPA
|
||||
from twisted.internet.protocol import ReconnectingClientFactory
|
||||
from twisted.internet import reactor
|
||||
from twisted.protocols import basic
|
||||
import argparse, logging
|
||||
|
||||
class IPACommon(basic.Int16StringReceiver):
|
||||
"""
|
||||
Generic IPA protocol handler: include some routines for simpler subprotocols.
|
||||
It's not intended as full implementation of all subprotocols, rather common ground and example code.
|
||||
"""
|
||||
def dbg(self, line):
|
||||
"""
|
||||
Debug print helper
|
||||
"""
|
||||
self.factory.log.debug(line)
|
||||
|
||||
def osmo_CTRL(self, data):
|
||||
"""
|
||||
OSMO CTRL protocol
|
||||
Placeholder, see corresponding derived class
|
||||
"""
|
||||
pass
|
||||
|
||||
def osmo_MGCP(self, data):
|
||||
"""
|
||||
OSMO MGCP extension
|
||||
"""
|
||||
self.dbg('OSMO MGCP received %s' % data)
|
||||
|
||||
def osmo_LAC(self, data):
|
||||
"""
|
||||
OSMO LAC extension
|
||||
"""
|
||||
self.dbg('OSMO LAC received %s' % data)
|
||||
|
||||
def osmo_SMSC(self, data):
|
||||
"""
|
||||
OSMO SMSC extension
|
||||
"""
|
||||
self.dbg('OSMO SMSC received %s' % data)
|
||||
|
||||
def osmo_ORC(self, data):
|
||||
"""
|
||||
OSMO ORC extension
|
||||
"""
|
||||
self.dbg('OSMO ORC received %s' % data)
|
||||
|
||||
def osmo_GSUP(self, data):
|
||||
"""
|
||||
OSMO GSUP extension
|
||||
"""
|
||||
self.dbg('OSMO GSUP received %s' % data)
|
||||
|
||||
def osmo_OAP(self, data):
|
||||
"""
|
||||
OSMO OAP extension
|
||||
"""
|
||||
self.dbg('OSMO OAP received %s' % data)
|
||||
|
||||
def osmo_UNKNOWN(self, data):
|
||||
"""
|
||||
OSMO defaul extension handler
|
||||
"""
|
||||
self.dbg('OSMO unknown extension received %s' % data)
|
||||
|
||||
def handle_RSL(self, data, proto, extension):
|
||||
"""
|
||||
RSL protocol handler
|
||||
"""
|
||||
self.dbg('IPA RSL received message with extension %s' % extension)
|
||||
|
||||
def handle_CCM(self, data, proto, msgt):
|
||||
"""
|
||||
CCM (IPA Connection Management)
|
||||
Placeholder, see corresponding derived class
|
||||
"""
|
||||
pass
|
||||
|
||||
def handle_SCCP(self, data, proto, extension):
|
||||
"""
|
||||
SCCP protocol handler
|
||||
"""
|
||||
self.dbg('IPA SCCP received message with extension %s' % extension)
|
||||
|
||||
def handle_OML(self, data, proto, extension):
|
||||
"""
|
||||
OML protocol handler
|
||||
"""
|
||||
self.dbg('IPA OML received message with extension %s' % extension)
|
||||
|
||||
def handle_OSMO(self, data, proto, extension):
|
||||
"""
|
||||
Dispatcher point for OSMO subprotocols based on extension name, lambda default should never happen
|
||||
"""
|
||||
method = getattr(self, 'osmo_' + IPA().ext(extension), lambda: "extension dispatch failure")
|
||||
method(data)
|
||||
|
||||
def handle_MGCP(self, data, proto, extension):
|
||||
"""
|
||||
MGCP protocol handler
|
||||
"""
|
||||
self.dbg('IPA MGCP received message with attribute %s' % extension)
|
||||
|
||||
def handle_UNKNOWN(self, data, proto, extension):
|
||||
"""
|
||||
Default protocol handler
|
||||
"""
|
||||
self.dbg('IPA received message for %s (%s) protocol with attribute %s' % (IPA().proto(proto), proto, extension))
|
||||
|
||||
def process_chunk(self, data):
|
||||
"""
|
||||
Generic message dispatcher for IPA (sub)protocols based on protocol name, lambda default should never happen
|
||||
"""
|
||||
(_, proto, extension, content) = IPA().del_header(data)
|
||||
if content is not None:
|
||||
self.dbg('IPA received %s::%s [%d/%d] %s' % (IPA().proto(proto), IPA().ext_name(proto, extension), len(data), len(content), content))
|
||||
method = getattr(self, 'handle_' + IPA().proto(proto), lambda: "protocol dispatch failure")
|
||||
method(content, proto, extension)
|
||||
|
||||
def dataReceived(self, data):
|
||||
"""
|
||||
Override for dataReceived from Int16StringReceiver because of inherently incompatible interpretation of length
|
||||
If default handler is used than we would always get off-by-1 error (Int16StringReceiver use equivalent of l + 2)
|
||||
"""
|
||||
if len(data):
|
||||
(head, tail) = IPA().split_combined(data)
|
||||
self.process_chunk(head)
|
||||
self.dataReceived(tail)
|
||||
|
||||
def connectionMade(self):
|
||||
"""
|
||||
We have to resetDelay() here to drop internal state to default values to make reconnection logic work
|
||||
Make sure to call this via super() if overriding to keep reconnection logic intact
|
||||
"""
|
||||
addr = self.transport.getPeer()
|
||||
self.dbg('IPA connected to %s:%d peer' % (addr.host, addr.port))
|
||||
self.factory.resetDelay()
|
||||
|
||||
|
||||
class CCM(IPACommon):
|
||||
"""
|
||||
Implementation of CCM protocol for IPA multiplex
|
||||
"""
|
||||
def ack(self):
|
||||
self.transport.write(IPA().id_ack())
|
||||
|
||||
def ping(self):
|
||||
self.transport.write(IPA().ping())
|
||||
|
||||
def pong(self):
|
||||
self.transport.write(IPA().pong())
|
||||
|
||||
def handle_CCM(self, data, proto, msgt):
|
||||
"""
|
||||
CCM (IPA Connection Management)
|
||||
Only basic logic necessary for tests is implemented (ping-pong, id ack etc)
|
||||
"""
|
||||
if msgt == IPA.MSGT['ID_GET']:
|
||||
self.transport.getHandle().sendall(IPA().id_resp(self.factory.ccm_id))
|
||||
# if we call
|
||||
# self.transport.write(IPA().id_resp(self.factory.test_id))
|
||||
# instead, than we would have to also call
|
||||
# reactor.callLater(1, self.ack)
|
||||
# instead of self.ack()
|
||||
# otherwise the writes will be glued together - hence the necessity for ugly hack with 1s timeout
|
||||
# Note: this still might work depending on the IPA implementation details on the other side
|
||||
self.ack()
|
||||
# schedule PING in 4s
|
||||
reactor.callLater(4, self.ping)
|
||||
if msgt == IPA.MSGT['PING']:
|
||||
self.pong()
|
||||
|
||||
|
||||
class CTRL(IPACommon):
|
||||
"""
|
||||
Implementation of Osmocom control protocol for IPA multiplex
|
||||
"""
|
||||
def ctrl_SET(self, data, op_id, v):
|
||||
"""
|
||||
Handle CTRL SET command
|
||||
"""
|
||||
self.dbg('CTRL SET [%s] %s' % (op_id, v))
|
||||
|
||||
def ctrl_SET_REPLY(self, data, op_id, v):
|
||||
"""
|
||||
Handle CTRL SET reply
|
||||
"""
|
||||
self.dbg('CTRL SET REPLY [%s] %s' % (op_id, v))
|
||||
|
||||
def ctrl_GET(self, data, op_id, v):
|
||||
"""
|
||||
Handle CTRL GET command
|
||||
"""
|
||||
self.dbg('CTRL GET [%s] %s' % (op_id, v))
|
||||
|
||||
def ctrl_GET_REPLY(self, data, op_id, v):
|
||||
"""
|
||||
Handle CTRL GET reply
|
||||
"""
|
||||
self.dbg('CTRL GET REPLY [%s] %s' % (op_id, v))
|
||||
|
||||
def ctrl_TRAP(self, data, op_id, v):
|
||||
"""
|
||||
Handle CTRL TRAP command
|
||||
"""
|
||||
self.dbg('CTRL TRAP [%s] %s' % (op_id, v))
|
||||
|
||||
def ctrl_ERROR(self, data, op_id, v):
|
||||
"""
|
||||
Handle CTRL ERROR reply
|
||||
"""
|
||||
self.dbg('CTRL ERROR [%s] %s' % (op_id, v))
|
||||
|
||||
def osmo_CTRL(self, data):
|
||||
"""
|
||||
OSMO CTRL message dispatcher, lambda default should never happen
|
||||
For basic tests only, appropriate handling routines should be replaced: see CtrlServer for example
|
||||
"""
|
||||
self.dbg('OSMO CTRL received %s::%s' % Ctrl().parse(data.decode('utf-8')))
|
||||
(cmd, op_id, v) = data.decode('utf-8').split(' ', 2)
|
||||
method = getattr(self, 'ctrl_' + cmd, lambda: "CTRL unknown command")
|
||||
method(data, op_id, v)
|
||||
|
||||
|
||||
class IPAServer(CCM):
|
||||
"""
|
||||
Test implementation of IPA server
|
||||
Demonstrate CCM opearation by overriding necessary bits from CCM
|
||||
"""
|
||||
def connectionMade(self):
|
||||
"""
|
||||
Keep reconnection logic working by calling routine from CCM
|
||||
Initiate CCM upon connection
|
||||
"""
|
||||
addr = self.transport.getPeer()
|
||||
self.factory.log.info('IPA server: connection from %s:%d client' % (addr.host, addr.port))
|
||||
super(IPAServer, self).connectionMade()
|
||||
self.transport.write(IPA().id_get())
|
||||
|
||||
|
||||
class CtrlServer(CTRL):
|
||||
"""
|
||||
Test implementation of CTRL server
|
||||
Demonstarte CTRL handling by overriding simpler routines from CTRL
|
||||
"""
|
||||
def connectionMade(self):
|
||||
"""
|
||||
Keep reconnection logic working by calling routine from CTRL
|
||||
Send TRAP upon connection
|
||||
Note: we can't use sendString() because of it's incompatibility with IPA interpretation of length prefix
|
||||
"""
|
||||
addr = self.transport.getPeer()
|
||||
self.factory.log.info('CTRL server: connection from %s:%d client' % (addr.host, addr.port))
|
||||
super(CtrlServer, self).connectionMade()
|
||||
self.transport.write(Ctrl().trap('LOL', 'what'))
|
||||
self.transport.write(Ctrl().trap('rulez', 'XXX'))
|
||||
|
||||
def reply(self, r):
|
||||
self.transport.write(Ctrl().add_header(r))
|
||||
|
||||
def ctrl_SET(self, data, op_id, v):
|
||||
"""
|
||||
CTRL SET command: always succeed
|
||||
"""
|
||||
self.dbg('SET [%s] %s' % (op_id, v))
|
||||
self.reply('SET_REPLY %s %s' % (op_id, v))
|
||||
|
||||
def ctrl_GET(self, data, op_id, v):
|
||||
"""
|
||||
CTRL GET command: always fail
|
||||
"""
|
||||
self.dbg('GET [%s] %s' % (op_id, v))
|
||||
self.reply('ERROR %s No variable found' % op_id)
|
||||
|
||||
|
||||
class IPAFactory(ReconnectingClientFactory):
|
||||
"""
|
||||
Generic IPA Client Factory which can be used to store state for various subprotocols and manage connections
|
||||
Note: so far we do not really need separate Factory for acting as a server due to protocol simplicity
|
||||
"""
|
||||
protocol = IPACommon
|
||||
log = None
|
||||
ccm_id = IPA().identity(unit=b'1515/0/1', mac=b'b0:0b:fa:ce:de:ad:be:ef', utype=b'sysmoBTS', name=b'StingRay', location=b'hell', sw=IPA.version.encode('utf-8'))
|
||||
|
||||
def __init__(self, proto=None, log=None, ccm_id=None):
|
||||
if proto:
|
||||
self.protocol = proto
|
||||
if ccm_id:
|
||||
self.ccm_id = ccm_id
|
||||
if log:
|
||||
self.log = log
|
||||
else:
|
||||
self.log = logging.getLogger('IPAFactory')
|
||||
self.log.setLevel(logging.CRITICAL)
|
||||
self.log.addHandler(logging.NullHandler)
|
||||
|
||||
def clientConnectionFailed(self, connector, reason):
|
||||
"""
|
||||
Only necessary for as debugging aid - if we can somehow set parent's class noisy attribute then we can omit this method
|
||||
"""
|
||||
self.log.warning('IPAFactory connection failed: %s' % reason.getErrorMessage())
|
||||
ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
|
||||
|
||||
def clientConnectionLost(self, connector, reason):
|
||||
"""
|
||||
Only necessary for as debugging aid - if we can somehow set parent's class noisy attribute then we can omit this method
|
||||
"""
|
||||
self.log.warning('IPAFactory connection lost: %s' % reason.getErrorMessage())
|
||||
ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
p = argparse.ArgumentParser("Twisted IPA (module v%s) app" % IPA.version)
|
||||
p.add_argument('-v', '--version', action='version', version="%(prog)s v" + __version__)
|
||||
p.add_argument('-p', '--port', type=int, default=4250, help="Port to use for CTRL interface")
|
||||
p.add_argument('-d', '--host', default='localhost', help="Adress to use for CTRL interface")
|
||||
cs = p.add_mutually_exclusive_group()
|
||||
cs.add_argument("-c", "--client", action='store_true', help="asume client role")
|
||||
cs.add_argument("-s", "--server", action='store_true', help="asume server role")
|
||||
ic = p.add_mutually_exclusive_group()
|
||||
ic.add_argument("--ipa", action='store_true', help="use IPA protocol")
|
||||
ic.add_argument("--ctrl", action='store_true', help="use CTRL protocol")
|
||||
args = p.parse_args()
|
||||
test = False
|
||||
|
||||
log = logging.getLogger('TwistedIPA')
|
||||
log.setLevel(logging.DEBUG)
|
||||
log.addHandler(logging.StreamHandler(sys.stdout))
|
||||
|
||||
if args.ctrl:
|
||||
if args.client:
|
||||
# Start osmo-bsc to receive TRAP messages when osmo-bts-* connects to it
|
||||
print('CTRL client, connecting to %s:%d' % (args.host, args.port))
|
||||
reactor.connectTCP(args.host, args.port, IPAFactory(CTRL, log))
|
||||
test = True
|
||||
if args.server:
|
||||
# Use bsc_control.py to issue set/get commands
|
||||
print('CTRL server, listening on port %d' % args.port)
|
||||
reactor.listenTCP(args.port, IPAFactory(CtrlServer, log))
|
||||
test = True
|
||||
if args.ipa:
|
||||
if args.client:
|
||||
# Start osmo-nitb which would initiate A-bis/IP session
|
||||
print('IPA client, connecting to %s ports %d and %d' % (args.host, IPA.TCP_PORT_OML, IPA.TCP_PORT_RSL))
|
||||
reactor.connectTCP(args.host, IPA.TCP_PORT_OML, IPAFactory(CCM, log))
|
||||
reactor.connectTCP(args.host, IPA.TCP_PORT_RSL, IPAFactory(CCM, log))
|
||||
test = True
|
||||
if args.server:
|
||||
# Start osmo-bts-* which would attempt to connect to us
|
||||
print('IPA server, listening on ports %d and %d' % (IPA.TCP_PORT_OML, IPA.TCP_PORT_RSL))
|
||||
reactor.listenTCP(IPA.TCP_PORT_RSL, IPAFactory(IPAServer, log))
|
||||
reactor.listenTCP(IPA.TCP_PORT_OML, IPAFactory(IPAServer, log))
|
||||
test = True
|
||||
if test:
|
||||
reactor.run()
|
||||
else:
|
||||
print("Please specify which protocol in which role you'd like to test.")
|
@@ -1,3 +1 @@
|
||||
SUBDIRS = \
|
||||
examples \
|
||||
$(NULL)
|
||||
SUBDIRS = examples
|
||||
|
21
openbsc/doc/control-interface.txt
Normal file
21
openbsc/doc/control-interface.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
The protocol for the control interface is wrapped inside the ip.access header
|
||||
with the IPAC_PROTO_OSMO protocol ID (0xee). Inside the ip.access header is
|
||||
a struct ipaccess_head_ext with protocol ID 0x00 which indicates the control
|
||||
interface.
|
||||
|
||||
After that the actual protocol is text based:
|
||||
|
||||
* Getting the value of a variable
|
||||
-> GET <id> <var>
|
||||
<- GET_REPLY <id> <var> <val>
|
||||
or ERROR <id> <reason>
|
||||
|
||||
* Setting the value of a variable
|
||||
-> SET <id> <var> <val>
|
||||
<- SET_REPLY <id> <var> <val>
|
||||
or ERROR <id> <reason>
|
||||
|
||||
* A value changes which triggers a trap
|
||||
<- TRAP <var> <val>
|
||||
|
||||
<id> needs to be unique within a connection. '0' is not allowed
|
@@ -1,3 +1,4 @@
|
||||
|
||||
CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,'
|
||||
|
||||
dist-hook:
|
||||
|
@@ -40,6 +40,7 @@ network
|
||||
timer t3119 0
|
||||
timer t3122 0
|
||||
timer t3141 0
|
||||
dtx-used 0
|
||||
subscriber-keep-in-ram 0
|
||||
bts 0
|
||||
type nanobts
|
||||
@@ -54,8 +55,6 @@ network
|
||||
channel allocator ascending
|
||||
rach tx integer 9
|
||||
rach max transmission 7
|
||||
dtx uplink force
|
||||
dtx downlink
|
||||
ip.access unit_id 0 0
|
||||
oml ip.access stream_id 255 line 0
|
||||
neighbor-list mode manual-si5
|
||||
@@ -70,30 +69,30 @@ network
|
||||
nominal power 23
|
||||
max_power_red 20
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
msc
|
||||
ip.access rtp-base 4000
|
||||
timeout-ping 20
|
||||
|
@@ -1,13 +0,0 @@
|
||||
nat
|
||||
bsc 0
|
||||
token lol
|
||||
location_area_code 1234
|
||||
description bsc
|
||||
max-endpoints 32
|
||||
paging forbidden 0
|
||||
bsc 1
|
||||
token wat
|
||||
location_area_code 5678
|
||||
description bsc
|
||||
max-endpoints 32
|
||||
paging forbidden 0
|
@@ -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
|
||||
@@ -62,5 +62,11 @@ nat
|
||||
timeout ping 20
|
||||
timeout pong 5
|
||||
ip-dscp 0
|
||||
bscs-config-file bscs.config
|
||||
access-list bla imsi-allow ^11$
|
||||
|
||||
bsc 0
|
||||
token bla
|
||||
location_area_code 1234
|
||||
description bsc
|
||||
max-endpoints 32
|
||||
paging forbidden 0
|
||||
|
@@ -1,44 +0,0 @@
|
||||
!
|
||||
! OsmoGbProxy (UNKNOWN) configuration saved from vty
|
||||
!!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging timestamp 0
|
||||
logging level all debug
|
||||
logging level gprs debug
|
||||
logging level ns info
|
||||
logging level bssgp debug
|
||||
logging level lglobal notice
|
||||
logging level llapd notice
|
||||
logging level linp notice
|
||||
logging level lmux notice
|
||||
logging level lmi notice
|
||||
logging level lmib notice
|
||||
logging level lsms notice
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
ns
|
||||
nse 666 nsvci 666
|
||||
nse 666 remote-role sgsn
|
||||
! nse 666 encapsulation framerelay-gre
|
||||
! nse 666 remote-ip 172.16.1.70
|
||||
! nse 666 fr-dlci 666
|
||||
timer tns-block 3
|
||||
timer tns-block-retries 3
|
||||
timer tns-reset 3
|
||||
timer tns-reset-retries 3
|
||||
timer tns-test 30
|
||||
timer tns-alive 3
|
||||
timer tns-alive-retries 10
|
||||
encapsulation udp local-port 23000
|
||||
! encapsulation framerelay-gre enabled 1
|
||||
gbproxy
|
||||
sgsn nsei 666
|
||||
core-mobile-country-code 666
|
||||
core-mobile-network-code 6
|
||||
core-access-point-name none match-imsi ^666066|^66607
|
||||
tlli-list max-length 200
|
@@ -1,90 +0,0 @@
|
||||
Here is a simple setup to test GTPHub operations. The IP addresses picked will
|
||||
work well only on a system that creates local addresses (127.0.0.123) on the
|
||||
fly (like linux) -- you may pick of course different IP addresses.
|
||||
|
||||
Overview of the example setup:
|
||||
|
||||
sgsnemu gtphub ggsn
|
||||
127.0.0.1 <--> 127.0.0.3 127.0.0.4 <--> 127.0.0.2
|
||||
|
||||
Prerequisites: openggsn.
|
||||
|
||||
Have a local directory where you store config files and from which you launch
|
||||
the GSNs and the hub (they will store restart counter files in that dir).
|
||||
In it, have these config files:
|
||||
|
||||
ggsn.conf:
|
||||
|
||||
# GGSN local address
|
||||
listen 127.0.0.2
|
||||
|
||||
# End User Addresses are picked from this range
|
||||
net 10.23.42.0/24
|
||||
|
||||
pcodns1 8.8.8.8
|
||||
|
||||
logfile /tmp/foo
|
||||
|
||||
gtphub.conf:
|
||||
|
||||
gtphub
|
||||
bind-to-sgsns 127.0.0.3
|
||||
bind-to-ggsns 127.0.0.4
|
||||
ggsn-proxy 127.0.0.2
|
||||
end
|
||||
|
||||
|
||||
(
|
||||
You may omit the ggsn-proxy if GRX ares is working, or if you add the GRX
|
||||
address and GGSN IP address to /etc/hosts something like:
|
||||
|
||||
127.0.0.2 internet.mnc070.mcc901.gprs
|
||||
|
||||
)
|
||||
|
||||
|
||||
Once the config files are in place, start the programs, in separate terminals.
|
||||
GGSN and SGSN need to be started with root priviliges to be able to create tun
|
||||
interfaces. GTPHub may run as unprivileged user.
|
||||
|
||||
The LD_LIBRARY_PATH below may be needed if OpenGGSN installed to /usr/local.
|
||||
|
||||
|
||||
1. GGSN:
|
||||
|
||||
sudo -s
|
||||
cd <your-test-dir>
|
||||
LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/ggsn -f -c ./ggsn.conf
|
||||
|
||||
2. GTPHub:
|
||||
|
||||
cd <your-test-dir>
|
||||
path/to/openbsc/openbsc/src/gprs/osmo-gtphub -c gtphub.conf #-e 1 #for DEBUG level
|
||||
|
||||
3. SGSN tests:
|
||||
|
||||
sudo -s
|
||||
cd <your-test-dir>
|
||||
/usr/local/bin/sgsnemu --createif -l 127.0.0.1 -r 127.0.0.3 --imsi 420001214365100 --contexts=3
|
||||
|
||||
Add more SGSNs using different IMSIs and local ports (if the same IMSI is used,
|
||||
the GGSN will reuse TEIs and tunnels will be discarded automatically):
|
||||
|
||||
/usr/local/bin/sgsnemu --createif -l 127.0.0.11 -r 127.0.0.3 --imsi 420001214365300 --contexts=3
|
||||
|
||||
This shows the basic setup of GTPHub. Testing internet traffic via sgsnemu
|
||||
still needs some effort to announce a mobile subscriber or the like (I have
|
||||
used a real BTS, osmo-sgsn and a testing SIM in a web phone, instead).
|
||||
|
||||
The core capability of GTPHub is to manage more than two GSNs, e.g. an SGSN
|
||||
contacting various GGSNs over the single GTPHub link. You would configure the
|
||||
SGSN to use one fixed GGSN (sending to gtphub) and gtphub will resolve the
|
||||
GGSNs once it has received the messages. So the SGSN may be behind NAT (add
|
||||
"sgsn-use-sender" to gtphub.conf) and communicate to various GGSNs over a
|
||||
single link to gtphub.
|
||||
|
||||
I hope this helps to get you going.
|
||||
Any suggestions/patches are welcome!
|
||||
|
||||
~Neels
|
||||
|
@@ -1,25 +0,0 @@
|
||||
!
|
||||
! Osmocom gtphub configuration
|
||||
!
|
||||
! This file is used for VTY tests, referenced by openbsc/osmoappdesc.py
|
||||
! For the test, try to use most config commands.
|
||||
!
|
||||
|
||||
line vty
|
||||
no login
|
||||
|
||||
gtphub
|
||||
! Local addresses to listen on and send from, both on one interface.
|
||||
! The side towards SGSN uses nonstandard ports.
|
||||
bind-to-sgsns ctrl 127.0.0.1 12123 user 127.0.0.1 12153
|
||||
! The GGSN side with standard ports.
|
||||
bind-to-ggsns 127.0.0.1
|
||||
|
||||
! Proxy: unconditionally direct all traffic to...
|
||||
sgsn-proxy 127.0.0.4
|
||||
|
||||
! Proxy with nonstandard ports or separate IPs:
|
||||
ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152
|
||||
|
||||
! Add a name server for GGSN resolution
|
||||
grx-dns-add 192.168.0.1
|
@@ -1,25 +0,0 @@
|
||||
!
|
||||
! Osmocom gtphub configuration
|
||||
!
|
||||
|
||||
line vty
|
||||
no login
|
||||
|
||||
gtphub
|
||||
! Local addresses to listen on and send from, each on standard ports
|
||||
! 2123 and 2152. Setting these addresses is mandatory.
|
||||
bind-to-sgsns 127.0.0.1
|
||||
bind-to-ggsns 127.0.0.2
|
||||
|
||||
! Local nonstandard ports or separate IPs:
|
||||
!bind-to-sgsns ctrl 127.0.0.1 2342 user 127.0.0.1 4223
|
||||
|
||||
! Proxy: unconditionally direct all traffic to...
|
||||
!ggsn-proxy 127.0.0.3
|
||||
!sgsn-proxy 127.0.0.4
|
||||
|
||||
! Proxy with nonstandard ports or separate IPs:
|
||||
!ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152
|
||||
|
||||
! Add a name server for GGSN resolution
|
||||
!grx-dns-add 192.168.0.1
|
@@ -60,38 +60,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
trx 1
|
||||
rf_locked 0
|
||||
arfcn 119
|
||||
@@ -99,66 +99,66 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config SDCCH8
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config SDCCH8
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
|
@@ -29,56 +29,56 @@ network
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
trx 1
|
||||
arfcn 123
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
|
@@ -27,59 +27,59 @@ network
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
trx 1
|
||||
arfcn 123
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
bts 1
|
||||
type bs11
|
||||
band GSM900
|
||||
@@ -93,56 +93,56 @@ network
|
||||
max_power_red 0
|
||||
rsl e1 line 1 timeslot 6 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 1 timeslot 7 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 1 timeslot 7 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 7 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 7 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 1 timeslot 7 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 1 timeslot 7 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 7 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 7 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 3
|
||||
trx 1
|
||||
arfcn 124
|
||||
max_power_red 0
|
||||
rsl e1 line 1 timeslot 6 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 3
|
||||
|
@@ -29,28 +29,28 @@ network
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
|
||||
|
@@ -59,41 +59,41 @@ network
|
||||
nominal power 23
|
||||
max_power_red 0
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
trx 1
|
||||
rf_locked 0
|
||||
arfcn 873
|
||||
nominal power 23
|
||||
max_power_red 0
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
timeslot 0
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
|
@@ -59,19 +59,19 @@ network
|
||||
nominal power 23
|
||||
max_power_red 20
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
|
@@ -31,87 +31,87 @@ network
|
||||
max_power_red 24
|
||||
rsl e1 line 0 timeslot 2 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 6 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 0 timeslot 6 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 6 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 6 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 6 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 0 timeslot 6 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 6 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 6 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 3
|
||||
|
||||
trx 1
|
||||
arfcn 870
|
||||
max_power_red 24
|
||||
rsl e1 line 0 timeslot 3 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 3
|
||||
|
||||
trx 2
|
||||
arfcn 874
|
||||
max_power_red 24
|
||||
rsl e1 line 0 timeslot 4 sub-slot full
|
||||
rsl e1 tei 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 3
|
||||
|
@@ -37,6 +37,7 @@ network
|
||||
timer t3119 0
|
||||
timer t3122 0
|
||||
timer t3141 0
|
||||
dtx-used 0
|
||||
subscriber-keep-in-ram 0
|
||||
bts 0
|
||||
type rbs2000
|
||||
@@ -66,38 +67,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
trx 1
|
||||
rf_locked 0
|
||||
arfcn 57
|
||||
@@ -105,38 +106,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 4 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 3
|
||||
trx 2
|
||||
rf_locked 0
|
||||
arfcn 59
|
||||
@@ -144,38 +145,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 7 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 3
|
||||
trx 3
|
||||
rf_locked 0
|
||||
arfcn 61
|
||||
@@ -183,38 +184,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 10 sub-slot full
|
||||
rsl e1 tei 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 3
|
||||
|
||||
e1_input
|
||||
e1_line 0 driver dahdi
|
||||
|
@@ -1,77 +0,0 @@
|
||||
!
|
||||
! OpenBSC configuration saved from vty
|
||||
! !
|
||||
password foo
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
e1_input
|
||||
e1_line 0 driver ipa
|
||||
network
|
||||
network country code 1
|
||||
mobile network code 1
|
||||
short name OpenBSC
|
||||
long name OpenBSC
|
||||
auth policy closed
|
||||
location updating reject cause 13
|
||||
encryption a5 0
|
||||
neci 1
|
||||
rrlp mode none
|
||||
mm info 1
|
||||
handover 0
|
||||
handover window rxlev averaging 10
|
||||
handover window rxqual averaging 1
|
||||
handover window rxlev neighbor averaging 10
|
||||
handover power budget interval 6
|
||||
handover power budget hysteresis 3
|
||||
handover maximum distance 9999
|
||||
timer t3101 10
|
||||
timer t3103 0
|
||||
timer t3105 0
|
||||
timer t3107 0
|
||||
timer t3109 4
|
||||
timer t3111 0
|
||||
timer t3113 60
|
||||
timer t3115 0
|
||||
timer t3117 0
|
||||
timer t3119 0
|
||||
timer t3141 0
|
||||
bts 0
|
||||
type sysmobts
|
||||
band DCS1800
|
||||
cell_identity 0
|
||||
location_area_code 1
|
||||
training_sequence_code 7
|
||||
base_station_id_code 63
|
||||
ms max power 15
|
||||
cell reselection hysteresis 4
|
||||
rxlev access min 0
|
||||
channel allocator ascending
|
||||
rach tx integer 9
|
||||
rach max transmission 7
|
||||
ip.access unit_id 1801 0
|
||||
oml ip.access stream_id 255 line 0
|
||||
gprs mode none
|
||||
trx 0
|
||||
rf_locked 0
|
||||
arfcn 514
|
||||
nominal power 23
|
||||
max_power_red 20
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
@@ -1,33 +0,0 @@
|
||||
digraph G {
|
||||
net [label="gsm_network"]
|
||||
bts [label="gsm_bts"]
|
||||
trx [label="gsm_bts_trx"]
|
||||
ts [label="gsm_bts_trx_ts"]
|
||||
lchan [label="gsm_lchan"]
|
||||
sub [label="gsm_subscriber"]
|
||||
subcon [label="gsm_subscriber_conn"]
|
||||
sccpcon [label="osmo_bsc_sccp_con"]
|
||||
subgrp [label="gsm_subscriber_group"]
|
||||
|
||||
net -> bts
|
||||
bts -> trx
|
||||
trx -> ts
|
||||
ts -> lchan
|
||||
|
||||
lchan -> ts
|
||||
ts -> trx
|
||||
trx -> bts
|
||||
bts -> net
|
||||
|
||||
lchan -> subcon
|
||||
|
||||
subcon -> sub
|
||||
subcon -> sccpcon
|
||||
subcon -> lchan
|
||||
subcon -> lchan [label="ho_lchan"]
|
||||
subcon -> bts
|
||||
subcon -> lchan [label="secondary_lchan"]
|
||||
|
||||
sub -> subgrp
|
||||
subgrp -> net
|
||||
}
|
444
openbsc/doc/sgsn-remote-protocol.txt
Normal file
444
openbsc/doc/sgsn-remote-protocol.txt
Normal file
@@ -0,0 +1,444 @@
|
||||
|
||||
GPRS Subscriber Update Protocol
|
||||
|
||||
1. General
|
||||
|
||||
This document describes the remote protocol that is used by the SGSN to update
|
||||
and manage the local subscriber list. The protocol and the messages are
|
||||
designed after the corresponding MAP messages (see GSM 09.02) with the
|
||||
following differences:
|
||||
|
||||
- The encoding uses TLV structures instead of ASN.1 encodings
|
||||
- Segmentation is not used
|
||||
|
||||
See the specification of the Gr interface (GSM 03.60).
|
||||
|
||||
2. Connection
|
||||
|
||||
The protocol expects that a reliable, ordered, packet boundaries preserving
|
||||
connection is used (e.g. IPA over TCP). The remote peer is either a service
|
||||
that understands the protocol natively or a wrapper service that maps the
|
||||
messages to/from real MAP messages that can be used to directly communicate
|
||||
with an HLR.
|
||||
|
||||
2.1. Using IPA
|
||||
|
||||
By default, the following identifiers should be used:
|
||||
- IPA protocol: 0xee (OSMO)
|
||||
- IPA OSMO protocol extension: 0x05
|
||||
|
||||
2. Procedures
|
||||
|
||||
2.1. Authentication management
|
||||
|
||||
The SGSN sends a SEND_AUTHENTICATION_INFO_REQ message containing the MS's IMSI
|
||||
to the peer. On errors, especially if authentication info is not availabe for
|
||||
that IMSI, the peer returns a SEND_AUTHENTICATION_INFO_ERR message. Otherwise
|
||||
the peer returns a SEND_AUTHENTICATION_INFO_RES message. If this message
|
||||
contains at least one authentication tuple, the SGSN replaces all tuples that
|
||||
are assigned to the subscriber. If the message doesn't contain any tuple the
|
||||
SGSN may reject the Attach Request. (see GSM 09.02, 25.5.6)
|
||||
|
||||
2.2. Location Updating
|
||||
|
||||
The SGSN sends a UPDATE_LOCATION_REQ to the peer. If the request is denied by
|
||||
the network, the peer returns an UPDATE_LOCATION_ERR message to the SGSN.
|
||||
Otherwise the peer returns an UPDATE_LOCATION_RES message containing all
|
||||
information fields that shall be inserted into the subscriber record. If
|
||||
the 'PDP info complete' information element is set in the message, the SGSN
|
||||
clears existing PDP information fields in the subscriber record first.
|
||||
(see GSM 09.02, 19.1.1.8)
|
||||
|
||||
[...]
|
||||
|
||||
3. Message Format
|
||||
|
||||
3.1. General
|
||||
|
||||
Every message is based on the following message format
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
|
||||
If a numeric range is indicated in the 'presence' column, multiple information
|
||||
elements with the same tag may be used in sequence. The information elements
|
||||
shall be sent in the given order. Nevertheless after the generic part the
|
||||
receiver shall be able to received them in any order. Unknown IE shall be
|
||||
ignored.
|
||||
|
||||
3.2.1. Send Authentication Info Request
|
||||
|
||||
SGSN -> Network peer
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
|
||||
3.2.2. Send Authentication Info Error
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
02 Cause GMM cause, M TLV 3
|
||||
04.08: 10.5.5.14
|
||||
|
||||
3.2.3. Send Authentication Info Response
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
03 Auth tuple 4.2.5 0-5 TLV 36
|
||||
|
||||
3.2.4. Update Location Request
|
||||
|
||||
SGSN -> Network peer
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
|
||||
3.2.5. Update Location Error
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
02 Cause GMM cause, M TLV 3
|
||||
04.08: 10.5.5.14
|
||||
|
||||
3.2.6. Update Location Result
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
08 MSISDN 4.2.10 O TLV 0-9
|
||||
04 PDP info complete 4.2.8 O TLV 2
|
||||
05 PDP info 4.2.3 1-10 TLV
|
||||
|
||||
If the PDP info complete IE is present, the old PDP info list shall be cleared.
|
||||
|
||||
3.2.7. Location Cancellation Request
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
06 Cancellation type 4.2.6 M TLV 3
|
||||
|
||||
3.2.8. Location Cancellation Result
|
||||
|
||||
SGSN -> Network peer
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
|
||||
3.2.9. Purge MS Request
|
||||
|
||||
SGSN -> Network peer
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
|
||||
3.2.10. Purge MS Error
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
02 Cause GMM cause, M TLV 3
|
||||
04.08: 10.5.5.14
|
||||
|
||||
3.2.11. Purge MS Result
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
07 Freeze P-TMSI 4.2.8 O TLV 2
|
||||
|
||||
3.2.12. Insert Subscriber Data Request
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
04 PDP info complete 4.2.8 O TLV 2
|
||||
05 PDP info 4.2.3 0-10 TLV
|
||||
|
||||
If the PDP info complete IE is present, the old PDP info list shall be cleared.
|
||||
|
||||
3.2.13. Insert Subscriber Data Error
|
||||
|
||||
SGSN -> Network peer
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
02 Cause GMM cause, M TLV 3
|
||||
04.08: 10.5.5.14
|
||||
|
||||
3.2.14. Insert Subscriber Data Result
|
||||
|
||||
SGSN -> Network peer
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
|
||||
3.2.15. Delete Subscriber Data Request
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
10 PDP context id 4.2.3 0-10 TLV
|
||||
(no conditional IE)
|
||||
|
||||
3.2.16. Delete Subscriber Data Error
|
||||
|
||||
SGSN -> Network peer
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
02 Cause GMM cause, M TLV 3
|
||||
04.08: 10.5.5.14
|
||||
|
||||
3.2.17. Delete Subscriber Data Result
|
||||
|
||||
Network peer -> SGSN
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
|
||||
4. Information Elements
|
||||
|
||||
4.1. General
|
||||
|
||||
[...]
|
||||
|
||||
4.2.1. Message Type
|
||||
|
||||
+---------------------------------------------------+
|
||||
| 8 7 6 5 4 3 2 1 |
|
||||
| |
|
||||
| 0 0 0 0 0 1 0 0 - Update Location Request |
|
||||
| 0 0 0 0 0 1 0 1 - Update Location Error |
|
||||
| 0 0 0 0 0 1 1 0 - Update Location Result |
|
||||
| |
|
||||
| 0 0 0 0 1 0 0 0 - Send Auth Info Request |
|
||||
| 0 0 0 0 1 0 0 1 - Send Auth Info Error |
|
||||
| 0 0 0 0 1 0 1 0 - Send Auth Info Result |
|
||||
| |
|
||||
| 0 0 0 0 1 1 0 0 - Purge MS Request |
|
||||
| 0 0 0 0 1 1 0 1 - Purge MS Error |
|
||||
| 0 0 0 0 1 1 1 0 - Purge MS Result |
|
||||
| |
|
||||
| 0 0 0 1 0 0 0 0 - Insert Subscr. Data Request |
|
||||
| 0 0 0 1 0 0 0 1 - Insert Subscr. Data Error |
|
||||
| 0 0 0 1 0 0 1 0 - Insert Subscr. Data Result |
|
||||
| |
|
||||
| 0 0 0 1 0 1 0 0 - Delete Subscr. Data Request |
|
||||
| 0 0 0 1 0 1 0 1 - Delete Subscr. Data Error |
|
||||
| 0 0 0 1 0 1 1 0 - Delete Subscr. Data Result |
|
||||
| |
|
||||
| 0 0 0 1 1 1 0 0 - Location Cancellation Request |
|
||||
| 0 0 0 1 1 1 0 1 - Location Cancellation Error |
|
||||
| 0 0 0 1 1 1 1 0 - Location Cancellation Result |
|
||||
| |
|
||||
+---------------------------------------------------+
|
||||
|
||||
4.2.2. IP Address
|
||||
|
||||
The value part is encoded like in the Packet data protocol address IE defined
|
||||
in GSM 04.08, 10.5.6.4. PDP type organization must be set to 'IETF allocated
|
||||
address'.
|
||||
|
||||
4.2.3. PDP Info
|
||||
|
||||
This is a container for information elements describing a single PDP.
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
PDP Info IEI M V 1
|
||||
Length of PDP Info IE length, no ext M V 1
|
||||
10 PDP context id big endian int, 1-N C TLV 3
|
||||
11 PDP type 4.2.4 C TLV 4
|
||||
12 Access point name 04.08, 10.5.6.1 C TLV 3-102
|
||||
13 Quality of Service 4.2.11 O TLV 1-20
|
||||
|
||||
The conditional IE are mandantory unless mentioned otherwise.
|
||||
|
||||
4.2.4. PDP Type
|
||||
|
||||
The PDP type value consists of 2 octets that are encoded like octet 4-5 of the
|
||||
End User Address defined in GSM 09.60, 7.9.18.
|
||||
|
||||
8 7 6 5 4 3 2 1
|
||||
+-----------------------------------------------------+
|
||||
| | PDP type IEI | octet 1
|
||||
+-----------------------------------------------------+
|
||||
| Length of PDP type IE contents (2) | octet 2
|
||||
+-----------------------------------------------------+
|
||||
| Spare | PDP type org. | octet 3
|
||||
+-----------------------------------------------------+
|
||||
| PDP type number | octet 4
|
||||
+-----------------------------------------------------+
|
||||
|
||||
The spare bits are left undefined. While 09.60 defines them as '1 1 1 1', there
|
||||
are MAP traces where these bits are set to '0 0 0 0'. So the receiver shall
|
||||
ignore these bits.
|
||||
|
||||
Examples:
|
||||
|
||||
IPv4: PDP type org: 1 (IETF), PDP type number: 0x21
|
||||
IPv6: PDP type org: 1 (IETF), PDP type number: 0x57
|
||||
|
||||
4.2.5. Auth tuple
|
||||
|
||||
This is a container for information elements describing a single authentication
|
||||
tuple.
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Auth. Tuple IEI M V 1
|
||||
Length of Ath Tuple IE length, no ext M V 1
|
||||
20 RAND octet string (16) M TLV 18
|
||||
21 SRES octet string (4) M TLV 6
|
||||
22 Kc octet string (8) M TLV 10
|
||||
|
||||
4.2.6. Cancellation Type
|
||||
|
||||
8 7 6 5 4 3 2 1
|
||||
+-----------------------------------------------------+
|
||||
| | Cancellation type IEI | octet 1
|
||||
+-----------------------------------------------------+
|
||||
| Length of Cancellation Type IE contents (1) | octet 2
|
||||
+-----------------------------------------------------+
|
||||
| Cancellation type number | octet 4
|
||||
+-----------------------------------------------------+
|
||||
|
||||
Where the cancellation type number is:
|
||||
|
||||
+---------------------------------------------------+
|
||||
| 8 7 6 5 4 3 2 1 |
|
||||
| |
|
||||
| 0 0 0 0 0 0 0 0 - Update Procedure |
|
||||
| 0 0 0 0 0 0 0 1 - Subscription Withdraw |
|
||||
+---------------------------------------------------+
|
||||
|
||||
4.2.7. IE Identifier (informational)
|
||||
|
||||
These are the standard values for the IEI. See the message definitions for the
|
||||
IEI that shall be used for the encoding.
|
||||
|
||||
+---------------------------------------------------------+
|
||||
| IEI Info Element Type |
|
||||
| |
|
||||
| 0x01 IMSI Mobile identity, 04.08: 10.5.1.4 |
|
||||
| 0x02 Cause GMM cause, 04.08: 10.5.5.14 |
|
||||
| 0x03 Auth tuple 4.2.5 |
|
||||
| 0x04 PDP info compl 4.2.8 |
|
||||
| 0x05 PDP info 4.2.3 |
|
||||
| 0x06 Cancel type 4.2.6 |
|
||||
| 0x07 Freeze P-TMSI 4.2.8 |
|
||||
| 0x08 MSISDN ISDN-AddressString/octet, 4.2.10 |
|
||||
| 0x10 PDP context id big endian int |
|
||||
| 0x11 PDP type 4.2.4 |
|
||||
| 0x12 APN 04.08, 10.5.6.1 |
|
||||
| 0x13 QoS 4.2.11 |
|
||||
| 0x20 RAND octet string |
|
||||
| 0x21 SRES octet string |
|
||||
| 0x22 Kc octet string |
|
||||
+---------------------------------------------------------+
|
||||
|
||||
|
||||
4.2.8 Empty field
|
||||
|
||||
This is used for flags, if and only if this IE is present, the flag is set.
|
||||
The semantics depend on the IEI and the context.
|
||||
|
||||
8 7 6 5 4 3 2 1
|
||||
+-----------------------------------------------------+
|
||||
| | IEI | octet 1
|
||||
+-----------------------------------------------------+
|
||||
| Length of IE contents (0) | octet 2
|
||||
+-----------------------------------------------------+
|
||||
|
||||
4.2.9. IMSI
|
||||
|
||||
The IMSI is encoded like in octet 4-N of the Called Party BCD Number defined in GSM 04.08, 10.5.4.7.
|
||||
|
||||
8 7 6 5 4 3 2 1
|
||||
+-----------------------------------------------------+
|
||||
| | IMSI IEI | octet 1
|
||||
+-----------------------------------------------------+
|
||||
| Length of IMSI IE contents | octet 2
|
||||
+-----------------------------------------------------+
|
||||
| Number digit 2 | Number digit 1 | octet 3
|
||||
+-----------------------------------------------------+
|
||||
| Number digit 4 | Number digit 3 | octet 4
|
||||
+-----------------------------------------------------+
|
||||
: : :
|
||||
+-----------------------------------------------------+
|
||||
| see note 1) | octet 2+(N+1)div2
|
||||
+-----------------------------------------------------+
|
||||
|
||||
Note 1) Either '1 1 1 1 | Number digit N' (N odd) or
|
||||
'Number digit N | Number digit N-1' (N even),
|
||||
where N is the number of digits.
|
||||
|
||||
4.2.10. ISDN-AddressString / MSISDN / Called Party BCD Number
|
||||
|
||||
The MSISDN is encoded as an ISDN-AddressString in GSM 09.02 and Called Party
|
||||
BCD Number in GSM 04.08. It will be stored by the SGSN and then passed as is
|
||||
to the GGSN during the activation of the primary PDP Context.
|
||||
|
||||
8 7 6 5 4 3 2 1
|
||||
+-----------------------------------------------------+
|
||||
| | IEI | octet 1
|
||||
+-----------------------------------------------------+
|
||||
| Length of IE contents | octet 2
|
||||
+-----------------------------------------------------+
|
||||
| ext | Type of num | Numbering plan | octet 2
|
||||
+-----------------------------------------------------+
|
||||
| Number digit 2 | Number digit 1 | octet 3
|
||||
+-----------------------------------------------------+
|
||||
| Number digit 4 | Number digit 3 | octet 4
|
||||
+-----------------------------------------------------+
|
||||
: : :
|
||||
+-----------------------------------------------------+
|
||||
|
||||
|
||||
4.2.11 Quality of Service Subscribed Service
|
||||
|
||||
This encodes the subscribed QoS of a subscriber. It will be used by the
|
||||
SGSN during the PDP Context activation. If the length of the QoS data
|
||||
is 3 (three) octets it is assumed that these are octets 3-5 of the TS
|
||||
3GPP TS 24.008 Quality of Service Octets. If it is more than three then
|
||||
then it is assumed that the first octet is the Allocation/Retention
|
||||
Priority and the reset are encoded as octets 3-N of 24.008.
|
||||
|
||||
|
||||
8 7 6 5 4 3 2 1
|
||||
+-----------------------------------------------------+
|
||||
| | IEI | octet 1
|
||||
+-----------------------------------------------------+
|
||||
| Length of IE contents | octet 2
|
||||
+-----------------------------------------------------+
|
||||
: : :
|
||||
+-----------------------------------------------------+
|
@@ -1,8 +1,3 @@
|
||||
SUBDIRS = \
|
||||
openbsc \
|
||||
$(NULL)
|
||||
SUBDIRS = openbsc
|
||||
|
||||
noinst_HEADERS = \
|
||||
mISDNif.h \
|
||||
compat_af_isdn.h \
|
||||
$(NULL)
|
||||
noinst_HEADERS = mISDNif.h compat_af_isdn.h
|
||||
|
@@ -1,100 +1,22 @@
|
||||
noinst_HEADERS = \
|
||||
abis_nm.h \
|
||||
abis_om2000.h \
|
||||
abis_rsl.h \
|
||||
arfcn_range_encode.h \
|
||||
auth.h \
|
||||
bsc_msc.h \
|
||||
bsc_msg_filter.h \
|
||||
bsc_nat.h \
|
||||
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_bsc.h \
|
||||
common_cs.h \
|
||||
crc24.h \
|
||||
ctrl.h \
|
||||
db.h \
|
||||
debug.h \
|
||||
e1_config.h \
|
||||
gb_proxy.h \
|
||||
gprs_gb_parse.h \
|
||||
gprs_gmm.h \
|
||||
gprs_llc.h \
|
||||
gprs_llc_xid.h \
|
||||
gprs_sgsn.h \
|
||||
gprs_sndcp.h \
|
||||
gprs_sndcp_comp.h \
|
||||
gprs_sndcp_dcomp.h \
|
||||
gprs_sndcp_pcomp.h \
|
||||
gprs_sndcp_xid.h \
|
||||
gprs_subscriber.h \
|
||||
gprs_utils.h \
|
||||
gsm_04_08.h \
|
||||
gsm_04_11.h \
|
||||
gsm_04_80.h \
|
||||
gsm_data.h \
|
||||
gsm_data_shared.h \
|
||||
gsm_subscriber.h \
|
||||
gsup_client.h \
|
||||
gtphub.h \
|
||||
handover.h \
|
||||
handover_decision.h \
|
||||
ipaccess.h \
|
||||
iu.h \
|
||||
meas_feed.h \
|
||||
meas_rep.h \
|
||||
mgcp.h \
|
||||
mgcp_internal.h \
|
||||
mgcp_transcode.h \
|
||||
misdn.h \
|
||||
mncc.h \
|
||||
mncc_int.h \
|
||||
nat_rewrite_trie.h \
|
||||
network_listen.h \
|
||||
oap_client.h \
|
||||
openbscdefines.h \
|
||||
osmo_bsc.h \
|
||||
osmo_bsc_grace.h \
|
||||
osmo_bsc_rf.h \
|
||||
osmo_msc.h \
|
||||
bsc_msc_data.h \
|
||||
osmux.h \
|
||||
paging.h \
|
||||
pcu_if.h \
|
||||
pcuif_proto.h \
|
||||
rest_octets.h \
|
||||
rrlp.h \
|
||||
rs232.h \
|
||||
rtp_proxy.h \
|
||||
sgsn.h \
|
||||
signal.h \
|
||||
silent_call.h \
|
||||
slhc.h \
|
||||
smpp.h \
|
||||
sms_queue.h \
|
||||
socket.h \
|
||||
system_information.h \
|
||||
token_auth.h \
|
||||
transaction.h \
|
||||
trau_mux.h \
|
||||
trau_upqueue.h \
|
||||
ussd.h \
|
||||
vty.h \
|
||||
v42bis.h \
|
||||
v42bis_private.h \
|
||||
$(NULL)
|
||||
noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
|
||||
gsm_subscriber.h gsm_04_11.h debug.h signal.h \
|
||||
misdn.h chan_alloc.h paging.h ctrl.h \
|
||||
trau_mux.h rs232.h openbscdefines.h rtp_proxy.h \
|
||||
bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \
|
||||
silent_call.h mgcp.h meas_rep.h rest_octets.h \
|
||||
system_information.h handover.h mgcp_internal.h \
|
||||
vty.h socket.h e1_config.h trau_upqueue.h token_auth.h \
|
||||
handover_decision.h rrlp.h \
|
||||
crc24.h gprs_llc.h gprs_gmm.h \
|
||||
gb_proxy.h gprs_sgsn.h gsm_04_08_gprs.h sgsn.h \
|
||||
auth.h osmo_msc.h bsc_msc.h bsc_nat.h \
|
||||
osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h \
|
||||
osmo_msc_data.h osmo_bsc_grace.h sms_queue.h abis_om2000.h \
|
||||
bss.h gsm_data_shared.h ipaccess.h mncc_int.h \
|
||||
arfcn_range_encode.h nat_rewrite_trie.h bsc_nat_callstats.h \
|
||||
osmux.h mgcp_transcode.h gprs_utils.h \
|
||||
gprs_gb_parse.h smpp.h meas_feed.h gprs_gsup_messages.h \
|
||||
gprs_gsup_client.h bsc_msg_filter.h
|
||||
|
||||
openbsc_HEADERS = \
|
||||
bsc_api.h \
|
||||
gsm_04_08.h \
|
||||
meas_rep.h \
|
||||
$(NULL)
|
||||
|
||||
# DO NOT add a newline and '$(NULL)' to this line. That would add a trailing
|
||||
# space to the directory installed: $prefix/include/'openbsc '
|
||||
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
|
||||
openbscdir = $(includedir)/openbsc
|
||||
|
@@ -26,11 +26,6 @@
|
||||
#include <osmocom/gsm/abis_nm.h>
|
||||
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
/* max number of attributes represented as 3GPP TS 52.021 §9.4.62 SW Description array */
|
||||
#define MAX_BTS_ATTR 5
|
||||
|
||||
struct cell_global_id {
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
@@ -71,6 +66,18 @@ struct abis_nm_cfg {
|
||||
int (*sw_act_req)(struct msgb *);
|
||||
};
|
||||
|
||||
struct abis_nm_sw_descr {
|
||||
/* where does it start? how long is it? */
|
||||
const uint8_t *start;
|
||||
size_t len;
|
||||
|
||||
/* the parsed data */
|
||||
const uint8_t *file_id;
|
||||
uint16_t file_id_len;
|
||||
const uint8_t *file_ver;
|
||||
uint16_t file_ver_len;
|
||||
};
|
||||
|
||||
extern int abis_nm_rcvmsg(struct msgb *msg);
|
||||
|
||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const uint8_t *buf, int len);
|
||||
@@ -88,7 +95,7 @@ int abis_nm_conn_terr_traf(struct gsm_bts_trx_ts *ts,
|
||||
uint8_t e1_subslot);
|
||||
int abis_nm_get_attr(struct gsm_bts *bts, uint8_t obj_class,
|
||||
uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
|
||||
const uint8_t *attr, uint8_t attr_len);
|
||||
uint8_t *attr, uint8_t attr_len);
|
||||
int abis_nm_set_bts_attr(struct gsm_bts *bts, uint8_t *attr, int attr_len);
|
||||
int abis_nm_set_radio_attr(struct gsm_bts_trx *trx, uint8_t *attr, int attr_len);
|
||||
int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, uint8_t chan_comb);
|
||||
@@ -172,7 +179,9 @@ int _abis_nm_sendmsg(struct msgb *msg);
|
||||
|
||||
void abis_nm_queue_send_next(struct gsm_bts *bts); /* for bs11_config. */
|
||||
|
||||
int abis_nm_select_newest_sw(const struct abis_nm_sw_desc *sw, const size_t len);
|
||||
int abis_nm_parse_sw_config(const uint8_t *data, const size_t len,
|
||||
struct abis_nm_sw_descr *res, const int res_len);
|
||||
int abis_nm_select_newest_sw(const struct abis_nm_sw_descr *sw, const size_t len);
|
||||
|
||||
/* Helper functions for updating attributes */
|
||||
int abis_nm_update_max_power_red(struct gsm_bts_trx *trx);
|
||||
|
@@ -41,6 +41,13 @@ enum om2k_mo_state {
|
||||
OM2K_MO_S_DISABLED,
|
||||
};
|
||||
|
||||
struct abis_om2k_mo {
|
||||
uint8_t class;
|
||||
uint8_t bts;
|
||||
uint8_t assoc_so;
|
||||
uint8_t inst;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* on-wire format for IS conn group */
|
||||
struct om2k_is_conn_grp {
|
||||
uint16_t icp1;
|
||||
@@ -56,39 +63,6 @@ struct is_conn_group {
|
||||
uint8_t ci;
|
||||
};
|
||||
|
||||
/* on-wire format for CON Path */
|
||||
struct om2k_con_path {
|
||||
uint16_t ccp;
|
||||
uint8_t ci;
|
||||
uint8_t tag;
|
||||
uint8_t tei;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* internal data format for CON group */
|
||||
struct con_group {
|
||||
/* links list of CON groups in BTS */
|
||||
struct llist_head list;
|
||||
struct gsm_bts *bts;
|
||||
/* CON Group ID */
|
||||
uint8_t cg;
|
||||
/* list of CON paths in this group */
|
||||
struct llist_head paths;
|
||||
};
|
||||
|
||||
/* internal data format for CON path */
|
||||
struct con_path {
|
||||
/* links with con_group.paths */
|
||||
struct llist_head list;
|
||||
/* CON Connection Point */
|
||||
uint16_t ccp;
|
||||
/* Contiguity Index */
|
||||
uint8_t ci;
|
||||
/* Tag */
|
||||
uint8_t tag;
|
||||
/* TEI */
|
||||
uint8_t tei;
|
||||
};
|
||||
|
||||
extern const struct abis_om2k_mo om2k_mo_cf;
|
||||
extern const struct abis_om2k_mo om2k_mo_is;
|
||||
extern const struct abis_om2k_mo om2k_mo_con;
|
||||
@@ -110,17 +84,12 @@ int abis_om2k_tx_disable_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo)
|
||||
int abis_om2k_tx_test_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo);
|
||||
int abis_om2k_tx_op_info(struct gsm_bts *bts, const struct abis_om2k_mo *mo,
|
||||
uint8_t operational);
|
||||
int abis_om2k_tx_cap_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo);
|
||||
int abis_om2k_tx_is_conf_req(struct gsm_bts *bts);
|
||||
int abis_om2k_tx_tf_conf_req(struct gsm_bts *bts);
|
||||
int abis_om2k_tx_rx_conf_req(struct gsm_bts_trx *trx);
|
||||
int abis_om2k_tx_tx_conf_req(struct gsm_bts_trx *trx);
|
||||
int abis_om2k_tx_ts_conf_req(struct gsm_bts_trx_ts *ts);
|
||||
|
||||
struct osmo_fsm_inst *om2k_bts_fsm_start(struct gsm_bts *bts);
|
||||
void abis_om2k_bts_init(struct gsm_bts *bts);
|
||||
void abis_om2k_trx_init(struct gsm_bts_trx *trx);
|
||||
|
||||
int abis_om2k_vty_init(void);
|
||||
|
||||
struct vty;
|
||||
|
@@ -22,10 +22,8 @@
|
||||
#ifndef _RSL_H
|
||||
#define _RSL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/gsm/sysinfo.h>
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
|
||||
struct gsm_bts;
|
||||
@@ -33,9 +31,9 @@ struct gsm_lchan;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_bts_trx_ts;
|
||||
|
||||
#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
|
||||
|
||||
int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len);
|
||||
int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
|
||||
const uint8_t *data, int len);
|
||||
int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type,
|
||||
const uint8_t *data, int len);
|
||||
int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr,
|
||||
@@ -49,16 +47,13 @@ int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
|
||||
int rsl_chan_mode_modify_req(struct gsm_lchan *ts);
|
||||
int rsl_encryption_cmd(struct msgb *msg);
|
||||
int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
|
||||
uint8_t *ms_ident, uint8_t chan_needed, bool is_gprs);
|
||||
uint8_t *ms_ident, uint8_t chan_needed);
|
||||
int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val);
|
||||
|
||||
int rsl_data_request(struct msgb *msg, uint8_t link_id);
|
||||
int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id);
|
||||
int rsl_relase_request(struct gsm_lchan *lchan, uint8_t link_id);
|
||||
|
||||
/* Ericcson vendor specific RSL extensions */
|
||||
int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val);
|
||||
|
||||
/* Siemens vendor-specific RSL extensions */
|
||||
int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
|
||||
|
||||
@@ -110,9 +105,5 @@ int rsl_start_t3109(struct gsm_lchan *lchan);
|
||||
|
||||
int rsl_direct_rf_release(struct gsm_lchan *lchan);
|
||||
|
||||
void dyn_ts_init(struct gsm_bts_trx_ts *ts);
|
||||
int dyn_ts_switchover_start(struct gsm_bts_trx_ts *ts,
|
||||
enum gsm_phys_chan_config to_pchan);
|
||||
|
||||
#endif /* RSL_MT_H */
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum gsm48_range {
|
||||
enum {
|
||||
ARFCN_RANGE_INVALID = -1,
|
||||
ARFCN_RANGE_128 = 127,
|
||||
ARFCN_RANGE_256 = 255,
|
||||
@@ -14,8 +14,8 @@ enum gsm48_range {
|
||||
#define RANGE_ENC_MAX_ARFCNS 29
|
||||
|
||||
int range_enc_determine_range(const int *arfcns, int size, int *f0_out);
|
||||
int range_enc_arfcns(enum gsm48_range rng, const int *arfcns, int sze, int *out, int idx);
|
||||
int range_enc_find_index(enum gsm48_range rng, const int *arfcns, int size);
|
||||
int range_enc_arfcns(const int rng, const int *arfcns, int sze, int *out, int idx);
|
||||
int range_enc_find_index(const int rng, const int *arfcns, int size);
|
||||
int range_enc_filter_arfcns(int *arfcns, const int sze, const int f0, int *f0_included);
|
||||
|
||||
int range_enc_range128(uint8_t *chan_list, int f0, int *w);
|
||||
|
@@ -1,25 +1,16 @@
|
||||
#ifndef _AUTH_H
|
||||
#define _AUTH_H
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
struct gsm_auth_tuple;
|
||||
struct gsm_subscriber;
|
||||
|
||||
enum auth_action {
|
||||
AUTH_ERROR = -1, /* Internal error */
|
||||
AUTH_NOT_AVAIL = 0, /* No auth tuple available */
|
||||
AUTH_DO_AUTH_THEN_CIPH = 1, /* Firsth authenticate, then cipher */
|
||||
AUTH_DO_AUTH_THAN_CIPH = 1, /* Firsth authenticate, then cipher */
|
||||
AUTH_DO_CIPH = 2, /* Only ciphering */
|
||||
AUTH_DO_AUTH = 3, /* Only authentication, no ciphering */
|
||||
};
|
||||
|
||||
extern const struct value_string auth_action_names[];
|
||||
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(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr, int key_seq);
|
||||
|
||||
|
@@ -40,7 +40,7 @@ struct bsc_api {
|
||||
* not implemented AMR5.9 will be used.
|
||||
*/
|
||||
void (*mr_config)(struct gsm_subscriber_connection *conn,
|
||||
struct gsm_lchan *lchan, int full_rate);
|
||||
uint8_t *mr_ms_lv, uint8_t *mr_bts_lv);
|
||||
};
|
||||
|
||||
int bsc_api_init(struct gsm_network *network, struct bsc_api *api);
|
||||
@@ -52,4 +52,6 @@ int gsm0808_page(struct gsm_bts *bts, unsigned int page_group,
|
||||
unsigned int mi_len, uint8_t *mi, int chan_type);
|
||||
int gsm0808_clear(struct gsm_subscriber_connection *conn);
|
||||
|
||||
struct llist_head *bsc_api_sub_connections(struct gsm_network *net);
|
||||
|
||||
#endif
|
||||
|
@@ -60,6 +60,6 @@ void bsc_msc_schedule_connect(struct bsc_msc_connection *);
|
||||
|
||||
void bsc_msc_lost(struct bsc_msc_connection *);
|
||||
|
||||
struct msgb *bsc_msc_id_get_resp(int fixed, const char *token, const uint8_t *res, int len);
|
||||
struct msgb *bsc_msc_id_get_resp(const char *token);
|
||||
|
||||
#endif
|
||||
|
@@ -35,7 +35,6 @@
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
#include <regex.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DIR_BSC 1
|
||||
#define DIR_MSC 2
|
||||
@@ -85,7 +84,6 @@ struct bsc_connection {
|
||||
|
||||
/* do we know anything about this BSC? */
|
||||
int authenticated;
|
||||
uint8_t last_rand[16];
|
||||
|
||||
/* the fd we use to communicate */
|
||||
struct osmo_wqueue write_queue;
|
||||
@@ -149,8 +147,6 @@ enum bsc_cfg_ctr {
|
||||
struct bsc_config {
|
||||
struct llist_head entry;
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t key_present;
|
||||
char *token;
|
||||
int nr;
|
||||
|
||||
@@ -165,10 +161,6 @@ struct bsc_config {
|
||||
/* audio handling */
|
||||
int max_endpoints;
|
||||
|
||||
/* used internally for reload handling */
|
||||
bool remove;
|
||||
bool token_updated;
|
||||
|
||||
/* backpointer */
|
||||
struct bsc_nat *nat;
|
||||
|
||||
@@ -269,11 +261,6 @@ struct bsc_nat {
|
||||
|
||||
struct bsc_endpoint *bsc_endpoints;
|
||||
|
||||
/* path to file with BSC config */
|
||||
char *include_file;
|
||||
char *include_base;
|
||||
char *resolved_path;
|
||||
|
||||
/* filter */
|
||||
char *acc_lst_name;
|
||||
|
||||
@@ -330,10 +317,8 @@ struct bsc_nat_ussd_con {
|
||||
};
|
||||
|
||||
/* create and init the structures */
|
||||
struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token,
|
||||
unsigned int number);
|
||||
struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token);
|
||||
struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num);
|
||||
struct bsc_config *bsc_config_by_token(struct bsc_nat *nat, const char *token, int len);
|
||||
void bsc_config_free(struct bsc_config *);
|
||||
void bsc_config_add_lac(struct bsc_config *cfg, int lac);
|
||||
void bsc_config_del_lac(struct bsc_config *cfg, int lac);
|
||||
@@ -383,7 +368,7 @@ int bsc_mgcp_nat_init(struct bsc_nat *nat);
|
||||
|
||||
struct nat_sccp_connection *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
|
||||
struct msgb *bsc_mgcp_rewrite(char *input, int length, int endp, const char *ip,
|
||||
int port, int osmux, int *first_payload_type, int mode_set);
|
||||
int port, int osmux, int *payload_type, int mode_set);
|
||||
void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);
|
||||
|
||||
void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
|
||||
@@ -434,8 +419,7 @@ void bsc_nat_num_rewr_entry_adapt(void *ctx, struct llist_head *head, const stru
|
||||
void bsc_nat_send_mgcp_to_msc(struct bsc_nat *bsc_nat, struct msgb *msg);
|
||||
void bsc_nat_handle_mgcp(struct bsc_nat *bsc, struct msgb *msg);
|
||||
|
||||
struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat,
|
||||
const char *bind_addr, int port);
|
||||
struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat, int port);
|
||||
void bsc_nat_ctrl_del_pending(struct bsc_cmd_list *pending);
|
||||
int bsc_nat_handle_ctrlif_msg(struct bsc_connection *bsc, struct msgb *msg);
|
||||
|
||||
|
@@ -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);
|
@@ -1,13 +1,11 @@
|
||||
#ifndef _BSS_H_
|
||||
#define _BSS_H_
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
struct gsm_network;
|
||||
struct msgb;
|
||||
|
||||
/* start and stop network */
|
||||
extern int bsc_network_alloc(mncc_recv_cb_t mncc_recv);
|
||||
extern int bsc_network_configure(const char *cfg_file);
|
||||
extern int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *), const char *cfg_file);
|
||||
extern int bsc_shutdown_net(struct gsm_network *net);
|
||||
|
||||
/* register all supported BTS */
|
||||
|
@@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <openbsc/common_cs.h>
|
||||
|
||||
struct gsm_network *bsc_network_init(void *ctx,
|
||||
uint16_t country_code,
|
||||
uint16_t network_code,
|
||||
mncc_recv_cb_t mncc_recv);
|
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct msgb;
|
||||
struct gsm_network;
|
||||
|
||||
typedef int (*mncc_recv_cb_t)(struct gsm_network *, struct msgb *);
|
||||
|
||||
struct vty;
|
||||
|
||||
#define MAX_A5_KEY_LEN (128/8)
|
||||
|
||||
struct gsm_encr {
|
||||
uint8_t alg_id;
|
||||
uint8_t key_len;
|
||||
uint8_t key[MAX_A5_KEY_LEN];
|
||||
};
|
||||
|
||||
struct gsm_network *gsm_network_init(void *ctx,
|
||||
uint16_t country_code,
|
||||
uint16_t network_code,
|
||||
mncc_recv_cb_t mncc_recv);
|
||||
|
||||
int common_cs_vty_init(struct gsm_network *network,
|
||||
int (* config_write_net )(struct vty *));
|
||||
struct gsm_network *gsmnet_from_vty(struct vty *v);
|
@@ -1,4 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net,
|
||||
const char *bind_addr, uint16_t port);
|
||||
struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net, uint16_t port);
|
||||
|
@@ -20,8 +20,6 @@
|
||||
#ifndef _DB_H
|
||||
#define _DB_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "gsm_subscriber.h"
|
||||
|
||||
struct gsm_equipment;
|
||||
@@ -37,15 +35,13 @@ 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_create_subscriber(const char *imsi, uint64_t prefix);
|
||||
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_exten(struct gsm_subscriber *subscriber, uint64_t prefix);
|
||||
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);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef _DEBUG_H
|
||||
#define _DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
@@ -28,22 +29,39 @@ enum {
|
||||
DBSSGP,
|
||||
DLLC,
|
||||
DSNDCP,
|
||||
DSLHC,
|
||||
DNAT,
|
||||
DCTRL,
|
||||
DSMPP,
|
||||
DFILTER,
|
||||
DGTPHUB,
|
||||
DRANAP,
|
||||
DSUA,
|
||||
DV42BIS,
|
||||
DPCU,
|
||||
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_filter_vlr_subscr(struct log_target *target,
|
||||
struct gsm_subscriber *vlr_subscr);
|
||||
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 */
|
||||
|
@@ -48,24 +48,8 @@ enum gbproxy_peer_ctr {
|
||||
GBPROX_PEER_CTR_PATCH_ERR,
|
||||
GBPROX_PEER_CTR_ATTACH_REQS,
|
||||
GBPROX_PEER_CTR_ATTACH_REJS,
|
||||
GBPROX_PEER_CTR_ATTACH_ACKS,
|
||||
GBPROX_PEER_CTR_ATTACH_COMPLS,
|
||||
GBPROX_PEER_CTR_RA_UPD_REQS,
|
||||
GBPROX_PEER_CTR_RA_UPD_REJS,
|
||||
GBPROX_PEER_CTR_RA_UPD_ACKS,
|
||||
GBPROX_PEER_CTR_RA_UPD_COMPLS,
|
||||
GBPROX_PEER_CTR_GMM_STATUS_BSS,
|
||||
GBPROX_PEER_CTR_GMM_STATUS_SGSN,
|
||||
GBPROX_PEER_CTR_DETACH_REQS,
|
||||
GBPROX_PEER_CTR_DETACH_ACKS,
|
||||
GBPROX_PEER_CTR_PDP_ACT_REQS,
|
||||
GBPROX_PEER_CTR_PDP_ACT_REJS,
|
||||
GBPROX_PEER_CTR_PDP_ACT_ACKS,
|
||||
GBPROX_PEER_CTR_PDP_DEACT_REQS,
|
||||
GBPROX_PEER_CTR_PDP_DEACT_ACKS,
|
||||
GBPROX_PEER_CTR_TLLI_UNKNOWN,
|
||||
GBPROX_PEER_CTR_TLLI_CACHE_SIZE,
|
||||
GBPROX_PEER_CTR_LAST,
|
||||
};
|
||||
|
||||
enum gbproxy_keep_mode {
|
||||
@@ -117,6 +101,10 @@ struct gbproxy_config {
|
||||
|
||||
/* IMSI checking/matching */
|
||||
struct gbproxy_match matches[GBPROX_MATCH_LAST];
|
||||
|
||||
/* Used to generate identifiers */
|
||||
unsigned bss_ptmsi_state;
|
||||
unsigned sgsn_tlli_state;
|
||||
};
|
||||
|
||||
struct gbproxy_patch_state {
|
||||
@@ -208,7 +196,7 @@ struct gbproxy_link_info *gbproxy_update_link_state_ul(
|
||||
struct gbproxy_link_info *gbproxy_update_link_state_dl(
|
||||
struct gbproxy_peer *peer, time_t now,
|
||||
struct gprs_gb_parse_context *parse_ctx);
|
||||
int gbproxy_update_link_state_after(
|
||||
void gbproxy_update_link_state_after(
|
||||
struct gbproxy_peer *peer, struct gbproxy_link_info *link_info,
|
||||
time_t now, struct gprs_gb_parse_context *parse_ctx);
|
||||
int gbproxy_remove_stale_link_infos(struct gbproxy_peer *peer, time_t now);
|
||||
|
@@ -4,21 +4,15 @@
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause);
|
||||
int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
|
||||
uint8_t cause, uint8_t pco_len, uint8_t *pco_v);
|
||||
int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp);
|
||||
int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
|
||||
|
||||
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
|
||||
bool drop_cipherable);
|
||||
int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
|
||||
uint16_t *sai);
|
||||
int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme);
|
||||
int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx);
|
||||
int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg,
|
||||
struct gprs_llc_llme *llme);
|
||||
int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg);
|
||||
void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx);
|
||||
void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx, int gmm_cause);
|
||||
void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx, int gmm_cause);
|
||||
@@ -30,6 +24,4 @@ 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, bool use_x213_nsap);
|
||||
|
||||
#endif /* _GPRS_GMM_H */
|
||||
|
@@ -23,38 +23,32 @@
|
||||
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
#include <openbsc/oap_client.h>
|
||||
|
||||
#define GSUP_CLIENT_RECONNECT_INTERVAL 10
|
||||
#define GSUP_CLIENT_PING_INTERVAL 20
|
||||
#define GPRS_GSUP_RECONNECT_INTERVAL 10
|
||||
#define GPRS_GSUP_PING_INTERVAL 20
|
||||
|
||||
struct msgb;
|
||||
struct ipa_client_conn;
|
||||
struct gsup_client;
|
||||
struct gprs_gsup_client;
|
||||
|
||||
/* Expects message in msg->l2h */
|
||||
typedef int (*gsup_client_read_cb_t)(struct gsup_client *gsupc,
|
||||
struct msgb *msg);
|
||||
typedef int (*gprs_gsup_read_cb_t)(struct gprs_gsup_client *gsupc, struct msgb *msg);
|
||||
|
||||
struct gsup_client {
|
||||
struct ipa_client_conn *link;
|
||||
gsup_client_read_cb_t read_cb;
|
||||
void *data;
|
||||
struct gprs_gsup_client {
|
||||
struct ipa_client_conn *link;
|
||||
gprs_gsup_read_cb_t read_cb;
|
||||
void *data;
|
||||
|
||||
struct oap_client_state oap_state;
|
||||
|
||||
struct osmo_timer_list ping_timer;
|
||||
struct osmo_timer_list connect_timer;
|
||||
int is_connected;
|
||||
int got_ipa_pong;
|
||||
struct osmo_timer_list ping_timer;
|
||||
struct osmo_timer_list connect_timer;
|
||||
int is_connected;
|
||||
int got_ipa_pong;
|
||||
};
|
||||
|
||||
struct gsup_client *gsup_client_create(const char *ip_addr,
|
||||
unsigned int tcp_port,
|
||||
gsup_client_read_cb_t read_cb,
|
||||
struct oap_client_config *oap_config);
|
||||
struct gprs_gsup_client *gprs_gsup_client_create(const char *ip_addr,
|
||||
unsigned int tcp_port,
|
||||
gprs_gsup_read_cb_t read_cb);
|
||||
|
||||
void gsup_client_destroy(struct gsup_client *gsupc);
|
||||
int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg);
|
||||
struct msgb *gsup_client_msgb_alloc(void);
|
||||
void gprs_gsup_client_destroy(struct gprs_gsup_client *gsupc);
|
||||
int gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
|
||||
struct msgb *gprs_gsup_msgb_alloc(void);
|
||||
|
116
openbsc/include/openbsc/gprs_gsup_messages.h
Normal file
116
openbsc/include/openbsc/gprs_gsup_messages.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* GPRS Subscriber Update Protocol message encoder/decoder */
|
||||
|
||||
/* (C) 2014 by Sysmocom s.f.m.c. GmbH
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Jacob Erlbeck
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <openbsc/gsm_04_08_gprs.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
/* Needed for GSM_IMSI_LENGTH: */
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
|
||||
#define GPRS_GSUP_MAX_NUM_PDP_INFO 10 /* GSM 09.02 limits this to 50 */
|
||||
#define GPRS_GSUP_MAX_NUM_AUTH_INFO 5
|
||||
#define GPRS_GSUP_MAX_MSISDN_LEN 9
|
||||
|
||||
#define GPRS_GSUP_PDP_TYPE_SIZE 2
|
||||
|
||||
enum gprs_gsup_iei {
|
||||
GPRS_GSUP_IMSI_IE = 0x01,
|
||||
GPRS_GSUP_CAUSE_IE = 0x02,
|
||||
GPRS_GSUP_AUTH_TUPLE_IE = 0x03,
|
||||
GPRS_GSUP_PDP_INFO_COMPL_IE = 0x04,
|
||||
GPRS_GSUP_PDP_INFO_IE = 0x05,
|
||||
GPRS_GSUP_CANCEL_TYPE_IE = 0x06,
|
||||
GPRS_GSUP_FREEZE_PTMSI_IE = 0x07,
|
||||
GPRS_GSUP_MSISDN_IE = 0x08,
|
||||
GPRS_GSUP_PDP_CONTEXT_ID_IE = 0x10,
|
||||
GPRS_GSUP_PDP_TYPE_IE = 0x11,
|
||||
GPRS_GSUP_ACCESS_POINT_NAME_IE = 0x12,
|
||||
GPRS_GSUP_PDP_QOS_IE = 0x13,
|
||||
GPRS_GSUP_RAND_IE = 0x20,
|
||||
GPRS_GSUP_SRES_IE = 0x21,
|
||||
GPRS_GSUP_KC_IE = 0x22
|
||||
};
|
||||
|
||||
enum gprs_gsup_message_type {
|
||||
GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST = 0b00000100,
|
||||
GPRS_GSUP_MSGT_UPDATE_LOCATION_ERROR = 0b00000101,
|
||||
GPRS_GSUP_MSGT_UPDATE_LOCATION_RESULT = 0b00000110,
|
||||
|
||||
GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST = 0b00001000,
|
||||
GPRS_GSUP_MSGT_SEND_AUTH_INFO_ERROR = 0b00001001,
|
||||
GPRS_GSUP_MSGT_SEND_AUTH_INFO_RESULT = 0b00001010,
|
||||
|
||||
GPRS_GSUP_MSGT_PURGE_MS_REQUEST = 0b00001100,
|
||||
GPRS_GSUP_MSGT_PURGE_MS_ERROR = 0b00001101,
|
||||
GPRS_GSUP_MSGT_PURGE_MS_RESULT = 0b00001110,
|
||||
|
||||
GPRS_GSUP_MSGT_INSERT_DATA_REQUEST = 0b00010000,
|
||||
GPRS_GSUP_MSGT_INSERT_DATA_ERROR = 0b00010001,
|
||||
GPRS_GSUP_MSGT_INSERT_DATA_RESULT = 0b00010010,
|
||||
|
||||
GPRS_GSUP_MSGT_DELETE_DATA_REQUEST = 0b00010100,
|
||||
GPRS_GSUP_MSGT_DELETE_DATA_ERROR = 0b00010101,
|
||||
GPRS_GSUP_MSGT_DELETE_DATA_RESULT = 0b00010110,
|
||||
|
||||
GPRS_GSUP_MSGT_LOCATION_CANCEL_REQUEST = 0b00011100,
|
||||
GPRS_GSUP_MSGT_LOCATION_CANCEL_ERROR = 0b00011101,
|
||||
GPRS_GSUP_MSGT_LOCATION_CANCEL_RESULT = 0b00011110,
|
||||
};
|
||||
|
||||
#define GPRS_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00)
|
||||
#define GPRS_GSUP_IS_MSGT_ERROR(msgt) (((msgt) & 0b00000011) == 0b01)
|
||||
#define GPRS_GSUP_TO_MSGT_ERROR(msgt) (((msgt) & 0b11111100) | 0b01)
|
||||
|
||||
enum gprs_gsup_cancel_type {
|
||||
GPRS_GSUP_CANCEL_TYPE_UPDATE = 1, /* on wire: 0 */
|
||||
GPRS_GSUP_CANCEL_TYPE_WITHDRAW = 2, /* on wire: 1 */
|
||||
};
|
||||
|
||||
struct gprs_gsup_pdp_info {
|
||||
unsigned int context_id;
|
||||
int have_info;
|
||||
uint16_t pdp_type;
|
||||
const uint8_t *apn_enc;
|
||||
size_t apn_enc_len;
|
||||
const uint8_t *qos_enc;
|
||||
size_t qos_enc_len;
|
||||
};
|
||||
|
||||
struct gprs_gsup_message {
|
||||
enum gprs_gsup_message_type message_type;
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
enum gsm48_gmm_cause cause;
|
||||
enum gprs_gsup_cancel_type cancel_type;
|
||||
int pdp_info_compl;
|
||||
int freeze_ptmsi;
|
||||
struct gsm_auth_tuple auth_tuples[GPRS_GSUP_MAX_NUM_AUTH_INFO];
|
||||
size_t num_auth_tuples;
|
||||
struct gprs_gsup_pdp_info pdp_infos[GPRS_GSUP_MAX_NUM_PDP_INFO];
|
||||
size_t num_pdp_infos;
|
||||
const uint8_t *msisdn_enc;
|
||||
size_t msisdn_enc_len;
|
||||
};
|
||||
|
||||
int gprs_gsup_decode(const uint8_t *data, size_t data_len,
|
||||
struct gprs_gsup_message *gsup_msg);
|
||||
void gprs_gsup_encode(struct msgb *msg, const struct gprs_gsup_message *gsup_msg);
|
@@ -2,9 +2,7 @@
|
||||
#define _GPRS_LLC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
#include <openbsc/gprs_llc_xid.h>
|
||||
|
||||
/* Section 4.7 LLC Layer Structure */
|
||||
enum gprs_llc_sapi {
|
||||
@@ -46,8 +44,6 @@ enum gprs_llc_xid_type {
|
||||
GPRS_LLC_XID_T_RESET = 12,
|
||||
};
|
||||
|
||||
extern const struct value_string gprs_llc_xid_type_names[];
|
||||
|
||||
/* TS 04.64 Section 7.1.2 Table 7: LLC layer primitives (GMM/SNDCP/SMS/TOM) */
|
||||
/* TS 04.65 Section 5.1.2 Table 2: Service primitives used by SNDCP */
|
||||
enum gprs_llc_primitive {
|
||||
@@ -159,32 +155,13 @@ struct gprs_llc_llme {
|
||||
|
||||
/* Crypto parameters */
|
||||
enum gprs_ciph_algo algo;
|
||||
uint8_t kc[16];
|
||||
uint8_t cksn;
|
||||
/* 3GPP TS 44.064 § 8.9.2: */
|
||||
uint32_t iov_ui;
|
||||
uint8_t kc[8];
|
||||
|
||||
/* over which BSSGP BTS ctx do we need to transmit */
|
||||
uint16_t bvci;
|
||||
uint16_t nsei;
|
||||
struct gprs_llc_lle lle[NUM_SAPIS];
|
||||
|
||||
/* Copy of the XID fields we have sent with the last
|
||||
* network originated XID-Request. Since the phone
|
||||
* may strip the optional fields in the confirmation
|
||||
* we need to remeber those fields in order to be
|
||||
* able to create the compression entity. */
|
||||
struct llist_head *xid;
|
||||
|
||||
/* Compression entities */
|
||||
struct {
|
||||
/* In these two list_heads we will store the
|
||||
* data and protocol compression entities,
|
||||
* together with their compression states */
|
||||
struct llist_head *proto;
|
||||
struct llist_head *data;
|
||||
} comp;
|
||||
|
||||
/* Internal management */
|
||||
uint32_t age_timestamp;
|
||||
};
|
||||
@@ -231,21 +208,16 @@ int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv);
|
||||
|
||||
/* LL-UNITDATA.req */
|
||||
int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
|
||||
struct sgsn_mm_ctx *mmctx, bool encryptable);
|
||||
void *mmctx);
|
||||
|
||||
/* Chapter 7.2.1.2 LLGMM-RESET.req */
|
||||
int gprs_llgmm_reset(struct gprs_llc_llme *llme);
|
||||
int gprs_llgmm_reset_oldmsg(struct msgb* oldmsg, uint8_t sapi,
|
||||
struct gprs_llc_llme *llme);
|
||||
|
||||
/* Set of LL-XID negotiation (See also: TS 101 351, Section 7.2.2.4) */
|
||||
int gprs_ll_xid_req(struct gprs_llc_lle *lle,
|
||||
struct gprs_llc_xid_field *l3_xid_field);
|
||||
int gprs_llgmm_reset_oldmsg(struct msgb* oldmsg, uint8_t sapi);
|
||||
|
||||
/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */
|
||||
int gprs_llgmm_assign(struct gprs_llc_llme *llme,
|
||||
uint32_t old_tlli, uint32_t new_tlli);
|
||||
int gprs_llgmm_unassign(struct gprs_llc_llme *llme);
|
||||
uint32_t old_tlli, uint32_t new_tlli,
|
||||
enum gprs_ciph_algo alg, const uint8_t *kc);
|
||||
|
||||
int gprs_llc_init(const char *cipher_plugin_path);
|
||||
int gprs_llc_vty_init(void);
|
||||
@@ -267,12 +239,11 @@ static inline int gprs_llc_is_retransmit(uint16_t nu, uint16_t vur)
|
||||
}
|
||||
|
||||
/* LLC low level functions */
|
||||
void gprs_llme_copy_key(struct sgsn_mm_ctx *mm, struct gprs_llc_llme *llme);
|
||||
|
||||
/* parse a GPRS LLC header, also check for invalid frames */
|
||||
int gprs_llc_hdr_parse(struct gprs_llc_hdr_parsed *ghp,
|
||||
uint8_t *llc_hdr, int len);
|
||||
void gprs_llc_hdr_dump(struct gprs_llc_hdr_parsed *gph, struct gprs_llc_lle *lle);
|
||||
void gprs_llc_hdr_dump(struct gprs_llc_hdr_parsed *gph);
|
||||
int gprs_llc_fcs(uint8_t *data, unsigned int len);
|
||||
|
||||
|
||||
|
@@ -1,57 +0,0 @@
|
||||
/* GPRS LLC XID field encoding/decoding as per 3GPP TS 44.064 */
|
||||
|
||||
/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
/* 3GPP TS 44.064 6.4.1.6 Exchange Identification (XID)
|
||||
command/response parameter field */
|
||||
struct gprs_llc_xid_field {
|
||||
struct llist_head list;
|
||||
uint8_t type; /* See also Table 6: LLC layer parameter
|
||||
negotiation */
|
||||
uint8_t *data; /* Payload data (memory is owned by the
|
||||
* creator of the struct) */
|
||||
unsigned int data_len; /* Payload length */
|
||||
};
|
||||
|
||||
/* Transform a list with XID fields into a XID message (dst) */
|
||||
int gprs_llc_compile_xid(uint8_t *dst, int dst_maxlen,
|
||||
const struct llist_head *xid_fields);
|
||||
|
||||
/* Transform a XID message (dst) into a list of XID fields */
|
||||
struct llist_head *gprs_llc_parse_xid(const void *ctx, const uint8_t *src,
|
||||
int src_len);
|
||||
|
||||
/* Create a duplicate of an XID-Field */
|
||||
struct gprs_llc_xid_field *gprs_llc_dup_xid_field(const void *ctx,
|
||||
const struct gprs_llc_xid_field *xid_field);
|
||||
|
||||
/* Copy an llist with xid fields */
|
||||
struct llist_head *gprs_llc_copy_xid(const void *ctx,
|
||||
const struct llist_head *xid_fields);
|
||||
|
||||
/* Dump a list with XID fields (Debug) */
|
||||
void gprs_llc_dump_xid_fields(const struct llist_head *xid_fields,
|
||||
unsigned int logl);
|
||||
|
@@ -9,21 +9,22 @@
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
|
||||
#include <osmocom/crypt/gprs_cipher.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
#define GSM_IMSI_LENGTH 17
|
||||
#define GSM_IMEI_LENGTH 17
|
||||
#define GSM_EXTENSION_LENGTH 15
|
||||
#define GSM_APN_LENGTH 102
|
||||
|
||||
struct gprs_llc_lle;
|
||||
struct ctrl_handle;
|
||||
struct gprs_subscr;
|
||||
struct gsm_subscriber;
|
||||
|
||||
enum gsm48_gsm_cause;
|
||||
|
||||
/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */
|
||||
enum gprs_gmm_state {
|
||||
enum gprs_mm_state {
|
||||
GMM_DEREGISTERED, /* 4.1.3.3.1.1 */
|
||||
GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */
|
||||
GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */
|
||||
@@ -31,16 +32,6 @@ enum gprs_gmm_state {
|
||||
GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
|
||||
};
|
||||
|
||||
/* TS 23.060 6.1.1 and 6.1.2 Mobility management states A/Gb and Iu mode */
|
||||
enum gprs_pmm_state {
|
||||
PMM_DETACHED,
|
||||
PMM_CONNECTED,
|
||||
PMM_IDLE,
|
||||
MM_IDLE,
|
||||
MM_READY,
|
||||
MM_STANDBY,
|
||||
};
|
||||
|
||||
enum gprs_mm_ctr {
|
||||
GMM_CTR_PKTS_SIG_IN,
|
||||
GMM_CTR_PKTS_SIG_OUT,
|
||||
@@ -73,95 +64,30 @@ enum gprs_t3350_mode {
|
||||
enum sgsn_auth_state {
|
||||
SGSN_AUTH_UNKNOWN,
|
||||
SGSN_AUTH_AUTHENTICATE,
|
||||
SGSN_AUTH_UMTS_RESYNC,
|
||||
SGSN_AUTH_ACCEPTED,
|
||||
SGSN_AUTH_REJECTED
|
||||
};
|
||||
|
||||
#define MS_RADIO_ACCESS_CAPA
|
||||
|
||||
enum sgsn_ggsn_lookup_state {
|
||||
SGSN_GGSN_2DIGIT,
|
||||
SGSN_GGSN_3DIGIT,
|
||||
};
|
||||
|
||||
struct sgsn_ggsn_lookup {
|
||||
int state;
|
||||
|
||||
struct sgsn_mm_ctx *mmctx;
|
||||
|
||||
/* APN string */
|
||||
char apn_str[GSM_APN_LENGTH];
|
||||
|
||||
/* the original data */
|
||||
struct msgb *orig_msg;
|
||||
struct tlv_parsed tp;
|
||||
|
||||
/* for dealing with re-transmissions */
|
||||
uint8_t nsapi;
|
||||
uint8_t sapi;
|
||||
uint8_t ti;
|
||||
};
|
||||
|
||||
enum sgsn_ran_type {
|
||||
/* GPRS/EDGE via Gb */
|
||||
MM_CTX_T_GERAN_Gb,
|
||||
/* UMTS via Iu */
|
||||
MM_CTX_T_UTRAN_Iu,
|
||||
/* GPRS/EDGE via Iu */
|
||||
MM_CTX_T_GERAN_Iu,
|
||||
};
|
||||
|
||||
struct service_info {
|
||||
uint8_t type;
|
||||
uint16_t pdp_status;
|
||||
};
|
||||
|
||||
struct ue_conn_ctx;
|
||||
|
||||
/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */
|
||||
/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */
|
||||
struct sgsn_mm_ctx {
|
||||
struct llist_head list;
|
||||
|
||||
enum sgsn_ran_type ran_type;
|
||||
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
enum gprs_gmm_state gmm_state;
|
||||
enum gprs_pmm_state pmm_state; /* Iu: page when in PMM-IDLE mode */
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
enum gprs_mm_state mm_state;
|
||||
uint32_t p_tmsi;
|
||||
uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */
|
||||
uint32_t p_tmsi_sig;
|
||||
char imei[GSM23003_IMEISV_NUM_DIGITS+1];
|
||||
char imei[GSM_IMEI_LENGTH];
|
||||
/* Opt: Software Version Numbber / TS 23.195 */
|
||||
char msisdn[GSM_EXTENSION_LENGTH];
|
||||
struct gprs_ra_id ra;
|
||||
struct {
|
||||
uint16_t cell_id; /* Gb only */
|
||||
uint32_t cell_id_age; /* Gb only */
|
||||
uint8_t radio_prio_sms;
|
||||
|
||||
/* Additional bits not present in the GSM TS */
|
||||
uint16_t nsei;
|
||||
uint16_t bvci;
|
||||
struct gprs_llc_llme *llme;
|
||||
uint32_t tlli;
|
||||
uint32_t tlli_new;
|
||||
} gb;
|
||||
struct {
|
||||
int new_key;
|
||||
uint16_t sac; /* Iu: Service Area Code */
|
||||
uint32_t sac_age; /* Iu: Service Area Code age */
|
||||
/* CSG ID */
|
||||
/* CSG Membership */
|
||||
/* Access Mode */
|
||||
/* Seelected CN Operator ID (TS 23.251) */
|
||||
/* CSG Subscription Data */
|
||||
/* LIPA Allowed */
|
||||
/* Voice Support Match Indicator */
|
||||
struct ue_conn_ctx *ue_ctx;
|
||||
struct service_info service;
|
||||
} iu;
|
||||
uint16_t cell_id;
|
||||
uint32_t cell_id_age;
|
||||
uint16_t sac; /* Iu: Service Area Code */
|
||||
uint32_t sac_age;/* Iu: Service Area Code age */
|
||||
/* VLR number */
|
||||
uint32_t new_sgsn_addr;
|
||||
/* Authentication Triplet */
|
||||
@@ -170,40 +96,30 @@ struct sgsn_mm_ctx {
|
||||
/* Iu: CK, IK, KSI */
|
||||
/* CKSN */
|
||||
enum gprs_ciph_algo ciph_algo;
|
||||
/* Auth & Ciphering Request reference from 3GPP TS 24.008 § 10.5.5.19: */
|
||||
uint8_t ac_ref_nr_used;
|
||||
|
||||
struct {
|
||||
uint8_t len;
|
||||
uint8_t buf[50]; /* GSM 04.08 10.5.5.12a, extended in TS 24.008 */
|
||||
} ms_radio_access_capa;
|
||||
/* Supported Codecs (SRVCC) */
|
||||
struct {
|
||||
uint8_t len;
|
||||
uint8_t buf[8]; /* GSM 04.08 10.5.5.12, extended in TS 24.008 */
|
||||
} ms_network_capa;
|
||||
/* UE Netowrk Capability (E-UTRAN) */
|
||||
uint16_t drx_parms;
|
||||
/* Active Time value for PSM */
|
||||
int mnrg; /* MS reported to HLR? */
|
||||
int ngaf; /* MS reported to MSC/VLR? */
|
||||
int ppf; /* paging for GPRS + non-GPRS? */
|
||||
/* Subscribed Charging Characteristics */
|
||||
/* Trace Reference */
|
||||
/* Trace Type */
|
||||
/* Trigger ID */
|
||||
/* OMC Identity */
|
||||
/* SMS Parameters */
|
||||
int recovery;
|
||||
/* Access Restriction */
|
||||
/* GPRS CSI (CAMEL) */
|
||||
/* MG-CSI (CAMEL) */
|
||||
/* Subscribed UE-AMBR */
|
||||
/* UE-AMBR */
|
||||
/* APN Subscribed */
|
||||
uint8_t radio_prio_sms;
|
||||
|
||||
struct llist_head pdp_list;
|
||||
|
||||
/* Additional bits not present in the GSM TS */
|
||||
struct gprs_llc_llme *llme;
|
||||
uint32_t tlli;
|
||||
uint32_t tlli_new;
|
||||
uint16_t nsei;
|
||||
uint16_t bvci;
|
||||
struct rate_ctr_group *ctrg;
|
||||
struct osmo_timer_list timer;
|
||||
unsigned int T; /* Txxxx number */
|
||||
@@ -220,13 +136,7 @@ struct sgsn_mm_ctx {
|
||||
enum sgsn_auth_state auth_state;
|
||||
int is_authenticated;
|
||||
|
||||
/* the string representation of the current hlr */
|
||||
char hlr[GSM_EXTENSION_LENGTH];
|
||||
|
||||
/* the current GGSN look-up operation */
|
||||
struct sgsn_ggsn_lookup *ggsn_lookup;
|
||||
|
||||
struct gprs_subscr *subscr;
|
||||
struct gsm_subscriber *subscr;
|
||||
};
|
||||
|
||||
#define LOGMMCTXP(level, mm, fmt, args...) \
|
||||
@@ -238,23 +148,16 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
|
||||
const struct gprs_ra_id *raid);
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx);
|
||||
|
||||
/* look-up by matching TLLI and P-TMSI (think twice before using this) */
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
|
||||
const struct gprs_ra_id *raid);
|
||||
|
||||
/* Allocate a new SGSN MM context */
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli,
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
|
||||
const struct gprs_ra_id *raid);
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx);
|
||||
|
||||
void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm);
|
||||
void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx);
|
||||
|
||||
struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
|
||||
struct tlv_parsed *tp,
|
||||
enum gsm48_gsm_cause *gsm_cause,
|
||||
char *apn_str);
|
||||
enum gsm48_gsm_cause *gsm_cause);
|
||||
|
||||
enum pdp_ctx_state {
|
||||
PDP_STATE_NONE,
|
||||
@@ -277,7 +180,6 @@ struct sgsn_pdp_ctx {
|
||||
struct llist_head list; /* list_head for mmctx->pdp_list */
|
||||
struct llist_head g_list; /* list_head for global list */
|
||||
struct sgsn_mm_ctx *mm; /* back pointer to MM CTX */
|
||||
int destroy_ggsn; /* destroy it on destruction */
|
||||
struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */
|
||||
struct rate_ctr_group *ctrg;
|
||||
|
||||
@@ -296,17 +198,16 @@ struct sgsn_pdp_ctx {
|
||||
//uint32_t qos_profile_req;
|
||||
//uint32_t qos_profile_neg;
|
||||
uint8_t radio_prio;
|
||||
uint32_t tx_npdu_nr;
|
||||
uint32_t rx_npdu_nr;
|
||||
uint32_t tx_gtp_snd;
|
||||
uint32_t rx_gtp_snu;
|
||||
//uint32_t charging_id;
|
||||
int reordering_reqd;
|
||||
|
||||
struct osmo_timer_list timer;
|
||||
unsigned int T; /* Txxxx number */
|
||||
unsigned int num_T_exp; /* number of consecutive T expirations */
|
||||
|
||||
struct osmo_timer_list cdr_timer; /* CDR record wird timer */
|
||||
struct timespec cdr_start; /* The start of the CDR */
|
||||
uint64_t cdr_bytes_in;
|
||||
uint64_t cdr_bytes_out;
|
||||
uint32_t cdr_charging_id;
|
||||
};
|
||||
|
||||
#define LOGPDPCTXP(level, pdp, fmt, args...) \
|
||||
@@ -367,12 +268,14 @@ int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn);
|
||||
|
||||
char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len);
|
||||
|
||||
/* Force re-attachment based on msgb meta data */
|
||||
int sgsn_force_reattach_oldmsg(struct msgb *oldmsg);
|
||||
|
||||
/*
|
||||
* ctrl interface related work
|
||||
*/
|
||||
struct gsm_network;
|
||||
struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *,
|
||||
const char *bind_addr, uint16_t port);
|
||||
struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *, uint16_t port);
|
||||
int sgsn_ctrl_cmds_install(void);
|
||||
|
||||
/*
|
||||
@@ -404,9 +307,6 @@ struct sgsn_subscriber_data {
|
||||
|
||||
uint8_t msisdn[9];
|
||||
size_t msisdn_len;
|
||||
|
||||
uint8_t hlr[9];
|
||||
size_t hlr_len;
|
||||
};
|
||||
|
||||
#define SGSN_ERROR_CAUSE_NONE (-1)
|
||||
@@ -434,7 +334,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 +346,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 */
|
||||
@@ -468,6 +363,4 @@ int gprs_sndcp_vty_init(void);
|
||||
struct sgsn_instance;
|
||||
int sgsn_gtp_init(struct sgsn_instance *sgi);
|
||||
|
||||
void sgsn_rate_ctr_init();
|
||||
|
||||
#endif /* _GPRS_SGSN_H */
|
||||
|
@@ -1,82 +0,0 @@
|
||||
/* GPRS SNDCP header compression entity management tools */
|
||||
|
||||
/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <openbsc/gprs_sndcp_xid.h>
|
||||
|
||||
/* Header / Data compression entity */
|
||||
struct gprs_sndcp_comp {
|
||||
struct llist_head list;
|
||||
|
||||
/* Serves as an ID in case we want to delete this entity later */
|
||||
unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */
|
||||
|
||||
/* Specifies to which NSAPIs the compression entity is assigned */
|
||||
uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */
|
||||
uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */
|
||||
|
||||
/* Assigned pcomp values */
|
||||
uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */
|
||||
uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */
|
||||
|
||||
/* Algorithm parameters */
|
||||
int algo; /* Algorithm type (see gprs_sndcp_xid.h) */
|
||||
int compclass; /* See gprs_sndcp_xid.h/c */
|
||||
void *state; /* Algorithm status and parameters */
|
||||
};
|
||||
|
||||
#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */
|
||||
#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */
|
||||
|
||||
/* Allocate a compression enitiy list */
|
||||
struct llist_head *gprs_sndcp_comp_alloc(const void *ctx);
|
||||
|
||||
/* Free a compression entitiy list */
|
||||
void gprs_sndcp_comp_free(struct llist_head *comp_entities);
|
||||
|
||||
/* Delete a compression entity */
|
||||
void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity);
|
||||
|
||||
/* Create and Add a new compression entity
|
||||
* (returns a pointer to the compression entity that has just been created) */
|
||||
struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx,
|
||||
struct llist_head *comp_entities,
|
||||
const struct gprs_sndcp_comp_field
|
||||
*comp_field);
|
||||
|
||||
/* Find which compression entity handles the specified pcomp/dcomp */
|
||||
struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head
|
||||
*comp_entities, uint8_t comp);
|
||||
|
||||
/* Find which compression entity handles the specified nsapi */
|
||||
struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head
|
||||
*comp_entities, uint8_t nsapi);
|
||||
|
||||
/* Find a comp_index for a given pcomp/dcomp value */
|
||||
uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity,
|
||||
uint8_t comp);
|
||||
|
||||
/* Find a pcomp/dcomp value for a given comp_index */
|
||||
uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity,
|
||||
uint8_t comp_index);
|
@@ -1,53 +0,0 @@
|
||||
/* GPRS SNDCP data compression handler */
|
||||
|
||||
/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <openbsc/gprs_sndcp_comp.h>
|
||||
|
||||
/* Note: The decompressed packet may have a maximum size of:
|
||||
* Return value * MAX_DATADECOMPR_FAC */
|
||||
#define MAX_DATADECOMPR_FAC 10
|
||||
|
||||
/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset
|
||||
* for every NPDU. The compressor needs a reasonably large payload to operate
|
||||
* effectively (yield positive compression gain). For packets shorter than 100
|
||||
* byte, no positive compression gain can be expected so we will skip the
|
||||
* compression for short packets. */
|
||||
#define MIN_COMPR_PAYLOAD 100
|
||||
|
||||
/* Initalize data compression */
|
||||
int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity,
|
||||
const struct gprs_sndcp_comp_field *comp_field);
|
||||
|
||||
/* Terminate data compression */
|
||||
void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity);
|
||||
|
||||
/* Expand packet */
|
||||
int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp,
|
||||
const struct llist_head *comp_entities);
|
||||
|
||||
/* Compress packet */
|
||||
int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp,
|
||||
const struct llist_head *comp_entities,
|
||||
uint8_t nsapi);
|
@@ -1,46 +0,0 @@
|
||||
/* GPRS SNDCP header compression handler */
|
||||
|
||||
/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <openbsc/gprs_sndcp_comp.h>
|
||||
|
||||
/* Note: The decompressed packet may have a maximum size of:
|
||||
* Return value + MAX_DECOMPR_INCR */
|
||||
#define MAX_HDRDECOMPR_INCR 64
|
||||
|
||||
/* Initalize header compression */
|
||||
int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity,
|
||||
const struct gprs_sndcp_comp_field *comp_field);
|
||||
|
||||
/* Terminate header compression */
|
||||
void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity);
|
||||
|
||||
/* Expand packet header */
|
||||
int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp,
|
||||
const struct llist_head *comp_entities);
|
||||
|
||||
/* Compress packet header */
|
||||
int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp,
|
||||
const struct llist_head *comp_entities,
|
||||
uint8_t nsapi);
|
@@ -1,218 +0,0 @@
|
||||
/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */
|
||||
|
||||
/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
#define DEFAULT_SNDCP_VERSION 0 /* See 3GPP TS 44.065, clause 8 */
|
||||
#define MAX_ENTITIES 32 /* 3GPP TS 44.065 reserves 5 bit
|
||||
* for compression enitity number */
|
||||
|
||||
#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */
|
||||
#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */
|
||||
#define MAX_ROHC 16 /* Maximum number of ROHC compression profiles */
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.5.1.1 Format of the protocol control
|
||||
* information compression field (Figure 7) and 3GPP TS 44.065,
|
||||
* 6.6.1.1 Format of the data compression field (Figure 9) */
|
||||
struct gprs_sndcp_comp_field {
|
||||
struct llist_head list;
|
||||
|
||||
/* Propose bit (P), see also: 6.5.1.1.2 and 6.6.1.1.2 */
|
||||
unsigned int p;
|
||||
|
||||
/* Entity number, see also: 6.5.1.1.3 and 6.6.1.1.3 */
|
||||
unsigned int entity;
|
||||
|
||||
/* Algorithm identifier, see also: 6.5.1.1.4 and 6.6.1.1.4 */
|
||||
int algo;
|
||||
|
||||
/* Number of contained PCOMP / DCOMP values */
|
||||
uint8_t comp_len;
|
||||
|
||||
/* PCOMP / DCOMP values, see also: 6.5.1.1.5 and 6.6.1.1.5 */
|
||||
uint8_t comp[MAX_COMP];
|
||||
|
||||
/* Note: Only one of the following struct pointers may,
|
||||
be used. Unused pointers must be set to NULL! */
|
||||
struct gprs_sndcp_pcomp_rfc1144_params *rfc1144_params;
|
||||
struct gprs_sndcp_pcomp_rfc2507_params *rfc2507_params;
|
||||
struct gprs_sndcp_pcomp_rohc_params *rohc_params;
|
||||
struct gprs_sndcp_dcomp_v42bis_params *v42bis_params;
|
||||
struct gprs_sndcp_dcomp_v44_params *v44_params;
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
|
||||
enum gprs_sndcp_hdr_comp_algo {
|
||||
RFC_1144, /* TCP/IP header compression, see also 6.5.2 */
|
||||
RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */
|
||||
ROHC /* Robust Header Compression, see also 6.5.4 */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
|
||||
enum gprs_sndcp_data_comp_algo {
|
||||
V42BIS, /* V.42bis data compression, see also 6.6.2 */
|
||||
V44 /* V44 data compression, see also: 6.6.3 */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 8 SNDCP XID parameters */
|
||||
enum gprs_sndcp_xid_param_types {
|
||||
SNDCP_XID_VERSION_NUMBER,
|
||||
SNDCP_XID_DATA_COMPRESSION, /* See also: subclause 6.6.1 */
|
||||
SNDCP_XID_PROTOCOL_COMPRESSION, /* See also: subclause 6.5.1 */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.5.2.1 Parameters (Table 5) */
|
||||
struct gprs_sndcp_pcomp_rfc1144_params {
|
||||
uint8_t nsapi_len; /* Number of applicable NSAPIs
|
||||
* (default 0) */
|
||||
uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */
|
||||
int s01; /* (default 15) */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.5.2.2 Assignment of PCOMP values */
|
||||
enum gprs_sndcp_pcomp_rfc1144_pcomp {
|
||||
RFC1144_PCOMP1, /* Uncompressed TCP */
|
||||
RFC1144_PCOMP2, /* Compressed TCP */
|
||||
RFC1144_PCOMP_NUM /* Number of pcomp values */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.5.3.1 Parameters (Table 6) */
|
||||
struct gprs_sndcp_pcomp_rfc2507_params {
|
||||
uint8_t nsapi_len; /* Number of applicable NSAPIs
|
||||
* (default 0) */
|
||||
uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */
|
||||
int f_max_period; /* (default 256) */
|
||||
int f_max_time; /* (default 5) */
|
||||
int max_header; /* (default 168) */
|
||||
int tcp_space; /* (default 15) */
|
||||
int non_tcp_space; /* (default 15) */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.5.3.2 Assignment of PCOMP values for RFC2507 */
|
||||
enum gprs_sndcp_pcomp_rfc2507_pcomp {
|
||||
RFC2507_PCOMP1, /* Full Header */
|
||||
RFC2507_PCOMP2, /* Compressed TCP */
|
||||
RFC2507_PCOMP3, /* Compressed TCP non delta */
|
||||
RFC2507_PCOMP4, /* Compressed non TCP */
|
||||
RFC2507_PCOMP5, /* Context state */
|
||||
RFC2507_PCOMP_NUM /* Number of pcomp values */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.5.4.1 Parameter (Table 10) */
|
||||
struct gprs_sndcp_pcomp_rohc_params {
|
||||
uint8_t nsapi_len; /* Number of applicable NSAPIs
|
||||
* (default 0) */
|
||||
uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */
|
||||
int max_cid; /* (default 15) */
|
||||
int max_header; /* (default 168) */
|
||||
uint8_t profile_len; /* (default 1) */
|
||||
uint16_t profile[MAX_ROHC]; /* (default 0, ROHC uncompressed) */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.5.4.2 Assignment of PCOMP values for ROHC */
|
||||
enum gprs_sndcp_pcomp_rohc_pcomp {
|
||||
ROHC_PCOMP1, /* ROHC small CIDs */
|
||||
ROHC_PCOMP2, /* ROHC large CIDs */
|
||||
ROHC_PCOMP_NUM /* Number of pcomp values */
|
||||
};
|
||||
|
||||
/* ROHC compression profiles, see also:
|
||||
http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.xhtml */
|
||||
enum gprs_sndcp_xid_rohc_profiles {
|
||||
ROHC_UNCOMPRESSED = 0x0000, /* ROHC uncompressed [RFC5795] */
|
||||
ROHC_RTP = 0x0001, /* ROHC RTP [RFC3095] */
|
||||
ROHCV2_RTP = 0x0101, /* ROHCv2 RTP [RFC5225] */
|
||||
ROHC_UDP = 0x0002, /* ROHC UDP [RFC3095] */
|
||||
ROHCv2_UDP = 0x0102, /* ROHCv2 UDP [RFC5225] */
|
||||
ROHC_ESP = 0x0003, /* ROHC ESP [RFC3095] */
|
||||
ROHCV2_ESP = 0x0103, /* ROHCv2 ESP [RFC5225] */
|
||||
ROHC_IP = 0x0004, /* ROHC IP [RFC3843] */
|
||||
ROHCV2_IP = 0x0104, /* ROHCv2 IP [RFC5225] */
|
||||
ROHC_LLA = 0x0005, /* ROHC LLA [RFC4362] */
|
||||
ROHC_LLA_WITH_R_MODE = 0x0105, /* ROHC LLA with R-mode [RFC3408] */
|
||||
ROHC_TCP = 0x0006, /* ROHC TCP [RFC6846] */
|
||||
ROHC_RTP_UDP_LITE = 0x0007, /* ROHC RTP/UDP-Lite [RFC4019] */
|
||||
ROHCV2_RTP_UDP_LITE = 0x0107, /* ROHCv2 RTP/UDP-Lite [RFC5225] */
|
||||
ROHC_UDP_LITE = 0x0008, /* ROHC UDP-Lite [RFC4019] */
|
||||
ROHCV2_UDP_LITE = 0x0108, /* ROHCv2 UDP-Lite [RFC5225] */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.6.2.1 Parameters (Table 7a) */
|
||||
struct gprs_sndcp_dcomp_v42bis_params {
|
||||
uint8_t nsapi_len; /* Number of applicable NSAPIs
|
||||
* (default 0) */
|
||||
uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */
|
||||
int p0; /* (default 3) */
|
||||
int p1; /* (default 2048) */
|
||||
int p2; /* (default 20) */
|
||||
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.6.2.2 Assignment of DCOMP values */
|
||||
enum gprs_sndcp_dcomp_v42bis_dcomp {
|
||||
V42BIS_DCOMP1, /* V.42bis enabled */
|
||||
V42BIS_DCOMP_NUM /* Number of dcomp values */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.6.3.1 Parameters (Table 7c) */
|
||||
struct gprs_sndcp_dcomp_v44_params {
|
||||
uint8_t nsapi_len; /* Number of applicable NSAPIs
|
||||
* (default 0) */
|
||||
uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */
|
||||
int c0; /* (default 10000000) */
|
||||
int p0; /* (default 3) */
|
||||
int p1t; /* Refer to subclause 6.6.3.1.4 */
|
||||
int p1r; /* Refer to subclause 6.6.3.1.5 */
|
||||
int p3t; /* (default 3 x p1t) */
|
||||
int p3r; /* (default 3 x p1r) */
|
||||
};
|
||||
|
||||
/* According to: 3GPP TS 44.065, 6.6.3.2 Assignment of DCOMP values */
|
||||
enum gprs_sndcp_dcomp_v44_dcomp {
|
||||
V44_DCOMP1, /* Packet method compressed */
|
||||
V44_DCOMP2, /* Multi packet method compressed */
|
||||
V44_DCOMP_NUM /* Number of dcomp values */
|
||||
};
|
||||
|
||||
/* Transform a list with compression fields into an SNDCP-XID message (dst) */
|
||||
int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen,
|
||||
const struct llist_head *comp_fields, int version);
|
||||
|
||||
/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */
|
||||
struct llist_head *gprs_sndcp_parse_xid(int *version,
|
||||
const void *ctx,
|
||||
const uint8_t *src,
|
||||
unsigned int src_len,
|
||||
const struct llist_head
|
||||
*comp_fields_req);
|
||||
|
||||
/* Find out to which compression class the specified comp-field belongs
|
||||
* (header compression or data compression?) */
|
||||
int gprs_sndcp_get_compression_class(
|
||||
const struct gprs_sndcp_comp_field *comp_field);
|
||||
|
||||
/* Dump a list with SNDCP-XID fields (Debug) */
|
||||
void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields,
|
||||
unsigned int logl);
|
||||
|
@@ -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__)
|
@@ -25,7 +25,6 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
struct msgb;
|
||||
struct gprs_ra_id;
|
||||
|
||||
struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name);
|
||||
int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area,
|
||||
@@ -42,4 +41,14 @@ int gprs_is_mi_imsi(const uint8_t *value, size_t value_len);
|
||||
int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi);
|
||||
void gprs_parse_tmsi(const uint8_t *value, uint32_t *tmsi);
|
||||
|
||||
int gprs_ra_id_equals(const struct gprs_ra_id *id1, const struct gprs_ra_id *id2);
|
||||
int gprs_shift_v_fixed(uint8_t **data, size_t *data_len,
|
||||
size_t len, uint8_t **value);
|
||||
int gprs_match_tv_fixed(uint8_t **data, size_t *data_len,
|
||||
uint8_t tag, size_t len, uint8_t **value);
|
||||
int gprs_shift_tlv(uint8_t **data, size_t *data_len,
|
||||
uint8_t *tag, uint8_t **value, size_t *value_len);
|
||||
int gprs_match_tlv(uint8_t **data, size_t *data_len,
|
||||
uint8_t tag, uint8_t **value, size_t *value_len);
|
||||
int gprs_shift_lv(uint8_t **data, size_t *data_len,
|
||||
uint8_t **value, size_t *value_len);
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
#include <openbsc/meas_rep.h>
|
||||
#include <openbsc/mncc.h>
|
||||
|
||||
struct msgb;
|
||||
struct gsm_bts;
|
||||
@@ -14,16 +15,28 @@ struct gsm_network;
|
||||
struct gsm_trans;
|
||||
struct gsm_subscriber_connection;
|
||||
struct amr_multirate_conf;
|
||||
struct amr_mode;
|
||||
struct bsc_subscr;
|
||||
|
||||
#define GSM48_ALLOC_SIZE 2048
|
||||
#define GSM48_ALLOC_HEADROOM 256
|
||||
|
||||
static inline struct msgb *gsm48_msgb_alloc_name(const char *name)
|
||||
static inline struct msgb *gsm48_msgb_alloc(void)
|
||||
{
|
||||
return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM,
|
||||
name);
|
||||
"GSM 04.08");
|
||||
}
|
||||
|
||||
static inline int get_radio_link_timeout(struct gsm48_cell_options *cell_options)
|
||||
{
|
||||
return (cell_options->radio_link_timeout + 1) << 2;
|
||||
}
|
||||
|
||||
static inline void set_radio_link_timeout(struct gsm48_cell_options *cell_options, int value)
|
||||
{
|
||||
if (value < 4)
|
||||
value = 4;
|
||||
if (value > 64)
|
||||
value = 64;
|
||||
cell_options->radio_link_timeout = (value >> 2) - 1;
|
||||
}
|
||||
|
||||
/* config options controlling the behaviour of the lower leves */
|
||||
@@ -40,8 +53,7 @@ int get_reason_by_chreq(uint8_t ra, int neci);
|
||||
void gsm_net_update_ctype(struct gsm_network *net);
|
||||
|
||||
int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn);
|
||||
int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand,
|
||||
uint8_t *autn, int key_seq);
|
||||
int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand, int key_seq);
|
||||
int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn);
|
||||
int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn);
|
||||
int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn,
|
||||
@@ -65,8 +77,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);
|
||||
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);
|
||||
@@ -80,6 +91,8 @@ void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
|
||||
void release_security_operation(struct gsm_subscriber_connection *conn);
|
||||
void allocate_security_operation(struct gsm_subscriber_connection *conn);
|
||||
|
||||
int gsm48_multirate_config(uint8_t *lv, const struct amr_multirate_conf *mr, const struct amr_mode *modes);
|
||||
int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data);
|
||||
|
||||
int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, int ms);
|
||||
|
||||
#endif
|
||||
|
397
openbsc/include/openbsc/gsm_04_08_gprs.h
Normal file
397
openbsc/include/openbsc/gsm_04_08_gprs.h
Normal file
@@ -0,0 +1,397 @@
|
||||
#ifndef _GSM48_GPRS_H
|
||||
#define _GSM48_GPRS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
/* Table 10.4 / 10.4a, GPRS Mobility Management (GMM) */
|
||||
#define GSM48_MT_GMM_ATTACH_REQ 0x01
|
||||
#define GSM48_MT_GMM_ATTACH_ACK 0x02
|
||||
#define GSM48_MT_GMM_ATTACH_COMPL 0x03
|
||||
#define GSM48_MT_GMM_ATTACH_REJ 0x04
|
||||
#define GSM48_MT_GMM_DETACH_REQ 0x05
|
||||
#define GSM48_MT_GMM_DETACH_ACK 0x06
|
||||
|
||||
#define GSM48_MT_GMM_RA_UPD_REQ 0x08
|
||||
#define GSM48_MT_GMM_RA_UPD_ACK 0x09
|
||||
#define GSM48_MT_GMM_RA_UPD_COMPL 0x0a
|
||||
#define GSM48_MT_GMM_RA_UPD_REJ 0x0b
|
||||
|
||||
#define GSM48_MT_GMM_PTMSI_REALL_CMD 0x10
|
||||
#define GSM48_MT_GMM_PTMSI_REALL_COMPL 0x11
|
||||
#define GSM48_MT_GMM_AUTH_CIPH_REQ 0x12
|
||||
#define GSM48_MT_GMM_AUTH_CIPH_RESP 0x13
|
||||
#define GSM48_MT_GMM_AUTH_CIPH_REJ 0x14
|
||||
#define GSM48_MT_GMM_ID_REQ 0x15
|
||||
#define GSM48_MT_GMM_ID_RESP 0x16
|
||||
#define GSM48_MT_GMM_STATUS 0x20
|
||||
#define GSM48_MT_GMM_INFO 0x21
|
||||
|
||||
/* Table 10.4a, GPRS Session Management (GSM) */
|
||||
#define GSM48_MT_GSM_ACT_PDP_REQ 0x41
|
||||
#define GSM48_MT_GSM_ACT_PDP_ACK 0x42
|
||||
#define GSM48_MT_GSM_ACT_PDP_REJ 0x43
|
||||
#define GSM48_MT_GSM_REQ_PDP_ACT 0x44
|
||||
#define GSM48_MT_GSM_REQ_PDP_ACT_REJ 0x45
|
||||
#define GSM48_MT_GSM_DEACT_PDP_REQ 0x46
|
||||
#define GSM48_MT_GSM_DEACT_PDP_ACK 0x47
|
||||
#define GSM48_MT_GSM_ACT_AA_PDP_REQ 0x50
|
||||
#define GSM48_MT_GSM_ACT_AA_PDP_ACK 0x51
|
||||
#define GSM48_MT_GSM_ACT_AA_PDP_REJ 0x52
|
||||
#define GSM48_MT_GSM_DEACT_AA_PDP_REQ 0x53
|
||||
#define GSM48_MT_GSM_DEACT_AA_PDP_ACK 0x54
|
||||
#define GSM48_MT_GSM_STATUS 0x55
|
||||
|
||||
/* Chapter 10.5.5.2 / Table 10.5.135 */
|
||||
#define GPRS_ATT_T_ATTACH 1
|
||||
#define GPRS_ATT_T_ATT_WHILE_IMSI 2
|
||||
#define GPRS_ATT_T_COMBINED 3
|
||||
|
||||
extern const struct value_string *gprs_att_t_strs;
|
||||
|
||||
/* Chapter 10.5.5.5 / Table 10.5.138 */
|
||||
#define GPRS_DET_T_MO_GPRS 1
|
||||
#define GPRS_DET_T_MO_IMSI 2
|
||||
#define GPRS_DET_T_MO_COMBINED 3
|
||||
/* Network to MS direction */
|
||||
#define GPRS_DET_T_MT_REATT_REQ 1
|
||||
#define GPRS_DET_T_MT_REATT_NOTREQ 2
|
||||
#define GPRS_DET_T_MT_IMSI 3
|
||||
|
||||
extern const struct value_string *gprs_det_t_mo_strs;
|
||||
extern const struct value_string *gprs_det_t_mt_strs;
|
||||
|
||||
/* Chapter 10.5.5.18 / Table 105.150 */
|
||||
#define GPRS_UPD_T_RA 0
|
||||
#define GPRS_UPD_T_RA_LA 1
|
||||
#define GPRS_UPD_T_RA_LA_IMSI_ATT 2
|
||||
#define GPRS_UPD_T_PERIODIC 3
|
||||
|
||||
extern const struct value_string *gprs_upd_t_strs;
|
||||
|
||||
enum gsm48_gprs_ie_mm {
|
||||
GSM48_IE_GMM_CIPH_CKSN = 0x08, /* 10.5.1.2 */
|
||||
GSM48_IE_GMM_TIMER_READY = 0x17, /* 10.5.7.3 */
|
||||
GSM48_IE_GMM_ALLOC_PTMSI = 0x18, /* 10.5.1.4 */
|
||||
GSM48_IE_GMM_PTMSI_SIG = 0x19, /* 10.5.5.8 */
|
||||
GSM48_IE_GMM_AUTH_RAND = 0x21, /* 10.5.3.1 */
|
||||
GSM48_IE_GMM_AUTH_SRES = 0x22, /* 10.5.3.2 */
|
||||
GSM48_IE_GMM_IMEISV = 0x23, /* 10.5.1.4 */
|
||||
GSM48_IE_GMM_CAUSE = 0x25, /* 10.5.5.14 */
|
||||
GSM48_IE_GMM_DRX_PARAM = 0x27, /* 10.5.5.6 */
|
||||
GSM48_IE_GMM_MS_NET_CAPA = 0x31, /* 10.5.5.12 */
|
||||
GSM48_IE_GMM_PDP_CTX_STATUS = 0x32, /* 10.5.7.1 */
|
||||
GSM48_IE_GMM_PS_LCS_CAPA = 0x33, /* 10.5.5.22 */
|
||||
GSM48_IE_GMM_GMM_MBMS_CTX_ST = 0x35, /* 10.5.7.6 */
|
||||
};
|
||||
|
||||
enum gsm48_gprs_ie_sm {
|
||||
GSM48_IE_GSM_APN = 0x28, /* 10.5.6.1 */
|
||||
GSM48_IE_GSM_PROTO_CONF_OPT = 0x27, /* 10.5.6.3 */
|
||||
GSM48_IE_GSM_PDP_ADDR = 0x2b, /* 10.5.6.4 */
|
||||
GSM48_IE_GSM_AA_TMR = 0x29, /* 10.5.7.3 */
|
||||
GSM48_IE_GSM_NAME_FULL = 0x43, /* 10.5.3.5a */
|
||||
GSM48_IE_GSM_NAME_SHORT = 0x45, /* 10.5.3.5a */
|
||||
GSM48_IE_GSM_TIMEZONE = 0x46, /* 10.5.3.8 */
|
||||
GSM48_IE_GSM_UTC_AND_TZ = 0x47, /* 10.5.3.9 */
|
||||
GSM48_IE_GSM_LSA_ID = 0x48, /* 10.5.3.11 */
|
||||
|
||||
/* Fake IEs that are not present on the Layer3 air interface,
|
||||
* but which we use to simplify internal APIs */
|
||||
OSMO_IE_GSM_REQ_QOS = 0xfd,
|
||||
OSMO_IE_GSM_REQ_PDP_ADDR = 0xfe,
|
||||
OSMO_IE_GSM_SUB_QOS = 0xff,
|
||||
};
|
||||
|
||||
/* Chapter 9.4.15 / Table 9.4.15 */
|
||||
struct gsm48_ra_upd_ack {
|
||||
uint8_t force_stby:4, /* 10.5.5.7 */
|
||||
upd_result:4; /* 10.5.5.17 */
|
||||
uint8_t ra_upd_timer; /* 10.5.7.3 */
|
||||
struct gsm48_ra_id ra_id; /* 10.5.5.15 */
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.7.3 */
|
||||
enum gsm48_gprs_tmr_unit {
|
||||
GPRS_TMR_2SECONDS = 0 << 5,
|
||||
GPRS_TMR_MINUTE = 1 << 5,
|
||||
GPRS_TMR_6MINUTE = 2 << 5,
|
||||
GPRS_TMR_DEACTIVATED = 7 << 5,
|
||||
};
|
||||
|
||||
#define GPRS_TMR_UNIT_MASK (7 << 5)
|
||||
#define GPRS_TMR_FACT_MASK ((1 << 5)-1)
|
||||
|
||||
/* Chapter 9.4.2 / Table 9.4.2 */
|
||||
struct gsm48_attach_ack {
|
||||
uint8_t att_result:4, /* 10.5.5.7 */
|
||||
force_stby:4; /* 10.5.5.1 */
|
||||
uint8_t ra_upd_timer; /* 10.5.7.3 */
|
||||
uint8_t radio_prio; /* 10.5.7.2 */
|
||||
struct gsm48_ra_id ra_id; /* 10.5.5.15 */
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.4.9 / Table 9.4.9 */
|
||||
struct gsm48_auth_ciph_req {
|
||||
uint8_t ciph_alg:4, /* 10.5.5.3 */
|
||||
imeisv_req:4; /* 10.5.5.10 */
|
||||
uint8_t force_stby:4, /* 10.5.5.7 */
|
||||
ac_ref_nr:4; /* 10.5.5.19 */
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
/* optional: TV RAND, TV CKSN */
|
||||
|
||||
struct gsm48_auth_ciph_resp {
|
||||
uint8_t ac_ref_nr:4,
|
||||
spare:4;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.5.1 / Table 9.5.1 */
|
||||
struct gsm48_act_pdp_ctx_req {
|
||||
uint8_t req_nsapi;
|
||||
uint8_t req_llc_sapi;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.5.14 / Table 10.5.147 */
|
||||
enum gsm48_gmm_cause {
|
||||
GMM_CAUSE_IMSI_UNKNOWN = 0x02,
|
||||
GMM_CAUSE_ILLEGAL_MS = 0x03,
|
||||
GMM_CAUSE_ILLEGAL_ME = 0x06,
|
||||
GMM_CAUSE_GPRS_NOTALLOWED = 0x07,
|
||||
GMM_CAUSE_GPRS_OTHER_NOTALLOWED = 0x08,
|
||||
GMM_CAUSE_MS_ID_NOT_DERIVED = 0x09,
|
||||
GMM_CAUSE_IMPL_DETACHED = 0x0a,
|
||||
GMM_CAUSE_PLMN_NOTALLOWED = 0x0b,
|
||||
GMM_CAUSE_LA_NOTALLOWED = 0x0c,
|
||||
GMM_CAUSE_ROAMING_NOTALLOWED = 0x0d,
|
||||
GMM_CAUSE_NO_GPRS_PLMN = 0x0e,
|
||||
GMM_CAUSE_MSC_TEMP_NOTREACH = 0x10,
|
||||
GMM_CAUSE_NET_FAIL = 0x11,
|
||||
GMM_CAUSE_CONGESTION = 0x16,
|
||||
GMM_CAUSE_SEM_INCORR_MSG = 0x5f,
|
||||
GMM_CAUSE_INV_MAND_INFO = 0x60,
|
||||
GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
|
||||
GMM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
|
||||
GMM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
|
||||
GMM_CAUSE_COND_IE_ERR = 0x64,
|
||||
GMM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
|
||||
GMM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
|
||||
};
|
||||
|
||||
extern const struct value_string *gsm48_gmm_cause_names;
|
||||
|
||||
/* Chapter 10.4.6.6 / Table 10.5.157 */
|
||||
enum gsm48_gsm_cause {
|
||||
GSM_CAUSE_INSUFF_RSRC = 0x1a,
|
||||
GSM_CAUSE_MISSING_APN = 0x1b,
|
||||
GSM_CAUSE_UNKNOWN_PDP = 0x1c,
|
||||
GSM_CAUSE_AUTH_FAILED = 0x1d,
|
||||
GSM_CAUSE_ACT_REJ_GGSN = 0x1e,
|
||||
GSM_CAUSE_ACT_REJ_UNSPEC = 0x1f,
|
||||
GSM_CAUSE_SERV_OPT_NOTSUPP = 0x20,
|
||||
GSM_CAUSE_REQ_SERV_OPT_NOTSUB = 0x21,
|
||||
GSM_CAUSE_SERV_OPT_TEMP_OOO = 0x22,
|
||||
GSM_CAUSE_NSAPI_IN_USE = 0x23,
|
||||
GSM_CAUSE_DEACT_REGULAR = 0x24,
|
||||
GSM_CAUSE_QOS_NOT_ACCEPTED = 0x25,
|
||||
GSM_CAUSE_NET_FAIL = 0x26,
|
||||
GSM_CAUSE_REACT_RQD = 0x27,
|
||||
GSM_CAUSE_FEATURE_NOTSUPP = 0x28,
|
||||
GSM_CAUSE_INVALID_TRANS_ID = 0x51,
|
||||
GSM_CAUSE_SEM_INCORR_MSG = 0x5f,
|
||||
GSM_CAUSE_INV_MAND_INFO = 0x60,
|
||||
GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
|
||||
GSM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
|
||||
GSM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
|
||||
GSM_CAUSE_COND_IE_ERR = 0x64,
|
||||
GSM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
|
||||
GSM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
|
||||
};
|
||||
|
||||
extern const struct value_string *gsm48_gsm_cause_names;
|
||||
|
||||
/* Section 6.1.2.2: Session management states on the network side */
|
||||
enum gsm48_pdp_state {
|
||||
PDP_S_INACTIVE,
|
||||
PDP_S_ACTIVE_PENDING,
|
||||
PDP_S_ACTIVE,
|
||||
PDP_S_INACTIVE_PENDING,
|
||||
PDP_S_MODIFY_PENDING,
|
||||
};
|
||||
|
||||
/* Table 10.5.155/3GPP TS 24.008 */
|
||||
enum gsm48_pdp_type_org {
|
||||
PDP_TYPE_ORG_ETSI = 0x00,
|
||||
PDP_TYPE_ORG_IETF = 0x01,
|
||||
};
|
||||
enum gsm48_pdp_type_nr {
|
||||
PDP_TYPE_N_ETSI_RESERVED = 0x00,
|
||||
PDP_TYPE_N_ETSI_PPP = 0x01,
|
||||
PDP_TYPE_N_IETF_IPv4 = 0x21,
|
||||
PDP_TYPE_N_IETF_IPv6 = 0x57,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_reliab_class {
|
||||
GSM48_QOS_RC_LLC_ACK_RLC_ACK_DATA_PROT = 2,
|
||||
GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT = 3,
|
||||
GSM48_QOS_RC_LLC_UN_RLC_UN_PROT_DATA = 4,
|
||||
GSM48_QOS_RC_LLC_UN_RLC_UN_DATA_UN = 5,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_preced_class {
|
||||
GSM48_QOS_PC_HIGH = 1,
|
||||
GSM48_QOS_PC_NORMAL = 2,
|
||||
GSM48_QOS_PC_LOW = 3,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_peak_tput {
|
||||
GSM48_QOS_PEAK_TPUT_1000bps = 1,
|
||||
GSM48_QOS_PEAK_TPUT_2000bps = 2,
|
||||
GSM48_QOS_PEAK_TPUT_4000bps = 3,
|
||||
GSM48_QOS_PEAK_TPUT_8000bps = 4,
|
||||
GSM48_QOS_PEAK_TPUT_16000bps = 5,
|
||||
GSM48_QOS_PEAK_TPUT_32000bps = 6,
|
||||
GSM48_QOS_PEAK_TPUT_64000bps = 7,
|
||||
GSM48_QOS_PEAK_TPUT_128000bps = 8,
|
||||
GSM48_QOS_PEAK_TPUT_256000bps = 9,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_mean_tput {
|
||||
GSM48_QOS_MEAN_TPUT_100bph = 1,
|
||||
GSM48_QOS_MEAN_TPUT_200bph = 2,
|
||||
GSM48_QOS_MEAN_TPUT_500bph = 3,
|
||||
GSM48_QOS_MEAN_TPUT_1000bph = 4,
|
||||
GSM48_QOS_MEAN_TPUT_2000bph = 5,
|
||||
GSM48_QOS_MEAN_TPUT_5000bph = 6,
|
||||
GSM48_QOS_MEAN_TPUT_10000bph = 7,
|
||||
GSM48_QOS_MEAN_TPUT_20000bph = 8,
|
||||
GSM48_QOS_MEAN_TPUT_50000bph = 9,
|
||||
GSM48_QOS_MEAN_TPUT_100kbph = 10,
|
||||
GSM48_QOS_MEAN_TPUT_200kbph = 11,
|
||||
GSM48_QOS_MEAN_TPUT_500kbph = 0xc,
|
||||
GSM48_QOS_MEAN_TPUT_1Mbph = 0xd,
|
||||
GSM48_QOS_MEAN_TPUT_2Mbph = 0xe,
|
||||
GSM48_QOS_MEAN_TPUT_5Mbph = 0xf,
|
||||
GSM48_QOS_MEAN_TPUT_10Mbph = 0x10,
|
||||
GSM48_QOS_MEAN_TPUT_20Mbph = 0x11,
|
||||
GSM48_QOS_MEAN_TPUT_50Mbph = 0x12,
|
||||
GSM48_QOS_MEAN_TPUT_BEST_EFFORT = 0x1f,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_err_sdu {
|
||||
GSM48_QOS_ERRSDU_NODETECT = 1,
|
||||
GSM48_QOS_ERRSDU_YES = 2,
|
||||
GSM48_QOS_ERRSDU_NO = 3,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_deliv_order {
|
||||
GSM48_QOS_DO_ORDERED = 1,
|
||||
GSM48_QOS_DO_UNORDERED = 2,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_traf_class {
|
||||
GSM48_QOS_TC_CONVERSATIONAL = 1,
|
||||
GSM48_QOS_TC_STREAMING = 2,
|
||||
GSM48_QOS_TC_INTERACTIVE = 3,
|
||||
GSM48_QOS_TC_BACKGROUND = 4,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_max_sdu_size {
|
||||
/* values below in 10 octet granularity */
|
||||
GSM48_QOS_MAXSDU_1502 = 0x97,
|
||||
GSM48_QOS_MAXSDU_1510 = 0x98,
|
||||
GSM48_QOS_MAXSDU_1520 = 0x99,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_max_bitrate {
|
||||
GSM48_QOS_MBRATE_1k = 0x01,
|
||||
GSM48_QOS_MBRATE_63k = 0x3f,
|
||||
GSM48_QOS_MBRATE_64k = 0x40,
|
||||
GSM48_QOS_MBRATE_568k = 0x7f,
|
||||
GSM48_QOS_MBRATE_576k = 0x80,
|
||||
GSM48_QOS_MBRATE_8640k = 0xfe,
|
||||
GSM48_QOS_MBRATE_0k = 0xff,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_resid_ber {
|
||||
GSM48_QOS_RBER_5e_2 = 0x01,
|
||||
GSM48_QOS_RBER_1e_2 = 0x02,
|
||||
GSM48_QOS_RBER_5e_3 = 0x03,
|
||||
GSM48_QOS_RBER_4e_3 = 0x04,
|
||||
GSM48_QOS_RBER_1e_3 = 0x05,
|
||||
GSM48_QOS_RBER_1e_4 = 0x06,
|
||||
GSM48_QOS_RBER_1e_5 = 0x07,
|
||||
GSM48_QOS_RBER_1e_6 = 0x08,
|
||||
GSM48_QOS_RBER_6e_8 = 0x09,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_sdu_err {
|
||||
GSM48_QOS_SERR_1e_2 = 0x01,
|
||||
GSM48_QOS_SERR_7e_2 = 0x02,
|
||||
GSM48_QOS_SERR_1e_3 = 0x03,
|
||||
GSM48_QOS_SERR_1e_4 = 0x04,
|
||||
GSM48_QOS_SERR_1e_5 = 0x05,
|
||||
GSM48_QOS_SERR_1e_6 = 0x06,
|
||||
GSM48_QOS_SERR_1e_1 = 0x07,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
struct gsm48_qos {
|
||||
/* octet 3 */
|
||||
uint8_t reliab_class:3;
|
||||
uint8_t delay_class:3;
|
||||
uint8_t spare:2;
|
||||
/* octet 4 */
|
||||
uint8_t preced_class:3;
|
||||
uint8_t spare2:1;
|
||||
uint8_t peak_tput:4;
|
||||
/* octet 5 */
|
||||
uint8_t mean_tput:5;
|
||||
uint8_t spare3:3;
|
||||
/* octet 6 */
|
||||
uint8_t deliv_err_sdu:3;
|
||||
uint8_t deliv_order:2;
|
||||
uint8_t traf_class:3;
|
||||
/* octet 7 */
|
||||
uint8_t max_sdu_size;
|
||||
/* octet 8 */
|
||||
uint8_t max_bitrate_up;
|
||||
/* octet 9 */
|
||||
uint8_t max_bitrate_down;
|
||||
/* octet 10 */
|
||||
uint8_t sdu_err_ratio:4;
|
||||
uint8_t resid_ber:4;
|
||||
/* octet 11 */
|
||||
uint8_t handling_prio:2;
|
||||
uint8_t xfer_delay:6;
|
||||
/* octet 12 */
|
||||
uint8_t guar_bitrate_up;
|
||||
/* octet 13 */
|
||||
uint8_t guar_bitrate_down;
|
||||
/* octet 14 */
|
||||
uint8_t src_stats_desc:4;
|
||||
uint8_t sig_ind:1;
|
||||
uint8_t spare5:3;
|
||||
/* octet 15 */
|
||||
uint8_t max_bitrate_down_ext;
|
||||
/* octet 16 */
|
||||
uint8_t guar_bitrate_down_ext;
|
||||
};
|
||||
|
||||
|
||||
#endif /* _GSM48_GPRS_H */
|
@@ -38,10 +38,5 @@ int gsm411_send_sms(struct gsm_subscriber_connection *conn,
|
||||
struct gsm_sms *sms);
|
||||
void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn);
|
||||
|
||||
uint8_t sms_next_rp_msg_ref(uint8_t *next_rp_ref);
|
||||
|
||||
int gsm411_send_rp_ack(struct gsm_trans *trans, uint8_t msg_ref);
|
||||
int gsm411_send_rp_error(struct gsm_trans *trans, uint8_t msg_ref,
|
||||
uint8_t cause);
|
||||
|
||||
uint8_t sms_next_rp_msg_ref(struct gsm_subscriber_connection *conn);
|
||||
#endif
|
||||
|
@@ -9,17 +9,12 @@ 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);
|
||||
const struct ussd_request *req);
|
||||
int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
|
||||
const struct msgb *msg,
|
||||
const struct ss_request *request);
|
||||
const struct ussd_request *request);
|
||||
|
||||
int msc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level,
|
||||
const char *text);
|
||||
int msc_send_ussd_release_complete(struct gsm_subscriber_connection *conn);
|
||||
|
||||
int bsc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level,
|
||||
const char *text);
|
||||
int bsc_send_ussd_release_complete(struct gsm_subscriber_connection *conn);
|
||||
int gsm0480_send_ussdNotify(struct gsm_subscriber_connection *conn, int level, const char *text);
|
||||
int gsm0480_send_releaseComplete(struct gsm_subscriber_connection *conn);
|
||||
|
||||
#endif
|
||||
|
@@ -2,19 +2,11 @@
|
||||
#define _GSM_DATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <regex.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/stats.h>
|
||||
|
||||
#include <osmocom/crypt/auth.h>
|
||||
|
||||
#include <openbsc/rest_octets.h>
|
||||
#include <openbsc/common_cs.h>
|
||||
|
||||
/** annotations for msgb ownership */
|
||||
#define __uses
|
||||
@@ -23,19 +15,9 @@
|
||||
|
||||
struct mncc_sock_state;
|
||||
struct gsm_subscriber_group;
|
||||
struct bsc_subscr;
|
||||
|
||||
#define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3]
|
||||
|
||||
#define tmsi_from_string(str) strtoul(str, NULL, 10)
|
||||
|
||||
/* 3-bit long values */
|
||||
#define EARFCN_PRIO_INVALID 8
|
||||
#define EARFCN_MEAS_BW_INVALID 8
|
||||
/* 5-bit long values */
|
||||
#define EARFCN_QRXLV_INVALID 32
|
||||
#define EARFCN_THRESH_LOW_INVALID 32
|
||||
|
||||
enum gsm_security_event {
|
||||
GSM_SECURITY_NOAVAIL,
|
||||
GSM_SECURITY_AUTH_FAILED,
|
||||
@@ -65,7 +47,9 @@ struct gsm_auth_info {
|
||||
struct gsm_auth_tuple {
|
||||
int use_count;
|
||||
int key_seq;
|
||||
struct osmo_auth_vector vec;
|
||||
uint8_t rand[16];
|
||||
uint8_t sres[4];
|
||||
uint8_t kc[8];
|
||||
};
|
||||
#define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */
|
||||
|
||||
@@ -114,22 +98,13 @@ 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) */
|
||||
};
|
||||
|
||||
/* active radio connection of a mobile subscriber */
|
||||
/* the per subscriber data for lchan */
|
||||
struct gsm_subscriber_connection {
|
||||
struct llist_head entry;
|
||||
|
||||
/* To whom we are allocated at the moment */
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
/* libbsc subscriber information */
|
||||
struct bsc_subscr *bsub;
|
||||
|
||||
/* LU expiration handling */
|
||||
uint8_t expire_timer_stopped;
|
||||
/* SMS helpers for libmsc */
|
||||
@@ -145,28 +120,19 @@ struct gsm_subscriber_connection {
|
||||
/* Are we part of a special "silent" call */
|
||||
int silent_call;
|
||||
|
||||
/* MNCC rtp bridge markers */
|
||||
int mncc_rtp_bridge;
|
||||
int mncc_rtp_create_pending;
|
||||
int mncc_rtp_connect_pending;
|
||||
|
||||
/* bsc structures */
|
||||
struct osmo_bsc_sccp_con *sccp_con; /* BSC */
|
||||
struct osmo_bsc_sccp_con *sccp_con;
|
||||
|
||||
/* back pointers */
|
||||
struct gsm_network *network;
|
||||
|
||||
int in_release;
|
||||
struct gsm_lchan *lchan; /* BSC */
|
||||
struct gsm_lchan *ho_lchan; /* BSC */
|
||||
struct gsm_bts *bts; /* BSC */
|
||||
struct gsm_lchan *lchan;
|
||||
struct gsm_lchan *ho_lchan;
|
||||
struct gsm_bts *bts;
|
||||
|
||||
/* for assignment handling */
|
||||
struct osmo_timer_list T10; /* BSC */
|
||||
struct gsm_lchan *secondary_lchan; /* BSC */
|
||||
struct osmo_timer_list T10;
|
||||
struct gsm_lchan *secondary_lchan;
|
||||
|
||||
/* connected via 2G or 3G? */
|
||||
enum ran_type via_ran;
|
||||
};
|
||||
|
||||
|
||||
@@ -174,119 +140,62 @@ struct gsm_subscriber_connection {
|
||||
#include "gsm_data_shared.h"
|
||||
|
||||
|
||||
enum {
|
||||
BSC_CTR_CHREQ_TOTAL,
|
||||
BSC_CTR_CHREQ_NO_CHANNEL,
|
||||
BSC_CTR_HANDOVER_ATTEMPTED,
|
||||
BSC_CTR_HANDOVER_NO_CHANNEL,
|
||||
BSC_CTR_HANDOVER_TIMEOUT,
|
||||
BSC_CTR_HANDOVER_COMPLETED,
|
||||
BSC_CTR_HANDOVER_FAILED,
|
||||
BSC_CTR_PAGING_ATTEMPTED,
|
||||
BSC_CTR_PAGING_DETACHED,
|
||||
BSC_CTR_PAGING_COMPLETED,
|
||||
BSC_CTR_PAGING_EXPIRED,
|
||||
BSC_CTR_CHAN_RF_FAIL,
|
||||
BSC_CTR_CHAN_RLL_ERR,
|
||||
BSC_CTR_BTS_OML_FAIL,
|
||||
BSC_CTR_BTS_RSL_FAIL,
|
||||
BSC_CTR_CODEC_AMR_F,
|
||||
BSC_CTR_CODEC_AMR_H,
|
||||
BSC_CTR_CODEC_EFR,
|
||||
BSC_CTR_CODEC_V1_FR,
|
||||
BSC_CTR_CODEC_V1_HR,
|
||||
};
|
||||
|
||||
static const struct rate_ctr_desc bsc_ctr_description[] = {
|
||||
[BSC_CTR_CHREQ_TOTAL] = {"chreq.total", "Received channel requests."},
|
||||
[BSC_CTR_CHREQ_NO_CHANNEL] = {"chreq.no_channel", "Sent to MS no channel available."},
|
||||
[BSC_CTR_HANDOVER_ATTEMPTED] = {"handover.attempted", "Received handover attempts."},
|
||||
[BSC_CTR_HANDOVER_NO_CHANNEL] = {"handover.no_channel", "Sent no channel available responses."},
|
||||
[BSC_CTR_HANDOVER_TIMEOUT] = {"handover.timeout", "Count the amount of timeouts of timer T3103."},
|
||||
[BSC_CTR_HANDOVER_COMPLETED] = {"handover.completed", "Received handover completed."},
|
||||
[BSC_CTR_HANDOVER_FAILED] = {"handover.failed", "Receive HO FAIL messages."},
|
||||
[BSC_CTR_PAGING_ATTEMPTED] = {"paging.attempted", "Paging attempts for a MS."},
|
||||
[BSC_CTR_PAGING_DETACHED] = {"paging.detached", "Counts the amount of paging attempts which couldn't sent out any paging request because no responsible bts found."},
|
||||
[BSC_CTR_PAGING_COMPLETED] = {"paging.completed", "Paging successful completed."},
|
||||
[BSC_CTR_PAGING_EXPIRED] = {"paging.expired", "Paging Request expired because of timeout T3113."},
|
||||
[BSC_CTR_CHAN_RF_FAIL] = {"chan.rf_fail", "Received a RF failure indication from BTS."},
|
||||
[BSC_CTR_CHAN_RLL_ERR] = {"chan.rll_err", "Received a RLL failure with T200 cause from BTS."},
|
||||
[BSC_CTR_BTS_OML_FAIL] = {"bts.oml_fail", "Received a TEI down on a OML link."},
|
||||
[BSC_CTR_BTS_RSL_FAIL] = {"bts.rsl_fail", "Received a TEI down on a OML link."},
|
||||
[BSC_CTR_CODEC_AMR_F] = {"bts.codec_amr_f", "Count the usage of AMR/F codec by channel mode requested."},
|
||||
[BSC_CTR_CODEC_AMR_H] = {"bts.codec_amr_h", "Count the usage of AMR/H codec by channel mode requested."},
|
||||
[BSC_CTR_CODEC_EFR] = {"bts.codec_efr", "Count the usage of EFR codec by channel mode requested."},
|
||||
[BSC_CTR_CODEC_V1_FR] = {"bts.codec_fr", "Count the usage of FR codec by channel mode requested."},
|
||||
[BSC_CTR_CODEC_V1_HR] = {"bts.codec_hr", "Count the usage of HR codec by channel mode requested."},
|
||||
};
|
||||
|
||||
enum {
|
||||
MSC_CTR_LOC_UPDATE_TYPE_ATTACH,
|
||||
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_SMS_SUBMITTED,
|
||||
MSC_CTR_SMS_NO_RECEIVER,
|
||||
MSC_CTR_SMS_DELIVERED,
|
||||
MSC_CTR_SMS_RP_ERR_MEM,
|
||||
MSC_CTR_SMS_RP_ERR_OTHER,
|
||||
MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR,
|
||||
MSC_CTR_CALL_MO_SETUP,
|
||||
MSC_CTR_CALL_MO_CONNECT_ACK,
|
||||
MSC_CTR_CALL_MT_SETUP,
|
||||
MSC_CTR_CALL_MT_CONNECT,
|
||||
MSC_CTR_CALL_ACTIVE,
|
||||
MSC_CTR_CALL_COMPLETE,
|
||||
MSC_CTR_CALL_INCOMPLETE,
|
||||
};
|
||||
|
||||
static const struct rate_ctr_desc msc_ctr_description[] = {
|
||||
[MSC_CTR_LOC_UPDATE_TYPE_ATTACH] = {"loc_update_type.attach", "Received location update imsi attach requests."},
|
||||
[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_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."},
|
||||
[MSC_CTR_SMS_RP_ERR_MEM] = {"sms.rp_err_mem", "CAUSE_MT_MEM_EXCEEDED errors of MS responses on a sms deliver attempt."},
|
||||
[MSC_CTR_SMS_RP_ERR_OTHER] = {"sms.rp_err_other", "Other error of MS responses on a sms delive attempt."},
|
||||
[MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms.deliver_unknown_error", "Unknown error occured during sms delivery."},
|
||||
/* FIXME: count also sms delivered */
|
||||
[MSC_CTR_CALL_MO_SETUP] = {"call.mo_setup", "Received setup requests from a MS to init a MO call."},
|
||||
[MSC_CTR_CALL_MO_CONNECT_ACK] = {"call.mo_connect_ack", "Received a connect ack from MS of a MO call. Call is now succesful connected up."},
|
||||
[MSC_CTR_CALL_MT_SETUP] = {"call.mt_setup", "Sent setup requests to the MS (MT)."},
|
||||
[MSC_CTR_CALL_MT_CONNECT] = {"call.mt_connect", "Sent a connect to the MS (MT)."},
|
||||
[MSC_CTR_CALL_ACTIVE] = {"call.active", "Count total amount of calls that ever reached active state."},
|
||||
[MSC_CTR_CALL_COMPLETE] = {"call.complete", "Count total amount of calls which got terminated by disconnect req or ind after reaching active state."},
|
||||
[MSC_CTR_CALL_INCOMPLETE] = {"call.incomplete", "Count total amount of call which got terminated by any other reason after reaching active state."},
|
||||
};
|
||||
|
||||
|
||||
static const struct rate_ctr_group_desc bsc_ctrg_desc = {
|
||||
"bsc",
|
||||
"base station controller",
|
||||
OSMO_STATS_CLASS_GLOBAL,
|
||||
ARRAY_SIZE(bsc_ctr_description),
|
||||
bsc_ctr_description,
|
||||
};
|
||||
|
||||
static const struct rate_ctr_group_desc msc_ctrg_desc = {
|
||||
"msc",
|
||||
"mobile switching center",
|
||||
OSMO_STATS_CLASS_GLOBAL,
|
||||
ARRAY_SIZE(msc_ctr_description),
|
||||
msc_ctr_description,
|
||||
/* Some statistics of our network */
|
||||
struct gsmnet_stats {
|
||||
struct {
|
||||
struct osmo_counter *total;
|
||||
struct osmo_counter *no_channel;
|
||||
} chreq;
|
||||
struct {
|
||||
struct osmo_counter *attempted;
|
||||
struct osmo_counter *no_channel; /* no channel available */
|
||||
struct osmo_counter *timeout; /* T3103 timeout */
|
||||
struct osmo_counter *completed; /* HO COMPL received */
|
||||
struct osmo_counter *failed; /* HO FAIL received */
|
||||
} handover;
|
||||
struct {
|
||||
struct osmo_counter *attach;
|
||||
struct osmo_counter *normal;
|
||||
struct osmo_counter *periodic;
|
||||
struct osmo_counter *detach;
|
||||
} loc_upd_type;
|
||||
struct {
|
||||
struct osmo_counter *reject;
|
||||
struct osmo_counter *accept;
|
||||
} loc_upd_resp;
|
||||
struct {
|
||||
struct osmo_counter *attempted;
|
||||
struct osmo_counter *detached;
|
||||
struct osmo_counter *completed;
|
||||
struct osmo_counter *expired;
|
||||
} paging;
|
||||
struct {
|
||||
struct osmo_counter *submitted; /* MO SMS submissions */
|
||||
struct osmo_counter *no_receiver;
|
||||
struct osmo_counter *delivered; /* MT SMS deliveries */
|
||||
struct osmo_counter *rp_err_mem;
|
||||
struct osmo_counter *rp_err_other;
|
||||
} sms;
|
||||
struct {
|
||||
struct osmo_counter *mo_setup;
|
||||
struct osmo_counter *mo_connect_ack;
|
||||
struct osmo_counter *mt_setup;
|
||||
struct osmo_counter *mt_connect;
|
||||
} call;
|
||||
struct {
|
||||
struct osmo_counter *rf_fail;
|
||||
struct osmo_counter *rll_err;
|
||||
} chan;
|
||||
struct {
|
||||
struct osmo_counter *oml_fail;
|
||||
struct osmo_counter *rsl_fail;
|
||||
} bts;
|
||||
};
|
||||
|
||||
enum gsm_auth_policy {
|
||||
GSM_AUTH_POLICY_CLOSED, /* only subscribers authorized in DB */
|
||||
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 */
|
||||
};
|
||||
|
||||
#define GSM_T3101_DEFAULT 10
|
||||
@@ -294,13 +203,6 @@ enum gsm_auth_policy {
|
||||
#define GSM_T3113_DEFAULT 60
|
||||
#define GSM_T3122_DEFAULT 10
|
||||
|
||||
struct gsm_tz {
|
||||
int override; /* if 0, use system's time zone instead. */
|
||||
int hr; /* hour */
|
||||
int mn; /* minute */
|
||||
int dst; /* daylight savings */
|
||||
};
|
||||
|
||||
struct gsm_network {
|
||||
/* global parameters */
|
||||
uint16_t country_code;
|
||||
@@ -308,8 +210,6 @@ struct gsm_network {
|
||||
char *name_long;
|
||||
char *name_short;
|
||||
enum gsm_auth_policy auth_policy;
|
||||
regex_t authorized_regexp;
|
||||
char *authorized_reg_str;
|
||||
enum gsm48_reject_value reject_cause;
|
||||
int a5_encryption;
|
||||
int neci;
|
||||
@@ -331,13 +231,11 @@ struct gsm_network {
|
||||
unsigned int max_distance; /* TA values */
|
||||
} handover;
|
||||
|
||||
struct rate_ctr_group *bsc_ctrs;
|
||||
struct rate_ctr_group *msc_ctrs;
|
||||
struct osmo_counter *active_calls;
|
||||
struct gsmnet_stats stats;
|
||||
|
||||
/* layer 4 */
|
||||
struct mncc_sock_state *mncc_state;
|
||||
mncc_recv_cb_t mncc_recv;
|
||||
int (*mncc_recv) (struct gsm_network *net, struct msgb *msg);
|
||||
struct llist_head upqueue;
|
||||
struct llist_head trans_list;
|
||||
struct bsc_api *bsc_api;
|
||||
@@ -367,7 +265,10 @@ struct gsm_network {
|
||||
enum rrlp_mode mode;
|
||||
} rrlp;
|
||||
|
||||
enum gsm_chan_t ctype_by_chreq[18];
|
||||
/* enable the DTXu and DTXd for this network */
|
||||
int dtx_enabled;
|
||||
|
||||
enum gsm_chan_t ctype_by_chreq[16];
|
||||
|
||||
/* Use a TCH for handling requests of type paging any */
|
||||
int pag_any_tch;
|
||||
@@ -376,39 +277,13 @@ struct gsm_network {
|
||||
struct osmo_bsc_data *bsc_data;
|
||||
|
||||
/* subscriber related features */
|
||||
bool auto_create_subscr;
|
||||
bool auto_assign_exten;
|
||||
uint64_t ext_min;
|
||||
uint64_t ext_max;
|
||||
int create_subscriber;
|
||||
struct gsm_subscriber_group *subscr_group;
|
||||
struct gsm_sms_queue *sms_queue;
|
||||
|
||||
/* nitb related control */
|
||||
int avoid_tmsi;
|
||||
uint64_t exten_prefix;
|
||||
|
||||
/* control interface */
|
||||
struct ctrl_handle *ctrl;
|
||||
|
||||
/* Allow or disallow TCH/F on dynamic TCH/F_TCH/H_PDCH; OS#1778 */
|
||||
bool dyn_ts_allow_tch_f;
|
||||
|
||||
/* all active subscriber connections. */
|
||||
struct llist_head subscr_conns;
|
||||
|
||||
/* if override is nonzero, this timezone data is used for all MM
|
||||
* 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). */
|
||||
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;
|
||||
};
|
||||
|
||||
struct osmo_esme;
|
||||
@@ -435,11 +310,6 @@ struct gsm_sms {
|
||||
struct gsm_sms_addr src, dst;
|
||||
enum gsm_sms_source_id source;
|
||||
|
||||
struct {
|
||||
uint8_t transaction_id;
|
||||
uint32_t msg_ref;
|
||||
} gsm411;
|
||||
|
||||
struct {
|
||||
struct osmo_esme *esme;
|
||||
uint32_t sequence_nr;
|
||||
@@ -460,8 +330,8 @@ struct gsm_sms {
|
||||
char text[SMS_TEXT_SIZE];
|
||||
};
|
||||
|
||||
extern void talloc_ctx_init(void *ctx_root);
|
||||
|
||||
struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code,
|
||||
int (*mncc_recv)(struct gsm_network *, struct msgb *));
|
||||
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 */
|
||||
@@ -481,7 +351,7 @@ static inline int is_ipaccess_bts(struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
case GSM_BTS_TYPE_OSMOBTS:
|
||||
case GSM_BTS_TYPE_OSMO_SYSMO:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
@@ -492,7 +362,7 @@ static inline int is_ipaccess_bts(struct gsm_bts *bts)
|
||||
static inline int is_sysmobts_v2(struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_OSMOBTS:
|
||||
case GSM_BTS_TYPE_OSMO_SYSMO:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
@@ -555,21 +425,18 @@ 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);
|
||||
|
||||
struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lchan);
|
||||
void bsc_subscr_con_free(struct gsm_subscriber_connection *conn);
|
||||
|
||||
struct gsm_subscriber_connection *msc_subscr_con_allocate(struct gsm_network *network);
|
||||
void msc_subscr_con_free(struct gsm_subscriber_connection *conn);
|
||||
struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan);
|
||||
void subscr_con_free(struct gsm_subscriber_connection *conn);
|
||||
|
||||
struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net,
|
||||
enum gsm_bts_type type,
|
||||
uint8_t bsic);
|
||||
uint8_t tsc, uint8_t bsic);
|
||||
|
||||
void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
|
||||
uint8_t e1_ts, uint8_t e1_ts_ss);
|
||||
|
||||
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
|
||||
bool gsm_btsmodel_has_feature(struct gsm_bts_model *model, enum gsm_bts_features feat);
|
||||
int gsm_bts_has_feature(struct gsm_bts *bts, enum gsm_bts_features feat);
|
||||
struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
|
||||
int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx);
|
||||
int gsm_bts_set_system_infos(struct gsm_bts *bts);
|
||||
@@ -590,7 +457,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);
|
||||
|
||||
int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts);
|
||||
void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value);
|
||||
|
||||
#endif /* _GSM_DATA_H */
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#include <osmocom/gsm/rxlev_stat.h>
|
||||
#include <osmocom/gsm/sysinfo.h>
|
||||
#include <osmocom/gsm/meas_rep.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
||||
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||
|
||||
@@ -24,15 +24,6 @@
|
||||
#include <osmocom/gsm/lapdm.h>
|
||||
#endif
|
||||
|
||||
#include <openbsc/common_cs.h>
|
||||
|
||||
/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1:
|
||||
4-bit index is used (2#1111 = 10#15) */
|
||||
#define SI2Q_MAX_NUM 16
|
||||
/* length in bits (for single SI2quater message) */
|
||||
#define SI2Q_MAX_LEN 160
|
||||
#define SI2Q_MIN_LEN 18
|
||||
|
||||
struct osmo_bsc_data;
|
||||
|
||||
struct osmo_bsc_sccp_con;
|
||||
@@ -53,17 +44,13 @@ 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,
|
||||
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
|
||||
#define CCCH_LCHAN 4
|
||||
|
||||
#define TRX_NR_TS 8
|
||||
#define TS_MAX_LCHAN 8
|
||||
|
||||
#define HARDCODED_ARFCN 123
|
||||
#define HARDCODED_TSC 7
|
||||
#define HARDCODED_BSIC 0x3f /* NCC = 7 / BCC = 7 */
|
||||
|
||||
/* for multi-drop config */
|
||||
@@ -71,10 +58,6 @@ enum gsm_chreq_reason_t {
|
||||
#define HARDCODED_BTS1_TS 6
|
||||
#define HARDCODED_BTS2_TS 11
|
||||
|
||||
#define MAX_VERSION_LENGTH 64
|
||||
|
||||
#define MAX_BTS_FEATURES 128
|
||||
|
||||
enum gsm_hooks {
|
||||
GSM_HOOK_NM_SWLOAD,
|
||||
GSM_HOOK_RR_PAGING,
|
||||
@@ -118,24 +101,11 @@ struct gsm_abis_mo {
|
||||
struct gsm_bts *bts;
|
||||
};
|
||||
|
||||
/* Ericsson OM2000 Managed Object */
|
||||
struct abis_om2k_mo {
|
||||
uint8_t class;
|
||||
uint8_t bts;
|
||||
uint8_t assoc_so;
|
||||
uint8_t inst;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct om2k_mo {
|
||||
struct abis_om2k_mo addr;
|
||||
struct osmo_fsm_inst *fsm;
|
||||
};
|
||||
|
||||
#define MAX_A5_KEY_LEN (128/8)
|
||||
#define A38_XOR_MIN_KEY_LEN 12
|
||||
#define A38_XOR_MAX_KEY_LEN 16
|
||||
#define A38_COMP128_KEY_LEN 16
|
||||
#define RSL_ENC_ALG_A5(x) (x+1)
|
||||
#define MAX_EARFCN_LIST 32
|
||||
|
||||
/* is the data link established? who established it? */
|
||||
#define LCHAN_SAPI_UNUSED 0
|
||||
@@ -180,14 +150,14 @@ struct bts_codec_conf {
|
||||
|
||||
struct amr_mode {
|
||||
uint8_t mode;
|
||||
uint8_t threshold;
|
||||
uint8_t hysteresis;
|
||||
uint8_t threshold_ms;
|
||||
uint8_t hysteresis_ms;
|
||||
uint8_t threshold_bts;
|
||||
uint8_t hysteresis_bts;
|
||||
};
|
||||
|
||||
struct amr_multirate_conf {
|
||||
uint8_t gsm48_ie[2];
|
||||
struct amr_mode ms_mode[4];
|
||||
struct amr_mode bts_mode[4];
|
||||
struct amr_mode mode[4];
|
||||
uint8_t num_modes;
|
||||
};
|
||||
/* /BTS ONLY */
|
||||
@@ -232,7 +202,11 @@ struct gsm_lchan {
|
||||
uint8_t bs_power;
|
||||
uint8_t ms_power;
|
||||
/* Encryption information */
|
||||
struct gsm_encr encr;
|
||||
struct {
|
||||
uint8_t alg_id;
|
||||
uint8_t key_len;
|
||||
uint8_t key[MAX_A5_KEY_LEN];
|
||||
} encr;
|
||||
|
||||
/* AMR bits */
|
||||
uint8_t mr_ms_lv[7];
|
||||
@@ -260,8 +234,6 @@ struct gsm_lchan {
|
||||
|
||||
uint8_t rqd_ta;
|
||||
|
||||
char *name;
|
||||
|
||||
#ifdef ROLE_BSC
|
||||
struct osmo_timer_list T3101;
|
||||
struct osmo_timer_list T3109;
|
||||
@@ -282,14 +254,6 @@ struct gsm_lchan {
|
||||
struct gsm48_req_ref *rqd_ref;
|
||||
|
||||
struct gsm_subscriber_connection *conn;
|
||||
|
||||
struct {
|
||||
/* channel activation type and handover ref */
|
||||
uint8_t act_type;
|
||||
uint8_t ho_ref;
|
||||
struct gsm48_req_ref *rqd_ref;
|
||||
uint8_t rqd_ta;
|
||||
} dyn;
|
||||
#else
|
||||
/* Number of different GsmL1_Sapi_t used in osmo_bts_sysmo is 23.
|
||||
* Currently we don't share these headers so this is a magic number. */
|
||||
@@ -302,9 +266,8 @@ struct gsm_lchan {
|
||||
/* bitmask of all SI that are present/valid in si_buf */
|
||||
uint32_t valid;
|
||||
uint32_t last;
|
||||
/* buffers where we put the pre-computed SI:
|
||||
SI2Q_MAX_NUM is the max number of SI2quater messages (see 3GPP TS 44.018) */
|
||||
sysinfo_buf_t buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
|
||||
/* buffers where we put the pre-computed SI */
|
||||
sysinfo_buf_t buf[_MAX_SYSINFO_TYPE];
|
||||
} si;
|
||||
struct {
|
||||
uint8_t flags;
|
||||
@@ -322,30 +285,11 @@ struct gsm_lchan {
|
||||
struct {
|
||||
struct amr_multirate_conf amr_mr;
|
||||
struct {
|
||||
struct osmo_fsm_inst *dl_amr_fsm;
|
||||
/* TCH cache */
|
||||
uint8_t cache[20];
|
||||
/* FACCH cache */
|
||||
uint8_t facch[GSM_MACBLOCK_LEN];
|
||||
uint8_t buf[16];
|
||||
uint8_t len;
|
||||
uint32_t fn;
|
||||
bool is_update;
|
||||
/* set for each SID frame to detect talkspurt for codecs
|
||||
without explicit ONSET event */
|
||||
bool ul_sid;
|
||||
/* indicates if DTXd was active during DL measurement
|
||||
period */
|
||||
bool dl_active;
|
||||
} dtx;
|
||||
} last_sid;
|
||||
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;
|
||||
@@ -362,26 +306,16 @@ struct gsm_lchan {
|
||||
int s;
|
||||
/* Kind of the release/activation. E.g. RSL or PCU */
|
||||
int rel_act_kind;
|
||||
/* RTP header Marker bit to indicate beginning of speech after pause */
|
||||
bool rtp_tx_marker;
|
||||
|
||||
/* power handling */
|
||||
struct {
|
||||
uint8_t current;
|
||||
uint8_t fixed;
|
||||
} ms_power_ctrl;
|
||||
|
||||
struct msgb *pending_rel_ind_msg;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum {
|
||||
TS_F_PDCH_ACTIVE = 0x1000,
|
||||
TS_F_PDCH_ACT_PENDING = 0x2000,
|
||||
TS_F_PDCH_DEACT_PENDING = 0x4000,
|
||||
TS_F_PDCH_PENDING_MASK = 0x6000 /*<
|
||||
TS_F_PDCH_ACT_PENDING | TS_F_PDCH_DEACT_PENDING */
|
||||
} gsm_bts_trx_ts_flags;
|
||||
|
||||
#define TS_F_PDCH_MODE 0x1000
|
||||
/* One Timeslot in a TRX */
|
||||
struct gsm_bts_trx_ts {
|
||||
struct gsm_bts_trx *trx;
|
||||
@@ -390,12 +324,6 @@ struct gsm_bts_trx_ts {
|
||||
|
||||
enum gsm_phys_chan_config pchan;
|
||||
|
||||
struct {
|
||||
enum gsm_phys_chan_config pchan_is;
|
||||
enum gsm_phys_chan_config pchan_want;
|
||||
struct msgb *pending_chan_activ;
|
||||
} dyn;
|
||||
|
||||
unsigned int flags;
|
||||
struct gsm_abis_mo mo;
|
||||
struct tlv_parsed nm_attr;
|
||||
@@ -418,12 +346,6 @@ struct gsm_bts_trx_ts {
|
||||
/* To which E1 subslot are we connected */
|
||||
struct gsm_e1_subslot e1_link;
|
||||
|
||||
union {
|
||||
struct {
|
||||
struct om2k_mo om2k_mo;
|
||||
} rbs2000;
|
||||
};
|
||||
|
||||
struct gsm_lchan lchan[TS_MAX_LCHAN];
|
||||
};
|
||||
|
||||
@@ -478,25 +400,11 @@ struct gsm_bts_trx {
|
||||
uint8_t test_nr;
|
||||
struct rxlev_stats rxlev_stat;
|
||||
} ipaccess;
|
||||
struct {
|
||||
struct {
|
||||
struct om2k_mo om2k_mo;
|
||||
} trxc;
|
||||
struct {
|
||||
struct om2k_mo om2k_mo;
|
||||
} rx;
|
||||
struct {
|
||||
struct om2k_mo om2k_mo;
|
||||
} tx;
|
||||
} rbs2000;
|
||||
};
|
||||
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
||||
};
|
||||
|
||||
#define GSM_BTS_SI2Q(bts, i) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
|
||||
#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
|
||||
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
|
||||
#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0])
|
||||
#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i])
|
||||
|
||||
enum gsm_bts_type {
|
||||
GSM_BTS_TYPE_UNKNOWN,
|
||||
@@ -504,33 +412,16 @@ enum gsm_bts_type {
|
||||
GSM_BTS_TYPE_NANOBTS,
|
||||
GSM_BTS_TYPE_RBS2000,
|
||||
GSM_BTS_TYPE_NOKIA_SITE,
|
||||
GSM_BTS_TYPE_OSMOBTS,
|
||||
GSM_BTS_TYPE_OSMO_SYSMO,
|
||||
_NUM_GSM_BTS_TYPE
|
||||
};
|
||||
|
||||
enum gsm_bts_type_variant {
|
||||
BTS_UNKNOWN,
|
||||
BTS_OSMO_LITECELL15,
|
||||
BTS_OSMO_OCTPHY,
|
||||
BTS_OSMO_SYSMO,
|
||||
BTS_OSMO_TRX,
|
||||
_NUM_BTS_VARIANT
|
||||
};
|
||||
|
||||
/* Used by OML layer for BTS Attribute reporting */
|
||||
enum bts_attribute {
|
||||
BTS_TYPE_VARIANT,
|
||||
BTS_SUB_MODEL,
|
||||
TRX_PHY_VERSION,
|
||||
};
|
||||
|
||||
struct vty;
|
||||
|
||||
struct gsm_bts_model {
|
||||
struct llist_head list;
|
||||
|
||||
enum gsm_bts_type type;
|
||||
enum gsm_bts_type_variant variant;
|
||||
const char *name;
|
||||
|
||||
bool started;
|
||||
@@ -545,13 +436,10 @@ struct gsm_bts_model {
|
||||
|
||||
struct tlv_definition nm_att_tlvdef;
|
||||
|
||||
/* features of a given BTS model set via gsm_bts_model_register() locally */
|
||||
struct bitvec features;
|
||||
uint8_t _features_data[MAX_BTS_FEATURES/8];
|
||||
uint8_t _features_data[128/8];
|
||||
};
|
||||
|
||||
/* N. B: always add new features to the end of the list (right before _NUM_BTS_FEAT) to avoid breaking compatibility
|
||||
with BTS compiled against earlier version of this header */
|
||||
enum gsm_bts_features {
|
||||
BTS_FEAT_HSCSD,
|
||||
BTS_FEAT_GPRS,
|
||||
@@ -559,14 +447,8 @@ enum gsm_bts_features {
|
||||
BTS_FEAT_ECSD,
|
||||
BTS_FEAT_HOPPING,
|
||||
BTS_FEAT_MULTI_TSC,
|
||||
BTS_FEAT_OML_ALERTS,
|
||||
BTS_FEAT_AGCH_PCH_PROP,
|
||||
BTS_FEAT_CBCH,
|
||||
_NUM_BTS_FEAT
|
||||
};
|
||||
|
||||
extern const struct value_string gsm_bts_features_descs[];
|
||||
|
||||
/*
|
||||
* This keeps track of the paging status of one BTS. It
|
||||
* includes a number of pending requests, a back pointer
|
||||
@@ -687,24 +569,14 @@ struct gsm_bts {
|
||||
uint16_t cell_identity;
|
||||
/* location area code of this BTS */
|
||||
uint16_t location_area_code;
|
||||
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
|
||||
* which is used as TSC for the CCCH */
|
||||
/* Training Sequence Code */
|
||||
uint8_t tsc;
|
||||
/* Base Station Identification Code (BSIC) */
|
||||
uint8_t bsic;
|
||||
/* type of BTS */
|
||||
enum gsm_bts_type type;
|
||||
enum gsm_bts_type_variant variant;
|
||||
struct gsm_bts_model *model;
|
||||
enum gsm_band band;
|
||||
char version[MAX_VERSION_LENGTH];
|
||||
char sub_model[MAX_VERSION_LENGTH];
|
||||
|
||||
/* features of a given BTS set/reported via OML */
|
||||
struct bitvec features;
|
||||
uint8_t _features_data[MAX_BTS_FEATURES/8];
|
||||
|
||||
/* Connected PCU version (if any) */
|
||||
char pcu_version[MAX_VERSION_LENGTH];
|
||||
|
||||
/* maximum Tx power that the MS is permitted to use in this cell */
|
||||
int ms_max_power;
|
||||
|
||||
@@ -721,10 +593,6 @@ struct gsm_bts {
|
||||
/* number of this BTS on given E1 link */
|
||||
uint8_t bts_nr;
|
||||
|
||||
/* DTX features of this BTS */
|
||||
enum gsm48_dtx_mode dtxu;
|
||||
bool dtxd;
|
||||
|
||||
/* paging state and control */
|
||||
struct gsm_bts_paging_state paging;
|
||||
|
||||
@@ -737,14 +605,16 @@ struct gsm_bts {
|
||||
|
||||
/* bitmask of all SI that are present/valid in si_buf */
|
||||
uint32_t si_valid;
|
||||
/* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
|
||||
uint8_t si2q_index; /* distinguish individual SI2quater messages */
|
||||
uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
|
||||
/* buffers where we put the pre-computed SI */
|
||||
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
|
||||
/* offsets used while generating SI2quater */
|
||||
size_t e_offset;
|
||||
size_t u_offset;
|
||||
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
|
||||
|
||||
/* TimeZone hours, mins, and bts specific */
|
||||
struct {
|
||||
int hr;
|
||||
int mn;
|
||||
int override;
|
||||
int dst;
|
||||
} tz;
|
||||
|
||||
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
|
||||
union {
|
||||
@@ -765,29 +635,19 @@ struct gsm_bts {
|
||||
} bs11;
|
||||
struct {
|
||||
struct {
|
||||
struct om2k_mo om2k_mo;
|
||||
struct gsm_abis_mo mo;
|
||||
struct llist_head conn_groups;
|
||||
} cf;
|
||||
struct {
|
||||
struct om2k_mo om2k_mo;
|
||||
struct gsm_abis_mo mo;
|
||||
struct llist_head conn_groups;
|
||||
} is;
|
||||
struct {
|
||||
struct om2k_mo om2k_mo;
|
||||
struct gsm_abis_mo mo;
|
||||
struct llist_head conn_groups;
|
||||
} con;
|
||||
struct {
|
||||
struct om2k_mo om2k_mo;
|
||||
struct gsm_abis_mo mo;
|
||||
} dp;
|
||||
struct {
|
||||
struct om2k_mo om2k_mo;
|
||||
struct gsm_abis_mo mo;
|
||||
} tf;
|
||||
uint32_t use_superchannel:1;
|
||||
} rbs2000;
|
||||
struct {
|
||||
uint8_t bts_type;
|
||||
@@ -803,7 +663,6 @@ struct gsm_bts {
|
||||
|
||||
/* Not entirely sure how ip.access specific this is */
|
||||
struct {
|
||||
uint8_t supports_egprs_11bit_rach;
|
||||
enum bts_gprs_mode mode;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
@@ -819,7 +678,6 @@ struct gsm_bts {
|
||||
struct gsm_bts_gprs_nsvc nsvc[2];
|
||||
uint8_t rac;
|
||||
uint8_t net_ctrl_ord;
|
||||
bool ctrl_ack_type_use_block;
|
||||
} gprs;
|
||||
|
||||
/* RACH NM values */
|
||||
@@ -857,23 +715,14 @@ struct gsm_bts {
|
||||
struct bitvec neigh_list;
|
||||
struct bitvec cell_alloc;
|
||||
struct bitvec si5_neigh_list;
|
||||
struct osmo_earfcn_si2q si2quater_neigh_list;
|
||||
size_t uarfcn_length; /* index for uarfcn and scramble lists */
|
||||
struct {
|
||||
/* bitmask large enough for all possible ARFCN's */
|
||||
uint8_t neigh_list[1024/8];
|
||||
uint8_t cell_alloc[1024/8];
|
||||
/* If the user wants a different neighbor list in SI5 than in SI2 */
|
||||
uint8_t si5_neigh_list[1024/8];
|
||||
uint8_t meas_bw_list[MAX_EARFCN_LIST];
|
||||
uint16_t earfcn_list[MAX_EARFCN_LIST];
|
||||
uint16_t uarfcn_list[MAX_EARFCN_LIST];
|
||||
uint16_t scramble_list[MAX_EARFCN_LIST];
|
||||
} data;
|
||||
} si_common;
|
||||
bool early_classmark_allowed;
|
||||
/* for testing only: Have an infinitely long radio link timeout */
|
||||
bool infinite_radio_link_timeout;
|
||||
|
||||
/* do we use static (user-defined) system information messages? (bitmask) */
|
||||
uint32_t si_mode_static;
|
||||
@@ -891,10 +740,6 @@ struct gsm_bts {
|
||||
struct amr_multirate_conf mr_full;
|
||||
struct amr_multirate_conf mr_half;
|
||||
|
||||
/* PCU socket state */
|
||||
char *pcu_sock_path;
|
||||
struct pcu_sock_state *pcu_state;
|
||||
|
||||
#endif /* ROLE_BSC */
|
||||
void *role;
|
||||
};
|
||||
@@ -906,44 +751,19 @@ struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
|
||||
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
|
||||
struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num);
|
||||
|
||||
enum gsm_bts_type str2btstype(const char *arg);
|
||||
const char *btstype2str(enum gsm_bts_type type);
|
||||
|
||||
enum bts_attribute str2btsattr(const char *s);
|
||||
const char *btsatttr2str(enum bts_attribute v);
|
||||
|
||||
enum gsm_bts_type_variant str2btsvariant(const char *arg);
|
||||
const char *btsvariant2str(enum gsm_bts_type_variant v);
|
||||
|
||||
extern const struct value_string gsm_chreq_descs[];
|
||||
const struct value_string gsm_pchant_names[13];
|
||||
const struct value_string gsm_pchant_descs[13];
|
||||
const struct value_string gsm_pchant_names[12];
|
||||
const struct value_string gsm_pchant_descs[12];
|
||||
const struct value_string gsm_lchant_names[8];
|
||||
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
|
||||
enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
|
||||
const char *gsm_lchant_name(enum gsm_chan_t c);
|
||||
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
|
||||
char *gsm_trx_name(const struct gsm_bts_trx *trx);
|
||||
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);
|
||||
char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts);
|
||||
char *gsm_lchan_name_compute(const struct gsm_lchan *lchan);
|
||||
char *gsm_lchan_name(const struct gsm_lchan *lchan);
|
||||
const char *gsm_lchans_name(enum gsm_lchan_state s);
|
||||
|
||||
static inline char *gsm_lchan_name(const struct gsm_lchan *lchan)
|
||||
{
|
||||
return lchan->name;
|
||||
}
|
||||
|
||||
static inline int gsm_bts_set_feature(struct gsm_bts *bts, enum gsm_bts_features feat)
|
||||
{
|
||||
OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES);
|
||||
return bitvec_set_bit_pos(&bts->features, feat, 1);
|
||||
}
|
||||
|
||||
static inline bool gsm_bts_has_feature(const struct gsm_bts *bts, enum gsm_bts_features feat)
|
||||
{
|
||||
OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES);
|
||||
return bitvec_get_bit_pos(&bts->features, feat);
|
||||
}
|
||||
|
||||
void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
|
||||
|
||||
@@ -961,11 +781,8 @@ gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
|
||||
/* reset the state of all MO in the BTS */
|
||||
void gsm_bts_mo_reset(struct gsm_bts *bts);
|
||||
|
||||
uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
||||
uint8_t ts_nr, uint8_t lchan_nr);
|
||||
uint8_t gsm_ts2chan_nr(const struct gsm_bts_trx_ts *ts, uint8_t lchan_nr);
|
||||
uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan);
|
||||
uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
|
||||
enum gsm_phys_chan_config as_pchan);
|
||||
|
||||
/* return the gsm_lchan for the CBCH (if it exists at all) */
|
||||
struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
|
||||
@@ -981,14 +798,8 @@ static inline uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)
|
||||
if (ts->tsc != -1)
|
||||
return ts->tsc;
|
||||
else
|
||||
return ts->trx->bts->bsic & 7;
|
||||
return ts->trx->bts->tsc;
|
||||
}
|
||||
|
||||
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
|
||||
int *rc);
|
||||
|
||||
enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts);
|
||||
uint8_t ts_subslots(struct gsm_bts_trx_ts *ts);
|
||||
bool ts_is_tch(struct gsm_bts_trx_ts *ts);
|
||||
|
||||
#endif
|
||||
|
@@ -1,13 +1,11 @@
|
||||
#ifndef _GSM_SUBSCR_H
|
||||
#define _GSM_SUBSCR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "gsm_data.h"
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
#define GSM_IMEI_LENGTH 17
|
||||
#define GSM_IMSI_LENGTH 17
|
||||
#define GSM_NAME_LENGTH 160
|
||||
|
||||
#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */
|
||||
@@ -16,6 +14,7 @@
|
||||
|
||||
#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
|
||||
|
||||
@@ -33,7 +32,7 @@ struct gsm_subscriber_group {
|
||||
|
||||
struct gsm_equipment {
|
||||
long long unsigned int id;
|
||||
char imei[GSM23003_IMEISV_NUM_DIGITS+1];
|
||||
char imei[GSM_IMEI_LENGTH];
|
||||
char name[GSM_NAME_LENGTH];
|
||||
|
||||
struct gsm48_classmark1 classmark1;
|
||||
@@ -46,7 +45,7 @@ struct gsm_equipment {
|
||||
struct gsm_subscriber {
|
||||
struct gsm_subscriber_group *group;
|
||||
long long unsigned int id;
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
uint32_t tmsi;
|
||||
uint16_t lac;
|
||||
char name[GSM_NAME_LENGTH];
|
||||
|
@@ -1,523 +0,0 @@
|
||||
/* GTP Hub Implementation */
|
||||
|
||||
/* (C) 2015 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Neels Hofmeyr
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
|
||||
|
||||
/* support */
|
||||
|
||||
/* TODO move to osmocom/core/socket.c ? */
|
||||
#include <netdb.h> /* for IPPROTO_* etc */
|
||||
struct osmo_sockaddr {
|
||||
struct sockaddr_storage a;
|
||||
socklen_t l;
|
||||
};
|
||||
|
||||
/* TODO move to osmocom/core/socket.c ? */
|
||||
/*! \brief Initialize a sockaddr
|
||||
* \param[out] addr Valid osmo_sockaddr pointer to write result to
|
||||
* \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC
|
||||
* \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
|
||||
* \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
|
||||
* \param[in] host Remote host name or IP address in string form
|
||||
* \param[in] port Remote port number in host byte order
|
||||
* \returns 0 on success, otherwise an error code (from getaddrinfo()).
|
||||
*
|
||||
* Copy the first result from a getaddrinfo() call with the given parameters to
|
||||
* *addr and *addr_len. On error, do not change *addr and return nonzero.
|
||||
*/
|
||||
int osmo_sockaddr_init(struct osmo_sockaddr *addr,
|
||||
uint16_t family, uint16_t type, uint8_t proto,
|
||||
const char *host, uint16_t port);
|
||||
|
||||
/* Conveniently pass AF_UNSPEC, SOCK_DGRAM and IPPROTO_UDP to
|
||||
* osmo_sockaddr_init(). */
|
||||
static inline int osmo_sockaddr_init_udp(struct osmo_sockaddr *addr,
|
||||
const char *host, uint16_t port)
|
||||
{
|
||||
return osmo_sockaddr_init(addr, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,
|
||||
host, port);
|
||||
}
|
||||
|
||||
/*! \brief convert sockaddr to human readable string.
|
||||
* \param[out] addr_str Valid pointer to a buffer of length addr_str_len.
|
||||
* \param[in] addr_str_len Size of buffer addr_str points at.
|
||||
* \param[out] port_str Valid pointer to a buffer of length port_str_len.
|
||||
* \param[in] port_str_len Size of buffer port_str points at.
|
||||
* \param[in] addr Binary representation as returned by osmo_sockaddr_init().
|
||||
* \param[in] flags flags as passed to getnameinfo().
|
||||
* \returns 0 on success, an error code on error.
|
||||
*
|
||||
* Return the IPv4 or IPv6 address string and the port (a.k.a. service) string
|
||||
* representations of the given struct osmo_sockaddr in two caller provided
|
||||
* char buffers. Flags of (NI_NUMERICHOST | NI_NUMERICSERV) return numeric
|
||||
* address and port. Either one of addr_str or port_str may be NULL, in which
|
||||
* case nothing is returned there.
|
||||
*
|
||||
* See also osmo_sockaddr_to_str() (less flexible, but much more convenient). */
|
||||
int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len,
|
||||
char *port_str, size_t port_str_len,
|
||||
const struct osmo_sockaddr *addr,
|
||||
int flags);
|
||||
|
||||
|
||||
/*! \brief concatenate the parts returned by osmo_sockaddr_to_strs().
|
||||
* \param[in] addr Binary representation as returned by osmo_sockaddr_init().
|
||||
* \param[in] buf A buffer to use for string operations.
|
||||
* \param[in] buf_len Length of the buffer.
|
||||
* \returns Address string (in buffer).
|
||||
*
|
||||
* Compose a string of the numeric IP-address and port represented by *addr of
|
||||
* the form "<ip-addr> port <port>". The returned string is valid until the
|
||||
* next invocation of this function.
|
||||
*/
|
||||
const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr,
|
||||
char *buf, size_t buf_len);
|
||||
|
||||
/*! \brief conveniently return osmo_sockaddr_to_strb() in a static buffer.
|
||||
* \param[in] addr Binary representation as returned by osmo_sockaddr_init().
|
||||
* \returns Address string in static buffer.
|
||||
*
|
||||
* See osmo_sockaddr_to_strb().
|
||||
*
|
||||
* Note: only one osmo_sockaddr_to_str() call will work per print/log
|
||||
* statement. For two or more, use osmo_sockaddr_to_strb() with a separate
|
||||
* buffer each.
|
||||
*/
|
||||
const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *addr);
|
||||
|
||||
/*! \brief compare two osmo_sockaddr.
|
||||
* \param[in] a The first address to compare.
|
||||
* \param[in] b The other address to compare.
|
||||
* \returns 0 if equal, otherwise -1 or 1.
|
||||
*/
|
||||
int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,
|
||||
const struct osmo_sockaddr *b);
|
||||
|
||||
/*! \brief Overwrite *dst with *src.
|
||||
* Like memcpy(), but copy only the valid bytes. */
|
||||
void osmo_sockaddr_copy(struct osmo_sockaddr *dst,
|
||||
const struct osmo_sockaddr *src);
|
||||
|
||||
|
||||
/* general */
|
||||
|
||||
enum gtphub_plane_idx {
|
||||
GTPH_PLANE_CTRL = 0,
|
||||
GTPH_PLANE_USER = 1,
|
||||
GTPH_PLANE_N
|
||||
};
|
||||
|
||||
enum gtphub_side_idx {
|
||||
GTPH_SIDE_SGSN = 0,
|
||||
GTPH_SIDE_GGSN = 1,
|
||||
GTPH_SIDE_N
|
||||
};
|
||||
|
||||
#define for_each_side(I) for (I = 0; I < GTPH_SIDE_N; I++)
|
||||
#define for_each_plane(I) for (I = 0; I < GTPH_PLANE_N; I++)
|
||||
#define for_each_side_and_plane(I,J) for_each_side(I) for_each_plane(J)
|
||||
|
||||
static inline int other_side_idx(int side_idx)
|
||||
{
|
||||
return (side_idx + 1) & 1;
|
||||
}
|
||||
|
||||
extern const char* const gtphub_plane_idx_names[GTPH_PLANE_N];
|
||||
extern const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N];
|
||||
|
||||
extern const char* const gtphub_side_idx_names[GTPH_SIDE_N];
|
||||
|
||||
/* A host address in the form that is expected in the 7.7.32 GSN Address IE.
|
||||
* len is either 4 (IPv4) or 16 (IPv6), any other value is invalid. If no
|
||||
* address is set, len shall be 0. */
|
||||
struct gsn_addr {
|
||||
uint16_t len;
|
||||
uint8_t buf[16];
|
||||
};
|
||||
|
||||
void gsn_addr_copy(struct gsn_addr *gsna, const struct gsn_addr *src);
|
||||
int gsn_addr_from_str(struct gsn_addr *gsna, const char *numeric_addr_str);
|
||||
|
||||
/* Return gsna in numeric string form, in a static buffer. */
|
||||
const char *gsn_addr_to_str(const struct gsn_addr *gsna);
|
||||
|
||||
/* note: strbuf_len doesn't need to be larger than INET6_ADDRSTRLEN + 1. */
|
||||
const char *gsn_addr_to_strb(const struct gsn_addr *gsna,
|
||||
char *strbuf, int strbuf_len);
|
||||
|
||||
/* Return 1 on match, zero otherwise. */
|
||||
int gsn_addr_same(const struct gsn_addr *a, const struct gsn_addr *b);
|
||||
|
||||
/* Decode sa to gsna. Return 0 on success. If port is non-NULL, the port number
|
||||
* from sa is also returned. */
|
||||
int gsn_addr_from_sockaddr(struct gsn_addr *gsna, uint16_t *port,
|
||||
const struct osmo_sockaddr *sa);
|
||||
|
||||
/* expiry */
|
||||
|
||||
struct expiring_item;
|
||||
typedef void (*del_cb_t)(struct expiring_item *);
|
||||
|
||||
struct expiring_item {
|
||||
struct llist_head entry;
|
||||
time_t expiry;
|
||||
del_cb_t del_cb;
|
||||
};
|
||||
|
||||
struct expiry {
|
||||
int expiry_in_seconds;
|
||||
struct llist_head items;
|
||||
};
|
||||
|
||||
/* Initialize an expiry queue. */
|
||||
void expiry_init(struct expiry *exq, int expiry_in_seconds);
|
||||
|
||||
/* Add a new mapping, or restart the expiry timeout for an already listed
|
||||
* mapping. */
|
||||
void expiry_add(struct expiry *exq, struct expiring_item *item, time_t now);
|
||||
|
||||
/* Initialize to all-empty; must be called before using the item in any way. */
|
||||
void expiring_item_init(struct expiring_item *item);
|
||||
|
||||
/* Remove the given item from its expiry queue, and call item->del_cb, if set.
|
||||
* This sets item->del_cb to NULL and is harmless when run a second time on the
|
||||
* same item, so the del_cb may choose to call this function, too, to allow
|
||||
* deleting items from several code paths. */
|
||||
void expiring_item_del(struct expiring_item *item);
|
||||
|
||||
/* Carry out due expiry of mappings. Must be invoked regularly.
|
||||
* 'now' is the current clock count in seconds and must correspond to the clock
|
||||
* count passed to nr_map_add(). A monotonous clock counter should be used. */
|
||||
int expiry_tick(struct expiry *exq, time_t now);
|
||||
|
||||
/* Expire all items. */
|
||||
void expiry_clear(struct expiry *exq);
|
||||
|
||||
|
||||
/* number map */
|
||||
|
||||
/* A number map assigns a "random" mapped number to each user provided number.
|
||||
* If the same number is requested multiple times, the same mapped number is
|
||||
* returned.
|
||||
*
|
||||
* Number maps plug into possibly shared pools and expiry queues, for example:
|
||||
*
|
||||
* mapA -----------+-> pool1 <-+-- mapB
|
||||
* {10->1, 11->5} | {1, 2, 3, ...} | {10->2, 11->3}
|
||||
* | |
|
||||
* | |
|
||||
* /-> \-> expiry1 <-/
|
||||
* | (30 seconds)
|
||||
* |
|
||||
* mapC -------+-----> pool2 <-+-- mapD
|
||||
* {10->1, 11->3} {1, 2, 3, ...} | {10->2, 11->5}
|
||||
* |
|
||||
* expiry2 <-/
|
||||
* (60 seconds)
|
||||
*
|
||||
* A map contains mappings ("10->1"). Each map needs a number pool, which can
|
||||
* be shared with other maps. Each new mapping receives a number from the pool,
|
||||
* which is then unavailable to any other map using the same pool.
|
||||
*
|
||||
* A map may point at an expiry queue, in which case all mappings added to it
|
||||
* are also appended to the expiry queue (using a separate llist entry in the
|
||||
* mapping). Any number of maps may submit to the same expiry queue, if they
|
||||
* desire the same expiry timeout. An expiry queue stores the mappings in
|
||||
* chronological order, so that expiry checking is needed only from the start
|
||||
* of the queue; hence only mappings with identical expiry timeout can be added
|
||||
* to the same expiry queue. Upon expiry, a mapping is dropped from the map it
|
||||
* was submitted at. expiry_tick() needs to be called regularly for each expiry
|
||||
* queue.
|
||||
*
|
||||
* A nr_mapping can be embedded in a larger struct: each mapping can have a
|
||||
* distinct destructor (del_cb), and each del_cb can figure out the container
|
||||
* struct's address and free that upon expiry or manual deletion. So in expiry
|
||||
* queues (and even maps), mappings of different container types can be mixed.
|
||||
* This can help to drastically reduce the amount of unnecessary visits during
|
||||
* expiry checking, for the case that no expiry is pending. An expiry queue
|
||||
* always knows which mappings to expire next, because they are right at the
|
||||
* start of its list.
|
||||
*
|
||||
* Mapping allocation and a del_cb are provided by the caller. If del_cb is
|
||||
* NULL, no deallocation will be done (allowing statically allocated entries).
|
||||
*/
|
||||
|
||||
typedef unsigned int nr_t;
|
||||
|
||||
/* Generator for unused numbers. So far this counts upwards from zero, but the
|
||||
* implementation may change in the future. Treat this like an opaque struct.
|
||||
* If this becomes random, the tests need to be fixed. */
|
||||
struct nr_pool {
|
||||
nr_t last_nr;
|
||||
nr_t nr_min;
|
||||
nr_t nr_max;
|
||||
};
|
||||
|
||||
struct nr_mapping {
|
||||
struct llist_head entry;
|
||||
struct expiring_item expiry_entry;
|
||||
|
||||
void *origin;
|
||||
nr_t orig;
|
||||
nr_t repl;
|
||||
};
|
||||
|
||||
struct nr_map {
|
||||
struct nr_pool *pool; /* multiple nr_maps can share a nr_pool. */
|
||||
struct expiry *add_items_to_expiry;
|
||||
struct llist_head mappings;
|
||||
};
|
||||
|
||||
|
||||
void nr_pool_init(struct nr_pool *pool, nr_t nr_min, nr_t nr_max);
|
||||
|
||||
/* Return the next unused number from the nr_pool. */
|
||||
nr_t nr_pool_next(struct nr_pool *pool);
|
||||
|
||||
/* Initialize the nr_mapping to zero/empty values. */
|
||||
void nr_mapping_init(struct nr_mapping *mapping);
|
||||
|
||||
/* Remove the given mapping from its parent map and expiry queue, and call
|
||||
* mapping->del_cb, if set. */
|
||||
void nr_mapping_del(struct nr_mapping *mapping);
|
||||
|
||||
/* Initialize an (already allocated) nr_map, and set the map's number pool.
|
||||
* Multiple nr_map instances may use the same nr_pool. Set the nr_map's expiry
|
||||
* queue to exq, so that all added mappings are automatically expired after the
|
||||
* time configured in exq. exq may be NULL to disable automatic expiry. */
|
||||
void nr_map_init(struct nr_map *map, struct nr_pool *pool,
|
||||
struct expiry *exq);
|
||||
|
||||
/* Add a new entry to the map. mapping->orig, mapping->origin and
|
||||
* mapping->del_cb must be set before calling this function. The remaining
|
||||
* fields of *mapping will be overwritten. mapping->repl is set to the next
|
||||
* available mapped number from map->pool. 'now' is the current clock count in
|
||||
* seconds; if no map->expiry is used, just pass 0 for 'now'. */
|
||||
void nr_map_add(struct nr_map *map, struct nr_mapping *mapping,
|
||||
time_t now);
|
||||
|
||||
/* Restart the timeout for the given mapping. mapping must be a member of map.
|
||||
*/
|
||||
void nr_map_refresh(struct nr_map *map, struct nr_mapping *mapping,
|
||||
time_t now);
|
||||
|
||||
/* Return a known mapping from nr_orig and the given origin. If nr_orig is
|
||||
* unknown, return NULL. */
|
||||
struct nr_mapping *nr_map_get(const struct nr_map *map,
|
||||
void *origin, nr_t nr_orig);
|
||||
|
||||
/* Return a known mapping to nr_repl. If nr_repl is unknown, return NULL. */
|
||||
struct nr_mapping *nr_map_get_inv(const struct nr_map *map, nr_t nr_repl);
|
||||
|
||||
/* Remove all mappings from map. */
|
||||
void nr_map_clear(struct nr_map *map);
|
||||
|
||||
/* Return 1 if map has no entries, 0 otherwise. */
|
||||
int nr_map_empty(const struct nr_map *map);
|
||||
|
||||
|
||||
/* config */
|
||||
|
||||
static const int GTPH_EXPIRE_QUICKLY_SECS = 30; /* TODO is there a spec for this? */
|
||||
static const int GTPH_EXPIRE_SLOWLY_MINUTES = 6 * 60; /* TODO is there a spec for this? */
|
||||
|
||||
struct gtphub_cfg_addr {
|
||||
const char *addr_str;
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
struct gtphub_cfg_bind {
|
||||
struct gtphub_cfg_addr bind;
|
||||
};
|
||||
|
||||
struct gtphub_cfg {
|
||||
struct gtphub_cfg_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
struct gtphub_cfg_addr proxy[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
int sgsn_use_sender; /* Use sender, not GSN addr IE with std ports */
|
||||
};
|
||||
|
||||
|
||||
/* state */
|
||||
|
||||
struct gtphub_peer {
|
||||
struct llist_head entry;
|
||||
|
||||
struct llist_head addresses; /* Alternatives, not load balancing. */
|
||||
struct nr_pool seq_pool;
|
||||
struct nr_map seq_map;
|
||||
};
|
||||
|
||||
struct gtphub_peer_addr {
|
||||
struct llist_head entry;
|
||||
|
||||
struct gtphub_peer *peer;
|
||||
struct gsn_addr addr;
|
||||
struct llist_head ports;
|
||||
};
|
||||
|
||||
struct gtphub_peer_port {
|
||||
struct llist_head entry;
|
||||
|
||||
struct gtphub_peer_addr *peer_addr;
|
||||
uint16_t port;
|
||||
unsigned int ref_count; /* references from other peers' seq_maps */
|
||||
struct osmo_sockaddr sa; /* a "cache" for (peer_addr->addr, port) */
|
||||
int last_restart_count; /* 0..255 = valid, all else means unknown */
|
||||
|
||||
struct rate_ctr_group *counters_io;
|
||||
};
|
||||
|
||||
struct gtphub_tunnel_endpoint {
|
||||
struct gtphub_peer_port *peer;
|
||||
uint32_t tei_orig; /* from/to peer */
|
||||
|
||||
struct rate_ctr_group *counters_io;
|
||||
};
|
||||
|
||||
struct gtphub_tunnel {
|
||||
struct llist_head entry;
|
||||
struct expiring_item expiry_entry;
|
||||
|
||||
uint32_t tei_repl; /* unique TEI to replace peers' TEIs */
|
||||
struct gtphub_tunnel_endpoint endpoint[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
};
|
||||
|
||||
struct gtphub_bind {
|
||||
struct gsn_addr local_addr;
|
||||
uint16_t local_port;
|
||||
struct osmo_fd ofd;
|
||||
|
||||
/* list of struct gtphub_peer */
|
||||
struct llist_head peers;
|
||||
|
||||
const char *label; /* For logging */
|
||||
struct rate_ctr_group *counters_io;
|
||||
};
|
||||
|
||||
struct gtphub_resolved_ggsn {
|
||||
struct llist_head entry;
|
||||
struct expiring_item expiry_entry;
|
||||
|
||||
/* The APN OI, the Operator Identifier, is the combined address,
|
||||
* including parts of the IMSI and APN NI, and ending with ".gprs". */
|
||||
char apn_oi_str[GSM_APN_LENGTH];
|
||||
|
||||
/* Which address and port we resolved that to. */
|
||||
struct gtphub_peer_port *peer;
|
||||
};
|
||||
|
||||
struct gtphub {
|
||||
struct gtphub_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
|
||||
/* pointers to an entry of to_gsns[s][p].peers */
|
||||
struct gtphub_peer_port *proxy[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
|
||||
/* The TEI numbers will simply wrap and be reused, which will work out
|
||||
* in practice. Problems would arise if one given peer maintained the
|
||||
* same TEI for a time long enough for the TEI nr map to wrap an entire
|
||||
* uint32_t; if a new TEI were mapped every second, this would take
|
||||
* more than 100 years (in which a single given TEI must not time out)
|
||||
* to cause a problem. */
|
||||
struct nr_pool tei_pool;
|
||||
|
||||
struct llist_head tunnels; /* struct gtphub_tunnel */
|
||||
struct llist_head pending_deletes; /* opaque (gtphub.c) */
|
||||
|
||||
struct llist_head ggsn_lookups; /* opaque (gtphub_ares.c) */
|
||||
struct llist_head resolved_ggsns; /* struct gtphub_resolved_ggsn */
|
||||
|
||||
struct osmo_timer_list gc_timer;
|
||||
struct expiry expire_quickly;
|
||||
struct expiry expire_slowly;
|
||||
|
||||
uint8_t restart_counter;
|
||||
|
||||
int sgsn_use_sender;
|
||||
};
|
||||
|
||||
struct gtp_packet_desc;
|
||||
|
||||
|
||||
/* api */
|
||||
|
||||
int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg);
|
||||
int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file);
|
||||
|
||||
/* Initialize and start gtphub: bind to ports, run expiry timers. */
|
||||
int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg,
|
||||
uint8_t restart_counter);
|
||||
|
||||
/* Close all sockets, expire all maps and peers and free all allocations. The
|
||||
* struct is then unusable, unless gtphub_start() is run on it again. */
|
||||
void gtphub_stop(struct gtphub *hub);
|
||||
|
||||
time_t gtphub_now(void);
|
||||
|
||||
/* Remove expired items, empty peers, ... */
|
||||
void gtphub_gc(struct gtphub *hub, time_t now);
|
||||
|
||||
/* Return the string of the first address for this peer. */
|
||||
const char *gtphub_peer_str(struct gtphub_peer *peer);
|
||||
|
||||
/* Return a human readable description of tun in a static buffer. */
|
||||
const char *gtphub_tunnel_str(struct gtphub_tunnel *tun);
|
||||
|
||||
/* Return 1 if all of tun's endpoints are fully established, 0 otherwise. */
|
||||
int gtphub_tunnel_complete(struct gtphub_tunnel *tun);
|
||||
|
||||
int gtphub_handle_buf(struct gtphub *hub,
|
||||
unsigned int side_idx,
|
||||
unsigned int port_idx,
|
||||
const struct osmo_sockaddr *from_addr,
|
||||
uint8_t *buf,
|
||||
size_t received,
|
||||
time_t now,
|
||||
uint8_t **reply_buf,
|
||||
struct osmo_fd **to_ofd,
|
||||
struct osmo_sockaddr *to_addr);
|
||||
|
||||
struct gtphub_peer_port *gtphub_port_have(struct gtphub *hub,
|
||||
struct gtphub_bind *bind,
|
||||
const struct gsn_addr *addr,
|
||||
uint16_t port);
|
||||
|
||||
struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind,
|
||||
const struct osmo_sockaddr *addr);
|
||||
|
||||
void gtphub_resolved_ggsn(struct gtphub *hub, const char *apn_oi_str,
|
||||
struct gsn_addr *resolved_addr,
|
||||
time_t now);
|
||||
|
||||
const char *gtphub_port_str(struct gtphub_peer_port *port);
|
||||
|
||||
int gtphub_write(const struct osmo_fd *to,
|
||||
const struct osmo_sockaddr *to_addr,
|
||||
const uint8_t *buf, size_t buf_len);
|
@@ -3,6 +3,9 @@
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
/* Hand over the specified logical channel to the specified new BTS.
|
||||
* This is the main entry point for the actual handover algorithm,
|
||||
* after it has decided it wants to initiate HO to a specific BTS */
|
||||
int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts);
|
||||
|
||||
/* clear any operation for this connection */
|
||||
|
@@ -5,14 +5,13 @@
|
||||
#include "gsm_subscriber.h"
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/protocol/ipaccess.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
|
||||
struct ipac_msgt_sccp_state {
|
||||
uint8_t src_ref[3];
|
||||
uint8_t dst_ref[3];
|
||||
uint8_t trans_id;
|
||||
uint8_t invoke_id;
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
@@ -1,62 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct sgsn_pdp_ctx;
|
||||
struct msgb;
|
||||
struct gprs_ra_id;
|
||||
|
||||
struct RANAP_RAB_SetupOrModifiedItemIEs_s;
|
||||
struct RANAP_GlobalRNC_ID;
|
||||
|
||||
struct ue_conn_ctx {
|
||||
struct llist_head list;
|
||||
struct osmo_sccp_link *link;
|
||||
uint32_t conn_id;
|
||||
int integrity_active;
|
||||
struct gprs_ra_id ra_id;
|
||||
};
|
||||
|
||||
enum iu_event_type {
|
||||
IU_EVENT_RAB_ASSIGN,
|
||||
IU_EVENT_SECURITY_MODE_COMPLETE,
|
||||
IU_EVENT_IU_RELEASE, /* An actual Iu Release message was received */
|
||||
IU_EVENT_LINK_INVALIDATED, /* A SUA link was lost or closed down */
|
||||
/* FIXME: maybe IU_EVENT_IU_RELEASE and IU_EVENT_LINK_INVALIDATED
|
||||
* should be combined to one generic event that simply means the
|
||||
* ue_conn_ctx should no longer be used, for whatever reason. */
|
||||
};
|
||||
|
||||
extern const struct value_string iu_event_type_names[];
|
||||
static inline const char *iu_event_type_str(enum iu_event_type e)
|
||||
{
|
||||
return get_value_string(iu_event_type_names, e);
|
||||
}
|
||||
|
||||
/* Implementations of iu_recv_cb_t shall find the ue_conn_ctx in msg->dst. */
|
||||
typedef int (* iu_recv_cb_t )(struct msgb *msg, struct gprs_ra_id *ra_id,
|
||||
/* TODO "gprs_" in generic CS+PS domain ^ */
|
||||
uint16_t *sai);
|
||||
|
||||
typedef int (* iu_event_cb_t )(struct ue_conn_ctx *ue_ctx,
|
||||
enum iu_event_type type, void *data);
|
||||
|
||||
typedef int (* iu_rab_ass_resp_cb_t )(struct ue_conn_ctx *ue_ctx, uint8_t rab_id,
|
||||
struct RANAP_RAB_SetupOrModifiedItemIEs_s *setup_ies);
|
||||
|
||||
int iu_init(void *ctx, const char *listen_addr, uint16_t listen_port,
|
||||
iu_recv_cb_t iu_recv_cb, iu_event_cb_t iu_event_cb);
|
||||
|
||||
void iu_link_del(struct osmo_sccp_link *link);
|
||||
|
||||
int iu_tx(struct msgb *msg, uint8_t sapi);
|
||||
|
||||
int iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac);
|
||||
int iu_page_ps(const char *imsi, const uint32_t *ptmsi, uint16_t lac, uint8_t rac);
|
||||
|
||||
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);
|
||||
|
||||
void iu_vty_init(int *asn_debug_p);
|
@@ -17,25 +17,13 @@ struct meas_feed_meas {
|
||||
char name[31+1];
|
||||
char scenario[31+1];
|
||||
struct gsm_meas_rep mr;
|
||||
/* The logical channel type, enum gsm_chan_t */
|
||||
uint8_t lchan_type;
|
||||
/* The physical channel type, enum gsm_phys_chan_config */
|
||||
uint8_t pchan_type;
|
||||
/* number of ths BTS in network */
|
||||
uint8_t bts_nr;
|
||||
/* number of this TRX in the BTS */
|
||||
uint8_t trx_nr;
|
||||
/* number of this timeslot at the TRX */
|
||||
uint8_t ts_nr;
|
||||
/* The logical subslot number in the TS */
|
||||
uint8_t ss_nr;
|
||||
};
|
||||
|
||||
enum meas_feed_msgtype {
|
||||
MEAS_FEED_MEAS = 0,
|
||||
};
|
||||
|
||||
#define MEAS_FEED_VERSION 1
|
||||
#define MEAS_FEED_VERSION 0
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -39,8 +39,7 @@ struct gsm_meas_rep {
|
||||
struct gsm_meas_rep_unidir dl;
|
||||
|
||||
uint8_t bs_power;
|
||||
/* according to 3GPP TS 48.058 § MS Timing Offset [-63; 192] */
|
||||
int16_t ms_timing_offset;
|
||||
uint8_t ms_timing_offset;
|
||||
struct {
|
||||
int8_t pwr; /* MS power in dBm */
|
||||
uint8_t ta; /* MS timing advance */
|
||||
|
@@ -30,9 +30,6 @@
|
||||
#include "debug.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define RTP_PORT_DEFAULT 4000
|
||||
#define RTP_PORT_NET_DEFAULT 16000
|
||||
@@ -117,9 +114,6 @@ typedef void (*mgcp_get_format)(struct mgcp_endpoint *endp,
|
||||
struct mgcp_port_range {
|
||||
int mode;
|
||||
|
||||
/* addr or NULL to fall-back to default */
|
||||
char *bind_addr;
|
||||
|
||||
/* pre-allocated from a base? */
|
||||
int base_port;
|
||||
|
||||
@@ -220,8 +214,6 @@ struct mgcp_config {
|
||||
|
||||
/* osmux translator: 0 means disabled, 1 means enabled */
|
||||
int osmux;
|
||||
/* addr to bind the server to */
|
||||
char *osmux_addr;
|
||||
/* The BSC-NAT may ask for enabling osmux on demand. This tells us if
|
||||
* the osmux socket is already initialized.
|
||||
*/
|
||||
@@ -232,10 +224,6 @@ struct mgcp_config {
|
||||
int osmux_batch_size;
|
||||
/* osmux port */
|
||||
uint16_t osmux_port;
|
||||
/* Pad circuit with dummy messages until we see the first voice
|
||||
* message.
|
||||
*/
|
||||
uint16_t osmux_dummy;
|
||||
};
|
||||
|
||||
/* config management */
|
||||
|
@@ -22,8 +22,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <osmocom/core/select.h>
|
||||
|
||||
#define CI_UNUSED 0
|
||||
@@ -192,8 +190,6 @@ struct mgcp_endpoint {
|
||||
/* Osmux state: disabled, activating, active */
|
||||
enum osmux_state state;
|
||||
/* Allocated Osmux circuit ID for this endpoint */
|
||||
int allocated_cid;
|
||||
/* Used Osmux circuit ID for this endpoint */
|
||||
uint8_t cid;
|
||||
/* handle to batch messages */
|
||||
struct osmux_in_handle *in;
|
||||
@@ -207,51 +203,11 @@ struct mgcp_endpoint {
|
||||
} osmux;
|
||||
};
|
||||
|
||||
#define for_each_line(line, save) \
|
||||
for (line = strline_r(NULL, &save); line;\
|
||||
line = strline_r(NULL, &save))
|
||||
|
||||
static inline char *strline_r(char *str, char **saveptr)
|
||||
{
|
||||
char *result;
|
||||
|
||||
if (str)
|
||||
*saveptr = str;
|
||||
|
||||
result = *saveptr;
|
||||
|
||||
if (*saveptr != NULL) {
|
||||
*saveptr = strpbrk(*saveptr, "\r\n");
|
||||
|
||||
if (*saveptr != NULL) {
|
||||
char *eos = *saveptr;
|
||||
|
||||
if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n')
|
||||
(*saveptr)++;
|
||||
(*saveptr)++;
|
||||
if ((*saveptr)[0] == '\0')
|
||||
*saveptr = NULL;
|
||||
|
||||
*eos = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define ENDPOINT_NUMBER(endp) abs((int)(endp - endp->tcfg->endpoints))
|
||||
|
||||
/**
|
||||
* Internal structure while parsing a request
|
||||
*/
|
||||
struct mgcp_parse_data {
|
||||
struct mgcp_config *cfg;
|
||||
struct mgcp_endpoint *endp;
|
||||
char *trans;
|
||||
char *save;
|
||||
int found;
|
||||
struct mgcp_msg_ptr {
|
||||
unsigned int start;
|
||||
unsigned int length;
|
||||
};
|
||||
|
||||
int mgcp_send_dummy(struct mgcp_endpoint *endp);
|
||||
@@ -304,39 +260,5 @@ enum {
|
||||
MGCP_DEST_BTS,
|
||||
};
|
||||
|
||||
|
||||
#define MGCP_DUMMY_LOAD 0x23
|
||||
|
||||
|
||||
/**
|
||||
* SDP related information
|
||||
*/
|
||||
/* Assume audio frame length of 20ms */
|
||||
#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
|
||||
#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
|
||||
#define DEFAULT_RTP_AUDIO_PACKET_DURATION_MS 20
|
||||
#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000
|
||||
#define DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS 1
|
||||
|
||||
#define PTYPE_UNDEFINED (-1)
|
||||
int mgcp_parse_sdp_data(struct mgcp_endpoint *endp, struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p);
|
||||
int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
|
||||
int payload_type, const char *audio_name);
|
||||
|
||||
|
||||
/**
|
||||
* Internal network related
|
||||
*/
|
||||
static inline const char *mgcp_net_src_addr(struct mgcp_endpoint *endp)
|
||||
{
|
||||
if (endp->cfg->net_ports.bind_addr)
|
||||
return endp->cfg->net_ports.bind_addr;
|
||||
return endp->cfg->source_addr;
|
||||
}
|
||||
|
||||
static inline const char *mgcp_bts_src_addr(struct mgcp_endpoint *endp)
|
||||
{
|
||||
if (endp->cfg->bts_ports.bind_addr)
|
||||
return endp->cfg->bts_ports.bind_addr;
|
||||
return endp->cfg->source_addr;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user