diff --git a/contrib/bsc-test/README b/contrib/bsc-test/README deleted file mode 100644 index adb222e21..000000000 --- a/contrib/bsc-test/README +++ /dev/null @@ -1 +0,0 @@ -Some crazy scripts call testing... and MSC link failure simulation diff --git a/contrib/bsc-test/all_dial b/contrib/bsc-test/all_dial deleted file mode 100644 index 96e5f00b3..000000000 --- a/contrib/bsc-test/all_dial +++ /dev/null @@ -1,8 +0,0 @@ -ABORT BUSY -ABORT 'NO CARRIER' -ABORT 'OK' - -'' AT -SAY "Dialing a number\n" -'OK' ATD05660066; - diff --git a/contrib/bsc-test/dial.sh b/contrib/bsc-test/dial.sh deleted file mode 100755 index e5e19f63e..000000000 --- a/contrib/bsc-test/dial.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# Evil dial script.. - -while true; -do - chat -v -f all_dial < /dev/ttyACM0 > /dev/ttyACM0 - sleep 5s - chat -v -f hangup < /dev/ttyACM0 > /dev/ttyACM0 - sleep 2s -done - diff --git a/contrib/bsc-test/drop-oml.sh b/contrib/bsc-test/drop-oml.sh deleted file mode 100755 index 84eead7b7..000000000 --- a/contrib/bsc-test/drop-oml.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -sleep 3 -echo "enable" -sleep 1 -echo "drop bts connection 0 oml" -sleep 1 diff --git a/contrib/bsc-test/drop.sh b/contrib/bsc-test/drop.sh deleted file mode 100755 index c7b66ba72..000000000 --- a/contrib/bsc-test/drop.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -while true; -do - echo "Going to drop the OML connection" - ./drop-oml.sh | telnet 127.0.0.1 4242 - sleep 58m -done diff --git a/contrib/bsc-test/hangup b/contrib/bsc-test/hangup deleted file mode 100644 index cad6870fd..000000000 --- a/contrib/bsc-test/hangup +++ /dev/null @@ -1,4 +0,0 @@ -TIMEOUT 10 -'' ^Z -SAY "Waiting for hangup confirm\n" -'' ATH; diff --git a/contrib/bsc-test/msc.sh b/contrib/bsc-test/msc.sh deleted file mode 100755 index bec011d4c..000000000 --- a/contrib/bsc-test/msc.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -while true; -do - echo "Kill the osmo-bsc" - /usr/bin/kill -s SIGUSR2 `pidof osmo-bsc` - sleep 58s -done diff --git a/contrib/bt.py b/contrib/bt.py deleted file mode 100755 index 1b111efc8..000000000 --- a/contrib/bt.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python - -import os - -f = open("unbalanced") -lines = [] -for line in f: - lines.append(line) - -filenames = {} - -output = [] -for line in lines: - if "[0x" in line: - start = line.find("[") - end = line.find("]") - addr = line[start+1:end] - try: - file = filenames[addr] - except KeyError: - r = os.popen("addr2line -fs -e ./bsc_hack %s" % addr) - all = r.read().replace("\n", ",") - file = all - filenames[addr] = file - - line = line.replace(addr, file) - output.append(line) - -g = open("unbalanced.2", "w") -g.write("".join(output)) - - - diff --git a/contrib/convert_to_enum.py b/contrib/convert_to_enum.py deleted file mode 100755 index bcd6f2cee..000000000 --- a/contrib/convert_to_enum.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python - -# -# Convert ETSI documents to an enum -# - -import re, sys - -def convert(string): - string = string.strip().replace(" ", "").rjust(8, "0") - var = 0 - offset = 7 - for char in string: - assert offset >= 0 - var = var | (int(char) << offset) - offset = offset - 1 - - return var - -def string(name): - name = name.replace(" ", "_") - name = name.replace('"', "") - name = name.replace('/', '_') - name = name.replace('(', '_') - name = name.replace(')', '_') - return "%s_%s" % (sys.argv[2], name.upper()) - -file = open(sys.argv[1]) - - -for line in file: - m = re.match(r"[ \t]*(?P[01 ]+)[ ]+(?P[a-zA-Z /0-9()]+)", line[:-1]) - - if m: - print "\t%s\t\t= %d," % (string(m.groupdict()["name"]), convert(m.groupdict()["value"])) - else: - print line[:-1] diff --git a/contrib/ctrl2sse.py b/contrib/ctrl2sse.py deleted file mode 100755 index 8b630ecfd..000000000 --- a/contrib/ctrl2sse.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/python2 - -mod_license = ''' -/* - * Copyright (C) 2016 sysmocom s.f.m.c. GmbH - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -''' - -import sys, argparse, random, logging, tornado.ioloop, tornado.web, tornado.tcpclient, tornado.httpclient, eventsource, bsc_control -from eventsource import listener, request - -''' -N. B: this is not an example of building proper REST API or building secure web application. -It's only purpose is to illustrate conversion of Osmocom's Control Interface to web-friendly API. -Exposing this to Internet while connected to production network might lead to all sorts of mischief and mayhem -from NSA' TAO breaking into your network to zombie apocalypse. Do NOT do that. -''' - -token = None -stream = None -url = None - -''' -Returns json according to following schema - see http://json-schema.org/documentation.html for details: -{ - "title": "Ctrl Schema", - "type": "object", - "properties": { - "variable": { - "type": "string" - }, - "varlue": { - "type": "string" - } - }, - "required": ["interface", "variable", "value"] -} -Example validation from command-line: -json validate --schema-file=schema.json --document-file=data.json -The interface is represented as string because it might look different for IPv4 vs v6. -''' - -def read_header(data): - t_length = bsc_control.ipa_ctrl_header(data) - if (t_length): - stream.read_bytes(t_length - 1, callback = read_trap) - else: - print >> sys.stderr, "protocol error: length missing in %s!" % data - -@tornado.gen.coroutine -def read_trap(data): - (t, z, v, p) = data.split() - if (t != 'TRAP' or int(z) != 0): - print >> sys.stderr, "protocol error: TRAP != %s or 0! = %d" % (t, int(z)) - else: - yield tornado.httpclient.AsyncHTTPClient().fetch(tornado.httpclient.HTTPRequest(url = "%s/%s/%s" % (url, "ping", token), - method = 'POST', - headers = {'Content-Type': 'application/json'}, - body = tornado.escape.json_encode({ 'variable' : v, 'value' : p }))) - stream.read_bytes(4, callback = read_header) - -@tornado.gen.coroutine -def trap_setup(host, port, target_host, target_port, tk): - global stream - global url - global token - token = tk - url = "http://%s:%s/sse" % (host, port) - stream = yield tornado.tcpclient.TCPClient().connect(target_host, target_port) - stream.read_bytes(4, callback = read_header) - -def get_v(s, v): - return { 'variable' : v, 'value' : bsc_control.get_var(s, tornado.escape.native_str(v)) } - -class CtrlHandler(tornado.web.RequestHandler): - def initialize(self): - self.skt = bsc_control.connect(self.settings['ctrl_host'], self.settings['ctrl_port']) - - def get(self, v): - self.write(get_v(self.skt, v)) - - def post(self): - self.write(get_v(self.skt, self.get_argument("variable"))) - -class SetCtrl(CtrlHandler): - def get(self, var, val): - bsc_control.set_var(self.skt, tornado.escape.native_str(var), tornado.escape.native_str(val)) - super(SetCtrl, self).get(tornado.escape.native_str(var)) - - def post(self): - bsc_control.set_var(self.skt, tornado.escape.native_str(self.get_argument("variable")), tornado.escape.native_str(self.get_argument("value"))) - super(SetCtrl, self).post() - -class Slash(tornado.web.RequestHandler): - def get(self): - self.write('%sUsing Tornado framework v%s' - '
' - '' - '' - '
' - '
' - '' - '' - '' - '
' - '' % ("Osmocom Control Interface Proxy", tornado.version)) - -if __name__ == '__main__': - p = argparse.ArgumentParser(description='Osmocom Control Interface proxy.') - p.add_argument('-c', '--control-port', type = int, default = 4252, help = "Target Control Interface port") - p.add_argument('-a', '--control-host', default = 'localhost', help = "Target Control Interface adress") - p.add_argument('-b', '--host', default = 'localhost', help = "Adress to bind proxy's web interface") - p.add_argument('-p', '--port', type = int, default = 6969, help = "Port to bind proxy's web interface") - p.add_argument('-d', '--debug', action='store_true', help = "Activate debugging (default off)") - p.add_argument('-t', '--token', default = 'osmocom', help = "Token to be used by SSE client in URL e. g. http://127.0.0.1:8888/poll/osmocom where 'osmocom' is default token value") - p.add_argument('-k', '--keepalive', type = int, default = 5000, help = "Timeout betwwen keepalive messages, in milliseconds, defaults to 5000") - args = p.parse_args() - random.seed() - tornado.netutil.Resolver.configure('tornado.netutil.ThreadedResolver') # Use non-blocking resolver - logging.basicConfig() - application = tornado.web.Application([ - (r"/", Slash), - (r"/get", CtrlHandler), - (r"/get/(.*)", CtrlHandler), - (r"/set", SetCtrl), - (r"/set/(.*)/(.*)", SetCtrl), - (r"/sse/(.*)/(.*)", listener.EventSourceHandler, dict(event_class = listener.JSONIdEvent, keepalive = args.keepalive)), - ], debug = args.debug, ctrl_host = args.control_host, ctrl_port = args.control_port) - application.listen(address = args.host, port = args.port) - trap_setup(args.host, args.port, application.settings['ctrl_host'], application.settings['ctrl_port'], args.token) - tornado.ioloop.IOLoop.instance().start() diff --git a/contrib/gprs/gb-proxy-unblock-bug.py b/contrib/gprs/gb-proxy-unblock-bug.py deleted file mode 100755 index 0cd4b871f..000000000 --- a/contrib/gprs/gb-proxy-unblock-bug.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python - -""" -demonstrate a unblock bug on the GB Proxy.. -""" - -bts_ns_reset = "\x02\x00\x81\x01\x01\x82\x1f\xe7\x04\x82\x1f\xe7" -ns_reset_ack = "\x03\x01\x82\x1f\xe7\x04\x82\x1f\xe7" - -bts_ns_unblock = "\x06" -ns_unblock_ack = "\x07" - -bts_bvc_reset_0 = "\x00\x00\x00\x00\x22\x04\x82\x00\x00\x07\x81\x03\x3b\x81\x02" -ns_bvc_reset_0_ack = "\x00\x00\x00\x00\x23\x04\x82\x00\x00" - -bts_bvc_reset_8167 = "\x00\x00\x00\x00\x22\x04\x82\x1f\xe7\x07\x81\x08\x08\x88\x72\xf4\x80\x10\x1c\x00\x9c\x40" - - -import socket -socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -socket.bind(("0.0.0.0", 0)) -socket.setblocking(1) - - -import sys -port = int(sys.argv[1]) -print "Sending data to port: %d" % port - -def send_and_receive(packet): - socket.sendto(packet, ("127.0.0.1", port)) - - try: - data, addr = socket.recvfrom(4096) - except socket.error, e: - print "ERROR", e - import sys - sys.exit(0) - return data - -#send stuff once - -to_send = [ - (bts_ns_reset, ns_reset_ack, "reset ack"), - (bts_ns_unblock, ns_unblock_ack, "unblock ack"), - (bts_bvc_reset_0, ns_bvc_reset_0_ack, "BVCI=0 reset ack"), -] - - -for (out, inp, type) in to_send: - res = send_and_receive(out) - if res != inp: - print "Failed to get the %s" % type - sys.exit(-1) - -import time -time.sleep(3) -res = send_and_receive(bts_bvc_reset_8167) -print "Sent all messages... check wireshark for the last response" diff --git a/contrib/gprs/gprs-bssgp-histogram.lua b/contrib/gprs/gprs-bssgp-histogram.lua deleted file mode 100644 index b1ab5df7f..000000000 --- a/contrib/gprs/gprs-bssgp-histogram.lua +++ /dev/null @@ -1,78 +0,0 @@ --- Simple LUA script to print the size of BSSGP messages over their type... - -do - local ip_bucket = {} - - local pdu_types = {} - pdu_types[ 6] = "PAGING" - pdu_types[11] = "SUSPEND" - pdu_types[12] = "SUSPEND-ACK" - pdu_types[32] = "BVC-BLOCK" - pdu_types[33] = "BVC-BLOCK-ACK" - pdu_types[34] = "BVC-RESET" - pdu_types[35] = "BVC-RESET-ACK" - pdu_types[36] = "UNBLOCK" - pdu_types[37] = "UNBLOCK-ACK" - pdu_types[38] = "FLOW-CONTROL-BVC" - pdu_types[39] = "FLOW-CONTROL-BVC-ACK" - pdu_types[40] = "FLOW-CONTROL-MS" - pdu_types[41] = "FLOW-CONTROL-MS-ACK" - pdu_types[44] = "LLC-DISCARDED" - - 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 udp_length_get = Field.new("udp.length") - - local tap = Listener.new("ip", "udp.port == 23000") - function tap.packet(pinfo,tvb,ip) - local pdu = bssgp_pdu_get() - local len = udp_length_get() - - -- only handle bssgp, but we also want the IP frame - if not pdu then - return - end - - pdu = tostring(pdu) - if tonumber(pdu) == 0 or tonumber(pdu) == 1 then - return - end - - local ip_src = tostring(ip.ip_src) - local bssgp_histo = ip_bucket[ip_src] - if not bssgp_histo then - bssgp_histo = {} - ip_bucket[ip_src] = bssgp_histo - end - - local key = pdu - local bucket = bssgp_histo[key] - if not bucket then - bucket = {} - bssgp_histo[key] = bucket - end - - table.insert(bucket, tostring(len)) - print("IP: " .. ip_src .. " PDU: " .. pdu_types[tonumber(pdu)] .. " 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 - end - - function tap.reset() - -- well... this will not be called... - end - end - - init_listener() -end diff --git a/contrib/gprs/gprs-buffer-count.lua b/contrib/gprs/gprs-buffer-count.lua deleted file mode 100644 index ca8864ad1..000000000 --- a/contrib/gprs/gprs-buffer-count.lua +++ /dev/null @@ -1,80 +0,0 @@ --- 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 diff --git a/contrib/gprs/gprs-split-trace-by-tlli.lua b/contrib/gprs/gprs-split-trace-by-tlli.lua deleted file mode 100644 index 018c377c5..000000000 --- a/contrib/gprs/gprs-split-trace-by-tlli.lua +++ /dev/null @@ -1,46 +0,0 @@ --- Create a file named by_ip/''ip_addess''.cap with all ip traffic of each ip host. (works for tshark only) --- Dump files are created for both source and destination hosts -do - local dir = "by_tlli" - local dumpers = {} - local function init_listener() - local udp_port_table = DissectorTable.get("udp.port") - local gprs_ns_dis = Dissector.get("gprs_ns") - udp_port_table:add(23000,gprs_ns_dis) - - local field_tlli = Field.new("bssgp.tlli") - local tap = Listener.new("ip", "udp.port == 23000") - - -- we will be called once for every IP Header. - -- If there's more than one IP header in a given packet we'll dump the packet once per every header - function tap.packet(pinfo,tvb,ip) - local tlli = field_tlli() - if not tlli then - return - end - - local tlli_str = tostring(tlli) - tlli_dmp = dumpers[tlli_str] - if not tlli_dmp then - local tlli_hex = string.format("0x%x", tonumber(tlli_str)) - print("Creating dump for TLLI " .. tlli_hex) - tlli_dmp = Dumper.new_for_current(dir .. "/" .. tlli_hex .. ".pcap") - dumpers[tlli_str] = tlli_dmp - end - tlli_dmp:dump_current() - tlli_dmp:flush() - end - function tap.draw() - for tlli,dumper in pairs(dumpers) do - dumper:flush() - end - end - function tap.reset() - for tlli,dumper in pairs(dumpers) do - dumper:close() - end - dumpers = {} - end - end - init_listener() -end diff --git a/contrib/gprs/gprs-verify-nu.lua b/contrib/gprs/gprs-verify-nu.lua deleted file mode 100644 index e44fdd16f..000000000 --- a/contrib/gprs/gprs-verify-nu.lua +++ /dev/null @@ -1,59 +0,0 @@ --- This script verifies that the N(U) is increasing... --- -do - local nu_state_src = {} - - 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) - - -- we want to look here... - local llc_sapi_get = Field.new("llcgprs.sapib") - local llc_nu_get = Field.new("llcgprs.nu") - local bssgp_tlli_get = Field.new("bssgp.tlli") - - local tap = Listener.new("ip", "udp.port == 23000") - function tap.packet(pinfo,tvb,ip) - local llc_sapi = llc_sapi_get() - local llc_nu = llc_nu_get() - local bssgp_tlli = bssgp_tlli_get() - - if not llc_sapi or not llc_nu or not bssgp_tlli then - return - end - - local ip_src = tostring(ip.ip_src) - local bssgp_tlli = tostring(bssgp_tlli) - local llc_nu = tostring(llc_nu) - local llc_sapi = tostring(llc_sapi) - - local src_key = ip_src .. "-" .. bssgp_tlli .. "-" .. llc_sapi - local last_nu = nu_state_src[src_key] - if not last_nu then - -- print("Establishing mapping for " .. src_key) - nu_state_src[src_key] = llc_nu - return - end - - local function tohex(number) - return string.format("0x%x", tonumber(number)) - end - - nu_state_src[src_key] = llc_nu - if tonumber(last_nu) + 1 ~= tonumber(llc_nu) then - print("JUMP in N(U) on TLLI " .. tohex(bssgp_tlli) .. " and SAPI: " .. llc_sapi .. " src: " .. ip_src) - print("\t last: " .. last_nu .. " now: " .. llc_nu) - end - end - - function tap.draw() - end - - function tap.reset() - end - end - init_listener() -end - diff --git a/contrib/hlr-remove-old.sql b/contrib/hlr-remove-old.sql deleted file mode 100644 index 626a331e1..000000000 --- a/contrib/hlr-remove-old.sql +++ /dev/null @@ -1,18 +0,0 @@ --- Remove old data from the database -DELETE FROM Subscriber - WHERE id != 1 AND datetime('now', '-10 days') > updated AND authorized != 1; -DELETE FROM Equipment - WHERE datetime('now', '-10 days') > updated; -DELETE FROM EquipmentWatch - WHERE datetime('now', '-10 days') > updated; -DELETE FROM SMS - WHERE datetime('now', '-10 days') > created; -DELETE FROM VLR - WHERE datetime('now', '-10 days') > updated; -DELETE FROM ApduBlobs - WHERE datetime('now', '-10 days') > created; -DELETE FROM Counters - WHERE datetime('now', '-10 days') > timestamp; -DELETE FROM RateCounters - WHERE datetime('now', '-10 days') > timestamp; -VACUUM; diff --git a/contrib/hlrsync/hlrsync.py b/contrib/hlrsync/hlrsync.py deleted file mode 100755 index e4a495555..000000000 --- a/contrib/hlrsync/hlrsync.py +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/python2.5 - -from __future__ import with_statement - -from pysqlite2 import dbapi2 as sqlite3 -import sys - -hlr = sqlite3.connect(sys.argv[1]) -web = sqlite3.connect(sys.argv[2]) - -# switch to autocommit -hlr.isolation_level = None -web.isolation_level = None - -hlr.row_factory = sqlite3.Row -web.row_factory = sqlite3.Row - -with hlr: - hlr_subscrs = hlr.execute(""" - SELECT * FROM Subscriber - """).fetchall() - hlr_tokens = hlr.execute(""" - SELECT * FROM AuthToken - """).fetchall() - -with web: - web_tokens = web.execute(""" - SELECT * FROM reg_tokens - """).fetchall() - web_sms = web.execute(""" - SELECT * FROM sms_queue - """).fetchall() - -# index by subscr id -hlr_subscrs_by_id = {} -hlr_subscrs_by_ext = {} -hlr_tokens_by_subscr_id = {} -for x in hlr_subscrs: - hlr_subscrs_by_id[x['id']] = x - hlr_subscrs_by_ext[x['extension']] = x -del hlr_subscrs -for x in hlr_tokens: - hlr_tokens_by_subscr_id[x['subscriber_id']] = x -del hlr_tokens - -web_tokens_by_subscr_id = {} -for x in web_tokens: - web_tokens_by_subscr_id[x['subscriber_id']] = x -del web_tokens - -# remove leftover web_tokens and correct inconsistent fields -with web: - for x in web_tokens_by_subscr_id.values(): - subscr = hlr_subscrs_by_id.get(x['subscriber_id'], None) - if subscr is None: - web.execute(""" - DELETE FROM reg_tokens WHERE subscriber_id = ? - """, (x['subscriber_id'],)) - del web_tokens_by_subscr_id[x['subscriber_id']] - continue - if str(x['imsi']) != str(subscr['imsi']) or \ - x['extension'] != subscr['extension'] or \ - x['tmsi'] != subscr['tmsi'] or \ - x['lac'] != subscr['lac']: - web.execute(""" - UPDATE reg_tokens - SET imsi = ?, extension = ?, tmsi = ?, lac = ? - WHERE subscriber_id = ? - """, (str(subscr['imsi']), subscr['extension'], - subscr['tmsi'], subscr['lac'], x['subscriber_id'])) - -# add missing web_tokens -with web: - for x in hlr_tokens_by_subscr_id.values(): - subscr = hlr_subscrs_by_id.get(x['subscriber_id'], None) - if subscr is None: - hlr.execute(""" - DELETE FROM AuthToken WHERE subscriber_id = ? - """, (x['subscriber_id'],)) - del hlr_tokens_by_subscr_id[x['subscriber_id']] - continue - webtoken = web_tokens_by_subscr_id.get(x['subscriber_id'], None) - if webtoken is None: - web.execute(""" - INSERT INTO reg_tokens - (subscriber_id, extension, reg_completed, name, email, lac, imsi, token, tmsi) - VALUES - (?, ?, 0, ?, '', ?, ?, ?, ?) - """, (x['subscriber_id'], subscr['extension'], subscr['name'], - subscr['lac'], str(subscr['imsi']), x['token'], subscr['tmsi'])) - -# authorize subscribers -with hlr: - for x in web_tokens_by_subscr_id.values(): - subscr = hlr_subscrs_by_id.get(x['subscriber_id'], None) - if x['reg_completed'] and not subscr['authorized']: - hlr.execute(""" - UPDATE Subscriber - SET authorized = 1 - WHERE id = ? - """, (x['subscriber_id'],)) - -# Sync SMS from web to hlr -with hlr: - for sms in web_sms: - subscr = hlr_subscrs_by_ext.get(sms['receiver_ext']) - if subscr is None: - print '%s not found' % sms['receiver_ext'] - continue - hlr.execute(""" - INSERT INTO SMS - (created, sender_id, receiver_id, reply_path_req, status_rep_req, protocol_id, data_coding_scheme, ud_hdr_ind, text) - VALUES - (?, 1, ?, 0, 0, 0, 0, 0, ?) - """, (sms['created'], subscr['id'], sms['text'])) -with web: - for sms in web_sms: - web.execute(""" - DELETE FROM sms_queue WHERE id = ? - """, (sms['id'],)) - - -hlr.close() -web.close() - diff --git a/contrib/mgcp_server.py b/contrib/mgcp_server.py deleted file mode 100755 index 05c489db5..000000000 --- a/contrib/mgcp_server.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python -# Simple server for mgcp... send audit, receive response.. - -import socket, time - -MGCP_GATEWAY_PORT = 2427 -MGCP_CALLAGENT_PORT = 2727 - -rsip_resp = """200 321321332\r\n""" -audit_packet = """AUEP %d 13@mgw MGCP 1.0\r\n""" -crcx_packet = """CRCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n""" -dlcx_packet = """DLCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\n""" -mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 6666 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n""" - -def hexdump(src, length=8): - """Recipe is from http://code.activestate.com/recipes/142812/""" - result = [] - digits = 4 if isinstance(src, unicode) else 2 - for i in xrange(0, len(src), length): - s = src[i:i+length] - hexa = b' '.join(["%0*X" % (digits, ord(x)) for x in s]) - text = b''.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s]) - result.append( b"%04X %-*s %s" % (i, length*(digits + 1), hexa, text) ) - return b'\n'.join(result) - -server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT)) -server_socket.setblocking(1) - -last_ci = 1 -def send_and_receive(packet): - global last_ci - server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT)) - try: - data, addr = server_socket.recvfrom(4096) - - # attempt to store the CI of the response - list = data.split("\n") - for item in list: - if item.startswith("I: "): - last_ci = int(item[3:]) - - print hexdump(data), addr - except socket.error, e: - print e - pass - -def generate_tid(): - import random - return random.randint(0, 65123) - - - -while True: - send_and_receive(audit_packet % generate_tid()) - send_and_receive(crcx_packet % generate_tid() ) - send_and_receive(mdcx_packet % (generate_tid(), last_ci)) - send_and_receive(dlcx_packet % (generate_tid(), last_ci)) - - time.sleep(3) diff --git a/contrib/nat/test_regexp.c b/contrib/nat/test_regexp.c deleted file mode 100644 index 808a703ca..000000000 --- a/contrib/nat/test_regexp.c +++ /dev/null @@ -1,30 +0,0 @@ -/* make test_regexp */ -#include -#include -#include - - -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; -} diff --git a/contrib/nat/ussd_example.py b/contrib/nat/ussd_example.py deleted file mode 100644 index 8f7a58d3f..000000000 --- a/contrib/nat/ussd_example.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python2.7 - -""" -AGPLv3+ 2016 Copyright Holger Hans Peter Freyther - -Example of how to connect to the USSD side-channel and how to respond -with a fixed message. -""" - -import socket -import struct - -ussdSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -ussdSocket.connect(('127.0.0.1', 5001)) - -def send_dt1(dstref, data): - dlen = struct.pack('B', len(data)).encode('hex') - hex = '06' + dstref.encode('hex') + '00' + '01' + dlen + data.encode('hex') - pdata = hex.decode('hex') - out = struct.pack('>HB', len(pdata), 0xfd) + pdata - ussdSocket.send(out) - -def send_rel(srcref, dstref): - hex = '04' + dstref.encode('hex') + srcref.encode('hex') + '000100' - pdata = hex.decode('hex') - out = struct.pack('>HB', len(pdata), 0xfd) + pdata - ussdSocket.send(out) - -def recv_one(): - plen = ussdSocket.recv(3) - (plen,ptype) = struct.unpack(">HB", plen) - data = ussdSocket.recv(plen) - - return ptype, data - -# Assume this is the ID request -data = ussdSocket.recv(4) -ussdSocket.send("\x00\x08\xfe\x05\x00" + "\x05\x01" + "ussd") -# ^len ^len of tag ... and ignore - -# Expect a fake message. see struct ipac_msgt_sccp_state -ptype, data = recv_one() -print("%d %s" % (ptype, data.encode('hex'))) -(srcref, dstref, transid, invokeid) = struct.unpack("<3s3sBB", data[1:9]) -print("New transID %d invoke %d" % (transid, invokeid)) - -# Expect a the invocation.. todo.. extract invoke id -ptype, data = recv_one() -print("%d %s" % (ptype, data.encode('hex'))) - -# Reply with BSSAP + GSM 04.08 + MAP portion -# 00 == invoke id 0f == DCS -res = "01002a9b2a0802e1901c22a220020100301b02013b301604010f041155e7d2f9bc3a41412894991c06a9c9a713" -send_dt1(dstref, res.decode('hex')) - -clear = "000420040109" -send_dt1(dstref, clear.decode('hex')) - -# should be the clear complete -send_rel(srcref, dstref) - -# Give it some time to handle connection shutdown properly -print("Gracefully sleeping") -import time -time.sleep(3) diff --git a/contrib/rtp/gen_rtp_header.erl b/contrib/rtp/gen_rtp_header.erl deleted file mode 100755 index 47839c1ca..000000000 --- a/contrib/rtp/gen_rtp_header.erl +++ /dev/null @@ -1,420 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang -*- -%%! -smp disable --module(gen_rtp_header). - -% -mode(compile). - --define(VERSION, "0.1"). - --export([main/1]). - --record(rtp_packet, - { - version = 2, - padding = 0, - marker = 0, - payload_type = 0, - seqno = 0, - timestamp = 0, - ssrc = 0, - csrcs = [], - extension = <<>>, - payload = <<>>, - realtime - }). - - -main(Args) -> - DefaultOpts = [{format, state}, - {ssrc, 16#11223344}, - {rate, 8000}, - {pt, 98}], - {PosArgs, Opts} = getopts_checked(Args, DefaultOpts), - log(debug, fun (Dev) -> - io:format(Dev, "Initial options:~n", []), - dump_opts(Dev, Opts), - io:format(Dev, "~s: ~p~n", ["Args", PosArgs]) - end, [], Opts), - main(PosArgs, Opts). - -main([First | RemArgs], Opts) -> - try - F = list_to_integer(First), - Format = proplists:get_value(format, Opts, state), - PayloadData = proplists:get_value(payload, Opts, undef), - InFile = proplists:get_value(file, Opts, undef), - - Payload = case {PayloadData, InFile} of - {undef, undef} -> - % use default value - #rtp_packet{}#rtp_packet.payload; - {P, undef} -> P; - {_, File} -> - log(info, "Loading file '~s'~n", [File], Opts), - {ok, InDev} = file:open(File, [read]), - DS = [ Pl#rtp_packet.payload || {_T, Pl} <- read_packets(InDev, Opts)], - file:close(InDev), - log(debug, "File '~s' closed, ~w packets read.~n", [File, length(DS)], Opts), - DS - end, - Dev = standard_io, - write_packet_pre(Dev, Format), - do_groups(Dev, Payload, F, RemArgs, Opts), - write_packet_post(Dev, Format), - 0 - catch - _:_ -> - log(debug, "~p~n", [hd(erlang:get_stacktrace())], Opts), - usage(), - halt(1) - end - ; - -main(_, _Opts) -> - usage(), - halt(1). - -%%% group (count + offset) handling %%% - -do_groups(_Dev, _Pl, _F, [], _Opts) -> - ok; - -do_groups(Dev, Pl, F, [L], Opts) -> - do_groups(Dev, Pl, F, [L, 0], Opts); - -do_groups(Dev, Pl, First, [L, O | Args], Opts) -> - Ssrc = proplists:get_value(ssrc, Opts, #rtp_packet.ssrc), - PT = proplists:get_value(pt, Opts, #rtp_packet.payload_type), - Len = list_to_num(L), - Offs = list_to_num(O), - log(info, "Starting group: Ssrc=~.16B, PT=~B, First=~B, Len=~B, Offs=~B~n", - [Ssrc, PT, First, Len, Offs], Opts), - Pkg = #rtp_packet{ssrc = Ssrc, payload_type = PT}, - Pl2 = write_packets(Dev, Pl, Pkg, First, Len, Offs, Opts), - {Args2, Opts2} = getopts_checked(Args, Opts), - log(debug, fun (Io) -> - io:format(Io, "Changed options:~n", []), - dump_opts(Io, Opts2 -- Opts) - end, [], Opts), - do_groups(Dev, Pl2, First+Len, Args2, Opts2). - -%%% error handling helpers %%% - -getopts_checked(Args, Opts) -> - try - getopts(Args, Opts) - catch - C:R -> - log(error, "~s~n", - [explain_error(C, R, erlang:get_stacktrace(), Opts)], Opts), - usage(), - halt(1) - end. - -explain_error(error, badarg, [{erlang,list_to_integer,[S,B]} | _ ], _Opts) -> - io_lib:format("Invalid number '~s' (base ~B)", [S, B]); -explain_error(error, badarg, [{erlang,list_to_integer,[S]} | _ ], _Opts) -> - io_lib:format("Invalid decimal number '~s'", [S]); -explain_error(C, R, [Hd | _ ], _Opts) -> - io_lib:format("~p, ~p:~p", [Hd, C, R]); -explain_error(_, _, [], _Opts) -> - "". - -%%% usage and options %%% - -myname() -> - filename:basename(escript:script_name()). - -usage(Text) -> - io:format(standard_error, "~s: ~s~n", [myname(), Text]), - usage(). - -usage() -> - io:format(standard_error, - "Usage: ~s [Options] Start Count1 Offs1 [[Options] Count2 Offs2 ...]~n", - [myname()]). - -show_version() -> - io:format(standard_io, - "~s ~s~n", [myname(), ?VERSION]). - -show_help() -> - io:format(standard_io, - "Usage: ~s [Options] Start Count1 Offs1 [[Options] Count2 Offs2 ...]~n~n" ++ - "Options:~n" ++ - " -h, --help this text~n" ++ - " --version show version info~n" ++ - " -i, --file=FILE reads payload from file (state format by default)~n" ++ - " -f, --frame-size=N read payload as binary frames of size N instead~n" ++ - " -p, --payload=HEX set constant payload~n" ++ - " --verbose=N set verbosity~n" ++ - " -v increase verbosity~n" ++ - " --format=state use state format for output (default)~n" ++ - " -C, --format=c use simple C lines for output~n" ++ - " --format=carray use a C array for output~n" ++ - " -s, --ssrc=SSRC set the SSRC~n" ++ - " -t, --type=N set the payload type~n" ++ - " -r, --rate=N set the RTP rate [8000]~n" ++ - " -D, --duration=N set the packet duration in RTP time units [160]~n" ++ - " -d, --delay=FLOAT add offset to playout timestamp~n" ++ - "~n" ++ - "Arguments:~n" ++ - " Start initial packet (sequence) number~n" ++ - " Count number of packets~n" ++ - " Offs timestamp offset (in RTP units)~n" ++ - "", [myname()]). - -getopts([ "--file=" ++ File | R], Opts) -> - getopts(R, [{file, File} | Opts]); -getopts([ "-i" ++ T | R], Opts) -> - getopts_alias_arg("--file", T, R, Opts); -getopts([ "--frame-size=" ++ N | R], Opts) -> - Size = list_to_integer(N), - getopts(R, [{frame_size, Size}, {in_format, bin} | Opts]); -getopts([ "-f" ++ T | R], Opts) -> - getopts_alias_arg("--frame-size", T, R, Opts); -getopts([ "--duration=" ++ N | R], Opts) -> - Duration = list_to_integer(N), - getopts(R, [{duration, Duration} | Opts]); -getopts([ "-D" ++ T | R], Opts) -> - getopts_alias_arg("--duration", T, R, Opts); -getopts([ "--rate=" ++ N | R], Opts) -> - Rate = list_to_integer(N), - getopts(R, [{rate, Rate} | Opts]); -getopts([ "-r" ++ T | R], Opts) -> - getopts_alias_arg("--rate", T, R, Opts); -getopts([ "--version" | _], _Opts) -> - show_version(), - halt(0); -getopts([ "--help" | _], _Opts) -> - show_help(), - halt(0); -getopts([ "-h" ++ T | R], Opts) -> - getopts_alias_no_arg("--help", T, R, Opts); -getopts([ "--verbose=" ++ V | R], Opts) -> - Verbose = list_to_integer(V), - getopts(R, [{verbose, Verbose} | Opts]); -getopts([ "-v" ++ T | R], Opts) -> - Verbose = proplists:get_value(verbose, Opts, 0), - getopts_short_no_arg(T, R, [ {verbose, Verbose+1} | Opts]); -getopts([ "--format=state" | R], Opts) -> - getopts(R, [{format, state} | Opts]); -getopts([ "--format=c" | R], Opts) -> - getopts(R, [{format, c} | Opts]); -getopts([ "-C" ++ T | R], Opts) -> - getopts_alias_no_arg("--format=c", T, R, Opts); -getopts([ "--format=carray" | R], Opts) -> - getopts(R, [{format, carray} | Opts]); -getopts([ "--payload=" ++ Hex | R], Opts) -> - getopts(R, [{payload, hex_to_bin(Hex)} | Opts]); -getopts([ "--ssrc=" ++ Num | R], Opts) -> - getopts(R, [{ssrc, list_to_num(Num)} | Opts]); -getopts([ "-s" ++ T | R], Opts) -> - getopts_alias_arg("--ssrc", T, R, Opts); -getopts([ "--type=" ++ Num | R], Opts) -> - getopts(R, [{pt, list_to_num(Num)} | Opts]); -getopts([ "-t" ++ T | R], Opts) -> - getopts_alias_arg("--type", T, R, Opts); -getopts([ "--delay=" ++ Num | R], Opts) -> - getopts(R, [{delay, list_to_float(Num)} | Opts]); -getopts([ "-d" ++ T | R], Opts) -> - getopts_alias_arg("--delay", T, R, Opts); - -% parsing helpers -getopts([ "--" | R], Opts) -> - {R, normalize_opts(Opts)}; -getopts([ O = "--" ++ _ | _], _Opts) -> - usage("Invalid option: " ++ O), - halt(1); -getopts([ [ $-, C | _] | _], _Opts) when C < $0; C > $9 -> - usage("Invalid option: -" ++ [C]), - halt(1); - -getopts(R, Opts) -> - {R, normalize_opts(Opts)}. - -getopts_short_no_arg([], R, Opts) -> getopts(R, Opts); -getopts_short_no_arg(T, R, Opts) -> getopts([ "-" ++ T | R], Opts). - -getopts_alias_no_arg(A, [], R, Opts) -> getopts([A | R], Opts); -getopts_alias_no_arg(A, T, R, Opts) -> getopts([A, "-" ++ T | R], Opts). - -getopts_alias_arg(A, [], [T | R], Opts) -> getopts([A ++ "=" ++ T | R], Opts); -getopts_alias_arg(A, T, R, Opts) -> getopts([A ++ "=" ++ T | R], Opts). - -normalize_opts(Opts) -> - [ proplists:lookup(E, Opts) || E <- proplists:get_keys(Opts) ]. - -%%% conversions %%% - -bin_to_hex(Bin) -> [hd(integer_to_list(N,16)) || <> <= Bin]. -hex_to_bin(Hex) -> << <<(list_to_integer([Nib],16)):4>> || Nib <- Hex>>. - -list_to_num("-" ++ Str) -> -list_to_num(Str); -list_to_num("0x" ++ Str) -> list_to_integer(Str, 16); -list_to_num("0b" ++ Str) -> list_to_integer(Str, 2); -list_to_num(Str = [ $0 | _ ]) -> list_to_integer(Str, 8); -list_to_num(Str) -> list_to_integer(Str, 10). - -%%% dumping data %%% - -dump_opts(Dev, Opts) -> - dump_opts2(Dev, Opts, proplists:get_keys(Opts)). - -dump_opts2(Dev, Opts, [OptName | R]) -> - io:format(Dev, " ~-10s: ~p~n", - [OptName, proplists:get_value(OptName, Opts)]), - dump_opts2(Dev, Opts, R); -dump_opts2(_Dev, _Opts, []) -> ok. - -%%% logging %%% - -log(L, Fmt, Args, Opts) when is_list(Opts) -> - log(L, Fmt, Args, proplists:get_value(verbose, Opts, 0), Opts). - -log(debug, Fmt, Args, V, Opts) when V > 2 -> log2("DEBUG", Fmt, Args, Opts); -log(info, Fmt, Args, V, Opts) when V > 1 -> log2("INFO", Fmt, Args, Opts); -log(notice, Fmt, Args, V, Opts) when V > 0 -> log2("NOTICE", Fmt, Args, Opts); -log(warn, Fmt, Args, _V, Opts) -> log2("WARNING", Fmt, Args, Opts); -log(error, Fmt, Args, _V, Opts) -> log2("ERROR", Fmt, Args, Opts); - -log(Lvl, Fmt, Args, V, Opts) when V >= Lvl -> log2("", Fmt, Args, Opts); - -log(_, _, _, _i, _) -> ok. - -log2(Type, Fmt, Args, _Opts) when is_list(Fmt) -> - io:format(standard_error, "~s: " ++ Fmt, [Type | Args]); -log2("", Fmt, Args, _Opts) when is_list(Fmt) -> - io:format(standard_error, Fmt, Args); -log2(_Type, Fun, _Args, _Opts) when is_function(Fun, 1) -> - Fun(standard_error). - -%%% RTP packets %%% - -make_rtp_packet(P = #rtp_packet{version = 2}) -> - << (P#rtp_packet.version):2, - 0:1, % P - 0:1, % X - 0:4, % CC - (P#rtp_packet.marker):1, - (P#rtp_packet.payload_type):7, - (P#rtp_packet.seqno):16, - (P#rtp_packet.timestamp):32, - (P#rtp_packet.ssrc):32, - (P#rtp_packet.payload)/bytes - >>. - -parse_rtp_packet( - << 2:2, % Version 2 - 0:1, % P (not supported yet) - 0:1, % X (not supported yet) - 0:4, % CC (not supported yet) - M:1, - PT:7, - SeqNo: 16, - TS:32, - Ssrc:32, - Payload/bytes >>) -> - #rtp_packet{ - version = 0, - marker = M, - payload_type = PT, - seqno = SeqNo, - timestamp = TS, - ssrc = Ssrc, - payload = Payload}. - -%%% payload generation %%% - -next_payload(F) when is_function(F) -> - {F(), F}; -next_payload({F, D}) when is_function(F) -> - {P, D2} = F(D), - {P, {F, D2}}; -next_payload([P | R]) -> - {P, R}; -next_payload([]) -> - undef; -next_payload(Bin = <<_/bytes>>) -> - {Bin, Bin}. - -%%% real writing work %%% - -write_packets(_Dev, DS, _P, _F, 0, _O, _Opts) -> - DS; -write_packets(Dev, DataSource, P = #rtp_packet{}, F, L, O, Opts) -> - Format = proplists:get_value(format, Opts, state), - Ptime = proplists:get_value(duration, Opts, 160), - Delay = proplists:get_value(delay, Opts, 0), - Rate = proplists:get_value(rate, Opts, 8000), - case next_payload(DataSource) of - {Payload, DataSource2} -> - write_packet(Dev, Ptime * F / Rate + Delay, - P#rtp_packet{seqno = F, timestamp = F*Ptime+O, - payload = Payload}, - Format), - write_packets(Dev, DataSource2, P, F+1, L-1, O, Opts); - Other -> Other - end. - -write_packet(Dev, Time, P = #rtp_packet{}, Format) -> - Bin = make_rtp_packet(P), - - write_packet_line(Dev, Time, P, Bin, Format). - -write_packet_pre(Dev, carray) -> - io:format(Dev, - "struct {float t; int len; char *data;} packets[] = {~n", []); - -write_packet_pre(_Dev, _) -> ok. - -write_packet_post(Dev, carray) -> - io:format(Dev, "};~n", []); - -write_packet_post(_Dev, _) -> ok. - -write_packet_line(Dev, Time, _P, Bin, state) -> - io:format(Dev, "~f ~s~n", [Time, bin_to_hex(Bin)]); - -write_packet_line(Dev, Time, #rtp_packet{seqno = N, timestamp = TS}, Bin, c) -> - ByteList = [ [ $0, $x | integer_to_list(Byte, 16) ] || <> <= Bin ], - ByteStr = string:join(ByteList, ", "), - io:format(Dev, "/* time=~f, SeqNo=~B, TS=~B */ {~s}~n", [Time, N, TS, ByteStr]); - -write_packet_line(Dev, Time, #rtp_packet{seqno = N, timestamp = TS}, Bin, carray) -> - io:format(Dev, " /* RTP: SeqNo=~B, TS=~B */~n", [N, TS]), - io:format(Dev, " {~f, ~B, \"", [Time, size(Bin)]), - [ io:format(Dev, "\\x~2.16.0B", [Byte]) || <> <= Bin ], - io:format(Dev, "\"},~n", []). - -%%% real reading work %%% - -read_packets(Dev, Opts) -> - Format = proplists:get_value(in_format, Opts, state), - - read_packets(Dev, Opts, Format). - -read_packets(Dev, Opts, Format) -> - case read_packet(Dev, Opts, Format) of - eof -> []; - Tuple -> [Tuple | read_packets(Dev, Opts, Format)] - end. - -read_packet(Dev, Opts, bin) -> - Size = proplists:get_value(frame_size, Opts), - case file:read(Dev, Size) of - {ok, Data} -> {0, #rtp_packet{payload = iolist_to_binary(Data)}}; - eof -> eof - end; -read_packet(Dev, _Opts, Format) -> - case read_packet_line(Dev, Format) of - {Time, Bin} -> {Time, parse_rtp_packet(Bin)}; - eof -> eof - end. - -read_packet_line(Dev, state) -> - case io:fread(Dev, "", "~f ~s") of - {ok, [Time, Hex]} -> {Time, hex_to_bin(Hex)}; - eof -> eof - end. diff --git a/contrib/rtp/rtp_replay.st b/contrib/rtp/rtp_replay.st deleted file mode 100644 index e26d07388..000000000 --- a/contrib/rtp/rtp_replay.st +++ /dev/null @@ -1,21 +0,0 @@ -" -Simple UDP replay from the state files -" - -PackageLoader fileInPackage: #Sockets. -FileStream fileIn: 'rtp_replay_shared.st'. - - -Eval [ - | replay file host dport | - - file := Smalltalk arguments at: 1 ifAbsent: [ 'rtpstream.state' ]. - host := Smalltalk arguments at: 2 ifAbsent: [ '127.0.0.1' ]. - dport := (Smalltalk arguments at: 3 ifAbsent: [ '4000' ]) asInteger. - sport := (Smalltalk arguments at: 4 ifAbsent: [ '0' ]) asInteger. - - replay := RTPReplay on: file fromPort: sport. - - Transcript nextPutAll: 'Going to stream now'; nl. - replay streamAudio: host port: dport. -] diff --git a/contrib/rtp/rtp_replay_shared.st b/contrib/rtp/rtp_replay_shared.st deleted file mode 100644 index 7b68c0f5e..000000000 --- a/contrib/rtp/rtp_replay_shared.st +++ /dev/null @@ -1,118 +0,0 @@ -" -Simple UDP replay from the state files -" - -PackageLoader fileInPackage: #Sockets. - -Object subclass: SDPUtils [ - "Look into using PetitParser." - SDPUtils class >> findPort: aSDP [ - aSDP linesDo: [:line | - (line startsWith: 'm=audio ') ifTrue: [ - | stream | - stream := line readStream - skip: 'm=audio ' size; - yourself. - ^ Number readFrom: stream. - ] - ]. - - ^ self error: 'Not found'. - ] - - SDPUtils class >> findHost: aSDP [ - aSDP linesDo: [:line | - (line startsWith: 'c=IN IP4 ') ifTrue: [ - | stream | - ^ stream := line readStream - skip: 'c=IN IP4 ' size; - upToEnd. - ] - ]. - - ^ self error: 'Not found'. - ] -] - -Object subclass: RTPReplay [ - | filename socket | - RTPReplay class >> on: aFile [ - ^ self new - initialize; - file: aFile; yourself - ] - - RTPReplay class >> on: aFile fromPort: aPort [ - ^ self new - initialize: aPort; - file: aFile; yourself - ] - - initialize [ - self initialize: 0. - ] - - initialize: aPort [ - socket := Sockets.DatagramSocket local: '0.0.0.0' port: aPort. - ] - - file: aFile [ - filename := aFile - ] - - localPort [ - ^ socket port - ] - - streamAudio: aHost port: aPort [ - | file last_time last_image udp_send dest | - - last_time := nil. - last_image := nil. - file := FileStream open: filename mode: #read. - - "Send the payload" - dest := Sockets.SocketAddress byName: aHost. - udp_send := [:payload | | datagram | - datagram := Sockets.Datagram data: payload contents address: dest port: aPort. - socket nextPut: datagram - ]. - - [file atEnd] whileFalse: [ - | lineStream time data now_image | - lineStream := file nextLine readStream. - - "Read the time, skip the blank, parse the data" - time := Number readFrom: lineStream. - lineStream skip: 1. - - data := WriteStream on: (ByteArray new: 30). - [lineStream atEnd] whileFalse: [ - | hex | - hex := lineStream next: 2. - data nextPut: (Number readFrom: hex readStream radix: 16). - ]. - - last_time isNil - ifTrue: [ - "First time, send it right now" - last_time := time. - last_image := Time millisecondClockValue. - udp_send value: data. - ] - ifFalse: [ - | wait_image new_image_time | - - "How long to wait?" - wait_image := last_image + ((time - last_time) * 1000). - [ wait_image > Time millisecondClockValue ] - whileTrue: [Processor yield]. - - udp_send value: data. - last_time := time. - last_image := wait_image. - ] - ] - ] -] - diff --git a/contrib/rtp/rtp_replay_sip.st b/contrib/rtp/rtp_replay_sip.st deleted file mode 100644 index 5f844df1d..000000000 --- a/contrib/rtp/rtp_replay_sip.st +++ /dev/null @@ -1,87 +0,0 @@ -""" -Create a SIP connection and then stream... -""" - -PackageLoader - fileInPackage: #OsmoSIP. - -"Load for the replay code" -FileStream fileIn: 'rtp_replay_shared.st'. - - -Osmo.SIPCall subclass: StreamCall [ - | sem stream | - - createCall: aSDP [ - | sdp | - stream := RTPReplay on: 'rtp_ssrc6976010.240.240.1_to_10.240.240.50.state'. - sdp := aSDP % {stream localPort}. - ^ super createCall: sdp. - ] - - sem: aSemaphore [ - sem := aSemaphore - ] - - sessionNew [ - | host port | - Transcript nextPutAll: 'The call has started'; nl. - Transcript nextPutAll: sdp_result; nl. - - host := SDPUtils findHost: sdp_result. - port := SDPUtils findPort: sdp_result. - - [ - stream streamAudio: host port: port. - Transcript nextPutAll: 'Streaming has finished.'; nl. - ] fork. - ] - - sessionFailed [ - sem signal - ] - - sessionEnd [ - sem signal - ] -] - -Eval [ - | transport agent call sem sdp_fr sdp_amr | - - - sdp_fr := (WriteStream on: String new) - nextPutAll: 'v=0'; cr; nl; - nextPutAll: 'o=twinkle 1739517580 1043400482 IN IP4 127.0.0.1'; cr; nl; - nextPutAll: 's=-'; cr; nl; - nextPutAll: 'c=IN IP4 127.0.0.1'; cr; nl; - nextPutAll: 't=0 0'; cr; nl; - nextPutAll: 'm=audio %1 RTP/AVP 0 101'; cr; nl; - nextPutAll: 'a=rtpmap:0 PCMU/8000'; cr; nl; - nextPutAll: 'a=rtpmap:101 telephone-event/8000'; cr; nl; - nextPutAll: 'a=fmtp:101 0-15'; cr; nl; - nextPutAll: 'a=ptime:20'; cr; nl; - contents. - - sem := Semaphore new. - transport := Osmo.SIPUdpTransport - startOn: '0.0.0.0' port: 5066. - agent := Osmo.SIPUserAgent createOn: transport. - transport start. - - call := (StreamCall - fromUser: 'sip:1000@sip.zecke.osmocom.org' - host: '127.0.0.1' - port: 5060 - to: 'sip:123456@127.0.0.1' - on: agent) - sem: sem; yourself. - - call createCall: sdp_fr. - - - "Wait for the stream to have ended" - sem wait. - - (Delay forSeconds: 4) wait. -] diff --git a/contrib/rtp/timestamp_rtp.lua b/contrib/rtp/timestamp_rtp.lua deleted file mode 100644 index c18a06bed..000000000 --- a/contrib/rtp/timestamp_rtp.lua +++ /dev/null @@ -1,28 +0,0 @@ -print("Ni hao") - - -do - local tap = Listener.new("ip", "rtp") - local rtp_ssrc = Field.new("rtp.ssrc") - local frame_time = Field.new("frame.time_relative") - local rtp = Field.new("rtp") - - function tap.packet(pinfo, tvb, ip) - local ip_src, ip_dst = tostring(ip.ip_src), tostring(ip.ip_dst) - local rtp_data = rtp() - local filename = "rtp_ssrc" .. rtp_ssrc() "_src_" .. ip_src .. "_to_" .. ip_dst .. ".state" - local f = io.open(filename, "a") - - f:write(tostring(frame_time()) .. " ") - f:write(tostring(rtp_data.value)) - f:write("\n") - f:close() - end - - function tap.draw() - print("DRAW") - end - function tap.reset() - print("RESET") - end -end diff --git a/contrib/sms/fill-hlr.st b/contrib/sms/fill-hlr.st deleted file mode 100644 index da0643ecf..000000000 --- a/contrib/sms/fill-hlr.st +++ /dev/null @@ -1,66 +0,0 @@ -"I create output for some simple SQL statements for the HLR db" - - -Eval [ - -"Create tables if they don't exist" -Transcript show: 'CREATE TABLE SMS ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - created TIMESTAMP NOT NULL, - sent TIMESTAMP, - sender_id INTEGER NOT NULL, - receiver_id INTEGER NOT NULL, - deliver_attempts INTEGER NOT NULL DEFAULT 0, - valid_until TIMESTAMP, - reply_path_req INTEGER NOT NULL, - status_rep_req INTEGER NOT NULL, - protocol_id INTEGER NOT NULL, - data_coding_scheme INTEGER NOT NULL, - ud_hdr_ind INTEGER NOT NULL, - dest_addr TEXT, - user_data BLOB, - header BLOB, - text TEXT);'; nl; - show: 'CREATE TABLE Subscriber ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - created TIMESTAMP NOT NULL, - updated TIMESTAMP NOT NULL, - imsi NUMERIC UNIQUE NOT NULL, - name TEXT, - extension TEXT UNIQUE, - authorized INTEGER NOT NULL DEFAULT 0, - tmsi TEXT UNIQUE, - lac INTEGER NOT NULL DEFAULT 0);'; nl. - -"Create some dummy subscribers" -num_sub := 1000. -num_sms := 30. -lac := 1. - -Transcript show: 'BEGIN;'; nl. - -1 to: num_sub do: [:each | - Transcript show: 'INSERT INTO Subscriber - (imsi, created, updated, authorized, lac, extension) - VALUES - (%1, datetime(''now''), datetime(''now''), 1, %2, %3);' % - {(274090000000000 + each). lac. each}; nl. -]. - -1 to: num_sms do: [:sms | - 1 to: num_sub do: [:sub | - Transcript show: 'INSERT INTO SMS - (created, sender_id, receiver_id, valid_until, - reply_path_req, status_rep_req, protocol_id, - data_coding_scheme, ud_hdr_ind, dest_addr, - text) VALUES - (datetime(''now''), 1, %1, ''2222-2-2'', - 0, 0, 0, - 0, 0, ''123456'', - ''abc'');' % {sub}; nl. - ] -]. - -Transcript show: 'COMMIT;'; nl. - -] diff --git a/contrib/sms/hlr-query.st b/contrib/sms/hlr-query.st deleted file mode 100644 index bd3f97a4a..000000000 --- a/contrib/sms/hlr-query.st +++ /dev/null @@ -1,10 +0,0 @@ -"Query for one SMS" - -Eval [ -1 to: 100 do: [:each | - Transcript show: 'SELECT SMS.* FROM SMS - JOIN Subscriber ON SMS.receiver_id = Subscriber.id - WHERE SMS.id >= 1 AND SMS.sent IS NULL AND Subscriber.lac > 0 - ORDER BY SMS.id LIMIT 1;'; nl. -]. -] diff --git a/contrib/sms/sqlite-probe.tap.d b/contrib/sms/sqlite-probe.tap.d deleted file mode 100644 index e75cdfcfa..000000000 --- a/contrib/sms/sqlite-probe.tap.d +++ /dev/null @@ -1,5 +0,0 @@ -probe process("/usr/lib/libsqlite3.so.0.8.6").function("sqlite3_get_table") -{ - a = user_string($zSql); - printf("sqlite3_get_table called '%s'\n", a); -} diff --git a/contrib/systemd/osmo-bsc-mgcp.service b/contrib/systemd/osmo-bsc-mgcp.service deleted file mode 100644 index c040e6078..000000000 --- a/contrib/systemd/osmo-bsc-mgcp.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=OpenBSC MGCP - -[Service] -Type=simple -Restart=always -ExecStart=/usr/bin/osmo-bsc_mgcp -s -c /etc/osmocom/osmo-bsc-mgcp.cfg -RestartSec=2 - -[Install] -WantedBy=multi-user.target diff --git a/contrib/systemd/osmo-gbproxy.service b/contrib/systemd/osmo-gbproxy.service deleted file mode 100644 index a0b7829db..000000000 --- a/contrib/systemd/osmo-gbproxy.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Osmocom Gb proxy - -[Service] -Type=simple -ExecStart=/usr/bin/osmo-gbproxy -c /etc/osmocom/osmo-gbproxy.cfg -Restart=always -RestartSec=2 -RestartPreventExitStatus=1 - -[Install] -WantedBy=multi-user.target diff --git a/contrib/systemd/osmo-msc.service b/contrib/systemd/osmo-msc.service deleted file mode 100644 index 7cebb1468..000000000 --- a/contrib/systemd/osmo-msc.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Osmocom Mobile Switching Center (MSC) -Wants=osmo-hlr.service -After=osmo-hlr.service -After=osmo-hnbgw.service - -[Service] -Type=simple -Restart=always -ExecStart=/usr/bin/osmo-msc -c /etc/osmocom/osmo-msc.cfg -RestartSec=2 - -[Install] -WantedBy=multi-user.target diff --git a/contrib/systemd/osmo-nitb.service b/contrib/systemd/osmo-nitb.service deleted file mode 100644 index 377497ee5..000000000 --- a/contrib/systemd/osmo-nitb.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=OpenBSC Network In the Box (NITB) - -[Service] -Type=simple -Restart=always -ExecStart=/usr/bin/osmo-nitb -s -C -c /etc/osmocom/osmo-nitb.cfg -l /var/lib/osmocom/hlr.sqlite3 -RestartSec=2 - -[Install] -WantedBy=multi-user.target diff --git a/contrib/systemd/osmo-sgsn.service b/contrib/systemd/osmo-sgsn.service deleted file mode 100644 index bf6a8e098..000000000 --- a/contrib/systemd/osmo-sgsn.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=OpenBSC SGSN -Wants=osmo-hlr.service -After=osmo-hlr.service -After=osmo-hnbgw.service - -[Service] -Type=simple -Restart=always -ExecStart=/usr/bin/osmo-sgsn -c /etc/osmocom/osmo-sgsn.cfg -RestartSec=2 - -[Install] -WantedBy=multi-user.target diff --git a/contrib/testconv/Makefile b/contrib/testconv/Makefile deleted file mode 100644 index bb856f750..000000000 --- a/contrib/testconv/Makefile +++ /dev/null @@ -1,16 +0,0 @@ - -OBJS = testconv_main.o - -CC = gcc -CFLAGS = -O0 -ggdb -Wall -LDFLAGS = -CPPFLAGS = -I../.. -I../../include $(shell pkg-config --cflags libosmocore) $(shell pkg-config --cflags libbcg729) -LIBS = ../../src/libmgcp/libmgcp.a ../../src/libcommon/libcommon.a $(shell pkg-config --libs libosmocore) $(shell pkg-config --libs libbcg729) -lgsm -lrt - -testconv: $(OBJS) - $(CC) -o $@ $^ $(LDFLAGS) $(LIBS) - -testconv_main.o: testconv_main.c - -$(OBJS): - $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< diff --git a/contrib/testconv/testconv_main.c b/contrib/testconv/testconv_main.c deleted file mode 100644 index 6c95c5542..000000000 --- a/contrib/testconv/testconv_main.c +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "bscconfig.h" -#ifndef BUILD_MGCP_TRANSCODING -#error "Requires MGCP transcoding enabled (see --enable-mgcp-transcoding)" -#endif - -#include "openbsc/mgcp_transcode.h" - -static int audio_name_to_type(const char *name) -{ - if (!strcasecmp(name, "gsm")) - return 3; -#ifdef HAVE_BCG729 - else if (!strcasecmp(name, "g729")) - return 18; -#endif - else if (!strcasecmp(name, "pcma")) - return 8; - else if (!strcasecmp(name, "l16")) - return 11; - return -1; -} - -int mgcp_get_trans_frame_size(void *state_, int nsamples, int dst); - -int main(int argc, char **argv) -{ - char buf[4096] = {0x80, 0}; - int cc, rc; - struct mgcp_rtp_end *dst_end; - struct mgcp_rtp_end *src_end; - struct mgcp_trunk_config tcfg = {{0}}; - struct mgcp_endpoint endp = {0}; - struct mgcp_process_rtp_state *state; - int in_size; - int in_samples = 160; - int out_samples = 0; - uint32_t ts = 0; - uint16_t seq = 0; - - osmo_init_logging(&log_info); - - tcfg.endpoints = &endp; - tcfg.number_endpoints = 1; - endp.tcfg = &tcfg; - mgcp_initialize_endp(&endp); - - dst_end = &endp.bts_end; - src_end = &endp.net_end; - - if (argc <= 2) - errx(1, "Usage: {gsm|g729|pcma|l16} {gsm|g729|pcma|l16} [SPP]"); - - if ((src_end->codec.payload_type = audio_name_to_type(argv[1])) == -1) - errx(1, "invalid input format '%s'", argv[1]); - if ((dst_end->codec.payload_type = audio_name_to_type(argv[2])) == -1) - errx(1, "invalid output format '%s'", argv[2]); - if (argc > 3) - out_samples = atoi(argv[3]); - - if (out_samples) { - dst_end->codec.frame_duration_den = dst_end->codec.rate; - dst_end->codec.frame_duration_num = out_samples; - dst_end->frames_per_packet = 1; - } - - rc = mgcp_transcoding_setup(&endp, dst_end, src_end); - if (rc < 0) - errx(1, "setup failed: %s", strerror(-rc)); - - state = dst_end->rtp_process_data; - OSMO_ASSERT(state != NULL); - - in_size = mgcp_transcoding_get_frame_size(state, in_samples, 0); - OSMO_ASSERT(sizeof(buf) >= in_size + 12); - - buf[1] = src_end->codec.payload_type; - *(uint16_t*)(buf+2) = htons(1); - *(uint32_t*)(buf+4) = htonl(0); - *(uint32_t*)(buf+8) = htonl(0xaabbccdd); - - while ((cc = read(0, buf + 12, in_size))) { - int cont; - int len; - - if (cc != in_size) - err(1, "read"); - - *(uint16_t*)(buf+2) = htonl(seq); - *(uint32_t*)(buf+4) = htonl(ts); - - seq += 1; - ts += in_samples; - - cc += 12; /* include RTP header */ - - len = cc; - - do { - cont = mgcp_transcoding_process_rtp(&endp, dst_end, - buf, &len, sizeof(buf)); - if (cont == -EAGAIN) { - fprintf(stderr, "Got EAGAIN\n"); - break; - } - - if (cont < 0) - errx(1, "processing failed: %s", strerror(-cont)); - - len -= 12; /* ignore RTP header */ - - if (write(1, buf + 12, len) != len) - err(1, "write"); - - len = cont; - } while (len > 0); - } - return 0; -} - diff --git a/doc/call-routing.txt b/doc/call-routing.txt deleted file mode 100644 index 3402f9e33..000000000 --- a/doc/call-routing.txt +++ /dev/null @@ -1,25 +0,0 @@ -Call routing in OpenBSC - -Flow of events: - - # MO call initiated by MS, CHANNEL RQD, IMMEDIATE ASSIGN - # MS sends CC SETUP message, we assume already on TCH/H FACCH - # OpenBSC does a subscriber lookup based on the target extension - * If a subscriber is found: - # send CALL PROCEEDING message to MO - # page the MT subscriber and ask itI to ask for TCH/H - # once paging completes, we have the TCH/H for the MT end - # send SETUP to MT - # receive CALL CONFIRMED from MT - # set-up the TRAU mux mapping between the E1 subslots for both TCH/H - # receive ALERTING from MT, route ALERTING to MO - # receive CONNECT from MT, confirm to MT with CONNECT_ACK - # send a CONNECT message to MO, receive CONNECT_ACK from MO - * If subscriber is not found: - # send RELEASE COMPLETE with apropriate cause to MO (1: unalloacated 3: no route) - - - -Thoughts about RR/MM: - -* we allocate RR/MM entities on demand, when we need them diff --git a/doc/channel_release.txt b/doc/channel_release.txt deleted file mode 100644 index c9cdfebca..000000000 --- a/doc/channel_release.txt +++ /dev/null @@ -1,95 +0,0 @@ - -GSM 04.08 7.1.7 / 9.1.7 RR CHANNEL RELESE - -RSL 08.58 3.4 / ? RLL Link Release Request - -RSL 08.58 4.6 / 8.4.5 DEACTivate SACCH - * Deactivate SACCH according to Channel Release Proc 04.08 - * to be sent after RR CHANNEL RELEASE is sent to MS - -RSL 08.58 4.7 / 8.4.14 RF CHANnel RELease - * tells the BTS to release a radio channel - * "when an activated radio channel is no longer needed" - * BTS responds with RF CHANnel RELease ACKnowledge - - -GSM 04.08 3.4.13: RR connection release procedure - -* network sends RR CHANNEL RELEASE to MS on the DCCH - * start T3109 - * deactivate SACCH -* MS disconnects main signalling link (by sending DISC) - * all other data links are disconnected by local end link release -* network receives DISC (BTS sends RLL REL IND to BSC) - * stop T3109 - * start T3111 -* when T3111 times out, the network can reuse the channls -* if T3109 times out, the network deactivates the channels - and can reuse them - * this probably means simply RF CHANnel RELease - - -== Implementation in OpenBSC == - -There are two possible reasons a gsm_subscriber_connection -will be released. One is a network failure, the other is -the completion of an operation/transaction. - -=== Failure === -The BSC API will call the gsm_04_08.c:gsm0408_clear_request callback -and the MSC part will release all transactions, operations and such -and the channels will be released as error case. - -=== Success === -Every time an 'operation' or 'transaction' is finished msc_release_connection -will be called and it will determine if the gsm_subscriber_connection can -be released. - -In case it can be released bsc_api.c:gsm0808_clear will be called -which will release all lchan's associated with the connection. For the -primary channel a SACH Deactivate will be send with the release -reason NORMAL RELEASE. - - -bsc_api.c:gsm0808_clear - * Release a channel used for handover - * Release the primary lchan with normal release, SACH deactivate - -chan_alloc.c:lchan_release(chan, sacch_deactivate, reason) - * Start the release procedure. It is working in steps with callbacks - coming from the abis_rsl.c code. - * Release all SAPI's > 0 as local end (The BTS should send a - REL_CONF a message) - * Send SACH Deactivate on SAPI=0 if required. - * Start T3109 (stop it when the main signalling link is disconnected) - or when the channel released. On timeout start the error handling. - * abis_rsl.c schedules the RSL_MT_RF_CHAN_REL once all SAPI's are - released and after T3111 has timed out or there is an error. - -RX of RELease INDication: - * Calls internal rsl_handle_release which might release the RF. - -RX of RELease CONFirmation: - * Calls internal rsl_handle_release which might release the RF. - -* RX of RF_CHAN_REL_ACK - * call lchan_free() - - -=== Integration with SMS === - -* RX of CP_ERROR or unimplemented MT - * trigger trans_free() which will msc_release_connection() - -* CP TC1* expired while waiting for CP-ACK - * trigger trans_free() which will msc_release_connection() - -* RX of RP_ERROR - * trigger trans_free() which will msc_release_connection() - -* TX of CP-ACK in MT DELIVER - * trigger trans_free() which will msc_release_connection() - -* RX of CP-ACK in MO SUBMIT - * trigger trans_free() which will msc_release_connection() - diff --git a/doc/examples/osmo-bsc_mgcp/mgcp.cfg b/doc/examples/osmo-bsc_mgcp/mgcp.cfg deleted file mode 100644 index 3c43f1feb..000000000 --- a/doc/examples/osmo-bsc_mgcp/mgcp.cfg +++ /dev/null @@ -1,19 +0,0 @@ -! -! MGCP configuration hand edited -! ! -password foo -! -line vty - no login -! -mgcp - !local ip 10.23.24.2 - !bts ip 10.24.24.1 - !bind ip 10.23.24.1 - bind port 2427 - rtp base 4000 - rtp force-ptime 20 - sdp audio payload number 98 - sdp audio payload name AMR/8000 - number endpoints 31 - no rtcp-omit diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg deleted file mode 100644 index 15fd74a2b..000000000 --- a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg +++ /dev/null @@ -1,44 +0,0 @@ -! -! OsmoGbProxy (UNKNOWN) configuration saved from vty -!! -! -log stderr - logging filter all 1 - logging color 1 - logging timestamp 0 - logging level all debug - logging level gprs debug - logging level ns info - logging level bssgp debug - logging level lglobal notice - logging level llapd notice - logging level linp notice - logging level lmux notice - logging level lmi notice - logging level lmib notice - logging level lsms notice -! -line vty - no login -! -ns - nse 666 nsvci 666 - nse 666 remote-role sgsn -! nse 666 encapsulation framerelay-gre -! nse 666 remote-ip 172.16.1.70 -! nse 666 fr-dlci 666 - timer tns-block 3 - timer tns-block-retries 3 - timer tns-reset 3 - timer tns-reset-retries 3 - timer tns-test 30 - timer tns-alive 3 - timer tns-alive-retries 10 - encapsulation udp local-port 23000 -! encapsulation framerelay-gre enabled 1 -gbproxy - sgsn nsei 666 - core-mobile-country-code 666 - core-mobile-network-code 6 - core-access-point-name none match-imsi ^666066|^66607 - tlli-list max-length 200 diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg deleted file mode 100644 index 0c3917a3e..000000000 --- a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg +++ /dev/null @@ -1,25 +0,0 @@ -! -! Osmocom Gb Proxy (0.9.0.404-6463) configuration saved from vty -!! -! -line vty - no login -! -gbproxy - sgsn nsei 101 -ns - nse 101 nsvci 101 - nse 101 remote-role sgsn - nse 101 encapsulation udp - nse 101 remote-ip 192.168.100.239 - nse 101 remote-port 7777 - 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 framerelay-gre enabled 0 - encapsulation framerelay-gre local-ip 0.0.0.0 - encapsulation udp local-port 23000 diff --git a/doc/examples/osmo-gtphub/gtphub-example.txt b/doc/examples/osmo-gtphub/gtphub-example.txt deleted file mode 100644 index 9c65f925f..000000000 --- a/doc/examples/osmo-gtphub/gtphub-example.txt +++ /dev/null @@ -1,90 +0,0 @@ -Here is a simple setup to test GTPHub operations. The IP addresses picked will -work well only on a system that creates local addresses (127.0.0.123) on the -fly (like linux) -- you may pick of course different IP addresses. - -Overview of the example setup: - - sgsnemu gtphub ggsn - 127.0.0.1 <--> 127.0.0.3 127.0.0.4 <--> 127.0.0.2 - -Prerequisites: openggsn. - -Have a local directory where you store config files and from which you launch -the GSNs and the hub (they will store restart counter files in that dir). -In it, have these config files: - -ggsn.conf: - - # GGSN local address - listen 127.0.0.2 - - # End User Addresses are picked from this range - net 10.23.42.0/24 - - pcodns1 8.8.8.8 - - logfile /tmp/foo - -gtphub.conf: - - gtphub - bind-to-sgsns 127.0.0.3 - bind-to-ggsns 127.0.0.4 - ggsn-proxy 127.0.0.2 - end - - -( -You may omit the ggsn-proxy if GRX ares is working, or if you add the GRX -address and GGSN IP address to /etc/hosts something like: - - 127.0.0.2 internet.mnc070.mcc901.gprs - -) - - -Once the config files are in place, start the programs, in separate terminals. -GGSN and SGSN need to be started with root priviliges to be able to create tun -interfaces. GTPHub may run as unprivileged user. - -The LD_LIBRARY_PATH below may be needed if OpenGGSN installed to /usr/local. - - -1. GGSN: - - sudo -s - cd - LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/ggsn -f -c ./ggsn.conf - -2. GTPHub: - - cd - path/to/openbsc/openbsc/src/gprs/osmo-gtphub -c gtphub.conf #-e 1 #for DEBUG level - -3. SGSN tests: - - sudo -s - cd - /usr/local/bin/sgsnemu --createif -l 127.0.0.1 -r 127.0.0.3 --imsi 420001214365100 --contexts=3 - -Add more SGSNs using different IMSIs and local ports (if the same IMSI is used, -the GGSN will reuse TEIs and tunnels will be discarded automatically): - - /usr/local/bin/sgsnemu --createif -l 127.0.0.11 -r 127.0.0.3 --imsi 420001214365300 --contexts=3 - -This shows the basic setup of GTPHub. Testing internet traffic via sgsnemu -still needs some effort to announce a mobile subscriber or the like (I have -used a real BTS, osmo-sgsn and a testing SIM in a web phone, instead). - -The core capability of GTPHub is to manage more than two GSNs, e.g. an SGSN -contacting various GGSNs over the single GTPHub link. You would configure the -SGSN to use one fixed GGSN (sending to gtphub) and gtphub will resolve the -GGSNs once it has received the messages. So the SGSN may be behind NAT (add -"sgsn-use-sender" to gtphub.conf) and communicate to various GGSNs over a -single link to gtphub. - -I hope this helps to get you going. -Any suggestions/patches are welcome! - -~Neels - diff --git a/doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg b/doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg deleted file mode 100644 index 3913d2c3c..000000000 --- a/doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg +++ /dev/null @@ -1,25 +0,0 @@ -! -! Osmocom gtphub configuration -! -! This file is used for VTY tests, referenced by openbsc/osmoappdesc.py -! For the test, try to use most config commands. -! - -line vty - no login - -gtphub - ! Local addresses to listen on and send from, both on one interface. - ! The side towards SGSN uses nonstandard ports. - bind-to-sgsns ctrl 127.0.0.1 12123 user 127.0.0.1 12153 - ! The GGSN side with standard ports. - bind-to-ggsns 127.0.0.1 - - ! Proxy: unconditionally direct all traffic to... - sgsn-proxy 127.0.0.4 - - ! Proxy with nonstandard ports or separate IPs: - ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152 - - ! Add a name server for GGSN resolution - grx-dns-add 192.168.0.1 diff --git a/doc/examples/osmo-gtphub/osmo-gtphub.cfg b/doc/examples/osmo-gtphub/osmo-gtphub.cfg deleted file mode 100644 index 0dc415047..000000000 --- a/doc/examples/osmo-gtphub/osmo-gtphub.cfg +++ /dev/null @@ -1,25 +0,0 @@ -! -! Osmocom gtphub configuration -! - -line vty - no login - -gtphub - ! Local addresses to listen on and send from, each on standard ports - ! 2123 and 2152. Setting these addresses is mandatory. - bind-to-sgsns 127.0.0.1 - bind-to-ggsns 127.0.0.2 - - ! Local nonstandard ports or separate IPs: - !bind-to-sgsns ctrl 127.0.0.1 2342 user 127.0.0.1 4223 - - ! Proxy: unconditionally direct all traffic to... - !ggsn-proxy 127.0.0.3 - !sgsn-proxy 127.0.0.4 - - ! Proxy with nonstandard ports or separate IPs: - !ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152 - - ! Add a name server for GGSN resolution - !grx-dns-add 192.168.0.1 diff --git a/doc/examples/osmo-msc/osmo-msc.cfg b/doc/examples/osmo-msc/osmo-msc.cfg deleted file mode 100644 index 1b1d19258..000000000 --- a/doc/examples/osmo-msc/osmo-msc.cfg +++ /dev/null @@ -1,19 +0,0 @@ -! -! OsmoMSC configuration saved from vty -! -line vty - no login -! -network - network country code 1 - mobile network code 1 - short name OsmoMSC - long name OsmoMSC - auth policy closed - location updating reject cause 13 - encryption a5 0 - rrlp mode none - mm info 1 -msc - mgcpgw remote-ip 10.23.24.1 - assign-tmsi diff --git a/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg b/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg deleted file mode 100644 index 5e6434263..000000000 --- a/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg +++ /dev/null @@ -1,27 +0,0 @@ -! -! Osmocom SGSN configuration -! -! -line vty - no login -! -sgsn - gtp local-ip 127.0.0.1 - ggsn 0 remote-ip 127.0.0.2 - 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 127.0.0.1 - encapsulation udp local-port 23000 - encapsulation framerelay-gre enabled 0 -! -bssgp -! diff --git a/doc/examples/osmo-sgsn/osmo-sgsn.cfg b/doc/examples/osmo-sgsn/osmo-sgsn.cfg deleted file mode 100644 index 06f035f1b..000000000 --- a/doc/examples/osmo-sgsn/osmo-sgsn.cfg +++ /dev/null @@ -1,29 +0,0 @@ -! -! Osmocom SGSN configuration -! -! -line vty - no login -! -sgsn - gtp local-ip 127.0.0.1 - ggsn 0 remote-ip 127.0.0.2 - ggsn 0 gtp-version 1 - auth-policy remote - gsup remote-ip 127.0.0.1 - gsup remote-port 4222 -! -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 127.0.0.1 - encapsulation udp local-port 23000 - encapsulation framerelay-gre enabled 0 -! -bssgp -! diff --git a/doc/gsm-hopping.txt b/doc/gsm-hopping.txt deleted file mode 100644 index c964963c0..000000000 --- a/doc/gsm-hopping.txt +++ /dev/null @@ -1,54 +0,0 @@ -according to GSM 05.02: - -general parameters from CCCH: -* CA cell allocation of ARFCN's (System Information / BCCH) -* FN: TDMA frame number (t1,t2,t3') in SCH - -specific parameters from channel assignment: -* MA: mobile allocation, defines set of ARFCN's, up to 64 -* MAIO: index -* HSN: hopping sequence generator number (0..64) - - -hopping sequence generation (6.2.3): - -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, - 80, 34, 127, 13, 6, 89, 57, 103, 12, 74, - 55, 111, 75, 38, 109, 71, 112, 29, 11, 88, - 87, 19, 3, 68, 110, 26, 33, 31, 8, 45, - 82, 58, 40, 107, 32, 5, 106, 92, 62, 67, - 77, 108, 122, 37, 60, 66, 121, 42, 51, 126, - 117, 114, 4, 90, 43, 52, 53, 113, 120, 72, - 16, 49, 7, 79, 119, 61, 22, 84, 9, 97, - 125, 99, 17, 123 -}; - -/* mai=0 represents lowest ARFCN in the MA */ - - -uint8_t hopping_mai(uint8_t hsn, uint32_t fn, uint8_t maio, - uint8_t t1, uint8_t t2, uint8_t t3_) -{ - uint8_t mai; - - if (hsn == 0) /* cyclic hopping */ - mai = (fn + maio) % n; - else { - uint32_t m, m_, t_, s; - - m = t2 + rntable[(hsn xor (t1 % 64)) + t3]; - m_ = m % (2^NBIN); - t_ = t3 % (2^NBIN); - if (m_ < n then) - s = m_; - else - s = (m_ + t_) % n; - mai = (s + maio) % n; - } - - return mai; -} - diff --git a/doc/ipa-sccp.txt b/doc/ipa-sccp.txt deleted file mode 100644 index 5d6719e98..000000000 --- a/doc/ipa-sccp.txt +++ /dev/null @@ -1,94 +0,0 @@ - -IPA SCCP message flow in the BSC - -February, 2013 Holger Hans Peter Freyther - -CONTENTS - -1. SCCP inside the IPA header -2. Supported SCCP message types -3. Receiving SCCP messages -4. Sending SCCP messages - - -1. SCCP inside the IPA header - -Many Soft-MSCs implement something that is called SCCP/lite. This means -that SCCP messages are transported inside a small multiplexing protocol -over TCP/IP. This is an alternative to a full SIGTRAN implementation. - -The multiplexing protocol is the same as used with the sysmoBTS and the -ip.access nanoBTS. It is a three byte header with two bytes for the length -in network byte order and one byte for the type. The type to be used for -SCCP is 0xFD. - - struct ipa_header { - uint16_t length_in_network_order; - uint8_t type; - } __attribute__((packed)); - - - -2. Supported SCCP message types - -To implement GSM 08.08 only a subset of SCCP messages need to be implemented. -For transporting paging and reset messages SCCP UDT messages are used. For -the connections with a Mobile Station (MS) a SCCP connection is opened. This -means that the SCCP CR, SCCP CC, SCCP CREF, SCCP RLC, SCCP RLSD, SCCP DT1 -and SCCP IT messages are supported. - - -3. Receiving SCCP UDT messages - -This is an illustration of the flow of messages. The IPA multiplexing protocol -is used for various protocols. This means there is a central place where the -multiplexing stream terminates. The stream is terminated in the osmo_bsc_msc.c -file and the ipaccess_a_fd_cb method. For SCCP messages the SCCP dispatching -sccp_system_incoming method is called. This function is implemented in the -libosmo-sccp library. - -To receive UDT messages osmo_bsc_sccp.c:osmo_bsc_sccp_init is using the -sccp_set_read function to register a callback for UDT messages. The callback -is msc_sccp_read and it is calling bsc_handle_udt that is implemented in the -osmo_bsc_bssap.c. This function will handle the GSM 08.08 BSSAP messages. -Currently only the reset acknowledge and the paging messages are handled. - -The BSC currently does not accept incoming SCCP messages and is only opening -SCCP connections to the MSC. When opening a connection the callbacks for state -changes (connection confirmed, released, release complete) are set and a routine -for handling incoming data. This registration is done in the osmo_bsc_sccp.c -file and the bsc_create_new_connection method. The name of the callback is -msc_outgoing_sccp_data and this will call bsc_handle_dt1 that is implemented -in the osmo_bsc_bssap.c file. This will forward the messages to the right -Mobile Station (MS). - - -4. Sending SCCP messages - -There are three parts to sending that will be explained below. The first part -is to send an entire SCCP frame (which includes the GSM 08.08 data) to the -MSC. This is done by first registering the low level sending. sccp_system_init -is called with the function that is responsible for sending a message. The -msc_sccp_write_ipa will call the msc_queue_write function with the data and -the right MSC connection. Below the msc_queue_write the IPA header will be -prepended to the msg and then send to the MSC. - -The BSC supports multiple different A-link connections, the decision to pick -the right MSC is done in this method. It is either done via the SCCP connection -or the ctx pointer. - -When the BSC is starting a BSS RESET message will be sent to the MSC. The reset -is created in osmo_bsc_msc.c:initialize_if_needed and sccp_write is called with -the GSM 08.08 data and the connection to use. The libosmo-sccp library will -embed it into a SCCP UDT message and call the msc_sccp_write_ipa method. - -When a new SCCP connection is to be created the bsc_create_new_connection -in the osmo_bsc_sccp.c file. The sccp_connection_socket method will create -the context for a SCCP connection. The state and data callback will be used -to be notified about data and changes. Once the connection is configured the -bsc_open_connection will be called that will ask the libosmo-sccp library to -create a SCCP CR message using the sccp_connection_connect method. For active -connections the sccp_connection_write method will be called. - - - diff --git a/doc/oml-interface.txt b/doc/oml-interface.txt deleted file mode 100644 index 02bead77a..000000000 --- a/doc/oml-interface.txt +++ /dev/null @@ -1,22 +0,0 @@ -oml interface design notes - -problems: - -* there is no way how to tag a command sent to the BTS, with the response - having the same tag to identify the originator of the command -* therefore, we can have e.g. both the BSC and the OML interface send a - SET ATTRIBUTE message, where the responses would end up at the wrong - query. -* The BTS has 10s to ACK/NACK a command. We do not run any timers. - -the only possible solutions i can imagine: -* have some kind of exclusive locking, where the OML interface gets blocked - from the BSC and is exclusively assigned to the OML console until all commands - of the OML console have terminated. This can either be done explicitly - dynamically or on demand - -* use the OML interface synchronously, i.e. always wait for the response from - the BTS before - -* unilateral / unsolicited messages need to be broadcasted to both the BSC and - the OML console diff --git a/doc/osmo-nitb-data_structures.dot b/doc/osmo-nitb-data_structures.dot deleted file mode 100644 index 81955e8b9..000000000 --- a/doc/osmo-nitb-data_structures.dot +++ /dev/null @@ -1,33 +0,0 @@ -digraph G { - net [label="gsm_network"] - bts [label="gsm_bts"] - trx [label="gsm_bts_trx"] - ts [label="gsm_bts_trx_ts"] - lchan [label="gsm_lchan"] - sub [label="gsm_subscriber"] - subcon [label="gsm_subscriber_conn"] - sccpcon [label="osmo_bsc_sccp_con"] - subgrp [label="gsm_subscriber_group"] - - net -> bts - bts -> trx - trx -> ts - ts -> lchan - - lchan -> ts - ts -> trx - trx -> bts - bts -> net - - lchan -> subcon - - subcon -> sub - subcon -> sccpcon - subcon -> lchan - subcon -> lchan [label="ho_lchan"] - subcon -> bts - subcon -> lchan [label="secondary_lchan"] - - sub -> subgrp - subgrp -> net -} diff --git a/doc/paging.txt b/doc/paging.txt deleted file mode 100644 index c597c22b4..000000000 --- a/doc/paging.txt +++ /dev/null @@ -1,48 +0,0 @@ - -GSM Paging implementation in OpenBSC - -== Code structure == - -The code is implemented in the libbsc/paging.c file. The external -interface is documented/specified in the include/openbsc/paging.h -header file. The code is used by the NITB and BSC application. - - -== Implementation == - -Paging can be initiated in two ways. The standard way is to page by -LAC. Each BTS has its own list/queue of outstanding paging operation. -When a subscriber is paged one "struct paging_request" per BTS will -be allocated and added to the tail of the list. The BTS is supposed -to be configured to not repeat the paging. - -A paging_request will remain in the queue until a paging response or at -the expiry of the T3113. Every 500 milliseconds a RSL paging command is -send to the BTS. The 500 milliseconds is a throttling to not crash the -ip.access nanoBTS. Once one paging_request has been handled it will be -put at the end of the queue/list and the available slots for the BTS -will be decreased. - -The available slots will be updated based on the paging load information -element of the CCCH Load indication. If no paging slots are considered -to be available and no load indication is sent a timer is started. The -current timeout is 500 milliseconds and at the expiry of the timer the -available slots will be set to 20. - -OpenBSC has the " paging free <-1-1024>" configuration option. In case -there are less free channels than required no paging request will be -sent to the BTS. Instead it will be attempted to send the paging request -at the next timeout (500 milliseconds). - -== Limitation == - -The paging throughput could be higher but this has lead to crashes on the -ip.access nanoBTS in the past. - -== Configuration == - -=== ip.access nanoBTS === - -The current CCCH Load indication threshold is 10% and the period is 1 second. -The code can be found inside the src/libbsc/bts_ipaccess_nanobts.c inside the -nanobts_attr_bts array. diff --git a/include/openbsc/gsm_04_14.h b/include/openbsc/gsm_04_14.h deleted file mode 100644 index 3cdbe0469..000000000 --- a/include/openbsc/gsm_04_14.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -int gsm0414_tx_close_tch_loop_cmd(struct gsm_subscriber_connection *conn, - enum gsm414_tch_loop_mode loop_mode); -int gsm0414_tx_open_loop_cmd(struct gsm_subscriber_connection *conn); -int gsm0414_tx_act_emmi_cmd(struct gsm_subscriber_connection *conn); -int gsm0414_tx_test_interface(struct gsm_subscriber_connection *conn, - uint8_t tested_devs); -int gsm0414_tx_reset_ms_pos_store(struct gsm_subscriber_connection *conn, - uint8_t technology); - -int gsm0414_rcv_test(struct gsm_subscriber_connection *conn, - struct msgb *msg); diff --git a/osmoappdesc.py b/osmoappdesc.py index 021bf5b61..36eb1a752 100644 --- a/osmoappdesc.py +++ b/osmoappdesc.py @@ -14,25 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see - -# Most systems won't be able to use these, so they're separated out -nitb_e1_configs = [ - "doc/examples/osmo-nitb/bs11/openbsc-2bts-2trx.cfg", - "doc/examples/osmo-nitb/bs11/openbsc-1bts-2trx-hopping.cfg", - "doc/examples/osmo-nitb/bs11/openbsc-1bts-2trx.cfg", - "doc/examples/osmo-nitb/bs11/openbsc.cfg", - "doc/examples/osmo-nitb/nokia/openbsc_nokia_3trx.cfg", - "doc/examples/osmo-nitb/nanobts/openbsc-multitrx.cfg", - "doc/examples/osmo-nitb/rbs2308/openbsc.cfg" -] - - app_configs = { "osmo-bsc": ["doc/examples/osmo-bsc/osmo-bsc.cfg"], "nat": ["doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg"], } - apps = [(4242, "src/osmo-bsc/osmo-bsc", "OsmoBSC", "osmo-bsc"), (4244, "src/osmo-bsc_nat/osmo-bsc_nat", "OsmoBSCNAT", "nat"), ] diff --git a/src/libcommon/oap_client.c b/src/libcommon/oap_client.c deleted file mode 100644 index 5128ac119..000000000 --- a/src/libcommon/oap_client.c +++ /dev/null @@ -1,280 +0,0 @@ -/* Osmocom Authentication Protocol API */ - -/* (C) 2015 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -#include -#include - -#include -#include -#include - -#include -#include - -int oap_client_init(struct oap_client_config *config, - struct oap_client_state *state) -{ - OSMO_ASSERT(state->state == OAP_UNINITIALIZED); - - if (!config) - goto disable; - - if (config->client_id == 0) - goto disable; - - if (config->secret_k_present == 0) { - LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret K missing.\n"); - goto disable; - } - - if (config->secret_opc_present == 0) { - LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret OPC missing.\n"); - goto disable; - } - - state->client_id = config->client_id; - memcpy(state->secret_k, config->secret_k, sizeof(state->secret_k)); - memcpy(state->secret_opc, config->secret_opc, sizeof(state->secret_opc)); - state->state = OAP_INITIALIZED; - return 0; - -disable: - state->state = OAP_DISABLED; - return 0; -} - -/* From the given state and received RAND and AUTN octets, validate the - * server's authenticity and formulate the matching milenage reply octets in - * *tx_xres. The state is not modified. - * On success, and if tx_res is not NULL, exactly 8 octets will be written to - * *tx_res. If not NULL, tx_res must point at allocated memory of at least 8 - * octets. The caller will want to send XRES back to the server in a challenge - * response message and update the state. - * Return 0 on success; -1 if OAP is disabled; -2 if rx_random and rx_autn fail - * the authentication check; -3 for any other errors. */ -static int oap_evaluate_challenge(const struct oap_client_state *state, - const uint8_t *rx_random, - const uint8_t *rx_autn, - uint8_t *tx_xres) -{ - struct osmo_auth_vector vec; - - struct osmo_sub_auth_data auth = { - .type = OSMO_AUTH_TYPE_UMTS, - .algo = OSMO_AUTH_ALG_MILENAGE, - }; - - osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.k) - == sizeof(state->secret_k), _secret_k_size_match); - osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.opc) - == sizeof(state->secret_opc), _secret_opc_size_match); - - switch (state->state) { - case OAP_UNINITIALIZED: - case OAP_DISABLED: - return -1; - default: - break; - } - - memcpy(auth.u.umts.k, state->secret_k, sizeof(auth.u.umts.k)); - memcpy(auth.u.umts.opc, state->secret_opc, sizeof(auth.u.umts.opc)); - memset(auth.u.umts.amf, '\0', sizeof(auth.u.umts.amf)); - auth.u.umts.sqn = 41; /* TODO use incrementing sequence nr */ - - memset(&vec, 0, sizeof(vec)); - osmo_auth_gen_vec(&vec, &auth, rx_random); - - if (vec.res_len != 8) { - LOGP(DLOAP, LOGL_ERROR, "OAP: Expected XRES to be 8 octets, got %d\n", - vec.res_len); - return -3; - } - - if (osmo_constant_time_cmp(vec.autn, rx_autn, sizeof(vec.autn)) != 0) { - LOGP(DLOAP, LOGL_ERROR, "OAP: AUTN mismatch!\n"); - LOGP(DLOAP, LOGL_INFO, "OAP: AUTN from server: %s\n", - osmo_hexdump_nospc(rx_autn, sizeof(vec.autn))); - LOGP(DLOAP, LOGL_INFO, "OAP: AUTN expected: %s\n", - osmo_hexdump_nospc(vec.autn, sizeof(vec.autn))); - return -2; - } - - if (tx_xres != NULL) - memcpy(tx_xres, vec.res, 8); - return 0; -} - -struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_msg) -{ - struct msgb *msg = msgb_alloc_headroom(1000, 64, __func__); - OSMO_ASSERT(msg); - osmo_oap_encode(msg, oap_msg); - return msg; -} - -/* Create a new msgb containing an OAP registration message. - * On error, return NULL. */ -static struct msgb* oap_msg_register(uint16_t client_id) -{ - struct osmo_oap_message oap_msg = {0}; - - if (client_id < 1) { - LOGP(DLOAP, LOGL_ERROR, "OAP: Invalid client ID: %d\n", client_id); - return NULL; - } - - oap_msg.message_type = OAP_MSGT_REGISTER_REQUEST; - oap_msg.client_id = client_id; - return oap_client_encoded(&oap_msg); -} - -int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx) -{ - *msg_tx = oap_msg_register(state->client_id); - if (!(*msg_tx)) - return -1; - - state->state = OAP_REQUESTED_CHALLENGE; - return 0; -} - -/* Create a new msgb containing an OAP challenge response message. - * xres must point at 8 octets to return as challenge response. - * On error, return NULL. */ -static struct msgb* oap_msg_challenge_response(uint8_t *xres) -{ - struct osmo_oap_message oap_reply = {0}; - - oap_reply.message_type = OAP_MSGT_CHALLENGE_RESULT; - memcpy(oap_reply.xres, xres, sizeof(oap_reply.xres)); - oap_reply.xres_present = 1; - return oap_client_encoded(&oap_reply); -} - -static int handle_challenge(struct oap_client_state *state, - struct osmo_oap_message *oap_rx, - struct msgb **msg_tx) -{ - int rc; - uint8_t xres[8]; - - if (!(oap_rx->rand_present && oap_rx->autn_present)) { - LOGP(DLOAP, LOGL_ERROR, - "OAP challenge incomplete (rand_present: %d, autn_present: %d)\n", - oap_rx->rand_present, oap_rx->autn_present); - rc = -2; - goto failure; - } - - rc = oap_evaluate_challenge(state, - oap_rx->rand, - oap_rx->autn, - xres); - if (rc < 0) - goto failure; - - *msg_tx = oap_msg_challenge_response(xres); - if ((*msg_tx) == NULL) { - rc = -1; - goto failure; - } - - state->state = OAP_SENT_CHALLENGE_RESULT; - return 0; - -failure: - OSMO_ASSERT(rc < 0); - state->state = OAP_INITIALIZED; - return rc; -} - -int oap_client_handle(struct oap_client_state *state, - const struct msgb *msg_rx, struct msgb **msg_tx) -{ - uint8_t *data = msgb_l2(msg_rx); - size_t data_len = msgb_l2len(msg_rx); - struct osmo_oap_message oap_msg = {0}; - int rc = 0; - - *msg_tx = NULL; - - OSMO_ASSERT(data); - - rc = osmo_oap_decode(&oap_msg, data, data_len); - if (rc < 0) { - LOGP(DLOAP, LOGL_ERROR, - "Decoding OAP message failed with error '%s' (%d)\n", - get_value_string(gsm48_gmm_cause_names, -rc), -rc); - return -10; - } - - switch (state->state) { - case OAP_UNINITIALIZED: - LOGP(DLOAP, LOGL_ERROR, - "Received OAP message %d, but the OAP client is" - " not initialized\n", oap_msg.message_type); - return -ENOTCONN; - case OAP_DISABLED: - LOGP(DLOAP, LOGL_ERROR, - "Received OAP message %d, but the OAP client is" - " disabled\n", oap_msg.message_type); - return -ENOTCONN; - default: - break; - } - - switch (oap_msg.message_type) { - case OAP_MSGT_CHALLENGE_REQUEST: - return handle_challenge(state, &oap_msg, msg_tx); - - case OAP_MSGT_REGISTER_RESULT: - /* successfully registered */ - state->state = OAP_REGISTERED; - break; - - case OAP_MSGT_REGISTER_ERROR: - LOGP(DLOAP, LOGL_ERROR, - "OAP registration failed\n"); - state->state = OAP_INITIALIZED; - if (state->registration_failures < 3) { - state->registration_failures ++; - return oap_client_register(state, msg_tx); - } - return -11; - - case OAP_MSGT_REGISTER_REQUEST: - case OAP_MSGT_CHALLENGE_RESULT: - LOGP(DLOAP, LOGL_ERROR, - "Received invalid OAP message type for OAP client side: %d\n", - (int)oap_msg.message_type); - return -12; - - default: - LOGP(DLOAP, LOGL_ERROR, - "Unknown OAP message type: %d\n", - (int)oap_msg.message_type); - return -13; - } - - return 0; -} diff --git a/src/libmsc/gsm_04_14.c b/src/libmsc/gsm_04_14.c deleted file mode 100644 index b529f4c72..000000000 --- a/src/libmsc/gsm_04_14.c +++ /dev/null @@ -1,133 +0,0 @@ -/* GSM MS Testing Layer 3 messages - * 3GPP TS 44.014 / GSM TS 04.14 */ - -/* (C) 2017 by Harald Welte - * - * 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 . - * - */ - -#include -#include -#include - -#include "bscconfig.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static struct msgb *create_gsm0414_msg(uint8_t msg_type) -{ - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.14"); - struct gsm48_hdr *gh; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_TEST; - gh->msg_type = msg_type; - return msg; -} - -static int gsm0414_conn_sendmsg(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - return msc_tx_dtap(conn, msg); -} - -static int gsm0414_tx_simple(struct gsm_subscriber_connection *conn, uint8_t msg_type) -{ - struct msgb *msg = create_gsm0414_msg(msg_type); - - return gsm0414_conn_sendmsg(conn, msg); -} - - -/* Send a CLOSE_TCH_LOOOP_CMD according to Section 8.1 */ -int gsm0414_tx_close_tch_loop_cmd(struct gsm_subscriber_connection *conn, - enum gsm414_tch_loop_mode loop_mode) -{ - struct msgb *msg = create_gsm0414_msg(GSM414_MT_CLOSE_TCH_LOOP_CMD); - uint8_t subch; - - subch = (loop_mode << 1); - msgb_put_u8(msg, subch); - - msg->lchan = conn->lchan; - return gsm0414_conn_sendmsg(conn, msg); -} - -/* Send a OPEN_LOOP_CMD according to Section 8.3 */ -int gsm0414_tx_open_loop_cmd(struct gsm_subscriber_connection *conn) -{ - return gsm0414_tx_simple(conn, GSM414_MT_OPEN_LOOP_CMD); -} - -/* Send a ACT_EMMI_CMD according to Section 8.8 */ -int gsm0414_tx_act_emmi_cmd(struct gsm_subscriber_connection *conn) -{ - return gsm0414_tx_simple(conn, GSM414_MT_ACT_EMMI_CMD); -} - -/* Send a DEACT_EMMI_CMD according to Section 8.10 */ -int gsm0414_tx_deact_emmi_cmd(struct gsm_subscriber_connection *conn) -{ - return gsm0414_tx_simple(conn, GSM414_MT_DEACT_EMMI_CMD); -} - -/* Send a TEST_INTERFACE according to Section 8.11 */ -int gsm0414_tx_test_interface(struct gsm_subscriber_connection *conn, - uint8_t tested_devs) -{ - struct msgb *msg = create_gsm0414_msg(GSM414_MT_TEST_INTERFACE); - msgb_put_u8(msg, tested_devs); - return gsm0414_conn_sendmsg(conn, msg); -} - -/* Send a RESET_MS_POSITION_STORED according to Section 8.11 */ -int gsm0414_tx_reset_ms_pos_store(struct gsm_subscriber_connection *conn, - uint8_t technology) -{ - struct msgb *msg = create_gsm0414_msg(GSM414_MT_RESET_MS_POS_STORED); - msgb_put_u8(msg, technology); - return gsm0414_conn_sendmsg(conn, msg); -} - - - -/* Entry point for incoming GSM48_PDISC_TEST received from MS */ -int gsm0414_rcv_test(struct gsm_subscriber_connection *conn, - struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - - if (msgb_l3len(msg) < sizeof(*gh)) - return -1; - - LOGP(DMM, LOGL_NOTICE, "%s: Received TEST class message '%s'\n", "FIXME", - get_value_string(gsm414_msgt_names, gh->msg_type)); - - return 0; -} diff --git a/tools/hlrstat.pl b/tools/hlrstat.pl deleted file mode 100755 index 668fc9a4a..000000000 --- a/tools/hlrstat.pl +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/perl - -use strict; -use DBI; -my $dbh = DBI->connect("dbi:SQLite:dbname=hlr.sqlite3","",""); - - -my %mcc_names; -my %mcc_mnc_names; - -sub get_mcc_mnc_name($) -{ - my $mcc_mnc = shift; - my $ret = $mcc_mnc; - - if ($mcc_mnc_names{$mcc_mnc} ne '') { - $ret = $mcc_mnc_names{$mcc_mnc}; - } - - return $ret; -} - -sub read_networks($) -{ - my $filename = shift; - my $cur_name; - - open(INFILE, $filename); - while (my $l = ) { - chomp($l); - if ($l =~ /^#/) { - next; - } - if ($l =~ /^\t/) { - my ($mcc, $mnc, $brand, $r) = split(' ', $l, 4); - #printf("%s|%s|%s\n", $mcc, $mnc, $brand); - $mcc_mnc_names{"$mcc-$mnc"} = $brand; - $mcc_names{$mcc} = $cur_name; - } elsif ($l =~ /^(\w\w)\t(.*)/) { - #printf("%s|%s\n", $1, $2); - $cur_name = $2; - } - } - close(INFILE); -} - -read_networks("networks.tab"); - -my %oper_count; -my %country_count; - -#my $sth = $dbh->prepare("SELECT imsi FROM subscriber where authorized=1"); -my $sth = $dbh->prepare("SELECT imsi FROM subscriber"); - -$sth->execute(); - -while (my $href = $sth->fetchrow_hashref) { - my ($mcc, $mnc) = $$href{imsi} =~ /(\d{3})(\d{2}).*/; - #printf("%s %s-%s \n", $$href{imsi}, $mcc, $mnc); - $oper_count{"$mcc-$mnc"}++; - $country_count{$mcc}++; -} - - -foreach my $c (sort{$country_count{$b} <=> $country_count{$a}} keys %country_count) { - printf("%s: %d\n", $mcc_names{$c}, $country_count{$c}); - - foreach my $k (sort{$oper_count{$b} <=> $oper_count{$a}} keys %oper_count) { - if ($k =~ /^$c-/) { - printf("\t%s: %d\n", get_mcc_mnc_name($k), $oper_count{$k}); - } - } -}