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>