Cellular Lab Setup
This page gives a quick introduction into the setup of openBSC in NITB mode with an outgoing call uplink to the PSTN via sipgate.de It does not contain a detailed explanation of all the involved components, but only a compressed installation guide. For detailed information check the osmocom website.
Hardware
nanoBTS
For information on connection and configuring the nanoBTS please check the nanoBTS page.
Host System
As host system I’m using Ubuntu 17.10.1 Desktop edition in a VirtualBox VM.
The overall setup will also perfectly run on a RaspberryPI 3.
VM
- 2048MB RAM (less should be sufficient)
- 2 Network adapters
- NAT adapter - for Uplink etc.
- Bridged adapter - Ethernet interface for connection to BTS etc.
Network Configuration
Settings for /etc/network/interfaces
auto lo
iface lo inet loopback
# The primary network interface
auto enp0s3
iface enp0s3 inet dhcp
dns-nameservers 8.8.8.8
auto enp0s8
iface enp0s8 inet static
address 192.168.1.20
netmask 255.255.255.0
auto enp0s8:0
iface enp0s8:0 inet static
address 192.168.1.21
netmask 255.255.255.0
Software Installation
Prerequisites
sudo apt install libdbi-dev libdbd-sqlite3 build-essential libtool autoconf automake git-core pkg-config libortp-dev libtalloc-dev libpcsclite-dev libsctp-dev libsctp1 libssl-dev libc-ares-dev libgtp-dev libsofia-sip-ua-glib-dev
You will also have to install libgnutls-dev
which does not exist in Ubuntu 17.10.1 anymore. As such:
apt install libgnutls28-dev
libosmocore
git clone git://git.osmocom.org/libosmocore.git
cd libosmocore
autoreconf -fi
./configure
make
sudo make install
sudo ldconfig
libosmo-abis
git clone git://git.osmocom.org/libosmo-abis.git
cd libosmo-abis
autoreconf -fi
./configure
make
sudo make install
sudo ldconfig
libosmo-netif
git clone git://git.osmocom.org/libosmo-netif.git
cd libosmo-netif
autoreconf -fi
./configure
make
sudo make install
sudo ldconfig
libsmpp
git clone git://git.osmocom.org/libsmpp34.git
cd libsmpp34
autoreconf -fi
./configure
make
sudo make install
sudo ldconfig
osmo-ggsn
git clone git://git.osmocom.org/osmo-ggsn/
cd osmo-ggsn
autoreconf -fi
./configure
make
sudo make install
sudo ldconfig
osmo-sgsn
git clone git://git.osmocom.org/osmo-sgsn/
cd osmo-sgsn
autoreconf -fi
./configure
make
sudo make install
sudo ldconfig
osmo-sip-connector
git clone git://git.osmocom.org/osmo-sip-connector
cd osmo-sip-connector
autoreconf -fi
./configure
make
sudo make install
sudo ldconfig
libpcap
libpcap can either be installed from the repositories ( apt install libpcap ) or built from source
You will need the following libs installed from the repositories in any way:
sudo apt install flex libbison-dev bison
git clone https://github.com/the-tcpdump-group/libpcap.git
./configure
make
sudo make install
sudo ldconfig
openbsc
openBSC is build with SMPP support.
git clone git://git.osmocom.org/openbsc.git
cd openbsc/openbsc
autoreconf -fi
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
./configure --enable-smpp
make
sudo make install
sudo ldconfig
SimpleHLR
You can fetch SimpleHLR from here. It just needs to be unpacked.
You will need the following packages
sudo apt install php php-sqlite3
asterisk
This also contains the creation of basic configuration.
sudo apt install libncurses5-dev libjansson-dev uuid-dev sqlite3 libsqlite3-dev libxml2-dev libncurses-dev libedit-dev
cd /usr/src
git clone http://gerrit.asterisk.org/asterisk asterisk
cd asterisk
./configure
make
sudo make install
sudo make basic-pbx
ntp
As we will need acurate time, we also need everything to synchronize our VM’s time.
sudo apt install ntpdate
Configuration Files
I’ve got my setup based in /root/ as such my config files are all in /root/cfg/
bsc.conf
A few lines in the follwing config need to be changed prior use.
- network country code (MCC) - Needs to be configured according to license for running the network
- mobile network code (MNC) - Needs to be configured according to the license for running the network
- arfcn (Absolute Radio Frequency Channel Number) - Needs to be configured according to the license for running the network
- nominal power - Should be set to 23
- max_power_red - Needs to be set according to allowed maximum transmission power. The final transmission power is nominal power - max_power_red
- ip.access unit_id needs to be set to the same configuration as your BTS
log stderr
logging filter all 1
logging color 1
logging print category 0
logging timestamp 0
logging level all everything
logging level rll everything
logging level cc everything
logging level mm everything
logging level rr everything
logging level rsl everything
logging level nm everything
logging level mncc everything
logging level pag notice
logging level meas notice
logging level sccp notice
logging level msc notice
logging level mgcp notice
logging level ho notice
logging level db everything
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 ctrl notice
logging level smpp debug
logging level filter debug
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
logging level lctrl notice
logging level lgtp notice
logging level lstats notice
e1_input
e1_line 0 driver ipa
network
network country code xxx
mobile network code xxx
short name my_network
long name my_network
auth policy closed
location updating reject cause 13
encryption a5 0
neci 1
rrlp mode none
mm info 1
handover 0
handover window rxlev averaging 10
handover window rxqual averaging 1
handover window rxlev neighbor averaging 10
handover power budget interval 6
handover power budget hysteresis 3
handover maximum distance 9999
timer t3101 10
timer t3113 60
timer t3122 10
timer t3109 4
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 xxxx x
gprs mode gprs
gprs routing area 0
gprs cell bvci 2
gprs nsei 101
gprs nsvc 0 nsvci 101
gprs nsvc 0 local udp port 23000
gprs nsvc 0 remote udp port 23000
gprs nsvc 0 remote ip 192.168.1.20
trx 0
rf_locked 0
arfcn xxx
nominal power xx
max_power_red xx
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
timeslot 1
phys_chan_config SDCCH8
timeslot 2
phys_chan_config PDCH
timeslot 3
phys_chan_config TCH/F
timeslot 4
phys_chan_config TCH/F
timeslot 5
phys_chan_config TCH/F
timeslot 6
phys_chan_config TCH/F
timeslot 7
phys_chan_config TCH/F
smpp
local-tcp-port 2775
system-id OSMO-SMPP
policy closed
esme admin
password admin
default-route
sgsn.conf
!
! Osmocom SGSN configuration
!
!
line vty
no login
!
sgsn
gtp local-ip 192.168.1.20
ggsn 0 remote-ip 127.0.0.1
ggsn 0 gtp-version 1
auth-policy accept-all
!
ns
timer tns-block 3
timer tns-block-retries 3
timer tns-reset 3
timer tns-reset-retries 3
timer tns-test 30
timer tns-alive 3
timer tns-alive-retries 10
encapsulation udp local-ip 192.168.1.20
encapsulation udp local-port 23000
encapsulation framerelay-gre enabled 0
!
bssgp
!
ggsn.conf
ggsn ggsn0
gtp state-dir /tmp
gtp bind-ip 127.0.0.6
apn internet
gtpu-mode tun
tun-device tun4
type-support v4
ip prefix dynamic 192.168.254.0/24
ip dns 0 8.8.8.8
ip dns 1 8.8.4.4
ip ifconfig 192.168.254.0/24
no shutdown
sip-connector.conf
app
mncc
socket-path /tmp/bsc_mncc
sip
local 0.0.0.0 5069
remote 192.168.1.21 5060
dnsmasq.conf
We will need a DHCP server to give IPs to the basestations
listen-address=192.168.1.20
dhcp-range=192.168.1.50,192.168.1.100,12h
/etc/asterisk/asterisk.conf
Yes, my asterisk.conf
is basically empty.
[options]
; If we want to start Asterisk with a default verbosity for the verbose
; or debug logger channel types, then we use these settings (by default
; they are disabled).
;verbose = 5
;debug = 2
; User and group to run asterisk as. NOTE: This will require changes to
; directory and device permissions.
;runuser = asterisk ; The user to run as. The default is root.
;rungroup = asterisk ; The group to run as. The default is root
;defaultlanguage = en
/etc/asterisk/extensions.conf
[globals]
; General internal dialing options used in context Dial-Users.
; Only the timeout is defined here. See the Dial app documentation for
; additional options.
INTERNAL_DIAL_OPT=,30
[Dialing-Errors]
; Handle any extensions dialed internally that don't otherwise exist.
; Comment out or remove this extension if you would rather have the calls
; ignored.
exten = _X.,1,Verbose(1, "User ${CALLERID(num)} dialed an invalid number.")
same = n,Playback(pbx-invalid)
same = n,Hangup()
[incoming]
exten => xxxSIPGATEUSERNAMExxx,1,Log(Notice, "Incoming call via sipgate from ${CALLERID(num)}. exten is currently ${EXTEN}")
exten => xxxSIPGATEUSERNAMExxx,2,Answer(),
exten => xxxSIGPATEUSERNAMExxx,n,Background(welcome)
exten => xxxSIPGATEUSERNAMExxx,n,Background(silence/9)
exten => xxxSIPGATEUSERNAMExxx,n,Hangup()
exten => _1337,1,Playback(tt-weasels)
exten => _1337,n,Hangup()
exten => _9090XXXXX,1,Log(Notice, "Incoming call for ${EXTEN} from ${CALLERID(num)}.")
exten => _9090XXXXX,2,DIAL(SIP/${EXTEN}@192.168.1.20:5069)
exten => _9090XXXXX,n,Hangup()
include = Dialing-Errors
[internal]
exten => 1337,1,Answer
exten => 1337,2,Playback(tt-weasels)
exten => 1337,3,Hangup
exten => _9090XXXXX,1,DIAL(SIP/${EXTEN}@192.168.1.20:5069)
exten => 2222,1,DIAL(SIP/${EXTEN}@192.168.1.20:5069)
exten => _0!X.,1,Set(CALLERID(num)=SIPID)
exten => _0!X.,2,Dial(SIP/*31${EXTEN}@sipgate,30,trg)
exten => _0!X.,3,Hangup
include = Dialing-Errors
/etc/asterisk/sip.conf
[general]
context=internal
allowoverlap=no
domainsasrealm=yes
udpbindaddr=192.168.1.21
tcpbindaddr=192.168.1.21
transport=udp
srvlookup=yes
; login for sipgate uplink
register=xxxUSERxxx:xxxPASSxxx@sipgate.de/xxxUSERxxx
[sipgate]
type=peer
defaultuser=xxxUSERxxx
fromuser=xxxUSERxxx
secret=xxxPASSxxx
context=incoming
extension=xxxUSERxxx
host=sipgate.de
dtmfmode=rfc2833
qualify=yes
fromdomain=sipgate.de
nat=no
directmedia=no
canreinvite=no
insecure=port,invite
allow=!all,alaw,g722
[8888]
type=friend
host=dynamic
secret=123
context=internal
[7002]
type=friend
host=dynamic
secret=456
context=internal
[1111]
type=friend
host=dynamic
secret=123
conext=internal
[gsm]
type=peer
host=192.168.1.20
port=5069
context=gsm
insecure=port,invite
dtmfmode=rfc2833
disallow=all
allow=gsm
/etc/asterisk/cdr.conf
[general]
enable=yes
[custom]
; We log the unique ID as it can be useful for troubleshooting any issues
; that arise.
loguniqueid=yes
/etc/asterisk/cdr_custom.conf
[mappings]
; Our CDR log will be written to /var/log/asterisk/cdr-custom/Master.csv
; with the following schema.
Master.csv => ${CSV_QUOTE(${CDR(clid)})},${CSV_QUOTE(${CDR(src)})},${CSV_QUOTE(${CDR(dst)})},${CSV_QUOTE(${CDR(dcontext)})},${CSV_QUOTE(${CDR(channel)})},${CSV_QUOTE(${CDR(dstchannel)})},${CSV_QUOTE(${CDR(lastapp)})},${CSV_QUOTE(${CDR(lastdata)})},${CSV_QUOTE(${CDR(start)})},${CSV_QUOTE(${CDR(answer)})},${CSV_QUOTE(${CDR(end)})},${CSV_QUOTE(${CDR(duration)})},${CSV_QUOTE(${CDR(billsec)})},${CSV_QUOTE(${CDR(disposition)})},${CSV_QUOTE(${CDR(amaflags)})},${CSV_QUOTE(${CDR(accountcode)})},${CSV_QUOTE(${CDR(uniqueid)})},${CSV_QUOTE(${CDR(userfield)})},${CDR(sequence)}
/etc/asterisk/logger.conf
[general]
[logfiles]
console = verbose,notice,warning,error
;messages = notice,warning,error
;full = verbose,notice,warning,error,debug
;security = security
/etc/asterisk/modules.conf
; Asterisk configuration file
;
; Module Loader configuration file
;
[modules]
autoload=yes
;
; Any modules that need to be loaded before the Asterisk core has been
; initialized (just after the logger has been initialized) can be loaded
; using 'preload'. This will frequently be needed if you wish to map all
; module configuration files into Realtime storage, since the Realtime
; driver will need to be loaded before the modules using those configuration
; files are initialized.
;
; An example of loading ODBC support would be:
;preload => res_odbc.so
;preload => res_config_odbc.so
;
; Uncomment the following if you wish to use the Speech Recognition API
;preload => res_speech.so
;
; If you want Asterisk to fail if a module does not load, then use
; the "require" keyword. Asterisk will exit with a status code of 2
; if a required module does not load.
;
; require = chan_sip.so
; If you want you can combine with preload
; preload-require = res_odbc.so
;
; If you want, load the GTK console right away.
;
noload => pbx_gtkconsole.so
;load => pbx_gtkconsole.so
;
load => res_musiconhold.so
;
; Load one of: chan_oss, alsa, or console (portaudio).
; By default, load chan_oss only (automatically).
;
noload => chan_alsa.so
;noload => chan_oss.so
noload => chan_console.so
load => chan_sip.so
Startup Scripts
bsc_start.sh
osmo-nitb -s -c ~/cfg/openbsc.conf -l ~/cfg/hlr.sqlite3 -P -C -d DLMUX:DRTP -m -T --debug=DSQL:DLSMS:DRLL:DCC:DMM:DRR:DMSC:DHO:DGPRS:DNS:DLLC:DCTRL 2>&1
ggsn_start.sh
osmo-ggsn -c ~/cfg/ggsn.conf
sgsn_start.sh
osmo-sgsn -c ~/cfg/sgsn.conf -d DRLL:DCC:DMM:DRR:DNM:DMSC:DHO:DGPRS:DNS:DLLC:DCTRL
sip-connector_start.sh
osmo-sip-connector -c ~/cfg/osmo-sip-connector.conf
simplehlr_start.sh
php -S 0.0.0.0:80 -t /root/webserver/SimpleHLR/.
routing.sh
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A POSTROUTING -s 192.168.254.0/24 -t nat -o enp0s3 -j MASQUERADE
iptables -A POSTROUTING -t nat -o enp0s8 -j MASQUERADE
Running
The easiest approach is using screen or multiple terminal sessions, as you will want to be able to view the log output. You will need a screen for the BSC, GGSN, SGSN and the sip-connector. Above this all the osmocom components offer access via VTY. As such you might need access to these terminals for configuration or trouble shooting. The same applies for the asterisk cli.
BSC VTY
The BSC VTY listens on port 4242 / TCP. The easiest way to connect is by using telnet.
telnet 127.0.0.1 4242
SGSN VTY
The SGSN VTY listens on port 4245 / TCP. The easist way to connect is by using telnet.
telnet 127.0.0.1 4245
The VTY is the easiest way of checking the active PDP contexts.
:~/cfg# telnet 127.0.0.1 4245
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Welcome to the OsmoSGSN control interface
Copyright (C) 2010 Harald Welte and On-Waves
License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
OsmoSGSN> show pdp-context all
PDP Context IMSI: 262230000000001, SAPI: 3, NSAPI: 5, TI: 0
APN: internet
PDP Address: IPv4 192.168.254.2
GTP Local Control(4.0.0.0 / TEIC: 0x00000001) Data(4.0.0.0 / TEID: 0x00000001)
GTP Remote Control(4.0.0.0 / TEIC: 0x00000001) Data(4.0.0.0 / TEID: 0x00000001)
SGSN PDP Context Statistics:
User Data Messages ( In): 2 (1/s 2/m 0/h 0/d)
User Data Messages (Out): 0 (0/s 0/m 0/h 0/d)
User Data Bytes ( In): 145 (73/s 145/m 0/h 0/d)
User Data Bytes (Out): 0 (0/s 0/m 0/h 0/d)
asterisk CLI
The asterisk CLI is necessary for evaluating the state of the PSTN uplink.
:~/cfg# asterisk -r
Asterisk GIT-master-7c27e71, Copyright (C) 1999 - 2016, Digium, Inc. and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk GIT-master-7c27e71 currently running on TelCore2 (pid = 14391)
TelCore2*CLI> sip show registry
Host dnsmgr Username Refresh State Reg.Time
sipgate.de:5060 N xxxxxxxxx 105 Registered Sun, 26 Feb 2017 10:33:58
1 SIP registrations.
TelCore2*CLI>