mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 13:03:33 +00:00
Compare commits
297 Commits
openbsc/0.
...
openbsc/0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b744836e1 | ||
|
|
ee927fcab7 | ||
|
|
d4c0114884 | ||
|
|
8697e43bb2 | ||
|
|
ed5cacb240 | ||
|
|
7abecfcfc9 | ||
|
|
c45a8045a6 | ||
|
|
7fad70c198 | ||
|
|
013ae46ef6 | ||
|
|
fc462dd59e | ||
|
|
6fc6a12c07 | ||
|
|
7ddc318687 | ||
|
|
513da17732 | ||
|
|
563d99d3c3 | ||
|
|
46f799b224 | ||
|
|
e8bd9e885d | ||
|
|
5da9b52d06 | ||
|
|
c21aa18e35 | ||
|
|
0000ca5885 | ||
|
|
986926ebde | ||
|
|
4da5592c46 | ||
|
|
28d9ccbca0 | ||
|
|
f7dc7614c2 | ||
|
|
2962c20f73 | ||
|
|
cd98656315 | ||
|
|
1045697c34 | ||
|
|
44d26113bc | ||
|
|
3c3003f703 | ||
|
|
c8755af8a5 | ||
|
|
9d2f377927 | ||
|
|
cde579473b | ||
|
|
bda367c697 | ||
|
|
1664602476 | ||
|
|
e5215b5398 | ||
|
|
6e4c26aa08 | ||
|
|
52a0b12fe1 | ||
|
|
0b69bc34d7 | ||
|
|
cdf76cff9f | ||
|
|
901d57db07 | ||
|
|
f31dd86059 | ||
|
|
402ccedcf4 | ||
|
|
eabb6e3e4f | ||
|
|
1f447fbef1 | ||
|
|
4b2ed35b8f | ||
|
|
074b2b24e0 | ||
|
|
07b7bd79d6 | ||
|
|
b226864db5 | ||
|
|
d455ebe5ff | ||
|
|
8d9876e1ba | ||
|
|
3118191f59 | ||
|
|
fa2218cbc9 | ||
|
|
6d718c054a | ||
|
|
44fb151c12 | ||
|
|
1c33d4c00d | ||
|
|
fc83a36cbd | ||
|
|
31f5f71647 | ||
|
|
0e412c7a55 | ||
|
|
74db7744ee | ||
|
|
9b9a171da9 | ||
|
|
5e3bbba962 | ||
|
|
fe1ca353bb | ||
|
|
95fd72b9f7 | ||
|
|
d010eb4651 | ||
|
|
74902c5435 | ||
|
|
baf7700429 | ||
|
|
f6b606f422 | ||
|
|
cd367b959e | ||
|
|
d4ab13b630 | ||
|
|
36ac775838 | ||
|
|
5b3c05d89a | ||
|
|
258c713343 | ||
|
|
d1476bc603 | ||
|
|
2c5f4c635a | ||
|
|
46324ccfcd | ||
|
|
142c4b8ca8 | ||
|
|
7017fa7c9d | ||
|
|
f071e16f23 | ||
|
|
6552047d44 | ||
|
|
f8e49dd187 | ||
|
|
1b5e5c3727 | ||
|
|
f505f5dff1 | ||
|
|
07252918ea | ||
|
|
a86bc39cc9 | ||
|
|
fc5391f54e | ||
|
|
bc07090af2 | ||
|
|
f7d557cdf2 | ||
|
|
e8aef2a84b | ||
|
|
2c192639b5 | ||
|
|
e46792971b | ||
|
|
4462f8c30f | ||
|
|
203d865317 | ||
|
|
4bcc1c37b8 | ||
|
|
7d33bdf962 | ||
|
|
75413c4928 | ||
|
|
376f782e28 | ||
|
|
cccd301499 | ||
|
|
9f32a8a3c1 | ||
|
|
a0d9db99cb | ||
|
|
3d331c0062 | ||
|
|
f5bbb1eb71 | ||
|
|
784ca9c179 | ||
|
|
b7849987e5 | ||
|
|
c7921c9205 | ||
|
|
e86b3ebf2e | ||
|
|
23cf666359 | ||
|
|
e31816c83b | ||
|
|
c90499bb28 | ||
|
|
1cf43ece12 | ||
|
|
bc82f92a8d | ||
|
|
457a081379 | ||
|
|
2c1ae479ab | ||
|
|
1a07e21eaf | ||
|
|
f6093a4d0e | ||
|
|
8b65ab9d91 | ||
|
|
d134cc7d9d | ||
|
|
df680288a9 | ||
|
|
850dc6bbfa | ||
|
|
32bc11698a | ||
|
|
978714d752 | ||
|
|
28307643d7 | ||
|
|
5ac0179f47 | ||
|
|
3300c01e82 | ||
|
|
472e7e937c | ||
|
|
135a648ad7 | ||
|
|
d64c0bca17 | ||
|
|
6be350c045 | ||
|
|
b96be39d47 | ||
|
|
bb6034e2d8 | ||
|
|
9bdf5a9ef7 | ||
|
|
e36b487958 | ||
|
|
acc4031cf5 | ||
|
|
9c20571280 | ||
|
|
2e2ff34021 | ||
|
|
df8e6e9e4a | ||
|
|
ad75eababc | ||
|
|
384ef09920 | ||
|
|
1d54c40dd6 | ||
|
|
20102b0c82 | ||
|
|
f2c1f25612 | ||
|
|
4e318f5938 | ||
|
|
4e4fa4ce9b | ||
|
|
792edebb4f | ||
|
|
9e26773167 | ||
|
|
2b245c4f2b | ||
|
|
db1bd6998b | ||
|
|
80cffaf323 | ||
|
|
f142c97907 | ||
|
|
cdc59ff5cc | ||
|
|
867d9f3985 | ||
|
|
15c6172a8d | ||
|
|
a85515bea5 | ||
|
|
0d2881ad58 | ||
|
|
c68f754b3b | ||
|
|
6e52b88a17 | ||
|
|
d2a7878b35 | ||
|
|
1e9ae4be66 | ||
|
|
c0370e4399 | ||
|
|
d3080be131 | ||
|
|
67cd75f9fa | ||
|
|
99beb96fc0 | ||
|
|
ebf8b0a291 | ||
|
|
0e1620ff4a | ||
|
|
5d41b90e60 | ||
|
|
52defe9506 | ||
|
|
eb113137c8 | ||
|
|
88b6a1fa80 | ||
|
|
66f27ed0cb | ||
|
|
9cbdf1138f | ||
|
|
ef466d4f06 | ||
|
|
ab46cf38d4 | ||
|
|
c0d17f2266 | ||
|
|
dfb342c19a | ||
|
|
e1273b1f3c | ||
|
|
bbc5b99a6b | ||
|
|
4db9299286 | ||
|
|
bf540cb7c3 | ||
|
|
286ba0e68f | ||
|
|
0dc36f1e3a | ||
|
|
ef1e587008 | ||
|
|
6860c44071 | ||
|
|
474698abef | ||
|
|
1ffe98c175 | ||
|
|
66e14cdda6 | ||
|
|
5a081bbb1d | ||
|
|
e188010512 | ||
|
|
2a9eeaa588 | ||
|
|
a78b6026c9 | ||
|
|
163f612326 | ||
|
|
de2b860dff | ||
|
|
c3f28320c2 | ||
|
|
5deb6c3c5f | ||
|
|
0b03f16cdb | ||
|
|
71dd06cfcb | ||
|
|
123bc32834 | ||
|
|
91b9a45be4 | ||
|
|
e5d324981d | ||
|
|
a64037cd4a | ||
|
|
80352e03ca | ||
|
|
d447e99587 | ||
|
|
0e7d071e47 | ||
|
|
a8a09df6a6 | ||
|
|
c42ad8b686 | ||
|
|
5cde92cb0e | ||
|
|
06009c8d5a | ||
|
|
fede54c821 | ||
|
|
7e737007d9 | ||
|
|
4c80a516f8 | ||
|
|
25ffe54118 | ||
|
|
23b1b808f1 | ||
|
|
91afbbc56a | ||
|
|
ca05d432d7 | ||
|
|
0d20b63574 | ||
|
|
81863cde82 | ||
|
|
090493863b | ||
|
|
18fe88933c | ||
|
|
0e8facca42 | ||
|
|
390ba3faa0 | ||
|
|
cfccedd74a | ||
|
|
0d93fb4127 | ||
|
|
ffcf66f30e | ||
|
|
b326100b12 | ||
|
|
5d7b65b407 | ||
|
|
755f7442dd | ||
|
|
9f1294d623 | ||
|
|
c281b4e85a | ||
|
|
625295b14f | ||
|
|
66add64b71 | ||
|
|
22f58a9a58 | ||
|
|
3ab864a860 | ||
|
|
55ef5fb7ef | ||
|
|
4b41746ce3 | ||
|
|
7d73642d0e | ||
|
|
ef38e85542 | ||
|
|
da2f769681 | ||
|
|
165fe56260 | ||
|
|
f22e348287 | ||
|
|
4c9557ef24 | ||
|
|
13673749ff | ||
|
|
a18b11602c | ||
|
|
9e7e55f164 | ||
|
|
6a7babd658 | ||
|
|
d000c27d3b | ||
|
|
06f4fc79a2 | ||
|
|
fcac2911cf | ||
|
|
6110a3f3fa | ||
|
|
3c409c249d | ||
|
|
928cb33eb4 | ||
|
|
7c6b8cbbed | ||
|
|
d36ff76f9d | ||
|
|
136f453dd2 | ||
|
|
3848770669 | ||
|
|
50e529d44e | ||
|
|
c76fb5dd10 | ||
|
|
739a566961 | ||
|
|
5d7ad47386 | ||
|
|
682587748f | ||
|
|
16b7f5c4ef | ||
|
|
40d1c3fef1 | ||
|
|
8b277ac381 | ||
|
|
1484d88d7a | ||
|
|
f38ca9aec7 | ||
|
|
d529db6e50 | ||
|
|
af9b810419 | ||
|
|
217c6b6ad2 | ||
|
|
e898ecc57b | ||
|
|
1edc2b4c85 | ||
|
|
ba9adbb951 | ||
|
|
4fcd3570cb | ||
|
|
75755c5d87 | ||
|
|
8aeac19dbd | ||
|
|
f6d6b21ec2 | ||
|
|
aff63bc089 | ||
|
|
1164dce679 | ||
|
|
3ede723cb4 | ||
|
|
e6e8383a92 | ||
|
|
5748c20be1 | ||
|
|
d4571f41a3 | ||
|
|
53492c86e8 | ||
|
|
52af3aee5a | ||
|
|
bab983764e | ||
|
|
366d215dbd | ||
|
|
f9cf961a66 | ||
|
|
a0ce349f0c | ||
|
|
c08e8be4ee | ||
|
|
c1b2cfafd4 | ||
|
|
388cbbfc41 | ||
|
|
17a7634043 | ||
|
|
63467e8f28 | ||
|
|
26d7907b02 | ||
|
|
fd355a3c6f | ||
|
|
89579b4317 | ||
|
|
5a6b68f416 | ||
|
|
bd34be0a96 | ||
|
|
e5e36af8ae | ||
|
|
a17faf8512 | ||
|
|
31c00f7d6f | ||
|
|
9349d7ff7c |
26
openbsc/.gitignore
vendored
26
openbsc/.gitignore
vendored
@@ -6,10 +6,9 @@ Makefile.in
|
||||
bscconfig.h
|
||||
bscconfig.h.in
|
||||
openbsc.pc
|
||||
bsc_hack
|
||||
bsc_msc_ip
|
||||
src/osmo-nitb/osmo-nitb
|
||||
bsc_mgcp
|
||||
src/bsc/osmo-bsc
|
||||
src/osmo-bsc/osmo-bsc
|
||||
*.*~
|
||||
*.sw?
|
||||
|
||||
@@ -31,21 +30,24 @@ stamp-h1
|
||||
|
||||
# apps and app data
|
||||
hlr.sqlite3
|
||||
bs11_config
|
||||
ipaccess-config
|
||||
ipaccess-find
|
||||
ipaccess-firmware
|
||||
ipaccess-proxy
|
||||
isdnsync
|
||||
bsc_nat
|
||||
osmo-sgsn
|
||||
osmo-gbproxy
|
||||
src/utils/bs11_config
|
||||
src/ipaccess/ipaccess-config
|
||||
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/osmo-bsc_nat/osmo-bsc_nat
|
||||
|
||||
#tests
|
||||
tests/bsc-nat/bsc_nat_test
|
||||
tests/channel/channel_test
|
||||
tests/db/db_test
|
||||
tests/debug/debug_test
|
||||
tests/gsm0408/gsm0408_test
|
||||
tests/mgcp/mgcp_test
|
||||
tests/sccp/sccp_test
|
||||
tests/sms/sms_test
|
||||
tests/timer/timer_test
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
|
||||
SUBDIRS = include src tests
|
||||
SUBDIRS = doc include src tests
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = openbsc.pc
|
||||
|
||||
BUILT_SOURCES = $(top_srcdir)/.version
|
||||
EXTRA_DIST = git-version-gen
|
||||
$(top_srcdir)/.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
dist-hook:
|
||||
|
||||
@@ -35,7 +35,7 @@ AM_CONDITIONAL(BUILD_NAT, test "x$osmo_ac_build_nat" = "xyes")
|
||||
|
||||
AC_ARG_ENABLE([osmo-bsc], [AS_HELP_STRING([--enable-osmo-bsc], [Build the Osmo BSC])],
|
||||
[
|
||||
PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.2)
|
||||
PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.6)
|
||||
osmo_ac_build_bsc="yes"
|
||||
],
|
||||
[
|
||||
@@ -43,12 +43,15 @@ AC_ARG_ENABLE([osmo-bsc], [AS_HELP_STRING([--enable-osmo-bsc], [Build the Osmo B
|
||||
])
|
||||
AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.27)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.1.28)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.2)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.0.2)
|
||||
|
||||
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))
|
||||
|
||||
|
||||
dnl Checks for typedefs, structures and compiler characteristics
|
||||
@@ -57,7 +60,7 @@ dnl Checks for typedefs, structures and compiler characteristics
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fvisibility=hidden "
|
||||
AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
|
||||
AC_COMPILE_IFELSE([char foo;],
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])],
|
||||
[ AC_MSG_RESULT([yes])
|
||||
SYMBOL_VISIBILITY="-fvisibility=hidden"],
|
||||
AC_MSG_RESULT([no]))
|
||||
@@ -87,10 +90,20 @@ AC_OUTPUT(
|
||||
include/openbsc/Makefile
|
||||
include/Makefile
|
||||
src/Makefile
|
||||
src/libtrau/Makefile
|
||||
src/libbsc/Makefile
|
||||
src/libctrl/Makefile
|
||||
src/libmsc/Makefile
|
||||
src/libmgcp/Makefile
|
||||
src/libcommon/Makefile
|
||||
src/osmo-nitb/Makefile
|
||||
src/osmo-bsc/Makefile
|
||||
src/osmo-bsc_nat/Makefile
|
||||
src/osmo-bsc_mgcp/Makefile
|
||||
src/ipaccess/Makefile
|
||||
src/utils/Makefile
|
||||
src/libgb/Makefile
|
||||
src/gprs/Makefile
|
||||
src/nat/Makefile
|
||||
src/bsc/Makefile
|
||||
tests/Makefile
|
||||
tests/debug/Makefile
|
||||
tests/gsm0408/Makefile
|
||||
@@ -98,4 +111,6 @@ AC_OUTPUT(
|
||||
tests/channel/Makefile
|
||||
tests/bsc-nat/Makefile
|
||||
tests/mgcp/Makefile
|
||||
doc/Makefile
|
||||
doc/examples/Makefile
|
||||
Makefile)
|
||||
100
openbsc/contrib/bsc_control.py
Executable file
100
openbsc/contrib/bsc_control.py
Executable file
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys,os
|
||||
from optparse import OptionParser
|
||||
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)
|
||||
|
||||
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sck.setblocking(1)
|
||||
sck.connect((host, port))
|
||||
return sck
|
||||
|
||||
def send(sck, data):
|
||||
if verbose:
|
||||
print "Sending \"%s\"" %(data)
|
||||
data = prefix_ipa_ctrl_header(data)
|
||||
sck.send(data)
|
||||
|
||||
def do_set(var, value, id, sck):
|
||||
setmsg = "SET %s %s %s" %(options.id, var, value)
|
||||
send(sck, setmsg)
|
||||
|
||||
def do_get(var, id, sck):
|
||||
getmsg = "GET %s %s" %(options.id, var)
|
||||
send(sck, getmsg)
|
||||
|
||||
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)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
verbose = options.verbose
|
||||
|
||||
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.host):
|
||||
parser.error("Destination host and port required!")
|
||||
|
||||
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_get:
|
||||
if len(args) != 1:
|
||||
parser.error("Get requires the var argument")
|
||||
do_get(args[0], options.id, sock)
|
||||
|
||||
data = sock.recv(1024)
|
||||
while (len(data)>0):
|
||||
(answer, data) = remove_ipa_ctrl_header(data)
|
||||
print "Got message:", answer
|
||||
|
||||
if options.monitor:
|
||||
while (True):
|
||||
data = sock.recv(1024)
|
||||
while (len(data)>0):
|
||||
(answer, data) = remove_ipa_ctrl_header(data)
|
||||
print "Got message:", answer
|
||||
|
||||
sock.close()
|
||||
80
openbsc/contrib/gprs/gprs-buffer-count.lua
Normal file
80
openbsc/contrib/gprs/gprs-buffer-count.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
-- I count the buffer space needed for LLC PDUs in the worse case and print it
|
||||
|
||||
do
|
||||
local function init_listener()
|
||||
-- handle the port as NS over IP
|
||||
local udp_port_table = DissectorTable.get("udp.port")
|
||||
local gprs_ns_dis = Dissector.get("gprs_ns")
|
||||
udp_port_table:add(23000,gprs_ns_dis)
|
||||
|
||||
-- bssgp filters
|
||||
local bssgp_pdu_get = Field.new("bssgp.pdu_type")
|
||||
local bssgp_delay_get = Field.new("bssgp.delay_val")
|
||||
local llcgprs_get = Field.new("llcgprs")
|
||||
local pdus = nil
|
||||
|
||||
print("START...")
|
||||
|
||||
local tap = Listener.new("ip", "udp.port == 23000 && bssgp.pdu_type == 0")
|
||||
function tap.packet(pinfo,tvb,ip)
|
||||
local pdu = bssgp_pdu_get()
|
||||
local len = llcgprs_get().len
|
||||
local delay = bssgp_delay_get()
|
||||
|
||||
-- only handle bssgp, but we also want the IP frame
|
||||
if not pdu then
|
||||
return
|
||||
end
|
||||
|
||||
if tonumber(tostring(delay)) == 65535 then
|
||||
pdus = { next = pdus,
|
||||
len = len,
|
||||
expires = -1 }
|
||||
else
|
||||
local off = tonumber(tostring(delay)) / 100.0
|
||||
pdus = { next = pdus,
|
||||
len = len,
|
||||
expires = pinfo.rel_ts + off }
|
||||
end
|
||||
local now_time = tonumber(tostring(pinfo.rel_ts))
|
||||
local now_size = 0
|
||||
local l = pdus
|
||||
local prev = nil
|
||||
local count = 0
|
||||
while l do
|
||||
if now_time < l.expires or l.expires == -1 then
|
||||
now_size = now_size + l.len
|
||||
prev = l
|
||||
l = l.next
|
||||
count = count + 1
|
||||
else
|
||||
-- delete things
|
||||
if prev == nil then
|
||||
pdus = nil
|
||||
l = nil
|
||||
else
|
||||
prev.next = l.next
|
||||
l = l.next
|
||||
end
|
||||
end
|
||||
end
|
||||
-- print("TOTAL: " .. now_time .. " PDU_SIZE: " .. now_size)
|
||||
print(now_time .. " " .. now_size / 1024.0 .. " " .. count)
|
||||
-- print("NOW: " .. tostring(pinfo.rel_ts) .. " Delay: " .. tostring(delay) .. " Length: " .. tostring(len))
|
||||
end
|
||||
|
||||
function tap.draw()
|
||||
-- well... this will not be called...
|
||||
-- for ip,bssgp_histo in pairs(dumpers) do
|
||||
-- print("IP " .. ip)
|
||||
-- end
|
||||
print("END")
|
||||
end
|
||||
|
||||
function tap.reset()
|
||||
-- well... this will not be called...
|
||||
end
|
||||
end
|
||||
|
||||
init_listener()
|
||||
end
|
||||
30
openbsc/contrib/nat/test_regexp.c
Normal file
30
openbsc/contrib/nat/test_regexp.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/* make test_regexp */
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
regex_t reg;
|
||||
regmatch_t matches[2];
|
||||
|
||||
if (argc != 4) {
|
||||
printf("Invoke with: test_regexp REGEXP REPLACE NR\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (regcomp(®, argv[1], REG_EXTENDED) != 0) {
|
||||
fprintf(stderr, "Regexp '%s' is not valid.\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (regexec(®, argv[3], 2, matches, 0) == 0 && matches[1].rm_eo != -1)
|
||||
printf("New Number: %s%s\n", argv[2], &argv[3][matches[1].rm_so]);
|
||||
else
|
||||
printf("No match.\n");
|
||||
|
||||
regfree(®);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,3 +1,9 @@
|
||||
openbsc (0.9.13.115.eb113-1) natty; urgency=low
|
||||
|
||||
* New upstream release
|
||||
|
||||
-- Harald Welte <laforge@gnumonks.org> Wed, 11 May 2011 18:41:24 +0000
|
||||
|
||||
openbsc (0.9.4-1) unstable; urgency=low
|
||||
|
||||
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
|
||||
|
||||
@@ -1 +1 @@
|
||||
/usr/bin/bsc_nat
|
||||
/usr/bin/osmo-bsc_nat
|
||||
|
||||
1
openbsc/debian/osmocom-bsc.examples
Normal file
1
openbsc/debian/osmocom-bsc.examples
Normal file
@@ -0,0 +1 @@
|
||||
doc/examples/osmo-bsc_mgcp
|
||||
@@ -1,6 +1 @@
|
||||
src/openbsc.cfg.1-1
|
||||
src/openbsc.cfg.1-2
|
||||
src/openbsc.cfg.1-2-hopping
|
||||
src/openbsc.cfg.gprs
|
||||
src/openbsc.cfg.nanobts
|
||||
src/openbsc.cfg.nanobts.multitrx
|
||||
doc/examples/osmo-nitb
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC=osmo-nitb # Introduce a short description here
|
||||
NAME=osmo-nitb # Introduce the short server's name here
|
||||
DAEMON=/usr/sbin/bsc_hack # Introduce the server's location here
|
||||
DAEMON_ARGS="-D" # Arguments to run the daemon with
|
||||
DAEMON=/usr/sbin/osmo-nitb # Introduce the server's location here
|
||||
DAEMON_ARGS="-D" # Arguments to run the daemon with
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
/usr/bin/bsc_hack
|
||||
/usr/bin/osmo-nitb
|
||||
|
||||
1
openbsc/doc/Makefile.am
Normal file
1
openbsc/doc/Makefile.am
Normal file
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -52,10 +52,10 @@ int abis_link_event(int event, void *data);
|
||||
signal some event (such as layer 1 connect/disconnect) from the
|
||||
input core to the stack.
|
||||
|
||||
int subch_demux_in(mx, const u_int8_t *data, int len);
|
||||
int subch_demux_in(mx, const uint8_t *data, int len);
|
||||
receive 'len' bytes from a given E1 timeslot (TRAU frames)
|
||||
|
||||
int subchan_mux_out(mx, u_int8_t *data, int len);
|
||||
int subchan_mux_out(mx, uint8_t *data, int len);
|
||||
obtain 'len' bytes of output data to be sent on E1 timeslot
|
||||
|
||||
Intrface by Input Core for Input Plugins
|
||||
@@ -112,8 +112,8 @@ struct e1inp_sign_link {
|
||||
struct llist_head tx_list;
|
||||
|
||||
/* SAPI and TEI on the E1 TS */
|
||||
u_int8_t sapi;
|
||||
u_int8_t tei;
|
||||
uint8_t sapi;
|
||||
uint8_t tei;
|
||||
}
|
||||
|
||||
enum e1inp_ts_type {
|
||||
@@ -140,7 +140,7 @@ struct e1inp_ts {
|
||||
union {
|
||||
struct {
|
||||
/* mISDN driver has one fd for each ts */
|
||||
struct bsc_fd;
|
||||
struct osmo_fd;
|
||||
} misdn;
|
||||
} driver;
|
||||
};
|
||||
@@ -160,7 +160,7 @@ int e1inp_update_ts(struct e1inp_ts *ts);
|
||||
|
||||
/* Receive a packet from the E1 driver */
|
||||
int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
|
||||
u_int8_t tei, u_int8_t sapi);
|
||||
uint8_t tei, uint8_t sapi);
|
||||
|
||||
/* Send a packet, callback function in the driver */
|
||||
int e1driver_tx_ts(struct e1inp_ts *ts, struct msgb *msg)
|
||||
|
||||
23
openbsc/doc/examples/Makefile.am
Normal file
23
openbsc/doc/examples/Makefile.am
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,'
|
||||
|
||||
dist-hook:
|
||||
for f in $$($(CFG_FILES)); do \
|
||||
j="$(distdir)/$$f" && \
|
||||
mkdir -p "$$(dirname $$j)" && \
|
||||
$(INSTALL_DATA) $(srcdir)/$$f $$j; \
|
||||
done
|
||||
|
||||
install-data-hook:
|
||||
for f in $$($(CFG_FILES)); do \
|
||||
j="$(DESTDIR)$(docdir)/examples/$$f" && \
|
||||
mkdir -p "$$(dirname $$j)" && \
|
||||
$(INSTALL_DATA) $(srcdir)/$$f $$j; \
|
||||
done
|
||||
|
||||
uninstall-hook:
|
||||
@$(PRE_UNINSTALL)
|
||||
for f in $$($(CFG_FILES)); do \
|
||||
j="$(DESTDIR)$(docdir)/examples/$$f" && \
|
||||
$(RM) $$j; \
|
||||
done
|
||||
133
openbsc/doc/examples/osmo-bsc/osmo-bsc.cfg
Normal file
133
openbsc/doc/examples/osmo-bsc/osmo-bsc.cfg
Normal file
@@ -0,0 +1,133 @@
|
||||
!
|
||||
! OsmoBSC (0.9.14+gitr1+3d331c0062bb0c9694dbd4d1eab7adc58138c3ae) configuration saved from vty
|
||||
!!
|
||||
password foo
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging timestamp 0
|
||||
logging level all everything
|
||||
logging level rll notice
|
||||
logging level cc notice
|
||||
logging level mm notice
|
||||
logging level rr notice
|
||||
logging level rsl notice
|
||||
logging level nm info
|
||||
logging level mncc notice
|
||||
logging level sms notice
|
||||
logging level pag notice
|
||||
logging level meas notice
|
||||
logging level mi notice
|
||||
logging level mib notice
|
||||
logging level mux notice
|
||||
logging level inp notice
|
||||
logging level sccp notice
|
||||
logging level msc notice
|
||||
logging level mgcp notice
|
||||
logging level ho notice
|
||||
logging level db notice
|
||||
logging level ref notice
|
||||
logging level gprs debug
|
||||
logging level ns info
|
||||
logging level bssgp debug
|
||||
logging level llc debug
|
||||
logging level sndcp debug
|
||||
logging level nat notice
|
||||
logging level lglobal notice
|
||||
logging level llapdm notice
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
e1_input
|
||||
e1_line 0 driver ipa
|
||||
network
|
||||
network country code 1
|
||||
mobile network code 1
|
||||
short name OsmoBSC
|
||||
long name OsmoBSC
|
||||
auth policy closed
|
||||
location updating reject cause 13
|
||||
encryption a5 0
|
||||
neci 1
|
||||
paging any use tch 0
|
||||
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 0
|
||||
timer t3111 0
|
||||
timer t3113 60
|
||||
timer t3115 0
|
||||
timer t3117 0
|
||||
timer t3119 0
|
||||
timer t3122 0
|
||||
timer t3141 0
|
||||
dtx-used 0
|
||||
subscriber-keep-in-ram 0
|
||||
bts 0
|
||||
type nanobts
|
||||
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 0 0
|
||||
oml ip.access stream_id 255 line 0
|
||||
neighbor-list mode manual-si5
|
||||
neighbor-list add arfcn 100
|
||||
neighbor-list add arfcn 200
|
||||
si5 neighbor-list add arfcn 10
|
||||
si5 neighbor-list add arfcn 20
|
||||
gprs mode none
|
||||
trx 0
|
||||
rf_locked 0
|
||||
arfcn 871
|
||||
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
|
||||
msc
|
||||
ip.access rtp-base 4000
|
||||
timeout-ping 20
|
||||
timeout-pong 5
|
||||
mid-call-timeout 0
|
||||
dest 192.168.100.11 6666 0
|
||||
90
openbsc/doc/examples/osmo-nitb/hsl/openbsc.cfg
Normal file
90
openbsc/doc/examples/osmo-nitb/hsl/openbsc.cfg
Normal file
@@ -0,0 +1,90 @@
|
||||
!
|
||||
! OpenBSC (0.9.11.261-32c0) configuration saved from vty
|
||||
!!
|
||||
password foo
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
e1_input
|
||||
e1_line 0 driver hsl
|
||||
network
|
||||
network country code 262
|
||||
mobile network code 42
|
||||
short name OpenBSC
|
||||
long name OpenBSC
|
||||
auth policy closed
|
||||
location updating reject cause 13
|
||||
encryption a5 0
|
||||
neci 1
|
||||
paging any use tch 0
|
||||
rrlp mode none
|
||||
mm info 0
|
||||
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 0
|
||||
timer t3111 0
|
||||
timer t3113 60
|
||||
timer t3115 0
|
||||
timer t3117 0
|
||||
timer t3119 0
|
||||
timer t3122 0
|
||||
timer t3141 0
|
||||
dtx-used 1
|
||||
subscriber-keep-in-ram 0
|
||||
bts 0
|
||||
type hsl_femto
|
||||
band DCS1800
|
||||
cell_identity 0
|
||||
location_area_code 1
|
||||
training_sequence_code 0
|
||||
base_station_id_code 0
|
||||
ms max power 15
|
||||
cell reselection hysteresis 4
|
||||
rxlev access min 0
|
||||
channel allocator ascending
|
||||
rach tx integer 9
|
||||
rach max transmission 1
|
||||
hsl serial-number 8303701
|
||||
neighbor-list mode automatic
|
||||
oml hsl line 0
|
||||
gprs mode none
|
||||
trx 0
|
||||
rf_locked 0
|
||||
arfcn 871
|
||||
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
|
||||
@@ -6,6 +6,8 @@ password foo
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
e1_input
|
||||
e1_line 0 driver ipa
|
||||
network
|
||||
network country code 1
|
||||
mobile network code 1
|
||||
@@ -49,7 +51,7 @@ network
|
||||
rach tx integer 9
|
||||
rach max transmission 7
|
||||
ip.access unit_id 1800 0
|
||||
oml ip.access stream_id 255
|
||||
oml ip.access stream_id 255 line 0
|
||||
gprs mode none
|
||||
trx 0
|
||||
rf_locked 0
|
||||
@@ -6,6 +6,8 @@ password foo
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
e1_input
|
||||
e1_line 0 driver ipa
|
||||
network
|
||||
network country code 1
|
||||
mobile network code 1
|
||||
@@ -49,7 +51,7 @@ network
|
||||
rach tx integer 9
|
||||
rach max transmission 7
|
||||
ip.access unit_id 1801 0
|
||||
oml ip.access stream_id 255
|
||||
oml ip.access stream_id 255 line 0
|
||||
gprs mode none
|
||||
trx 0
|
||||
rf_locked 0
|
||||
118
openbsc/doc/examples/osmo-nitb/nokia/openbsc_nokia_3trx.cfg
Normal file
118
openbsc/doc/examples/osmo-nitb/nokia/openbsc_nokia_3trx.cfg
Normal file
@@ -0,0 +1,118 @@
|
||||
!
|
||||
! OpenBSC configuration saved from vty
|
||||
! !
|
||||
password foo
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
e1_input
|
||||
e1_line 0 driver misdn
|
||||
network
|
||||
network country code 1
|
||||
mobile network code 1
|
||||
short name OpenBSC
|
||||
long name OpenBSC
|
||||
auth policy accept-all
|
||||
timer t3101 10
|
||||
timer t3113 60
|
||||
bts 0
|
||||
type nokia_site
|
||||
band GSM1800
|
||||
cell_identity 1
|
||||
location_area_code 1
|
||||
base_station_id_code 63
|
||||
training_sequence_code 7
|
||||
|
||||
oml e1 line 0 timeslot 1 sub-slot full
|
||||
oml e1 tei 1
|
||||
|
||||
trx 0
|
||||
arfcn 866
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
@@ -12,7 +12,7 @@ specific parameters from channel assignment:
|
||||
|
||||
hopping sequence generation (6.2.3):
|
||||
|
||||
u_int8_t rntable[114] = {
|
||||
uint8_t rntable[114] = {
|
||||
48, 98, 63, 1, 36, 95, 78, 102, 94, 73,
|
||||
0, 64, 25, 81, 76, 59, 124, 23, 104, 100,
|
||||
101, 47, 118, 85, 18, 56, 96, 86, 54, 2,
|
||||
@@ -29,15 +29,15 @@ u_int8_t rntable[114] = {
|
||||
/* mai=0 represents lowest ARFCN in the MA */
|
||||
|
||||
|
||||
u_int8_t hopping_mai(u_int8_t hsn, u_int32_t fn, u_int8_t maio,
|
||||
u_int8_t t1, u_int8_t t2, u_int8_t t3_)
|
||||
uint8_t hopping_mai(uint8_t hsn, uint32_t fn, uint8_t maio,
|
||||
uint8_t t1, uint8_t t2, uint8_t t3_)
|
||||
{
|
||||
u_int8_t mai;
|
||||
uint8_t mai;
|
||||
|
||||
if (hsn == 0) /* cyclic hopping */
|
||||
mai = (fn + maio) % n;
|
||||
else {
|
||||
u_int32_t m, m_, t_, s;
|
||||
uint32_t m, m_, t_, s;
|
||||
|
||||
m = t2 + rntable[(hsn xor (t1 % 64)) + t3];
|
||||
m_ = m % (2^NBIN);
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
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 \
|
||||
subchan_demux.h trau_frame.h e1_input.h trau_mux.h \
|
||||
ipaccess.h rs232.h openbscdefines.h rtp_proxy.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 \
|
||||
@@ -11,7 +10,8 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
|
||||
gb_proxy.h gprs_sgsn.h gsm_04_08_gprs.h sgsn.h \
|
||||
gprs_ns_frgre.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
|
||||
osmo_msc_data.h osmo_bsc_grace.h sms_queue.h abis_om2000.h \
|
||||
bss.h gsm_data_shared.h control_cmd.h ipaccess.h
|
||||
|
||||
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
|
||||
openbscdir = $(includedir)/openbsc
|
||||
|
||||
@@ -22,15 +22,15 @@
|
||||
#ifndef _NM_H
|
||||
#define _NM_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/protocol/gsm_12_21.h>
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
#include <osmocom/gsm/abis_nm.h>
|
||||
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||
|
||||
struct cell_global_id {
|
||||
u_int16_t mcc;
|
||||
u_int16_t mnc;
|
||||
u_int16_t lac;
|
||||
u_int16_t ci;
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
uint16_t lac;
|
||||
uint16_t ci;
|
||||
};
|
||||
|
||||
/* The BCCH info from an ip.access test, in host byte order
|
||||
@@ -38,26 +38,22 @@ struct cell_global_id {
|
||||
struct ipac_bcch_info {
|
||||
struct llist_head list;
|
||||
|
||||
u_int16_t info_type;
|
||||
u_int8_t freq_qual;
|
||||
u_int16_t arfcn;
|
||||
u_int8_t rx_lev;
|
||||
u_int8_t rx_qual;
|
||||
uint16_t info_type;
|
||||
uint8_t freq_qual;
|
||||
uint16_t arfcn;
|
||||
uint8_t rx_lev;
|
||||
uint8_t rx_qual;
|
||||
int16_t freq_err;
|
||||
u_int16_t frame_offset;
|
||||
u_int32_t frame_nr_offset;
|
||||
u_int8_t bsic;
|
||||
uint16_t frame_offset;
|
||||
uint32_t frame_nr_offset;
|
||||
uint8_t bsic;
|
||||
struct cell_global_id cgi;
|
||||
u_int8_t ba_list_si2[16];
|
||||
u_int8_t ba_list_si2bis[16];
|
||||
u_int8_t ba_list_si2ter[16];
|
||||
u_int8_t ca_list_si1[16];
|
||||
uint8_t ba_list_si2[16];
|
||||
uint8_t ba_list_si2bis[16];
|
||||
uint8_t ba_list_si2ter[16];
|
||||
uint8_t ca_list_si1[16];
|
||||
};
|
||||
|
||||
extern const struct value_string abis_nm_adm_state_names[];
|
||||
extern const struct value_string abis_nm_obj_class_names[];
|
||||
extern const struct tlv_definition nm_att_tlvdef;
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
struct msgb;
|
||||
@@ -72,60 +68,58 @@ struct abis_nm_cfg {
|
||||
|
||||
extern int abis_nm_rcvmsg(struct msgb *msg);
|
||||
|
||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const u_int8_t *buf, int len);
|
||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const uint8_t *buf, int len);
|
||||
int abis_nm_rx(struct msgb *msg);
|
||||
int abis_nm_opstart(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1, u_int8_t i2);
|
||||
int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0,
|
||||
u_int8_t i1, u_int8_t i2, enum abis_nm_adm_state adm_state);
|
||||
int abis_nm_establish_tei(struct gsm_bts *bts, u_int8_t trx_nr,
|
||||
u_int8_t e1_port, u_int8_t e1_timeslot, u_int8_t e1_subslot,
|
||||
u_int8_t tei);
|
||||
int abis_nm_opstart(struct gsm_bts *bts, uint8_t obj_class, uint8_t i0, uint8_t i1, uint8_t i2);
|
||||
int abis_nm_chg_adm_state(struct gsm_bts *bts, uint8_t obj_class, uint8_t i0,
|
||||
uint8_t i1, uint8_t i2, enum abis_nm_adm_state adm_state);
|
||||
int abis_nm_establish_tei(struct gsm_bts *bts, uint8_t trx_nr,
|
||||
uint8_t e1_port, uint8_t e1_timeslot, uint8_t e1_subslot,
|
||||
uint8_t tei);
|
||||
int abis_nm_conn_terr_sign(struct gsm_bts_trx *trx,
|
||||
u_int8_t e1_port, u_int8_t e1_timeslot, u_int8_t e1_subslot);
|
||||
uint8_t e1_port, uint8_t e1_timeslot, uint8_t e1_subslot);
|
||||
int abis_nm_conn_terr_traf(struct gsm_bts_trx_ts *ts,
|
||||
u_int8_t e1_port, u_int8_t e1_timeslot,
|
||||
u_int8_t e1_subslot);
|
||||
int abis_nm_set_bts_attr(struct gsm_bts *bts, u_int8_t *attr, int attr_len);
|
||||
int abis_nm_set_radio_attr(struct gsm_bts_trx *trx, u_int8_t *attr, int attr_len);
|
||||
int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, u_int8_t chan_comb);
|
||||
int abis_nm_sw_act_req_ack(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i1,
|
||||
u_int8_t i2, u_int8_t i3, int nack, u_int8_t *attr, int att_len);
|
||||
int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *msg);
|
||||
uint8_t e1_port, uint8_t e1_timeslot,
|
||||
uint8_t e1_subslot);
|
||||
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);
|
||||
int abis_nm_sw_act_req_ack(struct gsm_bts *bts, uint8_t obj_class, uint8_t i1,
|
||||
uint8_t i2, uint8_t i3, int nack, uint8_t *attr, int att_len);
|
||||
int abis_nm_raw_msg(struct gsm_bts *bts, int len, uint8_t *msg);
|
||||
int abis_nm_event_reports(struct gsm_bts *bts, int on);
|
||||
int abis_nm_reset_resource(struct gsm_bts *bts);
|
||||
int abis_nm_software_load(struct gsm_bts *bts, int trx_nr, const char *fname,
|
||||
u_int8_t win_size, int forced,
|
||||
uint8_t win_size, int forced,
|
||||
gsm_cbfn *cbfn, void *cb_data);
|
||||
int abis_nm_software_load_status(struct gsm_bts *bts);
|
||||
int abis_nm_software_activate(struct gsm_bts *bts, const char *fname,
|
||||
gsm_cbfn *cbfn, void *cb_data);
|
||||
|
||||
int abis_nm_conn_mdrop_link(struct gsm_bts *bts, u_int8_t e1_port0, u_int8_t ts0,
|
||||
u_int8_t e1_port1, u_int8_t ts1);
|
||||
int abis_nm_conn_mdrop_link(struct gsm_bts *bts, uint8_t e1_port0, uint8_t ts0,
|
||||
uint8_t e1_port1, uint8_t ts1);
|
||||
|
||||
int abis_nm_perform_test(struct gsm_bts *bts, u_int8_t obj_class,
|
||||
u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
|
||||
u_int8_t test_nr, u_int8_t auton_report, struct msgb *msg);
|
||||
|
||||
int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan);
|
||||
int abis_nm_perform_test(struct gsm_bts *bts, uint8_t obj_class,
|
||||
uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
|
||||
uint8_t test_nr, uint8_t auton_report, struct msgb *msg);
|
||||
|
||||
/* Siemens / BS-11 specific */
|
||||
int abis_nm_bs11_reset_resource(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_db_transmission(struct gsm_bts *bts, int begin);
|
||||
int abis_nm_bs11_create_object(struct gsm_bts *bts, enum abis_bs11_objtype type,
|
||||
u_int8_t idx, u_int8_t attr_len, const u_int8_t *attr);
|
||||
int abis_nm_bs11_create_envaBTSE(struct gsm_bts *bts, u_int8_t idx);
|
||||
int abis_nm_bs11_create_bport(struct gsm_bts *bts, u_int8_t idx);
|
||||
uint8_t idx, uint8_t attr_len, const uint8_t *attr);
|
||||
int abis_nm_bs11_create_envaBTSE(struct gsm_bts *bts, uint8_t idx);
|
||||
int abis_nm_bs11_create_bport(struct gsm_bts *bts, uint8_t idx);
|
||||
int abis_nm_bs11_delete_object(struct gsm_bts *bts,
|
||||
enum abis_bs11_objtype type, u_int8_t idx);
|
||||
int abis_nm_bs11_delete_bport(struct gsm_bts *bts, u_int8_t idx);
|
||||
int abis_nm_bs11_conn_oml_tei(struct gsm_bts *bts, u_int8_t e1_port,
|
||||
u_int8_t e1_timeslot, u_int8_t e1_subslot, u_int8_t tei);
|
||||
enum abis_bs11_objtype type, uint8_t idx);
|
||||
int abis_nm_bs11_delete_bport(struct gsm_bts *bts, uint8_t idx);
|
||||
int abis_nm_bs11_conn_oml_tei(struct gsm_bts *bts, uint8_t e1_port,
|
||||
uint8_t e1_timeslot, uint8_t e1_subslot, uint8_t tei);
|
||||
int abis_nm_bs11_get_oml_tei_ts(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_get_serno(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, u_int8_t level);
|
||||
int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, uint8_t level);
|
||||
int abis_nm_bs11_get_trx_power(struct gsm_bts_trx *trx);
|
||||
int abis_nm_bs11_logon(struct gsm_bts *bts, u_int8_t level, const char *name, int on);
|
||||
int abis_nm_bs11_logon(struct gsm_bts *bts, uint8_t level, const char *name, int on);
|
||||
int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on);
|
||||
int abis_nm_bs11_infield_logon(struct gsm_bts *bts, int on);
|
||||
int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password);
|
||||
@@ -135,38 +129,39 @@ int abis_nm_bs11_set_pll(struct gsm_bts *bts, int value);
|
||||
int abis_nm_bs11_get_cclk(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_get_state(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
|
||||
u_int8_t win_size, int forced, gsm_cbfn *cbfn);
|
||||
uint8_t win_size, int forced, gsm_cbfn *cbfn);
|
||||
int abis_nm_bs11_set_ext_time(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_get_bport_line_cfg(struct gsm_bts *bts, u_int8_t bport);
|
||||
int abis_nm_bs11_set_bport_line_cfg(struct gsm_bts *bts, u_int8_t bport, enum abis_bs11_line_cfg line_cfg);
|
||||
int abis_nm_bs11_get_bport_line_cfg(struct gsm_bts *bts, uint8_t bport);
|
||||
int abis_nm_bs11_set_bport_line_cfg(struct gsm_bts *bts, uint8_t bport, enum abis_bs11_line_cfg line_cfg);
|
||||
int abis_nm_bs11_bsc_disconnect(struct gsm_bts *bts, int reconnect);
|
||||
int abis_nm_bs11_restart(struct gsm_bts *bts);
|
||||
|
||||
/* ip.access nanoBTS specific commands */
|
||||
int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type,
|
||||
u_int8_t obj_class, u_int8_t bts_nr,
|
||||
u_int8_t trx_nr, u_int8_t ts_nr,
|
||||
u_int8_t *attr, int attr_len);
|
||||
int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, u_int8_t *attr,
|
||||
int abis_nm_ipaccess_msg(struct gsm_bts *bts, uint8_t msg_type,
|
||||
uint8_t obj_class, uint8_t bts_nr,
|
||||
uint8_t trx_nr, uint8_t ts_nr,
|
||||
uint8_t *attr, int attr_len);
|
||||
int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, uint8_t *attr,
|
||||
int attr_len);
|
||||
int abis_nm_ipaccess_restart(struct gsm_bts_trx *trx);
|
||||
int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
|
||||
u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
|
||||
u_int8_t *attr, u_int8_t attr_len);
|
||||
int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, uint8_t obj_class,
|
||||
uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
|
||||
uint8_t *attr, uint8_t attr_len);
|
||||
int abis_nm_ipaccess_rsl_connect(struct gsm_bts_trx *trx,
|
||||
u_int32_t ip, u_int16_t port, u_int8_t stream);
|
||||
void abis_nm_ipaccess_cgi(u_int8_t *buf, struct gsm_bts *bts);
|
||||
int ipac_parse_bcch_info(struct ipac_bcch_info *binf, u_int8_t *buf);
|
||||
const char *ipacc_testres_name(u_int8_t res);
|
||||
uint32_t ip, uint16_t port, uint8_t stream);
|
||||
void abis_nm_ipaccess_cgi(uint8_t *buf, struct gsm_bts *bts);
|
||||
int ipac_parse_bcch_info(struct ipac_bcch_info *binf, uint8_t *buf);
|
||||
const char *ipacc_testres_name(uint8_t res);
|
||||
|
||||
/* Functions calling into other code parts */
|
||||
const char *nm_opstate_name(u_int8_t os);
|
||||
const char *nm_avail_name(u_int8_t avail);
|
||||
int nm_is_running(struct gsm_nm_state *s);
|
||||
|
||||
int abis_nm_vty_init(void);
|
||||
|
||||
void abis_nm_clear_queue(struct gsm_bts *bts);
|
||||
|
||||
int _abis_nm_sendmsg(struct msgb *msg, int to_trx_oml);
|
||||
|
||||
void abis_nm_queue_send_next(struct gsm_bts *bts); /* for bs11_config. */
|
||||
|
||||
#endif /* _NM_H */
|
||||
|
||||
@@ -22,6 +22,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
enum abis_om2k_mo_cls {
|
||||
OM2K_MO_CLS_TRXC = 0x01,
|
||||
OM2K_MO_CLS_TS = 0x03,
|
||||
OM2K_MO_CLS_TF = 0x04,
|
||||
OM2K_MO_CLS_IS = 0x05,
|
||||
OM2K_MO_CLS_CON = 0x06,
|
||||
OM2K_MO_CLS_DP = 0x07,
|
||||
OM2K_MO_CLS_CF = 0x0a,
|
||||
OM2K_MO_CLS_TX = 0x0b,
|
||||
OM2K_MO_CLS_RX = 0x0c,
|
||||
};
|
||||
|
||||
enum om2k_mo_state {
|
||||
OM2K_MO_S_RESET = 0,
|
||||
OM2K_MO_S_STARTED,
|
||||
OM2K_MO_S_ENABLED,
|
||||
OM2K_MO_S_DISABLED,
|
||||
};
|
||||
|
||||
struct abis_om2k_mo {
|
||||
uint8_t class;
|
||||
uint8_t bts;
|
||||
@@ -29,12 +48,26 @@ struct abis_om2k_mo {
|
||||
uint8_t inst;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* on-wire format for IS conn group */
|
||||
struct om2k_is_conn_grp {
|
||||
uint16_t icp1;
|
||||
uint16_t icp2;
|
||||
uint8_t cont_idx;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* internal data formant for IS conn group */
|
||||
struct is_conn_group {
|
||||
struct llist_head list;
|
||||
uint16_t icp1;
|
||||
uint16_t icp2;
|
||||
uint8_t ci;
|
||||
};
|
||||
|
||||
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;
|
||||
extern const struct abis_om2k_mo om2k_mo_tf;
|
||||
|
||||
extern const struct value_string om2k_mo_class_short_vals[];
|
||||
|
||||
int abis_om2k_rcvmsg(struct msgb *msg);
|
||||
@@ -51,8 +84,11 @@ 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_is_conf_req(struct gsm_bts *bts, struct om2k_is_conn_grp *cg,
|
||||
unsigned int num_cg);
|
||||
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);
|
||||
|
||||
int abis_om2k_vty_init(void);
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#ifndef _RSL_H
|
||||
#define _RSL_H
|
||||
|
||||
#include <osmocore/protocol/gsm_08_58.h>
|
||||
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
|
||||
struct gsm_bts;
|
||||
struct gsm_lchan;
|
||||
@@ -32,61 +32,56 @@ struct gsm_subscriber;
|
||||
struct gsm_bts_trx_ts;
|
||||
|
||||
|
||||
int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
|
||||
const u_int8_t *data, int len);
|
||||
int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
|
||||
const u_int8_t *data, int len);
|
||||
int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
|
||||
u_int8_t act_type,
|
||||
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,
|
||||
uint8_t act_type,
|
||||
struct rsl_ie_chan_mode *chan_mode,
|
||||
struct rsl_ie_chan_ident *chan_ident,
|
||||
u_int8_t bs_power, u_int8_t ms_power,
|
||||
u_int8_t ta);
|
||||
int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
|
||||
u_int8_t ta, u_int8_t ho_ref);
|
||||
uint8_t bs_power, uint8_t ms_power,
|
||||
uint8_t ta);
|
||||
int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type,
|
||||
uint8_t ta, uint8_t ho_ref);
|
||||
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, u_int8_t paging_group, u_int8_t len,
|
||||
u_int8_t *ms_ident, u_int8_t chan_needed);
|
||||
int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val);
|
||||
int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group, uint8_t len,
|
||||
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, u_int8_t link_id);
|
||||
int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
int rsl_relase_request(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
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);
|
||||
|
||||
/* Siemens vendor-specific RSL extensions */
|
||||
int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
|
||||
|
||||
/* ip.access specfic RSL extensions */
|
||||
int rsl_ipacc_crcx(struct gsm_lchan *lchan);
|
||||
int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip,
|
||||
u_int16_t port, u_int8_t rtp_payload2);
|
||||
int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip,
|
||||
uint16_t port, uint8_t rtp_payload2);
|
||||
int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan);
|
||||
int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act);
|
||||
|
||||
int abis_rsl_rcvmsg(struct msgb *msg);
|
||||
|
||||
unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
|
||||
int n_pag_blocks);
|
||||
unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res);
|
||||
u_int64_t str_to_imsi(const char *imsi_str);
|
||||
u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
|
||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t reason);
|
||||
uint64_t str_to_imsi(const char *imsi_str);
|
||||
int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason);
|
||||
|
||||
int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
|
||||
|
||||
/* to be provided by external code */
|
||||
int abis_rsl_sendmsg(struct msgb *msg);
|
||||
int rsl_deact_sacch(struct gsm_lchan *lchan);
|
||||
int rsl_lchan_rll_release(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
int rsl_lchan_rll_release(struct gsm_lchan *lchan, uint8_t link_id);
|
||||
|
||||
/* BCCH related code */
|
||||
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
|
||||
int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf);
|
||||
int rsl_number_of_paging_subchannels(struct gsm_bts *bts);
|
||||
|
||||
int rsl_sacch_info_modify(struct gsm_lchan *lchan, u_int8_t type,
|
||||
const u_int8_t *data, int len);
|
||||
int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type,
|
||||
const uint8_t *data, int len);
|
||||
|
||||
int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db);
|
||||
int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm);
|
||||
@@ -95,5 +90,12 @@ int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm);
|
||||
int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
|
||||
uint8_t cb_command, const uint8_t *data, int len);
|
||||
|
||||
/* some Nokia specific stuff */
|
||||
int rsl_nokia_si_begin(struct gsm_bts_trx *trx);
|
||||
int rsl_nokia_si_end(struct gsm_bts_trx *trx);
|
||||
|
||||
/* required for Nokia BTS power control */
|
||||
int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction);
|
||||
|
||||
#endif /* RSL_MT_H */
|
||||
|
||||
|
||||
@@ -22,25 +22,33 @@
|
||||
#ifndef BSC_MSC_H
|
||||
#define BSC_MSC_H
|
||||
|
||||
#include <osmocore/write_queue.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
struct bsc_msc_dest {
|
||||
struct llist_head list;
|
||||
|
||||
char *ip;
|
||||
int port;
|
||||
int dscp;
|
||||
};
|
||||
|
||||
|
||||
struct bsc_msc_connection {
|
||||
struct write_queue write_queue;
|
||||
struct osmo_wqueue write_queue;
|
||||
int is_connected;
|
||||
int is_authenticated;
|
||||
int first_contact;
|
||||
const char *ip;
|
||||
int port;
|
||||
int prio;
|
||||
|
||||
struct llist_head *dests;
|
||||
|
||||
void (*connection_loss) (struct bsc_msc_connection *);
|
||||
void (*connected) (struct bsc_msc_connection *);
|
||||
struct timer_list reconnect_timer;
|
||||
struct timer_list timeout_timer;
|
||||
struct osmo_timer_list reconnect_timer;
|
||||
struct osmo_timer_list timeout_timer;
|
||||
};
|
||||
|
||||
struct bsc_msc_connection *bsc_msc_create(const char *ip, int port, int prio);
|
||||
struct bsc_msc_connection *bsc_msc_create(void *ctx, struct llist_head *dest);
|
||||
int bsc_msc_connect(struct bsc_msc_connection *);
|
||||
void bsc_msc_schedule_connect(struct bsc_msc_connection *);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by On-Waves
|
||||
* (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010-2011 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -23,22 +23,23 @@
|
||||
|
||||
#include "mgcp.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/msgfile.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocore/write_queue.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocore/statistics.h>
|
||||
#include <osmocore/protocol/gsm_04_08.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/msgfile.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/statistics.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
#define DIR_BSC 1
|
||||
#define DIR_MSC 2
|
||||
|
||||
#define PAGIN_GROUP_UNASSIGNED -1
|
||||
|
||||
struct sccp_source_reference;
|
||||
struct sccp_connections;
|
||||
struct bsc_nat_parsed;
|
||||
@@ -55,6 +56,34 @@ enum {
|
||||
NAT_CON_TYPE_OTHER,
|
||||
};
|
||||
|
||||
/*
|
||||
* Is this terminated to the MSC, to the local machine (release
|
||||
* handling for IMSI filtering) or to a USSD provider?
|
||||
*/
|
||||
enum {
|
||||
NAT_CON_END_MSC,
|
||||
NAT_CON_END_LOCAL,
|
||||
NAT_CON_END_USSD,
|
||||
};
|
||||
|
||||
/*
|
||||
* Pending command entry
|
||||
*/
|
||||
struct bsc_cmd_list {
|
||||
struct llist_head list_entry;
|
||||
|
||||
struct osmo_timer_list timeout;
|
||||
|
||||
/* The NATed ID used on the bsc_con*/
|
||||
int nat_id;
|
||||
|
||||
/* The control connection from which the command originated */
|
||||
struct ctrl_connection *ccon;
|
||||
|
||||
/* The command from the control connection */
|
||||
struct ctrl_cmd *cmd;
|
||||
};
|
||||
|
||||
/*
|
||||
* Per BSC data structure
|
||||
*/
|
||||
@@ -65,17 +94,17 @@ struct bsc_connection {
|
||||
int authenticated;
|
||||
|
||||
/* the fd we use to communicate */
|
||||
struct write_queue write_queue;
|
||||
struct osmo_wqueue write_queue;
|
||||
|
||||
/* the BSS associated */
|
||||
struct bsc_config *cfg;
|
||||
|
||||
/* a timeout node */
|
||||
struct timer_list id_timeout;
|
||||
struct osmo_timer_list id_timeout;
|
||||
|
||||
/* pong timeout */
|
||||
struct timer_list ping_timeout;
|
||||
struct timer_list pong_timeout;
|
||||
struct osmo_timer_list ping_timeout;
|
||||
struct osmo_timer_list pong_timeout;
|
||||
|
||||
/* mgcp related code */
|
||||
char *_endpoint_status;
|
||||
@@ -83,6 +112,10 @@ struct bsc_connection {
|
||||
int max_endpoints;
|
||||
int last_endpoint;
|
||||
|
||||
/* track the pending commands for this BSC */
|
||||
struct llist_head cmd_pending;
|
||||
int last_id;
|
||||
|
||||
/* a back pointer */
|
||||
struct bsc_nat *nat;
|
||||
};
|
||||
@@ -125,6 +158,7 @@ struct bsc_config {
|
||||
char *acc_lst_name;
|
||||
|
||||
int forbid_paging;
|
||||
int paging_group;
|
||||
|
||||
/* audio handling */
|
||||
int max_endpoints;
|
||||
@@ -142,6 +176,14 @@ struct bsc_lac_entry {
|
||||
uint16_t lac;
|
||||
};
|
||||
|
||||
struct bsc_nat_paging_group {
|
||||
struct llist_head entry;
|
||||
|
||||
/* list of lac entries */
|
||||
struct llist_head lists;
|
||||
int nr;
|
||||
};
|
||||
|
||||
/**
|
||||
* BSCs point of view of endpoints
|
||||
*/
|
||||
@@ -159,21 +201,21 @@ struct bsc_endpoint {
|
||||
*/
|
||||
struct bsc_nat_statistics {
|
||||
struct {
|
||||
struct counter *conn;
|
||||
struct counter *calls;
|
||||
struct osmo_counter *conn;
|
||||
struct osmo_counter *calls;
|
||||
} sccp;
|
||||
|
||||
struct {
|
||||
struct counter *reconn;
|
||||
struct counter *auth_fail;
|
||||
struct osmo_counter *reconn;
|
||||
struct osmo_counter *auth_fail;
|
||||
} bsc;
|
||||
|
||||
struct {
|
||||
struct counter *reconn;
|
||||
struct osmo_counter *reconn;
|
||||
} msc;
|
||||
|
||||
struct {
|
||||
struct counter *reconn;
|
||||
struct osmo_counter *reconn;
|
||||
} ussd;
|
||||
};
|
||||
|
||||
@@ -216,6 +258,9 @@ struct bsc_nat {
|
||||
/* access lists */
|
||||
struct llist_head access_lists;
|
||||
|
||||
/* paging groups */
|
||||
struct llist_head paging_groups;
|
||||
|
||||
/* known BSC's */
|
||||
struct llist_head bsc_configs;
|
||||
int num_bsc;
|
||||
@@ -227,8 +272,8 @@ struct bsc_nat {
|
||||
int mgcp_length;
|
||||
|
||||
/* msc things */
|
||||
char *msc_ip;
|
||||
int msc_port;
|
||||
struct llist_head dests;
|
||||
struct bsc_msc_dest *main_dest;
|
||||
struct bsc_msc_connection *msc_con;
|
||||
char *token;
|
||||
|
||||
@@ -244,20 +289,37 @@ struct bsc_nat {
|
||||
|
||||
/* number rewriting */
|
||||
char *num_rewr_name;
|
||||
struct msg_entries *num_rewr;
|
||||
struct llist_head num_rewr;
|
||||
|
||||
char *smsc_rewr_name;
|
||||
struct llist_head smsc_rewr;
|
||||
char *tpdest_match_name;
|
||||
struct llist_head tpdest_match;
|
||||
|
||||
/* USSD messages we want to match */
|
||||
char *ussd_lst_name;
|
||||
char *ussd_query;
|
||||
regex_t ussd_query_re;
|
||||
char *ussd_token;
|
||||
char *ussd_local;
|
||||
struct bsc_fd ussd_listen;
|
||||
struct osmo_fd ussd_listen;
|
||||
struct bsc_nat_ussd_con *ussd_con;
|
||||
|
||||
/* for maintainenance */
|
||||
int blocked;
|
||||
|
||||
/* statistics */
|
||||
struct bsc_nat_statistics stats;
|
||||
};
|
||||
|
||||
struct bsc_nat_ussd_con {
|
||||
struct osmo_wqueue queue;
|
||||
struct bsc_nat *nat;
|
||||
int authorized;
|
||||
|
||||
struct osmo_timer_list auth_timeout;
|
||||
};
|
||||
|
||||
/* create and init the structures */
|
||||
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);
|
||||
@@ -285,7 +347,7 @@ struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
|
||||
*/
|
||||
int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed);
|
||||
int bsc_nat_vty_init(struct bsc_nat *nat);
|
||||
struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg, int *_lac);
|
||||
int bsc_nat_find_paging(struct msgb *msg, const uint8_t **,int *len);
|
||||
|
||||
/**
|
||||
* Content filtering.
|
||||
@@ -326,12 +388,12 @@ uint32_t bsc_mgcp_extract_ci(const char *resp);
|
||||
|
||||
|
||||
int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int id);
|
||||
int bsc_do_write(struct write_queue *queue, struct msgb *msg, int id);
|
||||
int bsc_write_msg(struct write_queue *queue, struct msgb *msg);
|
||||
int bsc_write_cb(struct bsc_fd *bfd, struct msgb *msg);
|
||||
int bsc_do_write(struct osmo_wqueue *queue, struct msgb *msg, int id);
|
||||
int bsc_write_msg(struct osmo_wqueue *queue, struct msgb *msg);
|
||||
int bsc_write_cb(struct osmo_fd *bfd, struct msgb *msg);
|
||||
|
||||
/* IMSI allow/deny handling */
|
||||
void bsc_parse_reg(void *ctx, regex_t *reg, char **imsi, int argc, const char **argv);
|
||||
int bsc_parse_reg(void *ctx, regex_t *reg, char **imsi, int argc, const char **argv) __attribute__ ((warn_unused_result));
|
||||
struct bsc_nat_acc_lst *bsc_nat_acc_lst_find(struct bsc_nat *nat, const char *name);
|
||||
struct bsc_nat_acc_lst *bsc_nat_acc_lst_get(struct bsc_nat *nat, const char *name);
|
||||
void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst);
|
||||
@@ -350,6 +412,27 @@ int bsc_ussd_init(struct bsc_nat *nat);
|
||||
int bsc_check_ussd(struct sccp_connections *con, struct bsc_nat_parsed *parsed, struct msgb *msg);
|
||||
int bsc_close_ussd_connections(struct bsc_nat *nat);
|
||||
|
||||
struct msgb *bsc_nat_rewrite_setup(struct bsc_nat *nat, struct msgb *msg, struct bsc_nat_parsed *, const char *imsi);
|
||||
struct msgb *bsc_nat_rewrite_msg(struct bsc_nat *nat, struct msgb *msg, struct bsc_nat_parsed *, const char *imsi);
|
||||
|
||||
/** paging group handling */
|
||||
struct bsc_nat_paging_group *bsc_nat_paging_group_num(struct bsc_nat *nat, int group);
|
||||
struct bsc_nat_paging_group *bsc_nat_paging_group_create(struct bsc_nat *nat, int group);
|
||||
void bsc_nat_paging_group_delete(struct bsc_nat_paging_group *);
|
||||
void bsc_nat_paging_group_add_lac(struct bsc_nat_paging_group *grp, int lac);
|
||||
void bsc_nat_paging_group_del_lac(struct bsc_nat_paging_group *grp, int lac);
|
||||
|
||||
/**
|
||||
* Number rewriting support below
|
||||
*/
|
||||
struct bsc_nat_num_rewr_entry {
|
||||
struct llist_head list;
|
||||
|
||||
regex_t msisdn_reg;
|
||||
regex_t num_reg;
|
||||
|
||||
char *replace;
|
||||
};
|
||||
|
||||
void bsc_nat_num_rewr_entry_adapt(void *ctx, struct llist_head *head, const struct osmo_config_list *);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#ifndef BSC_NAT_SCCP_H
|
||||
#define BSC_NAT_SCCP_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <osmocom/sccp/sccp_types.h>
|
||||
|
||||
/*
|
||||
@@ -77,9 +76,13 @@ struct sccp_connections {
|
||||
/* status */
|
||||
int con_type;
|
||||
int con_local;
|
||||
int authorized;
|
||||
int imsi_checked;
|
||||
char *imsi;
|
||||
|
||||
/* remember which Transactions we run over the bypass */
|
||||
char ussd_ti[8];
|
||||
|
||||
/*
|
||||
* audio handling. Remember if we have ever send a CRCX,
|
||||
* remember the endpoint used by the MSC and BSC.
|
||||
|
||||
@@ -10,10 +10,10 @@ enum bsc_rllr_ind {
|
||||
BSC_RLLR_IND_TIMEOUT,
|
||||
};
|
||||
|
||||
int rll_establish(struct gsm_lchan *lchan, u_int8_t link_id,
|
||||
void (*cb)(struct gsm_lchan *, u_int8_t, void *,
|
||||
int rll_establish(struct gsm_lchan *lchan, uint8_t link_id,
|
||||
void (*cb)(struct gsm_lchan *, uint8_t, void *,
|
||||
enum bsc_rllr_ind),
|
||||
void *data);
|
||||
void rll_indication(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t type);
|
||||
void rll_indication(struct gsm_lchan *lchan, uint8_t link_id, uint8_t type);
|
||||
|
||||
#endif /* _BSC_RLL_H */
|
||||
|
||||
18
openbsc/include/openbsc/bss.h
Normal file
18
openbsc/include/openbsc/bss.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef _BSS_H_
|
||||
#define _BSS_H_
|
||||
|
||||
struct gsm_network;
|
||||
struct msgb;
|
||||
|
||||
/* start and stop network */
|
||||
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 */
|
||||
extern int bts_init(void);
|
||||
extern int bts_model_bs11_init(void);
|
||||
extern int bts_model_rbs2k_init(void);
|
||||
extern int bts_model_nanobts_init(void);
|
||||
extern int bts_model_hslfemto_init(void);
|
||||
extern int bts_model_nokia_site_init(void);
|
||||
#endif
|
||||
154
openbsc/include/openbsc/control_cmd.h
Normal file
154
openbsc/include/openbsc/control_cmd.h
Normal file
@@ -0,0 +1,154 @@
|
||||
#ifndef _CONTROL_CMD_H
|
||||
#define _CONTROL_CMD_H
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
|
||||
#include <osmocom/vty/vector.h>
|
||||
|
||||
#define CTRL_CMD_ERROR -1
|
||||
#define CTRL_CMD_HANDLED 0
|
||||
#define CTRL_CMD_REPLY 1
|
||||
|
||||
enum ctrl_node_type {
|
||||
CTRL_NODE_ROOT, /* Root elements */
|
||||
CTRL_NODE_NET, /* Network specific (net.) */
|
||||
CTRL_NODE_BTS, /* BTS specific (net.btsN.) */
|
||||
CTRL_NODE_TRX, /* TRX specific (net.btsN.trxM.) */
|
||||
CTRL_NODE_TS, /* TS specific (net.btsN.trxM.tsI.) */
|
||||
_LAST_CTRL_NODE
|
||||
};
|
||||
|
||||
enum ctrl_type {
|
||||
CTRL_TYPE_UNKNOWN,
|
||||
CTRL_TYPE_GET,
|
||||
CTRL_TYPE_SET,
|
||||
CTRL_TYPE_GET_REPLY,
|
||||
CTRL_TYPE_SET_REPLY,
|
||||
CTRL_TYPE_TRAP,
|
||||
CTRL_TYPE_ERROR
|
||||
};
|
||||
|
||||
struct ctrl_connection {
|
||||
struct llist_head list_entry;
|
||||
|
||||
/* The queue for sending data back */
|
||||
struct osmo_wqueue write_queue;
|
||||
|
||||
/* Callback if the connection was closed */
|
||||
void (*closed_cb)(struct ctrl_connection *conn);
|
||||
|
||||
/* Pending commands for this connection */
|
||||
struct llist_head cmds;
|
||||
};
|
||||
|
||||
struct ctrl_cmd {
|
||||
struct ctrl_connection *ccon;
|
||||
enum ctrl_type type;
|
||||
char *id;
|
||||
void *node;
|
||||
char *variable;
|
||||
char *value;
|
||||
char *reply;
|
||||
};
|
||||
|
||||
struct ctrl_cmd_struct {
|
||||
int nr_commands;
|
||||
char **command;
|
||||
};
|
||||
|
||||
struct ctrl_cmd_element {
|
||||
const char *name;
|
||||
const char *param;
|
||||
struct ctrl_cmd_struct strcmd;
|
||||
int (*set)(struct ctrl_cmd *cmd, void *data);
|
||||
int (*get)(struct ctrl_cmd *cmd, void *data);
|
||||
int (*verify)(struct ctrl_cmd *cmd, const char *value, void *data);
|
||||
};
|
||||
|
||||
struct ctrl_cmd_map {
|
||||
char *cmd;
|
||||
enum ctrl_type type;
|
||||
};
|
||||
|
||||
int ctrl_cmd_exec(vector vline, struct ctrl_cmd *command, vector node, void *data);
|
||||
int ctrl_cmd_install(enum ctrl_node_type node, struct ctrl_cmd_element *cmd);
|
||||
int ctrl_cmd_handle(struct ctrl_cmd *cmd, void *data);
|
||||
int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd);
|
||||
struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg);
|
||||
struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd);
|
||||
struct ctrl_cmd *ctrl_cmd_cpy(void *ctx, struct ctrl_cmd *cmd);
|
||||
|
||||
#define CTRL_CMD_DEFINE_RANGE(cmdname, cmdstr, dtype, element, min, max) \
|
||||
int get_##cmdname(struct ctrl_cmd *cmd, void *data) \
|
||||
{ \
|
||||
dtype *node = data; \
|
||||
cmd->reply = talloc_asprintf(cmd, "%i", node->element); \
|
||||
if (!cmd->reply) { \
|
||||
cmd->reply = "OOM"; \
|
||||
return CTRL_CMD_ERROR; \
|
||||
} \
|
||||
return CTRL_CMD_REPLY; \
|
||||
} \
|
||||
int set_##cmdname(struct ctrl_cmd *cmd, void *data) \
|
||||
{ \
|
||||
dtype *node = data; \
|
||||
int tmp = atoi(cmd->value); \
|
||||
node->element = tmp; \
|
||||
return get_##cmdname(cmd, data); \
|
||||
} \
|
||||
int verify_##cmdname(struct ctrl_cmd *cmd, const char *value, void *data) \
|
||||
{ \
|
||||
int tmp = atoi(value); \
|
||||
if ((tmp >= min)&&(tmp <= max)) { \
|
||||
return 0; \
|
||||
} \
|
||||
return -1; \
|
||||
} \
|
||||
struct ctrl_cmd_element cmd_##cmdname = { \
|
||||
.name = cmdstr, \
|
||||
.param = NULL, \
|
||||
.get = &get_##cmdname, \
|
||||
.set = &set_##cmdname, \
|
||||
.verify = &verify_##cmdname, \
|
||||
}
|
||||
|
||||
#define CTRL_CMD_DEFINE_STRING(cmdname, cmdstr, dtype, element) \
|
||||
int get_##cmdname(struct ctrl_cmd *cmd, dtype *data) \
|
||||
{ \
|
||||
cmd->reply = talloc_asprintf(cmd, "%s", data->element); \
|
||||
if (!cmd->reply) { \
|
||||
cmd->reply = "OOM"; \
|
||||
return CTRL_CMD_ERROR; \
|
||||
} \
|
||||
return CTRL_CMD_REPLY; \
|
||||
} \
|
||||
int set_##cmdname(struct ctrl_cmd *cmd, dtype *data) \
|
||||
{ \
|
||||
bsc_replace_string(cmd->node, &data->element, cmd->value); \
|
||||
return get_##cmdname(cmd, data); \
|
||||
} \
|
||||
struct ctrl_cmd_element cmd_##cmdname = { \
|
||||
.name = cmdstr, \
|
||||
.param = NULL, \
|
||||
.get = &get_##cmdname, \
|
||||
.set = &set_##cmdname, \
|
||||
.verify = NULL, \
|
||||
}
|
||||
|
||||
#define CTRL_CMD_DEFINE(cmdname, cmdstr) \
|
||||
int get_##cmdname(struct ctrl_cmd *cmd, void *data); \
|
||||
int set_##cmdname(struct ctrl_cmd *cmd, void *data); \
|
||||
int verify_##cmdname(struct ctrl_cmd *cmd, const char *value, void *data); \
|
||||
struct ctrl_cmd_element cmd_##cmdname = { \
|
||||
.name = cmdstr, \
|
||||
.param = NULL, \
|
||||
.get = &get_##cmdname, \
|
||||
.set = &set_##cmdname, \
|
||||
.verify = &verify_##cmdname, \
|
||||
}
|
||||
|
||||
struct gsm_network;
|
||||
int controlif_setup(struct gsm_network *gsmnet, uint16_t port);
|
||||
|
||||
#endif /* _CONTROL_CMD_H */
|
||||
@@ -1,8 +1,10 @@
|
||||
#ifndef _CRC24_H
|
||||
#define _CRC24_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define INIT_CRC24 0xffffff
|
||||
|
||||
u_int32_t crc24_calc(u_int32_t fcs, u_int8_t *cp, unsigned int len);
|
||||
uint32_t crc24_calc(uint32_t fcs, uint8_t *cp, unsigned int len);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef _DB_H
|
||||
#define _DB_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "gsm_subscriber.h"
|
||||
|
||||
struct gsm_equipment;
|
||||
struct gsm_network;
|
||||
@@ -29,12 +29,10 @@ struct gsm_auth_tuple;
|
||||
struct gsm_sms;
|
||||
struct gsm_subscriber;
|
||||
|
||||
enum gsm_subscriber_field;
|
||||
|
||||
/* one time initialisation */
|
||||
int db_init(const char *name);
|
||||
int db_prepare();
|
||||
int db_fini();
|
||||
int db_prepare(void);
|
||||
int db_fini(void);
|
||||
|
||||
/* subscriber management */
|
||||
struct gsm_subscriber *db_create_subscriber(struct gsm_network *net,
|
||||
@@ -45,7 +43,7 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
|
||||
int db_sync_subscriber(struct gsm_subscriber *subscriber);
|
||||
int db_subscriber_alloc_tmsi(struct gsm_subscriber *subscriber);
|
||||
int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber);
|
||||
int db_subscriber_alloc_token(struct gsm_subscriber *subscriber, u_int32_t* token);
|
||||
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_sync_equipment(struct gsm_equipment *equip);
|
||||
int db_subscriber_update(struct gsm_subscriber *subscriber);
|
||||
@@ -71,12 +69,12 @@ int db_sms_inc_deliver_attempts(struct gsm_sms *sms);
|
||||
|
||||
/* APDU blob storage */
|
||||
int db_apdu_blob_store(struct gsm_subscriber *subscr,
|
||||
u_int8_t apdu_id_flags, u_int8_t len,
|
||||
u_int8_t *apdu);
|
||||
uint8_t apdu_id_flags, uint8_t len,
|
||||
uint8_t *apdu);
|
||||
|
||||
/* Statistics counter storage */
|
||||
struct counter;
|
||||
int db_store_counter(struct counter *ctr);
|
||||
struct osmo_counter;
|
||||
int db_store_counter(struct osmo_counter *ctr);
|
||||
struct rate_ctr_group;
|
||||
int db_store_rate_ctr_group(struct rate_ctr_group *ctrg);
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
#define _DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
#define DEBUG
|
||||
#include <osmocore/logging.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
/* Debug Areas of the code */
|
||||
enum {
|
||||
@@ -19,10 +19,6 @@ enum {
|
||||
DSMS,
|
||||
DPAG,
|
||||
DMEAS,
|
||||
DMI,
|
||||
DMIB,
|
||||
DMUX,
|
||||
DINP,
|
||||
DSCCP,
|
||||
DMSC,
|
||||
DMGCP,
|
||||
@@ -35,6 +31,7 @@ enum {
|
||||
DLLC,
|
||||
DSNDCP,
|
||||
DNAT,
|
||||
DCTRL,
|
||||
Debug_LastEntry,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
#ifndef _E1_INPUT_H
|
||||
#define _E1_INPUT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <openbsc/subchan_demux.h>
|
||||
|
||||
#define NUM_E1_TS 32
|
||||
|
||||
enum e1inp_sign_type {
|
||||
E1INP_SIGN_NONE,
|
||||
E1INP_SIGN_OML,
|
||||
E1INP_SIGN_RSL,
|
||||
};
|
||||
const char *e1inp_signtype_name(enum e1inp_sign_type tp);
|
||||
|
||||
struct e1inp_ts;
|
||||
|
||||
struct e1inp_sign_link {
|
||||
/* list of signalling links */
|
||||
struct llist_head list;
|
||||
|
||||
/* to which timeslot do we belong? */
|
||||
struct e1inp_ts *ts;
|
||||
|
||||
enum e1inp_sign_type type;
|
||||
|
||||
/* trx for msg->trx of received msgs */
|
||||
struct gsm_bts_trx *trx;
|
||||
|
||||
/* msgb queue of to-be-transmitted msgs */
|
||||
struct llist_head tx_list;
|
||||
|
||||
/* SAPI and TEI on the E1 TS */
|
||||
u_int8_t sapi;
|
||||
u_int8_t tei;
|
||||
|
||||
union {
|
||||
struct {
|
||||
u_int8_t channel;
|
||||
} misdn;
|
||||
} driver;
|
||||
};
|
||||
|
||||
enum e1inp_ts_type {
|
||||
E1INP_TS_TYPE_NONE,
|
||||
E1INP_TS_TYPE_SIGN,
|
||||
E1INP_TS_TYPE_TRAU,
|
||||
};
|
||||
const char *e1inp_tstype_name(enum e1inp_ts_type tp);
|
||||
|
||||
/* A timeslot in the E1 interface */
|
||||
struct e1inp_ts {
|
||||
enum e1inp_ts_type type;
|
||||
int num;
|
||||
|
||||
/* to which line do we belong ? */
|
||||
struct e1inp_line *line;
|
||||
|
||||
union {
|
||||
struct {
|
||||
/* list of all signalling links on this TS */
|
||||
struct llist_head sign_links;
|
||||
/* delay for the queue */
|
||||
int delay;
|
||||
/* timer when to dequeue next frame */
|
||||
struct timer_list tx_timer;
|
||||
} sign;
|
||||
struct {
|
||||
/* subchannel demuxer for frames from E1 */
|
||||
struct subch_demux demux;
|
||||
/* subchannel muxer for frames to E1 */
|
||||
struct subch_mux mux;
|
||||
} trau;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
/* mISDN driver has one fd for each ts */
|
||||
struct bsc_fd fd;
|
||||
} misdn;
|
||||
struct {
|
||||
/* ip.access driver has one fd for each ts */
|
||||
struct bsc_fd fd;
|
||||
} ipaccess;
|
||||
struct {
|
||||
/* DAHDI driver has one fd for each ts */
|
||||
struct bsc_fd fd;
|
||||
struct lapd_instance *lapd;
|
||||
} dahdi;
|
||||
} driver;
|
||||
};
|
||||
|
||||
struct e1inp_driver {
|
||||
struct llist_head list;
|
||||
const char *name;
|
||||
int (*want_write)(struct e1inp_ts *ts);
|
||||
int (*line_update)(struct e1inp_line *line);
|
||||
int default_delay;
|
||||
};
|
||||
|
||||
struct e1inp_line {
|
||||
struct llist_head list;
|
||||
unsigned int num;
|
||||
const char *name;
|
||||
|
||||
/* array of timestlots */
|
||||
struct e1inp_ts ts[NUM_E1_TS];
|
||||
|
||||
struct e1inp_driver *driver;
|
||||
void *driver_data;
|
||||
};
|
||||
|
||||
/* register a driver with the E1 core */
|
||||
int e1inp_driver_register(struct e1inp_driver *drv);
|
||||
|
||||
/* fine a previously registered driver */
|
||||
struct e1inp_driver *e1inp_driver_find(const char *name);
|
||||
|
||||
/* register a line with the E1 core */
|
||||
int e1inp_line_register(struct e1inp_line *line);
|
||||
|
||||
/* get a line by its ID */
|
||||
struct e1inp_line *e1inp_line_get(u_int8_t e1_nr);
|
||||
|
||||
/* create a line in the E1 input core */
|
||||
struct e1inp_line *e1inp_line_create(u_int8_t e1_nr, const char *driver_name);
|
||||
|
||||
/* find a sign_link for given TEI and SAPI in a TS */
|
||||
struct e1inp_sign_link *
|
||||
e1inp_lookup_sign_link(struct e1inp_ts *ts, u_int8_t tei,
|
||||
u_int8_t sapi);
|
||||
|
||||
/* create a new signalling link in a E1 timeslot */
|
||||
struct e1inp_sign_link *
|
||||
e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type,
|
||||
struct gsm_bts_trx *trx, u_int8_t tei,
|
||||
u_int8_t sapi);
|
||||
|
||||
/* configure and initialize one e1inp_ts */
|
||||
int e1inp_ts_config(struct e1inp_ts *ts, struct e1inp_line *line,
|
||||
enum e1inp_ts_type type);
|
||||
|
||||
/* Call from the Stack: configuration of this TS has changed */
|
||||
int e1inp_update_ts(struct e1inp_ts *ts);
|
||||
|
||||
/* Receive a packet from the E1 driver */
|
||||
int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
|
||||
u_int8_t tei, u_int8_t sapi);
|
||||
|
||||
/* called by driver if it wants to transmit on a given TS */
|
||||
struct msgb *e1inp_tx_ts(struct e1inp_ts *e1i_ts,
|
||||
struct e1inp_sign_link **sign_link);
|
||||
|
||||
/* called by driver in case some kind of link state event */
|
||||
int e1inp_event(struct e1inp_ts *ts, int evt, u_int8_t tei, u_int8_t sapi);
|
||||
|
||||
/* Write LAPD frames to the fd. */
|
||||
void e1_set_pcap_fd(int fd);
|
||||
|
||||
/* called by TRAU muxer to obtain the destination mux entity */
|
||||
struct subch_mux *e1inp_get_mux(u_int8_t e1_nr, u_int8_t ts_nr);
|
||||
|
||||
void e1inp_sign_link_destroy(struct e1inp_sign_link *link);
|
||||
int e1inp_line_update(struct e1inp_line *line);
|
||||
|
||||
/* e1_config.c */
|
||||
int e1_reconfig_ts(struct gsm_bts_trx_ts *ts);
|
||||
int e1_reconfig_trx(struct gsm_bts_trx *trx);
|
||||
int e1_reconfig_bts(struct gsm_bts *bts);
|
||||
|
||||
int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin);
|
||||
int ipaccess_setup(struct gsm_network *gsmnet);
|
||||
|
||||
extern struct llist_head e1inp_driver_list;
|
||||
extern struct llist_head e1inp_line_list;
|
||||
|
||||
int e1inp_vty_init(void);
|
||||
void e1inp_init(void);
|
||||
|
||||
int _abis_nm_sendmsg(struct msgb *msg, int to_trx_oml);
|
||||
|
||||
#endif /* _E1_INPUT_H */
|
||||
@@ -1,16 +1,15 @@
|
||||
#ifndef _GB_PROXY_H
|
||||
#define _GB_PROXY_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
|
||||
#include <openbsc/gprs_ns.h>
|
||||
#include <osmocom/vty/command.h>
|
||||
|
||||
struct gbproxy_config {
|
||||
/* parsed from config file */
|
||||
u_int16_t nsip_sgsn_nsei;
|
||||
uint16_t nsip_sgsn_nsei;
|
||||
|
||||
/* misc */
|
||||
struct gprs_ns_inst *nsi;
|
||||
|
||||
@@ -182,7 +182,7 @@ struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t
|
||||
/* Find a BTS context based on BVCI+NSEI tuple */
|
||||
struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei);
|
||||
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
|
||||
/* BSSGP-UL-UNITDATA.ind */
|
||||
int gprs_bssgp_rcvmsg(struct msgb *msg);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _GPRS_GMM_H
|
||||
#define _GPRS_GMM_H
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
|
||||
int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause);
|
||||
|
||||
@@ -99,8 +99,8 @@ struct gprs_llc_lle {
|
||||
|
||||
enum gprs_llc_lle_state state;
|
||||
|
||||
struct timer_list t200;
|
||||
struct timer_list t201; /* wait for acknowledgement */
|
||||
struct osmo_timer_list t200;
|
||||
struct osmo_timer_list t201; /* wait for acknowledgement */
|
||||
|
||||
uint16_t v_sent;
|
||||
uint16_t v_ack;
|
||||
|
||||
@@ -77,10 +77,10 @@ enum ns_cause {
|
||||
|
||||
/* Our Implementation */
|
||||
#include <netinet/in.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/select.h>
|
||||
|
||||
#define NS_TIMERS_COUNT 7
|
||||
#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)"
|
||||
@@ -133,13 +133,13 @@ struct gprs_ns_inst {
|
||||
|
||||
/* NS-over-IP specific bits */
|
||||
struct {
|
||||
struct bsc_fd fd;
|
||||
struct osmo_fd fd;
|
||||
uint32_t local_ip;
|
||||
uint16_t local_port;
|
||||
} nsip;
|
||||
/* NS-over-FR-over-GRE-over-IP specific bits */
|
||||
struct {
|
||||
struct bsc_fd fd;
|
||||
struct osmo_fd fd;
|
||||
uint32_t local_ip;
|
||||
int enabled:1;
|
||||
} frgre;
|
||||
@@ -163,7 +163,7 @@ struct gprs_nsvc {
|
||||
uint32_t state;
|
||||
uint32_t remote_state;
|
||||
|
||||
struct timer_list timer;
|
||||
struct osmo_timer_list timer;
|
||||
enum nsvc_timer_mode timer_mode;
|
||||
int alive_retries;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <osmocore/gsm48.h>
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
|
||||
#include <osmocom/crypt/gprs_cipher.h>
|
||||
|
||||
@@ -78,7 +78,7 @@ struct sgsn_mm_ctx {
|
||||
/* CKSN */
|
||||
enum gprs_ciph_algo ciph_algo;
|
||||
struct {
|
||||
uint8_t buf[14]; /* 10.5.5.12a */
|
||||
uint8_t buf[52]; /* 10.5.5.12a */
|
||||
uint8_t len;
|
||||
} ms_radio_access_capa;
|
||||
struct {
|
||||
@@ -102,7 +102,7 @@ struct sgsn_mm_ctx {
|
||||
uint16_t nsei;
|
||||
uint16_t bvci;
|
||||
struct rate_ctr_group *ctrg;
|
||||
struct timer_list timer;
|
||||
struct osmo_timer_list timer;
|
||||
unsigned int T; /* Txxxx number */
|
||||
unsigned int num_T_exp; /* number of consecutive T expirations */
|
||||
|
||||
@@ -168,7 +168,7 @@ struct sgsn_pdp_ctx {
|
||||
//uint32_t charging_id;
|
||||
int reordering_reqd;
|
||||
|
||||
struct timer_list timer;
|
||||
struct osmo_timer_list timer;
|
||||
unsigned int T; /* Txxxx number */
|
||||
unsigned int num_T_exp; /* number of consecutive T expirations */
|
||||
};
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#ifndef _GSM_04_08_H
|
||||
#define _GSM_04_08_H
|
||||
|
||||
#include <openbsc/meas_rep.h>
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
#include <osmocore/protocol/gsm_04_08.h>
|
||||
#include <osmocore/gsm48.h>
|
||||
#include <openbsc/meas_rep.h>
|
||||
|
||||
struct msgb;
|
||||
struct gsm_bts;
|
||||
@@ -28,37 +29,38 @@ void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t caus
|
||||
void gsm0408_clear_all_trans(struct gsm_network *net, int protocol);
|
||||
int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
|
||||
int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id);
|
||||
int gsm0408_new_conn(struct gsm_subscriber_connection *conn);
|
||||
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *bts, u_int8_t ra);
|
||||
enum gsm_chreq_reason_t get_reason_by_chreq(u_int8_t ra, int neci);
|
||||
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *bts, uint8_t ra);
|
||||
/* don't use "enum gsm_chreq_reason_t" to avoid circular dependency */
|
||||
int get_reason_by_chreq(uint8_t ra, int neci);
|
||||
void gsm_net_update_ctype(struct gsm_network *net);
|
||||
|
||||
int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn);
|
||||
int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, u_int8_t *rand, 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_send_rr_release(struct gsm_lchan *lchan);
|
||||
int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
|
||||
int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, u_int8_t apdu_id,
|
||||
u_int8_t apdu_len, const u_int8_t *apdu);
|
||||
int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, u_int8_t power_class);
|
||||
int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_id,
|
||||
uint8_t apdu_len, const uint8_t *apdu);
|
||||
int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, uint8_t power_class);
|
||||
int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
|
||||
u_int8_t power_command, u_int8_t ho_ref);
|
||||
uint8_t power_command, uint8_t ho_ref);
|
||||
|
||||
int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg);
|
||||
|
||||
/* convert a ASCII phone number to call-control BCD */
|
||||
int encode_bcd_number(u_int8_t *bcd_lv, u_int8_t max_len,
|
||||
int encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len,
|
||||
int h_len, const char *input);
|
||||
int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
|
||||
int decode_bcd_number(char *output, int output_len, const uint8_t *bcd_lv,
|
||||
int h_len);
|
||||
|
||||
int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_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, u_int8_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 gsm_subscriber *subscr);
|
||||
|
||||
int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode);
|
||||
int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t lchan_mode);
|
||||
int gsm48_rx_rr_modif_ack(struct msgb *msg);
|
||||
int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define _GSM48_GPRS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocore/protocol/gsm_04_08.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
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
#ifndef _GSM_04_11_H
|
||||
#define _GSM_04_11_H
|
||||
|
||||
#include <osmocore/protocol/gsm_04_11.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_11.h>
|
||||
|
||||
#define UM_SAPI_SMS 3 /* See GSM 04.05/04.06 */
|
||||
|
||||
/* SMS deliver PDU */
|
||||
struct sms_deliver {
|
||||
u_int8_t mti:2; /* message type indicator */
|
||||
u_int8_t mms:1; /* more messages to send */
|
||||
u_int8_t rp:1; /* reply path */
|
||||
u_int8_t udhi:1; /* user data header indicator */
|
||||
u_int8_t sri:1; /* status report indication */
|
||||
u_int8_t *orig_addr; /* originating address */
|
||||
u_int8_t pid; /* protocol identifier */
|
||||
u_int8_t dcs; /* data coding scheme */
|
||||
uint8_t mti:2; /* message type indicator */
|
||||
uint8_t mms:1; /* more messages to send */
|
||||
uint8_t rp:1; /* reply path */
|
||||
uint8_t udhi:1; /* user data header indicator */
|
||||
uint8_t sri:1; /* status report indication */
|
||||
uint8_t *orig_addr; /* originating address */
|
||||
uint8_t pid; /* protocol identifier */
|
||||
uint8_t dcs; /* data coding scheme */
|
||||
/* service centre time stamp */
|
||||
u_int8_t ud_len; /* user data length */
|
||||
u_int8_t *user_data; /* user data */
|
||||
uint8_t ud_len; /* user data length */
|
||||
uint8_t *user_data; /* user data */
|
||||
|
||||
u_int8_t msg_ref; /* message reference */
|
||||
u_int8_t *smsc;
|
||||
uint8_t msg_ref; /* message reference */
|
||||
uint8_t *smsc;
|
||||
};
|
||||
|
||||
struct msgb;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef _GSM_04_80_H
|
||||
#define _GSM_04_80_H
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/protocol/gsm_04_80.h>
|
||||
#include <osmocore/gsm0480.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_80.h>
|
||||
#include <osmocom/gsm/gsm0480.h>
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
|
||||
@@ -1,97 +1,13 @@
|
||||
#ifndef _GSM_DATA_H
|
||||
#define _GSM_DATA_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct osmo_msc_data;
|
||||
struct osmo_bsc_sccp_con;
|
||||
struct gsm_sms_queue;
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/select.h>
|
||||
|
||||
enum gsm_phys_chan_config {
|
||||
GSM_PCHAN_NONE,
|
||||
GSM_PCHAN_CCCH,
|
||||
GSM_PCHAN_CCCH_SDCCH4,
|
||||
GSM_PCHAN_TCH_F,
|
||||
GSM_PCHAN_TCH_H,
|
||||
GSM_PCHAN_SDCCH8_SACCH8C,
|
||||
GSM_PCHAN_PDCH, /* GPRS PDCH */
|
||||
GSM_PCHAN_TCH_F_PDCH, /* TCH/F if used, PDCH otherwise */
|
||||
GSM_PCHAN_UNKNOWN,
|
||||
};
|
||||
|
||||
enum gsm_chan_t {
|
||||
GSM_LCHAN_NONE,
|
||||
GSM_LCHAN_SDCCH,
|
||||
GSM_LCHAN_TCH_F,
|
||||
GSM_LCHAN_TCH_H,
|
||||
GSM_LCHAN_UNKNOWN,
|
||||
};
|
||||
|
||||
/* RRLP mode of operation */
|
||||
enum rrlp_mode {
|
||||
RRLP_MODE_NONE,
|
||||
RRLP_MODE_MS_BASED,
|
||||
RRLP_MODE_MS_PREF,
|
||||
RRLP_MODE_ASS_PREF,
|
||||
};
|
||||
|
||||
/* Channel Request reason */
|
||||
enum gsm_chreq_reason_t {
|
||||
GSM_CHREQ_REASON_EMERG,
|
||||
GSM_CHREQ_REASON_PAG,
|
||||
GSM_CHREQ_REASON_CALL,
|
||||
GSM_CHREQ_REASON_LOCATION_UPD,
|
||||
GSM_CHREQ_REASON_OTHER,
|
||||
};
|
||||
|
||||
#include <osmocore/timer.h>
|
||||
#include <openbsc/system_information.h>
|
||||
#include <openbsc/rest_octets.h>
|
||||
#include <openbsc/mncc.h>
|
||||
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/bitvec.h>
|
||||
#include <osmocore/statistics.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
#include <osmocore/utils.h>
|
||||
#include <osmocore/rxlev_stat.h>
|
||||
|
||||
#include <osmocore/protocol/gsm_08_58.h>
|
||||
|
||||
|
||||
#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 */
|
||||
#define HARDCODED_BTS0_TS 1
|
||||
#define HARDCODED_BTS1_TS 6
|
||||
#define HARDCODED_BTS2_TS 11
|
||||
|
||||
/* reserved according to GSM 03.03 § 2.4 */
|
||||
#define GSM_RESERVED_TMSI 0xFFFFFFFF
|
||||
|
||||
enum gsm_hooks {
|
||||
GSM_HOOK_NM_SWLOAD,
|
||||
GSM_HOOK_RR_PAGING,
|
||||
GSM_HOOK_RR_SECURITY,
|
||||
};
|
||||
|
||||
enum gsm_paging_event {
|
||||
GSM_PAGING_SUCCEEDED,
|
||||
GSM_PAGING_EXPIRED,
|
||||
GSM_PAGING_OOM,
|
||||
GSM_PAGING_BUSY,
|
||||
};
|
||||
|
||||
enum bts_gprs_mode {
|
||||
BTS_GPRS_NONE = 0,
|
||||
BTS_GPRS_GPRS = 1,
|
||||
BTS_GPRS_EGPRS = 2,
|
||||
};
|
||||
#include <osmocom/abis/e1_input.h>
|
||||
|
||||
#define OBSC_NM_W_ACK_CB(__msgb) (__msgb)->cb[3]
|
||||
|
||||
@@ -104,11 +20,11 @@ struct openbsc_msgb_cb {
|
||||
unsigned char *bssgp_cell_id;
|
||||
|
||||
/* Identifiers of a BTS, equal to 'struct bssgp_bts_ctx' */
|
||||
u_int16_t nsei;
|
||||
u_int16_t bvci;
|
||||
uint16_t nsei;
|
||||
uint16_t bvci;
|
||||
|
||||
/* Identifier of a MS (inside BTS), equal to 'struct sgsn_mm_ctx' */
|
||||
u_int32_t tlli;
|
||||
uint32_t tlli;
|
||||
} __attribute__((packed));
|
||||
#define OBSC_MSGB_CB(__msgb) ((struct openbsc_msgb_cb *)&((__msgb)->cb[0]))
|
||||
#define msgb_tlli(__x) OBSC_MSGB_CB(__x)->tlli
|
||||
@@ -144,32 +60,18 @@ enum gsm_auth_algo {
|
||||
struct gsm_auth_info {
|
||||
enum gsm_auth_algo auth_algo;
|
||||
unsigned int a3a8_ki_len;
|
||||
u_int8_t a3a8_ki[16];
|
||||
uint8_t a3a8_ki[16];
|
||||
};
|
||||
|
||||
struct gsm_auth_tuple {
|
||||
int use_count;
|
||||
int key_seq;
|
||||
u_int8_t rand[16];
|
||||
u_int8_t sres[4];
|
||||
u_int8_t kc[8];
|
||||
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 */
|
||||
|
||||
|
||||
struct gsm_lchan;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_mncc;
|
||||
struct rtp_socket;
|
||||
struct bsc_api;
|
||||
|
||||
/* Network Management State */
|
||||
struct gsm_nm_state {
|
||||
u_int8_t operational;
|
||||
u_int8_t administrative;
|
||||
u_int8_t availability;
|
||||
};
|
||||
|
||||
/*
|
||||
* LOCATION UPDATING REQUEST state
|
||||
*
|
||||
@@ -178,7 +80,7 @@ struct gsm_nm_state {
|
||||
* - Accept/Reject according to global policy
|
||||
*/
|
||||
struct gsm_loc_updating_operation {
|
||||
struct timer_list updating_timer;
|
||||
struct osmo_timer_list updating_timer;
|
||||
unsigned int waiting_for_imsi : 1;
|
||||
unsigned int waiting_for_imei : 1;
|
||||
unsigned int key_seq : 4;
|
||||
@@ -198,7 +100,7 @@ struct gsm_security_operation {
|
||||
* a couple of seconds to work around MSC issues.
|
||||
*/
|
||||
struct gsm_anchor_operation {
|
||||
struct timer_list timeout;
|
||||
struct osmo_timer_list timeout;
|
||||
};
|
||||
|
||||
/* Maximum number of neighbor cells whose average we track */
|
||||
@@ -208,32 +110,11 @@ struct gsm_anchor_operation {
|
||||
|
||||
/* processed neighbor measurements for one cell */
|
||||
struct neigh_meas_proc {
|
||||
u_int16_t arfcn;
|
||||
u_int8_t bsic;
|
||||
u_int8_t rxlev[MAX_WIN_NEIGH_AVG];
|
||||
uint16_t arfcn;
|
||||
uint8_t bsic;
|
||||
uint8_t rxlev[MAX_WIN_NEIGH_AVG];
|
||||
unsigned int rxlev_cnt;
|
||||
u_int8_t last_seen_nr;
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
/* is the data link established? who established it? */
|
||||
#define LCHAN_SAPI_UNUSED 0
|
||||
#define LCHAN_SAPI_MS 1
|
||||
#define LCHAN_SAPI_NET 2
|
||||
|
||||
/* state of a logical channel */
|
||||
enum gsm_lchan_state {
|
||||
LCHAN_S_NONE, /* channel is not active */
|
||||
LCHAN_S_ACT_REQ, /* channel activatin requested */
|
||||
LCHAN_S_ACTIVE, /* channel is active and operational */
|
||||
LCHAN_S_REL_REQ, /* channel release has been requested */
|
||||
LCHAN_S_REL_ERR, /* channel is in an error state */
|
||||
LCHAN_S_INACTIVE, /* channel is set inactive */
|
||||
uint8_t last_seen_nr;
|
||||
};
|
||||
|
||||
/* the per subscriber data for lchan */
|
||||
@@ -264,423 +145,65 @@ struct gsm_subscriber_connection {
|
||||
struct gsm_bts *bts;
|
||||
|
||||
/* for assignment handling */
|
||||
struct timer_list T10;
|
||||
struct osmo_timer_list T10;
|
||||
struct gsm_lchan *secondary_lchan;
|
||||
|
||||
};
|
||||
|
||||
struct gsm_lchan {
|
||||
/* The TS that we're part of */
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
/* The logical subslot number in the TS */
|
||||
u_int8_t nr;
|
||||
/* The logical channel type */
|
||||
enum gsm_chan_t type;
|
||||
/* RSL channel mode */
|
||||
enum rsl_cmod_spd rsl_cmode;
|
||||
/* If TCH, traffic channel mode */
|
||||
enum gsm48_chan_mode tch_mode;
|
||||
/* State */
|
||||
enum gsm_lchan_state state;
|
||||
/* Power levels for MS and BTS */
|
||||
u_int8_t bs_power;
|
||||
u_int8_t ms_power;
|
||||
/* Encryption information */
|
||||
struct {
|
||||
u_int8_t alg_id;
|
||||
u_int8_t key_len;
|
||||
u_int8_t key[MAX_A5_KEY_LEN];
|
||||
} encr;
|
||||
|
||||
struct timer_list T3101;
|
||||
struct timer_list T3111;
|
||||
struct timer_list error_timer;
|
||||
#define ROLE_BSC
|
||||
#include "gsm_data_shared.h"
|
||||
|
||||
/* AMR bits */
|
||||
struct gsm48_multi_rate_conf mr_conf;
|
||||
|
||||
/* Established data link layer services */
|
||||
u_int8_t sapis[8];
|
||||
int sach_deact;
|
||||
int release_reason;
|
||||
|
||||
/* GSM Random Access data */
|
||||
struct gsm48_req_ref *rqd_ref;
|
||||
uint8_t rqd_ta;
|
||||
|
||||
/* cache of last measurement reports on this lchan */
|
||||
struct gsm_meas_rep meas_rep[6];
|
||||
int meas_rep_idx;
|
||||
|
||||
/* table of neighbor cell measurements */
|
||||
struct neigh_meas_proc neigh_meas[MAX_NEIGH_MEAS];
|
||||
|
||||
struct {
|
||||
u_int32_t bound_ip;
|
||||
u_int32_t connect_ip;
|
||||
u_int16_t bound_port;
|
||||
u_int16_t connect_port;
|
||||
u_int16_t conn_id;
|
||||
u_int8_t rtp_payload;
|
||||
u_int8_t rtp_payload2;
|
||||
u_int8_t speech_mode;
|
||||
struct rtp_socket *rtp_socket;
|
||||
} abis_ip;
|
||||
|
||||
struct gsm_subscriber_connection *conn;
|
||||
};
|
||||
|
||||
struct gsm_e1_subslot {
|
||||
/* Number of E1 link */
|
||||
u_int8_t e1_nr;
|
||||
/* Number of E1 TS inside E1 link */
|
||||
u_int8_t e1_ts;
|
||||
/* Sub-slot within the E1 TS, 0xff if full TS */
|
||||
u_int8_t e1_ts_ss;
|
||||
};
|
||||
|
||||
#define TS_F_PDCH_MODE 0x1000
|
||||
/* One Timeslot in a TRX */
|
||||
struct gsm_bts_trx_ts {
|
||||
struct gsm_bts_trx *trx;
|
||||
/* number of this timeslot at the TRX */
|
||||
u_int8_t nr;
|
||||
|
||||
enum gsm_phys_chan_config pchan;
|
||||
|
||||
unsigned int flags;
|
||||
struct gsm_nm_state nm_state;
|
||||
struct tlv_parsed nm_attr;
|
||||
u_int8_t nm_chan_comb;
|
||||
|
||||
struct {
|
||||
/* Parameters below are configured by VTY */
|
||||
int enabled;
|
||||
u_int8_t maio;
|
||||
u_int8_t hsn;
|
||||
struct bitvec arfcns;
|
||||
u_int8_t arfcns_data[1024/8];
|
||||
/* This is the pre-computed MA for channel assignments */
|
||||
struct bitvec ma;
|
||||
u_int8_t ma_len; /* part of ma_data that is used */
|
||||
u_int8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */
|
||||
} hopping;
|
||||
|
||||
/* To which E1 subslot are we connected */
|
||||
struct gsm_e1_subslot e1_link;
|
||||
|
||||
struct gsm_lchan lchan[TS_MAX_LCHAN];
|
||||
};
|
||||
|
||||
/* One TRX in a BTS */
|
||||
struct gsm_bts_trx {
|
||||
/* list header in bts->trx_list */
|
||||
struct llist_head list;
|
||||
|
||||
struct gsm_bts *bts;
|
||||
/* number of this TRX in the BTS */
|
||||
u_int8_t nr;
|
||||
/* human readable name / description */
|
||||
char *description;
|
||||
/* how do we talk RSL with this TRX? */
|
||||
struct gsm_e1_subslot rsl_e1_link;
|
||||
u_int8_t rsl_tei;
|
||||
struct e1inp_sign_link *rsl_link;
|
||||
/* Some BTS (specifically Ericsson RBS) have a per-TRX OML Link */
|
||||
struct e1inp_sign_link *oml_link;
|
||||
|
||||
struct gsm_nm_state nm_state;
|
||||
struct tlv_parsed nm_attr;
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
} bb_transc;
|
||||
|
||||
u_int16_t arfcn;
|
||||
int nominal_power; /* in dBm */
|
||||
unsigned int max_power_red; /* in actual dB */
|
||||
|
||||
union {
|
||||
struct {
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
} bbsig;
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
} pa;
|
||||
} bs11;
|
||||
struct {
|
||||
unsigned int test_state;
|
||||
u_int8_t test_nr;
|
||||
struct rxlev_stats rxlev_stat;
|
||||
} ipaccess;
|
||||
};
|
||||
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
||||
};
|
||||
|
||||
#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i])
|
||||
|
||||
enum gsm_bts_type {
|
||||
GSM_BTS_TYPE_UNKNOWN,
|
||||
GSM_BTS_TYPE_BS11,
|
||||
GSM_BTS_TYPE_NANOBTS,
|
||||
GSM_BTS_TYPE_RBS2000,
|
||||
};
|
||||
|
||||
struct vty;
|
||||
|
||||
struct gsm_bts_model {
|
||||
struct llist_head list;
|
||||
|
||||
enum gsm_bts_type type;
|
||||
const char *name;
|
||||
|
||||
int (*oml_rcvmsg)(struct msgb *msg);
|
||||
|
||||
void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);
|
||||
void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);
|
||||
void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts);
|
||||
|
||||
struct tlv_definition nm_att_tlvdef;
|
||||
|
||||
struct bitvec features;
|
||||
uint8_t _features_data[128/8];
|
||||
};
|
||||
|
||||
enum gsm_bts_features {
|
||||
BTS_FEAT_HSCSD,
|
||||
BTS_FEAT_GPRS,
|
||||
BTS_FEAT_EGPRS,
|
||||
BTS_FEAT_ECSD,
|
||||
BTS_FEAT_HOPPING,
|
||||
};
|
||||
|
||||
/*
|
||||
* This keeps track of the paging status of one BTS. It
|
||||
* includes a number of pending requests, a back pointer
|
||||
* to the gsm_bts, a timer and some more state.
|
||||
*/
|
||||
struct gsm_bts_paging_state {
|
||||
/* pending requests */
|
||||
struct llist_head pending_requests;
|
||||
struct gsm_bts *bts;
|
||||
|
||||
struct timer_list work_timer;
|
||||
struct timer_list credit_timer;
|
||||
|
||||
/* free chans needed */
|
||||
int free_chans_need;
|
||||
|
||||
/* load */
|
||||
u_int16_t available_slots;
|
||||
};
|
||||
|
||||
struct gsm_envabtse {
|
||||
struct gsm_nm_state nm_state;
|
||||
};
|
||||
|
||||
struct gsm_bts_gprs_nsvc {
|
||||
struct gsm_bts *bts;
|
||||
/* data read via VTY config file, to configure the BTS
|
||||
* via OML from BSC */
|
||||
int id;
|
||||
u_int16_t nsvci;
|
||||
u_int16_t local_port; /* on the BTS */
|
||||
u_int16_t remote_port; /* on the SGSN */
|
||||
u_int32_t remote_ip; /* on the SGSN */
|
||||
|
||||
struct gsm_nm_state nm_state;
|
||||
};
|
||||
|
||||
enum neigh_list_manual_mode {
|
||||
NL_MODE_AUTOMATIC = 0,
|
||||
NL_MODE_MANUAL = 1,
|
||||
NL_MODE_MANUAL_SI5SEP = 2, /* SI2 and SI5 have separate neighbor lists */
|
||||
};
|
||||
|
||||
/* One BTS */
|
||||
struct gsm_bts {
|
||||
/* list header in net->bts_list */
|
||||
struct llist_head list;
|
||||
|
||||
struct gsm_network *network;
|
||||
/* number of ths BTS in network */
|
||||
u_int8_t nr;
|
||||
/* human readable name / description */
|
||||
char *description;
|
||||
/* Cell Identity */
|
||||
u_int16_t cell_identity;
|
||||
/* location area code of this BTS */
|
||||
u_int16_t location_area_code;
|
||||
/* Training Sequence Code */
|
||||
u_int8_t tsc;
|
||||
/* Base Station Identification Code (BSIC) */
|
||||
u_int8_t bsic;
|
||||
/* type of BTS */
|
||||
enum gsm_bts_type type;
|
||||
struct gsm_bts_model *model;
|
||||
enum gsm_band band;
|
||||
/* should the channel allocator allocate channels from high TRX to TRX0,
|
||||
* rather than starting from TRX0 and go upwards? */
|
||||
int chan_alloc_reverse;
|
||||
/* maximum Tx power that the MS is permitted to use in this cell */
|
||||
int ms_max_power;
|
||||
|
||||
/* how do we talk OML with this TRX? */
|
||||
struct gsm_e1_subslot oml_e1_link;
|
||||
u_int8_t oml_tei;
|
||||
struct e1inp_sign_link *oml_link;
|
||||
|
||||
/* Abis network management O&M handle */
|
||||
struct abis_nm_h *nmh;
|
||||
struct gsm_nm_state nm_state;
|
||||
struct tlv_parsed nm_attr;
|
||||
|
||||
/* number of this BTS on given E1 link */
|
||||
u_int8_t bts_nr;
|
||||
|
||||
/* paging state and control */
|
||||
struct gsm_bts_paging_state paging;
|
||||
|
||||
/* CCCH is on C0 */
|
||||
struct gsm_bts_trx *c0;
|
||||
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
} site_mgr;
|
||||
|
||||
enum neigh_list_manual_mode neigh_list_manual_mode;
|
||||
/* parameters from which we build SYSTEM INFORMATION */
|
||||
struct {
|
||||
struct gsm48_rach_control rach_control;
|
||||
u_int8_t ncc_permitted;
|
||||
struct gsm48_cell_sel_par cell_sel_par;
|
||||
struct gsm48_si_selection_params cell_ro_sel_par; /* rest octet */
|
||||
struct gsm48_cell_options cell_options;
|
||||
struct gsm48_control_channel_descr chan_desc;
|
||||
struct bitvec neigh_list;
|
||||
struct bitvec cell_alloc;
|
||||
struct bitvec si5_neigh_list;
|
||||
struct {
|
||||
/* bitmask large enough for all possible ARFCN's */
|
||||
u_int8_t neigh_list[1024/8];
|
||||
u_int8_t cell_alloc[1024/8];
|
||||
/* If the user wants a different neighbor list in SI5 than in SI2 */
|
||||
u_int8_t si5_neigh_list[1024/8];
|
||||
} data;
|
||||
} si_common;
|
||||
|
||||
/* do we use static (user-defined) system information messages? (bitmask) */
|
||||
uint32_t si_mode_static;
|
||||
/* bitmask of all SI that are present/valid in si_buf */
|
||||
uint32_t si_valid;
|
||||
/* buffers where we put the pre-computed SI */
|
||||
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
|
||||
|
||||
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
|
||||
union {
|
||||
struct {
|
||||
u_int16_t site_id;
|
||||
u_int16_t bts_id;
|
||||
u_int32_t flags;
|
||||
} ip_access;
|
||||
struct {
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
} cclk;
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
} rack;
|
||||
struct gsm_envabtse envabtse[4];
|
||||
} bs11;
|
||||
struct {
|
||||
struct {
|
||||
struct llist_head conn_groups;
|
||||
} is;
|
||||
struct {
|
||||
struct llist_head conn_groups;
|
||||
} con;
|
||||
} rbs2000;
|
||||
};
|
||||
|
||||
/* Not entirely sure how ip.access specific this is */
|
||||
struct {
|
||||
enum bts_gprs_mode mode;
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
u_int16_t nsei;
|
||||
uint8_t timer[7];
|
||||
} nse;
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
u_int16_t bvci;
|
||||
uint8_t timer[11];
|
||||
} cell;
|
||||
struct gsm_bts_gprs_nsvc nsvc[2];
|
||||
u_int8_t rac;
|
||||
} gprs;
|
||||
|
||||
/* RACH NM values */
|
||||
int rach_b_thresh;
|
||||
int rach_ldavg_slots;
|
||||
|
||||
/* transceivers */
|
||||
int num_trx;
|
||||
struct llist_head trx_list;
|
||||
|
||||
/* Abis NM queue */
|
||||
struct llist_head abis_queue;
|
||||
int abis_nm_pend;
|
||||
};
|
||||
|
||||
/* Some statistics of our network */
|
||||
struct gsmnet_stats {
|
||||
struct {
|
||||
struct counter *total;
|
||||
struct counter *no_channel;
|
||||
struct osmo_counter *total;
|
||||
struct osmo_counter *no_channel;
|
||||
} chreq;
|
||||
struct {
|
||||
struct counter *attempted;
|
||||
struct counter *no_channel; /* no channel available */
|
||||
struct counter *timeout; /* T3103 timeout */
|
||||
struct counter *completed; /* HO COMPL received */
|
||||
struct counter *failed; /* HO FAIL received */
|
||||
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 counter *attach;
|
||||
struct counter *normal;
|
||||
struct counter *periodic;
|
||||
struct counter *detach;
|
||||
struct osmo_counter *attach;
|
||||
struct osmo_counter *normal;
|
||||
struct osmo_counter *periodic;
|
||||
struct osmo_counter *detach;
|
||||
} loc_upd_type;
|
||||
struct {
|
||||
struct counter *reject;
|
||||
struct counter *accept;
|
||||
struct osmo_counter *reject;
|
||||
struct osmo_counter *accept;
|
||||
} loc_upd_resp;
|
||||
struct {
|
||||
struct counter *attempted;
|
||||
struct counter *detached;
|
||||
struct counter *completed;
|
||||
struct counter *expired;
|
||||
struct osmo_counter *attempted;
|
||||
struct osmo_counter *detached;
|
||||
struct osmo_counter *completed;
|
||||
struct osmo_counter *expired;
|
||||
} paging;
|
||||
struct {
|
||||
struct counter *submitted; /* MO SMS submissions */
|
||||
struct counter *no_receiver;
|
||||
struct counter *delivered; /* MT SMS deliveries */
|
||||
struct counter *rp_err_mem;
|
||||
struct counter *rp_err_other;
|
||||
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 counter *mo_setup;
|
||||
struct counter *mo_connect_ack;
|
||||
struct counter *mt_setup;
|
||||
struct counter *mt_connect;
|
||||
struct osmo_counter *mo_setup;
|
||||
struct osmo_counter *mo_connect_ack;
|
||||
struct osmo_counter *mt_setup;
|
||||
struct osmo_counter *mt_connect;
|
||||
} call;
|
||||
struct {
|
||||
struct counter *rf_fail;
|
||||
struct counter *rll_err;
|
||||
struct osmo_counter *rf_fail;
|
||||
struct osmo_counter *rll_err;
|
||||
} chan;
|
||||
struct {
|
||||
struct counter *oml_fail;
|
||||
struct counter *rsl_fail;
|
||||
struct osmo_counter *oml_fail;
|
||||
struct osmo_counter *rsl_fail;
|
||||
} bts;
|
||||
};
|
||||
|
||||
@@ -695,8 +218,8 @@ enum gsm_auth_policy {
|
||||
|
||||
struct gsm_network {
|
||||
/* global parameters */
|
||||
u_int16_t country_code;
|
||||
u_int16_t network_code;
|
||||
uint16_t country_code;
|
||||
uint16_t network_code;
|
||||
char *name_long;
|
||||
char *name_short;
|
||||
enum gsm_auth_policy auth_policy;
|
||||
@@ -776,50 +299,32 @@ struct gsm_sms {
|
||||
struct gsm_subscriber *receiver;
|
||||
|
||||
unsigned long validity_minutes;
|
||||
u_int8_t reply_path_req;
|
||||
u_int8_t status_rep_req;
|
||||
u_int8_t ud_hdr_ind;
|
||||
u_int8_t protocol_id;
|
||||
u_int8_t data_coding_scheme;
|
||||
u_int8_t msg_ref;
|
||||
uint8_t reply_path_req;
|
||||
uint8_t status_rep_req;
|
||||
uint8_t ud_hdr_ind;
|
||||
uint8_t protocol_id;
|
||||
uint8_t data_coding_scheme;
|
||||
uint8_t msg_ref;
|
||||
char dest_addr[20+1]; /* DA LV is 12 bytes max, i.e. 10 bytes
|
||||
* BCD == 20 bytes string */
|
||||
u_int8_t user_data_len;
|
||||
u_int8_t user_data[SMS_TEXT_SIZE];
|
||||
uint8_t user_data_len;
|
||||
uint8_t user_data[SMS_TEXT_SIZE];
|
||||
|
||||
char text[SMS_TEXT_SIZE];
|
||||
};
|
||||
|
||||
|
||||
struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_code,
|
||||
struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code,
|
||||
int (*mncc_recv)(struct gsm_network *, struct msgb *));
|
||||
struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
|
||||
u_int8_t tsc, u_int8_t bsic);
|
||||
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
|
||||
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
|
||||
|
||||
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
|
||||
|
||||
/* Get reference to a neighbor cell on a given BCCH ARFCN */
|
||||
struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
|
||||
u_int16_t arfcn, u_int8_t bsic);
|
||||
uint16_t arfcn, uint8_t bsic);
|
||||
|
||||
struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num);
|
||||
|
||||
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(struct gsm_bts_trx *trx);
|
||||
char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
|
||||
char *gsm_lchan_name(struct gsm_lchan *lchan);
|
||||
const char *gsm_lchans_name(enum gsm_lchan_state s);
|
||||
|
||||
void set_ts_e1link(struct gsm_bts_trx_ts *ts, u_int8_t e1_nr,
|
||||
u_int8_t e1_ts, u_int8_t e1_ts_ss);
|
||||
enum gsm_bts_type parse_btstype(const char *arg);
|
||||
const char *btstype2str(enum gsm_bts_type type);
|
||||
struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
|
||||
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
|
||||
struct gsm_bts *start_bts);
|
||||
|
||||
@@ -849,7 +354,6 @@ static inline int is_siemens_bts(struct gsm_bts *bts)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
enum gsm_auth_policy gsm_auth_policy_parse(const char *arg);
|
||||
const char *gsm_auth_policy_name(enum gsm_auth_policy policy);
|
||||
|
||||
@@ -859,17 +363,27 @@ const char *rrlp_mode_name(enum rrlp_mode mode);
|
||||
enum bts_gprs_mode bts_gprs_mode_parse(const char *arg);
|
||||
const char *bts_gprs_mode_name(enum bts_gprs_mode mode);
|
||||
|
||||
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
|
||||
|
||||
int gsm48_ra_id_by_bts(u_int8_t *buf, struct gsm_bts *bts);
|
||||
int gsm48_ra_id_by_bts(uint8_t *buf, struct gsm_bts *bts);
|
||||
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
|
||||
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
|
||||
|
||||
int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat);
|
||||
int gsm_bts_has_feature(struct gsm_bts *bts, enum gsm_bts_features feat);
|
||||
int gsm_bts_model_register(struct gsm_bts_model *model);
|
||||
|
||||
struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan);
|
||||
void subscr_con_free(struct gsm_subscriber_connection *conn);
|
||||
|
||||
#endif
|
||||
struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net,
|
||||
enum gsm_bts_type type,
|
||||
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);
|
||||
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);
|
||||
|
||||
/* generic E1 line operations for all ISDN-based BTS. */
|
||||
extern struct e1inp_line_ops bts_isdn_e1inp_line_ops;
|
||||
|
||||
#endif /* _GSM_DATA_H */
|
||||
|
||||
591
openbsc/include/openbsc/gsm_data_shared.h
Normal file
591
openbsc/include/openbsc/gsm_data_shared.h
Normal file
@@ -0,0 +1,591 @@
|
||||
#ifndef _GSM_DATA_SHAREDH
|
||||
#define _GSM_DATA_SHAREDH
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/bitvec.h>
|
||||
#include <osmocom/core/statistics.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
#include <osmocom/gsm/rxlev_stat.h>
|
||||
#include <osmocom/gsm/sysinfo.h>
|
||||
|
||||
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
||||
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||
|
||||
struct osmo_msc_data;
|
||||
struct osmo_bsc_sccp_con;
|
||||
struct gsm_sms_queue;
|
||||
|
||||
/* RRLP mode of operation */
|
||||
enum rrlp_mode {
|
||||
RRLP_MODE_NONE,
|
||||
RRLP_MODE_MS_BASED,
|
||||
RRLP_MODE_MS_PREF,
|
||||
RRLP_MODE_ASS_PREF,
|
||||
};
|
||||
|
||||
/* Channel Request reason */
|
||||
enum gsm_chreq_reason_t {
|
||||
GSM_CHREQ_REASON_EMERG,
|
||||
GSM_CHREQ_REASON_PAG,
|
||||
GSM_CHREQ_REASON_CALL,
|
||||
GSM_CHREQ_REASON_LOCATION_UPD,
|
||||
GSM_CHREQ_REASON_OTHER,
|
||||
};
|
||||
|
||||
#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 */
|
||||
#define HARDCODED_BTS0_TS 1
|
||||
#define HARDCODED_BTS1_TS 6
|
||||
#define HARDCODED_BTS2_TS 11
|
||||
|
||||
/* reserved according to GSM 03.03 § 2.4 */
|
||||
#define GSM_RESERVED_TMSI 0xFFFFFFFF
|
||||
|
||||
enum gsm_hooks {
|
||||
GSM_HOOK_NM_SWLOAD,
|
||||
GSM_HOOK_RR_PAGING,
|
||||
GSM_HOOK_RR_SECURITY,
|
||||
};
|
||||
|
||||
enum gsm_paging_event {
|
||||
GSM_PAGING_SUCCEEDED,
|
||||
GSM_PAGING_EXPIRED,
|
||||
GSM_PAGING_OOM,
|
||||
GSM_PAGING_BUSY,
|
||||
};
|
||||
|
||||
enum bts_gprs_mode {
|
||||
BTS_GPRS_NONE = 0,
|
||||
BTS_GPRS_GPRS = 1,
|
||||
BTS_GPRS_EGPRS = 2,
|
||||
};
|
||||
|
||||
struct gsm_lchan;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_mncc;
|
||||
struct rtp_socket;
|
||||
struct bsc_api;
|
||||
|
||||
/* Network Management State */
|
||||
struct gsm_nm_state {
|
||||
uint8_t operational;
|
||||
uint8_t administrative;
|
||||
uint8_t availability;
|
||||
};
|
||||
|
||||
struct gsm_abis_mo {
|
||||
uint8_t obj_class;
|
||||
struct abis_om_obj_inst obj_inst;
|
||||
const char *name;
|
||||
struct gsm_nm_state nm_state;
|
||||
struct tlv_parsed *nm_attr;
|
||||
struct gsm_bts *bts;
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
/* is the data link established? who established it? */
|
||||
#define LCHAN_SAPI_UNUSED 0
|
||||
#define LCHAN_SAPI_MS 1
|
||||
#define LCHAN_SAPI_NET 2
|
||||
|
||||
/* state of a logical channel */
|
||||
enum gsm_lchan_state {
|
||||
LCHAN_S_NONE, /* channel is not active */
|
||||
LCHAN_S_ACT_REQ, /* channel activatin requested */
|
||||
LCHAN_S_ACTIVE, /* channel is active and operational */
|
||||
LCHAN_S_REL_REQ, /* channel release has been requested */
|
||||
LCHAN_S_REL_ERR, /* channel is in an error state */
|
||||
LCHAN_S_INACTIVE, /* channel is set inactive */
|
||||
};
|
||||
|
||||
/* BTS ONLY */
|
||||
#define MAX_NUM_UL_MEAS 104
|
||||
#define LC_UL_M_F_L1_VALID (1 << 0)
|
||||
#define LC_UL_M_F_RES_VALID (1 << 1)
|
||||
|
||||
struct bts_ul_meas {
|
||||
/* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */
|
||||
uint16_t ber10k;
|
||||
/* timing advance offset (in quarter bits) */
|
||||
int16_t ta_offs_qbits;
|
||||
/* C/I ratio in dB */
|
||||
float c_i;
|
||||
/* flags */
|
||||
uint8_t is_sub:1;
|
||||
/* RSSI in dBm * -1 */
|
||||
uint8_t inv_rssi;
|
||||
};
|
||||
/* /BTS ONLY */
|
||||
|
||||
struct gsm_lchan {
|
||||
/* The TS that we're part of */
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
/* The logical subslot number in the TS */
|
||||
uint8_t nr;
|
||||
/* The logical channel type */
|
||||
enum gsm_chan_t type;
|
||||
/* RSL channel mode */
|
||||
enum rsl_cmod_spd rsl_cmode;
|
||||
/* If TCH, traffic channel mode */
|
||||
enum gsm48_chan_mode tch_mode;
|
||||
/* State */
|
||||
enum gsm_lchan_state state;
|
||||
/* Power levels for MS and BTS */
|
||||
uint8_t bs_power;
|
||||
uint8_t ms_power;
|
||||
/* Encryption information */
|
||||
struct {
|
||||
uint8_t alg_id;
|
||||
uint8_t key_len;
|
||||
uint8_t key[MAX_A5_KEY_LEN];
|
||||
} encr;
|
||||
|
||||
/* AMR bits */
|
||||
struct gsm48_multi_rate_conf mr_conf;
|
||||
|
||||
/* Established data link layer services */
|
||||
uint8_t sapis[8];
|
||||
int sach_deact;
|
||||
int release_reason;
|
||||
|
||||
struct {
|
||||
uint32_t bound_ip;
|
||||
uint32_t connect_ip;
|
||||
uint16_t bound_port;
|
||||
uint16_t connect_port;
|
||||
uint16_t conn_id;
|
||||
uint8_t rtp_payload;
|
||||
uint8_t rtp_payload2;
|
||||
uint8_t speech_mode;
|
||||
struct rtp_socket *rtp_socket;
|
||||
} abis_ip;
|
||||
|
||||
uint8_t rqd_ta;
|
||||
|
||||
#ifdef ROLE_BSC
|
||||
struct osmo_timer_list T3101;
|
||||
struct osmo_timer_list T3111;
|
||||
struct osmo_timer_list error_timer;
|
||||
struct osmo_timer_list act_timer;
|
||||
|
||||
/* table of neighbor cell measurements */
|
||||
struct neigh_meas_proc neigh_meas[MAX_NEIGH_MEAS];
|
||||
|
||||
/* cache of last measurement reports on this lchan */
|
||||
struct gsm_meas_rep meas_rep[6];
|
||||
int meas_rep_idx;
|
||||
|
||||
/* GSM Random Access data */
|
||||
struct gsm48_req_ref *rqd_ref;
|
||||
|
||||
struct gsm_subscriber_connection *conn;
|
||||
#else
|
||||
struct lapdm_channel lapdm_ch;
|
||||
struct {
|
||||
/* 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 */
|
||||
sysinfo_buf_t buf[_MAX_SYSINFO_TYPE];
|
||||
} si;
|
||||
struct {
|
||||
uint8_t flags;
|
||||
/* RSL measurment result number, 0 at lchan_act */
|
||||
uint8_t res_nr;
|
||||
/* current Tx power level of the BTS */
|
||||
uint8_t bts_tx_pwr;
|
||||
/* number of measurements stored in array below */
|
||||
uint8_t num_ul_meas;
|
||||
struct bts_ul_meas uplink[MAX_NUM_UL_MEAS];
|
||||
/* last L1 header from the MS */
|
||||
uint8_t l1_info[2];
|
||||
struct {
|
||||
uint8_t rxlev_full;
|
||||
uint8_t rxlev_sub;
|
||||
uint8_t rxqual_full;
|
||||
uint8_t rxqual_sub;
|
||||
} res;
|
||||
} meas;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define TS_F_PDCH_MODE 0x1000
|
||||
/* One Timeslot in a TRX */
|
||||
struct gsm_bts_trx_ts {
|
||||
struct gsm_bts_trx *trx;
|
||||
/* number of this timeslot at the TRX */
|
||||
uint8_t nr;
|
||||
|
||||
enum gsm_phys_chan_config pchan;
|
||||
|
||||
unsigned int flags;
|
||||
struct gsm_abis_mo mo;
|
||||
struct tlv_parsed nm_attr;
|
||||
uint8_t nm_chan_comb;
|
||||
int tsc; /* -1 == use BTS TSC */
|
||||
|
||||
struct {
|
||||
/* Parameters below are configured by VTY */
|
||||
int enabled;
|
||||
uint8_t maio;
|
||||
uint8_t hsn;
|
||||
struct bitvec arfcns;
|
||||
uint8_t arfcns_data[1024/8];
|
||||
/* This is the pre-computed MA for channel assignments */
|
||||
struct bitvec ma;
|
||||
uint8_t ma_len; /* part of ma_data that is used */
|
||||
uint8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */
|
||||
} hopping;
|
||||
|
||||
/* To which E1 subslot are we connected */
|
||||
struct gsm_e1_subslot e1_link;
|
||||
|
||||
struct gsm_lchan lchan[TS_MAX_LCHAN];
|
||||
};
|
||||
|
||||
/* One TRX in a BTS */
|
||||
struct gsm_bts_trx {
|
||||
/* list header in bts->trx_list */
|
||||
struct llist_head list;
|
||||
|
||||
struct gsm_bts *bts;
|
||||
/* number of this TRX in the BTS */
|
||||
uint8_t nr;
|
||||
/* human readable name / description */
|
||||
char *description;
|
||||
/* how do we talk RSL with this TRX? */
|
||||
struct gsm_e1_subslot rsl_e1_link;
|
||||
uint8_t rsl_tei;
|
||||
struct e1inp_sign_link *rsl_link;
|
||||
/* Some BTS (specifically Ericsson RBS) have a per-TRX OML Link */
|
||||
struct e1inp_sign_link *oml_link;
|
||||
|
||||
struct gsm_abis_mo mo;
|
||||
struct tlv_parsed nm_attr;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
} bb_transc;
|
||||
|
||||
uint16_t arfcn;
|
||||
int nominal_power; /* in dBm */
|
||||
unsigned int max_power_red; /* in actual dB */
|
||||
|
||||
struct {
|
||||
void *l1h;
|
||||
} role_bts;
|
||||
|
||||
union {
|
||||
struct {
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
} bbsig;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
} pa;
|
||||
} bs11;
|
||||
struct {
|
||||
unsigned int test_state;
|
||||
uint8_t test_nr;
|
||||
struct rxlev_stats rxlev_stat;
|
||||
} ipaccess;
|
||||
};
|
||||
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
||||
};
|
||||
|
||||
#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i])
|
||||
|
||||
enum gsm_bts_type {
|
||||
GSM_BTS_TYPE_UNKNOWN,
|
||||
GSM_BTS_TYPE_BS11,
|
||||
GSM_BTS_TYPE_NANOBTS,
|
||||
GSM_BTS_TYPE_RBS2000,
|
||||
GSM_BTS_TYPE_HSL_FEMTO,
|
||||
GSM_BTS_TYPE_NOKIA_SITE,
|
||||
};
|
||||
|
||||
struct vty;
|
||||
|
||||
struct gsm_bts_model {
|
||||
struct llist_head list;
|
||||
|
||||
enum gsm_bts_type type;
|
||||
const char *name;
|
||||
|
||||
bool started;
|
||||
int (*start)(struct gsm_network *net);
|
||||
int (*oml_rcvmsg)(struct msgb *msg);
|
||||
|
||||
void (*e1line_bind_ops)(struct e1inp_line *line);
|
||||
|
||||
void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);
|
||||
void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);
|
||||
void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts);
|
||||
|
||||
struct tlv_definition nm_att_tlvdef;
|
||||
|
||||
struct bitvec features;
|
||||
uint8_t _features_data[128/8];
|
||||
};
|
||||
|
||||
enum gsm_bts_features {
|
||||
BTS_FEAT_HSCSD,
|
||||
BTS_FEAT_GPRS,
|
||||
BTS_FEAT_EGPRS,
|
||||
BTS_FEAT_ECSD,
|
||||
BTS_FEAT_HOPPING,
|
||||
};
|
||||
|
||||
/*
|
||||
* This keeps track of the paging status of one BTS. It
|
||||
* includes a number of pending requests, a back pointer
|
||||
* to the gsm_bts, a timer and some more state.
|
||||
*/
|
||||
struct gsm_bts_paging_state {
|
||||
/* pending requests */
|
||||
struct llist_head pending_requests;
|
||||
struct gsm_bts *bts;
|
||||
|
||||
struct osmo_timer_list work_timer;
|
||||
struct osmo_timer_list credit_timer;
|
||||
|
||||
/* free chans needed */
|
||||
int free_chans_need;
|
||||
|
||||
/* load */
|
||||
uint16_t available_slots;
|
||||
};
|
||||
|
||||
struct gsm_envabtse {
|
||||
struct gsm_abis_mo mo;
|
||||
};
|
||||
|
||||
struct gsm_bts_gprs_nsvc {
|
||||
struct gsm_bts *bts;
|
||||
/* data read via VTY config file, to configure the BTS
|
||||
* via OML from BSC */
|
||||
int id;
|
||||
uint16_t nsvci;
|
||||
uint16_t local_port; /* on the BTS */
|
||||
uint16_t remote_port; /* on the SGSN */
|
||||
uint32_t remote_ip; /* on the SGSN */
|
||||
|
||||
struct gsm_abis_mo mo;
|
||||
};
|
||||
|
||||
enum neigh_list_manual_mode {
|
||||
NL_MODE_AUTOMATIC = 0,
|
||||
NL_MODE_MANUAL = 1,
|
||||
NL_MODE_MANUAL_SI5SEP = 2, /* SI2 and SI5 have separate neighbor lists */
|
||||
};
|
||||
|
||||
/* One BTS */
|
||||
struct gsm_bts {
|
||||
/* list header in net->bts_list */
|
||||
struct llist_head list;
|
||||
|
||||
/* number of ths BTS in network */
|
||||
uint8_t nr;
|
||||
/* human readable name / description */
|
||||
char *description;
|
||||
/* Cell Identity */
|
||||
uint16_t cell_identity;
|
||||
/* location area code of this BTS */
|
||||
uint16_t location_area_code;
|
||||
/* Training Sequence Code */
|
||||
uint8_t tsc;
|
||||
/* Base Station Identification Code (BSIC) */
|
||||
uint8_t bsic;
|
||||
/* type of BTS */
|
||||
enum gsm_bts_type type;
|
||||
struct gsm_bts_model *model;
|
||||
enum gsm_band band;
|
||||
/* maximum Tx power that the MS is permitted to use in this cell */
|
||||
int ms_max_power;
|
||||
|
||||
/* how do we talk OML with this TRX? */
|
||||
struct gsm_e1_subslot oml_e1_link;
|
||||
uint8_t oml_tei;
|
||||
struct e1inp_sign_link *oml_link;
|
||||
|
||||
/* Abis network management O&M handle */
|
||||
struct abis_nm_h *nmh;
|
||||
|
||||
struct gsm_abis_mo mo;
|
||||
|
||||
/* number of this BTS on given E1 link */
|
||||
uint8_t bts_nr;
|
||||
|
||||
/* paging state and control */
|
||||
struct gsm_bts_paging_state paging;
|
||||
|
||||
/* CCCH is on C0 */
|
||||
struct gsm_bts_trx *c0;
|
||||
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
} site_mgr;
|
||||
|
||||
/* bitmask of all SI that are present/valid in si_buf */
|
||||
uint32_t si_valid;
|
||||
/* buffers where we put the pre-computed SI */
|
||||
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
|
||||
|
||||
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
|
||||
union {
|
||||
struct {
|
||||
uint16_t site_id;
|
||||
uint16_t bts_id;
|
||||
uint32_t flags;
|
||||
} ip_access;
|
||||
struct {
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
} cclk;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
} rack;
|
||||
struct gsm_envabtse envabtse[4];
|
||||
} bs11;
|
||||
struct {
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
struct llist_head conn_groups;
|
||||
} is;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
struct llist_head conn_groups;
|
||||
} con;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
} dp;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
} tf;
|
||||
} rbs2000;
|
||||
struct {
|
||||
unsigned long serno;
|
||||
} hsl;
|
||||
struct {
|
||||
uint8_t bts_type;
|
||||
int configured:1,
|
||||
do_reset:1,
|
||||
wait_reset:1;
|
||||
struct osmo_timer_list reset_timer;
|
||||
} nokia;
|
||||
};
|
||||
|
||||
/* Not entirely sure how ip.access specific this is */
|
||||
struct {
|
||||
enum bts_gprs_mode mode;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
uint16_t nsei;
|
||||
uint8_t timer[7];
|
||||
} nse;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
uint16_t bvci;
|
||||
uint8_t timer[11];
|
||||
} cell;
|
||||
struct gsm_bts_gprs_nsvc nsvc[2];
|
||||
uint8_t rac;
|
||||
} gprs;
|
||||
|
||||
/* RACH NM values */
|
||||
int rach_b_thresh;
|
||||
int rach_ldavg_slots;
|
||||
|
||||
/* transceivers */
|
||||
int num_trx;
|
||||
struct llist_head trx_list;
|
||||
|
||||
#ifdef ROLE_BSC
|
||||
/* Abis NM queue */
|
||||
struct llist_head abis_queue;
|
||||
int abis_nm_pend;
|
||||
|
||||
struct gsm_network *network;
|
||||
|
||||
/* should the channel allocator allocate channels from high TRX to TRX0,
|
||||
* rather than starting from TRX0 and go upwards? */
|
||||
int chan_alloc_reverse;
|
||||
|
||||
enum neigh_list_manual_mode neigh_list_manual_mode;
|
||||
/* parameters from which we build SYSTEM INFORMATION */
|
||||
struct {
|
||||
struct gsm48_rach_control rach_control;
|
||||
uint8_t ncc_permitted;
|
||||
struct gsm48_cell_sel_par cell_sel_par;
|
||||
struct gsm48_si_selection_params cell_ro_sel_par; /* rest octet */
|
||||
struct gsm48_cell_options cell_options;
|
||||
struct gsm48_control_channel_descr chan_desc;
|
||||
struct bitvec neigh_list;
|
||||
struct bitvec cell_alloc;
|
||||
struct bitvec si5_neigh_list;
|
||||
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];
|
||||
} data;
|
||||
} si_common;
|
||||
|
||||
/* do we use static (user-defined) system information messages? (bitmask) */
|
||||
uint32_t si_mode_static;
|
||||
#endif /* ROLE_BSC */
|
||||
void *role;
|
||||
};
|
||||
|
||||
|
||||
struct gsm_bts *gsm_bts_alloc(void *talloc_ctx);
|
||||
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
|
||||
|
||||
struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num);
|
||||
|
||||
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(struct gsm_bts_trx *trx);
|
||||
char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
|
||||
char *gsm_lchan_name(struct gsm_lchan *lchan);
|
||||
const char *gsm_lchans_name(enum gsm_lchan_state s);
|
||||
|
||||
|
||||
void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
|
||||
|
||||
struct gsm_abis_mo *
|
||||
gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
|
||||
struct abis_om_obj_inst *obj_inst);
|
||||
|
||||
struct gsm_nm_state *
|
||||
gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
|
||||
struct abis_om_obj_inst *obj_inst);
|
||||
void *
|
||||
gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
|
||||
struct abis_om_obj_inst *obj_inst);
|
||||
|
||||
/* reset the state of all MO in the BTS */
|
||||
void gsm_bts_mo_reset(struct gsm_bts *bts);
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,8 @@
|
||||
#ifndef _GSM_SUBSCR_H
|
||||
#define _GSM_SUBSCR_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "gsm_data.h"
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
#define GSM_IMEI_LENGTH 17
|
||||
#define GSM_IMSI_LENGTH 17
|
||||
@@ -24,24 +23,24 @@ struct gsm_equipment {
|
||||
char name[GSM_NAME_LENGTH];
|
||||
|
||||
struct gsm48_classmark1 classmark1;
|
||||
u_int8_t classmark2_len;
|
||||
u_int8_t classmark2[3];
|
||||
u_int8_t classmark3_len;
|
||||
u_int8_t classmark3[14];
|
||||
uint8_t classmark2_len;
|
||||
uint8_t classmark2[3];
|
||||
uint8_t classmark3_len;
|
||||
uint8_t classmark3[14];
|
||||
};
|
||||
|
||||
struct gsm_subscriber {
|
||||
struct gsm_network *net;
|
||||
long long unsigned int id;
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
u_int32_t tmsi;
|
||||
u_int16_t lac;
|
||||
uint32_t tmsi;
|
||||
uint16_t lac;
|
||||
char name[GSM_NAME_LENGTH];
|
||||
char extension[GSM_EXTENSION_LENGTH];
|
||||
int authorized;
|
||||
|
||||
/* Temporary field which is not stored in the DB/HLR */
|
||||
u_int32_t flags;
|
||||
uint32_t flags;
|
||||
|
||||
/* Every user can only have one equipment in use at any given
|
||||
* point in time */
|
||||
@@ -72,7 +71,7 @@ enum gsm_subscriber_update_reason {
|
||||
struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_network *net,
|
||||
u_int32_t tmsi);
|
||||
uint32_t tmsi);
|
||||
struct gsm_subscriber *subscr_get_by_imsi(struct gsm_network *net,
|
||||
const char *imsi);
|
||||
struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net,
|
||||
|
||||
@@ -1,58 +1,10 @@
|
||||
#ifndef _IPACCESS_H
|
||||
#define _IPACCESS_H
|
||||
|
||||
#include "e1_input.h"
|
||||
#include <osmocom/abis/e1_input.h>
|
||||
#include "gsm_subscriber.h"
|
||||
#include <osmocore/linuxlist.h>
|
||||
|
||||
#define IPA_TCP_PORT_OML 3002
|
||||
#define IPA_TCP_PORT_RSL 3003
|
||||
|
||||
struct ipaccess_head {
|
||||
u_int16_t len; /* network byte order */
|
||||
u_int8_t proto;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ipaccess_head_ext {
|
||||
uint8_t proto;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum ipaccess_proto {
|
||||
IPAC_PROTO_RSL = 0x00,
|
||||
IPAC_PROTO_IPACCESS = 0xfe,
|
||||
IPAC_PROTO_SCCP = 0xfd,
|
||||
IPAC_PROTO_OML = 0xff,
|
||||
|
||||
|
||||
/* OpenBSC extensions */
|
||||
IPAC_PROTO_OSMO = 0xee,
|
||||
IPAC_PROTO_MGCP_OLD = 0xfc,
|
||||
};
|
||||
|
||||
enum ipaccess_msgtype {
|
||||
IPAC_MSGT_PING = 0x00,
|
||||
IPAC_MSGT_PONG = 0x01,
|
||||
IPAC_MSGT_ID_GET = 0x04,
|
||||
IPAC_MSGT_ID_RESP = 0x05,
|
||||
IPAC_MSGT_ID_ACK = 0x06,
|
||||
|
||||
/* OpenBSC extension */
|
||||
IPAC_MSGT_SCCP_OLD = 0xff,
|
||||
};
|
||||
|
||||
enum ipaccess_id_tags {
|
||||
IPAC_IDTAG_SERNR = 0x00,
|
||||
IPAC_IDTAG_UNITNAME = 0x01,
|
||||
IPAC_IDTAG_LOCATION1 = 0x02,
|
||||
IPAC_IDTAG_LOCATION2 = 0x03,
|
||||
IPAC_IDTAG_EQUIPVERS = 0x04,
|
||||
IPAC_IDTAG_SWVERSION = 0x05,
|
||||
IPAC_IDTAG_IPADDR = 0x06,
|
||||
IPAC_IDTAG_MACADDR = 0x07,
|
||||
IPAC_IDTAG_UNIT = 0x08,
|
||||
};
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/protocol/ipaccess.h>
|
||||
|
||||
struct ipac_msgt_sccp_state {
|
||||
uint8_t src_ref[3];
|
||||
@@ -62,54 +14,35 @@ struct ipac_msgt_sccp_state {
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
} __attribute__((packed));
|
||||
|
||||
int ipaccess_connect(struct e1inp_line *line, struct sockaddr_in *sa);
|
||||
/*
|
||||
* @add_remove 0 for remove, 1 for add, 3 to asK
|
||||
* @nr_lacs Number of extra lacs inside this package
|
||||
* @lac One lac entry
|
||||
*/
|
||||
struct ipac_ext_lac_cmd {
|
||||
uint8_t add_remove;
|
||||
uint8_t nr_extra_lacs;
|
||||
uint16_t lac;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* methods for parsing and sending a message
|
||||
*/
|
||||
int ipaccess_rcvmsg_base(struct msgb *msg, struct bsc_fd *bfd);
|
||||
struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error);
|
||||
int ipaccess_rcvmsg_base(struct msgb *msg, struct osmo_fd *bfd);
|
||||
void ipaccess_prepend_header(struct msgb *msg, int proto);
|
||||
void ipaccess_prepend_header_ext(struct msgb *msg, int proto);
|
||||
int ipaccess_send_pong(int fd);
|
||||
int ipaccess_send_id_ack(int fd);
|
||||
int ipaccess_send_id_req(int fd);
|
||||
|
||||
const char *ipaccess_idtag_name(uint8_t tag);
|
||||
int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
|
||||
int ipaccess_parse_unitid(const char *str, uint16_t *site_id, uint16_t *bts_id, uint16_t *trx_id);
|
||||
|
||||
int ipaccess_drop_oml(struct gsm_bts *bts);
|
||||
int ipaccess_drop_rsl(struct gsm_bts_trx *trx);
|
||||
|
||||
/*
|
||||
* Firmware specific header
|
||||
*/
|
||||
struct sdp_firmware {
|
||||
char magic[4];
|
||||
char more_magic[2];
|
||||
u_int16_t more_more_magic;
|
||||
u_int32_t header_length;
|
||||
u_int32_t file_length;
|
||||
char sw_part[20];
|
||||
char text1[64];
|
||||
char time[12];
|
||||
char date[14];
|
||||
char text2[10];
|
||||
char version[20];
|
||||
u_int16_t table_offset;
|
||||
/* stuff i don't know */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sdp_header_entry {
|
||||
u_int16_t something1;
|
||||
char text1[64];
|
||||
char time[12];
|
||||
char date[14];
|
||||
char text2[10];
|
||||
char version[20];
|
||||
u_int32_t length;
|
||||
u_int32_t addr1;
|
||||
u_int32_t addr2;
|
||||
u_int32_t start;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sdp_header_item {
|
||||
struct sdp_header_entry header_entry;
|
||||
struct llist_head entry;
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
#ifndef _MEAS_REP_H
|
||||
#define _MEAS_REP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MRC_F_PROCESSED 0x0001
|
||||
|
||||
/* extracted from a L3 measurement report IE */
|
||||
struct gsm_meas_rep_cell {
|
||||
u_int8_t rxlev;
|
||||
u_int8_t bsic;
|
||||
u_int8_t neigh_idx;
|
||||
u_int16_t arfcn;
|
||||
uint8_t rxlev;
|
||||
uint8_t bsic;
|
||||
uint8_t neigh_idx;
|
||||
uint16_t arfcn;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
/* RX Level and RX Quality */
|
||||
struct gsm_rx_lev_qual {
|
||||
u_int8_t rx_lev;
|
||||
u_int8_t rx_qual;
|
||||
uint8_t rx_lev;
|
||||
uint8_t rx_qual;
|
||||
};
|
||||
|
||||
/* unidirectional measumrement report */
|
||||
@@ -38,7 +40,7 @@ struct gsm_meas_rep {
|
||||
struct gsm_lchan *lchan;
|
||||
|
||||
/* number of the measurement report */
|
||||
u_int8_t nr;
|
||||
uint8_t nr;
|
||||
/* flags, see MEAS_REP_F_* */
|
||||
unsigned int flags;
|
||||
|
||||
@@ -46,11 +48,11 @@ struct gsm_meas_rep {
|
||||
struct gsm_meas_rep_unidir ul;
|
||||
struct gsm_meas_rep_unidir dl;
|
||||
|
||||
u_int8_t bs_power;
|
||||
u_int8_t ms_timing_offset;
|
||||
uint8_t bs_power;
|
||||
uint8_t ms_timing_offset;
|
||||
struct {
|
||||
int8_t pwr; /* MS power in dBm */
|
||||
u_int8_t ta; /* MS timing advance */
|
||||
uint8_t ta; /* MS timing advance */
|
||||
} ms_l1;
|
||||
|
||||
/* neighbor measurement reports for up to 6 cells */
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#ifndef OPENBSC_MGCP_H
|
||||
#define OPENBSC_MGCP_H
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/write_queue.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
@@ -82,7 +82,7 @@ struct mgcp_trunk_config;
|
||||
typedef int (*mgcp_realloc)(struct mgcp_trunk_config *cfg, int endpoint);
|
||||
typedef int (*mgcp_change)(struct mgcp_trunk_config *cfg, int endpoint, int state);
|
||||
typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int state, const char *transactio_id);
|
||||
typedef int (*mgcp_reset)(struct mgcp_config *cfg);
|
||||
typedef int (*mgcp_reset)(struct mgcp_trunk_config *cfg);
|
||||
|
||||
#define PORT_ALLOC_STATIC 0
|
||||
#define PORT_ALLOC_DYNAMIC 1
|
||||
@@ -135,7 +135,7 @@ struct mgcp_config {
|
||||
struct in_addr transcoder_in;
|
||||
int transcoder_remote_base;
|
||||
|
||||
struct write_queue gw_fd;
|
||||
struct osmo_wqueue gw_fd;
|
||||
|
||||
struct mgcp_port_range bts_ports;
|
||||
struct mgcp_port_range net_ports;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#ifndef OPENBSC_MGCP_DATA_H
|
||||
#define OPENBSC_MGCP_DATA_H
|
||||
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocom/core/select.h>
|
||||
|
||||
#define CI_UNUSED 0
|
||||
|
||||
@@ -66,8 +66,8 @@ struct mgcp_rtp_end {
|
||||
/*
|
||||
* Each end has a socket...
|
||||
*/
|
||||
struct bsc_fd rtp;
|
||||
struct bsc_fd rtcp;
|
||||
struct osmo_fd rtp;
|
||||
struct osmo_fd rtcp;
|
||||
|
||||
int local_port;
|
||||
int local_alloc;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifndef MISDN_H
|
||||
#define MISDN_H
|
||||
|
||||
#include "e1_input.h"
|
||||
#include <osmocom/abis/e1_input.h>
|
||||
|
||||
int mi_setup(int cardnr, struct e1inp_line *line, int release_l2);
|
||||
int mi_e1_line_update(struct e1inp_line *line);
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#ifndef _MNCC_H
|
||||
#define _MNCC_H
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/mncc.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/mncc.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ struct osmo_bsc_sccp_con {
|
||||
/* SCCP connection realted */
|
||||
struct sccp_connection *sccp;
|
||||
struct bsc_msc_connection *msc_con;
|
||||
struct timer_list sccp_it_timeout;
|
||||
struct timer_list sccp_cc_timeout;
|
||||
struct osmo_timer_list sccp_it_timeout;
|
||||
struct osmo_timer_list sccp_cc_timeout;
|
||||
|
||||
struct llist_head sccp_queue;
|
||||
unsigned int sccp_queue_size;
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
#ifndef OSMO_BSC_RF
|
||||
#define OSMO_BSC_RF
|
||||
|
||||
#include <osmocore/write_queue.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
struct gsm_network;
|
||||
|
||||
struct osmo_bsc_rf {
|
||||
/* the value of signal.h */
|
||||
int policy;
|
||||
struct bsc_fd listen;
|
||||
struct osmo_fd listen;
|
||||
struct gsm_network *gsm_network;
|
||||
|
||||
const char *last_state_command;
|
||||
|
||||
/* delay the command */
|
||||
char last_request;
|
||||
struct timer_list delay_cmd;
|
||||
struct osmo_timer_list delay_cmd;
|
||||
|
||||
/* verify that RF is up as it should be */
|
||||
struct timer_list rf_check;
|
||||
struct osmo_timer_list rf_check;
|
||||
|
||||
/* some handling for the automatic grace switch */
|
||||
struct timer_list grace_timeout;
|
||||
struct osmo_timer_list grace_timeout;
|
||||
};
|
||||
|
||||
struct osmo_bsc_rf_conn {
|
||||
struct write_queue queue;
|
||||
struct osmo_wqueue queue;
|
||||
struct osmo_bsc_rf *rf;
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "bsc_msc.h"
|
||||
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
struct osmo_bsc_rf;
|
||||
struct gsm_network;
|
||||
@@ -36,15 +36,15 @@ struct gsm_audio_support {
|
||||
};
|
||||
|
||||
struct osmo_msc_data {
|
||||
/* Back pointer */
|
||||
struct gsm_network *network;
|
||||
|
||||
/* Connection data */
|
||||
char *bsc_token;
|
||||
int msc_port;
|
||||
int msc_ip_dscp;
|
||||
char *msc_ip;
|
||||
int ping_timeout;
|
||||
int pong_timeout;
|
||||
struct timer_list ping_timer;
|
||||
struct timer_list pong_timer;
|
||||
struct osmo_timer_list ping_timer;
|
||||
struct osmo_timer_list pong_timer;
|
||||
struct bsc_msc_connection *msc_con;
|
||||
int core_ncc;
|
||||
int core_mcc;
|
||||
@@ -54,14 +54,18 @@ struct osmo_msc_data {
|
||||
struct gsm_audio_support **audio_support;
|
||||
int audio_length;
|
||||
|
||||
/* destinations */
|
||||
struct llist_head dests;
|
||||
|
||||
|
||||
/* mgcp agent */
|
||||
struct write_queue mgcp_agent;
|
||||
struct osmo_wqueue mgcp_agent;
|
||||
|
||||
/* rf ctl related bits */
|
||||
char *mid_call_txt;
|
||||
int mid_call_timeout;
|
||||
struct osmo_bsc_rf *rf_ctl;
|
||||
char *rf_ctrl_name;
|
||||
struct osmo_bsc_rf *rf_ctrl;
|
||||
|
||||
/* ussd welcome text */
|
||||
char *ussd_welcome_txt;
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include "gsm_data.h"
|
||||
#include "gsm_subscriber.h"
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
/**
|
||||
* A pending paging request
|
||||
@@ -43,7 +43,7 @@ struct gsm_paging_request {
|
||||
int chan_type;
|
||||
|
||||
/* Timer 3113: how long do we try to page? */
|
||||
struct timer_list T3113;
|
||||
struct osmo_timer_list T3113;
|
||||
|
||||
/* How often did we ask the BTS to page? */
|
||||
int attempts;
|
||||
@@ -53,9 +53,6 @@ struct gsm_paging_request {
|
||||
void *cbfn_param;
|
||||
};
|
||||
|
||||
/* call once for every gsm_bts... */
|
||||
void paging_init(struct gsm_bts *bts);
|
||||
|
||||
/* schedule paging request */
|
||||
int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *data);
|
||||
@@ -66,6 +63,11 @@ void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr,
|
||||
struct msgb *msg);
|
||||
|
||||
/* update paging load */
|
||||
void paging_update_buffer_space(struct gsm_bts *bts, u_int16_t);
|
||||
void paging_update_buffer_space(struct gsm_bts *bts, uint16_t);
|
||||
|
||||
/* pending paging requests */
|
||||
unsigned int paging_pending_requests_nr(struct gsm_bts *bts);
|
||||
|
||||
void *paging_get_data(struct gsm_bts *bts, struct gsm_subscriber *subscr);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
#ifndef _REST_OCTETS_H
|
||||
#define _REST_OCTETS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
|
||||
/* generate SI1 rest octets */
|
||||
int rest_octets_si1(u_int8_t *data, u_int8_t *nch_pos);
|
||||
int rest_octets_si1(uint8_t *data, uint8_t *nch_pos);
|
||||
|
||||
struct gsm48_si_selection_params {
|
||||
u_int16_t penalty_time:5,
|
||||
uint16_t penalty_time:5,
|
||||
temp_offs:3,
|
||||
cell_resel_off:6,
|
||||
cbq:1,
|
||||
@@ -16,18 +15,18 @@ struct gsm48_si_selection_params {
|
||||
};
|
||||
|
||||
struct gsm48_si_power_offset {
|
||||
u_int8_t power_offset:2,
|
||||
uint8_t power_offset:2,
|
||||
present:1;
|
||||
};
|
||||
|
||||
struct gsm48_si3_gprs_ind {
|
||||
u_int8_t si13_position:1,
|
||||
uint8_t si13_position:1,
|
||||
ra_colour:3,
|
||||
present:1;
|
||||
};
|
||||
|
||||
struct gsm48_lsa_params {
|
||||
u_int32_t prio_thr:3,
|
||||
uint32_t prio_thr:3,
|
||||
lsa_offset:3,
|
||||
mcc:12,
|
||||
mnc:12;
|
||||
@@ -37,26 +36,26 @@ struct gsm48_lsa_params {
|
||||
struct gsm48_si_ro_info {
|
||||
struct gsm48_si_selection_params selection_params;
|
||||
struct gsm48_si_power_offset power_offset;
|
||||
u_int8_t si2ter_indicator;
|
||||
u_int8_t early_cm_ctrl;
|
||||
uint8_t si2ter_indicator;
|
||||
uint8_t early_cm_ctrl;
|
||||
struct {
|
||||
u_int8_t where:3,
|
||||
uint8_t where:3,
|
||||
present:1;
|
||||
} scheduling;
|
||||
struct gsm48_si3_gprs_ind gprs_ind;
|
||||
|
||||
/* SI 4 specific */
|
||||
struct gsm48_lsa_params lsa_params;
|
||||
u_int16_t cell_id;
|
||||
u_int8_t break_ind; /* do we have SI7 + SI8 ? */
|
||||
uint16_t cell_id;
|
||||
uint8_t break_ind; /* do we have SI7 + SI8 ? */
|
||||
};
|
||||
|
||||
|
||||
/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */
|
||||
int rest_octets_si3(u_int8_t *data, const struct gsm48_si_ro_info *si3);
|
||||
int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3);
|
||||
|
||||
/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
|
||||
int rest_octets_si4(u_int8_t *data, const struct gsm48_si_ro_info *si4);
|
||||
int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4);
|
||||
|
||||
enum pbcch_carrier_type {
|
||||
PBCCH_BCCH,
|
||||
@@ -75,59 +74,59 @@ enum gprs_nmo {
|
||||
struct gprs_cell_options {
|
||||
enum gprs_nmo nmo;
|
||||
/* T3168: wait for packet uplink assignment message */
|
||||
u_int32_t t3168; /* in milliseconds */
|
||||
uint32_t t3168; /* in milliseconds */
|
||||
/* T3192: wait for release of the TBF after reception of the final block */
|
||||
u_int32_t t3192; /* in milliseconds */
|
||||
u_int32_t drx_timer_max;/* in seconds */
|
||||
u_int32_t bs_cv_max;
|
||||
uint32_t t3192; /* in milliseconds */
|
||||
uint32_t drx_timer_max;/* in seconds */
|
||||
uint32_t bs_cv_max;
|
||||
|
||||
u_int8_t ext_info_present;
|
||||
uint8_t ext_info_present;
|
||||
struct {
|
||||
u_int8_t egprs_supported;
|
||||
u_int8_t use_egprs_p_ch_req;
|
||||
u_int8_t bep_period;
|
||||
u_int8_t pfc_supported;
|
||||
u_int8_t dtm_supported;
|
||||
u_int8_t bss_paging_coordination;
|
||||
uint8_t egprs_supported;
|
||||
uint8_t use_egprs_p_ch_req;
|
||||
uint8_t bep_period;
|
||||
uint8_t pfc_supported;
|
||||
uint8_t dtm_supported;
|
||||
uint8_t bss_paging_coordination;
|
||||
} ext_info;
|
||||
};
|
||||
|
||||
/* TS 04.60 Table 12.9.2 */
|
||||
struct gprs_power_ctrl_pars {
|
||||
u_int8_t alpha;
|
||||
u_int8_t t_avg_w;
|
||||
u_int8_t t_avg_t;
|
||||
u_int8_t pc_meas_chan;
|
||||
u_int8_t n_avg_i;
|
||||
uint8_t alpha;
|
||||
uint8_t t_avg_w;
|
||||
uint8_t t_avg_t;
|
||||
uint8_t pc_meas_chan;
|
||||
uint8_t n_avg_i;
|
||||
};
|
||||
|
||||
struct gsm48_si13_info {
|
||||
struct gprs_cell_options cell_opts;
|
||||
struct gprs_power_ctrl_pars pwr_ctrl_pars;
|
||||
u_int8_t bcch_change_mark;
|
||||
u_int8_t si_change_field;
|
||||
u_int8_t pbcch_present;
|
||||
uint8_t bcch_change_mark;
|
||||
uint8_t si_change_field;
|
||||
uint8_t pbcch_present;
|
||||
|
||||
union {
|
||||
struct {
|
||||
u_int8_t rac;
|
||||
u_int8_t spgc_ccch_sup;
|
||||
u_int8_t net_ctrl_ord;
|
||||
u_int8_t prio_acc_thr;
|
||||
uint8_t rac;
|
||||
uint8_t spgc_ccch_sup;
|
||||
uint8_t net_ctrl_ord;
|
||||
uint8_t prio_acc_thr;
|
||||
} no_pbcch;
|
||||
struct {
|
||||
u_int8_t psi1_rep_per;
|
||||
u_int8_t pb;
|
||||
u_int8_t tsc;
|
||||
u_int8_t tn;
|
||||
uint8_t psi1_rep_per;
|
||||
uint8_t pb;
|
||||
uint8_t tsc;
|
||||
uint8_t tn;
|
||||
enum pbcch_carrier_type carrier_type;
|
||||
u_int16_t arfcn;
|
||||
u_int8_t maio;
|
||||
uint16_t arfcn;
|
||||
uint8_t maio;
|
||||
} pbcch;
|
||||
};
|
||||
};
|
||||
|
||||
/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */
|
||||
int rest_octets_si13(u_int8_t *data, const struct gsm48_si13_info *si13);
|
||||
int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13);
|
||||
|
||||
#endif /* _REST_OCTETS_H */
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/select.h>
|
||||
|
||||
#include <openbsc/mncc.h>
|
||||
|
||||
#define RTP_PT_GSM_FULL 3
|
||||
#define RTP_PT_GSM_HALF 96
|
||||
@@ -48,7 +50,7 @@ struct rtp_sub_socket {
|
||||
struct sockaddr_in sin_local;
|
||||
struct sockaddr_in sin_remote;
|
||||
|
||||
struct bsc_fd bfd;
|
||||
struct osmo_fd bfd;
|
||||
/* linked list of to-be-transmitted msgb's */
|
||||
struct llist_head tx_queue;
|
||||
};
|
||||
@@ -67,23 +69,23 @@ struct rtp_socket {
|
||||
} proxy;
|
||||
struct {
|
||||
struct gsm_network *net;
|
||||
u_int32_t callref;
|
||||
uint32_t callref;
|
||||
} receive;
|
||||
};
|
||||
enum rtp_tx_action tx_action;
|
||||
struct {
|
||||
u_int16_t sequence;
|
||||
u_int32_t timestamp;
|
||||
u_int32_t ssrc;
|
||||
uint16_t sequence;
|
||||
uint32_t timestamp;
|
||||
uint32_t ssrc;
|
||||
struct timeval last_tv;
|
||||
} transmit;
|
||||
};
|
||||
|
||||
struct rtp_socket *rtp_socket_create(void);
|
||||
int rtp_socket_bind(struct rtp_socket *rs, u_int32_t ip);
|
||||
int rtp_socket_connect(struct rtp_socket *rs, u_int32_t ip, u_int16_t port);
|
||||
int rtp_socket_bind(struct rtp_socket *rs, uint32_t ip);
|
||||
int rtp_socket_connect(struct rtp_socket *rs, uint32_t ip, uint16_t port);
|
||||
int rtp_socket_proxy(struct rtp_socket *this, struct rtp_socket *other);
|
||||
int rtp_socket_upstream(struct rtp_socket *this, struct gsm_network *net, u_int32_t callref);
|
||||
int rtp_socket_upstream(struct rtp_socket *this, struct gsm_network *net, uint32_t callref);
|
||||
int rtp_socket_free(struct rtp_socket *rs);
|
||||
int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame);
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#ifndef _SGSN_H
|
||||
#define _SGSN_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
|
||||
#include <openbsc/gprs_ns.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
@@ -22,11 +21,11 @@ struct sgsn_instance {
|
||||
char *config_file;
|
||||
struct sgsn_config cfg;
|
||||
/* File descriptor wrappers for LibGTP */
|
||||
struct bsc_fd gtp_fd0;
|
||||
struct bsc_fd gtp_fd1c;
|
||||
struct bsc_fd gtp_fd1u;
|
||||
struct osmo_fd gtp_fd0;
|
||||
struct osmo_fd gtp_fd1c;
|
||||
struct osmo_fd gtp_fd1u;
|
||||
/* Timer for libGTP */
|
||||
struct timer_list gtp_timer;
|
||||
struct osmo_timer_list gtp_timer;
|
||||
/* GSN instance for libgtp */
|
||||
struct gsn_t *gsn;
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
#include <osmocore/signal.h>
|
||||
#include <osmocom/core/signal.h>
|
||||
|
||||
/*
|
||||
* Signalling subsystems
|
||||
@@ -40,14 +40,12 @@ enum signal_subsystems {
|
||||
SS_LCHAN,
|
||||
SS_SUBSCR,
|
||||
SS_SCALL,
|
||||
SS_GLOBAL,
|
||||
SS_CHALLOC,
|
||||
SS_NS,
|
||||
SS_IPAC_NWL,
|
||||
SS_RF,
|
||||
SS_MSC,
|
||||
SS_HO,
|
||||
SS_INPUT,
|
||||
};
|
||||
|
||||
/* SS_PAGING signals */
|
||||
@@ -84,6 +82,7 @@ enum signal_nm {
|
||||
S_NM_TEST_REP, /* GSM 12.21 Test Report */
|
||||
S_NM_STATECHG_OPER, /* Operational State changed*/
|
||||
S_NM_STATECHG_ADM, /* Administrative State changed */
|
||||
S_NM_OM2K_CONF_RES, /* OM2K Configuration Result */
|
||||
};
|
||||
|
||||
/* SS_LCHAN signals */
|
||||
@@ -128,7 +127,6 @@ enum signal_ipaccess {
|
||||
};
|
||||
|
||||
enum signal_global {
|
||||
S_GLOBAL_SHUTDOWN,
|
||||
S_GLOBAL_BTS_CLOSE_OM,
|
||||
};
|
||||
|
||||
@@ -139,16 +137,6 @@ enum signal_rf {
|
||||
S_RF_GRACE,
|
||||
};
|
||||
|
||||
/* SS_INPUT signals */
|
||||
enum signal_input {
|
||||
S_INP_NONE,
|
||||
S_INP_TEI_UP,
|
||||
S_INP_TEI_DN,
|
||||
S_INP_LINE_INIT,
|
||||
S_INP_LINE_ALARM,
|
||||
S_INP_LINE_NOALARM,
|
||||
};
|
||||
|
||||
struct gsm_subscriber;
|
||||
|
||||
struct paging_signal_data {
|
||||
@@ -169,15 +157,30 @@ struct scall_signal_data {
|
||||
|
||||
struct ipacc_ack_signal_data {
|
||||
struct gsm_bts_trx *trx;
|
||||
u_int8_t msg_type;
|
||||
uint8_t msg_type;
|
||||
};
|
||||
|
||||
struct abis_om2k_mo;
|
||||
|
||||
struct nm_statechg_signal_data {
|
||||
u_int8_t obj_class;
|
||||
struct gsm_bts *bts;
|
||||
uint8_t obj_class;
|
||||
void *obj;
|
||||
struct gsm_nm_state *old_state;
|
||||
struct gsm_nm_state *new_state;
|
||||
|
||||
/* This pointer is vaold for TS 12.21 MO */
|
||||
struct abis_om_obj_inst *obj_inst;
|
||||
/* This pointer is vaold for RBS2000 MO */
|
||||
struct abis_om2k_mo *om2k_mo;
|
||||
};
|
||||
|
||||
struct nm_om2k_signal_data {
|
||||
struct gsm_bts *bts;
|
||||
void *obj;
|
||||
struct abis_om2k_mo *om2k_mo;
|
||||
|
||||
uint8_t accordance_ind;
|
||||
};
|
||||
|
||||
struct nm_nack_signal_data {
|
||||
@@ -244,12 +247,4 @@ struct ho_signal_data {
|
||||
struct gsm_lchan *new_lchan;
|
||||
};
|
||||
|
||||
struct input_signal_data {
|
||||
int link_type;
|
||||
uint8_t tei;
|
||||
uint8_t sapi;
|
||||
struct gsm_bts_trx *trx;
|
||||
struct e1inp_line *line;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#ifndef _BSC_SOCKET_H
|
||||
#define _BSC_SOCKET_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocom/core/select.h>
|
||||
|
||||
#ifndef IPPROTO_GRE
|
||||
#define IPPROTO_GRE 47
|
||||
#endif
|
||||
|
||||
int make_sock(struct bsc_fd *bfd, int proto, u_int32_t ip, u_int16_t port,
|
||||
int (*cb)(struct bsc_fd *fd, unsigned int what));
|
||||
int make_sock(struct osmo_fd *bfd, int proto,
|
||||
uint32_t ip, uint16_t port, int priv_nr,
|
||||
int (*cb)(struct osmo_fd *fd, unsigned int what), void *data);
|
||||
|
||||
#endif /* _BSC_SOCKET_H */
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
#ifndef _SUBCH_DEMUX_H
|
||||
#define _SUBCH_DEMUX_H
|
||||
/* A E1 sub-channel (de)multiplexer with TRAU frame sync */
|
||||
|
||||
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
|
||||
#define NR_SUBCH 4
|
||||
#define TRAU_FRAME_SIZE 40
|
||||
#define TRAU_FRAME_BITS (TRAU_FRAME_SIZE*8)
|
||||
|
||||
/***********************************************************************/
|
||||
/* DEMULTIPLEXER */
|
||||
/***********************************************************************/
|
||||
|
||||
struct demux_subch {
|
||||
u_int8_t out_bitbuf[TRAU_FRAME_BITS];
|
||||
u_int16_t out_idx; /* next bit to be written in out_bitbuf */
|
||||
/* number of consecutive zeros that we have received (for sync) */
|
||||
unsigned int consecutive_zeros;
|
||||
/* are we in TRAU frame sync or not? */
|
||||
unsigned int in_sync;
|
||||
};
|
||||
|
||||
struct subch_demux {
|
||||
/* bitmask of currently active subchannels */
|
||||
u_int8_t chan_activ;
|
||||
/* one demux_subch struct for every subchannel */
|
||||
struct demux_subch subch[NR_SUBCH];
|
||||
/* callback to be called once we have received a complete
|
||||
* frame on a given subchannel */
|
||||
int (*out_cb)(struct subch_demux *dmx, int ch, u_int8_t *data, int len,
|
||||
void *);
|
||||
/* user-provided data, transparently passed to out_cb() */
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* initialize one demultiplexer instance */
|
||||
int subch_demux_init(struct subch_demux *dmx);
|
||||
|
||||
/* feed 'len' number of muxed bytes into the demultiplexer */
|
||||
int subch_demux_in(struct subch_demux *dmx, u_int8_t *data, int len);
|
||||
|
||||
/* activate decoding/processing for one subchannel */
|
||||
int subch_demux_activate(struct subch_demux *dmx, int subch);
|
||||
|
||||
/* deactivate decoding/processing for one subchannel */
|
||||
int subch_demux_deactivate(struct subch_demux *dmx, int subch);
|
||||
|
||||
/***********************************************************************/
|
||||
/* MULTIPLEXER */
|
||||
/***********************************************************************/
|
||||
|
||||
/* one element in the tx_queue of a muxer sub-channel */
|
||||
struct subch_txq_entry {
|
||||
struct llist_head list;
|
||||
|
||||
unsigned int bit_len; /* total number of bits in 'bits' */
|
||||
unsigned int next_bit; /* next bit to be transmitted */
|
||||
|
||||
u_int8_t bits[0]; /* one bit per byte */
|
||||
};
|
||||
|
||||
struct mux_subch {
|
||||
struct llist_head tx_queue;
|
||||
};
|
||||
|
||||
/* structure representing one instance of the subchannel muxer */
|
||||
struct subch_mux {
|
||||
struct mux_subch subch[NR_SUBCH];
|
||||
};
|
||||
|
||||
/* initialize a subchannel muxer instance */
|
||||
int subchan_mux_init(struct subch_mux *mx);
|
||||
|
||||
/* request the output of 'len' multiplexed bytes */
|
||||
int subchan_mux_out(struct subch_mux *mx, u_int8_t *data, int len);
|
||||
|
||||
/* enqueue some data into one sub-channel of the muxer */
|
||||
int subchan_mux_enqueue(struct subch_mux *mx, int s_nr, const u_int8_t *data,
|
||||
int len);
|
||||
|
||||
#endif /* _SUBCH_DEMUX_H */
|
||||
@@ -1,45 +1,10 @@
|
||||
#ifndef _SYSTEM_INFO_H
|
||||
#define _SYSTEM_INFO_H
|
||||
|
||||
#include <osmocore/utils.h>
|
||||
|
||||
#define GSM_MACBLOCK_LEN 23
|
||||
#include <osmocom/gsm/sysinfo.h>
|
||||
|
||||
struct gsm_bts;
|
||||
|
||||
|
||||
enum osmo_sysinfo_type {
|
||||
SYSINFO_TYPE_NONE,
|
||||
SYSINFO_TYPE_1,
|
||||
SYSINFO_TYPE_2,
|
||||
SYSINFO_TYPE_3,
|
||||
SYSINFO_TYPE_4,
|
||||
SYSINFO_TYPE_5,
|
||||
SYSINFO_TYPE_6,
|
||||
SYSINFO_TYPE_7,
|
||||
SYSINFO_TYPE_8,
|
||||
SYSINFO_TYPE_9,
|
||||
SYSINFO_TYPE_10,
|
||||
SYSINFO_TYPE_13,
|
||||
SYSINFO_TYPE_16,
|
||||
SYSINFO_TYPE_17,
|
||||
SYSINFO_TYPE_18,
|
||||
SYSINFO_TYPE_19,
|
||||
SYSINFO_TYPE_20,
|
||||
SYSINFO_TYPE_2bis,
|
||||
SYSINFO_TYPE_2ter,
|
||||
SYSINFO_TYPE_2quater,
|
||||
SYSINFO_TYPE_5bis,
|
||||
SYSINFO_TYPE_5ter,
|
||||
/* FIXME all the various bis and ter */
|
||||
_MAX_SYSINFO_TYPE
|
||||
};
|
||||
|
||||
typedef u_int8_t sysinfo_buf_t[GSM_MACBLOCK_LEN];
|
||||
|
||||
extern const struct value_string osmo_sitype_strs[_MAX_SYSINFO_TYPE];
|
||||
uint8_t gsm_sitype2rsl(enum osmo_sysinfo_type si_type);
|
||||
const char *gsm_sitype_name(enum osmo_sysinfo_type si_type);
|
||||
int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <openbsc/gsm_04_11.h>
|
||||
#include <openbsc/mncc.h>
|
||||
|
||||
/* One transaction */
|
||||
struct gsm_trans {
|
||||
@@ -12,10 +13,10 @@ struct gsm_trans {
|
||||
struct llist_head entry;
|
||||
|
||||
/* The protocol within which we live */
|
||||
u_int8_t protocol;
|
||||
uint8_t protocol;
|
||||
|
||||
/* The current transaction ID */
|
||||
u_int8_t transaction_id;
|
||||
uint8_t transaction_id;
|
||||
|
||||
/* To whom we belong, unique identifier of remote MM entity */
|
||||
struct gsm_subscriber *subscr;
|
||||
@@ -24,7 +25,7 @@ struct gsm_trans {
|
||||
struct gsm_subscriber_connection *conn;
|
||||
|
||||
/* reference from MNCC or other application */
|
||||
u_int32_t callref;
|
||||
uint32_t callref;
|
||||
|
||||
/* if traffic channel receive was requested */
|
||||
int tch_recv;
|
||||
@@ -41,14 +42,14 @@ struct gsm_trans {
|
||||
/* current timer and message queue */
|
||||
int Tcurrent; /* current CC timer */
|
||||
int T308_second; /* used to send release again */
|
||||
struct timer_list timer;
|
||||
struct osmo_timer_list timer;
|
||||
struct gsm_mncc msg; /* stores setup/disconnect/release message */
|
||||
} cc;
|
||||
struct {
|
||||
u_int8_t link_id; /* RSL Link ID to be used for this trans */
|
||||
uint8_t link_id; /* RSL Link ID to be used for this trans */
|
||||
int is_mt; /* is this a MO (0) or MT (1) transfer */
|
||||
enum gsm411_cp_state cp_state;
|
||||
struct timer_list cp_timer;
|
||||
struct osmo_timer_list cp_timer;
|
||||
|
||||
enum gsm411_rp_state rp_state;
|
||||
|
||||
@@ -60,16 +61,16 @@ struct gsm_trans {
|
||||
|
||||
|
||||
struct gsm_trans *trans_find_by_id(struct gsm_subscriber *subscr,
|
||||
u_int8_t proto, u_int8_t trans_id);
|
||||
uint8_t proto, uint8_t trans_id);
|
||||
struct gsm_trans *trans_find_by_callref(struct gsm_network *net,
|
||||
u_int32_t callref);
|
||||
uint32_t callref);
|
||||
|
||||
struct gsm_trans *trans_alloc(struct gsm_subscriber *subscr,
|
||||
u_int8_t protocol, u_int8_t trans_id,
|
||||
u_int32_t callref);
|
||||
uint8_t protocol, uint8_t trans_id,
|
||||
uint32_t callref);
|
||||
void trans_free(struct gsm_trans *trans);
|
||||
|
||||
int trans_assign_trans_id(struct gsm_subscriber *subscr,
|
||||
u_int8_t protocol, u_int8_t ti_flag);
|
||||
uint8_t protocol, uint8_t ti_flag);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
#ifndef _TRAU_FRAME_H
|
||||
#define _TRAU_FRAME_H
|
||||
/* TRAU frame handling according to GSM TS 08.60 */
|
||||
|
||||
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* 21 for FR/EFR, 25 for AMR, 15 for OM, 15 for data, 13 for E-data, 21 idle */
|
||||
#define MAX_C_BITS 25
|
||||
/* 260 for FR/EFR, 256 for AMR, 264 for OM, 288 for E-data */
|
||||
#define MAX_D_BITS 288
|
||||
/* for all speech frames */
|
||||
#define MAX_T_BITS 4
|
||||
/* for OM */
|
||||
#define MAX_S_BITS 6
|
||||
/* for E-data */
|
||||
#define MAX_M_BITS 2
|
||||
|
||||
struct decoded_trau_frame {
|
||||
u_int8_t c_bits[MAX_C_BITS];
|
||||
u_int8_t d_bits[MAX_D_BITS];
|
||||
u_int8_t t_bits[MAX_T_BITS];
|
||||
u_int8_t s_bits[MAX_S_BITS];
|
||||
u_int8_t m_bits[MAX_M_BITS];
|
||||
};
|
||||
|
||||
#define TRAU_FT_FR_UP 0x02 /* 0 0 0 1 0 - 3.5.1.1.1 */
|
||||
#define TRAU_FT_FR_DOWN 0x1c /* 1 1 1 0 0 - 3.5.1.1.1 */
|
||||
#define TRAU_FT_EFR 0x1a /* 1 1 0 1 0 - 3.5.1.1.1 */
|
||||
#define TRAU_FT_AMR 0x06 /* 0 0 1 1 0 - 3.5.1.2 */
|
||||
#define TRAU_FT_OM_UP 0x07 /* 0 0 1 0 1 - 3.5.2 */
|
||||
#define TRAU_FT_OM_DOWN 0x1b /* 1 1 0 1 1 - 3.5.2 */
|
||||
#define TRAU_FT_DATA_UP 0x08 /* 0 1 0 0 0 - 3.5.3 */
|
||||
#define TRAU_FT_DATA_DOWN 0x16 /* 1 0 1 1 0 - 3.5.3 */
|
||||
#define TRAU_FT_D145_SYNC 0x14 /* 1 0 1 0 0 - 3.5.3 */
|
||||
#define TRAU_FT_EDATA 0x1f /* 1 1 1 1 1 - 3.5.4 */
|
||||
#define TRAU_FT_IDLE_UP 0x10 /* 1 0 0 0 0 - 3.5.5 */
|
||||
#define TRAU_FT_IDLE_DOWN 0x0e /* 0 1 1 1 0 - 3.5.5 */
|
||||
|
||||
|
||||
int decode_trau_frame(struct decoded_trau_frame *fr, const u_int8_t *trau_bits);
|
||||
int encode_trau_frame(u_int8_t *trau_bits, const struct decoded_trau_frame *fr);
|
||||
int trau_frame_up2down(struct decoded_trau_frame *fr);
|
||||
u_int8_t *trau_idle_frame(void);
|
||||
|
||||
|
||||
#endif /* _TRAU_FRAME_H */
|
||||
@@ -28,6 +28,10 @@
|
||||
* optimization to routing them externally.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/mncc.h>
|
||||
|
||||
/* map a TRAU mux map entry */
|
||||
int trau_mux_map(const struct gsm_e1_subslot *src,
|
||||
const struct gsm_e1_subslot *dst);
|
||||
@@ -35,14 +39,17 @@ int trau_mux_map_lchan(const struct gsm_lchan *src,
|
||||
const struct gsm_lchan *dst);
|
||||
|
||||
/* unmap a TRAU mux map entry */
|
||||
int trau_mux_unmap(const struct gsm_e1_subslot *ss, u_int32_t callref);
|
||||
int trau_mux_unmap(const struct gsm_e1_subslot *ss, uint32_t callref);
|
||||
|
||||
/* we get called by subchan_demux */
|
||||
int trau_mux_input(struct gsm_e1_subslot *src_e1_ss,
|
||||
const u_int8_t *trau_bits, int num_bits);
|
||||
const uint8_t *trau_bits, int num_bits);
|
||||
|
||||
/* add a trau receiver */
|
||||
int trau_recv_lchan(struct gsm_lchan *lchan, u_int32_t callref);
|
||||
int trau_recv_lchan(struct gsm_lchan *lchan, uint32_t callref);
|
||||
|
||||
/* send trau from application */
|
||||
int trau_send_frame(struct gsm_lchan *lchan, struct gsm_data_frame *frame);
|
||||
|
||||
/* callback invoked if we receive TRAU frames */
|
||||
int subch_cb(struct subch_demux *dmx, int ch, uint8_t *data, int len, void *_priv);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
/* Handler function for mobile-originated USSD messages */
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
|
||||
int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
|
||||
@@ -29,18 +29,19 @@ enum bsc_vty_node {
|
||||
NS_NODE,
|
||||
BSSGP_NODE,
|
||||
OML_NODE,
|
||||
E1INP_NODE,
|
||||
NAT_NODE,
|
||||
NAT_BSC_NODE,
|
||||
MSC_NODE,
|
||||
OM2K_NODE,
|
||||
TRUNK_NODE,
|
||||
PGROUP_NODE,
|
||||
};
|
||||
|
||||
extern int bsc_vty_is_config_node(struct vty *vty, int node);
|
||||
extern void bsc_replace_string(void *ctx, char **dst, const char *newstr);
|
||||
|
||||
int bsc_vty_init(void);
|
||||
struct log_info;
|
||||
int bsc_vty_init(const struct log_info *cat);
|
||||
int bsc_vty_init_extra(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,52 +1,13 @@
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
|
||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(COVERAGE_LDFLAGS)
|
||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(COVERAGE_LDFLAGS)
|
||||
|
||||
# build current directory before building gprs
|
||||
SUBDIRS = . ipaccess gprs
|
||||
SUBDIRS = libcommon libmgcp libbsc libmsc libtrau libctrl osmo-nitb osmo-bsc_mgcp utils ipaccess libgb gprs
|
||||
|
||||
# Conditional modules
|
||||
if BUILD_NAT
|
||||
SUBDIRS += nat
|
||||
SUBDIRS += osmo-bsc_nat
|
||||
endif
|
||||
if BUILD_BSC
|
||||
SUBDIRS += bsc
|
||||
SUBDIRS += osmo-bsc
|
||||
endif
|
||||
|
||||
bin_PROGRAMS = bsc_hack bs11_config isdnsync bsc_mgcp
|
||||
noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libmgcp.a
|
||||
|
||||
libbsc_a_SOURCES = abis_rsl.c abis_nm.c abis_om2000.c gsm_data.c gsm_04_08_utils.c \
|
||||
chan_alloc.c debug.c socket.c abis_nm_vty.c abis_om2000_vty.c \
|
||||
gsm_subscriber_base.c subchan_demux.c bsc_rll.c transaction.c \
|
||||
trau_frame.c trau_mux.c paging.c \
|
||||
e1_config.c e1_input.c e1_input_vty.c \
|
||||
input/misdn.c input/ipaccess.c input/dahdi.c input/lapd.c \
|
||||
handover_logic.c talloc_ctx.c system_information.c rest_octets.c \
|
||||
bts_siemens_bs11.c bts_ipaccess_nanobts.c bts_ericsson_rbs2000.c mncc_upqueue.c \
|
||||
bts_unknown.c bsc_version.c bsc_api.c bsc_vty.c meas_rep.c gsm_04_80.c
|
||||
|
||||
libmsc_a_SOURCES = gsm_subscriber.c db.c \
|
||||
mncc.c mncc_builtin.c mncc_sock.c \
|
||||
gsm_04_08.c gsm_04_11.c transaction.c \
|
||||
token_auth.c rrlp.c ussd.c silent_call.c \
|
||||
handover_decision.c auth.c \
|
||||
osmo_msc.c rtp_proxy.c
|
||||
|
||||
libvty_a_SOURCES = common_vty.c
|
||||
|
||||
libmgcp_a_SOURCES = mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c
|
||||
|
||||
bsc_hack_SOURCES = bsc_hack.c bsc_init.c bsc_vty.c vty_interface_layer3.c sms_queue.c
|
||||
bsc_hack_LDADD = libmsc.a libbsc.a libvty.a libmsc.a \
|
||||
-ldl -ldbi $(LIBCRYPT) $(LIBOSMOVTY_LIBS)
|
||||
|
||||
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c debug.c \
|
||||
rs232.c bts_siemens_bs11.c
|
||||
|
||||
isdnsync_SOURCES = isdnsync.c
|
||||
|
||||
bsc_mgcp_SOURCES = mgcp/mgcp_main.c debug.c
|
||||
bsc_mgcp_LDADD = libvty.a libmgcp.a $(LIBOSMOVTY_LIBS)
|
||||
|
||||
EXTRA_DIST = input/lapd.h
|
||||
|
||||
@@ -1,269 +0,0 @@
|
||||
/* An implementation of the GSM A3A8 algorithm. (Specifically, COMP128.)
|
||||
*/
|
||||
|
||||
/* Copyright 1998, Marc Briceno, Ian Goldberg, and David Wagner.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the authors nor the names of the contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Coded in C merely because C is a much more precise, concise form of
|
||||
* expression for these purposes. See Judge Patel if you have any problems
|
||||
* with this...
|
||||
* Of course, it's only authentication, so it should be exportable for the
|
||||
* usual boring reasons.
|
||||
*/
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
||||
#include <stdio.h>
|
||||
/* #define TEST */
|
||||
|
||||
/*
|
||||
* rand[0..15]: the challenge from the base station
|
||||
* key[0..15]: the SIM's A3/A8 long-term key Ki
|
||||
* simoutput[0..11]: what you'd get back if you fed rand and key to a real
|
||||
* SIM.
|
||||
*
|
||||
* The GSM spec states that simoutput[0..3] is SRES,
|
||||
* and simoutput[4..11] is Kc (the A5 session key).
|
||||
* (See GSM 11.11, Section 8.16. See also the leaked document
|
||||
* referenced below.)
|
||||
* Note that Kc is bits 74..127 of the COMP128 output, followed by 10
|
||||
* zeros.
|
||||
* In other words, A5 is keyed with only 54 bits of entropy. This
|
||||
* represents a deliberate weakening of the key used for voice privacy
|
||||
* by a factor of over 1000.
|
||||
*
|
||||
* Verified with a Pacific Bell Schlumberger SIM. Your mileage may vary.
|
||||
*
|
||||
* Marc Briceno <marc@scard.org>, Ian Goldberg <iang@cs.berkeley.edu>,
|
||||
* and David Wagner <daw@cs.berkeley.edu>
|
||||
*/
|
||||
|
||||
void A3A8(/* in */ Byte rand[16], /* in */ Byte key[16],
|
||||
/* out */ Byte simoutput[12]);
|
||||
|
||||
/* The compression tables. */
|
||||
static const Byte table_0[512] = {
|
||||
102,177,186,162, 2,156,112, 75, 55, 25, 8, 12,251,193,246,188,
|
||||
109,213,151, 53, 42, 79,191,115,233,242,164,223,209,148,108,161,
|
||||
252, 37,244, 47, 64,211, 6,237,185,160,139,113, 76,138, 59, 70,
|
||||
67, 26, 13,157, 63,179,221, 30,214, 36,166, 69,152,124,207,116,
|
||||
247,194, 41, 84, 71, 1, 49, 14, 95, 35,169, 21, 96, 78,215,225,
|
||||
182,243, 28, 92,201,118, 4, 74,248,128, 17, 11,146,132,245, 48,
|
||||
149, 90,120, 39, 87,230,106,232,175, 19,126,190,202,141,137,176,
|
||||
250, 27,101, 40,219,227, 58, 20, 51,178, 98,216,140, 22, 32,121,
|
||||
61,103,203, 72, 29,110, 85,212,180,204,150,183, 15, 66,172,196,
|
||||
56,197,158, 0,100, 45,153, 7,144,222,163,167, 60,135,210,231,
|
||||
174,165, 38,249,224, 34,220,229,217,208,241, 68,206,189,125,255,
|
||||
239, 54,168, 89,123,122, 73,145,117,234,143, 99,129,200,192, 82,
|
||||
104,170,136,235, 93, 81,205,173,236, 94,105, 52, 46,228,198, 5,
|
||||
57,254, 97,155,142,133,199,171,187, 50, 65,181,127,107,147,226,
|
||||
184,218,131, 33, 77, 86, 31, 44, 88, 62,238, 18, 24, 43,154, 23,
|
||||
80,159,134,111, 9,114, 3, 91, 16,130, 83, 10,195,240,253,119,
|
||||
177,102,162,186,156, 2, 75,112, 25, 55, 12, 8,193,251,188,246,
|
||||
213,109, 53,151, 79, 42,115,191,242,233,223,164,148,209,161,108,
|
||||
37,252, 47,244,211, 64,237, 6,160,185,113,139,138, 76, 70, 59,
|
||||
26, 67,157, 13,179, 63, 30,221, 36,214, 69,166,124,152,116,207,
|
||||
194,247, 84, 41, 1, 71, 14, 49, 35, 95, 21,169, 78, 96,225,215,
|
||||
243,182, 92, 28,118,201, 74, 4,128,248, 11, 17,132,146, 48,245,
|
||||
90,149, 39,120,230, 87,232,106, 19,175,190,126,141,202,176,137,
|
||||
27,250, 40,101,227,219, 20, 58,178, 51,216, 98, 22,140,121, 32,
|
||||
103, 61, 72,203,110, 29,212, 85,204,180,183,150, 66, 15,196,172,
|
||||
197, 56, 0,158, 45,100, 7,153,222,144,167,163,135, 60,231,210,
|
||||
165,174,249, 38, 34,224,229,220,208,217, 68,241,189,206,255,125,
|
||||
54,239, 89,168,122,123,145, 73,234,117, 99,143,200,129, 82,192,
|
||||
170,104,235,136, 81, 93,173,205, 94,236, 52,105,228, 46, 5,198,
|
||||
254, 57,155, 97,133,142,171,199, 50,187,181, 65,107,127,226,147,
|
||||
218,184, 33,131, 86, 77, 44, 31, 62, 88, 18,238, 43, 24, 23,154,
|
||||
159, 80,111,134,114, 9, 91, 3,130, 16, 10, 83,240,195,119,253
|
||||
}, table_1[256] = {
|
||||
19, 11, 80,114, 43, 1, 69, 94, 39, 18,127,117, 97, 3, 85, 43,
|
||||
27,124, 70, 83, 47, 71, 63, 10, 47, 89, 79, 4, 14, 59, 11, 5,
|
||||
35,107,103, 68, 21, 86, 36, 91, 85,126, 32, 50,109, 94,120, 6,
|
||||
53, 79, 28, 45, 99, 95, 41, 34, 88, 68, 93, 55,110,125,105, 20,
|
||||
90, 80, 76, 96, 23, 60, 89, 64,121, 56, 14, 74,101, 8, 19, 78,
|
||||
76, 66,104, 46,111, 50, 32, 3, 39, 0, 58, 25, 92, 22, 18, 51,
|
||||
57, 65,119,116, 22,109, 7, 86, 59, 93, 62,110, 78, 99, 77, 67,
|
||||
12,113, 87, 98,102, 5, 88, 33, 38, 56, 23, 8, 75, 45, 13, 75,
|
||||
95, 63, 28, 49,123,120, 20,112, 44, 30, 15, 98,106, 2,103, 29,
|
||||
82,107, 42,124, 24, 30, 41, 16,108,100,117, 40, 73, 40, 7,114,
|
||||
82,115, 36,112, 12,102,100, 84, 92, 48, 72, 97, 9, 54, 55, 74,
|
||||
113,123, 17, 26, 53, 58, 4, 9, 69,122, 21,118, 42, 60, 27, 73,
|
||||
118,125, 34, 15, 65,115, 84, 64, 62, 81, 70, 1, 24,111,121, 83,
|
||||
104, 81, 49,127, 48,105, 31, 10, 6, 91, 87, 37, 16, 54,116,126,
|
||||
31, 38, 13, 0, 72,106, 77, 61, 26, 67, 46, 29, 96, 37, 61, 52,
|
||||
101, 17, 44,108, 71, 52, 66, 57, 33, 51, 25, 90, 2,119,122, 35
|
||||
}, table_2[128] = {
|
||||
52, 50, 44, 6, 21, 49, 41, 59, 39, 51, 25, 32, 51, 47, 52, 43,
|
||||
37, 4, 40, 34, 61, 12, 28, 4, 58, 23, 8, 15, 12, 22, 9, 18,
|
||||
55, 10, 33, 35, 50, 1, 43, 3, 57, 13, 62, 14, 7, 42, 44, 59,
|
||||
62, 57, 27, 6, 8, 31, 26, 54, 41, 22, 45, 20, 39, 3, 16, 56,
|
||||
48, 2, 21, 28, 36, 42, 60, 33, 34, 18, 0, 11, 24, 10, 17, 61,
|
||||
29, 14, 45, 26, 55, 46, 11, 17, 54, 46, 9, 24, 30, 60, 32, 0,
|
||||
20, 38, 2, 30, 58, 35, 1, 16, 56, 40, 23, 48, 13, 19, 19, 27,
|
||||
31, 53, 47, 38, 63, 15, 49, 5, 37, 53, 25, 36, 63, 29, 5, 7
|
||||
}, table_3[64] = {
|
||||
1, 5, 29, 6, 25, 1, 18, 23, 17, 19, 0, 9, 24, 25, 6, 31,
|
||||
28, 20, 24, 30, 4, 27, 3, 13, 15, 16, 14, 18, 4, 3, 8, 9,
|
||||
20, 0, 12, 26, 21, 8, 28, 2, 29, 2, 15, 7, 11, 22, 14, 10,
|
||||
17, 21, 12, 30, 26, 27, 16, 31, 11, 7, 13, 23, 10, 5, 22, 19
|
||||
}, table_4[32] = {
|
||||
15, 12, 10, 4, 1, 14, 11, 7, 5, 0, 14, 7, 1, 2, 13, 8,
|
||||
10, 3, 4, 9, 6, 0, 3, 2, 5, 6, 8, 9, 11, 13, 15, 12
|
||||
}, *table[5] = { table_0, table_1, table_2, table_3, table_4 };
|
||||
|
||||
/*
|
||||
* This code derived from a leaked document from the GSM standards.
|
||||
* Some missing pieces were filled in by reverse-engineering a working SIM.
|
||||
* We have verified that this is the correct COMP128 algorithm.
|
||||
*
|
||||
* The first page of the document identifies it as
|
||||
* _Technical Information: GSM System Security Study_.
|
||||
* 10-1617-01, 10th June 1988.
|
||||
* The bottom of the title page is marked
|
||||
* Racal Research Ltd.
|
||||
* Worton Drive, Worton Grange Industrial Estate,
|
||||
* Reading, Berks. RG2 0SB, England.
|
||||
* Telephone: Reading (0734) 868601 Telex: 847152
|
||||
* The relevant bits are in Part I, Section 20 (pages 66--67). Enjoy!
|
||||
*
|
||||
* Note: There are three typos in the spec (discovered by
|
||||
* reverse-engineering).
|
||||
* First, "z = (2 * x[n] + x[n]) mod 2^(9-j)" should clearly read
|
||||
* "z = (2 * x[m] + x[n]) mod 2^(9-j)".
|
||||
* Second, the "k" loop in the "Form bits from bytes" section is severely
|
||||
* botched: the k index should run only from 0 to 3, and clearly the range
|
||||
* on "the (8-k)th bit of byte j" is also off (should be 0..7, not 1..8,
|
||||
* to be consistent with the subsequent section).
|
||||
* Third, SRES is taken from the first 8 nibbles of x[], not the last 8 as
|
||||
* claimed in the document. (And the document doesn't specify how Kc is
|
||||
* derived, but that was also easily discovered with reverse engineering.)
|
||||
* All of these typos have been corrected in the following code.
|
||||
*/
|
||||
|
||||
void A3A8(/* in */ Byte rand[16], /* in */ Byte key[16],
|
||||
/* out */ Byte simoutput[12])
|
||||
{
|
||||
Byte x[32], bit[128];
|
||||
int i, j, k, l, m, n, y, z, next_bit;
|
||||
|
||||
/* ( Load RAND into last 16 bytes of input ) */
|
||||
for (i=16; i<32; i++)
|
||||
x[i] = rand[i-16];
|
||||
|
||||
/* ( Loop eight times ) */
|
||||
for (i=1; i<9; i++) {
|
||||
/* ( Load key into first 16 bytes of input ) */
|
||||
for (j=0; j<16; j++)
|
||||
x[j] = key[j];
|
||||
/* ( Perform substitutions ) */
|
||||
for (j=0; j<5; j++)
|
||||
for (k=0; k<(1<<j); k++)
|
||||
for (l=0; l<(1<<(4-j)); l++) {
|
||||
m = l + k*(1<<(5-j));
|
||||
n = m + (1<<(4-j));
|
||||
y = (x[m]+2*x[n]) % (1<<(9-j));
|
||||
z = (2*x[m]+x[n]) % (1<<(9-j));
|
||||
x[m] = table[j][y];
|
||||
x[n] = table[j][z];
|
||||
}
|
||||
/* ( Form bits from bytes ) */
|
||||
for (j=0; j<32; j++)
|
||||
for (k=0; k<4; k++)
|
||||
bit[4*j+k] = (x[j]>>(3-k)) & 1;
|
||||
/* ( Permutation but not on the last loop ) */
|
||||
if (i < 8)
|
||||
for (j=0; j<16; j++) {
|
||||
x[j+16] = 0;
|
||||
for (k=0; k<8; k++) {
|
||||
next_bit = ((8*j + k)*17) % 128;
|
||||
x[j+16] |= bit[next_bit] << (7-k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ( At this stage the vector x[] consists of 32 nibbles.
|
||||
* The first 8 of these are taken as the output SRES. )
|
||||
*/
|
||||
|
||||
/* The remainder of the code is not given explicitly in the
|
||||
* standard, but was derived by reverse-engineering.
|
||||
*/
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
simoutput[i] = (x[2*i]<<4) | x[2*i+1];
|
||||
for (i=0; i<6; i++)
|
||||
simoutput[4+i] = (x[2*i+18]<<6) | (x[2*i+18+1]<<2)
|
||||
| (x[2*i+18+2]>>2);
|
||||
simoutput[4+6] = (x[2*6+18]<<6) | (x[2*6+18+1]<<2);
|
||||
simoutput[4+7] = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
int hextoint(char x)
|
||||
{
|
||||
x = toupper(x);
|
||||
if (x >= 'A' && x <= 'F')
|
||||
return x-'A'+10;
|
||||
else if (x >= '0' && x <= '9')
|
||||
return x-'0';
|
||||
fprintf(stderr, "bad input.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Byte key[16], rand[16], simoutput[12];
|
||||
int i;
|
||||
|
||||
if (argc != 3 || strlen(argv[1]) != 34 || strlen(argv[2]) != 34
|
||||
|| strncmp(argv[1], "0x", 2) != 0
|
||||
|| strncmp(argv[2], "0x", 2) != 0) {
|
||||
fprintf(stderr, "Usage: %s 0x<key> 0x<rand>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
key[i] = (hextoint(argv[1][2*i+2])<<4)
|
||||
| hextoint(argv[1][2*i+3]);
|
||||
for (i=0; i<16; i++)
|
||||
rand[i] = (hextoint(argv[2][2*i+2])<<4)
|
||||
| hextoint(argv[2][2*i+3]);
|
||||
A3A8(rand, key, simoutput);
|
||||
printf("simoutput: ");
|
||||
for (i=0; i<12; i++)
|
||||
printf("%02X", simoutput[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
|
||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS)
|
||||
|
||||
bin_PROGRAMS = osmo-bsc
|
||||
|
||||
|
||||
osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_rf.c osmo_bsc_vty.c osmo_bsc_api.c \
|
||||
osmo_bsc_grace.c osmo_bsc_msc.c osmo_bsc_sccp.c \
|
||||
osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c \
|
||||
$(top_srcdir)/src/debug.c $(top_srcdir)/src/bsc_msc.c \
|
||||
$(top_srcdir)/src/bsc_init.c
|
||||
osmo_bsc_LDADD = $(top_builddir)/src/libvty.a \
|
||||
$(top_builddir)/src/libmgcp.a $(top_builddir)/src/libbsc.a \
|
||||
$(LIBOSMOSCCP_LIBS)
|
||||
@@ -1,261 +0,0 @@
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/osmo_bsc.h>
|
||||
#include <openbsc/osmo_bsc_rf.h>
|
||||
#include <openbsc/osmo_msc_data.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/vty.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/process.h>
|
||||
|
||||
#include <osmocom/sccp/sccp.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include "bscconfig.h"
|
||||
|
||||
static struct log_target *stderr_target;
|
||||
struct gsm_network *bsc_gsmnet = 0;
|
||||
static const char *config_file = "openbsc.cfg";
|
||||
static const char *rf_ctl = NULL;
|
||||
extern const char *openbsc_copyright;
|
||||
static int daemonize = 0;
|
||||
|
||||
extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, struct msgb *), const char *cfg_file);
|
||||
|
||||
static void print_usage()
|
||||
{
|
||||
printf("Usage: bsc_msc_ip\n");
|
||||
}
|
||||
|
||||
static void print_help()
|
||||
{
|
||||
printf(" Some useful help...\n");
|
||||
printf(" -h --help this text\n");
|
||||
printf(" -D --daemonize Fork the process into a background daemon\n");
|
||||
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
|
||||
printf(" -s --disable-color\n");
|
||||
printf(" -T --timestamp. Print a timestamp in the debug output.\n");
|
||||
printf(" -c --config-file filename The config file to use.\n");
|
||||
printf(" -l --local=IP. The local address of the MGCP.\n");
|
||||
printf(" -e --log-level number. Set a global loglevel.\n");
|
||||
printf(" -r --rf-ctl NAME. A unix domain socket to listen for cmds.\n");
|
||||
printf(" -t --testmode. A special mode to provoke failures at the MSC.\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
{
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
static struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"debug", 1, 0, 'd'},
|
||||
{"daemonize", 0, 0, 'D'},
|
||||
{"config-file", 1, 0, 'c'},
|
||||
{"disable-color", 0, 0, 's'},
|
||||
{"timestamp", 0, 0, 'T'},
|
||||
{"local", 1, 0, 'l'},
|
||||
{"log-level", 1, 0, 'e'},
|
||||
{"rf-ctl", 1, 0, 'r'},
|
||||
{"testmode", 0, 0, 't'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hd:DsTc:e:r:t",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_usage();
|
||||
print_help();
|
||||
exit(0);
|
||||
case 's':
|
||||
log_set_use_color(stderr_target, 0);
|
||||
break;
|
||||
case 'd':
|
||||
log_parse_category_mask(stderr_target, optarg);
|
||||
break;
|
||||
case 'D':
|
||||
daemonize = 1;
|
||||
break;
|
||||
case 'c':
|
||||
config_file = strdup(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
log_set_print_timestamp(stderr_target, 1);
|
||||
break;
|
||||
case 'P':
|
||||
ipacc_rtp_direct = 0;
|
||||
break;
|
||||
case 'e':
|
||||
log_set_log_level(stderr_target, atoi(optarg));
|
||||
break;
|
||||
case 'r':
|
||||
rf_ctl = optarg;
|
||||
break;
|
||||
default:
|
||||
/* ignore */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern int bts_model_unknown_init(void);
|
||||
extern int bts_model_bs11_init(void);
|
||||
extern int bts_model_nanobts_init(void);
|
||||
|
||||
extern enum node_type bsc_vty_go_parent(struct vty *vty);
|
||||
|
||||
static struct vty_app_info vty_info = {
|
||||
.name = "OsmoBSC",
|
||||
.version = PACKAGE_VERSION,
|
||||
.go_parent_cb = bsc_vty_go_parent,
|
||||
.is_config_node = bsc_vty_is_config_node,
|
||||
};
|
||||
|
||||
extern int bsc_shutdown_net(struct gsm_network *net);
|
||||
static void signal_handler(int signal)
|
||||
{
|
||||
fprintf(stdout, "signal %u received\n", signal);
|
||||
|
||||
switch (signal) {
|
||||
case SIGINT:
|
||||
bsc_shutdown_net(bsc_gsmnet);
|
||||
dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
|
||||
sleep(3);
|
||||
exit(0);
|
||||
break;
|
||||
case SIGABRT:
|
||||
/* in case of abort, we want to obtain a talloc report
|
||||
* and then return to the caller, who will abort the process */
|
||||
case SIGUSR1:
|
||||
talloc_report(tall_vty_ctx, stderr);
|
||||
talloc_report_full(tall_bsc_ctx, stderr);
|
||||
break;
|
||||
case SIGUSR2:
|
||||
if (!bsc_gsmnet->msc_data)
|
||||
return;
|
||||
if (!bsc_gsmnet->msc_data->msc_con)
|
||||
return;
|
||||
if (!bsc_gsmnet->msc_data->msc_con->is_connected)
|
||||
return;
|
||||
bsc_msc_lost(bsc_gsmnet->msc_data->msc_con);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
log_init(&log_info);
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
|
||||
bts_model_unknown_init();
|
||||
bts_model_bs11_init();
|
||||
bts_model_nanobts_init();
|
||||
|
||||
/* enable filters */
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
|
||||
/* This needs to precede handle_options() */
|
||||
vty_info.copyright = openbsc_copyright;
|
||||
vty_init(&vty_info);
|
||||
bsc_vty_init();
|
||||
|
||||
/* parse options */
|
||||
handle_options(argc, argv);
|
||||
|
||||
/* seed the PRNG */
|
||||
srand(time(NULL));
|
||||
|
||||
/* initialize SCCP */
|
||||
sccp_set_log_area(DSCCP);
|
||||
|
||||
|
||||
rc = bsc_bootstrap_network(NULL, config_file);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
bsc_api_init(bsc_gsmnet, osmo_bsc_api());
|
||||
|
||||
if (rf_ctl) {
|
||||
struct osmo_msc_data *data = bsc_gsmnet->msc_data;
|
||||
data->rf_ctl = osmo_bsc_rf_create(rf_ctl, bsc_gsmnet);
|
||||
if (!data->rf_ctl) {
|
||||
fprintf(stderr, "Failed to create the RF service.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (osmo_bsc_msc_init(bsc_gsmnet) != 0) {
|
||||
LOGP(DNAT, LOGL_ERROR, "Failed to start up. Exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (osmo_bsc_sccp_init(bsc_gsmnet) != 0) {
|
||||
LOGP(DNM, LOGL_ERROR, "Failed to register SCCP.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (osmo_bsc_audio_init(bsc_gsmnet) != 0) {
|
||||
LOGP(DMSC, LOGL_ERROR, "Failed to register audio support.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
signal(SIGINT, &signal_handler);
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
signal(SIGUSR2, &signal_handler);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (daemonize) {
|
||||
rc = osmo_daemonize();
|
||||
if (rc < 0) {
|
||||
perror("Error during daemonize");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
bsc_select_main(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,649 +0,0 @@
|
||||
/* OpenBSC Abis interface to E1 */
|
||||
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <mISDNif.h>
|
||||
|
||||
//#define AF_COMPATIBILITY_FUNC
|
||||
//#include <compat_af_isdn.h>
|
||||
#ifndef AF_ISDN
|
||||
#define AF_ISDN 34
|
||||
#define PF_ISDN AF_ISDN
|
||||
#endif
|
||||
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/e1_input.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/subchan_demux.h>
|
||||
#include <openbsc/trau_frame.h>
|
||||
#include <openbsc/trau_mux.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/misdn.h>
|
||||
|
||||
#include "../bscconfig.h"
|
||||
|
||||
#define NUM_E1_TS 32
|
||||
|
||||
/* list of all E1 drivers */
|
||||
LLIST_HEAD(e1inp_driver_list);
|
||||
|
||||
/* list of all E1 lines */
|
||||
LLIST_HEAD(e1inp_line_list);
|
||||
|
||||
static void *tall_sigl_ctx;
|
||||
|
||||
/*
|
||||
* pcap writing of the misdn load
|
||||
* pcap format is from http://wiki.wireshark.org/Development/LibpcapFileFormat
|
||||
*/
|
||||
#define DLT_LINUX_LAPD 177
|
||||
#define PCAP_INPUT 0
|
||||
#define PCAP_OUTPUT 1
|
||||
|
||||
struct pcap_hdr {
|
||||
u_int32_t magic_number;
|
||||
u_int16_t version_major;
|
||||
u_int16_t version_minor;
|
||||
int32_t thiszone;
|
||||
u_int32_t sigfigs;
|
||||
u_int32_t snaplen;
|
||||
u_int32_t network;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct pcaprec_hdr {
|
||||
u_int32_t ts_sec;
|
||||
u_int32_t ts_usec;
|
||||
u_int32_t incl_len;
|
||||
u_int32_t orig_len;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct fake_linux_lapd_header {
|
||||
u_int16_t pkttype;
|
||||
u_int16_t hatype;
|
||||
u_int16_t halen;
|
||||
u_int64_t addr;
|
||||
int16_t protocol;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct lapd_header {
|
||||
u_int8_t ea1 : 1;
|
||||
u_int8_t cr : 1;
|
||||
u_int8_t sapi : 6;
|
||||
u_int8_t ea2 : 1;
|
||||
u_int8_t tei : 7;
|
||||
u_int8_t control_foo; /* fake UM's ... */
|
||||
} __attribute__((packed));
|
||||
|
||||
static_assert(offsetof(struct fake_linux_lapd_header, hatype) == 2, hatype_offset);
|
||||
static_assert(offsetof(struct fake_linux_lapd_header, halen) == 4, halen_offset);
|
||||
static_assert(offsetof(struct fake_linux_lapd_header, addr) == 6, addr_offset);
|
||||
static_assert(offsetof(struct fake_linux_lapd_header, protocol) == 14, proto_offset);
|
||||
static_assert(sizeof(struct fake_linux_lapd_header) == 16, lapd_header_size);
|
||||
|
||||
|
||||
static int pcap_fd = -1;
|
||||
|
||||
void e1_set_pcap_fd(int fd)
|
||||
{
|
||||
int ret;
|
||||
struct pcap_hdr header = {
|
||||
.magic_number = 0xa1b2c3d4,
|
||||
.version_major = 2,
|
||||
.version_minor = 4,
|
||||
.thiszone = 0,
|
||||
.sigfigs = 0,
|
||||
.snaplen = 65535,
|
||||
.network = DLT_LINUX_LAPD,
|
||||
};
|
||||
|
||||
pcap_fd = fd;
|
||||
ret = write(pcap_fd, &header, sizeof(header));
|
||||
}
|
||||
|
||||
/* This currently only works for the D-Channel */
|
||||
static void write_pcap_packet(int direction, int sapi, int tei,
|
||||
struct msgb *msg) {
|
||||
if (pcap_fd < 0)
|
||||
return;
|
||||
|
||||
int ret;
|
||||
time_t cur_time;
|
||||
struct tm *tm;
|
||||
|
||||
struct fake_linux_lapd_header header = {
|
||||
.pkttype = 4,
|
||||
.hatype = 0,
|
||||
.halen = 0,
|
||||
.addr = direction == PCAP_OUTPUT ? 0x0 : 0x1,
|
||||
.protocol = ntohs(48),
|
||||
};
|
||||
|
||||
struct lapd_header lapd_header = {
|
||||
.ea1 = 0,
|
||||
.cr = direction == PCAP_OUTPUT ? 1 : 0,
|
||||
.sapi = sapi & 0x3F,
|
||||
.ea2 = 1,
|
||||
.tei = tei & 0x7F,
|
||||
.control_foo = 0x03 /* UI */,
|
||||
};
|
||||
|
||||
struct pcaprec_hdr payload_header = {
|
||||
.ts_sec = 0,
|
||||
.ts_usec = 0,
|
||||
.incl_len = msgb_l2len(msg) + sizeof(struct fake_linux_lapd_header)
|
||||
+ sizeof(struct lapd_header),
|
||||
.orig_len = msgb_l2len(msg) + sizeof(struct fake_linux_lapd_header)
|
||||
+ sizeof(struct lapd_header),
|
||||
};
|
||||
|
||||
|
||||
cur_time = time(NULL);
|
||||
tm = localtime(&cur_time);
|
||||
payload_header.ts_sec = mktime(tm);
|
||||
|
||||
ret = write(pcap_fd, &payload_header, sizeof(payload_header));
|
||||
ret = write(pcap_fd, &header, sizeof(header));
|
||||
ret = write(pcap_fd, &lapd_header, sizeof(lapd_header));
|
||||
ret = write(pcap_fd, msg->l2h, msgb_l2len(msg));
|
||||
}
|
||||
|
||||
static const char *sign_types[] = {
|
||||
[E1INP_SIGN_NONE] = "None",
|
||||
[E1INP_SIGN_OML] = "OML",
|
||||
[E1INP_SIGN_RSL] = "RSL",
|
||||
};
|
||||
const char *e1inp_signtype_name(enum e1inp_sign_type tp)
|
||||
{
|
||||
if (tp >= ARRAY_SIZE(sign_types))
|
||||
return "undefined";
|
||||
return sign_types[tp];
|
||||
}
|
||||
|
||||
static const char *ts_types[] = {
|
||||
[E1INP_TS_TYPE_NONE] = "None",
|
||||
[E1INP_TS_TYPE_SIGN] = "Signalling",
|
||||
[E1INP_TS_TYPE_TRAU] = "TRAU",
|
||||
};
|
||||
|
||||
const char *e1inp_tstype_name(enum e1inp_ts_type tp)
|
||||
{
|
||||
if (tp >= ARRAY_SIZE(ts_types))
|
||||
return "undefined";
|
||||
return ts_types[tp];
|
||||
}
|
||||
|
||||
/* callback when a TRAU frame was received */
|
||||
static int subch_cb(struct subch_demux *dmx, int ch, u_int8_t *data, int len,
|
||||
void *_priv)
|
||||
{
|
||||
struct e1inp_ts *e1i_ts = _priv;
|
||||
struct gsm_e1_subslot src_ss;
|
||||
|
||||
src_ss.e1_nr = e1i_ts->line->num;
|
||||
src_ss.e1_ts = e1i_ts->num;
|
||||
src_ss.e1_ts_ss = ch;
|
||||
|
||||
return trau_mux_input(&src_ss, data, len);
|
||||
}
|
||||
|
||||
int abis_rsl_sendmsg(struct msgb *msg)
|
||||
{
|
||||
struct e1inp_sign_link *sign_link;
|
||||
struct e1inp_driver *e1inp_driver;
|
||||
struct e1inp_ts *e1i_ts;
|
||||
|
||||
msg->l2h = msg->data;
|
||||
|
||||
if (!msg->trx) {
|
||||
LOGP(DRSL, LOGL_ERROR, "rsl_sendmsg: msg->trx == NULL: %s\n",
|
||||
hexdump(msg->data, msg->len));
|
||||
talloc_free(msg);
|
||||
return -EINVAL;
|
||||
} else if (!msg->trx->rsl_link) {
|
||||
LOGP(DRSL, LOGL_ERROR, "rsl_sendmsg: msg->trx->rsl_link == NULL: %s\n",
|
||||
hexdump(msg->data, msg->len));
|
||||
talloc_free(msg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
sign_link = msg->trx->rsl_link;
|
||||
e1i_ts = sign_link->ts;
|
||||
if (!bsc_timer_pending(&e1i_ts->sign.tx_timer)) {
|
||||
/* notify the driver we have something to write */
|
||||
e1inp_driver = sign_link->ts->line->driver;
|
||||
e1inp_driver->want_write(e1i_ts);
|
||||
}
|
||||
msgb_enqueue(&sign_link->tx_list, msg);
|
||||
|
||||
/* dump it */
|
||||
write_pcap_packet(PCAP_OUTPUT, sign_link->sapi, sign_link->tei, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _abis_nm_sendmsg(struct msgb *msg, int to_trx_oml)
|
||||
{
|
||||
struct e1inp_sign_link *sign_link;
|
||||
struct e1inp_driver *e1inp_driver;
|
||||
struct e1inp_ts *e1i_ts;
|
||||
|
||||
msg->l2h = msg->data;
|
||||
|
||||
if (!msg->trx || !msg->trx->bts || !msg->trx->bts->oml_link) {
|
||||
LOGP(DNM, LOGL_ERROR, "nm_sendmsg: msg->trx == NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check for TRX-specific OML link first */
|
||||
if (to_trx_oml) {
|
||||
if (!msg->trx->oml_link)
|
||||
return -ENODEV;
|
||||
sign_link = msg->trx->oml_link;
|
||||
} else
|
||||
sign_link = msg->trx->bts->oml_link;
|
||||
|
||||
e1i_ts = sign_link->ts;
|
||||
if (!bsc_timer_pending(&e1i_ts->sign.tx_timer)) {
|
||||
/* notify the driver we have something to write */
|
||||
e1inp_driver = sign_link->ts->line->driver;
|
||||
e1inp_driver->want_write(e1i_ts);
|
||||
}
|
||||
msgb_enqueue(&sign_link->tx_list, msg);
|
||||
|
||||
/* dump it */
|
||||
write_pcap_packet(PCAP_OUTPUT, sign_link->sapi, sign_link->tei, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Timeslot */
|
||||
|
||||
/* configure and initialize one e1inp_ts */
|
||||
int e1inp_ts_config(struct e1inp_ts *ts, struct e1inp_line *line,
|
||||
enum e1inp_ts_type type)
|
||||
{
|
||||
if (ts->type == type && ts->line && line)
|
||||
return 0;
|
||||
|
||||
ts->type = type;
|
||||
ts->line = line;
|
||||
|
||||
switch (type) {
|
||||
case E1INP_TS_TYPE_SIGN:
|
||||
if (line && line->driver)
|
||||
ts->sign.delay = line->driver->default_delay;
|
||||
else
|
||||
ts->sign.delay = 100000;
|
||||
INIT_LLIST_HEAD(&ts->sign.sign_links);
|
||||
break;
|
||||
case E1INP_TS_TYPE_TRAU:
|
||||
subchan_mux_init(&ts->trau.mux);
|
||||
ts->trau.demux.out_cb = subch_cb;
|
||||
ts->trau.demux.data = ts;
|
||||
subch_demux_init(&ts->trau.demux);
|
||||
break;
|
||||
default:
|
||||
LOGP(DMI, LOGL_ERROR, "unsupported E1 timeslot type %u\n",
|
||||
ts->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct e1inp_line *e1inp_line_get(u_int8_t e1_nr)
|
||||
{
|
||||
struct e1inp_line *e1i_line;
|
||||
|
||||
/* iterate over global list of e1 lines */
|
||||
llist_for_each_entry(e1i_line, &e1inp_line_list, list) {
|
||||
if (e1i_line->num == e1_nr)
|
||||
return e1i_line;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct e1inp_line *e1inp_line_create(u_int8_t e1_nr, const char *driver_name)
|
||||
{
|
||||
struct e1inp_driver *driver;
|
||||
struct e1inp_line *line;
|
||||
int i;
|
||||
|
||||
line = e1inp_line_get(e1_nr);
|
||||
if (line) {
|
||||
LOGP(DINP, LOGL_ERROR, "E1 Line %u already exists\n",
|
||||
e1_nr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
driver = e1inp_driver_find(driver_name);
|
||||
if (!driver) {
|
||||
LOGP(DINP, LOGL_ERROR, "No such E1 driver '%s'\n",
|
||||
driver_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line = talloc_zero(tall_bsc_ctx, struct e1inp_line);
|
||||
if (!line)
|
||||
return NULL;
|
||||
|
||||
line->driver = driver;
|
||||
|
||||
line->num = e1_nr;
|
||||
for (i = 0; i < NUM_E1_TS; i++) {
|
||||
line->ts[i].num = i+1;
|
||||
line->ts[i].line = line;
|
||||
}
|
||||
llist_add_tail(&line->list, &e1inp_line_list);
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct e1inp_line *e1inp_line_get_create(u_int8_t e1_nr)
|
||||
{
|
||||
struct e1inp_line *line;
|
||||
int i;
|
||||
|
||||
line = e1inp_line_get(e1_nr);
|
||||
if (line)
|
||||
return line;
|
||||
|
||||
line = talloc_zero(tall_bsc_ctx, struct e1inp_line);
|
||||
if (!line)
|
||||
return NULL;
|
||||
|
||||
line->num = e1_nr;
|
||||
for (i = 0; i < NUM_E1_TS; i++) {
|
||||
line->ts[i].num = i+1;
|
||||
line->ts[i].line = line;
|
||||
}
|
||||
llist_add_tail(&line->list, &e1inp_line_list);
|
||||
|
||||
return line;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct e1inp_ts *e1inp_ts_get(u_int8_t e1_nr, u_int8_t ts_nr)
|
||||
{
|
||||
struct e1inp_line *e1i_line;
|
||||
|
||||
e1i_line = e1inp_line_get(e1_nr);
|
||||
if (!e1i_line)
|
||||
return NULL;
|
||||
|
||||
return &e1i_line->ts[ts_nr-1];
|
||||
}
|
||||
|
||||
struct subch_mux *e1inp_get_mux(u_int8_t e1_nr, u_int8_t ts_nr)
|
||||
{
|
||||
struct e1inp_ts *e1i_ts = e1inp_ts_get(e1_nr, ts_nr);
|
||||
|
||||
if (!e1i_ts)
|
||||
return NULL;
|
||||
|
||||
return &e1i_ts->trau.mux;
|
||||
}
|
||||
|
||||
/* Signalling Link */
|
||||
|
||||
struct e1inp_sign_link *e1inp_lookup_sign_link(struct e1inp_ts *e1i,
|
||||
u_int8_t tei, u_int8_t sapi)
|
||||
{
|
||||
struct e1inp_sign_link *link;
|
||||
|
||||
llist_for_each_entry(link, &e1i->sign.sign_links, list) {
|
||||
if (link->sapi == sapi && link->tei == tei)
|
||||
return link;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create a new signalling link in a E1 timeslot */
|
||||
|
||||
struct e1inp_sign_link *
|
||||
e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type,
|
||||
struct gsm_bts_trx *trx, u_int8_t tei,
|
||||
u_int8_t sapi)
|
||||
{
|
||||
struct e1inp_sign_link *link;
|
||||
|
||||
if (ts->type != E1INP_TS_TYPE_SIGN)
|
||||
return NULL;
|
||||
|
||||
link = talloc_zero(tall_sigl_ctx, struct e1inp_sign_link);
|
||||
if (!link)
|
||||
return NULL;
|
||||
|
||||
link->ts = ts;
|
||||
link->type = type;
|
||||
INIT_LLIST_HEAD(&link->tx_list);
|
||||
link->trx = trx;
|
||||
link->tei = tei;
|
||||
link->sapi = sapi;
|
||||
|
||||
llist_add_tail(&link->list, &ts->sign.sign_links);
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
void e1inp_sign_link_destroy(struct e1inp_sign_link *link)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
||||
llist_del(&link->list);
|
||||
while (!llist_empty(&link->tx_list)) {
|
||||
msg = msgb_dequeue(&link->tx_list);
|
||||
msgb_free(msg);
|
||||
}
|
||||
|
||||
if (link->ts->type == E1INP_TS_TYPE_SIGN)
|
||||
bsc_del_timer(&link->ts->sign.tx_timer);
|
||||
|
||||
talloc_free(link);
|
||||
}
|
||||
|
||||
/* the E1 driver tells us he has received something on a TS */
|
||||
int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
|
||||
u_int8_t tei, u_int8_t sapi)
|
||||
{
|
||||
struct e1inp_sign_link *link;
|
||||
struct gsm_bts *bts;
|
||||
int ret;
|
||||
|
||||
switch (ts->type) {
|
||||
case E1INP_TS_TYPE_SIGN:
|
||||
/* consult the list of signalling links */
|
||||
write_pcap_packet(PCAP_INPUT, sapi, tei, msg);
|
||||
link = e1inp_lookup_sign_link(ts, tei, sapi);
|
||||
if (!link) {
|
||||
LOGP(DMI, LOGL_ERROR, "didn't find signalling link for "
|
||||
"tei %d, sapi %d\n", tei, sapi);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_set_context(BSC_CTX_BTS, link->trx->bts);
|
||||
switch (link->type) {
|
||||
case E1INP_SIGN_OML:
|
||||
msg->trx = link->trx;
|
||||
bts = msg->trx->bts;
|
||||
ret = bts->model->oml_rcvmsg(msg);
|
||||
break;
|
||||
case E1INP_SIGN_RSL:
|
||||
msg->trx = link->trx;
|
||||
ret = abis_rsl_rcvmsg(msg);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
LOGP(DMI, LOGL_ERROR, "unknown link type %u\n", link->type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case E1INP_TS_TYPE_TRAU:
|
||||
ret = subch_demux_in(&ts->trau.demux, msg->l2h, msgb_l2len(msg));
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
LOGP(DMI, LOGL_ERROR, "unknown TS type %u\n", ts->type);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define TSX_ALLOC_SIZE 4096
|
||||
|
||||
/* called by driver if it wants to transmit on a given TS */
|
||||
struct msgb *e1inp_tx_ts(struct e1inp_ts *e1i_ts,
|
||||
struct e1inp_sign_link **sign_link)
|
||||
{
|
||||
struct e1inp_sign_link *link;
|
||||
struct msgb *msg = NULL;
|
||||
int len;
|
||||
|
||||
switch (e1i_ts->type) {
|
||||
case E1INP_TS_TYPE_SIGN:
|
||||
/* FIXME: implement this round robin */
|
||||
llist_for_each_entry(link, &e1i_ts->sign.sign_links, list) {
|
||||
msg = msgb_dequeue(&link->tx_list);
|
||||
if (msg) {
|
||||
if (sign_link)
|
||||
*sign_link = link;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case E1INP_TS_TYPE_TRAU:
|
||||
msg = msgb_alloc(TSX_ALLOC_SIZE, "TRAU_TX");
|
||||
if (!msg)
|
||||
return NULL;
|
||||
len = subchan_mux_out(&e1i_ts->trau.mux, msg->data, 40);
|
||||
msgb_put(msg, 40);
|
||||
break;
|
||||
default:
|
||||
LOGP(DMI, LOGL_ERROR, "unsupported E1 TS type %u\n", e1i_ts->type);
|
||||
return NULL;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
/* called by driver in case some kind of link state event */
|
||||
int e1inp_event(struct e1inp_ts *ts, int evt, u_int8_t tei, u_int8_t sapi)
|
||||
{
|
||||
struct e1inp_sign_link *link;
|
||||
struct input_signal_data isd;
|
||||
|
||||
link = e1inp_lookup_sign_link(ts, tei, sapi);
|
||||
if (!link)
|
||||
return -EINVAL;
|
||||
|
||||
isd.link_type = link->type;
|
||||
isd.trx = link->trx;
|
||||
isd.tei = tei;
|
||||
isd.sapi = sapi;
|
||||
|
||||
/* report further upwards */
|
||||
dispatch_signal(SS_INPUT, evt, &isd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* register a driver with the E1 core */
|
||||
int e1inp_driver_register(struct e1inp_driver *drv)
|
||||
{
|
||||
llist_add_tail(&drv->list, &e1inp_driver_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct e1inp_driver *e1inp_driver_find(const char *name)
|
||||
{
|
||||
struct e1inp_driver *drv;
|
||||
|
||||
llist_for_each_entry(drv, &e1inp_driver_list, list) {
|
||||
if (!strcasecmp(name, drv->name))
|
||||
return drv;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int e1inp_line_update(struct e1inp_line *line)
|
||||
{
|
||||
struct input_signal_data isd;
|
||||
int rc;
|
||||
|
||||
if (line->driver && line->driver->line_update)
|
||||
rc = line->driver->line_update(line);
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
/* Send a signal to anyone who is interested in new lines being
|
||||
* configured */
|
||||
memset(&isd, 0, sizeof(isd));
|
||||
isd.line = line;
|
||||
dispatch_signal(SS_INPUT, S_INP_LINE_INIT, &isd);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int e1i_sig_cb(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data)
|
||||
{
|
||||
if (subsys != SS_GLOBAL ||
|
||||
signal != S_GLOBAL_SHUTDOWN)
|
||||
return 0;
|
||||
|
||||
if (pcap_fd) {
|
||||
close(pcap_fd);
|
||||
pcap_fd = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void e1inp_misdn_init(void);
|
||||
void e1inp_dahdi_init(void);
|
||||
|
||||
void e1inp_init(void)
|
||||
{
|
||||
tall_sigl_ctx = talloc_named_const(tall_bsc_ctx, 1,
|
||||
"e1inp_sign_link");
|
||||
register_signal_handler(SS_GLOBAL, e1i_sig_cb, NULL);
|
||||
|
||||
e1inp_misdn_init();
|
||||
#ifdef HAVE_DAHDI_USER_H
|
||||
e1inp_dahdi_init();
|
||||
#endif
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/* OpenBSC E1 vty interface */
|
||||
/* (C) 2011 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocom/vty/command.h>
|
||||
#include <osmocom/vty/buffer.h>
|
||||
#include <osmocom/vty/vty.h>
|
||||
#include <osmocom/vty/logging.h>
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/e1_input.h>
|
||||
#include <osmocore/utils.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <openbsc/vty.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
#include "../bscconfig.h"
|
||||
|
||||
#define E1_DRIVER_NAMES "(misdn|dahdi)"
|
||||
#define E1_DRIVER_HELP "mISDN supported E1 Card\n" \
|
||||
"DAHDI supported E1/T1/J1 Card\n"
|
||||
|
||||
DEFUN(cfg_e1line_driver, cfg_e1_line_driver_cmd,
|
||||
"e1_line <0-255> driver " E1_DRIVER_NAMES,
|
||||
"Configure E1/T1/J1 Line\n" "Line Number\n" "Set driver for this line\n"
|
||||
E1_DRIVER_HELP)
|
||||
{
|
||||
struct e1inp_line *line;
|
||||
int e1_nr = atoi(argv[0]);
|
||||
|
||||
line = e1inp_line_get(e1_nr);
|
||||
if (line) {
|
||||
vty_out(vty, "%% Line %d already exists%s", e1_nr, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
line = e1inp_line_create(e1_nr, argv[1]);
|
||||
if (!line) {
|
||||
vty_out(vty, "%% Error creating line %d%s", e1_nr, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_e1inp, cfg_e1inp_cmd,
|
||||
"e1_input",
|
||||
"Configure E1/T1/J1 TDM input\n")
|
||||
{
|
||||
vty->node = E1INP_NODE;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static int e1inp_config_write(struct vty *vty)
|
||||
{
|
||||
struct e1inp_line *line;
|
||||
|
||||
vty_out(vty, "e1_input%s", VTY_NEWLINE);
|
||||
|
||||
llist_for_each_entry(line, &e1inp_line_list, list) {
|
||||
vty_out(vty, " e1_line %u driver %s%s", line->num,
|
||||
line->driver->name, VTY_NEWLINE);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
struct cmd_node e1inp_node = {
|
||||
E1INP_NODE,
|
||||
"%s(e1_input)#",
|
||||
1,
|
||||
};
|
||||
|
||||
int e1inp_vty_init(void)
|
||||
{
|
||||
install_element(CONFIG_NODE, &cfg_e1inp_cmd);
|
||||
install_node(&e1inp_node, e1inp_config_write);
|
||||
install_element(E1INP_NODE, &cfg_e1_line_driver_cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
|
||||
AM_CFLAGS=-Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS)
|
||||
AM_CFLAGS=-Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS)
|
||||
|
||||
noinst_LIBRARIES = libgb.a
|
||||
noinst_HEADERS = gprs_sndcp.h
|
||||
|
||||
if HAVE_LIBGTP
|
||||
@@ -11,16 +10,13 @@ else
|
||||
bin_PROGRAMS = osmo-gbproxy
|
||||
endif
|
||||
|
||||
|
||||
libgb_a_SOURCES = gprs_ns.c gprs_ns_frgre.c gprs_ns_vty.c \
|
||||
gprs_bssgp.c gprs_bssgp_util.c gprs_bssgp_vty.c \
|
||||
gprs_llc.c gprs_llc_vty.c crc24.c
|
||||
|
||||
osmo_gbproxy_SOURCES = gb_proxy.c gb_proxy_main.c gb_proxy_vty.c \
|
||||
$(top_srcdir)/src/socket.c $(top_srcdir)/src/debug.c
|
||||
osmo_gbproxy_LDADD = libgb.a $(top_builddir)/src/libvty.a
|
||||
osmo_gbproxy_SOURCES = gb_proxy.c gb_proxy_main.c gb_proxy_vty.c
|
||||
osmo_gbproxy_LDADD = $(top_builddir)/src/libgb/libgb.a \
|
||||
$(top_builddir)/src/libcommon/libcommon.a
|
||||
|
||||
osmo_sgsn_SOURCES = gprs_gmm.c gprs_sgsn.c gprs_sndcp.c gprs_sndcp_vty.c \
|
||||
sgsn_main.c sgsn_vty.c sgsn_libgtp.c \
|
||||
$(top_srcdir)/src/socket.c $(top_srcdir)/src/debug.c
|
||||
osmo_sgsn_LDADD = libgb.a $(top_builddir)/src/libvty.a -lgtp
|
||||
gprs_llc.c gprs_llc_vty.c crc24.c
|
||||
osmo_sgsn_LDADD = $(top_builddir)/src/libgb/libgb.a \
|
||||
$(top_builddir)/src/libcommon/libcommon.a \
|
||||
-lgtp
|
||||
|
||||
@@ -19,11 +19,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openbsc/crc24.h>
|
||||
|
||||
/* CRC24 table - FCS */
|
||||
static const u_int32_t tbl_crc24[256] = {
|
||||
static const uint32_t tbl_crc24[256] = {
|
||||
0x00000000, 0x00d6a776, 0x00f64557, 0x0020e221, 0x00b78115, 0x00612663, 0x0041c442, 0x00976334,
|
||||
0x00340991, 0x00e2aee7, 0x00c24cc6, 0x0014ebb0, 0x00838884, 0x00552ff2, 0x0075cdd3, 0x00a36aa5,
|
||||
0x00681322, 0x00beb454, 0x009e5675, 0x0048f103, 0x00df9237, 0x00093541, 0x0029d760, 0x00ff7016,
|
||||
@@ -60,7 +59,7 @@ static const u_int32_t tbl_crc24[256] = {
|
||||
|
||||
#define INIT_CRC24 0xffffff
|
||||
|
||||
u_int32_t crc24_calc(u_int32_t fcs, u_int8_t *cp, unsigned int len)
|
||||
uint32_t crc24_calc(uint32_t fcs, uint8_t *cp, unsigned int len)
|
||||
{
|
||||
while (len--)
|
||||
fcs = (fcs >> 8) ^ tbl_crc24[(fcs ^ *cp++) & 0xff];
|
||||
|
||||
@@ -27,11 +27,10 @@
|
||||
#include <errno.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
@@ -28,15 +28,14 @@
|
||||
#include <signal.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocore/process.h>
|
||||
#include <osmocom/core/application.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/debug.h>
|
||||
@@ -47,6 +46,7 @@
|
||||
|
||||
#include <osmocom/vty/command.h>
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
#include <osmocom/vty/logging.h>
|
||||
|
||||
#include "../../bscconfig.h"
|
||||
|
||||
@@ -64,7 +64,6 @@ const char *openbsc_copyright =
|
||||
"This is free software: you are free to change and redistribute it.\r\n"
|
||||
"There is NO WARRANTY, to the extent permitted by law.\r\n";
|
||||
|
||||
static struct log_target *stderr_target;
|
||||
static char *config_file = "osmo_gbproxy.cfg";
|
||||
struct gbproxy_config gbcfg;
|
||||
static int daemonize = 0;
|
||||
@@ -74,7 +73,7 @@ extern struct gbprox_peer *gbprox_peer_sgsn;
|
||||
|
||||
/* call-back function for the NS protocol */
|
||||
static int proxy_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
|
||||
struct msgb *msg, u_int16_t bvci)
|
||||
struct msgb *msg, uint16_t bvci)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@@ -98,7 +97,7 @@ static void signal_handler(int signal)
|
||||
|
||||
switch (signal) {
|
||||
case SIGINT:
|
||||
dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
|
||||
osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
|
||||
sleep(1);
|
||||
exit(0);
|
||||
break;
|
||||
@@ -162,10 +161,10 @@ static void handle_options(int argc, char **argv)
|
||||
print_help();
|
||||
exit(0);
|
||||
case 's':
|
||||
log_set_use_color(stderr_target, 0);
|
||||
log_set_use_color(osmo_stderr_target, 0);
|
||||
break;
|
||||
case 'd':
|
||||
log_parse_category_mask(stderr_target, optarg);
|
||||
log_parse_category_mask(osmo_stderr_target, optarg);
|
||||
break;
|
||||
case 'D':
|
||||
daemonize = 1;
|
||||
@@ -174,10 +173,10 @@ static void handle_options(int argc, char **argv)
|
||||
config_file = strdup(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
log_set_print_timestamp(stderr_target, 1);
|
||||
log_set_print_timestamp(osmo_stderr_target, 1);
|
||||
break;
|
||||
case 'e':
|
||||
log_set_log_level(stderr_target, atoi(optarg));
|
||||
log_set_log_level(osmo_stderr_target, atoi(optarg));
|
||||
break;
|
||||
case 'V':
|
||||
print_version(1);
|
||||
@@ -212,16 +211,13 @@ int main(int argc, char **argv)
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
signal(SIGUSR2, &signal_handler);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
osmo_init_ignore_signals();
|
||||
|
||||
log_init(&log_info);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
osmo_init_logging(&log_info);
|
||||
|
||||
vty_info.copyright = openbsc_copyright;
|
||||
vty_init(&vty_info);
|
||||
logging_vty_add_cmds();
|
||||
logging_vty_add_cmds(&log_info);
|
||||
gbproxy_vty_init();
|
||||
|
||||
handle_options(argc, argv);
|
||||
@@ -239,7 +235,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
gbcfg.nsi = bssgp_nsi;
|
||||
gprs_ns_vty_init(bssgp_nsi);
|
||||
register_signal_handler(SS_NS, &gbprox_signal, NULL);
|
||||
osmo_signal_register_handler(SS_NS, &gbprox_signal, NULL);
|
||||
|
||||
rc = gbproxy_parse_config(config_file, &gbcfg);
|
||||
if (rc < 0) {
|
||||
@@ -279,7 +275,7 @@ int main(int argc, char **argv)
|
||||
gbprox_reset_persistent_nsvcs(bssgp_nsi);
|
||||
|
||||
while (1) {
|
||||
rc = bsc_select_main(0);
|
||||
rc = osmo_select_main(0);
|
||||
if (rc < 0)
|
||||
exit(3);
|
||||
}
|
||||
|
||||
@@ -18,12 +18,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gb_proxy.h>
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <openbsc/db.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
#include <osmocore/signal.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/core/signal.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
@@ -208,7 +208,7 @@ static void mmctx_timer_cb(void *_mm);
|
||||
static void mmctx_timer_start(struct sgsn_mm_ctx *mm, unsigned int T,
|
||||
unsigned int seconds)
|
||||
{
|
||||
if (bsc_timer_pending(&mm->timer))
|
||||
if (osmo_timer_pending(&mm->timer))
|
||||
LOGP(DMM, LOGL_ERROR, "Starting MM timer %u while old "
|
||||
"timer %u pending\n", T, mm->T);
|
||||
mm->T = T;
|
||||
@@ -218,7 +218,7 @@ static void mmctx_timer_start(struct sgsn_mm_ctx *mm, unsigned int T,
|
||||
mm->timer.data = mm;
|
||||
mm->timer.cb = &mmctx_timer_cb;
|
||||
|
||||
bsc_schedule_timer(&mm->timer, seconds, 0);
|
||||
osmo_timer_schedule(&mm->timer, seconds, 0);
|
||||
}
|
||||
|
||||
static void mmctx_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T)
|
||||
@@ -226,7 +226,7 @@ static void mmctx_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T)
|
||||
if (mm->T != T)
|
||||
LOGP(DMM, LOGL_ERROR, "Stopping MM timer %u but "
|
||||
"%u is running\n", T, mm->T);
|
||||
bsc_del_timer(&mm->timer);
|
||||
osmo_timer_del(&mm->timer);
|
||||
}
|
||||
|
||||
/* Send a message through the underlying layer */
|
||||
@@ -463,7 +463,7 @@ static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm, uint8_t *rand,
|
||||
uint8_t *m_rand, *m_cksn;
|
||||
|
||||
DEBUGP(DMM, "<- GPRS AUTH AND CIPHERING REQ (rand = %s)\n",
|
||||
hexdump(rand, 16));
|
||||
osmo_hexdump(rand, 16));
|
||||
|
||||
mmctx2msgid(msg, mm);
|
||||
|
||||
@@ -675,8 +675,9 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
|
||||
/* MS Radio Access Capability 10.5.5.12a */
|
||||
ms_ra_acc_cap_len = *cur++;
|
||||
ms_ra_acc_cap = cur;
|
||||
if (ms_ra_acc_cap_len > 51)
|
||||
if (ms_ra_acc_cap_len > 52)
|
||||
goto err_inval;
|
||||
cur += ms_ra_acc_cap_len;
|
||||
|
||||
/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status */
|
||||
|
||||
@@ -735,8 +736,10 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
|
||||
ctx->cell_id = cid;
|
||||
/* Update MM Context with other data */
|
||||
ctx->drx_parms = drx_par;
|
||||
ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len;
|
||||
memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap, ms_ra_acc_cap_len);
|
||||
ctx->ms_radio_access_capa.len = OSMO_MIN(ms_ra_acc_cap_len,
|
||||
sizeof((ctx->ms_radio_access_capa.buf)));
|
||||
memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap,
|
||||
ctx->ms_radio_access_capa.len);
|
||||
ctx->ms_network_capa.len = msnc_len;
|
||||
memcpy(ctx->ms_network_capa.buf, msnc, msnc_len);
|
||||
|
||||
@@ -754,7 +757,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
|
||||
GPRS_ALGO_GEA0, NULL);
|
||||
|
||||
DEBUGPC(DMM, "\n");
|
||||
return ctx ? gsm48_gmm_authorize(ctx, GMM_T3350_MODE_ATT) : 0;
|
||||
return gsm48_gmm_authorize(ctx, GMM_T3350_MODE_ATT);
|
||||
|
||||
err_inval:
|
||||
DEBUGPC(DMM, "\n");
|
||||
@@ -864,7 +867,7 @@ static int gsm48_tx_gmm_ra_upd_rej(struct msgb *old_msg, uint8_t cause)
|
||||
}
|
||||
|
||||
static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx,
|
||||
uint16_t pdp_status)
|
||||
uint8_t *pdp_status)
|
||||
{
|
||||
struct sgsn_pdp_ctx *pdp, *pdp2;
|
||||
/* 24.008 4.7.5.1.3: If the PDP context status information element is
|
||||
@@ -875,11 +878,20 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx,
|
||||
* being in state PDP-INACTIVE. */
|
||||
|
||||
llist_for_each_entry_safe(pdp, pdp2, &mmctx->pdp_list, list) {
|
||||
if (!(pdp_status & (1 << pdp->nsapi))) {
|
||||
LOGP(DMM, LOGL_NOTICE, "Dropping PDP context for NSAPI=%u "
|
||||
"due to PDP CTX STATUS IE= 0x%04x\n",
|
||||
pdp->nsapi, pdp_status);
|
||||
sgsn_delete_pdp_ctx(pdp);
|
||||
if (pdp->nsapi < 8) {
|
||||
if (!(pdp_status[0] & (1 << pdp->nsapi))) {
|
||||
LOGP(DMM, LOGL_NOTICE, "Dropping PDP context for NSAPI=%u "
|
||||
"due to PDP CTX STATUS IE= 0x%02x%02x\n",
|
||||
pdp->nsapi, pdp_status[1], pdp_status[0]);
|
||||
sgsn_delete_pdp_ctx(pdp);
|
||||
}
|
||||
} else {
|
||||
if (!(pdp_status[1] & (1 << (pdp->nsapi - 8)))) {
|
||||
LOGP(DMM, LOGL_NOTICE, "Dropping PDP context for NSAPI=%u "
|
||||
"due to PDP CTX STATUS IE= 0x%02x%02x\n",
|
||||
pdp->nsapi, pdp_status[1], pdp_status[0]);
|
||||
sgsn_delete_pdp_ctx(pdp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -910,6 +922,9 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
|
||||
/* MS Radio Access Capability 10.5.5.12a */
|
||||
ms_ra_acc_cap_len = *cur++;
|
||||
ms_ra_acc_cap = cur;
|
||||
if (ms_ra_acc_cap_len > 52)
|
||||
return gsm48_tx_gmm_ra_upd_rej(msg, GMM_CAUSE_PROTO_ERR_UNSPEC);
|
||||
cur += ms_ra_acc_cap_len;
|
||||
|
||||
/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status,
|
||||
* DRX parameter, MS network capability */
|
||||
@@ -969,8 +984,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
|
||||
/* Look at PDP Context Status IE and see if MS's view of
|
||||
* activated/deactivated NSAPIs agrees with our view */
|
||||
if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) {
|
||||
uint16_t pdp_status = ntohs(*(uint16_t *)
|
||||
TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS));
|
||||
uint8_t *pdp_status = TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS);
|
||||
process_ms_ctx_status(mmctx, pdp_status);
|
||||
}
|
||||
|
||||
@@ -1087,7 +1101,7 @@ static void mmctx_timer_cb(void *_mm)
|
||||
/* FIXME */
|
||||
break;
|
||||
}
|
||||
bsc_schedule_timer(&mm->timer, GSM0408_T3350_SECS, 0);
|
||||
osmo_timer_schedule(&mm->timer, GSM0408_T3350_SECS, 0);
|
||||
break;
|
||||
case 3360: /* waiting for AUTH AND CIPH RESP */
|
||||
if (mm->num_T_exp >= 5) {
|
||||
@@ -1096,7 +1110,7 @@ static void mmctx_timer_cb(void *_mm)
|
||||
break;
|
||||
}
|
||||
/* FIXME: re-transmit the respective msg and re-start timer */
|
||||
bsc_schedule_timer(&mm->timer, GSM0408_T3360_SECS, 0);
|
||||
osmo_timer_schedule(&mm->timer, GSM0408_T3360_SECS, 0);
|
||||
break;
|
||||
case 3370: /* waiting for IDENTITY RESPONSE */
|
||||
if (mm->num_T_exp >= 5) {
|
||||
@@ -1107,7 +1121,7 @@ static void mmctx_timer_cb(void *_mm)
|
||||
}
|
||||
/* re-tranmit IDENTITY REQUEST and re-start timer */
|
||||
gsm48_tx_gmm_id_req(mm, mm->t3370_id_type);
|
||||
bsc_schedule_timer(&mm->timer, GSM0408_T3370_SECS, 0);
|
||||
osmo_timer_schedule(&mm->timer, GSM0408_T3370_SECS, 0);
|
||||
break;
|
||||
default:
|
||||
LOGP(DMM, LOGL_ERROR, "timer expired in unknown mode %u\n",
|
||||
@@ -1122,7 +1136,7 @@ static void pdpctx_timer_cb(void *_mm);
|
||||
static void pdpctx_timer_start(struct sgsn_pdp_ctx *pdp, unsigned int T,
|
||||
unsigned int seconds)
|
||||
{
|
||||
if (bsc_timer_pending(&pdp->timer))
|
||||
if (osmo_timer_pending(&pdp->timer))
|
||||
LOGP(DMM, LOGL_ERROR, "Starting MM timer %u while old "
|
||||
"timer %u pending\n", T, pdp->T);
|
||||
pdp->T = T;
|
||||
@@ -1132,7 +1146,7 @@ static void pdpctx_timer_start(struct sgsn_pdp_ctx *pdp, unsigned int T,
|
||||
pdp->timer.data = pdp;
|
||||
pdp->timer.cb = &pdpctx_timer_cb;
|
||||
|
||||
bsc_schedule_timer(&pdp->timer, seconds, 0);
|
||||
osmo_timer_schedule(&pdp->timer, seconds, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1457,7 +1471,7 @@ static void pdpctx_timer_cb(void *_pdp)
|
||||
break;
|
||||
}
|
||||
gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL);
|
||||
bsc_schedule_timer(&pdp->timer, GSM0408_T3395_SECS, 0);
|
||||
osmo_timer_schedule(&pdp->timer, GSM0408_T3395_SECS, 0);
|
||||
break;
|
||||
default:
|
||||
LOGP(DMM, LOGL_ERROR, "timer expired in unknown mode %u\n",
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/debug.h>
|
||||
@@ -696,7 +696,7 @@ int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv)
|
||||
struct gprs_llc_llme *llme;
|
||||
/* FIXME: don't use the TLLI but the 0xFFFF unassigned? */
|
||||
llme = llme_alloc(msgb_tlli(msg));
|
||||
LOGP(DLLC, LOGL_DEBUG, "LLC RX: unknown TLLI 0x08x, "
|
||||
LOGP(DLLC, LOGL_DEBUG, "LLC RX: unknown TLLI 0x%08x, "
|
||||
"creating LLME on the fly\n", msgb_tlli(msg));
|
||||
lle = &llme->lle[llhp.sapi];
|
||||
} else {
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/gprs_llc.h>
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define _INT_SNDCP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
/* A fragment queue header, maintaining list of fragments for one N-PDU */
|
||||
struct defrag_state {
|
||||
@@ -20,7 +20,7 @@ struct defrag_state {
|
||||
/* linked list of defrag_queue_entry: one for each fragment */
|
||||
struct llist_head frag_list;
|
||||
|
||||
struct timer_list timer;
|
||||
struct osmo_timer_list timer;
|
||||
};
|
||||
|
||||
/* See 6.7.1.2 Reassembly */
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/gprs_llc.h>
|
||||
|
||||
@@ -29,14 +29,13 @@
|
||||
#include <signal.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <openbsc/gsm_04_08_gprs.h>
|
||||
|
||||
#include <openbsc/signal.h>
|
||||
@@ -501,12 +500,10 @@ int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi,
|
||||
rate_ctr_add(&mmctx->ctrg->ctr[GMM_CTR_BYTES_UDATA_IN], npdu_len);
|
||||
|
||||
return gtp_data_req(pdp->ggsn->gsn, pdp->lib, npdu, npdu_len);
|
||||
|
||||
return gtp_data_req(pdp->ggsn->gsn, pdp->lib, npdu, npdu_len);
|
||||
}
|
||||
|
||||
/* libgtp select loop integration */
|
||||
static int sgsn_gtp_fd_cb(struct bsc_fd *fd, unsigned int what)
|
||||
static int sgsn_gtp_fd_cb(struct osmo_fd *fd, unsigned int what)
|
||||
{
|
||||
struct sgsn_instance *sgi = fd->data;
|
||||
int rc;
|
||||
@@ -539,7 +536,7 @@ static void sgsn_gtp_tmr_start(struct sgsn_instance *sgi)
|
||||
gtp_retranstimeout(sgi->gsn, &next);
|
||||
|
||||
/* re-schedule the timer */
|
||||
bsc_schedule_timer(&sgi->gtp_timer, next.tv_sec, next.tv_usec/1000);
|
||||
osmo_timer_schedule(&sgi->gtp_timer, next.tv_sec, next.tv_usec/1000);
|
||||
}
|
||||
|
||||
/* timer callback for libgtp retransmissions and ping */
|
||||
@@ -571,7 +568,7 @@ int sgsn_gtp_init(struct sgsn_instance *sgi)
|
||||
sgi->gtp_fd0.data = sgi;
|
||||
sgi->gtp_fd0.when = BSC_FD_READ;
|
||||
sgi->gtp_fd0.cb = sgsn_gtp_fd_cb;
|
||||
rc = bsc_register_fd(&sgi->gtp_fd0);
|
||||
rc = osmo_fd_register(&sgi->gtp_fd0);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -580,7 +577,7 @@ int sgsn_gtp_init(struct sgsn_instance *sgi)
|
||||
sgi->gtp_fd1c.data = sgi;
|
||||
sgi->gtp_fd1c.when = BSC_FD_READ;
|
||||
sgi->gtp_fd1c.cb = sgsn_gtp_fd_cb;
|
||||
bsc_register_fd(&sgi->gtp_fd1c);
|
||||
osmo_fd_register(&sgi->gtp_fd1c);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -589,7 +586,7 @@ int sgsn_gtp_init(struct sgsn_instance *sgi)
|
||||
sgi->gtp_fd1u.data = sgi;
|
||||
sgi->gtp_fd1u.when = BSC_FD_READ;
|
||||
sgi->gtp_fd1u.cb = sgsn_gtp_fd_cb;
|
||||
bsc_register_fd(&sgi->gtp_fd1u);
|
||||
osmo_fd_register(&sgi->gtp_fd1u);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
||||
@@ -28,18 +28,19 @@
|
||||
#include <signal.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocore/logging.h>
|
||||
#include <osmocore/process.h>
|
||||
#include <osmocom/core/application.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/process.h>
|
||||
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
#include <osmocom/vty/logging.h>
|
||||
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/debug.h>
|
||||
@@ -62,7 +63,6 @@ void subscr_put() { abort(); }
|
||||
void *tall_bsc_ctx;
|
||||
|
||||
struct gprs_ns_inst *sgsn_nsi;
|
||||
static struct log_target *stderr_target;
|
||||
static int daemonize = 0;
|
||||
const char *openbsc_copyright =
|
||||
"Copyright (C) 2010 Harald Welte and On-Waves\r\n"
|
||||
@@ -80,7 +80,7 @@ struct sgsn_instance *sgsn = &sgsn_inst;
|
||||
|
||||
/* call-back function for the NS protocol */
|
||||
static int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
|
||||
struct msgb *msg, u_int16_t bvci)
|
||||
struct msgb *msg, uint16_t bvci)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@@ -105,7 +105,7 @@ static void signal_handler(int signal)
|
||||
|
||||
switch (signal) {
|
||||
case SIGINT:
|
||||
dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
|
||||
osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
|
||||
sleep(1);
|
||||
exit(0);
|
||||
break;
|
||||
@@ -174,10 +174,10 @@ static void handle_options(int argc, char **argv)
|
||||
print_help();
|
||||
exit(0);
|
||||
case 's':
|
||||
log_set_use_color(stderr_target, 0);
|
||||
log_set_use_color(osmo_stderr_target, 0);
|
||||
break;
|
||||
case 'd':
|
||||
log_parse_category_mask(stderr_target, optarg);
|
||||
log_parse_category_mask(osmo_stderr_target, optarg);
|
||||
break;
|
||||
case 'D':
|
||||
daemonize = 1;
|
||||
@@ -186,10 +186,10 @@ static void handle_options(int argc, char **argv)
|
||||
sgsn_inst.config_file = strdup(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
log_set_print_timestamp(stderr_target, 1);
|
||||
log_set_print_timestamp(osmo_stderr_target, 1);
|
||||
break;
|
||||
case 'e':
|
||||
log_set_log_level(stderr_target, atoi(optarg));
|
||||
log_set_log_level(osmo_stderr_target, atoi(optarg));
|
||||
break;
|
||||
default:
|
||||
/* ignore */
|
||||
@@ -211,16 +211,13 @@ int main(int argc, char **argv)
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
signal(SIGUSR2, &signal_handler);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
log_init(&log_info);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
osmo_init_ignore_signals();
|
||||
osmo_init_logging(&log_info);
|
||||
|
||||
vty_info.copyright = openbsc_copyright;
|
||||
vty_init(&vty_info);
|
||||
logging_vty_add_cmds();
|
||||
logging_vty_add_cmds(&log_info);
|
||||
sgsn_vty_init();
|
||||
|
||||
handle_options(argc, argv);
|
||||
@@ -279,10 +276,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
while (1) {
|
||||
rc = bsc_select_main(0);
|
||||
rc = osmo_select_main(0);
|
||||
if (rc < 0)
|
||||
exit(3);
|
||||
}
|
||||
|
||||
/* not reached */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -18,14 +18,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/utils.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/sgsn.h>
|
||||
@@ -36,6 +35,7 @@
|
||||
|
||||
#include <osmocom/vty/command.h>
|
||||
#include <osmocom/vty/vty.h>
|
||||
#include <osmocom/vty/misc.h>
|
||||
|
||||
#include <pdp.h>
|
||||
|
||||
|
||||
@@ -1,494 +0,0 @@
|
||||
/* OpenBSC Abis input driver for DAHDI */
|
||||
|
||||
/* (C) 2008-2011 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by Digium and Matthew Fredrickson <creslin@digium.com>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../bscconfig.h"
|
||||
|
||||
#ifdef HAVE_DAHDI_USER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <dahdi/user.h>
|
||||
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/subchan_demux.h>
|
||||
#include <openbsc/e1_input.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <osmocore/talloc.h>
|
||||
|
||||
#include "lapd.h"
|
||||
|
||||
#define TS1_ALLOC_SIZE 300
|
||||
|
||||
/* Corresponds to dahdi/user.h, only PRI related events */
|
||||
static const struct value_string dahdi_evt_names[] = {
|
||||
{ DAHDI_EVENT_NONE, "NONE" },
|
||||
{ DAHDI_EVENT_ALARM, "ALARM" },
|
||||
{ DAHDI_EVENT_NOALARM, "NOALARM" },
|
||||
{ DAHDI_EVENT_ABORT, "HDLC ABORT" },
|
||||
{ DAHDI_EVENT_OVERRUN, "HDLC OVERRUN" },
|
||||
{ DAHDI_EVENT_BADFCS, "HDLC BAD FCS" },
|
||||
{ DAHDI_EVENT_REMOVED, "REMOVED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static void handle_dahdi_exception(struct e1inp_ts *ts)
|
||||
{
|
||||
int rc, evt;
|
||||
struct input_signal_data isd;
|
||||
|
||||
rc = ioctl(ts->driver.dahdi.fd.fd, DAHDI_GETEVENT, &evt);
|
||||
if (rc < 0)
|
||||
return;
|
||||
|
||||
LOGP(DMI, LOGL_NOTICE, "Line %u(%s) / TS %u DAHDI EVENT %s\n",
|
||||
ts->line->num, ts->line->name, ts->num,
|
||||
get_value_string(dahdi_evt_names, evt));
|
||||
|
||||
isd.line = ts->line;
|
||||
|
||||
switch (evt) {
|
||||
case DAHDI_EVENT_ALARM:
|
||||
/* we should notify the code that the line is gone */
|
||||
dispatch_signal(SS_INPUT, S_INP_LINE_ALARM, &isd);
|
||||
break;
|
||||
case DAHDI_EVENT_NOALARM:
|
||||
/* alarm has gone, we should re-start the SABM requests */
|
||||
dispatch_signal(SS_INPUT, S_INP_LINE_NOALARM, &isd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int handle_ts1_read(struct bsc_fd *bfd)
|
||||
{
|
||||
struct e1inp_line *line = bfd->data;
|
||||
unsigned int ts_nr = bfd->priv_nr;
|
||||
struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
|
||||
struct msgb *msg = msgb_alloc(TS1_ALLOC_SIZE, "DAHDI TS1");
|
||||
lapd_mph_type prim;
|
||||
unsigned int sapi, tei;
|
||||
int ilen, ret;
|
||||
uint8_t *idata;
|
||||
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = read(bfd->fd, msg->data, TS1_ALLOC_SIZE - 16);
|
||||
if (ret == -1)
|
||||
handle_dahdi_exception(e1i_ts);
|
||||
else if (ret < 0) {
|
||||
perror("read ");
|
||||
}
|
||||
msgb_put(msg, ret - 2);
|
||||
if (ret <= 3) {
|
||||
perror("read ");
|
||||
}
|
||||
|
||||
sapi = msg->data[0] >> 2;
|
||||
tei = msg->data[1] >> 1;
|
||||
|
||||
DEBUGP(DMI, "<= len = %d, sapi(%d) tei(%d)", ret, sapi, tei);
|
||||
|
||||
idata = lapd_receive(e1i_ts->driver.dahdi.lapd, msg->data, msg->len, &ilen, &prim);
|
||||
if (!idata && prim == 0)
|
||||
return -EIO;
|
||||
|
||||
msgb_pull(msg, 2);
|
||||
|
||||
DEBUGP(DMI, "prim %08x\n", prim);
|
||||
|
||||
switch (prim) {
|
||||
case 0:
|
||||
break;
|
||||
case LAPD_MPH_ACTIVATE_IND:
|
||||
DEBUGP(DMI, "MPH_ACTIVATE_IND: sapi(%d) tei(%d)\n", sapi, tei);
|
||||
ret = e1inp_event(e1i_ts, S_INP_TEI_UP, tei, sapi);
|
||||
break;
|
||||
case LAPD_MPH_DEACTIVATE_IND:
|
||||
DEBUGP(DMI, "MPH_DEACTIVATE_IND: sapi(%d) tei(%d)\n", sapi, tei);
|
||||
ret = e1inp_event(e1i_ts, S_INP_TEI_DN, tei, sapi);
|
||||
break;
|
||||
case LAPD_DL_DATA_IND:
|
||||
case LAPD_DL_UNITDATA_IND:
|
||||
if (prim == LAPD_DL_DATA_IND)
|
||||
msg->l2h = msg->data + 2;
|
||||
else
|
||||
msg->l2h = msg->data + 1;
|
||||
DEBUGP(DMI, "RX: %s\n", hexdump(msgb_l2(msg), ret));
|
||||
ret = e1inp_rx_ts(e1i_ts, msg, tei, sapi);
|
||||
break;
|
||||
default:
|
||||
printf("ERROR: unknown prim\n");
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUGP(DMI, "Returned ok\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ts_want_write(struct e1inp_ts *e1i_ts)
|
||||
{
|
||||
/* We never include the DAHDI B-Channel FD into the
|
||||
* writeset, since it doesn't support poll() based
|
||||
* write flow control */
|
||||
if (e1i_ts->type == E1INP_TS_TYPE_TRAU) {
|
||||
fprintf(stderr, "Trying to write TRAU ts\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
e1i_ts->driver.dahdi.fd.when |= BSC_FD_WRITE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void timeout_ts1_write(void *data)
|
||||
{
|
||||
struct e1inp_ts *e1i_ts = (struct e1inp_ts *)data;
|
||||
|
||||
/* trigger write of ts1, due to tx delay timer */
|
||||
ts_want_write(e1i_ts);
|
||||
}
|
||||
|
||||
static void dahdi_write_msg(uint8_t *data, int len, void *cbdata)
|
||||
{
|
||||
struct bsc_fd *bfd = cbdata;
|
||||
struct e1inp_line *line = bfd->data;
|
||||
unsigned int ts_nr = bfd->priv_nr;
|
||||
struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
|
||||
int ret;
|
||||
|
||||
ret = write(bfd->fd, data, len + 2);
|
||||
if (ret == -1)
|
||||
handle_dahdi_exception(e1i_ts);
|
||||
else if (ret < 0)
|
||||
LOGP(DMI, LOGL_NOTICE, "%s write failed %d\n", __func__, ret);
|
||||
}
|
||||
|
||||
static int handle_ts1_write(struct bsc_fd *bfd)
|
||||
{
|
||||
struct e1inp_line *line = bfd->data;
|
||||
unsigned int ts_nr = bfd->priv_nr;
|
||||
struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
|
||||
struct e1inp_sign_link *sign_link;
|
||||
struct msgb *msg;
|
||||
|
||||
bfd->when &= ~BSC_FD_WRITE;
|
||||
|
||||
/* get the next msg for this timeslot */
|
||||
msg = e1inp_tx_ts(e1i_ts, &sign_link);
|
||||
if (!msg) {
|
||||
/* no message after tx delay timer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUGP(DMI, "TX: %s\n", hexdump(msg->data, msg->len));
|
||||
lapd_transmit(e1i_ts->driver.dahdi.lapd, sign_link->tei,
|
||||
sign_link->sapi, msg->data, msg->len);
|
||||
msgb_free(msg);
|
||||
|
||||
/* set tx delay timer for next event */
|
||||
e1i_ts->sign.tx_timer.cb = timeout_ts1_write;
|
||||
e1i_ts->sign.tx_timer.data = e1i_ts;
|
||||
bsc_schedule_timer(&e1i_ts->sign.tx_timer, 0, 50000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int invertbits = 1;
|
||||
|
||||
static u_int8_t flip_table[256];
|
||||
|
||||
static void init_flip_bits(void)
|
||||
{
|
||||
int i,k;
|
||||
|
||||
for (i = 0 ; i < 256 ; i++) {
|
||||
u_int8_t sample = 0 ;
|
||||
for (k = 0; k<8; k++) {
|
||||
if ( i & 1 << k ) sample |= 0x80 >> k;
|
||||
}
|
||||
flip_table[i] = sample;
|
||||
}
|
||||
}
|
||||
|
||||
static u_int8_t * flip_buf_bits ( u_int8_t * buf , int len)
|
||||
{
|
||||
int i;
|
||||
u_int8_t * start = buf;
|
||||
|
||||
for (i = 0 ; i < len; i++) {
|
||||
buf[i] = flip_table[(u_int8_t)buf[i]];
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
#define D_BCHAN_TX_GRAN 160
|
||||
/* write to a B channel TS */
|
||||
static int handle_tsX_write(struct bsc_fd *bfd)
|
||||
{
|
||||
struct e1inp_line *line = bfd->data;
|
||||
unsigned int ts_nr = bfd->priv_nr;
|
||||
struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
|
||||
u_int8_t tx_buf[D_BCHAN_TX_GRAN];
|
||||
struct subch_mux *mx = &e1i_ts->trau.mux;
|
||||
int ret;
|
||||
|
||||
ret = subchan_mux_out(mx, tx_buf, D_BCHAN_TX_GRAN);
|
||||
|
||||
if (ret != D_BCHAN_TX_GRAN) {
|
||||
fprintf(stderr, "Huh, got ret of %d\n", ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUGP(DMIB, "BCHAN TX: %s\n",
|
||||
hexdump(tx_buf, D_BCHAN_TX_GRAN));
|
||||
|
||||
if (invertbits) {
|
||||
flip_buf_bits(tx_buf, ret);
|
||||
}
|
||||
|
||||
ret = write(bfd->fd, tx_buf, ret);
|
||||
if (ret < D_BCHAN_TX_GRAN)
|
||||
fprintf(stderr, "send returns %d instead of %d\n", ret,
|
||||
D_BCHAN_TX_GRAN);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define D_TSX_ALLOC_SIZE (D_BCHAN_TX_GRAN)
|
||||
/* FIXME: read from a B channel TS */
|
||||
static int handle_tsX_read(struct bsc_fd *bfd)
|
||||
{
|
||||
struct e1inp_line *line = bfd->data;
|
||||
unsigned int ts_nr = bfd->priv_nr;
|
||||
struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
|
||||
struct msgb *msg = msgb_alloc(D_TSX_ALLOC_SIZE, "DAHDI TSx");
|
||||
int ret;
|
||||
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = read(bfd->fd, msg->data, D_TSX_ALLOC_SIZE);
|
||||
if (ret < 0 || ret != D_TSX_ALLOC_SIZE) {
|
||||
fprintf(stderr, "read error %d %s\n", ret, strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (invertbits) {
|
||||
flip_buf_bits(msg->data, ret);
|
||||
}
|
||||
|
||||
msgb_put(msg, ret);
|
||||
|
||||
msg->l2h = msg->data;
|
||||
DEBUGP(DMIB, "BCHAN RX: %s\n",
|
||||
hexdump(msgb_l2(msg), ret));
|
||||
ret = e1inp_rx_ts(e1i_ts, msg, 0, 0);
|
||||
/* physical layer indicates that data has been sent,
|
||||
* we thus can send some more data */
|
||||
ret = handle_tsX_write(bfd);
|
||||
msgb_free(msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* callback from select.c in case one of the fd's can be read/written */
|
||||
static int dahdi_fd_cb(struct bsc_fd *bfd, unsigned int what)
|
||||
{
|
||||
struct e1inp_line *line = bfd->data;
|
||||
unsigned int ts_nr = bfd->priv_nr;
|
||||
unsigned int idx = ts_nr-1;
|
||||
struct e1inp_ts *e1i_ts = &line->ts[idx];
|
||||
int rc = 0;
|
||||
|
||||
switch (e1i_ts->type) {
|
||||
case E1INP_TS_TYPE_SIGN:
|
||||
if (what & BSC_FD_EXCEPT)
|
||||
handle_dahdi_exception(e1i_ts);
|
||||
if (what & BSC_FD_READ)
|
||||
rc = handle_ts1_read(bfd);
|
||||
if (what & BSC_FD_WRITE)
|
||||
rc = handle_ts1_write(bfd);
|
||||
break;
|
||||
case E1INP_TS_TYPE_TRAU:
|
||||
if (what & BSC_FD_EXCEPT)
|
||||
handle_dahdi_exception(e1i_ts);
|
||||
if (what & BSC_FD_READ)
|
||||
rc = handle_tsX_read(bfd);
|
||||
if (what & BSC_FD_WRITE)
|
||||
rc = handle_tsX_write(bfd);
|
||||
/* We never include the DAHDI B-Channel FD into the
|
||||
* writeset, since it doesn't support poll() based
|
||||
* write flow control */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown E1 TS type %u\n", e1i_ts->type);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dahdi_e1_line_update(struct e1inp_line *line);
|
||||
|
||||
struct e1inp_driver dahdi_driver = {
|
||||
.name = "dahdi",
|
||||
.want_write = ts_want_write,
|
||||
.line_update = &dahdi_e1_line_update,
|
||||
};
|
||||
|
||||
void dahdi_set_bufinfo(int fd, int as_sigchan)
|
||||
{
|
||||
struct dahdi_bufferinfo bi;
|
||||
int x = 0;
|
||||
|
||||
if (ioctl(fd, DAHDI_GET_BUFINFO, &bi)) {
|
||||
fprintf(stderr, "Error getting bufinfo\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (as_sigchan) {
|
||||
bi.numbufs = 4;
|
||||
bi.bufsize = 512;
|
||||
} else {
|
||||
bi.numbufs = 8;
|
||||
bi.bufsize = D_BCHAN_TX_GRAN;
|
||||
bi.txbufpolicy = DAHDI_POLICY_WHEN_FULL;
|
||||
}
|
||||
|
||||
if (ioctl(fd, DAHDI_SET_BUFINFO, &bi)) {
|
||||
fprintf(stderr, "Error setting bufinfo\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (!as_sigchan) {
|
||||
if (ioctl(fd, DAHDI_AUDIOMODE, &x)) {
|
||||
fprintf(stderr, "Error setting bufinfo\n");
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
int one = 1;
|
||||
ioctl(fd, DAHDI_HDLCFCSMODE, &one);
|
||||
/* we cannot reliably check for the ioctl return value here
|
||||
* as this command will fail if the slot _already_ was a
|
||||
* signalling slot before :( */
|
||||
}
|
||||
}
|
||||
|
||||
static int dahdi_e1_setup(struct e1inp_line *line)
|
||||
{
|
||||
int ts, ret;
|
||||
|
||||
/* TS0 is CRC4, don't need any fd for it */
|
||||
for (ts = 1; ts < NUM_E1_TS; ts++) {
|
||||
unsigned int idx = ts-1;
|
||||
char openstr[128];
|
||||
struct e1inp_ts *e1i_ts = &line->ts[idx];
|
||||
struct bsc_fd *bfd = &e1i_ts->driver.dahdi.fd;
|
||||
|
||||
bfd->data = line;
|
||||
bfd->priv_nr = ts;
|
||||
bfd->cb = dahdi_fd_cb;
|
||||
snprintf(openstr, sizeof(openstr), "/dev/dahdi/%d", ts);
|
||||
|
||||
switch (e1i_ts->type) {
|
||||
case E1INP_TS_TYPE_NONE:
|
||||
continue;
|
||||
break;
|
||||
case E1INP_TS_TYPE_SIGN:
|
||||
bfd->fd = open(openstr, O_RDWR | O_NONBLOCK);
|
||||
if (bfd->fd == -1) {
|
||||
fprintf(stderr, "%s could not open %s %s\n",
|
||||
__func__, openstr, strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
bfd->when = BSC_FD_READ | BSC_FD_EXCEPT;
|
||||
dahdi_set_bufinfo(bfd->fd, 1);
|
||||
e1i_ts->driver.dahdi.lapd = lapd_instance_alloc(1, dahdi_write_msg, bfd);
|
||||
break;
|
||||
case E1INP_TS_TYPE_TRAU:
|
||||
bfd->fd = open(openstr, O_RDWR | O_NONBLOCK);
|
||||
if (bfd->fd == -1) {
|
||||
fprintf(stderr, "%s could not open %s %s\n",
|
||||
__func__, openstr, strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
dahdi_set_bufinfo(bfd->fd, 0);
|
||||
/* We never include the DAHDI B-Channel FD into the
|
||||
* writeset, since it doesn't support poll() based
|
||||
* write flow control */
|
||||
bfd->when = BSC_FD_READ | BSC_FD_EXCEPT;// | BSC_FD_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bfd->fd < 0) {
|
||||
fprintf(stderr, "%s could not open %s %s\n",
|
||||
__func__, openstr, strerror(errno));
|
||||
return bfd->fd;
|
||||
}
|
||||
|
||||
ret = bsc_register_fd(bfd);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "could not register FD: %s\n",
|
||||
strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dahdi_e1_line_update(struct e1inp_line *line)
|
||||
{
|
||||
if (line->driver != &dahdi_driver)
|
||||
return -EINVAL;
|
||||
|
||||
return dahdi_e1_setup(line);
|
||||
}
|
||||
|
||||
int e1inp_dahdi_init(void)
|
||||
{
|
||||
init_flip_bits();
|
||||
|
||||
/* register the driver with the core */
|
||||
return e1inp_driver_register(&dahdi_driver);
|
||||
}
|
||||
|
||||
#endif /* HAVE_DAHDI_USER_H */
|
||||
@@ -1,797 +0,0 @@
|
||||
/* OpenBSC Abis input driver for ip.access */
|
||||
|
||||
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2010 by Holger Hans Peter Freyther
|
||||
* (C) 2010 by On-Waves
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/subchan_demux.h>
|
||||
#include <openbsc/e1_input.h>
|
||||
#include <openbsc/ipaccess.h>
|
||||
#include <openbsc/socket.h>
|
||||
#include <openbsc/signal.h>
|
||||
|
||||
#define PRIV_OML 1
|
||||
#define PRIV_RSL 2
|
||||
|
||||
/* data structure for one E1 interface with A-bis */
|
||||
struct ia_e1_handle {
|
||||
struct bsc_fd listen_fd;
|
||||
struct bsc_fd rsl_listen_fd;
|
||||
struct gsm_network *gsmnet;
|
||||
};
|
||||
|
||||
static struct ia_e1_handle *e1h;
|
||||
|
||||
|
||||
#define TS1_ALLOC_SIZE 900
|
||||
|
||||
static const u_int8_t pong[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_PONG };
|
||||
static const u_int8_t id_ack[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK };
|
||||
static const u_int8_t id_req[] = { 0, 17, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_GET,
|
||||
0x01, IPAC_IDTAG_UNIT,
|
||||
0x01, IPAC_IDTAG_MACADDR,
|
||||
0x01, IPAC_IDTAG_LOCATION1,
|
||||
0x01, IPAC_IDTAG_LOCATION2,
|
||||
0x01, IPAC_IDTAG_EQUIPVERS,
|
||||
0x01, IPAC_IDTAG_SWVERSION,
|
||||
0x01, IPAC_IDTAG_UNITNAME,
|
||||
0x01, IPAC_IDTAG_SERNR,
|
||||
};
|
||||
|
||||
static const char *idtag_names[] = {
|
||||
[IPAC_IDTAG_SERNR] = "Serial_Number",
|
||||
[IPAC_IDTAG_UNITNAME] = "Unit_Name",
|
||||
[IPAC_IDTAG_LOCATION1] = "Location_1",
|
||||
[IPAC_IDTAG_LOCATION2] = "Location_2",
|
||||
[IPAC_IDTAG_EQUIPVERS] = "Equipment_Version",
|
||||
[IPAC_IDTAG_SWVERSION] = "Software_Version",
|
||||
[IPAC_IDTAG_IPADDR] = "IP_Address",
|
||||
[IPAC_IDTAG_MACADDR] = "MAC_Address",
|
||||
[IPAC_IDTAG_UNIT] = "Unit_ID",
|
||||
};
|
||||
|
||||
static const char *ipac_idtag_name(int tag)
|
||||
{
|
||||
if (tag >= ARRAY_SIZE(idtag_names))
|
||||
return "unknown";
|
||||
|
||||
return idtag_names[tag];
|
||||
}
|
||||
|
||||
int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len)
|
||||
{
|
||||
u_int8_t t_len;
|
||||
u_int8_t t_tag;
|
||||
u_int8_t *cur = buf;
|
||||
|
||||
memset(dec, 0, sizeof(*dec));
|
||||
|
||||
while (len >= 2) {
|
||||
len -= 2;
|
||||
t_len = *cur++;
|
||||
t_tag = *cur++;
|
||||
|
||||
if (t_len > len + 1) {
|
||||
LOGP(DMI, LOGL_ERROR, "The tag does not fit: %d\n", t_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUGPC(DMI, "%s='%s' ", ipac_idtag_name(t_tag), cur);
|
||||
|
||||
dec->lv[t_tag].len = t_len;
|
||||
dec->lv[t_tag].val = cur;
|
||||
|
||||
cur += t_len;
|
||||
len -= t_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct gsm_bts *find_bts_by_unitid(struct gsm_network *net,
|
||||
u_int16_t site_id, u_int16_t bts_id)
|
||||
{
|
||||
struct gsm_bts *bts;
|
||||
|
||||
llist_for_each_entry(bts, &net->bts_list, list) {
|
||||
|
||||
if (!is_ipaccess_bts(bts))
|
||||
continue;
|
||||
|
||||
if (bts->ip_access.site_id == site_id &&
|
||||
bts->ip_access.bts_id == bts_id)
|
||||
return bts;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int parse_unitid(const char *str, u_int16_t *site_id, u_int16_t *bts_id,
|
||||
u_int16_t *trx_id)
|
||||
{
|
||||
unsigned long ul;
|
||||
char *endptr;
|
||||
const char *nptr;
|
||||
|
||||
nptr = str;
|
||||
ul = strtoul(nptr, &endptr, 10);
|
||||
if (endptr <= nptr)
|
||||
return -EINVAL;
|
||||
if (site_id)
|
||||
*site_id = ul & 0xffff;
|
||||
|
||||
if (*endptr++ != '/')
|
||||
return -EINVAL;
|
||||
|
||||
nptr = endptr;
|
||||
ul = strtoul(nptr, &endptr, 10);
|
||||
if (endptr <= nptr)
|
||||
return -EINVAL;
|
||||
if (bts_id)
|
||||
*bts_id = ul & 0xffff;
|
||||
|
||||
if (*endptr++ != '/')
|
||||
return -EINVAL;
|
||||
|
||||
nptr = endptr;
|
||||
ul = strtoul(nptr, &endptr, 10);
|
||||
if (endptr <= nptr)
|
||||
return -EINVAL;
|
||||
if (trx_id)
|
||||
*trx_id = ul & 0xffff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* send the id ack */
|
||||
int ipaccess_send_id_ack(int fd)
|
||||
{
|
||||
return write(fd, id_ack, sizeof(id_ack));
|
||||
}
|
||||
|
||||
int ipaccess_send_id_req(int fd)
|
||||
{
|
||||
return write(fd, id_req, sizeof(id_req));
|
||||
}
|
||||
|
||||
/* base handling of the ip.access protocol */
|
||||
int ipaccess_rcvmsg_base(struct msgb *msg,
|
||||
struct bsc_fd *bfd)
|
||||
{
|
||||
u_int8_t msg_type = *(msg->l2h);
|
||||
int ret = 0;
|
||||
|
||||
switch (msg_type) {
|
||||
case IPAC_MSGT_PING:
|
||||
ret = write(bfd->fd, pong, sizeof(pong));
|
||||
break;
|
||||
case IPAC_MSGT_PONG:
|
||||
DEBUGP(DMI, "PONG!\n");
|
||||
break;
|
||||
case IPAC_MSGT_ID_ACK:
|
||||
DEBUGP(DMI, "ID_ACK? -> ACK!\n");
|
||||
ret = ipaccess_send_id_ack(bfd->fd);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
|
||||
struct bsc_fd *bfd)
|
||||
{
|
||||
struct tlv_parsed tlvp;
|
||||
u_int8_t msg_type = *(msg->l2h);
|
||||
u_int16_t site_id = 0, bts_id = 0, trx_id = 0;
|
||||
struct gsm_bts *bts;
|
||||
char *unitid;
|
||||
int len;
|
||||
|
||||
/* handle base messages */
|
||||
ipaccess_rcvmsg_base(msg, bfd);
|
||||
|
||||
switch (msg_type) {
|
||||
case IPAC_MSGT_ID_RESP:
|
||||
DEBUGP(DMI, "ID_RESP ");
|
||||
/* parse tags, search for Unit ID */
|
||||
ipaccess_idtag_parse(&tlvp, (u_int8_t *)msg->l2h + 2,
|
||||
msgb_l2len(msg)-2);
|
||||
DEBUGP(DMI, "\n");
|
||||
|
||||
if (!TLVP_PRESENT(&tlvp, IPAC_IDTAG_UNIT))
|
||||
break;
|
||||
|
||||
len = TLVP_LEN(&tlvp, IPAC_IDTAG_UNIT);
|
||||
if (len < 1)
|
||||
break;
|
||||
|
||||
/* lookup BTS, create sign_link, ... */
|
||||
unitid = (char *) TLVP_VAL(&tlvp, IPAC_IDTAG_UNIT);
|
||||
unitid[len - 1] = '\0';
|
||||
parse_unitid(unitid, &site_id, &bts_id, &trx_id);
|
||||
bts = find_bts_by_unitid(e1h->gsmnet, site_id, bts_id);
|
||||
if (!bts) {
|
||||
LOGP(DINP, LOGL_ERROR, "Unable to find BTS configuration for "
|
||||
" %u/%u/%u, disconnecting\n", site_id, bts_id,
|
||||
trx_id);
|
||||
return -EIO;
|
||||
}
|
||||
DEBUGP(DINP, "Identified BTS %u/%u/%u\n", site_id, bts_id, trx_id);
|
||||
if (bfd->priv_nr == PRIV_OML) {
|
||||
/* drop any old oml connection */
|
||||
ipaccess_drop_oml(bts);
|
||||
bts->oml_link = e1inp_sign_link_create(&line->ts[PRIV_OML - 1],
|
||||
E1INP_SIGN_OML, bts->c0,
|
||||
bts->oml_tei, 0);
|
||||
} else if (bfd->priv_nr == PRIV_RSL) {
|
||||
struct e1inp_ts *e1i_ts;
|
||||
struct bsc_fd *newbfd;
|
||||
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_id);
|
||||
|
||||
/* drop any old rsl connection */
|
||||
ipaccess_drop_rsl(trx);
|
||||
|
||||
if (!bts->oml_link) {
|
||||
bsc_unregister_fd(bfd);
|
||||
close(bfd->fd);
|
||||
bfd->fd = -1;
|
||||
talloc_free(bfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bfd->data = line = bts->oml_link->ts->line;
|
||||
e1i_ts = &line->ts[PRIV_RSL + trx_id - 1];
|
||||
newbfd = &e1i_ts->driver.ipaccess.fd;
|
||||
e1inp_ts_config(e1i_ts, line, E1INP_TS_TYPE_SIGN);
|
||||
|
||||
trx->rsl_link = e1inp_sign_link_create(e1i_ts,
|
||||
E1INP_SIGN_RSL, trx,
|
||||
trx->rsl_tei, 0);
|
||||
trx->rsl_link->ts->sign.delay = 0;
|
||||
|
||||
/* get rid of our old temporary bfd */
|
||||
memcpy(newbfd, bfd, sizeof(*newbfd));
|
||||
newbfd->priv_nr = PRIV_RSL + trx_id;
|
||||
bsc_unregister_fd(bfd);
|
||||
bfd->fd = -1;
|
||||
talloc_free(bfd);
|
||||
bsc_register_fd(newbfd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OML_UP 0x0001
|
||||
#define RSL_UP 0x0002
|
||||
|
||||
/*
|
||||
* read one ipa message from the socket
|
||||
* return NULL in case of error
|
||||
*/
|
||||
struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error)
|
||||
{
|
||||
struct msgb *msg = msgb_alloc(TS1_ALLOC_SIZE, "Abis/IP");
|
||||
struct ipaccess_head *hh;
|
||||
int len, ret = 0;
|
||||
|
||||
if (!msg) {
|
||||
*error = -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* first read our 3-byte header */
|
||||
hh = (struct ipaccess_head *) msg->data;
|
||||
ret = recv(bfd->fd, msg->data, sizeof(*hh), 0);
|
||||
if (ret == 0) {
|
||||
msgb_free(msg);
|
||||
*error = ret;
|
||||
return NULL;
|
||||
} else if (ret != sizeof(*hh)) {
|
||||
if (errno != EAGAIN)
|
||||
LOGP(DINP, LOGL_ERROR, "recv error %d %s\n", ret, strerror(errno));
|
||||
msgb_free(msg);
|
||||
*error = ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msgb_put(msg, ret);
|
||||
|
||||
/* then read te length as specified in header */
|
||||
msg->l2h = msg->data + sizeof(*hh);
|
||||
len = ntohs(hh->len);
|
||||
|
||||
if (len < 0 || TS1_ALLOC_SIZE < len + sizeof(*hh)) {
|
||||
LOGP(DINP, LOGL_ERROR, "Can not read this packet. %d avail\n", len);
|
||||
msgb_free(msg);
|
||||
*error = -EIO;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = recv(bfd->fd, msg->l2h, len, 0);
|
||||
if (ret < len) {
|
||||
LOGP(DINP, LOGL_ERROR, "short read! Got %d from %d\n", ret, len);
|
||||
msgb_free(msg);
|
||||
*error = -EIO;
|
||||
return NULL;
|
||||
}
|
||||
msgb_put(msg, ret);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
int ipaccess_drop_oml(struct gsm_bts *bts)
|
||||
{
|
||||
struct gsm_bts_trx *trx;
|
||||
struct e1inp_ts *ts;
|
||||
struct e1inp_line *line;
|
||||
struct bsc_fd *bfd;
|
||||
|
||||
if (!bts || !bts->oml_link)
|
||||
return -1;
|
||||
|
||||
/* send OML down */
|
||||
ts = bts->oml_link->ts;
|
||||
line = ts->line;
|
||||
e1inp_event(ts, S_INP_TEI_DN, bts->oml_link->tei, bts->oml_link->sapi);
|
||||
|
||||
bfd = &ts->driver.ipaccess.fd;
|
||||
bsc_unregister_fd(bfd);
|
||||
close(bfd->fd);
|
||||
bfd->fd = -1;
|
||||
|
||||
/* clean up OML and RSL */
|
||||
e1inp_sign_link_destroy(bts->oml_link);
|
||||
bts->oml_link = NULL;
|
||||
bts->ip_access.flags = 0;
|
||||
|
||||
/* drop all RSL connections too */
|
||||
llist_for_each_entry(trx, &bts->trx_list, list)
|
||||
ipaccess_drop_rsl(trx);
|
||||
|
||||
/* kill the E1 line now... as we have no one left to use it */
|
||||
talloc_free(line);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ipaccess_drop(struct e1inp_ts *ts, struct bsc_fd *bfd)
|
||||
{
|
||||
struct e1inp_sign_link *link;
|
||||
int bts_nr;
|
||||
|
||||
if (!ts) {
|
||||
/*
|
||||
* If we don't have a TS this means that this is a RSL
|
||||
* connection but we are not past the authentication
|
||||
* handling yet. So we can safely delete this bfd and
|
||||
* wait for a reconnect.
|
||||
*/
|
||||
bsc_unregister_fd(bfd);
|
||||
close(bfd->fd);
|
||||
bfd->fd = -1;
|
||||
talloc_free(bfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* attempt to find a signalling link */
|
||||
if (ts->type == E1INP_TS_TYPE_SIGN) {
|
||||
llist_for_each_entry(link, &ts->sign.sign_links, list) {
|
||||
bts_nr = link->trx->bts->bts_nr;
|
||||
/* we have issues just reconnecting RLS so we drop OML */
|
||||
ipaccess_drop_oml(link->trx->bts);
|
||||
return bts_nr;
|
||||
}
|
||||
}
|
||||
|
||||
/* error case */
|
||||
LOGP(DINP, LOGL_ERROR, "Failed to find a signalling link for ts: %p\n", ts);
|
||||
bsc_unregister_fd(bfd);
|
||||
close(bfd->fd);
|
||||
bfd->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ipaccess_drop_rsl(struct gsm_bts_trx *trx)
|
||||
{
|
||||
struct bsc_fd *bfd;
|
||||
struct e1inp_ts *ts;
|
||||
|
||||
if (!trx || !trx->rsl_link)
|
||||
return -1;
|
||||
|
||||
/* send RSL down */
|
||||
ts = trx->rsl_link->ts;
|
||||
e1inp_event(ts, S_INP_TEI_DN, trx->rsl_link->tei, trx->rsl_link->sapi);
|
||||
|
||||
/* close the socket */
|
||||
bfd = &ts->driver.ipaccess.fd;
|
||||
bsc_unregister_fd(bfd);
|
||||
close(bfd->fd);
|
||||
bfd->fd = -1;
|
||||
|
||||
/* destroy */
|
||||
e1inp_sign_link_destroy(trx->rsl_link);
|
||||
trx->rsl_link = NULL;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int handle_ts1_read(struct bsc_fd *bfd)
|
||||
{
|
||||
struct e1inp_line *line = bfd->data;
|
||||
unsigned int ts_nr = bfd->priv_nr;
|
||||
struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
|
||||
struct e1inp_sign_link *link;
|
||||
struct msgb *msg;
|
||||
struct ipaccess_head *hh;
|
||||
int ret = 0, error;
|
||||
|
||||
msg = ipaccess_read_msg(bfd, &error);
|
||||
if (!msg) {
|
||||
if (error == 0) {
|
||||
int ret = ipaccess_drop(e1i_ts, bfd);
|
||||
if (ret >= 0)
|
||||
LOGP(DINP, LOGL_NOTICE, "BTS %u disappeared, dead socket\n",
|
||||
ret);
|
||||
else
|
||||
LOGP(DINP, LOGL_NOTICE, "unknown BTS disappeared, dead socket\n");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
DEBUGP(DMI, "RX %u: %s\n", ts_nr, hexdump(msgb_l2(msg), msgb_l2len(msg)));
|
||||
|
||||
hh = (struct ipaccess_head *) msg->data;
|
||||
if (hh->proto == IPAC_PROTO_IPACCESS) {
|
||||
ret = ipaccess_rcvmsg(line, msg, bfd);
|
||||
if (ret < 0)
|
||||
ipaccess_drop(e1i_ts, bfd);
|
||||
msgb_free(msg);
|
||||
return ret;
|
||||
}
|
||||
/* BIG FAT WARNING: bfd might no longer exist here, since ipaccess_rcvmsg()
|
||||
* might have free'd it !!! */
|
||||
|
||||
link = e1inp_lookup_sign_link(e1i_ts, hh->proto, 0);
|
||||
if (!link) {
|
||||
LOGP(DINP, LOGL_ERROR, "no matching signalling link for "
|
||||
"hh->proto=0x%02x\n", hh->proto);
|
||||
msgb_free(msg);
|
||||
return -EIO;
|
||||
}
|
||||
msg->trx = link->trx;
|
||||
|
||||
switch (link->type) {
|
||||
case E1INP_SIGN_RSL:
|
||||
if (!(msg->trx->bts->ip_access.flags & (RSL_UP << msg->trx->nr))) {
|
||||
e1inp_event(e1i_ts, S_INP_TEI_UP, link->tei, link->sapi);
|
||||
msg->trx->bts->ip_access.flags |= (RSL_UP << msg->trx->nr);
|
||||
}
|
||||
ret = abis_rsl_rcvmsg(msg);
|
||||
break;
|
||||
case E1INP_SIGN_OML:
|
||||
if (!(msg->trx->bts->ip_access.flags & OML_UP)) {
|
||||
e1inp_event(e1i_ts, S_INP_TEI_UP, link->tei, link->sapi);
|
||||
msg->trx->bts->ip_access.flags |= OML_UP;
|
||||
}
|
||||
ret = abis_nm_rcvmsg(msg);
|
||||
break;
|
||||
default:
|
||||
LOGP(DINP, LOGL_NOTICE, "Unknown IP.access protocol proto=0x%02x\n", hh->proto);
|
||||
msgb_free(msg);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ipaccess_prepend_header(struct msgb *msg, int proto)
|
||||
{
|
||||
struct ipaccess_head *hh;
|
||||
|
||||
/* prepend the ip.access header */
|
||||
hh = (struct ipaccess_head *) msgb_push(msg, sizeof(*hh));
|
||||
hh->len = htons(msg->len - sizeof(*hh));
|
||||
hh->proto = proto;
|
||||
}
|
||||
|
||||
static int ts_want_write(struct e1inp_ts *e1i_ts)
|
||||
{
|
||||
e1i_ts->driver.ipaccess.fd.when |= BSC_FD_WRITE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void timeout_ts1_write(void *data)
|
||||
{
|
||||
struct e1inp_ts *e1i_ts = (struct e1inp_ts *)data;
|
||||
|
||||
/* trigger write of ts1, due to tx delay timer */
|
||||
ts_want_write(e1i_ts);
|
||||
}
|
||||
|
||||
static int handle_ts1_write(struct bsc_fd *bfd)
|
||||
{
|
||||
struct e1inp_line *line = bfd->data;
|
||||
unsigned int ts_nr = bfd->priv_nr;
|
||||
struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
|
||||
struct e1inp_sign_link *sign_link;
|
||||
struct msgb *msg;
|
||||
u_int8_t proto;
|
||||
int ret;
|
||||
|
||||
bfd->when &= ~BSC_FD_WRITE;
|
||||
|
||||
/* get the next msg for this timeslot */
|
||||
msg = e1inp_tx_ts(e1i_ts, &sign_link);
|
||||
if (!msg) {
|
||||
/* no message after tx delay timer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (sign_link->type) {
|
||||
case E1INP_SIGN_OML:
|
||||
proto = IPAC_PROTO_OML;
|
||||
break;
|
||||
case E1INP_SIGN_RSL:
|
||||
proto = IPAC_PROTO_RSL;
|
||||
break;
|
||||
default:
|
||||
msgb_free(msg);
|
||||
bfd->when |= BSC_FD_WRITE; /* come back for more msg */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msg->l2h = msg->data;
|
||||
ipaccess_prepend_header(msg, sign_link->tei);
|
||||
|
||||
DEBUGP(DMI, "TX %u: %s\n", ts_nr, hexdump(msg->l2h, msgb_l2len(msg)));
|
||||
|
||||
ret = send(bfd->fd, msg->data, msg->len, 0);
|
||||
msgb_free(msg);
|
||||
|
||||
/* set tx delay timer for next event */
|
||||
e1i_ts->sign.tx_timer.cb = timeout_ts1_write;
|
||||
e1i_ts->sign.tx_timer.data = e1i_ts;
|
||||
|
||||
/* Reducing this might break the nanoBTS 900 init. */
|
||||
bsc_schedule_timer(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* callback from select.c in case one of the fd's can be read/written */
|
||||
static int ipaccess_fd_cb(struct bsc_fd *bfd, unsigned int what)
|
||||
{
|
||||
struct e1inp_line *line = bfd->data;
|
||||
unsigned int ts_nr = bfd->priv_nr;
|
||||
unsigned int idx = ts_nr-1;
|
||||
struct e1inp_ts *e1i_ts;
|
||||
int rc = 0;
|
||||
|
||||
/* In case of early RSL we might not yet have a line */
|
||||
|
||||
if (line)
|
||||
e1i_ts = &line->ts[idx];
|
||||
|
||||
if (!line || e1i_ts->type == E1INP_TS_TYPE_SIGN) {
|
||||
if (what & BSC_FD_READ)
|
||||
rc = handle_ts1_read(bfd);
|
||||
if (what & BSC_FD_WRITE)
|
||||
rc = handle_ts1_write(bfd);
|
||||
} else
|
||||
LOGP(DINP, LOGL_ERROR, "unknown E1 TS type %u\n", e1i_ts->type);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct e1inp_driver ipaccess_driver = {
|
||||
.name = "ip.access",
|
||||
.want_write = ts_want_write,
|
||||
.default_delay = 0,
|
||||
};
|
||||
|
||||
/* callback of the OML listening filedescriptor */
|
||||
static int listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
|
||||
{
|
||||
int ret;
|
||||
int idx = 0;
|
||||
int i;
|
||||
struct e1inp_line *line;
|
||||
struct e1inp_ts *e1i_ts;
|
||||
struct bsc_fd *bfd;
|
||||
struct sockaddr_in sa;
|
||||
socklen_t sa_len = sizeof(sa);
|
||||
|
||||
if (!(what & BSC_FD_READ))
|
||||
return 0;
|
||||
|
||||
ret = accept(listen_bfd->fd, (struct sockaddr *) &sa, &sa_len);
|
||||
if (ret < 0) {
|
||||
perror("accept");
|
||||
return ret;
|
||||
}
|
||||
LOGP(DINP, LOGL_NOTICE, "accept()ed new OML link from %s\n",
|
||||
inet_ntoa(sa.sin_addr));
|
||||
|
||||
line = talloc_zero(tall_bsc_ctx, struct e1inp_line);
|
||||
if (!line) {
|
||||
close(ret);
|
||||
return -ENOMEM;
|
||||
}
|
||||
line->driver = &ipaccess_driver;
|
||||
//line->driver_data = e1h;
|
||||
/* create virrtual E1 timeslots for signalling */
|
||||
e1inp_ts_config(&line->ts[1-1], line, E1INP_TS_TYPE_SIGN);
|
||||
|
||||
/* initialize the fds */
|
||||
for (i = 0; i < ARRAY_SIZE(line->ts); ++i)
|
||||
line->ts[i].driver.ipaccess.fd.fd = -1;
|
||||
|
||||
e1i_ts = &line->ts[idx];
|
||||
|
||||
bfd = &e1i_ts->driver.ipaccess.fd;
|
||||
bfd->fd = ret;
|
||||
bfd->data = line;
|
||||
bfd->priv_nr = PRIV_OML;
|
||||
bfd->cb = ipaccess_fd_cb;
|
||||
bfd->when = BSC_FD_READ;
|
||||
ret = bsc_register_fd(bfd);
|
||||
if (ret < 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "could not register FD\n");
|
||||
close(bfd->fd);
|
||||
talloc_free(line);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */
|
||||
ret = ipaccess_send_id_req(bfd->fd);
|
||||
|
||||
return ret;
|
||||
//return e1inp_line_register(line);
|
||||
}
|
||||
|
||||
static int rsl_listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
socklen_t sa_len = sizeof(sa);
|
||||
struct bsc_fd *bfd;
|
||||
int ret;
|
||||
|
||||
if (!(what & BSC_FD_READ))
|
||||
return 0;
|
||||
|
||||
bfd = talloc_zero(tall_bsc_ctx, struct bsc_fd);
|
||||
if (!bfd)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Some BTS has connected to us, but we don't know yet which line
|
||||
* (as created by the OML link) to associate it with. Thus, we
|
||||
* allocate a temporary bfd until we have received ID from BTS */
|
||||
|
||||
bfd->fd = accept(listen_bfd->fd, (struct sockaddr *) &sa, &sa_len);
|
||||
if (bfd->fd < 0) {
|
||||
perror("accept");
|
||||
return bfd->fd;
|
||||
}
|
||||
LOGP(DINP, LOGL_NOTICE, "accept()ed new RSL link from %s\n", inet_ntoa(sa.sin_addr));
|
||||
bfd->priv_nr = PRIV_RSL;
|
||||
bfd->cb = ipaccess_fd_cb;
|
||||
bfd->when = BSC_FD_READ;
|
||||
ret = bsc_register_fd(bfd);
|
||||
if (ret < 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "could not register FD\n");
|
||||
close(bfd->fd);
|
||||
talloc_free(bfd);
|
||||
return ret;
|
||||
}
|
||||
/* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */
|
||||
ret = write(bfd->fd, id_req, sizeof(id_req));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Actively connect to a BTS. Currently used by ipaccess-config.c */
|
||||
int ipaccess_connect(struct e1inp_line *line, struct sockaddr_in *sa)
|
||||
{
|
||||
struct e1inp_ts *e1i_ts = &line->ts[0];
|
||||
struct bsc_fd *bfd = &e1i_ts->driver.ipaccess.fd;
|
||||
int ret, on = 1;
|
||||
|
||||
bfd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
bfd->cb = ipaccess_fd_cb;
|
||||
bfd->when = BSC_FD_READ | BSC_FD_WRITE;
|
||||
bfd->data = line;
|
||||
bfd->priv_nr = PRIV_OML;
|
||||
|
||||
if (bfd->fd < 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "could not create TCP socket.\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||
|
||||
ret = connect(bfd->fd, (struct sockaddr *) sa, sizeof(*sa));
|
||||
if (ret < 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "could not connect socket\n");
|
||||
close(bfd->fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = bsc_register_fd(bfd);
|
||||
if (ret < 0) {
|
||||
close(bfd->fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
line->driver = &ipaccess_driver;
|
||||
|
||||
return ret;
|
||||
//return e1inp_line_register(line);
|
||||
}
|
||||
|
||||
int ipaccess_setup(struct gsm_network *gsmnet)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* register the driver with the core */
|
||||
/* FIXME: do this in the plugin initializer function */
|
||||
ret = e1inp_driver_register(&ipaccess_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
e1h = talloc_zero(tall_bsc_ctx, struct ia_e1_handle);
|
||||
if (!e1h)
|
||||
return -ENOMEM;
|
||||
|
||||
e1h->gsmnet = gsmnet;
|
||||
|
||||
/* Listen for OML connections */
|
||||
ret = make_sock(&e1h->listen_fd, IPPROTO_TCP, 0, IPA_TCP_PORT_OML,
|
||||
listen_fd_cb);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Listen for RSL connections */
|
||||
ret = make_sock(&e1h->rsl_listen_fd, IPPROTO_TCP, 0,
|
||||
IPA_TCP_PORT_RSL, rsl_listen_fd_cb);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user