mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-03 21:43:32 +00:00 
			
		
		
		
	Compare commits
	
		
			100 Commits
		
	
	
		
			openbsc/0.
			...
			on-waves/0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2727909dba | ||
| 
						 | 
					ad9856ec15 | ||
| 
						 | 
					9d53a8ad2a | ||
| 
						 | 
					058956e8ee | ||
| 
						 | 
					a34bb9167f | ||
| 
						 | 
					b8ac7ffd7c | ||
| 
						 | 
					b13cf829da | ||
| 
						 | 
					fdc64f6806 | ||
| 
						 | 
					ab46372e2a | ||
| 
						 | 
					ff0a562f9a | ||
| 
						 | 
					556008d724 | ||
| 
						 | 
					0094f84f30 | ||
| 
						 | 
					86069143ff | ||
| 
						 | 
					44f0be88a3 | ||
| 
						 | 
					5d88b372d7 | ||
| 
						 | 
					71c7bf5907 | ||
| 
						 | 
					869033148c | ||
| 
						 | 
					bc0f7c0988 | ||
| 
						 | 
					7d06063cfb | ||
| 
						 | 
					4e42b637fd | ||
| 
						 | 
					f44de9942b | ||
| 
						 | 
					3a110ae60b | ||
| 
						 | 
					bb84adc465 | ||
| 
						 | 
					8d123ea3c0 | ||
| 
						 | 
					88ca894df7 | ||
| 
						 | 
					42b0d6b494 | ||
| 
						 | 
					82d8b0457b | ||
| 
						 | 
					433d6ee1a2 | ||
| 
						 | 
					203a6eddf8 | ||
| 
						 | 
					56ef6249e3 | ||
| 
						 | 
					b2a96b1be7 | ||
| 
						 | 
					d4c29c1574 | ||
| 
						 | 
					3d947e6d67 | ||
| 
						 | 
					b62c9a19cf | ||
| 
						 | 
					ff5957568f | ||
| 
						 | 
					7d2e1ca4be | ||
| 
						 | 
					7ce2e0c8b0 | ||
| 
						 | 
					78d442420b | ||
| 
						 | 
					8cd2709ebf | ||
| 
						 | 
					41a1780102 | ||
| 
						 | 
					2f84715984 | ||
| 
						 | 
					7253154fc5 | ||
| 
						 | 
					6c1c76683f | ||
| 
						 | 
					a92fe9a4ca | ||
| 
						 | 
					e83a3f584e | ||
| 
						 | 
					118ddebc36 | ||
| 
						 | 
					bb53004d47 | ||
| 
						 | 
					6af20842cb | ||
| 
						 | 
					cc41cb07e7 | ||
| 
						 | 
					d6fb23523a | ||
| 
						 | 
					2aa0b45cc0 | ||
| 
						 | 
					619df61ad2 | ||
| 
						 | 
					893ea65f38 | ||
| 
						 | 
					64b811f113 | ||
| 
						 | 
					91fc9bf862 | ||
| 
						 | 
					111a58dd37 | ||
| 
						 | 
					d1a2563a74 | ||
| 
						 | 
					7d3ef919ce | ||
| 
						 | 
					cba98d87d6 | ||
| 
						 | 
					5c18ad0829 | ||
| 
						 | 
					0d9ed87d5c | ||
| 
						 | 
					ec7be0c969 | ||
| 
						 | 
					9be3347601 | ||
| 
						 | 
					3eef7b7d81 | ||
| 
						 | 
					9de4a6daa9 | ||
| 
						 | 
					851ace9f33 | ||
| 
						 | 
					d1dd069b48 | ||
| 
						 | 
					401db32ca2 | ||
| 
						 | 
					17e03d21d2 | ||
| 
						 | 
					26a9bff201 | ||
| 
						 | 
					80fb260a60 | ||
| 
						 | 
					55a0716da7 | ||
| 
						 | 
					c88fb75616 | ||
| 
						 | 
					d55a4dc326 | ||
| 
						 | 
					a4e6f2e6e1 | ||
| 
						 | 
					7f71d99cc3 | ||
| 
						 | 
					b92167cf80 | ||
| 
						 | 
					4b6a6dbe7e | ||
| 
						 | 
					763e8c7766 | ||
| 
						 | 
					823ff16088 | ||
| 
						 | 
					6f93c6a1e0 | ||
| 
						 | 
					f97e48b0de | ||
| 
						 | 
					761600b0fd | ||
| 
						 | 
					8549462bc6 | ||
| 
						 | 
					436e5c6308 | ||
| 
						 | 
					f8b9d844c1 | ||
| 
						 | 
					58ec07d580 | ||
| 
						 | 
					71465c21f4 | ||
| 
						 | 
					16d0a833f8 | ||
| 
						 | 
					ea72b62cac | ||
| 
						 | 
					49a84ec6e9 | ||
| 
						 | 
					42c636b6c8 | ||
| 
						 | 
					a0a55f555e | ||
| 
						 | 
					23ed00e410 | ||
| 
						 | 
					3fe910b9f1 | ||
| 
						 | 
					097bdeb77d | ||
| 
						 | 
					1b85de02e0 | ||
| 
						 | 
					2281d1835f | ||
| 
						 | 
					fb4433a129 | ||
| 
						 | 
					d954dcf9e1 | 
							
								
								
									
										12
									
								
								openbsc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								openbsc/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -3,12 +3,8 @@
 | 
				
			|||||||
.deps
 | 
					.deps
 | 
				
			||||||
Makefile
 | 
					Makefile
 | 
				
			||||||
Makefile.in
 | 
					Makefile.in
 | 
				
			||||||
bscconfig.h
 | 
					 | 
				
			||||||
bscconfig.h.in
 | 
					 | 
				
			||||||
openbsc.pc
 | 
					 | 
				
			||||||
bsc_hack
 | 
					bsc_hack
 | 
				
			||||||
bsc_msc_ip
 | 
					bsc_msc_ip
 | 
				
			||||||
bsc_mgcp
 | 
					 | 
				
			||||||
*.*~
 | 
					*.*~
 | 
				
			||||||
*.sw?
 | 
					*.sw?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,9 +19,6 @@ install-sh
 | 
				
			|||||||
missing
 | 
					missing
 | 
				
			||||||
stamp-h1
 | 
					stamp-h1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# git-version-gen magic
 | 
					 | 
				
			||||||
.tarball-version
 | 
					 | 
				
			||||||
.version
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# apps and app data
 | 
					# apps and app data
 | 
				
			||||||
@@ -33,12 +26,7 @@ hlr.sqlite3
 | 
				
			|||||||
bs11_config
 | 
					bs11_config
 | 
				
			||||||
ipaccess-config
 | 
					ipaccess-config
 | 
				
			||||||
ipaccess-find
 | 
					ipaccess-find
 | 
				
			||||||
ipaccess-firmware
 | 
					 | 
				
			||||||
ipaccess-proxy
 | 
					 | 
				
			||||||
isdnsync
 | 
					isdnsync
 | 
				
			||||||
bsc_nat
 | 
					 | 
				
			||||||
osmo-sgsn
 | 
					 | 
				
			||||||
osmo-gbproxy
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#tests
 | 
					#tests
 | 
				
			||||||
tests/channel/channel_test
 | 
					tests/channel/channel_test
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,5 +3,3 @@ Holger Freyther <zecke@selfish.org>
 | 
				
			|||||||
Jan Luebbe <jluebbe@debian.org>
 | 
					Jan Luebbe <jluebbe@debian.org>
 | 
				
			||||||
Stefan Schmidt <stefan@datenfreihafen.org>
 | 
					Stefan Schmidt <stefan@datenfreihafen.org>
 | 
				
			||||||
Daniel Willmann <daniel@totalueberwachung.de>
 | 
					Daniel Willmann <daniel@totalueberwachung.de>
 | 
				
			||||||
Andreas Eversberg <Andreas.Eversberg@versatel.de>
 | 
					 | 
				
			||||||
Sylvain Munaut <246tnt@gmail.com>
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,5 @@ SUBDIRS = include src tests
 | 
				
			|||||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
					pkgconfigdir = $(libdir)/pkgconfig
 | 
				
			||||||
pkgconfig_DATA = openbsc.pc
 | 
					pkgconfig_DATA = openbsc.pc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BUILT_SOURCES = $(top_srcdir)/.version
 | 
					#dist-hook:
 | 
				
			||||||
$(top_srcdir)/.version:
 | 
					#	rm -rf `find $(distdir) -name .svn`
 | 
				
			||||||
	echo $(VERSION) > $@-t && mv $@-t $@
 | 
					 | 
				
			||||||
dist-hook:
 | 
					 | 
				
			||||||
	echo $(VERSION) > $(distdir)/.tarball-version
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,32 +1,18 @@
 | 
				
			|||||||
About OpenBSC
 | 
					About OpenBSC
 | 
				
			||||||
=============
 | 
					=============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OpenBSC is a minimalistic implementation of the GSM Network, with
 | 
					OpenBSC is a minimalistic implementation of the GSM Network, with particular
 | 
				
			||||||
particular emphasis on the functionality typically provided by the BSC,
 | 
					emphasis on the functionality typically provided by the BSC, MSC, HLR, VLR.
 | 
				
			||||||
MSC, HLR, VLR and SMSC.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Its currently supported interfaces towards the BTS are:
 | 
					Its only current interface is a mISDN based E1 interface utilizing the A-bis
 | 
				
			||||||
 | 
					protocol between BSC and BTS.  In other words, you can connect an existing
 | 
				
			||||||
 | 
					GSM Base Transceiver Station (BTS) through E1 to OpenBSC.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 * Classic A-bis over E1 using a mISDN based E1 interface. In other
 | 
					So far, it has only been tested with the Siemens microBTS BS-11.  Test reports
 | 
				
			||||||
   words, you can connect existing GSM Base Transceiver Station (BTS)
 | 
					with other BTS are appreciated!
 | 
				
			||||||
   through E1 to OpenBSC.  So far, we have only tested the Siemens BS-11
 | 
					 | 
				
			||||||
   Test reports with other BTS are much appreciated!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * A-bis over IP as used by the ip.access nanoBTS product family
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You can find the project documentation at http://openbsc.gnumonks.org/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
This project is still in its early days, and there are lots of areas where it
 | 
					This project is still in its early days, and there are lots of areas where it
 | 
				
			||||||
doesn't behave as per GSM spec.
 | 
					doesn't behave as per GSM spec.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					December 29, 2008
 | 
				
			||||||
	Harald Welte <laforge@gnumonks.org>
 | 
						Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
libosmocore
 | 
					 | 
				
			||||||
===========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Please note that as of March 2010, OpenBSC has a dependency to a library
 | 
					 | 
				
			||||||
called "libosmocore".  You can obtain that library from
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	git://git.osmocom.org/libosmocore.git
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,7 @@
 | 
				
			|||||||
dnl Process this file with autoconf to produce a configure script
 | 
					dnl Process this file with autoconf to produce a configure script
 | 
				
			||||||
AC_INIT([openbsc],
 | 
					AC_INIT
 | 
				
			||||||
	m4_esyscmd([./git-version-gen .tarball-version]),
 | 
					 | 
				
			||||||
	[openbsc-devel@lists.openbsc.org])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
AM_INIT_AUTOMAKE([dist-bzip2])
 | 
					AM_INIT_AUTOMAKE(openbsc, 0.3.4onwaves)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dnl kernel style compile messages
 | 
					dnl kernel style compile messages
 | 
				
			||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
					m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
				
			||||||
@@ -17,34 +15,6 @@ AC_PROG_RANLIB
 | 
				
			|||||||
dnl checks for libraries
 | 
					dnl checks for libraries
 | 
				
			||||||
AC_SEARCH_LIBS(crypt, crypt,
 | 
					AC_SEARCH_LIBS(crypt, crypt,
 | 
				
			||||||
    [LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
 | 
					    [LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
 | 
				
			||||||
AC_SEARCH_LIBS(gtp_new, gtp,
 | 
					 | 
				
			||||||
    [LIBCRYPT="-lgtp"; AC_SUBST([GPRS_LIBGTP], [1])])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AM_CONDITIONAL(HAVE_LIBGTP, test "x$GPRS_LIBGTP" != "x")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AC_ARG_ENABLE([nat], [AS_HELP_STRING([--enable-nat], [Build the BSC NAT. Requires SCCP])],
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.2)
 | 
					 | 
				
			||||||
        osmo_ac_build_nat="yes"
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        osmo_ac_build_nat="no"
 | 
					 | 
				
			||||||
    ])
 | 
					 | 
				
			||||||
AM_CONDITIONAL(BUILD_NAT, test "x$osmo_ac_build_nat" = "xyes")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AC_ARG_ENABLE([osmo-bsc], [AS_HELP_STRING([--enable-osmo-bsc], [Build the Osmo BSC])],
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.2)
 | 
					 | 
				
			||||||
        osmo_ac_build_bsc="yes"
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    [
 | 
					 | 
				
			||||||
        osmo_ac_build_bsc="no"
 | 
					 | 
				
			||||||
    ])
 | 
					 | 
				
			||||||
AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.15)
 | 
					 | 
				
			||||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.1.9)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
dnl checks for header files
 | 
					dnl checks for header files
 | 
				
			||||||
AC_HEADER_STDC
 | 
					AC_HEADER_STDC
 | 
				
			||||||
@@ -69,16 +39,16 @@ AM_CONFIG_HEADER(bscconfig.h)
 | 
				
			|||||||
AC_OUTPUT(
 | 
					AC_OUTPUT(
 | 
				
			||||||
    openbsc.pc
 | 
					    openbsc.pc
 | 
				
			||||||
    include/openbsc/Makefile
 | 
					    include/openbsc/Makefile
 | 
				
			||||||
 | 
					    include/vty/Makefile
 | 
				
			||||||
 | 
					    include/sccp/Makefile
 | 
				
			||||||
    include/Makefile
 | 
					    include/Makefile
 | 
				
			||||||
    src/Makefile
 | 
					    src/Makefile
 | 
				
			||||||
    src/ipaccess/Makefile
 | 
					 | 
				
			||||||
    src/gprs/Makefile
 | 
					 | 
				
			||||||
    src/nat/Makefile
 | 
					 | 
				
			||||||
    src/bsc/Makefile
 | 
					 | 
				
			||||||
    tests/Makefile
 | 
					    tests/Makefile
 | 
				
			||||||
    tests/debug/Makefile
 | 
					    tests/debug/Makefile
 | 
				
			||||||
 | 
					    tests/timer/Makefile
 | 
				
			||||||
 | 
					    tests/sms/Makefile
 | 
				
			||||||
    tests/gsm0408/Makefile
 | 
					    tests/gsm0408/Makefile
 | 
				
			||||||
    tests/db/Makefile
 | 
					    tests/db/Makefile
 | 
				
			||||||
    tests/channel/Makefile
 | 
					    tests/channel/Makefile
 | 
				
			||||||
    tests/bsc-nat/Makefile
 | 
					    tests/sccp/Makefile
 | 
				
			||||||
    Makefile)
 | 
					    Makefile)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								openbsc/contrib/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								openbsc/contrib/README
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					This contains a set of scripts used for the development of the
 | 
				
			||||||
 | 
					MSC functionality.
 | 
				
			||||||
@@ -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"
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -10,7 +10,7 @@ rsip_resp = """200 321321332\r\n"""
 | 
				
			|||||||
audit_packet = """AUEP %d 13@mgw MGCP 1.0\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"""
 | 
					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"""
 | 
					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"""
 | 
					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 4400 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):
 | 
					def hexdump(src, length=8):
 | 
				
			||||||
    """Recipe is from http://code.activestate.com/recipes/142812/"""
 | 
					    """Recipe is from http://code.activestate.com/recipes/142812/"""
 | 
				
			||||||
@@ -25,24 +25,15 @@ def hexdump(src, length=8):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 | 
					server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 | 
				
			||||||
server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT))
 | 
					server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT))
 | 
				
			||||||
server_socket.setblocking(1)
 | 
					server_socket.setblocking(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
last_ci = 1
 | 
					
 | 
				
			||||||
def send_and_receive(packet):
 | 
					def send_receive(packet):
 | 
				
			||||||
    global last_ci
 | 
					 | 
				
			||||||
    server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT))
 | 
					    server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT))
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        data, addr = server_socket.recvfrom(4096)
 | 
					        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
 | 
					        print hexdump(data), addr
 | 
				
			||||||
    except socket.error, e:
 | 
					    except socket.error:
 | 
				
			||||||
        print e
 | 
					 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def generate_tid():
 | 
					def generate_tid():
 | 
				
			||||||
@@ -51,10 +42,13 @@ def generate_tid():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i = 1
 | 
				
			||||||
while True:
 | 
					while True:
 | 
				
			||||||
    send_and_receive(audit_packet % generate_tid())
 | 
					    send_receive(rsip_resp)
 | 
				
			||||||
    send_and_receive(crcx_packet % generate_tid() )
 | 
					    send_receive(audit_packet)
 | 
				
			||||||
    send_and_receive(mdcx_packet % (generate_tid(), last_ci))
 | 
					    send_receive(crcx_packet % generate_tid() )
 | 
				
			||||||
    send_and_receive(dlcx_packet % (generate_tid(), last_ci))
 | 
					    send_receive(mdcx_packet % (generate_tid(), i))
 | 
				
			||||||
 | 
					    send_receive(dlcx_packet % (generate_tid(), i))
 | 
				
			||||||
 | 
					    i = i + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    time.sleep(3)
 | 
					    time.sleep(3)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								openbsc/contrib/send_handshake.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								openbsc/contrib/send_handshake.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# packages
 | 
				
			||||||
 | 
					ACK ="\x00\x01\xfe\x06"
 | 
				
			||||||
 | 
					RESET_ACK = "\x00\x13\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x03\x00\x01\x31"
 | 
				
			||||||
 | 
					PAGE = "\x00\x20\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x10\x00\x0e\x52\x08\x08\x29\x42\x08\x05\x03\x12\x23\x42\x1a\x01\x06"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# simple handshake...
 | 
				
			||||||
 | 
					sys.stdout.write(ACK)
 | 
				
			||||||
 | 
					sys.stdout.flush()
 | 
				
			||||||
 | 
					sys.stdin.read(4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# wait for some data and send reset ack
 | 
				
			||||||
 | 
					sys.stdin.read(21)
 | 
				
			||||||
 | 
					sys.stdout.write(RESET_ACK)
 | 
				
			||||||
 | 
					sys.stdout.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sys.stdout.write(RESET_ACK)
 | 
				
			||||||
 | 
					sys.stdout.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# page a subscriber
 | 
				
			||||||
 | 
					sys.stdout.write(PAGE)
 | 
				
			||||||
 | 
					sys.stdout.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					while True:
 | 
				
			||||||
 | 
					    sys.stdin.read(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -31,8 +31,6 @@ GSM 04.08 3.4.13: RR connection release procedure
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
== Implementation in OpenBSC ==
 | 
					== Implementation in OpenBSC ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
THIS IS OUTDATED and will be updated...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
chan_alloc.c:lchan_auto_release()
 | 
					chan_alloc.c:lchan_auto_release()
 | 
				
			||||||
	* checks if use count still > 0 (abort)
 | 
						* checks if use count still > 0 (abort)
 | 
				
			||||||
	* calls gsm48_send_rr_release()
 | 
						* calls gsm48_send_rr_release()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,151 +0,0 @@
 | 
				
			|||||||
#!/bin/sh
 | 
					 | 
				
			||||||
# Print a version string.
 | 
					 | 
				
			||||||
scriptversion=2010-01-28.01
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Copyright (C) 2007-2010 Free Software Foundation, Inc.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# 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, see <http://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
 | 
					 | 
				
			||||||
# It may be run two ways:
 | 
					 | 
				
			||||||
# - from a git repository in which the "git describe" command below
 | 
					 | 
				
			||||||
#   produces useful output (thus requiring at least one signed tag)
 | 
					 | 
				
			||||||
# - from a non-git-repo directory containing a .tarball-version file, which
 | 
					 | 
				
			||||||
#   presumes this script is invoked like "./git-version-gen .tarball-version".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# In order to use intra-version strings in your project, you will need two
 | 
					 | 
				
			||||||
# separate generated version string files:
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# .tarball-version - present only in a distribution tarball, and not in
 | 
					 | 
				
			||||||
#   a checked-out repository.  Created with contents that were learned at
 | 
					 | 
				
			||||||
#   the last time autoconf was run, and used by git-version-gen.  Must not
 | 
					 | 
				
			||||||
#   be present in either $(srcdir) or $(builddir) for git-version-gen to
 | 
					 | 
				
			||||||
#   give accurate answers during normal development with a checked out tree,
 | 
					 | 
				
			||||||
#   but must be present in a tarball when there is no version control system.
 | 
					 | 
				
			||||||
#   Therefore, it cannot be used in any dependencies.  GNUmakefile has
 | 
					 | 
				
			||||||
#   hooks to force a reconfigure at distribution time to get the value
 | 
					 | 
				
			||||||
#   correct, without penalizing normal development with extra reconfigures.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# .version - present in a checked-out repository and in a distribution
 | 
					 | 
				
			||||||
#   tarball.  Usable in dependencies, particularly for files that don't
 | 
					 | 
				
			||||||
#   want to depend on config.h but do want to track version changes.
 | 
					 | 
				
			||||||
#   Delete this file prior to any autoconf run where you want to rebuild
 | 
					 | 
				
			||||||
#   files to pick up a version string change; and leave it stale to
 | 
					 | 
				
			||||||
#   minimize rebuild time after unrelated changes to configure sources.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# It is probably wise to add these two files to .gitignore, so that you
 | 
					 | 
				
			||||||
# don't accidentally commit either generated file.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Use the following line in your configure.ac, so that $(VERSION) will
 | 
					 | 
				
			||||||
# automatically be up-to-date each time configure is run (and note that
 | 
					 | 
				
			||||||
# since configure.ac no longer includes a version string, Makefile rules
 | 
					 | 
				
			||||||
# should not depend on configure.ac for version updates).
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# AC_INIT([GNU project],
 | 
					 | 
				
			||||||
#         m4_esyscmd([build-aux/git-version-gen .tarball-version]),
 | 
					 | 
				
			||||||
#         [bug-project@example])
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Then use the following lines in your Makefile.am, so that .version
 | 
					 | 
				
			||||||
# will be present for dependencies, and so that .tarball-version will
 | 
					 | 
				
			||||||
# exist in distribution tarballs.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# BUILT_SOURCES = $(top_srcdir)/.version
 | 
					 | 
				
			||||||
# $(top_srcdir)/.version:
 | 
					 | 
				
			||||||
#	echo $(VERSION) > $@-t && mv $@-t $@
 | 
					 | 
				
			||||||
# dist-hook:
 | 
					 | 
				
			||||||
#	echo $(VERSION) > $(distdir)/.tarball-version
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
case $# in
 | 
					 | 
				
			||||||
    1) ;;
 | 
					 | 
				
			||||||
    *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
 | 
					 | 
				
			||||||
esac
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
tarball_version_file=$1
 | 
					 | 
				
			||||||
nl='
 | 
					 | 
				
			||||||
'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# First see if there is a tarball-only version file.
 | 
					 | 
				
			||||||
# then try "git describe", then default.
 | 
					 | 
				
			||||||
if test -f $tarball_version_file
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
    v=`cat $tarball_version_file` || exit 1
 | 
					 | 
				
			||||||
    case $v in
 | 
					 | 
				
			||||||
	*$nl*) v= ;; # reject multi-line output
 | 
					 | 
				
			||||||
	[0-9]*) ;;
 | 
					 | 
				
			||||||
	*) v= ;;
 | 
					 | 
				
			||||||
    esac
 | 
					 | 
				
			||||||
    test -z "$v" \
 | 
					 | 
				
			||||||
	&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if test -n "$v"
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
    : # use $v
 | 
					 | 
				
			||||||
elif test -d ./../.git \
 | 
					 | 
				
			||||||
    && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
 | 
					 | 
				
			||||||
	  || git describe --abbrev=4 HEAD 2>/dev/null` \
 | 
					 | 
				
			||||||
    && case $v in
 | 
					 | 
				
			||||||
	 [0-9]*) ;;
 | 
					 | 
				
			||||||
	 v[0-9]*) ;;
 | 
					 | 
				
			||||||
	 *) (exit 1) ;;
 | 
					 | 
				
			||||||
       esac
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
    # Is this a new git that lists number of commits since the last
 | 
					 | 
				
			||||||
    # tag or the previous older version that did not?
 | 
					 | 
				
			||||||
    #   Newer: v6.10-77-g0f8faeb
 | 
					 | 
				
			||||||
    #   Older: v6.10-g0f8faeb
 | 
					 | 
				
			||||||
    case $v in
 | 
					 | 
				
			||||||
	*-*-*) : git describe is okay three part flavor ;;
 | 
					 | 
				
			||||||
	*-*)
 | 
					 | 
				
			||||||
	    : git describe is older two part flavor
 | 
					 | 
				
			||||||
	    # Recreate the number of commits and rewrite such that the
 | 
					 | 
				
			||||||
	    # result is the same as if we were using the newer version
 | 
					 | 
				
			||||||
	    # of git describe.
 | 
					 | 
				
			||||||
	    vtag=`echo "$v" | sed 's/-.*//'`
 | 
					 | 
				
			||||||
	    numcommits=`git rev-list "$vtag"..HEAD | wc -l`
 | 
					 | 
				
			||||||
	    v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
 | 
					 | 
				
			||||||
	    ;;
 | 
					 | 
				
			||||||
    esac
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Change the first '-' to a '.', so version-comparing tools work properly.
 | 
					 | 
				
			||||||
    # Remove the "g" in git describe's output string, to save a byte.
 | 
					 | 
				
			||||||
    v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
    v=UNKNOWN
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
v=`echo "$v" |sed 's/^v//'`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Don't declare a version "dirty" merely because a time stamp has changed.
 | 
					 | 
				
			||||||
git status > /dev/null 2>&1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
 | 
					 | 
				
			||||||
case "$dirty" in
 | 
					 | 
				
			||||||
    '') ;;
 | 
					 | 
				
			||||||
    *) # Append the suffix only if there isn't one already.
 | 
					 | 
				
			||||||
	case $v in
 | 
					 | 
				
			||||||
	  *-dirty) ;;
 | 
					 | 
				
			||||||
	  *) v="$v-dirty" ;;
 | 
					 | 
				
			||||||
	esac ;;
 | 
					 | 
				
			||||||
esac
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
 | 
					 | 
				
			||||||
echo "$v" | tr -d '\012'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Local variables:
 | 
					 | 
				
			||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
 | 
					 | 
				
			||||||
# time-stamp-start: "scriptversion="
 | 
					 | 
				
			||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
 | 
					 | 
				
			||||||
# time-stamp-end: "$"
 | 
					 | 
				
			||||||
# End:
 | 
					 | 
				
			||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
SUBDIRS = openbsc
 | 
					SUBDIRS = openbsc vty sccp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
noinst_HEADERS = mISDNif.h compat_af_isdn.h
 | 
					noinst_HEADERS = mISDNif.h compat_af_isdn.h
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,8 @@
 | 
				
			|||||||
noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
 | 
					noinst_HEADERS = abis_nm.h abis_rsl.h debug.h db.h gsm_04_08.h gsm_data.h \
 | 
				
			||||||
		 gsm_subscriber.h gsm_04_11.h debug.h signal.h \
 | 
							 gsm_subscriber.h linuxlist.h msgb.h select.h tlv.h gsm_04_11.h \
 | 
				
			||||||
		 misdn.h chan_alloc.h paging.h \
 | 
							 timer.h misdn.h chan_alloc.h telnet_interface.h paging.h \
 | 
				
			||||||
		 subchan_demux.h trau_frame.h e1_input.h trau_mux.h \
 | 
							 subchan_demux.h trau_frame.h e1_input.h trau_mux.h signal.h \
 | 
				
			||||||
		 ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
 | 
							 gsm_utils.h ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
 | 
				
			||||||
		 bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \
 | 
							 bsc_rll.h mncc.h talloc.h transaction.h ussd.h gsm_04_80.h \
 | 
				
			||||||
		 silent_call.h mgcp.h meas_rep.h rest_octets.h \
 | 
							 silent_call.h mgcp.h meas_rep.h bitvec.h rest_octets.h \
 | 
				
			||||||
		 system_information.h handover.h mgcp_internal.h \
 | 
							 system_information.h handover.h bssap.h bsc_msc.h bsc_nat.h
 | 
				
			||||||
		 vty.h socket.h \
 | 
					 | 
				
			||||||
		crc24.h gprs_bssgp.h gprs_llc.h gprs_ns.h gprs_gmm.h \
 | 
					 | 
				
			||||||
		gb_proxy.h gprs_sgsn.h gsm_04_08_gprs.h sgsn.h \
 | 
					 | 
				
			||||||
		gprs_ns_frgre.h auth.h osmo_msc.h bsc_msc.h bsc_nat.h \
 | 
					 | 
				
			||||||
		osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
 | 
					 | 
				
			||||||
openbscdir = $(includedir)/openbsc
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,8 +24,665 @@
 | 
				
			|||||||
#define _NM_H
 | 
					#define _NM_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <osmocore/tlv.h>
 | 
					
 | 
				
			||||||
#include <osmocore/protocol/gsm_12_21.h>
 | 
					#include <openbsc/tlv.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* PRIVATE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* generic header in front of every OML message according to TS 08.59 */
 | 
				
			||||||
 | 
					struct abis_om_hdr {
 | 
				
			||||||
 | 
						u_int8_t	mdisc;
 | 
				
			||||||
 | 
						u_int8_t	placement;
 | 
				
			||||||
 | 
						u_int8_t	sequence;
 | 
				
			||||||
 | 
						u_int8_t	length;
 | 
				
			||||||
 | 
						u_int8_t	data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ABIS_OM_MDISC_FOM		0x80
 | 
				
			||||||
 | 
					#define ABIS_OM_MDISC_MMI		0x40
 | 
				
			||||||
 | 
					#define ABIS_OM_MDISC_TRAU		0x20
 | 
				
			||||||
 | 
					#define ABIS_OM_MDISC_MANUF		0x10
 | 
				
			||||||
 | 
					#define ABIS_OM_PLACEMENT_ONLY		0x80
 | 
				
			||||||
 | 
					#define ABIS_OM_PLACEMENT_FIRST 	0x40
 | 
				
			||||||
 | 
					#define ABIS_OM_PLACEMENT_MIDDLE	0x20
 | 
				
			||||||
 | 
					#define ABIS_OM_PLACEMENT_LAST		0x10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct abis_om_obj_inst {
 | 
				
			||||||
 | 
						u_int8_t	bts_nr;
 | 
				
			||||||
 | 
						u_int8_t	trx_nr;
 | 
				
			||||||
 | 
						u_int8_t	ts_nr;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct abis_om_fom_hdr {
 | 
				
			||||||
 | 
						u_int8_t	msg_type;
 | 
				
			||||||
 | 
						u_int8_t	obj_class;
 | 
				
			||||||
 | 
						struct abis_om_obj_inst	obj_inst;
 | 
				
			||||||
 | 
						u_int8_t	data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ABIS_OM_FOM_HDR_SIZE	(sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1: Message Types */
 | 
				
			||||||
 | 
					enum abis_nm_msgtype {
 | 
				
			||||||
 | 
						/* SW Download Management Messages */
 | 
				
			||||||
 | 
						NM_MT_LOAD_INIT			= 0x01,
 | 
				
			||||||
 | 
						NM_MT_LOAD_INIT_ACK,
 | 
				
			||||||
 | 
						NM_MT_LOAD_INIT_NACK,
 | 
				
			||||||
 | 
						NM_MT_LOAD_SEG,
 | 
				
			||||||
 | 
						NM_MT_LOAD_SEG_ACK,
 | 
				
			||||||
 | 
						NM_MT_LOAD_ABORT,
 | 
				
			||||||
 | 
						NM_MT_LOAD_END,
 | 
				
			||||||
 | 
						NM_MT_LOAD_END_ACK,
 | 
				
			||||||
 | 
						NM_MT_LOAD_END_NACK,
 | 
				
			||||||
 | 
						NM_MT_SW_ACT_REQ,		/* BTS->BSC */
 | 
				
			||||||
 | 
						NM_MT_SW_ACT_REQ_ACK,
 | 
				
			||||||
 | 
						NM_MT_SW_ACT_REQ_NACK,
 | 
				
			||||||
 | 
						NM_MT_ACTIVATE_SW,		/* BSC->BTS */
 | 
				
			||||||
 | 
						NM_MT_ACTIVATE_SW_ACK,
 | 
				
			||||||
 | 
						NM_MT_ACTIVATE_SW_NACK,
 | 
				
			||||||
 | 
						NM_MT_SW_ACTIVATED_REP,		/* 0x10 */
 | 
				
			||||||
 | 
						/* A-bis Interface Management Messages */
 | 
				
			||||||
 | 
						NM_MT_ESTABLISH_TEI		= 0x21,
 | 
				
			||||||
 | 
						NM_MT_ESTABLISH_TEI_ACK,
 | 
				
			||||||
 | 
						NM_MT_ESTABLISH_TEI_NACK,
 | 
				
			||||||
 | 
						NM_MT_CONN_TERR_SIGN,
 | 
				
			||||||
 | 
						NM_MT_CONN_TERR_SIGN_ACK,
 | 
				
			||||||
 | 
						NM_MT_CONN_TERR_SIGN_NACK,
 | 
				
			||||||
 | 
						NM_MT_DISC_TERR_SIGN,
 | 
				
			||||||
 | 
						NM_MT_DISC_TERR_SIGN_ACK,
 | 
				
			||||||
 | 
						NM_MT_DISC_TERR_SIGN_NACK,
 | 
				
			||||||
 | 
						NM_MT_CONN_TERR_TRAF,
 | 
				
			||||||
 | 
						NM_MT_CONN_TERR_TRAF_ACK,
 | 
				
			||||||
 | 
						NM_MT_CONN_TERR_TRAF_NACK,
 | 
				
			||||||
 | 
						NM_MT_DISC_TERR_TRAF,
 | 
				
			||||||
 | 
						NM_MT_DISC_TERR_TRAF_ACK,
 | 
				
			||||||
 | 
						NM_MT_DISC_TERR_TRAF_NACK,
 | 
				
			||||||
 | 
						/* Transmission Management Messages */
 | 
				
			||||||
 | 
						NM_MT_CONN_MDROP_LINK		= 0x31,
 | 
				
			||||||
 | 
						NM_MT_CONN_MDROP_LINK_ACK,
 | 
				
			||||||
 | 
						NM_MT_CONN_MDROP_LINK_NACK,
 | 
				
			||||||
 | 
						NM_MT_DISC_MDROP_LINK,
 | 
				
			||||||
 | 
						NM_MT_DISC_MDROP_LINK_ACK,
 | 
				
			||||||
 | 
						NM_MT_DISC_MDROP_LINK_NACK,
 | 
				
			||||||
 | 
						/* Air Interface Management Messages */
 | 
				
			||||||
 | 
						NM_MT_SET_BTS_ATTR		= 0x41,
 | 
				
			||||||
 | 
						NM_MT_SET_BTS_ATTR_ACK,
 | 
				
			||||||
 | 
						NM_MT_SET_BTS_ATTR_NACK,
 | 
				
			||||||
 | 
						NM_MT_SET_RADIO_ATTR,
 | 
				
			||||||
 | 
						NM_MT_SET_RADIO_ATTR_ACK,
 | 
				
			||||||
 | 
						NM_MT_SET_RADIO_ATTR_NACK,
 | 
				
			||||||
 | 
						NM_MT_SET_CHAN_ATTR,
 | 
				
			||||||
 | 
						NM_MT_SET_CHAN_ATTR_ACK,
 | 
				
			||||||
 | 
						NM_MT_SET_CHAN_ATTR_NACK,
 | 
				
			||||||
 | 
						/* Test Management Messages */
 | 
				
			||||||
 | 
						NM_MT_PERF_TEST			= 0x51,
 | 
				
			||||||
 | 
						NM_MT_PERF_TEST_ACK,
 | 
				
			||||||
 | 
						NM_MT_PERF_TEST_NACK,
 | 
				
			||||||
 | 
						NM_MT_TEST_REP,
 | 
				
			||||||
 | 
						NM_MT_SEND_TEST_REP,
 | 
				
			||||||
 | 
						NM_MT_SEND_TEST_REP_ACK,
 | 
				
			||||||
 | 
						NM_MT_SEND_TEST_REP_NACK,
 | 
				
			||||||
 | 
						NM_MT_STOP_TEST,
 | 
				
			||||||
 | 
						NM_MT_STOP_TEST_ACK,
 | 
				
			||||||
 | 
						NM_MT_STOP_TEST_NACK,
 | 
				
			||||||
 | 
						/* State Management and Event Report Messages */
 | 
				
			||||||
 | 
						NM_MT_STATECHG_EVENT_REP	= 0x61,
 | 
				
			||||||
 | 
						NM_MT_FAILURE_EVENT_REP,
 | 
				
			||||||
 | 
						NM_MT_STOP_EVENT_REP,
 | 
				
			||||||
 | 
						NM_MT_STOP_EVENT_REP_ACK,
 | 
				
			||||||
 | 
						NM_MT_STOP_EVENT_REP_NACK,
 | 
				
			||||||
 | 
						NM_MT_REST_EVENT_REP,
 | 
				
			||||||
 | 
						NM_MT_REST_EVENT_REP_ACK,
 | 
				
			||||||
 | 
						NM_MT_REST_EVENT_REP_NACK,
 | 
				
			||||||
 | 
						NM_MT_CHG_ADM_STATE,
 | 
				
			||||||
 | 
						NM_MT_CHG_ADM_STATE_ACK,
 | 
				
			||||||
 | 
						NM_MT_CHG_ADM_STATE_NACK,
 | 
				
			||||||
 | 
						NM_MT_CHG_ADM_STATE_REQ,
 | 
				
			||||||
 | 
						NM_MT_CHG_ADM_STATE_REQ_ACK,
 | 
				
			||||||
 | 
						NM_MT_CHG_ADM_STATE_REQ_NACK,
 | 
				
			||||||
 | 
						NM_MT_REP_OUTST_ALARMS		= 0x93,
 | 
				
			||||||
 | 
						NM_MT_REP_OUTST_ALARMS_ACK,
 | 
				
			||||||
 | 
						NM_MT_REP_OUTST_ALARMS_NACK,
 | 
				
			||||||
 | 
						/* Equipment Management Messages */
 | 
				
			||||||
 | 
						NM_MT_CHANGEOVER		= 0x71,
 | 
				
			||||||
 | 
						NM_MT_CHANGEOVER_ACK,
 | 
				
			||||||
 | 
						NM_MT_CHANGEOVER_NACK,
 | 
				
			||||||
 | 
						NM_MT_OPSTART,
 | 
				
			||||||
 | 
						NM_MT_OPSTART_ACK,
 | 
				
			||||||
 | 
						NM_MT_OPSTART_NACK,
 | 
				
			||||||
 | 
						NM_MT_REINIT,
 | 
				
			||||||
 | 
						NM_MT_REINIT_ACK,
 | 
				
			||||||
 | 
						NM_MT_REINIT_NACK,
 | 
				
			||||||
 | 
						NM_MT_SET_SITE_OUT,		/* BS11: get alarm ?!? */
 | 
				
			||||||
 | 
						NM_MT_SET_SITE_OUT_ACK,
 | 
				
			||||||
 | 
						NM_MT_SET_SITE_OUT_NACK,
 | 
				
			||||||
 | 
						NM_MT_CHG_HW_CONF		= 0x90,
 | 
				
			||||||
 | 
						NM_MT_CHG_HW_CONF_ACK,
 | 
				
			||||||
 | 
						NM_MT_CHG_HW_CONF_NACK,
 | 
				
			||||||
 | 
						/* Measurement Management Messages */
 | 
				
			||||||
 | 
						NM_MT_MEAS_RES_REQ		= 0x8a,
 | 
				
			||||||
 | 
						NM_MT_MEAS_RES_RESP,
 | 
				
			||||||
 | 
						NM_MT_STOP_MEAS,
 | 
				
			||||||
 | 
						NM_MT_START_MEAS,
 | 
				
			||||||
 | 
						/* Other Messages */
 | 
				
			||||||
 | 
						NM_MT_GET_ATTR			= 0x81,
 | 
				
			||||||
 | 
						NM_MT_GET_ATTR_RESP,
 | 
				
			||||||
 | 
						NM_MT_GET_ATTR_NACK,
 | 
				
			||||||
 | 
						NM_MT_SET_ALARM_THRES,
 | 
				
			||||||
 | 
						NM_MT_SET_ALARM_THRES_ACK,
 | 
				
			||||||
 | 
						NM_MT_SET_ALARM_THRES_NACK,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum abis_nm_msgtype_bs11 {
 | 
				
			||||||
 | 
						NM_MT_BS11_RESET_RESOURCE	= 0x74,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_MT_BS11_BEGIN_DB_TX		= 0xa3,
 | 
				
			||||||
 | 
						NM_MT_BS11_BEGIN_DB_TX_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_BEGIN_DB_TX_NACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_END_DB_TX		= 0xa6,
 | 
				
			||||||
 | 
						NM_MT_BS11_END_DB_TX_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_END_DB_TX_NACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_CREATE_OBJ		= 0xa9,
 | 
				
			||||||
 | 
						NM_MT_BS11_CREATE_OBJ_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_CREATE_OBJ_NACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_DELETE_OBJ		= 0xac,
 | 
				
			||||||
 | 
						NM_MT_BS11_DELETE_OBJ_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_DELETE_OBJ_NACK,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_MT_BS11_SET_ATTR		= 0xd0,
 | 
				
			||||||
 | 
						NM_MT_BS11_SET_ATTR_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_SET_ATTR_NACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_LMT_SESSION		= 0xdc,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_MT_BS11_GET_STATE		= 0xe3,
 | 
				
			||||||
 | 
						NM_MT_BS11_GET_STATE_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_LMT_LOGON		= 0xe5,
 | 
				
			||||||
 | 
						NM_MT_BS11_LMT_LOGON_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_RESTART		= 0xe7,
 | 
				
			||||||
 | 
						NM_MT_BS11_RESTART_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_DISCONNECT		= 0xe9,
 | 
				
			||||||
 | 
						NM_MT_BS11_DISCONNECT_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_LMT_LOGOFF		= 0xec,
 | 
				
			||||||
 | 
						NM_MT_BS11_LMT_LOGOFF_ACK,
 | 
				
			||||||
 | 
						NM_MT_BS11_RECONNECT		= 0xf1,
 | 
				
			||||||
 | 
						NM_MT_BS11_RECONNECT_ACK,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum abis_nm_msgtype_ipacc {
 | 
				
			||||||
 | 
						NM_MT_IPACC_RESTART		= 0x87,
 | 
				
			||||||
 | 
						NM_MT_IPACC_RESTART_ACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_RSL_CONNECT		= 0xe0,
 | 
				
			||||||
 | 
						NM_MT_IPACC_RSL_CONNECT_ACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_RSL_CONNECT_NACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_RSL_DISCONNECT	= 0xe3,
 | 
				
			||||||
 | 
						NM_MT_IPACC_RSL_DISCONNECT_ACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_RSL_DISCONNECT_NACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_CONN_TRAF		= 0xe6,
 | 
				
			||||||
 | 
						NM_MT_IPACC_CONN_TRAF_ACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_CONN_TRAF_NACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_DEF_BOOT_SW		= 0xec,
 | 
				
			||||||
 | 
						NM_MT_IPACC_DEF_BOOT_SW_ACK,
 | 
				
			||||||
 | 
						MN_MT_IPACC_DEF_BOOT_SW_NACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_SET_NVATTR		= 0xef,
 | 
				
			||||||
 | 
						NM_MT_IPACC_SET_NVATTR_ACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_SET_NVATTR_NACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_GET_NVATTR		= 0xf2,
 | 
				
			||||||
 | 
						NM_MT_IPACC_GET_NVATTR_ACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_GET_NVATTR_NACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_SET_ATTR		= 0xf5,
 | 
				
			||||||
 | 
						NM_MT_IPACC_SET_ATTR_ACK,
 | 
				
			||||||
 | 
						NM_MT_IPACC_SET_ATTR_NACK,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum abis_nm_bs11_cell_alloc {
 | 
				
			||||||
 | 
						NM_BS11_CANR_GSM	= 0x00,
 | 
				
			||||||
 | 
						NM_BS11_CANR_DCS1800	= 0x01,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.2: Object Class */
 | 
				
			||||||
 | 
					enum abis_nm_obj_class {
 | 
				
			||||||
 | 
						NM_OC_SITE_MANAGER		= 0x00,
 | 
				
			||||||
 | 
						NM_OC_BTS,
 | 
				
			||||||
 | 
						NM_OC_RADIO_CARRIER,
 | 
				
			||||||
 | 
						NM_OC_CHANNEL,
 | 
				
			||||||
 | 
						NM_OC_BASEB_TRANSC,
 | 
				
			||||||
 | 
						/* RFU: 05-FE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_OC_IPAC_E1_TRUNK		= 0x0e,
 | 
				
			||||||
 | 
						NM_OC_IPAC_E1_PORT		= 0x0f,
 | 
				
			||||||
 | 
						NM_OC_IPAC_E1_CHAN		= 0x10,
 | 
				
			||||||
 | 
						NM_OC_IPAC_CLK_MODULE		= 0x22,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_OC_BS11_ADJC			= 0xa0,
 | 
				
			||||||
 | 
						NM_OC_BS11_HANDOVER		= 0xa1,
 | 
				
			||||||
 | 
						NM_OC_BS11_PWR_CTRL		= 0xa2,
 | 
				
			||||||
 | 
						NM_OC_BS11_BTSE			= 0xa3,		/* LMT? */
 | 
				
			||||||
 | 
						NM_OC_BS11_RACK			= 0xa4,
 | 
				
			||||||
 | 
						NM_OC_BS11			= 0xa5,		/* 01: ALCO */
 | 
				
			||||||
 | 
						NM_OC_BS11_TEST			= 0xa6,
 | 
				
			||||||
 | 
						NM_OC_BS11_ENVABTSE		= 0xa8,
 | 
				
			||||||
 | 
						NM_OC_BS11_BPORT		= 0xa9,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_OC_GPRS_NSE			= 0xf0,
 | 
				
			||||||
 | 
						NM_OC_GPRS_CELL			= 0xf1,
 | 
				
			||||||
 | 
						NM_OC_GPRS_NSVC			= 0xf2,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_OC_NULL			= 0xff,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.4: Attributes */
 | 
				
			||||||
 | 
					enum abis_nm_attr {
 | 
				
			||||||
 | 
						NM_ATT_ABIS_CHANNEL	= 0x01,
 | 
				
			||||||
 | 
						NM_ATT_ADD_INFO,
 | 
				
			||||||
 | 
						NM_ATT_ADD_TEXT,
 | 
				
			||||||
 | 
						NM_ATT_ADM_STATE,
 | 
				
			||||||
 | 
						NM_ATT_ARFCN_LIST,
 | 
				
			||||||
 | 
						NM_ATT_AUTON_REPORT,
 | 
				
			||||||
 | 
						NM_ATT_AVAIL_STATUS,
 | 
				
			||||||
 | 
						NM_ATT_BCCH_ARFCN,
 | 
				
			||||||
 | 
						NM_ATT_BSIC,
 | 
				
			||||||
 | 
						NM_ATT_BTS_AIR_TIMER,
 | 
				
			||||||
 | 
						NM_ATT_CCCH_L_I_P,
 | 
				
			||||||
 | 
						NM_ATT_CCCH_L_T,
 | 
				
			||||||
 | 
						NM_ATT_CHAN_COMB,
 | 
				
			||||||
 | 
						NM_ATT_CONN_FAIL_CRIT,
 | 
				
			||||||
 | 
						NM_ATT_DEST,
 | 
				
			||||||
 | 
						/* res */
 | 
				
			||||||
 | 
						NM_ATT_EVENT_TYPE	= 0x11, /* BS11: file data ?!? */
 | 
				
			||||||
 | 
						NM_ATT_FILE_ID,
 | 
				
			||||||
 | 
						NM_ATT_FILE_VERSION,
 | 
				
			||||||
 | 
						NM_ATT_GSM_TIME,
 | 
				
			||||||
 | 
						NM_ATT_HSN,
 | 
				
			||||||
 | 
						NM_ATT_HW_CONFIG,
 | 
				
			||||||
 | 
						NM_ATT_HW_DESC,
 | 
				
			||||||
 | 
						NM_ATT_INTAVE_PARAM,
 | 
				
			||||||
 | 
						NM_ATT_INTERF_BOUND,
 | 
				
			||||||
 | 
						NM_ATT_LIST_REQ_ATTR,
 | 
				
			||||||
 | 
						NM_ATT_MAIO,
 | 
				
			||||||
 | 
						NM_ATT_MANUF_STATE,
 | 
				
			||||||
 | 
						NM_ATT_MANUF_THRESH,
 | 
				
			||||||
 | 
						NM_ATT_MANUF_ID,
 | 
				
			||||||
 | 
						NM_ATT_MAX_TA,
 | 
				
			||||||
 | 
						NM_ATT_MDROP_LINK,	/* 0x20 */
 | 
				
			||||||
 | 
						NM_ATT_MDROP_NEXT,
 | 
				
			||||||
 | 
						NM_ATT_NACK_CAUSES,
 | 
				
			||||||
 | 
						NM_ATT_NY1,
 | 
				
			||||||
 | 
						NM_ATT_OPER_STATE,
 | 
				
			||||||
 | 
						NM_ATT_OVERL_PERIOD,
 | 
				
			||||||
 | 
						NM_ATT_PHYS_CONF,
 | 
				
			||||||
 | 
						NM_ATT_POWER_CLASS,
 | 
				
			||||||
 | 
						NM_ATT_POWER_THRESH,
 | 
				
			||||||
 | 
						NM_ATT_PROB_CAUSE,
 | 
				
			||||||
 | 
						NM_ATT_RACH_B_THRESH,
 | 
				
			||||||
 | 
						NM_ATT_LDAVG_SLOTS,
 | 
				
			||||||
 | 
						NM_ATT_RAD_SUBC,
 | 
				
			||||||
 | 
						NM_ATT_RF_MAXPOWR_R,
 | 
				
			||||||
 | 
						NM_ATT_SITE_INPUTS,
 | 
				
			||||||
 | 
						NM_ATT_SITE_OUTPUTS,
 | 
				
			||||||
 | 
						NM_ATT_SOURCE,		/* 0x30 */
 | 
				
			||||||
 | 
						NM_ATT_SPEC_PROB,
 | 
				
			||||||
 | 
						NM_ATT_START_TIME,
 | 
				
			||||||
 | 
						NM_ATT_T200,
 | 
				
			||||||
 | 
						NM_ATT_TEI,
 | 
				
			||||||
 | 
						NM_ATT_TEST_DUR,
 | 
				
			||||||
 | 
						NM_ATT_TEST_NO,
 | 
				
			||||||
 | 
						NM_ATT_TEST_REPORT,
 | 
				
			||||||
 | 
						NM_ATT_VSWR_THRESH,
 | 
				
			||||||
 | 
						NM_ATT_WINDOW_SIZE,
 | 
				
			||||||
 | 
						/* Res  */
 | 
				
			||||||
 | 
						NM_ATT_BS11_RSSI_OFFS	= 0x3d,
 | 
				
			||||||
 | 
						NM_ATT_BS11_TXPWR	= 0x3e,
 | 
				
			||||||
 | 
						NM_ATT_BS11_DIVERSITY	= 0x3f,
 | 
				
			||||||
 | 
						/* Res  */
 | 
				
			||||||
 | 
						NM_ATT_TSC		= 0x40,
 | 
				
			||||||
 | 
						NM_ATT_SW_CONFIG,
 | 
				
			||||||
 | 
						NM_ATT_SW_DESCR,
 | 
				
			||||||
 | 
						NM_ATT_SEVERITY,
 | 
				
			||||||
 | 
						NM_ATT_GET_ARI,
 | 
				
			||||||
 | 
						NM_ATT_HW_CONF_CHG,
 | 
				
			||||||
 | 
						NM_ATT_OUTST_ALARM,
 | 
				
			||||||
 | 
						NM_ATT_FILE_DATA,
 | 
				
			||||||
 | 
						NM_ATT_MEAS_RES,
 | 
				
			||||||
 | 
						NM_ATT_MEAS_TYPE,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_ESN_FW_CODE_NO	= 0x4c,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ESN_HW_CODE_NO	= 0x4f,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_ESN_PCB_SERIAL	= 0x55,
 | 
				
			||||||
 | 
						NM_ATT_BS11_EXCESSIVE_DISTANCE	= 0x58,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_ALL_TEST_CATG	= 0x60,
 | 
				
			||||||
 | 
						NM_ATT_BS11_BTSLS_HOPPING,
 | 
				
			||||||
 | 
						NM_ATT_BS11_CELL_ALLOC_NR,
 | 
				
			||||||
 | 
						NM_ATT_BS11_CELL_GLOBAL_ID,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ENA_INTERF_CLASS	= 0x66,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ENA_INT_INTEC_HANDO	= 0x67,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ENA_INT_INTRC_HANDO	= 0x68,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ENA_MS_PWR_CTRL	= 0x69,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ENA_PWR_BDGT_HO	= 0x6a,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ENA_PWR_CTRL_RLFW	= 0x6b,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ENA_RXLEV_HO	= 0x6c,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ENA_RXQUAL_HO	= 0x6d,
 | 
				
			||||||
 | 
						NM_ATT_BS11_FACCH_QUAL		= 0x6e,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_IPACC_DST_IP		= 0x80,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_DST_IP_PORT	= 0x81,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_SSRC		= 0x82,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_RTP_PAYLD_TYPE	= 0x83,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_BASEB_ID		= 0x84,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_STREAM_ID		= 0x85,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_NV_FLAGS		= 0x86,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_FREQ_CTRL		= 0x87,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_PRIM_OML_CFG	= 0x88,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_SEC_OML_CFG	= 0x89,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_IP_IF_CFG		= 0x8a,		/* IP interface */
 | 
				
			||||||
 | 
						NM_ATT_IPACC_IP_GW_CFG		= 0x8b,		/* IP gateway */
 | 
				
			||||||
 | 
						NM_ATT_IPACC_IN_SERV_TIME	= 0x8c,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_TRX_BTS_ASS	= 0x8d,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_LOCATION		= 0x8e,		/* string describing location */
 | 
				
			||||||
 | 
						NM_ATT_IPACC_PAGING_CFG		= 0x8f,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_FILE_DATA		= 0x90,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_UNIT_ID		= 0x91,		/* Site/BTS/TRX */
 | 
				
			||||||
 | 
						NM_ATT_IPACC_PARENT_UNIT_ID	= 0x92,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_UNIT_NAME		= 0x93,		/* default: nbts-<mac-as-string> */
 | 
				
			||||||
 | 
						NM_ATT_IPACC_SNMP_CFG		= 0x94,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_PRIM_OML_CFG_LIST	= 0x95,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_PRIM_OML_FB_TOUT	= 0x96,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_CUR_SW_CFG		= 0x97,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_TIMING_BUS		= 0x98,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_CGI		= 0x99,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_RAC		= 0x9a,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_OBJ_VERSION	= 0x9b,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_GPRS_PAGING_CFG	= 0x9c,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_NSEI		= 0x9d,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_BVCI		= 0x9e,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_NSVCI		= 0x9f,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_NS_CFG		= 0xa0,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_BSSGP_CFG		= 0xa1,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_NS_LINK_CFG	= 0xa2,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_RLC_CFG		= 0xa3,	
 | 
				
			||||||
 | 
						NM_ATT_IPACC_ALM_THRESH_LIST	= 0xa4,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_MONIT_VAL_LIST	= 0xa5,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_TIB_CONTROL	= 0xa6,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_SUPP_FEATURES	= 0xa7,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_CODING_SCHEMES	= 0xa8,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_RLC_CFG_2		= 0xa9,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_HEARTB_TOUT	= 0xaa,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_UPTIME		= 0xab,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_RLC_CFG_3		= 0xac,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_SSL_CFG		= 0xad,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_SEC_POSSIBLE	= 0xae,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_IML_SSL_STATE	= 0xaf,
 | 
				
			||||||
 | 
						NM_ATT_IPACC_REVOC_DATE		= 0xb0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_RF_RES_IND_PER	= 0x8f,
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						NM_ATT_BS11_RX_LEV_MIN_CELL	= 0x90,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ABIS_EXT_TIME	= 0x91,
 | 
				
			||||||
 | 
						NM_ATT_BS11_TIMER_HO_REQUEST	= 0x92,
 | 
				
			||||||
 | 
						NM_ATT_BS11_TIMER_NCELL		= 0x93,
 | 
				
			||||||
 | 
						NM_ATT_BS11_TSYNC		= 0x94,
 | 
				
			||||||
 | 
						NM_ATT_BS11_TTRAU		= 0x95,
 | 
				
			||||||
 | 
						NM_ATT_BS11_EMRG_CFG_MEMBER	= 0x9b,
 | 
				
			||||||
 | 
						NM_ATT_BS11_TRX_AREA		= 0x9f,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_BCCH_RECONF		= 0xd7,
 | 
				
			||||||
 | 
						NM_ATT_BS11_BIT_ERR_THESH	= 0xa0,
 | 
				
			||||||
 | 
						NM_ATT_BS11_BOOT_SW_VERS	= 0xa1,
 | 
				
			||||||
 | 
						NM_ATT_BS11_CCLK_ACCURACY	= 0xa3,
 | 
				
			||||||
 | 
						NM_ATT_BS11_CCLK_TYPE		= 0xa4,
 | 
				
			||||||
 | 
						NM_ATT_BS11_INP_IMPEDANCE	= 0xaa,
 | 
				
			||||||
 | 
						NM_ATT_BS11_L1_PROT_TYPE	= 0xab,
 | 
				
			||||||
 | 
						NM_ATT_BS11_LINE_CFG		= 0xac,
 | 
				
			||||||
 | 
						NM_ATT_BS11_LI_PORT_1		= 0xad,
 | 
				
			||||||
 | 
						NM_ATT_BS11_LI_PORT_2		= 0xae,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_L1_REM_ALM_TYPE	= 0xb0,
 | 
				
			||||||
 | 
						NM_ATT_BS11_SW_LOAD_INTENDED	= 0xbb,
 | 
				
			||||||
 | 
						NM_ATT_BS11_SW_LOAD_SAFETY	= 0xbc,
 | 
				
			||||||
 | 
						NM_ATT_BS11_SW_LOAD_STORED	= 0xbd,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_VENDOR_NAME		= 0xc1,
 | 
				
			||||||
 | 
						NM_ATT_BS11_HOPPING_MODE	= 0xc5,
 | 
				
			||||||
 | 
						NM_ATT_BS11_LMT_LOGON_SESSION	= 0xc6,
 | 
				
			||||||
 | 
						NM_ATT_BS11_LMT_LOGIN_TIME	= 0xc7,
 | 
				
			||||||
 | 
						NM_ATT_BS11_LMT_USER_ACC_LEV	= 0xc8,
 | 
				
			||||||
 | 
						NM_ATT_BS11_LMT_USER_NAME	= 0xc9,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_L1_CONTROL_TS	= 0xd8,
 | 
				
			||||||
 | 
						NM_ATT_BS11_RADIO_MEAS_GRAN	= 0xdc,	/* in SACCH multiframes */
 | 
				
			||||||
 | 
						NM_ATT_BS11_RADIO_MEAS_REP	= 0xdd,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_SH_LAPD_INT_TIMER	= 0xe8,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NM_ATT_BS11_BTS_STATE		= 0xf0,
 | 
				
			||||||
 | 
						NM_ATT_BS11_E1_STATE		= 0xf1,
 | 
				
			||||||
 | 
						NM_ATT_BS11_PLL			= 0xf2,
 | 
				
			||||||
 | 
						NM_ATT_BS11_RX_OFFSET		= 0xf3,
 | 
				
			||||||
 | 
						NM_ATT_BS11_ANT_TYPE		= 0xf4,
 | 
				
			||||||
 | 
						NM_ATT_BS11_PLL_MODE		= 0xfc,
 | 
				
			||||||
 | 
						NM_ATT_BS11_PASSWORD		= 0xfd,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#define NM_ATT_BS11_FILE_DATA	NM_ATT_EVENT_TYPE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.4.4: Administrative State */
 | 
				
			||||||
 | 
					enum abis_nm_adm_state {
 | 
				
			||||||
 | 
						NM_STATE_LOCKED		= 0x01,
 | 
				
			||||||
 | 
						NM_STATE_UNLOCKED	= 0x02,
 | 
				
			||||||
 | 
						NM_STATE_SHUTDOWN	= 0x03,
 | 
				
			||||||
 | 
						NM_STATE_NULL		= 0xff,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.4.7: Administrative State */
 | 
				
			||||||
 | 
					enum abis_nm_avail_state {
 | 
				
			||||||
 | 
						NM_AVSTATE_IN_TEST	= 1,
 | 
				
			||||||
 | 
						NM_AVSTATE_POWER_OFF	= 2,
 | 
				
			||||||
 | 
						NM_AVSTATE_OFF_LINE	= 3,
 | 
				
			||||||
 | 
						NM_AVSTATE_DEPENDENCY	= 5,
 | 
				
			||||||
 | 
						NM_AVSTATE_DEGRADED	= 6,
 | 
				
			||||||
 | 
						NM_AVSTATE_NOT_INSTALLED= 7,
 | 
				
			||||||
 | 
						NM_AVSTATE_OK		= 0xff,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.4.13: Channel Combination */
 | 
				
			||||||
 | 
					enum abis_nm_chan_comb {
 | 
				
			||||||
 | 
						NM_CHANC_TCHFull	= 0x00,	/* TCH/F + TCH/H + SACCH/TF */
 | 
				
			||||||
 | 
						NM_CHANC_TCHHalf	= 0x01, /* TCH/H(0,1) + FACCH/H(0,1) +
 | 
				
			||||||
 | 
										   SACCH/TH(0,1) */
 | 
				
			||||||
 | 
						NM_CHANC_TCHHalf2	= 0x02, /* TCH/H(0) + FACCH/H(0) + SACCH/TH(0) +
 | 
				
			||||||
 | 
										   TCH/H(1) */
 | 
				
			||||||
 | 
						NM_CHANC_SDCCH		= 0x03,	/* SDCCH/8 + SACCH/8 */
 | 
				
			||||||
 | 
						NM_CHANC_mainBCCH	= 0x04,	/* FCCH + SCH + BCCH + CCCH */
 | 
				
			||||||
 | 
						NM_CHANC_BCCHComb	= 0x05,	/* FCCH + SCH + BCCH + CCCH + SDCCH/4 +
 | 
				
			||||||
 | 
										   SACCH/C4 */
 | 
				
			||||||
 | 
						NM_CHANC_BCCH		= 0x06,	/* BCCH + CCCH */
 | 
				
			||||||
 | 
						NM_CHANC_BCCH_CBCH	= 0x07,	/* CHANC_BCCHComb + CBCH */
 | 
				
			||||||
 | 
						NM_CHANC_SDCCH_CBCH	= 0x08,	/* CHANC_SDCCH8 + CBCH */
 | 
				
			||||||
 | 
						/* ip.access */
 | 
				
			||||||
 | 
						NM_CHANC_IPAC_bPDCH	= 0x0b,	/* PBCCH + PCCCH + PDTCH/F + PACCH/F +
 | 
				
			||||||
 | 
										   PTCCH/F */
 | 
				
			||||||
 | 
						NM_CHANC_IPAC_cPDCH	= 0x0c, /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */
 | 
				
			||||||
 | 
						NM_CHANC_IPAC_PDCH	= 0x0d,	/* PDTCH/F + PACCH/F + PTCCH/F */
 | 
				
			||||||
 | 
						NM_CHANC_IPAC_TCHFull_PDCH = 0x80,
 | 
				
			||||||
 | 
						NM_CHANC_IPAC_TCHFull_TCHHalf = 0x81,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.4.16: Event Type */
 | 
				
			||||||
 | 
					enum abis_nm_event_type {
 | 
				
			||||||
 | 
						NM_EVT_COMM_FAIL	= 0x00,
 | 
				
			||||||
 | 
						NM_EVT_QOS_FAIL		= 0x01,
 | 
				
			||||||
 | 
						NM_EVT_PROC_FAIL	= 0x02,
 | 
				
			||||||
 | 
						NM_EVT_EQUIP_FAIL	= 0x03,
 | 
				
			||||||
 | 
						NM_EVT_ENV_FAIL		= 0x04,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section: 9.4.63: Perceived Severity */
 | 
				
			||||||
 | 
					enum abis_nm_severity {
 | 
				
			||||||
 | 
						NM_SEVER_CEASED		= 0x00,
 | 
				
			||||||
 | 
						NM_SEVER_CRITICAL	= 0x01,
 | 
				
			||||||
 | 
						NM_SEVER_MAJOR		= 0x02,
 | 
				
			||||||
 | 
						NM_SEVER_MINOR		= 0x03,
 | 
				
			||||||
 | 
						NM_SEVER_WARNING	= 0x04,
 | 
				
			||||||
 | 
						NM_SEVER_INDETERMINATE	= 0x05,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.4.43: Probable Cause Type */
 | 
				
			||||||
 | 
					enum abis_nm_pcause_type {
 | 
				
			||||||
 | 
						NM_PCAUSE_T_X721	= 0x01,
 | 
				
			||||||
 | 
						NM_PCAUSE_T_GSM		= 0x02,
 | 
				
			||||||
 | 
						NM_PCAUSE_T_MANUF	= 0x03,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.4.36: NACK Causes */
 | 
				
			||||||
 | 
					enum abis_nm_nack_cause {
 | 
				
			||||||
 | 
						/* General Nack Causes */
 | 
				
			||||||
 | 
						NM_NACK_INCORR_STRUCT		= 0x01,
 | 
				
			||||||
 | 
						NM_NACK_MSGTYPE_INVAL		= 0x02,
 | 
				
			||||||
 | 
						NM_NACK_OBJCLASS_INVAL		= 0x05,
 | 
				
			||||||
 | 
						NM_NACK_OBJCLASS_NOTSUPP	= 0x06,
 | 
				
			||||||
 | 
						NM_NACK_BTSNR_UNKN		= 0x07,
 | 
				
			||||||
 | 
						NM_NACK_TRXNR_UNKN		= 0x08,
 | 
				
			||||||
 | 
						NM_NACK_OBJINST_UNKN		= 0x09,
 | 
				
			||||||
 | 
						NM_NACK_ATTRID_INVAL		= 0x0c,
 | 
				
			||||||
 | 
						NM_NACK_ATTRID_NOTSUPP		= 0x0d,
 | 
				
			||||||
 | 
						NM_NACK_PARAM_RANGE		= 0x0e,
 | 
				
			||||||
 | 
						NM_NACK_ATTRLIST_INCONSISTENT	= 0x0f,
 | 
				
			||||||
 | 
						NM_NACK_SPEC_IMPL_NOTSUPP	= 0x10,
 | 
				
			||||||
 | 
						NM_NACK_CANT_PERFORM		= 0x11,
 | 
				
			||||||
 | 
						/* Specific Nack Causes */
 | 
				
			||||||
 | 
						NM_NACK_RES_NOTIMPL		= 0x19,
 | 
				
			||||||
 | 
						NM_NACK_RES_NOTAVAIL		= 0x1a,
 | 
				
			||||||
 | 
						NM_NACK_FREQ_NOTAVAIL		= 0x1b,
 | 
				
			||||||
 | 
						NM_NACK_TEST_NOTSUPP		= 0x1c,
 | 
				
			||||||
 | 
						NM_NACK_CAPACITY_RESTR		= 0x1d,
 | 
				
			||||||
 | 
						NM_NACK_PHYSCFG_NOTPERFORM	= 0x1e,
 | 
				
			||||||
 | 
						NM_NACK_TEST_NOTINIT		= 0x1f,
 | 
				
			||||||
 | 
						NM_NACK_PHYSCFG_NOTRESTORE	= 0x20,
 | 
				
			||||||
 | 
						NM_NACK_TEST_NOSUCH		= 0x21,
 | 
				
			||||||
 | 
						NM_NACK_TEST_NOSTOP		= 0x22,
 | 
				
			||||||
 | 
						NM_NACK_MSGINCONSIST_PHYSCFG	= 0x23,
 | 
				
			||||||
 | 
						NM_NACK_FILE_INCOMPLETE		= 0x25,
 | 
				
			||||||
 | 
						NM_NACK_FILE_NOTAVAIL		= 0x26,
 | 
				
			||||||
 | 
						NM_NACK_FILE_NOTACTIVATE	= 0x27,
 | 
				
			||||||
 | 
						NM_NACK_REQ_NOT_GRANT		= 0x28,
 | 
				
			||||||
 | 
						NM_NACK_WAIT			= 0x29,
 | 
				
			||||||
 | 
						NM_NACK_NOTH_REPORT_EXIST	= 0x2a,
 | 
				
			||||||
 | 
						NM_NACK_MEAS_NOTSUPP		= 0x2b,
 | 
				
			||||||
 | 
						NM_NACK_MEAS_NOTSTART		= 0x2c,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.4.1 */
 | 
				
			||||||
 | 
					struct abis_nm_channel {
 | 
				
			||||||
 | 
						u_int8_t	attrib;
 | 
				
			||||||
 | 
						u_int8_t	bts_port;
 | 
				
			||||||
 | 
						u_int8_t	timeslot;
 | 
				
			||||||
 | 
						u_int8_t	subslot;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */
 | 
				
			||||||
 | 
					enum abis_bs11_objtype {
 | 
				
			||||||
 | 
						BS11_OBJ_ALCO		= 0x01,
 | 
				
			||||||
 | 
						BS11_OBJ_BBSIG		= 0x02,	/* obj_class: 0,1 */
 | 
				
			||||||
 | 
						BS11_OBJ_TRX1		= 0x03,	/* only DEACTIVATE TRX1 */
 | 
				
			||||||
 | 
						BS11_OBJ_CCLK		= 0x04,
 | 
				
			||||||
 | 
						BS11_OBJ_GPSU		= 0x06,
 | 
				
			||||||
 | 
						BS11_OBJ_LI		= 0x07,
 | 
				
			||||||
 | 
						BS11_OBJ_PA		= 0x09,	/* obj_class: 0, 1*/
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum abis_bs11_trx_power {
 | 
				
			||||||
 | 
						BS11_TRX_POWER_GSM_2W	= 0x06,
 | 
				
			||||||
 | 
						BS11_TRX_POWER_GSM_250mW= 0x07,
 | 
				
			||||||
 | 
						BS11_TRX_POWER_GSM_80mW	= 0x08,
 | 
				
			||||||
 | 
						BS11_TRX_POWER_GSM_30mW	= 0x09,
 | 
				
			||||||
 | 
						BS11_TRX_POWER_DCS_3W	= 0x0a,
 | 
				
			||||||
 | 
						BS11_TRX_POWER_DCS_1W6	= 0x0b,
 | 
				
			||||||
 | 
						BS11_TRX_POWER_DCS_500mW= 0x0c,
 | 
				
			||||||
 | 
						BS11_TRX_POWER_DCS_160mW= 0x0d,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum abis_bs11_li_pll_mode {
 | 
				
			||||||
 | 
						BS11_LI_PLL_LOCKED	= 2,
 | 
				
			||||||
 | 
						BS11_LI_PLL_STANDALONE	= 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum abis_bs11_line_cfg {
 | 
				
			||||||
 | 
						BS11_LINE_CFG_STAR	= 0x00,
 | 
				
			||||||
 | 
						BS11_LINE_CFG_MULTIDROP	= 0x01,
 | 
				
			||||||
 | 
						BS11_LINE_CFG_LOOP	= 0x02,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum abis_bs11_phase {
 | 
				
			||||||
 | 
						BS11_STATE_SOFTWARE_RQD		= 0x01,
 | 
				
			||||||
 | 
						BS11_STATE_LOAD_SMU_INTENDED	= 0x11,
 | 
				
			||||||
 | 
						BS11_STATE_LOAD_SMU_SAFETY	= 0x21,
 | 
				
			||||||
 | 
						BS11_STATE_LOAD_FAILED		= 0x31,
 | 
				
			||||||
 | 
						BS11_STATE_LOAD_DIAGNOSTIC	= 0x41,
 | 
				
			||||||
 | 
						BS11_STATE_WARM_UP		= 0x51,
 | 
				
			||||||
 | 
						BS11_STATE_WARM_UP_2		= 0x52,
 | 
				
			||||||
 | 
						BS11_STATE_WAIT_MIN_CFG		= 0x62,
 | 
				
			||||||
 | 
						BS11_STATE_MAINTENANCE		= 0x72,
 | 
				
			||||||
 | 
						BS11_STATE_LOAD_MBCCU		= 0x92,
 | 
				
			||||||
 | 
						BS11_STATE_WAIT_MIN_CFG_2	= 0xA2,
 | 
				
			||||||
 | 
						BS11_STATE_NORMAL		= 0x03,
 | 
				
			||||||
 | 
						BS11_STATE_ABIS_LOAD		= 0x13,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum abis_nm_ipacc_test_no {
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_RLOOP_ANT	= 0x01,
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_RLOOP_XCVR	= 0x02,
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_FUNC_OBJ	= 0x03,
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_CHAN_USAGE	= 0x40,
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_BCCH_CHAN_USAGE	= 0x41,
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_FREQ_SYNC	= 0x42,
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_BCCH_INFO	= 0x43,
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_TX_BEACON	= 0x44,
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_SYSINFO_MONITOR	= 0x45,
 | 
				
			||||||
 | 
						NM_IPACC_TESTNO_BCCCH_MONITOR	= 0x46,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* first byte after length inside NM_ATT_TEST_REPORT */
 | 
				
			||||||
 | 
					enum abis_nm_ipacc_test_res {
 | 
				
			||||||
 | 
						NM_IPACC_TESTRES_SUCCESS	= 0,
 | 
				
			||||||
 | 
						NM_IPACC_TESTRES_TIMEOUT	= 1,
 | 
				
			||||||
 | 
						NM_IPACC_TESTRES_NO_CHANS	= 2,
 | 
				
			||||||
 | 
						NM_IPACC_TESTRES_PARTIAL	= 3,
 | 
				
			||||||
 | 
						NM_IPACC_TESTRES_STOPPED	= 4,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* internal IE inside NM_ATT_TEST_REPORT */
 | 
				
			||||||
 | 
					enum abis_nm_ipacc_testres_ie {
 | 
				
			||||||
 | 
						NM_IPACC_TR_IE_FREQ_ERR_LIST	= 3,
 | 
				
			||||||
 | 
						NM_IPACC_TR_IE_CHAN_USAGE	= 4,
 | 
				
			||||||
 | 
						NM_IPACC_TR_IE_BCCH_INFO	= 6,
 | 
				
			||||||
 | 
						NM_IPACC_TR_IE_RESULT_DETAILS	= 8,
 | 
				
			||||||
 | 
						NM_IPACC_TR_IE_FREQ_ERR		= 18,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ipac_eie {
 | 
				
			||||||
 | 
						NM_IPAC_EIE_ARFCN_WHITE		= 0x01,
 | 
				
			||||||
 | 
						NM_IPAC_EIE_ARFCH_BLACK		= 0x02,
 | 
				
			||||||
 | 
						NM_IPAC_EIE_FREQ_ERR_LIST	= 0x03,
 | 
				
			||||||
 | 
						NM_IPAC_EIE_CHAN_USE_LIST	= 0x04,
 | 
				
			||||||
 | 
						NM_IPAC_EIE_BCCH_INFO_TYPE	= 0x05,
 | 
				
			||||||
 | 
						NM_IPAC_EIE_BCCH_INFO		= 0x06,
 | 
				
			||||||
 | 
						/* FIXME */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ipac_bcch_info_type {
 | 
				
			||||||
 | 
						IPAC_BINF_RXLEV			= (1 << 8),
 | 
				
			||||||
 | 
						IPAC_BINF_RXQUAL		= (1 << 9),
 | 
				
			||||||
 | 
						IPAC_BINF_FREQ_ERR_QUAL		= (1 << 10),
 | 
				
			||||||
 | 
						IPAC_BINF_FRAME_OFFSET		= (1 << 11),
 | 
				
			||||||
 | 
						IPAC_BINF_FRAME_NR_OFFSET	= (1 << 12),
 | 
				
			||||||
 | 
						IPAC_BINF_BSIC			= (1 << 13),
 | 
				
			||||||
 | 
						IPAC_BINF_CGI			= (1 << 14),
 | 
				
			||||||
 | 
						IPAC_BINF_NEIGH_BA_SI2		= (1 << 15),
 | 
				
			||||||
 | 
						IPAC_BINF_NEIGH_BA_SI2bis	= (1 << 0),
 | 
				
			||||||
 | 
						IPAC_BINF_NEIGH_BA_SI2ter	= (1 << 1),
 | 
				
			||||||
 | 
						IPAC_BINF_CELL_ALLOC		= (1 << 2),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct cell_global_id {
 | 
					struct cell_global_id {
 | 
				
			||||||
	u_int16_t mcc;
 | 
						u_int16_t mcc;
 | 
				
			||||||
@@ -55,10 +712,6 @@ struct ipac_bcch_info {
 | 
				
			|||||||
	u_int8_t ca_list_si1[16];
 | 
						u_int8_t ca_list_si1[16];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const struct value_string abis_nm_adm_state_names[];
 | 
					 | 
				
			||||||
extern const struct value_string abis_nm_obj_class_names[];
 | 
					 | 
				
			||||||
extern const struct tlv_definition nm_att_tlvdef;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* PUBLIC */
 | 
					/* PUBLIC */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct msgb;
 | 
					struct msgb;
 | 
				
			||||||
@@ -73,7 +726,7 @@ struct abis_nm_cfg {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern int abis_nm_rcvmsg(struct msgb *msg);
 | 
					extern int abis_nm_rcvmsg(struct msgb *msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const u_int8_t *buf, int len);
 | 
					int abis_nm_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int len);
 | 
				
			||||||
int abis_nm_rx(struct msgb *msg);
 | 
					int abis_nm_rx(struct msgb *msg);
 | 
				
			||||||
int abis_nm_opstart(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1, u_int8_t i2);
 | 
					int abis_nm_opstart(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1, u_int8_t i2);
 | 
				
			||||||
int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0,
 | 
					int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0,
 | 
				
			||||||
@@ -94,7 +747,7 @@ int abis_nm_sw_act_req_ack(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i1,
 | 
				
			|||||||
int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *msg);
 | 
					int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *msg);
 | 
				
			||||||
int abis_nm_event_reports(struct gsm_bts *bts, int on);
 | 
					int abis_nm_event_reports(struct gsm_bts *bts, int on);
 | 
				
			||||||
int abis_nm_reset_resource(struct gsm_bts *bts);
 | 
					int abis_nm_reset_resource(struct gsm_bts *bts);
 | 
				
			||||||
int abis_nm_software_load(struct gsm_bts *bts, int trx_nr, const char *fname,
 | 
					int abis_nm_software_load(struct gsm_bts *bts, const char *fname,
 | 
				
			||||||
			  u_int8_t win_size, int forced,
 | 
								  u_int8_t win_size, int forced,
 | 
				
			||||||
			  gsm_cbfn *cbfn, void *cb_data);
 | 
								  gsm_cbfn *cbfn, void *cb_data);
 | 
				
			||||||
int abis_nm_software_load_status(struct gsm_bts *bts);
 | 
					int abis_nm_software_load_status(struct gsm_bts *bts);
 | 
				
			||||||
@@ -106,7 +759,8 @@ int abis_nm_conn_mdrop_link(struct gsm_bts *bts, u_int8_t e1_port0, u_int8_t ts0
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int abis_nm_perform_test(struct gsm_bts *bts, u_int8_t obj_class,
 | 
					int abis_nm_perform_test(struct gsm_bts *bts, u_int8_t obj_class,
 | 
				
			||||||
			 u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
 | 
								 u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
 | 
				
			||||||
			 u_int8_t test_nr, u_int8_t auton_report, struct msgb *msg);
 | 
								 u_int8_t test_nr, u_int8_t auton_report,
 | 
				
			||||||
 | 
								 u_int8_t *phys_config, u_int16_t phys_config_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan);
 | 
					int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -126,13 +780,10 @@ int abis_nm_bs11_get_oml_tei_ts(struct gsm_bts *bts);
 | 
				
			|||||||
int abis_nm_bs11_get_serno(struct gsm_bts *bts);
 | 
					int abis_nm_bs11_get_serno(struct gsm_bts *bts);
 | 
				
			||||||
int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, u_int8_t level);
 | 
					int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, u_int8_t level);
 | 
				
			||||||
int abis_nm_bs11_get_trx_power(struct gsm_bts_trx *trx);
 | 
					int abis_nm_bs11_get_trx_power(struct gsm_bts_trx *trx);
 | 
				
			||||||
int abis_nm_bs11_logon(struct gsm_bts *bts, u_int8_t level, const char *name, int on);
 | 
					 | 
				
			||||||
int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on);
 | 
					int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on);
 | 
				
			||||||
int abis_nm_bs11_infield_logon(struct gsm_bts *bts, int on);
 | 
					 | 
				
			||||||
int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password);
 | 
					int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password);
 | 
				
			||||||
int abis_nm_bs11_set_pll_locked(struct gsm_bts *bts, int locked);
 | 
					int abis_nm_bs11_set_pll_locked(struct gsm_bts *bts, int locked);
 | 
				
			||||||
int abis_nm_bs11_get_pll_mode(struct gsm_bts *bts);
 | 
					int abis_nm_bs11_get_pll_mode(struct gsm_bts *bts);
 | 
				
			||||||
int abis_nm_bs11_set_pll(struct gsm_bts *bts, int value);
 | 
					 | 
				
			||||||
int abis_nm_bs11_get_cclk(struct gsm_bts *bts);
 | 
					int abis_nm_bs11_get_cclk(struct gsm_bts *bts);
 | 
				
			||||||
int abis_nm_bs11_get_state(struct gsm_bts *bts);
 | 
					int abis_nm_bs11_get_state(struct gsm_bts *bts);
 | 
				
			||||||
int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
 | 
					int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
 | 
				
			||||||
@@ -147,15 +798,14 @@ int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type,
 | 
				
			|||||||
			 u_int8_t obj_class, u_int8_t bts_nr,
 | 
								 u_int8_t obj_class, u_int8_t bts_nr,
 | 
				
			||||||
			 u_int8_t trx_nr, u_int8_t ts_nr,
 | 
								 u_int8_t trx_nr, u_int8_t ts_nr,
 | 
				
			||||||
			 u_int8_t *attr, int attr_len);
 | 
								 u_int8_t *attr, int attr_len);
 | 
				
			||||||
int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, u_int8_t *attr,
 | 
					int abis_nm_ipaccess_set_nvattr(struct gsm_bts *bts, u_int8_t *attr,
 | 
				
			||||||
				int attr_len);
 | 
									int attr_len);
 | 
				
			||||||
int abis_nm_ipaccess_restart(struct gsm_bts_trx *trx);
 | 
					int abis_nm_ipaccess_restart(struct gsm_bts *bts);
 | 
				
			||||||
int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
 | 
					int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
 | 
				
			||||||
				u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
 | 
									u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
 | 
				
			||||||
				u_int8_t *attr, u_int8_t attr_len);
 | 
									u_int8_t *attr, u_int8_t attr_len);
 | 
				
			||||||
int abis_nm_ipaccess_rsl_connect(struct gsm_bts_trx *trx, 
 | 
					int abis_nm_ipaccess_rsl_connect(struct gsm_bts_trx *trx, 
 | 
				
			||||||
				 u_int32_t ip, u_int16_t port, u_int8_t stream);
 | 
									 u_int32_t ip, u_int16_t port, u_int8_t stream);
 | 
				
			||||||
void abis_nm_ipaccess_cgi(u_int8_t *buf, struct gsm_bts *bts);
 | 
					 | 
				
			||||||
int ipac_parse_bcch_info(struct ipac_bcch_info *binf, u_int8_t *buf);
 | 
					int ipac_parse_bcch_info(struct ipac_bcch_info *binf, u_int8_t *buf);
 | 
				
			||||||
const char *ipacc_testres_name(u_int8_t res);
 | 
					const char *ipacc_testres_name(u_int8_t res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -165,13 +815,8 @@ enum nm_evt {
 | 
				
			|||||||
	EVT_STATECHG_ADM,
 | 
						EVT_STATECHG_ADM,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
 | 
					int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
 | 
				
			||||||
		   struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,
 | 
							   struct gsm_nm_state *old_state, struct gsm_nm_state *new_state); 
 | 
				
			||||||
		   struct abis_om_obj_inst *obj_inst);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *nm_opstate_name(u_int8_t os);
 | 
					const char *nm_opstate_name(u_int8_t os);
 | 
				
			||||||
const char *nm_avail_name(u_int8_t avail);
 | 
					const char *nm_avail_name(u_int8_t avail);
 | 
				
			||||||
int nm_is_running(struct gsm_nm_state *s);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int abis_nm_vty_init(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _NM_H */
 | 
					#endif /* _NM_H */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,9 +23,468 @@
 | 
				
			|||||||
#ifndef _RSL_H
 | 
					#ifndef _RSL_H
 | 
				
			||||||
#define _RSL_H
 | 
					#define _RSL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/protocol/gsm_08_58.h>
 | 
					struct abis_rsl_common_hdr {
 | 
				
			||||||
 | 
						u_int8_t	msg_discr;
 | 
				
			||||||
 | 
						u_int8_t	msg_type;
 | 
				
			||||||
 | 
						u_int8_t	data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					/* Chapter 8.3 */
 | 
				
			||||||
 | 
					struct abis_rsl_rll_hdr {
 | 
				
			||||||
 | 
						struct abis_rsl_common_hdr c;
 | 
				
			||||||
 | 
						u_int8_t	ie_chan;
 | 
				
			||||||
 | 
						u_int8_t	chan_nr;
 | 
				
			||||||
 | 
						u_int8_t	ie_link_id;
 | 
				
			||||||
 | 
						u_int8_t	link_id;
 | 
				
			||||||
 | 
						u_int8_t	data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 8.3 and 8.4 */
 | 
				
			||||||
 | 
					struct abis_rsl_dchan_hdr {
 | 
				
			||||||
 | 
						struct abis_rsl_common_hdr c;
 | 
				
			||||||
 | 
						u_int8_t	ie_chan;
 | 
				
			||||||
 | 
						u_int8_t	chan_nr;
 | 
				
			||||||
 | 
						u_int8_t	data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.1 */
 | 
				
			||||||
 | 
					#define ABIS_RSL_MDISC_RLL		0x02
 | 
				
			||||||
 | 
					#define ABIS_RSL_MDISC_DED_CHAN		0x08
 | 
				
			||||||
 | 
					#define ABIS_RSL_MDISC_COM_CHAN		0x0c
 | 
				
			||||||
 | 
					#define ABIS_RSL_MDISC_TRX		0x10
 | 
				
			||||||
 | 
					#define ABIS_RSL_MDISC_LOC		0x20
 | 
				
			||||||
 | 
					#define ABIS_RSL_MDISC_IPACCESS		0x7e
 | 
				
			||||||
 | 
					#define ABIS_RSL_MDISC_TRANSP		0x01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ABIS_RSL_MDISC_IS_TRANSP(x)	(x & 0x01)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.1 */
 | 
				
			||||||
 | 
					enum abis_rsl_msgtype {
 | 
				
			||||||
 | 
						/* Radio Link Layer Management */
 | 
				
			||||||
 | 
						RSL_MT_DATA_REQ			= 0x01,
 | 
				
			||||||
 | 
						RSL_MT_DATA_IND,
 | 
				
			||||||
 | 
						RSL_MT_ERROR_IND,
 | 
				
			||||||
 | 
						RSL_MT_EST_REQ,
 | 
				
			||||||
 | 
						RSL_MT_EST_CONF,
 | 
				
			||||||
 | 
						RSL_MT_EST_IND,
 | 
				
			||||||
 | 
						RSL_MT_REL_REQ,
 | 
				
			||||||
 | 
						RSL_MT_REL_CONF,
 | 
				
			||||||
 | 
						RSL_MT_REL_IND,
 | 
				
			||||||
 | 
						RSL_MT_UNIT_DATA_REQ,
 | 
				
			||||||
 | 
						RSL_MT_UNIT_DATA_IND,		/* 0x0b */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Common Channel Management / TRX Management */
 | 
				
			||||||
 | 
						RSL_MT_BCCH_INFO			= 0x11,
 | 
				
			||||||
 | 
						RSL_MT_CCCH_LOAD_IND,
 | 
				
			||||||
 | 
						RSL_MT_CHAN_RQD,
 | 
				
			||||||
 | 
						RSL_MT_DELETE_IND,
 | 
				
			||||||
 | 
						RSL_MT_PAGING_CMD,
 | 
				
			||||||
 | 
						RSL_MT_IMMEDIATE_ASSIGN_CMD,
 | 
				
			||||||
 | 
						RSL_MT_SMS_BC_REQ,
 | 
				
			||||||
 | 
						/* empty */
 | 
				
			||||||
 | 
						RSL_MT_RF_RES_IND			= 0x19,
 | 
				
			||||||
 | 
						RSL_MT_SACCH_FILL,
 | 
				
			||||||
 | 
						RSL_MT_OVERLOAD,
 | 
				
			||||||
 | 
						RSL_MT_ERROR_REPORT,
 | 
				
			||||||
 | 
						RSL_MT_SMS_BC_CMD,
 | 
				
			||||||
 | 
						RSL_MT_CBCH_LOAD_IND,
 | 
				
			||||||
 | 
						RSL_MT_NOT_CMD,			/* 0x1f */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Dedicate Channel Management */
 | 
				
			||||||
 | 
						RSL_MT_CHAN_ACTIV			= 0x21,
 | 
				
			||||||
 | 
						RSL_MT_CHAN_ACTIV_ACK,
 | 
				
			||||||
 | 
						RSL_MT_CHAN_ACTIV_NACK,
 | 
				
			||||||
 | 
						RSL_MT_CONN_FAIL,
 | 
				
			||||||
 | 
						RSL_MT_DEACTIVATE_SACCH,
 | 
				
			||||||
 | 
						RSL_MT_ENCR_CMD,
 | 
				
			||||||
 | 
						RSL_MT_HANDO_DET,
 | 
				
			||||||
 | 
						RSL_MT_MEAS_RES,
 | 
				
			||||||
 | 
						RSL_MT_MODE_MODIFY_REQ,
 | 
				
			||||||
 | 
						RSL_MT_MODE_MODIFY_ACK,
 | 
				
			||||||
 | 
						RSL_MT_MODE_MODIFY_NACK,
 | 
				
			||||||
 | 
						RSL_MT_PHY_CONTEXT_REQ,
 | 
				
			||||||
 | 
						RSL_MT_PHY_CONTEXT_CONF,
 | 
				
			||||||
 | 
						RSL_MT_RF_CHAN_REL,
 | 
				
			||||||
 | 
						RSL_MT_MS_POWER_CONTROL,
 | 
				
			||||||
 | 
						RSL_MT_BS_POWER_CONTROL,		/* 0x30 */
 | 
				
			||||||
 | 
						RSL_MT_PREPROC_CONFIG,
 | 
				
			||||||
 | 
						RSL_MT_PREPROC_MEAS_RES,
 | 
				
			||||||
 | 
						RSL_MT_RF_CHAN_REL_ACK,
 | 
				
			||||||
 | 
						RSL_MT_SACCH_INFO_MODIFY,
 | 
				
			||||||
 | 
						RSL_MT_TALKER_DET,
 | 
				
			||||||
 | 
						RSL_MT_LISTENER_DET,
 | 
				
			||||||
 | 
						RSL_MT_REMOTE_CODEC_CONF_REP,
 | 
				
			||||||
 | 
						RSL_MT_RTD_REP,
 | 
				
			||||||
 | 
						RSL_MT_PRE_HANDO_NOTIF,
 | 
				
			||||||
 | 
						RSL_MT_MR_CODEC_MOD_REQ,
 | 
				
			||||||
 | 
						RSL_MT_MR_CODEC_MOD_ACK,
 | 
				
			||||||
 | 
						RSL_MT_MR_CODEC_MOD_NACK,
 | 
				
			||||||
 | 
						RSL_MT_MR_CODEC_MOD_PER,
 | 
				
			||||||
 | 
						RSL_MT_TFO_REP,
 | 
				
			||||||
 | 
						RSL_MT_TFO_MOD_REQ,		/* 0x3f */
 | 
				
			||||||
 | 
						RSL_MT_LOCATION_INFO		= 0x41,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ip.access specific RSL message types */
 | 
				
			||||||
 | 
						RSL_MT_IPAC_DIR_RETR_ENQ	= 0x40,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_PDCH_ACT		= 0x48,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_PDCH_ACT_ACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_PDCH_ACT_NACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_PDCH_DEACT		= 0x4b,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_PDCH_DEACT_ACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_PDCH_DEACT_NACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_CONNECT_MUX		= 0x50,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_CONNECT_MUX_ACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_CONNECT_MUX_NACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_BIND_MUX		= 0x53,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_BIND_MUX_ACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_BIND_MUX_NACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_DISC_MUX		= 0x56,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_DISC_MUX_ACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_DISC_MUX_NACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_CRCX		= 0x70,		/* Bind to local BTS RTP port */
 | 
				
			||||||
 | 
						RSL_MT_IPAC_CRCX_ACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_CRCX_NACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_MDCX		= 0x73,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_MDCX_ACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_MDCX_NACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_DLCX_IND		= 0x76,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_DLCX		= 0x77,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_DLCX_ACK,
 | 
				
			||||||
 | 
						RSL_MT_IPAC_DLCX_NACK,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Siemens vendor-specific */
 | 
				
			||||||
 | 
					enum abis_rsl_msgtype_siemens {
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_MRPCI		= 0x41,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_INTRAC_HO_COND_IND = 0x42,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_INTERC_HO_COND_IND = 0x43,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_FORCED_HO_REQ	= 0x44,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_PREF_AREA_REQ	= 0x45,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_PREF_AREA	= 0x46,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_START_TRACE	= 0x47,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_START_TRACE_ACK	= 0x48,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_STOP_TRACE	= 0x49,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_TRMR		= 0x4a,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_HO_FAIL_IND	= 0x4b,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_STOP_TRACE_ACK	= 0x4c,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_UPLF		= 0x4d,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_UPLB		= 0x4e,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_SET_SYS_INFO_10	= 0x4f,
 | 
				
			||||||
 | 
						RSL_MT_SIEMENS_MODIF_COND_IND	= 0x50,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.3 */
 | 
				
			||||||
 | 
					enum abis_rsl_ie {
 | 
				
			||||||
 | 
						RSL_IE_CHAN_NR			= 0x01,
 | 
				
			||||||
 | 
						RSL_IE_LINK_IDENT,
 | 
				
			||||||
 | 
						RSL_IE_ACT_TYPE,
 | 
				
			||||||
 | 
						RSL_IE_BS_POWER,
 | 
				
			||||||
 | 
						RSL_IE_CHAN_IDENT,
 | 
				
			||||||
 | 
						RSL_IE_CHAN_MODE,
 | 
				
			||||||
 | 
						RSL_IE_ENCR_INFO,
 | 
				
			||||||
 | 
						RSL_IE_FRAME_NUMBER,
 | 
				
			||||||
 | 
						RSL_IE_HANDO_REF,
 | 
				
			||||||
 | 
						RSL_IE_L1_INFO,
 | 
				
			||||||
 | 
						RSL_IE_L3_INFO,
 | 
				
			||||||
 | 
						RSL_IE_MS_IDENTITY,
 | 
				
			||||||
 | 
						RSL_IE_MS_POWER,
 | 
				
			||||||
 | 
						RSL_IE_PAGING_GROUP,
 | 
				
			||||||
 | 
						RSL_IE_PAGING_LOAD,
 | 
				
			||||||
 | 
						RSL_IE_PYHS_CONTEXT		= 0x10,
 | 
				
			||||||
 | 
						RSL_IE_ACCESS_DELAY,
 | 
				
			||||||
 | 
						RSL_IE_RACH_LOAD,
 | 
				
			||||||
 | 
						RSL_IE_REQ_REFERENCE,
 | 
				
			||||||
 | 
						RSL_IE_RELEASE_MODE,
 | 
				
			||||||
 | 
						RSL_IE_RESOURCE_INFO,
 | 
				
			||||||
 | 
						RSL_IE_RLM_CAUSE,
 | 
				
			||||||
 | 
						RSL_IE_STARTNG_TIME,
 | 
				
			||||||
 | 
						RSL_IE_TIMING_ADVANCE,
 | 
				
			||||||
 | 
						RSL_IE_UPLINK_MEAS,
 | 
				
			||||||
 | 
						RSL_IE_CAUSE,
 | 
				
			||||||
 | 
						RSL_IE_MEAS_RES_NR,
 | 
				
			||||||
 | 
						RSL_IE_MSG_ID,
 | 
				
			||||||
 | 
						/* reserved */
 | 
				
			||||||
 | 
						RSL_IE_SYSINFO_TYPE		= 0x1e,
 | 
				
			||||||
 | 
						RSL_IE_MS_POWER_PARAM,
 | 
				
			||||||
 | 
						RSL_IE_BS_POWER_PARAM,
 | 
				
			||||||
 | 
						RSL_IE_PREPROC_PARAM,
 | 
				
			||||||
 | 
						RSL_IE_PREPROC_MEAS,
 | 
				
			||||||
 | 
						RSL_IE_IMM_ASS_INFO,		/* Phase 1 (3.6.0), later Full below */
 | 
				
			||||||
 | 
						RSL_IE_SMSCB_INFO		= 0x24,
 | 
				
			||||||
 | 
						RSL_IE_MS_TIMING_OFFSET,
 | 
				
			||||||
 | 
						RSL_IE_ERR_MSG,
 | 
				
			||||||
 | 
						RSL_IE_FULL_BCCH_INFO,
 | 
				
			||||||
 | 
						RSL_IE_CHAN_NEEDED,
 | 
				
			||||||
 | 
						RSL_IE_CB_CMD_TYPE,
 | 
				
			||||||
 | 
						RSL_IE_SMSCB_MSG,
 | 
				
			||||||
 | 
						RSL_IE_FULL_IMM_ASS_INFO,
 | 
				
			||||||
 | 
						RSL_IE_SACCH_INFO,
 | 
				
			||||||
 | 
						RSL_IE_CBCH_LOAD_INFO,
 | 
				
			||||||
 | 
						RSL_IE_SMSCB_CHAN_INDICATOR,
 | 
				
			||||||
 | 
						RSL_IE_GROUP_CALL_REF,
 | 
				
			||||||
 | 
						RSL_IE_CHAN_DESC		= 0x30,
 | 
				
			||||||
 | 
						RSL_IE_NCH_DRX_INFO,
 | 
				
			||||||
 | 
						RSL_IE_CMD_INDICATOR,
 | 
				
			||||||
 | 
						RSL_IE_EMLPP_PRIO,
 | 
				
			||||||
 | 
						RSL_IE_UIC,
 | 
				
			||||||
 | 
						RSL_IE_MAIN_CHAN_REF,
 | 
				
			||||||
 | 
						RSL_IE_MR_CONFIG,
 | 
				
			||||||
 | 
						RSL_IE_MR_CONTROL,
 | 
				
			||||||
 | 
						RSL_IE_SUP_CODEC_TYPES,
 | 
				
			||||||
 | 
						RSL_IE_CODEC_CONFIG,
 | 
				
			||||||
 | 
						RSL_IE_RTD,
 | 
				
			||||||
 | 
						RSL_IE_TFO_STATUS,
 | 
				
			||||||
 | 
						RSL_IE_LLP_APDU,
 | 
				
			||||||
 | 
						/* Siemens vendor-specific */
 | 
				
			||||||
 | 
						RSL_IE_SIEMENS_MRPCI		= 0x40,
 | 
				
			||||||
 | 
						RSL_IE_SIEMENS_PREF_AREA_TYPE	= 0x43,
 | 
				
			||||||
 | 
						RSL_IE_SIEMENS_ININ_CELL_HO_PAR	= 0x45,
 | 
				
			||||||
 | 
						RSL_IE_SIEMENS_TRACE_REF_NR	= 0x46,
 | 
				
			||||||
 | 
						RSL_IE_SIEMENS_INT_TRACE_IDX	= 0x47,
 | 
				
			||||||
 | 
						RSL_IE_SIEMENS_L2_HDR_INFO	= 0x48,
 | 
				
			||||||
 | 
						RSL_IE_SIEMENS_HIGHEST_RATE	= 0x4e,
 | 
				
			||||||
 | 
						RSL_IE_SIEMENS_SUGGESTED_RATE	= 0x4f,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ip.access */
 | 
				
			||||||
 | 
						RSL_IE_IPAC_SRTP_CONFIG	= 0xe0,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_PROXY_UDP	= 0xe1,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_BSCMPL_TOUT	= 0xe2,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_REMOTE_IP	= 0xf0,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_REMOTE_PORT	= 0xf1,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_RTP_PAYLOAD	= 0xf2,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_LOCAL_PORT	= 0xf3,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_SPEECH_MODE	= 0xf4,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_LOCAL_IP	= 0xf5,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_CONN_STAT	= 0xf6,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_HO_C_PARMS	= 0xf7,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_CONN_ID	= 0xf8,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_RTP_CSD_FMT	= 0xf9,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_RTP_JIT_BUF	= 0xfa,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_RTP_COMPR	= 0xfb,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_RTP_PAYLOAD2= 0xfc,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_RTP_MPLEX	= 0xfd,
 | 
				
			||||||
 | 
						RSL_IE_IPAC_RTP_MPLEX_ID= 0xfe,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.3.1 */
 | 
				
			||||||
 | 
					#define RSL_CHAN_NR_MASK	0xf8
 | 
				
			||||||
 | 
					#define RSL_CHAN_Bm_ACCHs	0x08
 | 
				
			||||||
 | 
					#define RSL_CHAN_Lm_ACCHs	0x10	/* .. 0x18 */
 | 
				
			||||||
 | 
					#define RSL_CHAN_SDCCH4_ACCH	0x20	/* .. 0x38 */
 | 
				
			||||||
 | 
					#define RSL_CHAN_SDCCH8_ACCH	0x40	/* ...0x78 */
 | 
				
			||||||
 | 
					#define RSL_CHAN_BCCH		0x80
 | 
				
			||||||
 | 
					#define RSL_CHAN_RACH		0x88
 | 
				
			||||||
 | 
					#define RSL_CHAN_PCH_AGCH	0x90
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.3.3 */
 | 
				
			||||||
 | 
					#define RSL_ACT_TYPE_INITIAL	0x00
 | 
				
			||||||
 | 
					#define RSL_ACT_TYPE_REACT	0x80
 | 
				
			||||||
 | 
					#define RSL_ACT_INTRA_IMM_ASS	0x00
 | 
				
			||||||
 | 
					#define RSL_ACT_INTRA_NORM_ASS	0x01
 | 
				
			||||||
 | 
					#define RSL_ACT_INTER_ASYNC	0x02
 | 
				
			||||||
 | 
					#define RSL_ACT_INTER_SYNC	0x03
 | 
				
			||||||
 | 
					#define RSL_ACT_SECOND_ADD	0x04
 | 
				
			||||||
 | 
					#define RSL_ACT_SECOND_MULTI	0x05
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.3.6 */
 | 
				
			||||||
 | 
					struct rsl_ie_chan_mode {
 | 
				
			||||||
 | 
						u_int8_t dtx_dtu;
 | 
				
			||||||
 | 
						u_int8_t spd_ind;
 | 
				
			||||||
 | 
						u_int8_t chan_rt;
 | 
				
			||||||
 | 
						u_int8_t chan_rate;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					#define RSL_CMOD_DTXu		0x01	/* uplink */
 | 
				
			||||||
 | 
					#define RSL_CMOD_DTXd		0x02	/* downlink */
 | 
				
			||||||
 | 
					enum rsl_cmod_spd {
 | 
				
			||||||
 | 
						RSL_CMOD_SPD_SPEECH	= 0x01,
 | 
				
			||||||
 | 
						RSL_CMOD_SPD_DATA	= 0x02,
 | 
				
			||||||
 | 
						RSL_CMOD_SPD_SIGN	= 0x03,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#define RSL_CMOD_CRT_SDCCH	0x01
 | 
				
			||||||
 | 
					#define RSL_CMOD_CRT_TCH_Bm	0x08	/* full-rate */
 | 
				
			||||||
 | 
					#define RSL_CMOD_CRT_TCH_Lm	0x09	/* half-rate */
 | 
				
			||||||
 | 
					/* FIXME: More CRT types */
 | 
				
			||||||
 | 
					/* Speech */
 | 
				
			||||||
 | 
					#define RSL_CMOD_SP_GSM1	0x01
 | 
				
			||||||
 | 
					#define RSL_CMOD_SP_GSM2	0x11
 | 
				
			||||||
 | 
					#define RSL_CMOD_SP_GSM3	0x21
 | 
				
			||||||
 | 
					/* Data */
 | 
				
			||||||
 | 
					#define RSL_CMOD_SP_NT_14k5	0x58
 | 
				
			||||||
 | 
					#define RSL_CMOD_SP_NT_12k0	0x50
 | 
				
			||||||
 | 
					#define RSL_CMOD_SP_NT_6k0	0x51
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.3.5 */
 | 
				
			||||||
 | 
					struct rsl_ie_chan_ident {
 | 
				
			||||||
 | 
						/* GSM 04.08 10.5.2.5 */
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							u_int8_t iei;
 | 
				
			||||||
 | 
							u_int8_t chan_nr;	/* enc_chan_nr */
 | 
				
			||||||
 | 
							u_int8_t oct3;
 | 
				
			||||||
 | 
							u_int8_t oct4;
 | 
				
			||||||
 | 
						} chan_desc;
 | 
				
			||||||
 | 
					#if 0	/* spec says we need this but Abissim doesn't use it */
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							u_int8_t tag;
 | 
				
			||||||
 | 
							u_int8_t len;
 | 
				
			||||||
 | 
						} mobile_alloc;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.3.22 */
 | 
				
			||||||
 | 
					#define RLL_CAUSE_T200_EXPIRED		0x01
 | 
				
			||||||
 | 
					#define RLL_CAUSE_REEST_REQ		0x02
 | 
				
			||||||
 | 
					#define RLL_CAUSE_UNSOL_UA_RESP		0x03
 | 
				
			||||||
 | 
					#define RLL_CAUSE_UNSOL_DM_RESP		0x04
 | 
				
			||||||
 | 
					#define RLL_CAUSE_UNSOL_DM_RESP_MF	0x05
 | 
				
			||||||
 | 
					#define RLL_CAUSE_UNSOL_SPRV_RESP	0x06
 | 
				
			||||||
 | 
					#define RLL_CAUSE_SEQ_ERR		0x07
 | 
				
			||||||
 | 
					#define RLL_CAUSE_UFRM_INC_PARAM	0x08
 | 
				
			||||||
 | 
					#define RLL_CAUSE_SFRM_INC_PARAM	0x09
 | 
				
			||||||
 | 
					#define RLL_CAUSE_IFRM_INC_MBITS	0x0a
 | 
				
			||||||
 | 
					#define RLL_CAUSE_IFRM_INC_LEN		0x0b
 | 
				
			||||||
 | 
					#define RLL_CAUSE_FRM_UNIMPL		0x0c
 | 
				
			||||||
 | 
					#define RLL_CAUSE_SABM_MF		0x0d
 | 
				
			||||||
 | 
					#define RLL_CAUSE_SABM_INFO_NOTALL	0x0e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.3.26 */
 | 
				
			||||||
 | 
					#define RSL_ERRCLS_NORMAL		0x00
 | 
				
			||||||
 | 
					#define RSL_ERRCLS_RESOURCE_UNAVAIL	0x20
 | 
				
			||||||
 | 
					#define RSL_ERRCLS_SERVICE_UNAVAIL	0x30
 | 
				
			||||||
 | 
					#define RSL_ERRCLS_SERVICE_UNIMPL	0x40
 | 
				
			||||||
 | 
					#define RSL_ERRCLS_INVAL_MSG		0x50
 | 
				
			||||||
 | 
					#define RSL_ERRCLS_PROTO_ERROR		0x60
 | 
				
			||||||
 | 
					#define RSL_ERRCLS_INTERWORKING		0x70
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* normal event */
 | 
				
			||||||
 | 
					#define RSL_ERR_RADIO_IF_FAIL		0x00
 | 
				
			||||||
 | 
					#define RSL_ERR_RADIO_LINK_FAIL		0x01
 | 
				
			||||||
 | 
					#define RSL_ERR_HANDOVER_ACC_FAIL	0x02
 | 
				
			||||||
 | 
					#define RSL_ERR_TALKER_ACC_FAIL		0x03
 | 
				
			||||||
 | 
					#define RSL_ERR_OM_INTERVENTION		0x07
 | 
				
			||||||
 | 
					#define RSL_ERR_NORMAL_UNSPEC		0x0f
 | 
				
			||||||
 | 
					#define RSL_ERR_T_MSRFPCI_EXP		0x18
 | 
				
			||||||
 | 
					/* resource unavailable */
 | 
				
			||||||
 | 
					#define RSL_ERR_EQUIPMENT_FAIL		0x20
 | 
				
			||||||
 | 
					#define RSL_ERR_RR_UNAVAIL		0x21
 | 
				
			||||||
 | 
					#define RSL_ERR_TERR_CH_FAIL		0x22
 | 
				
			||||||
 | 
					#define RSL_ERR_CCCH_OVERLOAD		0x23
 | 
				
			||||||
 | 
					#define RSL_ERR_ACCH_OVERLOAD		0x24
 | 
				
			||||||
 | 
					#define RSL_ERR_PROCESSOR_OVERLOAD	0x25
 | 
				
			||||||
 | 
					#define RSL_ERR_RES_UNAVAIL		0x2f
 | 
				
			||||||
 | 
					/* service or option not available */
 | 
				
			||||||
 | 
					#define RSL_ERR_TRANSC_UNAVAIL		0x30
 | 
				
			||||||
 | 
					#define RSL_ERR_SERV_OPT_UNAVAIL	0x3f
 | 
				
			||||||
 | 
					/* service or option not implemented */
 | 
				
			||||||
 | 
					#define RSL_ERR_ENCR_UNIMPL		0x40
 | 
				
			||||||
 | 
					#define RSL_ERR_SERV_OPT_UNIMPL		0x4f
 | 
				
			||||||
 | 
					/* invalid message */
 | 
				
			||||||
 | 
					#define RSL_ERR_RCH_ALR_ACTV_ALLOC	0x50
 | 
				
			||||||
 | 
					#define RSL_ERR_INVALID_MESSAGE		0x5f
 | 
				
			||||||
 | 
					/* protocol error */
 | 
				
			||||||
 | 
					#define RSL_ERR_MSG_DISCR		0x60
 | 
				
			||||||
 | 
					#define RSL_ERR_MSG_TYPE		0x61
 | 
				
			||||||
 | 
					#define RSL_ERR_MSG_SEQ			0x62
 | 
				
			||||||
 | 
					#define RSL_ERR_IE_ERROR		0x63
 | 
				
			||||||
 | 
					#define RSL_ERR_MAND_IE_ERROR		0x64
 | 
				
			||||||
 | 
					#define RSL_ERR_OPT_IE_ERROR		0x65
 | 
				
			||||||
 | 
					#define RSL_ERR_IE_NONEXIST		0x66
 | 
				
			||||||
 | 
					#define RSL_ERR_IE_LENGTH		0x67
 | 
				
			||||||
 | 
					#define RSL_ERR_IE_CONTENT		0x68
 | 
				
			||||||
 | 
					#define RSL_ERR_PROTO			0x6f
 | 
				
			||||||
 | 
					/* interworking */
 | 
				
			||||||
 | 
					#define RSL_ERR_INTERWORKING		0x7f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.3.30 */
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_8	0x00
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_1	0x01
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_2	0x02
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_3	0x03
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_4	0x04
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_5	0x05
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_6	0x06
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_7	0x07
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_16	0x08
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_17	0x09
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_2bis	0x0a
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_2ter	0x0b
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_5bis	0x0d
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_5ter	0x0e
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_10	0x0f
 | 
				
			||||||
 | 
					#define REL_EXT_MEAS_ORDER	0x47
 | 
				
			||||||
 | 
					#define RSL_MEAS_INFO		0x48
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_13	0x28
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_2quater	0x29
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_9	0x2a
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_18	0x2b
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_19	0x2c
 | 
				
			||||||
 | 
					#define RSL_SYSTEM_INFO_20	0x2d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.3.40 */
 | 
				
			||||||
 | 
					#define RSL_CHANNEED_ANY	0x00
 | 
				
			||||||
 | 
					#define RSL_CHANNEED_SDCCH	0x01
 | 
				
			||||||
 | 
					#define RSL_CHANNEED_TCH_F	0x02
 | 
				
			||||||
 | 
					#define RSL_CHANNEED_TCH_ForH	0x03
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 3.3.2.3 Brocast control channel */
 | 
				
			||||||
 | 
					/* CCCH-CONF, NC is not combined */
 | 
				
			||||||
 | 
					#define RSL_BCCH_CCCH_CONF_1_NC	0x00
 | 
				
			||||||
 | 
					#define RSL_BCCH_CCCH_CONF_1_C	0x01
 | 
				
			||||||
 | 
					#define RSL_BCCH_CCCH_CONF_2_NC	0x02
 | 
				
			||||||
 | 
					#define RSL_BCCH_CCCH_CONF_3_NC	0x04
 | 
				
			||||||
 | 
					#define RSL_BCCH_CCCH_CONF_4_NC	0x06
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* BS-PA-MFRMS */
 | 
				
			||||||
 | 
					#define RSL_BS_PA_MFRMS_2	0x00
 | 
				
			||||||
 | 
					#define RSL_BS_PA_MFRMS_3	0x01
 | 
				
			||||||
 | 
					#define RSL_BS_PA_MFRMS_4	0x02
 | 
				
			||||||
 | 
					#define RSL_BS_PA_MFRMS_5	0x03
 | 
				
			||||||
 | 
					#define RSL_BS_PA_MFRMS_6	0x04
 | 
				
			||||||
 | 
					#define RSL_BS_PA_MFRMS_7	0x05
 | 
				
			||||||
 | 
					#define RSL_BS_PA_MFRMS_8	0x06
 | 
				
			||||||
 | 
					#define RSL_BS_PA_MFRMS_9	0x07
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RSL_IE_IPAC_RTP_PAYLOAD[2] */
 | 
				
			||||||
 | 
					enum rsl_ipac_rtp_payload {
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_GSM	= 1,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_EFR,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_AMR,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_CSD,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_MUX,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RSL_IE_IPAC_SPEECH_MODE, lower four bits */
 | 
				
			||||||
 | 
					enum rsl_ipac_speech_mode_s {
 | 
				
			||||||
 | 
						RSL_IPAC_SPEECH_GSM_FR = 0,	/* GSM FR (Type 1, FS) */
 | 
				
			||||||
 | 
						RSL_IPAC_SPEECH_GSM_EFR = 1,	/* GSM EFR (Type 2, FS) */
 | 
				
			||||||
 | 
						RSL_IPAC_SPEECH_GSM_AMR_FR = 2,	/* GSM AMR/FR (Type 3, FS) */
 | 
				
			||||||
 | 
						RSL_IPAC_SPEECH_GSM_HR = 3,	/* GSM HR (Type 1, HS) */
 | 
				
			||||||
 | 
						RSL_IPAC_SPEECH_GSM_AMR_HR = 5,	/* GSM AMR/hr (Type 3, HS) */
 | 
				
			||||||
 | 
						RSL_IPAC_SPEECH_AS_RTP = 0xf,	/* As specified by RTP Payload IE */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					/* RSL_IE_IPAC_SPEECH_MODE, upper four bits */
 | 
				
			||||||
 | 
					enum rsl_ipac_speech_mode_m {
 | 
				
			||||||
 | 
						RSL_IPAC_SPEECH_M_RXTX = 0,	/* Send and Receive */
 | 
				
			||||||
 | 
						RSL_IPAC_SPEECH_M_RX = 1,	/* Receive only */
 | 
				
			||||||
 | 
						RSL_IPAC_SPEECH_M_TX = 2,	/* Send only */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RSL_IE_IPAC_RTP_CSD_FMT, lower four bits */
 | 
				
			||||||
 | 
					enum rsl_ipac_rtp_csd_format_d {
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_CSD_EXT_TRAU = 0,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_CSD_NON_TRAU = 1,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_CSD_TRAU_BTS = 2,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_CSD_IWF_FREE = 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					/* RSL_IE_IPAC_RTP_CSD_FMT, upper four bits */
 | 
				
			||||||
 | 
					enum rsl_ipac_rtp_csd_format_ir {
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_CSD_IR_8k = 0,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_CSD_IR_16k = 1,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_CSD_IR_32k = 2,
 | 
				
			||||||
 | 
						RSL_IPAC_RTP_CSD_IR_64k = 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "msgb.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
 | 
					int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
 | 
				
			||||||
		  const u_int8_t *data, int len);
 | 
							  const u_int8_t *data, int len);
 | 
				
			||||||
@@ -52,6 +511,27 @@ int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id);
 | 
				
			|||||||
int rsl_relase_request(struct gsm_lchan *lchan, u_int8_t link_id);
 | 
					int rsl_relase_request(struct gsm_lchan *lchan, u_int8_t link_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Siemens vendor-specific RSL extensions */
 | 
					/* Siemens vendor-specific RSL extensions */
 | 
				
			||||||
 | 
					struct rsl_mrpci {
 | 
				
			||||||
 | 
						u_int8_t power_class:3,
 | 
				
			||||||
 | 
							 vgcs_capable:1,
 | 
				
			||||||
 | 
							 vbs_capable:1,
 | 
				
			||||||
 | 
							 gsm_phase:2;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum rsl_mrpci_pwrclass {
 | 
				
			||||||
 | 
						RSL_MRPCI_PWRC_1	= 0,
 | 
				
			||||||
 | 
						RSL_MRPCI_PWRC_2	= 1,
 | 
				
			||||||
 | 
						RSL_MRPCI_PWRC_3	= 2,
 | 
				
			||||||
 | 
						RSL_MRPCI_PWRC_4	= 3,
 | 
				
			||||||
 | 
						RSL_MRPCI_PWRC_5	= 4,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					enum rsl_mrpci_phase {
 | 
				
			||||||
 | 
						RSL_MRPCI_PHASE_1	= 0,
 | 
				
			||||||
 | 
						/* reserved */
 | 
				
			||||||
 | 
						RSL_MRPCI_PHASE_2	= 2,
 | 
				
			||||||
 | 
						RSL_MRPCI_PHASE_2PLUS	= 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
 | 
					int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ip.access specfic RSL extensions */
 | 
					/* ip.access specfic RSL extensions */
 | 
				
			||||||
@@ -59,7 +539,7 @@ int rsl_ipacc_crcx(struct gsm_lchan *lchan);
 | 
				
			|||||||
int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip,
 | 
					int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip,
 | 
				
			||||||
		   u_int16_t port, u_int8_t rtp_payload2);
 | 
							   u_int16_t port, u_int8_t rtp_payload2);
 | 
				
			||||||
int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan);
 | 
					int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan);
 | 
				
			||||||
int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan, int act);
 | 
					int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int abis_rsl_rcvmsg(struct msgb *msg);
 | 
					int abis_rsl_rcvmsg(struct msgb *msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -68,14 +548,12 @@ unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
 | 
				
			|||||||
unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res);
 | 
					unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res);
 | 
				
			||||||
u_int64_t str_to_imsi(const char *imsi_str);
 | 
					u_int64_t str_to_imsi(const char *imsi_str);
 | 
				
			||||||
u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
 | 
					u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
 | 
				
			||||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t reason);
 | 
					int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id);
 | 
				
			||||||
 | 
					 | 
				
			||||||
int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* to be provided by external code */
 | 
					/* to be provided by external code */
 | 
				
			||||||
int abis_rsl_sendmsg(struct msgb *msg);
 | 
					int abis_rsl_sendmsg(struct msgb *msg);
 | 
				
			||||||
int rsl_deact_sacch(struct gsm_lchan *lchan);
 | 
					int rsl_deact_sacch(struct gsm_lchan *lchan);
 | 
				
			||||||
int rsl_lchan_rll_release(struct gsm_lchan *lchan, u_int8_t link_id);
 | 
					int rsl_chan_release(struct gsm_lchan *lchan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* BCCH related code */
 | 
					/* BCCH related code */
 | 
				
			||||||
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
 | 
					int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
 | 
				
			||||||
@@ -85,9 +563,5 @@ int rsl_number_of_paging_subchannels(struct gsm_bts *bts);
 | 
				
			|||||||
int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db);
 | 
					int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db);
 | 
				
			||||||
int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm);
 | 
					int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SMSCB functionality */
 | 
					 | 
				
			||||||
int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
 | 
					 | 
				
			||||||
		       uint8_t cb_command, const uint8_t *data, int len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* RSL_MT_H */
 | 
					#endif /* RSL_MT_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
#ifndef _AUTH_H
 | 
					 | 
				
			||||||
#define _AUTH_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_auth_tuple;
 | 
					 | 
				
			||||||
struct gsm_subscriber;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple,
 | 
					 | 
				
			||||||
                              struct gsm_subscriber *subscr, int key_seq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _AUTH_H */
 | 
					 | 
				
			||||||
							
								
								
									
										65
									
								
								openbsc/include/openbsc/bitvec.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								openbsc/include/openbsc/bitvec.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					#ifndef _BITVEC_H
 | 
				
			||||||
 | 
					#define _BITVEC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* bit vector utility routines */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* In GSM mac blocks, every bit can be 0 or 1, or L or H.  L/H are
 | 
				
			||||||
 | 
					 * defined relative to the 0x2b padding pattern */
 | 
				
			||||||
 | 
					enum bit_value {
 | 
				
			||||||
 | 
						ZERO	= 0,
 | 
				
			||||||
 | 
						ONE	= 1,
 | 
				
			||||||
 | 
						L	= 2,
 | 
				
			||||||
 | 
						H	= 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bitvec {
 | 
				
			||||||
 | 
						unsigned int cur_bit;	/* curser to the next unused bit */
 | 
				
			||||||
 | 
						unsigned int data_len;	/* length of data array in bytes */
 | 
				
			||||||
 | 
						u_int8_t *data;		/* pointer to data array */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* check if the bit is 0 or 1 for a given position inside a bitvec */
 | 
				
			||||||
 | 
					enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* get the Nth set bit inside the bit vector */
 | 
				
			||||||
 | 
					unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set a bit at given position */
 | 
				
			||||||
 | 
					int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum,
 | 
				
			||||||
 | 
								enum bit_value bit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set the next bit in the vector */
 | 
				
			||||||
 | 
					int bitvec_set_bit(struct bitvec *bv, enum bit_value bit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set multiple bits at the current position */
 | 
				
			||||||
 | 
					int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add an unsigned integer (of length count bits) to current position */
 | 
				
			||||||
 | 
					int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Pad the bit vector up to a certain bit position */
 | 
				
			||||||
 | 
					int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* _BITVEC_H */
 | 
				
			||||||
@@ -1,38 +0,0 @@
 | 
				
			|||||||
/* GSM 08.08 like API for OpenBSC */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef OPENBSC_BSC_API_H
 | 
					 | 
				
			||||||
#define OPENBSC_BSC_API_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "gsm_data.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BSC_API_CONN_POL_ACCEPT	0
 | 
					 | 
				
			||||||
#define BSC_API_CONN_POL_REJECT	1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bsc_api {
 | 
					 | 
				
			||||||
	void (*sapi_n_reject)(struct gsm_subscriber_connection *conn, int dlci);
 | 
					 | 
				
			||||||
	void (*cipher_mode_compl)(struct gsm_subscriber_connection *conn,
 | 
					 | 
				
			||||||
				  struct msgb *msg, uint8_t chosen_encr);
 | 
					 | 
				
			||||||
	void (*cipher_mode_reject)(struct gsm_subscriber_connection *conn,
 | 
					 | 
				
			||||||
				  struct msgb *msg, uint16_t reason);
 | 
					 | 
				
			||||||
	int (*compl_l3)(struct gsm_subscriber_connection *conn,
 | 
					 | 
				
			||||||
			struct msgb *msg, uint16_t chosen_channel); 
 | 
					 | 
				
			||||||
	void (*dtap)(struct gsm_subscriber_connection *conn, struct msgb *msg);
 | 
					 | 
				
			||||||
	void (*assign_compl)(struct gsm_subscriber_connection *conn,
 | 
					 | 
				
			||||||
			  uint16_t rr_cause);
 | 
					 | 
				
			||||||
	void (*assign_fail)(struct gsm_subscriber_connection *conn,
 | 
					 | 
				
			||||||
			 uint16_t rr_cause);
 | 
					 | 
				
			||||||
	void (*clear_request)(struct gsm_subscriber_connection *conn,
 | 
					 | 
				
			||||||
			      uint32_t cause);
 | 
					 | 
				
			||||||
	void (*clear_compl)(struct gsm_subscriber_connection *conn);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bsc_api_init(struct gsm_network *network, struct bsc_api *api);
 | 
					 | 
				
			||||||
int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg, int link_id);
 | 
					 | 
				
			||||||
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_type, int audio);
 | 
					 | 
				
			||||||
int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
 | 
					 | 
				
			||||||
			uint8_t *key, int len);
 | 
					 | 
				
			||||||
int gsm0808_page(struct gsm_bts *bts, unsigned int page_group,
 | 
					 | 
				
			||||||
		 unsigned int mi_len, uint8_t *mi, int chan_type);
 | 
					 | 
				
			||||||
int gsm0808_clear(struct gsm_subscriber_connection *conn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/* Routines to talk to the MSC using the IPA Protocol */
 | 
					/* Routines to talk to the MSC using the IPA Protocol */
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 * (C) 2010 by On-Waves
 | 
					 * (C) 2010 by on-waves.com
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
@@ -23,30 +23,8 @@
 | 
				
			|||||||
#ifndef BSC_MSC_H
 | 
					#ifndef BSC_MSC_H
 | 
				
			||||||
#define BSC_MSC_H
 | 
					#define BSC_MSC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/write_queue.h>
 | 
					#include "select.h"
 | 
				
			||||||
#include <osmocore/timer.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct bsc_msc_connection {
 | 
					int connect_to_msc(struct bsc_fd *fd, const char *ip, int port);
 | 
				
			||||||
	struct write_queue write_queue;
 | 
					 | 
				
			||||||
	int is_connected;
 | 
					 | 
				
			||||||
	int is_authenticated;
 | 
					 | 
				
			||||||
	int first_contact;
 | 
					 | 
				
			||||||
	const char *ip;
 | 
					 | 
				
			||||||
	int port;
 | 
					 | 
				
			||||||
	int prio;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void (*connection_loss) (struct bsc_msc_connection *);
 | 
					 | 
				
			||||||
	void (*connected) (struct bsc_msc_connection *);
 | 
					 | 
				
			||||||
	struct timer_list reconnect_timer;
 | 
					 | 
				
			||||||
	struct timer_list timeout_timer;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bsc_msc_connection *bsc_msc_create(const char *ip, int port, int prio);
 | 
					 | 
				
			||||||
int bsc_msc_connect(struct bsc_msc_connection *);
 | 
					 | 
				
			||||||
void bsc_msc_schedule_connect(struct bsc_msc_connection *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void bsc_msc_lost(struct bsc_msc_connection *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct msgb *bsc_msc_id_get_resp(const char *token);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 * (C) 2010 by On-Waves
 | 
					 * (C) 2010 by on-waves.com
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
@@ -22,260 +22,12 @@
 | 
				
			|||||||
#ifndef BSC_NAT_H
 | 
					#ifndef BSC_NAT_H
 | 
				
			||||||
#define BSC_NAT_H
 | 
					#define BSC_NAT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "mgcp.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include "msgb.h"
 | 
				
			||||||
#include <osmocore/select.h>
 | 
					 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					 | 
				
			||||||
#include <osmocore/timer.h>
 | 
					 | 
				
			||||||
#include <osmocore/write_queue.h>
 | 
					 | 
				
			||||||
#include <osmocore/rate_ctr.h>
 | 
					 | 
				
			||||||
#include <osmocore/statistics.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <regex.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DIR_BSC 1
 | 
					 | 
				
			||||||
#define DIR_MSC 2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NAT_IPAC_PROTO_MGCP	0xfc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sccp_connections;
 | 
					 | 
				
			||||||
struct bsc_nat_parsed;
 | 
					 | 
				
			||||||
struct bsc_nat;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
	NAT_CON_TYPE_NONE,
 | 
					 | 
				
			||||||
	NAT_CON_TYPE_LU,
 | 
					 | 
				
			||||||
	NAT_CON_TYPE_CM_SERV_REQ,
 | 
					 | 
				
			||||||
	NAT_CON_TYPE_PAG_RESP,
 | 
					 | 
				
			||||||
	NAT_CON_TYPE_LOCAL_REJECT,
 | 
					 | 
				
			||||||
	NAT_CON_TYPE_OTHER,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Per BSC data structure
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct bsc_connection {
 | 
					 | 
				
			||||||
	struct llist_head list_entry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* do we know anything about this BSC? */
 | 
					 | 
				
			||||||
	int authenticated;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* the fd we use to communicate */
 | 
					 | 
				
			||||||
	struct write_queue write_queue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* the BSS associated */
 | 
					 | 
				
			||||||
	struct bsc_config *cfg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* a timeout node */
 | 
					 | 
				
			||||||
	struct timer_list id_timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* pong timeout */
 | 
					 | 
				
			||||||
	struct timer_list ping_timeout;
 | 
					 | 
				
			||||||
	struct timer_list pong_timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* a back pointer */
 | 
					 | 
				
			||||||
	struct bsc_nat *nat;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Stats per BSC
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct bsc_config_stats {
 | 
					 | 
				
			||||||
	struct rate_ctr_group *ctrg;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum bsc_cfg_ctr {
 | 
					 | 
				
			||||||
	BCFG_CTR_SCCP_CONN,
 | 
					 | 
				
			||||||
	BCFG_CTR_SCCP_CALLS,
 | 
					 | 
				
			||||||
	BCFG_CTR_NET_RECONN,
 | 
					 | 
				
			||||||
	BCFG_CTR_DROPPED_SCCP,
 | 
					 | 
				
			||||||
	BCFG_CTR_DROPPED_CALLS,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * One BSC entry in the config
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct bsc_config {
 | 
					 | 
				
			||||||
	struct llist_head entry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	char *token;
 | 
					 | 
				
			||||||
	unsigned int lac;
 | 
					 | 
				
			||||||
	int nr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	char *description;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* imsi white and blacklist */
 | 
					 | 
				
			||||||
	char *acc_lst_name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int forbid_paging;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* backpointer */
 | 
					 | 
				
			||||||
	struct bsc_nat *nat;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct bsc_config_stats stats;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * BSCs point of view of endpoints
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct bsc_endpoint {
 | 
					 | 
				
			||||||
	/* the pending transaction id */
 | 
					 | 
				
			||||||
	char *transaction_id;
 | 
					 | 
				
			||||||
	/* the bsc we are talking to */
 | 
					 | 
				
			||||||
	struct bsc_connection *bsc;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Statistic for the nat.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct bsc_nat_statistics {
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		struct counter *conn;
 | 
					 | 
				
			||||||
		struct counter *calls;
 | 
					 | 
				
			||||||
	} sccp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		struct counter *reconn;
 | 
					 | 
				
			||||||
                struct counter *auth_fail;
 | 
					 | 
				
			||||||
	} bsc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		struct counter *reconn;
 | 
					 | 
				
			||||||
	} msc;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bsc_nat_acc_lst {
 | 
					 | 
				
			||||||
	struct llist_head list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* the name of the list */
 | 
					 | 
				
			||||||
	const char *name;
 | 
					 | 
				
			||||||
	struct llist_head fltr_list;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bsc_nat_acc_lst_entry {
 | 
					 | 
				
			||||||
	struct llist_head list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* the filter */
 | 
					 | 
				
			||||||
	char *imsi_allow;
 | 
					 | 
				
			||||||
	regex_t imsi_allow_re;
 | 
					 | 
				
			||||||
	char *imsi_deny;
 | 
					 | 
				
			||||||
	regex_t imsi_deny_re;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * the structure of the "nat" network
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct bsc_nat {
 | 
					 | 
				
			||||||
	/* active SCCP connections that need patching */
 | 
					 | 
				
			||||||
	struct llist_head sccp_connections;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* active BSC connections that need patching */
 | 
					 | 
				
			||||||
	struct llist_head bsc_connections;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* access lists */
 | 
					 | 
				
			||||||
	struct llist_head access_lists;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* known BSC's */
 | 
					 | 
				
			||||||
	struct llist_head bsc_configs;
 | 
					 | 
				
			||||||
	int num_bsc;
 | 
					 | 
				
			||||||
	int bsc_ip_dscp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* MGCP config */
 | 
					 | 
				
			||||||
	struct mgcp_config *mgcp_cfg;
 | 
					 | 
				
			||||||
	struct write_queue mgcp_queue;
 | 
					 | 
				
			||||||
	uint8_t mgcp_msg[4096];
 | 
					 | 
				
			||||||
	int mgcp_length;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* msc things */
 | 
					 | 
				
			||||||
	char *msc_ip;
 | 
					 | 
				
			||||||
	int msc_port;
 | 
					 | 
				
			||||||
	struct bsc_msc_connection *msc_con;
 | 
					 | 
				
			||||||
	char *token;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* timeouts */
 | 
					 | 
				
			||||||
	int auth_timeout;
 | 
					 | 
				
			||||||
	int ping_timeout;
 | 
					 | 
				
			||||||
	int pong_timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct bsc_endpoint *bsc_endpoints;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* filter */
 | 
					 | 
				
			||||||
	char *acc_lst_name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* statistics */
 | 
					 | 
				
			||||||
	struct bsc_nat_statistics stats;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* create and init the structures */
 | 
					 | 
				
			||||||
struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token, unsigned int lac);
 | 
					 | 
				
			||||||
struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num);
 | 
					 | 
				
			||||||
struct bsc_nat *bsc_nat_alloc(void);
 | 
					 | 
				
			||||||
struct bsc_connection *bsc_connection_alloc(struct bsc_nat *nat);
 | 
					 | 
				
			||||||
void bsc_nat_set_msc_ip(struct bsc_nat *bsc, const char *ip);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void sccp_connection_destroy(struct sccp_connections *);
 | 
					 | 
				
			||||||
void bsc_close_connection(struct bsc_connection *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const char *bsc_con_type_to_string(int type);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * parse the given message into the above structure
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * filter based on IP Access header in both directions
 | 
					 * filter based on IP Access header in both directions
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed);
 | 
					int bsc_nat_filter_ipa(struct msgb *msg);
 | 
				
			||||||
int bsc_nat_vty_init(struct bsc_nat *nat);
 | 
					 | 
				
			||||||
struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg, int *_lac);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Content filtering.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg,
 | 
					 | 
				
			||||||
			   struct bsc_nat_parsed *, int *con_type);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * SCCP patching and handling
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct sccp_connections *create_sccp_src_ref(struct bsc_connection *bsc, struct bsc_nat_parsed *parsed);
 | 
					 | 
				
			||||||
int update_sccp_src_ref(struct sccp_connections *sccp, struct bsc_nat_parsed *parsed);
 | 
					 | 
				
			||||||
void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed);
 | 
					 | 
				
			||||||
struct sccp_connections *patch_sccp_src_ref_to_bsc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);
 | 
					 | 
				
			||||||
struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat_parsed *, struct bsc_connection *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * MGCP/Audio handling
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int bsc_write_mgcp(struct bsc_connection *bsc, const uint8_t *data, unsigned int length);
 | 
					 | 
				
			||||||
int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
 | 
					 | 
				
			||||||
void bsc_mgcp_init(struct sccp_connections *);
 | 
					 | 
				
			||||||
void bsc_mgcp_dlcx(struct sccp_connections *);
 | 
					 | 
				
			||||||
void bsc_mgcp_free_endpoints(struct bsc_nat *nat);
 | 
					 | 
				
			||||||
int bsc_mgcp_nat_init(struct bsc_nat *nat);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sccp_connections *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
 | 
					 | 
				
			||||||
struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port);
 | 
					 | 
				
			||||||
void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
 | 
					 | 
				
			||||||
int bsc_mgcp_parse_response(const char *str, int *code, char transaction[60]);
 | 
					 | 
				
			||||||
int bsc_mgcp_extract_ci(const char *resp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* IMSI allow/deny handling */
 | 
					 | 
				
			||||||
void bsc_parse_reg(void *ctx, regex_t *reg, char **imsi, int argc, const char **argv);
 | 
					 | 
				
			||||||
struct bsc_nat_acc_lst *bsc_nat_acc_lst_find(struct bsc_nat *nat, const char *name);
 | 
					 | 
				
			||||||
struct bsc_nat_acc_lst *bsc_nat_acc_lst_get(struct bsc_nat *nat, const char *name);
 | 
					 | 
				
			||||||
void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_lst *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bsc_nat_msc_is_connected(struct bsc_nat *nat);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,92 +0,0 @@
 | 
				
			|||||||
/* NAT utilities using SCCP types */
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 | 
				
			||||||
 * (C) 2010 by On-Waves
 | 
					 | 
				
			||||||
 * All Rights Reserved
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License along
 | 
					 | 
				
			||||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef BSC_NAT_SCCP_H
 | 
					 | 
				
			||||||
#define BSC_NAT_SCCP_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
#include <osmocom/sccp/sccp_types.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * For the NAT we will need to analyze and later patch
 | 
					 | 
				
			||||||
 * the received message. This would require us to parse
 | 
					 | 
				
			||||||
 * the IPA and SCCP header twice. Instead of doing this
 | 
					 | 
				
			||||||
 * we will have one analyze structure and have the patching
 | 
					 | 
				
			||||||
 * and filter operate on the same structure.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct bsc_nat_parsed {
 | 
					 | 
				
			||||||
	/* ip access prototype */
 | 
					 | 
				
			||||||
	int ipa_proto;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* source local reference */
 | 
					 | 
				
			||||||
	struct sccp_source_reference *src_local_ref;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* destination local reference */
 | 
					 | 
				
			||||||
	struct sccp_source_reference *dest_local_ref;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* called ssn number */
 | 
					 | 
				
			||||||
	int called_ssn;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* calling ssn number */
 | 
					 | 
				
			||||||
	int calling_ssn;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* sccp message type */
 | 
					 | 
				
			||||||
	int sccp_type;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* bssap type, e.g. 0 for BSS Management */
 | 
					 | 
				
			||||||
	int bssap;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* the gsm0808 message type */
 | 
					 | 
				
			||||||
	int gsm_type;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Per SCCP source local reference patch table. It needs to
 | 
					 | 
				
			||||||
 * be updated on new SCCP connections, connection confirm and reject,
 | 
					 | 
				
			||||||
 * and on the loss of the BSC connection.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct sccp_connections {
 | 
					 | 
				
			||||||
	struct llist_head list_entry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct bsc_connection *bsc;
 | 
					 | 
				
			||||||
	struct bsc_msc_connection *msc_con;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct sccp_source_reference real_ref;
 | 
					 | 
				
			||||||
	struct sccp_source_reference patched_ref;
 | 
					 | 
				
			||||||
	struct sccp_source_reference remote_ref;
 | 
					 | 
				
			||||||
	int has_remote_ref;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* status */
 | 
					 | 
				
			||||||
	int con_type;
 | 
					 | 
				
			||||||
	int con_local;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* GSM audio handling. That is 32 * multiplex + ts */
 | 
					 | 
				
			||||||
	int crcx;
 | 
					 | 
				
			||||||
	int msc_timeslot;
 | 
					 | 
				
			||||||
	int bsc_timeslot;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* timeout handling */
 | 
					 | 
				
			||||||
	struct timespec creation_time;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										334
									
								
								openbsc/include/openbsc/bssap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								openbsc/include/openbsc/bssap.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,334 @@
 | 
				
			|||||||
 | 
					/* From GSM08.08 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef BSSAP_H
 | 
				
			||||||
 | 
					#define BSSAP_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openbsc/msgb.h>
 | 
				
			||||||
 | 
					#include <openbsc/gsm_data.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * this is from GSM 03.03 CGI but is copied in GSM 08.08
 | 
				
			||||||
 | 
					 * in § 3.2.2.27 for Cell Identifier List
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum CELL_IDENT {
 | 
				
			||||||
 | 
						CELL_IDENT_WHOLE_GLOBAL		= 0,
 | 
				
			||||||
 | 
						CELL_IDENT_LAC_AND_CI		= 1,
 | 
				
			||||||
 | 
						CELL_IDENT_CI			= 2,
 | 
				
			||||||
 | 
						CELL_IDENT_NO_CELL		= 3,
 | 
				
			||||||
 | 
						CELL_IDENT_LAI_AND_LAC		= 4,
 | 
				
			||||||
 | 
						CELL_IDENT_LAC			= 5,
 | 
				
			||||||
 | 
						CELL_IDENT_BSS			= 6,
 | 
				
			||||||
 | 
						CELL_IDENT_UTRAN_PLMN_LAC_RNC	= 8,
 | 
				
			||||||
 | 
						CELL_IDENT_UTRAN_RNC		= 9,
 | 
				
			||||||
 | 
						CELL_IDENT_UTRAN_LAC_RNC	= 10,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 08.06 § 6.3 */
 | 
				
			||||||
 | 
					enum BSSAP_MSG_TYPE {
 | 
				
			||||||
 | 
						BSSAP_MSG_BSS_MANAGEMENT    = 0x0,
 | 
				
			||||||
 | 
						BSSAP_MSG_DTAP		    = 0x1,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bssmap_header {
 | 
				
			||||||
 | 
						u_int8_t type;
 | 
				
			||||||
 | 
						u_int8_t length;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dtap_header {
 | 
				
			||||||
 | 
						u_int8_t type;
 | 
				
			||||||
 | 
						u_int8_t link_id;
 | 
				
			||||||
 | 
						u_int8_t length;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum BSS_MAP_MSG_TYPE {
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESERVED_0		= 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ASSIGNMENT MESSAGES */
 | 
				
			||||||
 | 
						BSS_MAP_MSG_ASSIGMENT_RQST	= 1,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_ASSIGMENT_COMPLETE	= 2,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_ASSIGMENT_FAILURE	= 3,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*  HANDOVER MESSAGES */
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_RQST		= 16,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_REQUIRED		= 17,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE= 18,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_CMD		= 19,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_COMPLETE		= 20,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_SUCCEEDED		= 21,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_FAILURE		= 22,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_PERFORMED		= 23,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE	= 24,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE	= 25,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT	= 26,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_HANDOVER_DETECT		= 27,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* RELEASE MESSAGES */
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CLEAR_CMD		= 32,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CLEAR_COMPLETE		= 33,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CLEAR_RQST		= 34,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESERVED_1			= 35,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESERVED_2			= 36,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_SAPI_N_REJECT		= 37,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CONFUSION			= 38,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* OTHER CONNECTION RELATED MESSAGES */
 | 
				
			||||||
 | 
						BSS_MAP_MSG_SUSPEND			= 40,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESUME			= 41,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION = 42,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_PERFORM_LOCATION_RQST	= 43,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_LSA_INFORMATION		= 44,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE	= 45,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_PERFORM_LOCATION_ABORT	= 46,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_COMMON_ID			= 47,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* GENERAL MESSAGES */
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESET			= 48,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESET_ACKNOWLEDGE		= 49,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_OVERLOAD			= 50,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESERVED_3			= 51,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESET_CIRCUIT		= 52,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE	= 53,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_MSC_INVOKE_TRACE		= 54,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_BSS_INVOKE_TRACE		= 55,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CONNECTIONLESS_INFORMATION	= 58,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TERRESTRIAL RESOURCE MESSAGES */
 | 
				
			||||||
 | 
						BSS_MAP_MSG_BLOCK			= 64,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE	= 65,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UNBLOCK			= 66,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE	= 67,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK		= 68,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE	= 69,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK	= 70,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE = 71,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UNEQUIPPED_CIRCUIT		= 72,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CHANGE_CIRCUIT		= 78,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE	= 79,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* RADIO RESOURCE MESSAGES */
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESOURCE_RQST		= 80,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_RESOURCE_INDICATION		= 81,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_PAGING			= 82,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CIPHER_MODE_CMD		= 83,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CLASSMARK_UPDATE		= 84,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CIPHER_MODE_COMPLETE	= 85,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_QUEUING_INDICATION		= 86,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_COMPLETE_LAYER_3		= 87,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CLASSMARK_RQST		= 88,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_CIPHER_MODE_REJECT		= 89,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_LOAD_INDICATION		= 90,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* VGCS/VBS */
 | 
				
			||||||
 | 
						BSS_MAP_MSG_VGCS_VBS_SETUP		= 4,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_VGCS_VBS_SETUP_ACK		= 5,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE	= 6,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST	= 7,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT	= 28,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE	= 29,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION	= 30,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UPLINK_RQST		= 31,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UPLINK_RQST_ACKNOWLEDGE	= 39,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION	= 73,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UPLINK_RELEASE_INDICATION	= 74,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UPLINK_REJECT_CMD	= 75,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UPLINK_RELEASE_CMD	= 76,
 | 
				
			||||||
 | 
						BSS_MAP_MSG_UPLINK_SEIZED_CMD	= 77,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum GSM0808_IE_CODING {
 | 
				
			||||||
 | 
						GSM0808_IE_CIRCUIT_IDENTITY_CODE	= 1,
 | 
				
			||||||
 | 
						GSM0808_IE_RESERVED_0			= 2,
 | 
				
			||||||
 | 
						GSM0808_IE_RESOURCE_AVAILABLE		= 3,
 | 
				
			||||||
 | 
						GSM0808_IE_CAUSE			= 4,
 | 
				
			||||||
 | 
						GSM0808_IE_CELL_IDENTIFIER		= 5,
 | 
				
			||||||
 | 
						GSM0808_IE_PRIORITY			= 6,
 | 
				
			||||||
 | 
						GSM0808_IE_LAYER_3_HEADER_INFORMATION	= 7,
 | 
				
			||||||
 | 
						GSM0808_IE_IMSI				= 8,
 | 
				
			||||||
 | 
						GSM0808_IE_TMSI				= 9,
 | 
				
			||||||
 | 
						GSM0808_IE_ENCRYPTION_INFORMATION	= 10,
 | 
				
			||||||
 | 
						GSM0808_IE_CHANNEL_TYPE			= 11,
 | 
				
			||||||
 | 
						GSM0808_IE_PERIODICITY			= 12,
 | 
				
			||||||
 | 
						GSM0808_IE_EXTENDED_RESOURCE_INDICATOR	= 13,
 | 
				
			||||||
 | 
						GSM0808_IE_NUMBER_OF_MSS		= 14,
 | 
				
			||||||
 | 
						GSM0808_IE_RESERVED_1			= 15,
 | 
				
			||||||
 | 
						GSM0808_IE_RESERVED_2			= 16,
 | 
				
			||||||
 | 
						GSM0808_IE_RESERVED_3			= 17,
 | 
				
			||||||
 | 
						GSM0808_IE_CLASSMARK_INFORMATION_T2	= 18,
 | 
				
			||||||
 | 
						GSM0808_IE_CLASSMARK_INFORMATION_T3	= 19,
 | 
				
			||||||
 | 
						GSM0808_IE_INTERFERENCE_BAND_TO_USE	= 20,
 | 
				
			||||||
 | 
						GSM0808_IE_RR_CAUSE			= 21,
 | 
				
			||||||
 | 
						GSM0808_IE_RESERVED_4			= 22,
 | 
				
			||||||
 | 
						GSM0808_IE_LAYER_3_INFORMATION		= 23,
 | 
				
			||||||
 | 
						GSM0808_IE_DLCI				= 24,
 | 
				
			||||||
 | 
						GSM0808_IE_DOWNLINK_DTX_FLAG		= 25,
 | 
				
			||||||
 | 
						GSM0808_IE_CELL_IDENTIFIER_LIST		= 26,
 | 
				
			||||||
 | 
						GSM0808_IE_RESPONSE_RQST		= 27,
 | 
				
			||||||
 | 
						GSM0808_IE_RESOURCE_INDICATION_METHOD	= 28,
 | 
				
			||||||
 | 
						GSM0808_IE_CLASSMARK_INFORMATION_TYPE_1	= 29,
 | 
				
			||||||
 | 
						GSM0808_IE_CIRCUIT_IDENTITY_CODE_LIST	= 30,
 | 
				
			||||||
 | 
						GSM0808_IE_DIAGNOSTIC			= 31,
 | 
				
			||||||
 | 
						GSM0808_IE_LAYER_3_MESSAGE_CONTENTS	= 32,
 | 
				
			||||||
 | 
						GSM0808_IE_CHOSEN_CHANNEL		= 33,
 | 
				
			||||||
 | 
						GSM0808_IE_TOTAL_RESOURCE_ACCESSIBLE	= 34,
 | 
				
			||||||
 | 
						GSM0808_IE_CIPHER_RESPONSE_MODE		= 35,
 | 
				
			||||||
 | 
						GSM0808_IE_CHANNEL_NEEDED		= 36,
 | 
				
			||||||
 | 
						GSM0808_IE_TRACE_TYPE			= 37,
 | 
				
			||||||
 | 
						GSM0808_IE_TRIGGERID			= 38,
 | 
				
			||||||
 | 
						GSM0808_IE_TRACE_REFERENCE		= 39,
 | 
				
			||||||
 | 
						GSM0808_IE_TRANSACTIONID		= 40,
 | 
				
			||||||
 | 
						GSM0808_IE_MOBILE_IDENTITY		= 41,
 | 
				
			||||||
 | 
						GSM0808_IE_OMCID			= 42,
 | 
				
			||||||
 | 
						GSM0808_IE_FORWARD_INDICATOR		= 43,
 | 
				
			||||||
 | 
						GSM0808_IE_CHOSEN_ENCR_ALG		= 44,
 | 
				
			||||||
 | 
						GSM0808_IE_CIRCUIT_POOL			= 45,
 | 
				
			||||||
 | 
						GSM0808_IE_CIRCUIT_POOL_LIST		= 46,
 | 
				
			||||||
 | 
						GSM0808_IE_TIME_INDICATION		= 47,
 | 
				
			||||||
 | 
						GSM0808_IE_RESOURCE_SITUATION		= 48,
 | 
				
			||||||
 | 
						GSM0808_IE_CURRENT_CHANNEL_TYPE_1	= 49,
 | 
				
			||||||
 | 
						GSM0808_IE_QUEUEING_INDICATOR		= 50,
 | 
				
			||||||
 | 
						GSM0808_IE_SPEECH_VERSION		= 64,
 | 
				
			||||||
 | 
						GSM0808_IE_ASSIGNMENT_REQUIREMENT	= 51,
 | 
				
			||||||
 | 
						GSM0808_IE_TALKER_FLAG			= 53,
 | 
				
			||||||
 | 
						GSM0808_IE_CONNECTION_RELEASE_RQSTED	= 54,
 | 
				
			||||||
 | 
						GSM0808_IE_GROUP_CALL_REFERENCE		= 55,
 | 
				
			||||||
 | 
						GSM0808_IE_EMLPP_PRIORITY		= 56,
 | 
				
			||||||
 | 
						GSM0808_IE_CONFIG_EVO_INDI		= 57,
 | 
				
			||||||
 | 
						GSM0808_IE_OLD_BSS_TO_NEW_BSS_INFORMATION	= 58,
 | 
				
			||||||
 | 
						GSM0808_IE_LSA_IDENTIFIER		= 59,
 | 
				
			||||||
 | 
						GSM0808_IE_LSA_IDENTIFIER_LIST		= 60,
 | 
				
			||||||
 | 
						GSM0808_IE_LSA_INFORMATION		= 61,
 | 
				
			||||||
 | 
						GSM0808_IE_LCS_QOS			= 62,
 | 
				
			||||||
 | 
						GSM0808_IE_LSA_ACCESS_CTRL_SUPPR	= 63,
 | 
				
			||||||
 | 
						GSM0808_IE_LCS_PRIORITY			= 67,
 | 
				
			||||||
 | 
						GSM0808_IE_LOCATION_TYPE		= 68,
 | 
				
			||||||
 | 
						GSM0808_IE_LOCATION_ESTIMATE		= 69,
 | 
				
			||||||
 | 
						GSM0808_IE_POSITIONING_DATA		= 70,
 | 
				
			||||||
 | 
						GSM0808_IE_LCS_CAUSE			= 71,
 | 
				
			||||||
 | 
						GSM0808_IE_LCS_CLIENT_TYPE		= 72,
 | 
				
			||||||
 | 
						GSM0808_IE_APDU				= 73,
 | 
				
			||||||
 | 
						GSM0808_IE_NETWORK_ELEMENT_IDENTITY	= 74,
 | 
				
			||||||
 | 
						GSM0808_IE_GPS_ASSISTANCE_DATA		= 75,
 | 
				
			||||||
 | 
						GSM0808_IE_DECIPHERING_KEYS		= 76,
 | 
				
			||||||
 | 
						GSM0808_IE_RETURN_ERROR_RQST		= 77,
 | 
				
			||||||
 | 
						GSM0808_IE_RETURN_ERROR_CAUSE		= 78,
 | 
				
			||||||
 | 
						GSM0808_IE_SEGMENTATION			= 79,
 | 
				
			||||||
 | 
						GSM0808_IE_SERVICE_HANDOVER		= 80,
 | 
				
			||||||
 | 
						GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_UMTS	= 81,
 | 
				
			||||||
 | 
						GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_CDMA2000= 82,
 | 
				
			||||||
 | 
						GSM0808_IE_RESERVED_5			= 65,
 | 
				
			||||||
 | 
						GSM0808_IE_RESERVED_6			= 66,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsm0808_cause {
 | 
				
			||||||
 | 
						GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE			= 0,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_RADIO_INTERFACE_FAILURE				= 1,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_UPLINK_QUALITY					= 2,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_UPLINK_STRENGTH					= 3,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_DOWNLINK_QUALITY					= 4,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_DOWNLINK_STRENGTH					= 5,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_DISTANCE						= 6,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_O_AND_M_INTERVENTION				= 7,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_RESPONSE_TO_MSC_INVOCATION			= 8,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_CALL_CONTROL					= 9,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION			= 10,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_HANDOVER_SUCCESSFUL				= 11,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_BETTER_CELL					= 12,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_DIRECTED_RETRY					= 13,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_JOINED_GROUP_CALL_CHANNEL				= 14,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_TRAFFIC						= 15,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_EQUIPMENT_FAILURE					= 32,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE			= 33,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE	= 34,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_CCCH_OVERLOAD					= 35,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_PROCESSOR_OVERLOAD				= 36,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_BSS_NOT_EQUIPPED					= 37,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_MS_NOT_EQUIPPED					= 38,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_INVALID_CELL					= 39,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_TRAFFIC_LOAD					= 40,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_PREEMPTION					= 41,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_RQSTED_TRANSCODING_RATE_ADAPTION_UNAVAILABLE	= 48,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_CIRCUIT_POOL_MISMATCH				= 49,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_SWITCH_CIRCUIT_POOL				= 50,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_RQSTED_SPEECH_VERSION_UNAVAILABLE		= 51,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_LSA_NOT_ALLOWED					= 52,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED			= 64,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_TERRESTRIAL_CIRCUIT_ALREADY_ALLOCATED		= 80,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS				= 81,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING		= 82,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_INCORRECT_VALUE					= 83,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_UNKNOWN_MESSAGE_TYPE				= 84,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_UNKNOWN_INFORMATION_ELEMENT			= 85,
 | 
				
			||||||
 | 
						GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC		= 96,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 08.08 3.2.2.11 Channel Type */
 | 
				
			||||||
 | 
					enum gsm0808_chan_indicator {
 | 
				
			||||||
 | 
						GSM0808_CHAN_SPEECH = 1,
 | 
				
			||||||
 | 
						GSM0808_CHAN_DATA   = 2,
 | 
				
			||||||
 | 
						GSM0808_CHAN_SIGN   = 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsm0808_chan_rate_type_data {
 | 
				
			||||||
 | 
						GSM0808_DATA_FULL_BM	= 0x8,
 | 
				
			||||||
 | 
						GSM0808_DATA_HALF_LM	= 0x9,
 | 
				
			||||||
 | 
						GSM0808_DATA_FULL_RPREF	= 0xa,
 | 
				
			||||||
 | 
						GSM0808_DATA_HALF_PREF	= 0xb,
 | 
				
			||||||
 | 
						GSM0808_DATA_FULL_PREF_NO_CHANGE	= 0x1a,
 | 
				
			||||||
 | 
						GSM0808_DATA_HALF_PREF_NO_CHANGE	= 0x1b,
 | 
				
			||||||
 | 
						GSM0808_DATA_MULTI_MASK	= 0x20,
 | 
				
			||||||
 | 
						GSM0808_DATA_MULTI_MASK_NO_CHANGE	= 0x30,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsm0808_chan_rate_type_speech {
 | 
				
			||||||
 | 
						GSM0808_SPEECH_FULL_BM	= 0x8,
 | 
				
			||||||
 | 
						GSM0808_SPEECH_HALF_LM	= 0x9,
 | 
				
			||||||
 | 
						GSM0808_SPEECH_FULL_PREF= 0xa,
 | 
				
			||||||
 | 
						GSM0808_SPEECH_HALF_PREF= 0xb,
 | 
				
			||||||
 | 
						GSM0808_SPEECH_FULL_PREF_NO_CHANGE	= 0x1a,
 | 
				
			||||||
 | 
						GSM0808_SPEECH_HALF_PREF_NO_CHANGE	= 0x1b,
 | 
				
			||||||
 | 
						GSM0808_SPEECH_PERM	= 0xf,
 | 
				
			||||||
 | 
						GSM0808_SPEECH_PERM_NO_CHANGE = 0x1f,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsm0808_permitted_speech {
 | 
				
			||||||
 | 
						GSM0808_PERM_FR1	= 0x01,
 | 
				
			||||||
 | 
						GSM0808_PERM_FR2	= 0x11,
 | 
				
			||||||
 | 
						GSM0808_PERM_FR3	= 0x21,
 | 
				
			||||||
 | 
						GSM0808_PERM_HR1	= GSM0808_PERM_FR1 | 0x4,
 | 
				
			||||||
 | 
						GSM0808_PERM_HR2	= GSM0808_PERM_FR2 | 0x4,
 | 
				
			||||||
 | 
						GSM0808_PERM_HR3	= GSM0808_PERM_FR3 | 0x4,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int bssmap_rcvmsg_dt1(struct sccp_connection *conn, struct msgb *msg, unsigned int length);
 | 
				
			||||||
 | 
					int bssmap_rcvmsg_udt(struct gsm_network *net, struct msgb *msg, unsigned int length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct msgb *bssmap_create_layer3(struct msgb *msg);
 | 
				
			||||||
 | 
					struct msgb *bssmap_create_reset(void);
 | 
				
			||||||
 | 
					struct msgb *bssmap_create_clear_complete(void);
 | 
				
			||||||
 | 
					struct msgb *bssmap_create_cipher_complete(struct msgb *layer3);
 | 
				
			||||||
 | 
					struct msgb *bssmap_create_cipher_reject(u_int8_t cause);
 | 
				
			||||||
 | 
					struct msgb *bssmap_create_sapi_reject(u_int8_t link_id);
 | 
				
			||||||
 | 
					struct msgb *bssmap_create_assignment_completed(struct gsm_lchan *lchan, u_int8_t rr_cause);
 | 
				
			||||||
 | 
					struct msgb *bssmap_create_assignment_failure(u_int8_t cause, u_int8_t *rr_cause);
 | 
				
			||||||
 | 
					struct msgb *bssmap_create_classmark_update(const u_int8_t *classmark, u_int8_t length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void gsm0808_send_assignment_failure(struct gsm_lchan *l, u_int8_t cause, u_int8_t *rr_value);
 | 
				
			||||||
 | 
					void gsm0808_send_assignment_compl(struct gsm_lchan *l, u_int8_t rr_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int dtap_rcvmsg(struct gsm_lchan *lchan, struct msgb *msg, unsigned int length);
 | 
				
			||||||
 | 
					struct msgb *dtap_create_msg(struct msgb *msg_l3, u_int8_t link_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bsc_queue_connection_write(struct sccp_connection *conn, struct msgb *msg);
 | 
				
			||||||
 | 
					void bsc_free_queued(struct sccp_connection *conn);
 | 
				
			||||||
 | 
					void bsc_send_queued(struct sccp_connection *conn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bts_queue_send(struct msgb *msg, int link_id);
 | 
				
			||||||
 | 
					void bts_send_queued(struct bss_sccp_connection_data*);
 | 
				
			||||||
 | 
					void bts_free_queued(struct bss_sccp_connection_data*);
 | 
				
			||||||
 | 
					void bts_unblock_queue(struct bss_sccp_connection_data*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -23,7 +23,27 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "gsm_subscriber.h"
 | 
					#include "gsm_subscriber.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_subscriber_connection;
 | 
					/*
 | 
				
			||||||
 | 
					 * Refcounting for the lchan. If the refcount drops to zero
 | 
				
			||||||
 | 
					 * the channel will send a RSL release request.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define use_lchan(lchan) \
 | 
				
			||||||
 | 
						do {	lchan->use_count++; \
 | 
				
			||||||
 | 
							DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
 | 
				
			||||||
 | 
								lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
 | 
				
			||||||
 | 
								lchan->nr, lchan->use_count); \
 | 
				
			||||||
 | 
						} while(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define put_lchan(lchan) \
 | 
				
			||||||
 | 
						do { lchan->use_count--; \
 | 
				
			||||||
 | 
							DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
 | 
				
			||||||
 | 
								lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
 | 
				
			||||||
 | 
								lchan->nr, lchan->use_count); \
 | 
				
			||||||
 | 
						    if (lchan->use_count <= 0) \
 | 
				
			||||||
 | 
							_lchan_release(lchan); \
 | 
				
			||||||
 | 
						} while(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Special allocator for C0 of BTS */
 | 
					/* Special allocator for C0 of BTS */
 | 
				
			||||||
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
 | 
					struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
 | 
				
			||||||
@@ -36,31 +56,19 @@ struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts,
 | 
				
			|||||||
/* Regular physical channel (TS) */
 | 
					/* Regular physical channel (TS) */
 | 
				
			||||||
void ts_free(struct gsm_bts_trx_ts *ts);
 | 
					void ts_free(struct gsm_bts_trx_ts *ts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Find an allocated channel */
 | 
				
			||||||
 | 
					struct gsm_lchan *lchan_find(struct gsm_bts *bts, struct gsm_subscriber *subscr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Find an allocated channel for a specified subscriber */
 | 
					/* Find an allocated channel for a specified subscriber */
 | 
				
			||||||
struct gsm_subscriber_connection *connection_for_subscr(struct gsm_subscriber *subscr);
 | 
					struct gsm_lchan *lchan_for_subscr(struct gsm_subscriber *subscr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Allocate a logical channel (SDCCH, TCH, ...) */
 | 
					/* Allocate a logical channel (SDCCH, TCH, ...) */
 | 
				
			||||||
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
 | 
					struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Free a logical channel (SDCCH, TCH, ...) */
 | 
					/* Free a logical channel (SDCCH, TCH, ...) */
 | 
				
			||||||
void lchan_free(struct gsm_lchan *lchan);
 | 
					void lchan_free(struct gsm_lchan *lchan);
 | 
				
			||||||
void lchan_reset(struct gsm_lchan *lchan);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Release the given lchan */
 | 
					/* internal.. do not use */
 | 
				
			||||||
int lchan_release(struct gsm_lchan *lchan, int sach_deact, int reason);
 | 
					int _lchan_release(struct gsm_lchan *lchan);
 | 
				
			||||||
 | 
					 | 
				
			||||||
struct load_counter {
 | 
					 | 
				
			||||||
	unsigned int total;
 | 
					 | 
				
			||||||
	unsigned int used;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct pchan_load {
 | 
					 | 
				
			||||||
	struct load_counter pchan[GSM_PCHAN_UNKNOWN];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts);
 | 
					 | 
				
			||||||
void network_chan_load(struct pchan_load *pl, struct gsm_network *net);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int trx_is_usable(struct gsm_bts_trx *trx);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _CHAN_ALLOC_H */
 | 
					#endif /* _CHAN_ALLOC_H */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
#ifndef _CRC24_H
 | 
					 | 
				
			||||||
#define _CRC24_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define INIT_CRC24	0xffffff
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
u_int32_t crc24_calc(u_int32_t fcs, u_int8_t *cp, unsigned int len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -43,20 +43,9 @@ int db_subscriber_alloc_token(struct gsm_subscriber* subscriber, u_int32_t* toke
 | 
				
			|||||||
int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char *imei);
 | 
					int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char *imei);
 | 
				
			||||||
int db_sync_equipment(struct gsm_equipment *equip);
 | 
					int db_sync_equipment(struct gsm_equipment *equip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* auth info */
 | 
					 | 
				
			||||||
int db_get_authinfo_for_subscr(struct gsm_auth_info *ainfo,
 | 
					 | 
				
			||||||
                               struct gsm_subscriber *subscr);
 | 
					 | 
				
			||||||
int db_sync_authinfo_for_subscr(struct gsm_auth_info *ainfo,
 | 
					 | 
				
			||||||
                                struct gsm_subscriber *subscr);
 | 
					 | 
				
			||||||
int db_get_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple,
 | 
					 | 
				
			||||||
                                    struct gsm_subscriber *subscr);
 | 
					 | 
				
			||||||
int db_sync_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple,
 | 
					 | 
				
			||||||
                                     struct gsm_subscriber *subscr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SMS store-and-forward */
 | 
					/* SMS store-and-forward */
 | 
				
			||||||
int db_sms_store(struct gsm_sms *sms);
 | 
					int db_sms_store(struct gsm_sms *sms);
 | 
				
			||||||
struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, unsigned long long min_id);
 | 
					struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_id);
 | 
				
			||||||
struct gsm_sms *db_sms_get_unsent_by_subscr(struct gsm_network *net, unsigned long long min_subscr_id);
 | 
					 | 
				
			||||||
struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr);
 | 
					struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr);
 | 
				
			||||||
int db_sms_mark_sent(struct gsm_sms *sms);
 | 
					int db_sms_mark_sent(struct gsm_sms *sms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,11 +53,4 @@ int db_sms_mark_sent(struct gsm_sms *sms);
 | 
				
			|||||||
int db_apdu_blob_store(struct gsm_subscriber *subscr, 
 | 
					int db_apdu_blob_store(struct gsm_subscriber *subscr, 
 | 
				
			||||||
			u_int8_t apdu_id_flags, u_int8_t len,
 | 
								u_int8_t apdu_id_flags, u_int8_t len,
 | 
				
			||||||
			u_int8_t *apdu);
 | 
								u_int8_t *apdu);
 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Statistics counter storage */
 | 
					 | 
				
			||||||
struct counter;
 | 
					 | 
				
			||||||
int db_store_counter(struct counter *ctr);
 | 
					 | 
				
			||||||
struct rate_ctr_group;
 | 
					 | 
				
			||||||
int db_store_rate_ctr_group(struct rate_ctr_group *ctrg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _DB_H */
 | 
					#endif /* _DB_H */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,70 +1,58 @@
 | 
				
			|||||||
#ifndef _DEBUG_H
 | 
					#ifndef _DEBUG_H
 | 
				
			||||||
#define _DEBUG_H
 | 
					#define _DEBUG_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DEBUG
 | 
					#define DEBUG
 | 
				
			||||||
#include <osmocore/logging.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Debug Areas of the code */
 | 
					#define DRLL		0x0001
 | 
				
			||||||
enum {
 | 
					#define DCC		0x0002
 | 
				
			||||||
	DRLL,
 | 
					#define DMM		0x0004
 | 
				
			||||||
	DCC,
 | 
					#define DRR		0x0008
 | 
				
			||||||
	DMM,
 | 
					#define DRSL		0x0010
 | 
				
			||||||
	DRR,
 | 
					#define DNM		0x0020
 | 
				
			||||||
	DRSL,
 | 
					 | 
				
			||||||
	DNM,
 | 
					 | 
				
			||||||
	DMNCC,
 | 
					 | 
				
			||||||
	DSMS,
 | 
					 | 
				
			||||||
	DPAG,
 | 
					 | 
				
			||||||
	DMEAS,
 | 
					 | 
				
			||||||
	DMI,
 | 
					 | 
				
			||||||
	DMIB,
 | 
					 | 
				
			||||||
	DMUX,
 | 
					 | 
				
			||||||
	DINP,
 | 
					 | 
				
			||||||
	DSCCP,
 | 
					 | 
				
			||||||
	DMSC,
 | 
					 | 
				
			||||||
	DMGCP,
 | 
					 | 
				
			||||||
	DHO,
 | 
					 | 
				
			||||||
	DDB,
 | 
					 | 
				
			||||||
	DREF,
 | 
					 | 
				
			||||||
	DGPRS,
 | 
					 | 
				
			||||||
	DNS,
 | 
					 | 
				
			||||||
	DBSSGP,
 | 
					 | 
				
			||||||
	DLLC,
 | 
					 | 
				
			||||||
	DSNDCP,
 | 
					 | 
				
			||||||
	DNAT,
 | 
					 | 
				
			||||||
	Debug_LastEntry,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* context */
 | 
					#define DMNCC		0x0080
 | 
				
			||||||
#define BSC_CTX_LCHAN	0
 | 
					#define DSMS		0x0100
 | 
				
			||||||
#define BSC_CTX_SUBSCR	1
 | 
					#define DPAG		0x0200
 | 
				
			||||||
#define BSC_CTX_BTS	2
 | 
					#define DMEAS		0x0400
 | 
				
			||||||
#define BSC_CTX_SCCP	3
 | 
					 | 
				
			||||||
#define BSC_CTX_NSVC	4
 | 
					 | 
				
			||||||
#define BSC_CTX_BVC	5
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* target */
 | 
					#define DMI		0x1000
 | 
				
			||||||
 | 
					#define DMIB		0x2000
 | 
				
			||||||
 | 
					#define DMUX		0x4000
 | 
				
			||||||
 | 
					#define DINP		0x8000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					#define DSCCP		0x10000
 | 
				
			||||||
	//DEBUG_FILTER_ALL = 1 << 0,
 | 
					#define DMSC		0x20000
 | 
				
			||||||
	LOG_FILTER_IMSI = 1 << 1,
 | 
					 | 
				
			||||||
	LOG_FILTER_NSVC = 1 << 2,
 | 
					 | 
				
			||||||
	LOG_FILTER_BVC  = 1 << 3,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* we don't need a header dependency for this... */
 | 
					#define DMGCP		0x40000
 | 
				
			||||||
struct gprs_nsvc;
 | 
					 | 
				
			||||||
struct bssgp_bvc_ctx;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void log_set_imsi_filter(struct log_target *target, const char *imsi);
 | 
					#define DHO		0x80000
 | 
				
			||||||
void log_set_nsvc_filter(struct log_target *target,
 | 
					 | 
				
			||||||
			 struct gprs_nsvc *nsvc);
 | 
					 | 
				
			||||||
void log_set_bvc_filter(struct log_target *target,
 | 
					 | 
				
			||||||
			struct bssgp_bvc_ctx *bctx);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const struct log_info log_info;
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					#define DEBUGP(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ## args)
 | 
				
			||||||
 | 
					#define DEBUGPC(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ## args)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define DEBUGP(xss, fmt, args...) 
 | 
				
			||||||
 | 
					#define DEBUGPC(ss, fmt, args...)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *hexdump(const unsigned char *buf, int len);
 | 
				
			||||||
 | 
					void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
 | 
				
			||||||
 | 
					void debug_parse_category_mask(const char* mask);
 | 
				
			||||||
 | 
					void debug_use_color(int use_color);
 | 
				
			||||||
 | 
					void debug_timestamp(int enable);
 | 
				
			||||||
 | 
					extern unsigned int debug_mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* new logging interface */
 | 
				
			||||||
 | 
					#define LOGP(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ##args)
 | 
				
			||||||
 | 
					#define LOGPC(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ##args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* different levels */
 | 
				
			||||||
 | 
					#define LOGL_DEBUG	1	/* debugging information */
 | 
				
			||||||
 | 
					#define LOGL_INFO	3
 | 
				
			||||||
 | 
					#define LOGL_NOTICE	5	/* abnormal/unexpected condition */
 | 
				
			||||||
 | 
					#define LOGL_ERROR	7	/* error condition, requires user action */
 | 
				
			||||||
 | 
					#define LOGL_FATAL	8	/* fatal, program aborted */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _DEBUG_H */
 | 
					#endif /* _DEBUG_H */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,10 +4,10 @@
 | 
				
			|||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					#include <openbsc/linuxlist.h>
 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					#include <openbsc/gsm_data.h>
 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					#include <openbsc/msgb.h>
 | 
				
			||||||
#include <osmocore/select.h>
 | 
					#include <openbsc/select.h>
 | 
				
			||||||
#include <openbsc/subchan_demux.h>
 | 
					#include <openbsc/subchan_demux.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NUM_E1_TS   32
 | 
					#define NUM_E1_TS   32
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,39 +0,0 @@
 | 
				
			|||||||
#ifndef _GB_PROXY_H
 | 
					 | 
				
			||||||
#define _GB_PROXY_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <openbsc/gprs_ns.h>
 | 
					 | 
				
			||||||
#include <osmocom/vty/command.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gbproxy_config {
 | 
					 | 
				
			||||||
	/* parsed from config file */
 | 
					 | 
				
			||||||
	u_int16_t nsip_sgsn_nsei;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* misc */
 | 
					 | 
				
			||||||
	struct gprs_ns_inst *nsi;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern struct gbproxy_config gbcfg;
 | 
					 | 
				
			||||||
extern struct cmd_element show_gbproxy_cmd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* gb_proxy_vty .c */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gbproxy_vty_init(void);
 | 
					 | 
				
			||||||
int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* gb_proxy.c */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Main input function for Gb proxy */
 | 
					 | 
				
			||||||
int gbprox_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gbprox_signal(unsigned int subsys, unsigned int signal,
 | 
					 | 
				
			||||||
		  void *handler_data, void *signal_data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Reset all persistent NS-VC's */
 | 
					 | 
				
			||||||
int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,232 +0,0 @@
 | 
				
			|||||||
#ifndef _GPRS_BSSGP_H
 | 
					 | 
				
			||||||
#define _GPRS_BSSGP_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 5.4.1 */
 | 
					 | 
				
			||||||
#define BVCI_SIGNALLING	0x0000
 | 
					 | 
				
			||||||
#define BVCI_PTM	0x0001
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 11.3.26 / Table 11.27 */
 | 
					 | 
				
			||||||
enum bssgp_pdu_type {
 | 
					 | 
				
			||||||
	/* PDUs between RL and BSSGP SAPs */
 | 
					 | 
				
			||||||
	BSSGP_PDUT_DL_UNITDATA		= 0x00,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_UL_UNITDATA		= 0x01,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_RA_CAPABILITY	= 0x02,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_PTM_UNITDATA		= 0x03,
 | 
					 | 
				
			||||||
	/* PDUs between GMM SAPs */
 | 
					 | 
				
			||||||
	BSSGP_PDUT_PAGING_PS		= 0x06,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_PAGING_CS		= 0x07,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_RA_CAPA_UDPATE	= 0x08,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_RA_CAPA_UPDATE_ACK	= 0x09,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_RADIO_STATUS		= 0x0a,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_SUSPEND		= 0x0b,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_SUSPEND_ACK		= 0x0c,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_SUSPEND_NACK		= 0x0d,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_RESUME		= 0x0e,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_RESUME_ACK		= 0x0f,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_RESUME_NACK		= 0x10,
 | 
					 | 
				
			||||||
	/* PDus between NM SAPs */
 | 
					 | 
				
			||||||
	BSSGP_PDUT_BVC_BLOCK		= 0x20,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_BVC_BLOCK_ACK	= 0x21,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_BVC_RESET		= 0x22,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_BVC_RESET_ACK	= 0x23,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_BVC_UNBLOCK		= 0x24,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_BVC_UNBLOCK_ACK	= 0x25,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_FLOW_CONTROL_BVC	= 0x26,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_FLOW_CONTROL_BVC_ACK	= 0x27,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_FLOW_CONTROL_MS	= 0x28,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_FLOW_CONTROL_MS_ACK	= 0x29,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_FLUSH_LL		= 0x2a,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_FLUSH_LL_ACK		= 0x2b,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_LLC_DISCARD		= 0x2c,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_SGSN_INVOKE_TRACE	= 0x40,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_STATUS		= 0x41,
 | 
					 | 
				
			||||||
	/* PDUs between PFM SAP's */
 | 
					 | 
				
			||||||
	BSSGP_PDUT_DOWNLOAD_BSS_PFC	= 0x50,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_CREATE_BSS_PFC	= 0x51,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_CREATE_BSS_PFC_ACK	= 0x52,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_CREATE_BSS_PFC_NACK	= 0x53,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_MODIFY_BSS_PFC	= 0x54,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_MODIFY_BSS_PFC_ACK	= 0x55,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_DELETE_BSS_PFC	= 0x56,
 | 
					 | 
				
			||||||
	BSSGP_PDUT_DELETE_BSS_PFC_ACK	= 0x57,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 10.2.1 and 10.2.2 */
 | 
					 | 
				
			||||||
struct bssgp_ud_hdr {
 | 
					 | 
				
			||||||
	uint8_t pdu_type;
 | 
					 | 
				
			||||||
	uint32_t tlli;
 | 
					 | 
				
			||||||
	uint8_t qos_profile[3];
 | 
					 | 
				
			||||||
	uint8_t data[0];	/* TLV's */
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bssgp_normal_hdr {
 | 
					 | 
				
			||||||
	uint8_t pdu_type;
 | 
					 | 
				
			||||||
	uint8_t data[0];	/* TLV's */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum bssgp_iei_type {
 | 
					 | 
				
			||||||
	BSSGP_IE_ALIGNMENT		= 0x00,
 | 
					 | 
				
			||||||
	BSSGP_IE_BMAX_DEFAULT_MS	= 0x01,
 | 
					 | 
				
			||||||
	BSSGP_IE_BSS_AREA_ID		= 0x02,
 | 
					 | 
				
			||||||
	BSSGP_IE_BUCKET_LEAK_RATE	= 0x03,
 | 
					 | 
				
			||||||
	BSSGP_IE_BVCI			= 0x04,
 | 
					 | 
				
			||||||
	BSSGP_IE_BVC_BUCKET_SIZE	= 0x05,
 | 
					 | 
				
			||||||
	BSSGP_IE_BVC_MEASUREMENT	= 0x06,
 | 
					 | 
				
			||||||
	BSSGP_IE_CAUSE			= 0x07,
 | 
					 | 
				
			||||||
	BSSGP_IE_CELL_ID		= 0x08,
 | 
					 | 
				
			||||||
	BSSGP_IE_CHAN_NEEDED		= 0x09,
 | 
					 | 
				
			||||||
	BSSGP_IE_DRX_PARAMS		= 0x0a,
 | 
					 | 
				
			||||||
	BSSGP_IE_EMLPP_PRIO		= 0x0b,
 | 
					 | 
				
			||||||
	BSSGP_IE_FLUSH_ACTION		= 0x0c,
 | 
					 | 
				
			||||||
	BSSGP_IE_IMSI			= 0x0d,
 | 
					 | 
				
			||||||
	BSSGP_IE_LLC_PDU		= 0x0e,
 | 
					 | 
				
			||||||
	BSSGP_IE_LLC_FRAMES_DISCARDED	= 0x0f,
 | 
					 | 
				
			||||||
	BSSGP_IE_LOCATION_AREA		= 0x10,
 | 
					 | 
				
			||||||
	BSSGP_IE_MOBILE_ID		= 0x11,
 | 
					 | 
				
			||||||
	BSSGP_IE_MS_BUCKET_SIZE		= 0x12,
 | 
					 | 
				
			||||||
	BSSGP_IE_MS_RADIO_ACCESS_CAP	= 0x13,
 | 
					 | 
				
			||||||
	BSSGP_IE_OMC_ID			= 0x14,
 | 
					 | 
				
			||||||
	BSSGP_IE_PDU_IN_ERROR		= 0x15,
 | 
					 | 
				
			||||||
	BSSGP_IE_PDU_LIFETIME		= 0x16,
 | 
					 | 
				
			||||||
	BSSGP_IE_PRIORITY		= 0x17,
 | 
					 | 
				
			||||||
	BSSGP_IE_QOS_PROFILE		= 0x18,
 | 
					 | 
				
			||||||
	BSSGP_IE_RADIO_CAUSE		= 0x19,
 | 
					 | 
				
			||||||
	BSSGP_IE_RA_CAP_UPD_CAUSE	= 0x1a,
 | 
					 | 
				
			||||||
	BSSGP_IE_ROUTEING_AREA		= 0x1b,
 | 
					 | 
				
			||||||
	BSSGP_IE_R_DEFAULT_MS		= 0x1c,
 | 
					 | 
				
			||||||
	BSSGP_IE_SUSPEND_REF_NR		= 0x1d,
 | 
					 | 
				
			||||||
	BSSGP_IE_TAG			= 0x1e,
 | 
					 | 
				
			||||||
	BSSGP_IE_TLLI			= 0x1f,
 | 
					 | 
				
			||||||
	BSSGP_IE_TMSI			= 0x20,
 | 
					 | 
				
			||||||
	BSSGP_IE_TRACE_REFERENC		= 0x21,
 | 
					 | 
				
			||||||
	BSSGP_IE_TRACE_TYPE		= 0x22,
 | 
					 | 
				
			||||||
	BSSGP_IE_TRANSACTION_ID		= 0x23,
 | 
					 | 
				
			||||||
	BSSGP_IE_TRIGGER_ID		= 0x24,
 | 
					 | 
				
			||||||
	BSSGP_IE_NUM_OCT_AFF		= 0x25,
 | 
					 | 
				
			||||||
	BSSGP_IE_LSA_ID_LIST		= 0x26,
 | 
					 | 
				
			||||||
	BSSGP_IE_LSA_INFORMATION	= 0x27,
 | 
					 | 
				
			||||||
	BSSGP_IE_PACKET_FLOW_ID		= 0x28,
 | 
					 | 
				
			||||||
	BSSGP_IE_PACKET_FLOW_TIMER	= 0x29,
 | 
					 | 
				
			||||||
	BSSGP_IE_AGG_BSS_QOS_PROFILE	= 0x3a,
 | 
					 | 
				
			||||||
	BSSGP_IE_FEATURE_BITMAP		= 0x3b,
 | 
					 | 
				
			||||||
	BSSGP_IE_BUCKET_FULL_RATIO	= 0x3c,
 | 
					 | 
				
			||||||
	BSSGP_IE_SERVICE_UTRAN_CCO	= 0x3d,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 11.3.8 / Table 11.10: Cause coding */
 | 
					 | 
				
			||||||
enum gprs_bssgp_cause {
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_PROC_OVERLOAD	= 0x00,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_EQUIP_FAIL		= 0x01,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_TRASIT_NET_FAIL	= 0x02,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_CAPA_GREATER_0KPBS	= 0x03,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_UNKNOWN_MS		= 0x04,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_UNKNOWN_BVCI	= 0x05,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_CELL_TRAF_CONG	= 0x06,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_SGSN_CONG		= 0x07,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_OML_INTERV		= 0x08,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_BVCI_BLOCKED	= 0x09,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_PFC_CREATE_FAIL	= 0x0a,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_SEM_INCORR_PDU	= 0x20,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_INV_MAND_INF	= 0x21,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_MISSING_MAND_IE	= 0x22,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_MISSING_COND_IE	= 0x23,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_UNEXP_COND_IE	= 0x24,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_COND_IE_ERR		= 0x25,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_PDU_INCOMP_STATE	= 0x26,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_PROTO_ERR_UNSPEC	= 0x27,
 | 
					 | 
				
			||||||
	BSSGP_CAUSE_PDU_INCOMP_FEAT	= 0x28,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Our implementation */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* gprs_bssgp_util.c */
 | 
					 | 
				
			||||||
extern struct gprs_ns_inst *bssgp_nsi;
 | 
					 | 
				
			||||||
struct msgb *bssgp_msgb_alloc(void);
 | 
					 | 
				
			||||||
const char *bssgp_cause_str(enum gprs_bssgp_cause cause);
 | 
					 | 
				
			||||||
/* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */
 | 
					 | 
				
			||||||
int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
 | 
					 | 
				
			||||||
			 uint16_t bvci, uint16_t ns_bvci);
 | 
					 | 
				
			||||||
/* Chapter 10.4.14: Status */
 | 
					 | 
				
			||||||
int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* gprs_bssgp.c */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BVC_S_BLOCKED	0x0001
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* The per-BTS context that we keep on the SGSN side of the BSSGP link */
 | 
					 | 
				
			||||||
struct bssgp_bvc_ctx {
 | 
					 | 
				
			||||||
	struct llist_head list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* parsed RA ID and Cell ID of the remote BTS */
 | 
					 | 
				
			||||||
	struct gprs_ra_id ra_id;
 | 
					 | 
				
			||||||
	uint16_t cell_id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* NSEI and BVCI of underlying Gb link.  Together they
 | 
					 | 
				
			||||||
	 * uniquely identify a link to a BTS (5.4.4) */
 | 
					 | 
				
			||||||
	uint16_t bvci;
 | 
					 | 
				
			||||||
	uint16_t nsei;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t state;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct rate_ctr_group *ctrg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* we might want to add this as a shortcut later, avoiding the NSVC
 | 
					 | 
				
			||||||
	 * lookup for every packet, similar to a routing cache */
 | 
					 | 
				
			||||||
	//struct gprs_nsvc *nsvc;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
extern struct llist_head bssgp_bvc_ctxts;
 | 
					 | 
				
			||||||
/* Find a BTS Context based on parsed RA ID and Cell ID */
 | 
					 | 
				
			||||||
struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t cid);
 | 
					 | 
				
			||||||
/* Find a BTS context based on BVCI+NSEI tuple */
 | 
					 | 
				
			||||||
struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/tlv.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* BSSGP-UL-UNITDATA.ind */
 | 
					 | 
				
			||||||
int gprs_bssgp_rcvmsg(struct msgb *msg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* BSSGP-DL-UNITDATA.req */
 | 
					 | 
				
			||||||
struct sgsn_mm_ctx;
 | 
					 | 
				
			||||||
int gprs_bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Wrapper around TLV parser to parse BSSGP IEs */
 | 
					 | 
				
			||||||
static inline int bssgp_tlv_parse(struct tlv_parsed *tp, uint8_t *buf, int len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum bssgp_paging_mode {
 | 
					 | 
				
			||||||
	BSSGP_PAGING_PS,
 | 
					 | 
				
			||||||
	BSSGP_PAGING_CS,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum bssgp_paging_scope {
 | 
					 | 
				
			||||||
	BSSGP_PAGING_BSS_AREA,		/* all cells in BSS */
 | 
					 | 
				
			||||||
	BSSGP_PAGING_LOCATION_AREA,	/* all cells in LA */
 | 
					 | 
				
			||||||
	BSSGP_PAGING_ROUTEING_AREA,	/* all cells in RA */
 | 
					 | 
				
			||||||
	BSSGP_PAGING_BVCI,		/* one cell */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bssgp_paging_info {
 | 
					 | 
				
			||||||
	enum bssgp_paging_mode mode;
 | 
					 | 
				
			||||||
	enum bssgp_paging_scope scope;
 | 
					 | 
				
			||||||
	struct gprs_ra_id raid;
 | 
					 | 
				
			||||||
	uint16_t bvci;
 | 
					 | 
				
			||||||
	const char *imsi;
 | 
					 | 
				
			||||||
	uint32_t *ptmsi;
 | 
					 | 
				
			||||||
	uint16_t drx_params;
 | 
					 | 
				
			||||||
	uint8_t qos[3];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Send a single GMM-PAGING.req to a given NSEI/NS-BVCI */
 | 
					 | 
				
			||||||
int gprs_bssgp_tx_paging(uint16_t nsei, uint16_t ns_bvci,
 | 
					 | 
				
			||||||
			 struct bssgp_paging_info *pinfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* gprs_bssgp_vty.c */
 | 
					 | 
				
			||||||
int gprs_bssgp_vty_init(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _GPRS_BSSGP_H */
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
#ifndef _GPRS_GMM_H
 | 
					 | 
				
			||||||
#define _GPRS_GMM_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					 | 
				
			||||||
#include <openbsc/gprs_sgsn.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
 | 
					 | 
				
			||||||
			     uint8_t cause, uint8_t pco_len, uint8_t *pco_v);
 | 
					 | 
				
			||||||
int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp);
 | 
					 | 
				
			||||||
int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
 | 
					 | 
				
			||||||
int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
 | 
					 | 
				
			||||||
		       uint8_t suspend_ref);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _GPRS_GMM_H */
 | 
					 | 
				
			||||||
@@ -1,162 +0,0 @@
 | 
				
			|||||||
#ifndef _GPRS_LLC_H
 | 
					 | 
				
			||||||
#define _GPRS_LLC_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
#include <openbsc/gprs_sgsn.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 4.7 LLC Layer Structure */
 | 
					 | 
				
			||||||
enum gprs_llc_sapi {
 | 
					 | 
				
			||||||
	GPRS_SAPI_GMM		= 1,
 | 
					 | 
				
			||||||
	GPRS_SAPI_TOM2		= 2,
 | 
					 | 
				
			||||||
	GPRS_SAPI_SNDCP3	= 3,
 | 
					 | 
				
			||||||
	GPRS_SAPI_SNDCP5	= 5,
 | 
					 | 
				
			||||||
	GPRS_SAPI_SMS		= 7,
 | 
					 | 
				
			||||||
	GPRS_SAPI_TOM8		= 8,
 | 
					 | 
				
			||||||
	GPRS_SAPI_SNDCP9	= 9,
 | 
					 | 
				
			||||||
	GPRS_SAPI_SNDCP11	= 11,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 6.4 Commands and Responses */
 | 
					 | 
				
			||||||
enum gprs_llc_u_cmd {
 | 
					 | 
				
			||||||
	GPRS_LLC_U_DM_RESP		= 0x01,
 | 
					 | 
				
			||||||
	GPRS_LLC_U_DISC_CMD		= 0x04,
 | 
					 | 
				
			||||||
	GPRS_LLC_U_UA_RESP		= 0x06,
 | 
					 | 
				
			||||||
	GPRS_LLC_U_SABM_CMD		= 0x07,
 | 
					 | 
				
			||||||
	GPRS_LLC_U_FRMR_RESP		= 0x08,
 | 
					 | 
				
			||||||
	GPRS_LLC_U_XID			= 0x0b,
 | 
					 | 
				
			||||||
	GPRS_LLC_U_NULL_CMD		= 0x00,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TS 04.64 Section 7.1.2 Table 7: LLC layer primitives (GMM/SNDCP/SMS/TOM) */
 | 
					 | 
				
			||||||
/* TS 04.65 Section 5.1.2 Table 2: Service primitives used by SNDCP */
 | 
					 | 
				
			||||||
enum gprs_llc_primitive {
 | 
					 | 
				
			||||||
	/* GMM <-> LLME */
 | 
					 | 
				
			||||||
	LLGMM_ASSIGN_REQ,	/* GMM tells us new TLLI: TLLI old, TLLI new, Kc, CiphAlg */
 | 
					 | 
				
			||||||
	LLGMM_RESET_REQ,	/* GMM tells us to perform XID negotiation: TLLI */
 | 
					 | 
				
			||||||
	LLGMM_RESET_CNF,	/* LLC informs GMM that XID has completed: TLLI */
 | 
					 | 
				
			||||||
	LLGMM_SUSPEND_REQ,	/* GMM tells us MS has suspended: TLLI, Page */
 | 
					 | 
				
			||||||
	LLGMM_RESUME_REQ,	/* GMM tells us MS has resumed: TLLI */
 | 
					 | 
				
			||||||
	LLGMM_PAGE_IND,		/* LLC asks GMM to page MS: TLLI */
 | 
					 | 
				
			||||||
	LLGMM_IOV_REQ,		/* GMM tells us to perform XID: TLLI */
 | 
					 | 
				
			||||||
	LLGMM_STATUS_IND,	/* LLC informs GMM about error: TLLI, Cause */
 | 
					 | 
				
			||||||
	/* LLE <-> (GMM/SNDCP/SMS/TOM) */
 | 
					 | 
				
			||||||
	LL_RESET_IND,		/* TLLI */
 | 
					 | 
				
			||||||
	LL_ESTABLISH_REQ,	/* TLLI, XID Req */
 | 
					 | 
				
			||||||
	LL_ESTABLISH_IND,	/* TLLI, XID Req, N201-I, N201-U */
 | 
					 | 
				
			||||||
	LL_ESTABLISH_RESP,	/* TLLI, XID Negotiated */
 | 
					 | 
				
			||||||
	LL_ESTABLISH_CONF,	/* TLLI, XID Neg, N201-i, N201-U */
 | 
					 | 
				
			||||||
	LL_RELEASE_REQ,		/* TLLI, Local */
 | 
					 | 
				
			||||||
	LL_RELEASE_IND,		/* TLLI, Cause */
 | 
					 | 
				
			||||||
	LL_RELEASE_CONF,	/* TLLI */
 | 
					 | 
				
			||||||
	LL_XID_REQ,		/* TLLI, XID Requested */
 | 
					 | 
				
			||||||
	LL_XID_IND,		/* TLLI, XID Req, N201-I, N201-U */
 | 
					 | 
				
			||||||
	LL_XID_RESP,		/* TLLI, XID Negotiated */
 | 
					 | 
				
			||||||
	LL_XID_CONF,		/* TLLI, XID Neg, N201-I, N201-U */
 | 
					 | 
				
			||||||
	LL_DATA_REQ,		/* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */
 | 
					 | 
				
			||||||
	LL_DATA_IND,		/* TLLI, SN-PDU */
 | 
					 | 
				
			||||||
	LL_DATA_CONF,		/* TLLI, Ref */
 | 
					 | 
				
			||||||
	LL_UNITDATA_REQ,	/* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */
 | 
					 | 
				
			||||||
	LL_UNITDATA_IND,	/* TLLI, SN-PDU */
 | 
					 | 
				
			||||||
	LL_STATUS_IND,		/* TLLI, Cause */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 4.5.2 Logical Link States + Annex C.2 */
 | 
					 | 
				
			||||||
enum gprs_llc_lle_state {
 | 
					 | 
				
			||||||
	GPRS_LLES_UNASSIGNED	= 1,	/* No TLLI yet */
 | 
					 | 
				
			||||||
	GPRS_LLES_ASSIGNED_ADM	= 2,	/* TLLI assigned */
 | 
					 | 
				
			||||||
	GPRS_LLES_LOCAL_EST	= 3,	/* Local Establishment */
 | 
					 | 
				
			||||||
	GPRS_LLES_REMOTE_EST	= 4,	/* Remote Establishment */
 | 
					 | 
				
			||||||
	GPRS_LLES_ABM		= 5,
 | 
					 | 
				
			||||||
	GPRS_LLES_LOCAL_REL	= 6,	/* Local Release */
 | 
					 | 
				
			||||||
	GPRS_LLES_TIMER_REC 	= 7,	/* Timer Recovery */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gprs_llc_llme_state {
 | 
					 | 
				
			||||||
	GPRS_LLMS_UNASSIGNED	= 1,	/* No TLLI yet */
 | 
					 | 
				
			||||||
	GPRS_LLMS_ASSIGNED	= 2,	/* TLLI assigned */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 8.9.9 LLC layer parameter default values */
 | 
					 | 
				
			||||||
struct gprs_llc_params {
 | 
					 | 
				
			||||||
	uint16_t iov_i_exp;
 | 
					 | 
				
			||||||
	uint16_t t200_201;
 | 
					 | 
				
			||||||
	uint16_t n200;
 | 
					 | 
				
			||||||
	uint16_t n201_u;
 | 
					 | 
				
			||||||
	uint16_t n201_i;
 | 
					 | 
				
			||||||
	uint16_t mD;
 | 
					 | 
				
			||||||
	uint16_t mU;
 | 
					 | 
				
			||||||
	uint16_t kD;
 | 
					 | 
				
			||||||
	uint16_t kU;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */
 | 
					 | 
				
			||||||
struct gprs_llc_lle {
 | 
					 | 
				
			||||||
	struct llist_head list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t sapi;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct gprs_llc_llme *llme;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	enum gprs_llc_lle_state state;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct timer_list t200;
 | 
					 | 
				
			||||||
	struct timer_list t201;	/* wait for acknowledgement */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint16_t v_sent;
 | 
					 | 
				
			||||||
	uint16_t v_ack;
 | 
					 | 
				
			||||||
	uint16_t v_recv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint16_t vu_send;
 | 
					 | 
				
			||||||
	uint16_t vu_recv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Overflow Counter for ABM */
 | 
					 | 
				
			||||||
	uint32_t oc_i_send;
 | 
					 | 
				
			||||||
	uint32_t oc_i_recv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Overflow Counter for unconfirmed transfer */
 | 
					 | 
				
			||||||
	uint32_t oc_ui_send;
 | 
					 | 
				
			||||||
	uint32_t oc_ui_recv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	unsigned int retrans_ctr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct gprs_llc_params params;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NUM_SAPIS	16
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gprs_llc_llme {
 | 
					 | 
				
			||||||
	struct llist_head list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	enum gprs_llc_llme_state state;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t tlli;
 | 
					 | 
				
			||||||
	uint32_t old_tlli;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Crypto parameters */
 | 
					 | 
				
			||||||
	enum gprs_ciph_algo algo;
 | 
					 | 
				
			||||||
	uint8_t kc[8];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* over which BSSGP BTS ctx do we need to transmit */
 | 
					 | 
				
			||||||
	uint16_t bvci;
 | 
					 | 
				
			||||||
	uint16_t nsei;
 | 
					 | 
				
			||||||
	struct gprs_llc_lle lle[NUM_SAPIS];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern struct llist_head gprs_llc_llmes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* BSSGP-UL-UNITDATA.ind */
 | 
					 | 
				
			||||||
int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* LL-UNITDATA.req */
 | 
					 | 
				
			||||||
int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
 | 
					 | 
				
			||||||
		   void *mmctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */
 | 
					 | 
				
			||||||
int gprs_llgmm_assign(struct gprs_llc_llme *llme,
 | 
					 | 
				
			||||||
		      uint32_t old_tlli, uint32_t new_tlli,
 | 
					 | 
				
			||||||
		      enum gprs_ciph_algo alg, const uint8_t *kc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gprs_llc_init(const char *cipher_plugin_path);
 | 
					 | 
				
			||||||
int gprs_llc_vty_init(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,232 +0,0 @@
 | 
				
			|||||||
#ifndef _GPRS_NS_H
 | 
					 | 
				
			||||||
#define _GPRS_NS_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* GPRS Networks Service (NS) messages on the Gb interface
 | 
					 | 
				
			||||||
 * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
 | 
					 | 
				
			||||||
 * 3GPP TS 48.016 version 6.5.0 Release 6 / ETSI TS 148 016 V6.5.0 (2005-11) */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gprs_ns_hdr {
 | 
					 | 
				
			||||||
	uint8_t pdu_type;
 | 
					 | 
				
			||||||
	uint8_t data[0];
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TS 08.16, Section 10.3.7, Table 14 */
 | 
					 | 
				
			||||||
enum ns_pdu_type {
 | 
					 | 
				
			||||||
	NS_PDUT_UNITDATA	= 0x00,
 | 
					 | 
				
			||||||
	NS_PDUT_RESET		= 0x02,
 | 
					 | 
				
			||||||
	NS_PDUT_RESET_ACK	= 0x03,
 | 
					 | 
				
			||||||
	NS_PDUT_BLOCK		= 0x04,
 | 
					 | 
				
			||||||
	NS_PDUT_BLOCK_ACK	= 0x05,
 | 
					 | 
				
			||||||
	NS_PDUT_UNBLOCK		= 0x06,
 | 
					 | 
				
			||||||
	NS_PDUT_UNBLOCK_ACK	= 0x07,
 | 
					 | 
				
			||||||
	NS_PDUT_STATUS		= 0x08,
 | 
					 | 
				
			||||||
	NS_PDUT_ALIVE		= 0x0a,
 | 
					 | 
				
			||||||
	NS_PDUT_ALIVE_ACK	= 0x0b,
 | 
					 | 
				
			||||||
	/* TS 48.016 Section 10.3.7, Table 10.3.7.1 */
 | 
					 | 
				
			||||||
	SNS_PDUT_ACK		= 0x0c,
 | 
					 | 
				
			||||||
	SNS_PDUT_ADD		= 0x0d,
 | 
					 | 
				
			||||||
	SNS_PDUT_CHANGE_WEIGHT	= 0x0e,
 | 
					 | 
				
			||||||
	SNS_PDUT_CONFIG		= 0x0f,
 | 
					 | 
				
			||||||
	SNS_PDUT_CONFIG_ACK	= 0x10,
 | 
					 | 
				
			||||||
	SNS_PDUT_DELETE		= 0x11,
 | 
					 | 
				
			||||||
	SNS_PDUT_SIZE		= 0x12,
 | 
					 | 
				
			||||||
	SNS_PDUT_SIZE_ACK	= 0x13,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TS 08.16, Section 10.3, Table 12 */
 | 
					 | 
				
			||||||
enum ns_ctrl_ie {
 | 
					 | 
				
			||||||
	NS_IE_CAUSE		= 0x00,
 | 
					 | 
				
			||||||
	NS_IE_VCI		= 0x01,
 | 
					 | 
				
			||||||
	NS_IE_PDU		= 0x02,
 | 
					 | 
				
			||||||
	NS_IE_BVCI		= 0x03,
 | 
					 | 
				
			||||||
	NS_IE_NSEI		= 0x04,
 | 
					 | 
				
			||||||
	/* TS 48.016 Section 10.3, Table 10.3.1 */
 | 
					 | 
				
			||||||
	NS_IE_IPv4_LIST		= 0x05,
 | 
					 | 
				
			||||||
	NS_IE_IPv6_LIST		= 0x06,
 | 
					 | 
				
			||||||
	NS_IE_MAX_NR_NSVC	= 0x07,
 | 
					 | 
				
			||||||
	NS_IE_IPv4_EP_NR	= 0x08,
 | 
					 | 
				
			||||||
	NS_IE_IPv6_EP_NR	= 0x09,
 | 
					 | 
				
			||||||
	NS_IE_RESET_FLAG	= 0x0a,
 | 
					 | 
				
			||||||
	NS_IE_IP_ADDR		= 0x0b,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TS 08.16, Section 10.3.2, Table 13 */
 | 
					 | 
				
			||||||
enum ns_cause {
 | 
					 | 
				
			||||||
	NS_CAUSE_TRANSIT_FAIL		= 0x00,
 | 
					 | 
				
			||||||
	NS_CAUSE_OM_INTERVENTION	= 0x01,
 | 
					 | 
				
			||||||
	NS_CAUSE_EQUIP_FAIL		= 0x02,
 | 
					 | 
				
			||||||
	NS_CAUSE_NSVC_BLOCKED		= 0x03,
 | 
					 | 
				
			||||||
	NS_CAUSE_NSVC_UNKNOWN		= 0x04,
 | 
					 | 
				
			||||||
	NS_CAUSE_BVCI_UNKNOWN		= 0x05,
 | 
					 | 
				
			||||||
	NS_CAUSE_SEM_INCORR_PDU		= 0x08,
 | 
					 | 
				
			||||||
	NS_CAUSE_PDU_INCOMP_PSTATE	= 0x0a,
 | 
					 | 
				
			||||||
	NS_CAUSE_PROTO_ERR_UNSPEC	= 0x0b,
 | 
					 | 
				
			||||||
	NS_CAUSE_INVAL_ESSENT_IE	= 0x0c,
 | 
					 | 
				
			||||||
	NS_CAUSE_MISSING_ESSENT_IE	= 0x0d,
 | 
					 | 
				
			||||||
	/* TS 48.016 Section 10.3.2, Table 10.3.2.1 */
 | 
					 | 
				
			||||||
	NS_CAUSE_INVAL_NR_IPv4_EP	= 0x0e,
 | 
					 | 
				
			||||||
	NS_CAUSE_INVAL_NR_IPv6_EP	= 0x0f,
 | 
					 | 
				
			||||||
	NS_CAUSE_INVAL_NR_NS_VC		= 0x10,
 | 
					 | 
				
			||||||
	NS_CAUSE_INVAL_WEIGH		= 0x11,
 | 
					 | 
				
			||||||
	NS_CAUSE_UNKN_IP_EP		= 0x12,
 | 
					 | 
				
			||||||
	NS_CAUSE_UNKN_IP_ADDR		= 0x13,
 | 
					 | 
				
			||||||
	NS_CAUSE_UNKN_IP_TEST_FAILED	= 0x14,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Our Implementation */
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					 | 
				
			||||||
#include <osmocore/timer.h>
 | 
					 | 
				
			||||||
#include <osmocore/select.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NS_TIMERS_COUNT 7
 | 
					 | 
				
			||||||
#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)"
 | 
					 | 
				
			||||||
#define NS_TIMERS_HELP	\
 | 
					 | 
				
			||||||
	"(un)blocking Timer (Tns-block) timeout\n"		\
 | 
					 | 
				
			||||||
	"(un)blocking Timer (Tns-block) number of retries\n"	\
 | 
					 | 
				
			||||||
	"Reset Timer (Tns-reset) timeout\n"			\
 | 
					 | 
				
			||||||
	"Reset Timer (Tns-reset) number of retries\n"		\
 | 
					 | 
				
			||||||
	"Test Timer (Tns-test) timeout\n"			\
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum ns_timeout {
 | 
					 | 
				
			||||||
	NS_TOUT_TNS_BLOCK,
 | 
					 | 
				
			||||||
	NS_TOUT_TNS_BLOCK_RETRIES,
 | 
					 | 
				
			||||||
	NS_TOUT_TNS_RESET,
 | 
					 | 
				
			||||||
	NS_TOUT_TNS_RESET_RETRIES,
 | 
					 | 
				
			||||||
	NS_TOUT_TNS_TEST,
 | 
					 | 
				
			||||||
	NS_TOUT_TNS_ALIVE,
 | 
					 | 
				
			||||||
	NS_TOUT_TNS_ALIVE_RETRIES,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NSE_S_BLOCKED	0x0001
 | 
					 | 
				
			||||||
#define NSE_S_ALIVE	0x0002
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gprs_ns_ll {
 | 
					 | 
				
			||||||
	GPRS_NS_LL_UDP,
 | 
					 | 
				
			||||||
	GPRS_NS_LL_E1,
 | 
					 | 
				
			||||||
	GPRS_NS_LL_FR_GRE,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gprs_ns_evt {
 | 
					 | 
				
			||||||
	GPRS_NS_EVT_UNIT_DATA,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gprs_nsvc;
 | 
					 | 
				
			||||||
typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
 | 
					 | 
				
			||||||
			 struct msgb *msg, uint16_t bvci);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* An instance of the NS protocol stack */
 | 
					 | 
				
			||||||
struct gprs_ns_inst {
 | 
					 | 
				
			||||||
	/* callback to the user for incoming UNIT DATA IND */
 | 
					 | 
				
			||||||
	gprs_ns_cb_t *cb;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* linked lists of all NSVC in this instance */
 | 
					 | 
				
			||||||
	struct llist_head gprs_nsvcs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* a NSVC object that's needed to deal with packets for unknown NSVC */
 | 
					 | 
				
			||||||
	struct gprs_nsvc *unknown_nsvc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint16_t timeout[NS_TIMERS_COUNT];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* NS-over-IP specific bits */
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		struct bsc_fd fd;
 | 
					 | 
				
			||||||
		uint32_t local_ip;
 | 
					 | 
				
			||||||
		uint16_t local_port;
 | 
					 | 
				
			||||||
	} nsip;
 | 
					 | 
				
			||||||
	/* NS-over-FR-over-GRE-over-IP specific bits */
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		struct bsc_fd fd;
 | 
					 | 
				
			||||||
		uint32_t local_ip;
 | 
					 | 
				
			||||||
		int enabled:1;
 | 
					 | 
				
			||||||
	} frgre;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum nsvc_timer_mode {
 | 
					 | 
				
			||||||
	/* standard timers */
 | 
					 | 
				
			||||||
	NSVC_TIMER_TNS_TEST,
 | 
					 | 
				
			||||||
	NSVC_TIMER_TNS_ALIVE,
 | 
					 | 
				
			||||||
	NSVC_TIMER_TNS_RESET,
 | 
					 | 
				
			||||||
	_NSVC_TIMER_NR,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gprs_nsvc {
 | 
					 | 
				
			||||||
	struct llist_head list;
 | 
					 | 
				
			||||||
	struct gprs_ns_inst *nsi;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint16_t nsei;		/* end-to-end significance */
 | 
					 | 
				
			||||||
	uint16_t nsvci;	/* uniquely identifies NS-VC at SGSN */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t state;
 | 
					 | 
				
			||||||
	uint32_t remote_state;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct timer_list timer;
 | 
					 | 
				
			||||||
	enum nsvc_timer_mode timer_mode;
 | 
					 | 
				
			||||||
	int alive_retries;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	unsigned int remote_end_is_sgsn:1;
 | 
					 | 
				
			||||||
	unsigned int persistent:1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct rate_ctr_group *ctrg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* which link-layer are we based on? */
 | 
					 | 
				
			||||||
	enum gprs_ns_ll ll;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct {
 | 
					 | 
				
			||||||
			struct sockaddr_in bts_addr;
 | 
					 | 
				
			||||||
		} ip;
 | 
					 | 
				
			||||||
		struct {
 | 
					 | 
				
			||||||
			struct sockaddr_in bts_addr;
 | 
					 | 
				
			||||||
		} frgre;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Create a new NS protocol instance */
 | 
					 | 
				
			||||||
struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Destroy a NS protocol instance */
 | 
					 | 
				
			||||||
void gprs_ns_destroy(struct gprs_ns_inst *nsi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Listen for incoming GPRS packets via NS/UDP */
 | 
					 | 
				
			||||||
int gprs_ns_nsip_listen(struct gprs_ns_inst *nsi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sockaddr_in;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* main function for higher layers (BSSGP) to send NS messages */
 | 
					 | 
				
			||||||
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause);
 | 
					 | 
				
			||||||
int gprs_ns_tx_block(struct gprs_nsvc *nsvc, uint8_t cause);
 | 
					 | 
				
			||||||
int gprs_ns_tx_unblock(struct gprs_nsvc *nsvc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Listen for incoming GPRS packets via NS/FR/GRE */
 | 
					 | 
				
			||||||
int gprs_ns_frgre_listen(struct gprs_ns_inst *nsi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Establish a connection (from the BSS) to the SGSN */
 | 
					 | 
				
			||||||
struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
 | 
					 | 
				
			||||||
				struct sockaddr_in *dest, uint16_t nsei,
 | 
					 | 
				
			||||||
				uint16_t nsvci);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gprs_nsvc *nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci);
 | 
					 | 
				
			||||||
void nsvc_delete(struct gprs_nsvc *nsvc);
 | 
					 | 
				
			||||||
struct gprs_nsvc *nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
 | 
					 | 
				
			||||||
struct gprs_nsvc *nsvc_by_nsvci(struct gprs_ns_inst *nsi, uint16_t nsvci);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Initiate a RESET procedure (including timer start, ...)*/
 | 
					 | 
				
			||||||
void gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Add NS-specific VTY stuff */
 | 
					 | 
				
			||||||
int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NS_ALLOC_SIZE	2048
 | 
					 | 
				
			||||||
#define NS_ALLOC_HEADROOM 20
 | 
					 | 
				
			||||||
static inline struct msgb *gprs_ns_msgb_alloc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "GPRS/NS");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
#ifndef _GPRS_NS_FRGRE_H
 | 
					 | 
				
			||||||
#define _GPRS_NS_FRGRE_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gprs_ns_frgre_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,205 +0,0 @@
 | 
				
			|||||||
#ifndef _GPRS_SGSN_H
 | 
					 | 
				
			||||||
#define _GPRS_SGSN_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/gsm48.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocom/crypt/gprs_cipher.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define GSM_IMSI_LENGTH 17
 | 
					 | 
				
			||||||
#define GSM_IMEI_LENGTH 17
 | 
					 | 
				
			||||||
#define GSM_EXTENSION_LENGTH 15
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gprs_llc_lle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */
 | 
					 | 
				
			||||||
enum gprs_mm_state {
 | 
					 | 
				
			||||||
	GMM_DEREGISTERED,		/* 4.1.3.3.1.1 */
 | 
					 | 
				
			||||||
	GMM_COMMON_PROC_INIT,		/* 4.1.3.3.1.2 */
 | 
					 | 
				
			||||||
	GMM_REGISTERED_NORMAL,		/* 4.1.3.3.2.1 */
 | 
					 | 
				
			||||||
	GMM_REGISTERED_SUSPENDED,	/* 4.1.3.3.2.2 */
 | 
					 | 
				
			||||||
	GMM_DEREGISTERED_INIT,		/* 4.1.3.3.1.4 */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gprs_mm_ctr {
 | 
					 | 
				
			||||||
	GMM_CTR_PKTS_SIG_IN,
 | 
					 | 
				
			||||||
	GMM_CTR_PKTS_SIG_OUT,
 | 
					 | 
				
			||||||
	GMM_CTR_PKTS_UDATA_IN,
 | 
					 | 
				
			||||||
	GMM_CTR_PKTS_UDATA_OUT,
 | 
					 | 
				
			||||||
	GMM_CTR_BYTES_UDATA_IN,
 | 
					 | 
				
			||||||
	GMM_CTR_BYTES_UDATA_OUT,
 | 
					 | 
				
			||||||
	GMM_CTR_PDP_CTX_ACT,
 | 
					 | 
				
			||||||
	GMM_CTR_SUSPEND,
 | 
					 | 
				
			||||||
	GMM_CTR_PAGING_PS,
 | 
					 | 
				
			||||||
	GMM_CTR_PAGING_CS,
 | 
					 | 
				
			||||||
	GMM_CTR_RA_UPDATE,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gprs_pdp_ctx {
 | 
					 | 
				
			||||||
	PDP_CTR_PKTS_UDATA_IN,
 | 
					 | 
				
			||||||
	PDP_CTR_PKTS_UDATA_OUT,
 | 
					 | 
				
			||||||
	PDP_CTR_BYTES_UDATA_IN,
 | 
					 | 
				
			||||||
	PDP_CTR_BYTES_UDATA_OUT,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gprs_t3350_mode {
 | 
					 | 
				
			||||||
	GMM_T3350_MODE_ATT,
 | 
					 | 
				
			||||||
	GMM_T3350_MODE_RAU,
 | 
					 | 
				
			||||||
	GMM_T3350_MODE_PTMSI_REALL,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MS_RADIO_ACCESS_CAPA
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */
 | 
					 | 
				
			||||||
/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */
 | 
					 | 
				
			||||||
struct sgsn_mm_ctx {
 | 
					 | 
				
			||||||
	struct llist_head	list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	char 			imsi[GSM_IMSI_LENGTH];
 | 
					 | 
				
			||||||
	enum gprs_mm_state	mm_state;
 | 
					 | 
				
			||||||
	uint32_t 		p_tmsi;
 | 
					 | 
				
			||||||
	uint32_t 		p_tmsi_old;	/* old P-TMSI before new is confirmed */
 | 
					 | 
				
			||||||
	uint32_t 		p_tmsi_sig;
 | 
					 | 
				
			||||||
	char 			imei[GSM_IMEI_LENGTH];
 | 
					 | 
				
			||||||
	/* Opt: Software Version Numbber / TS 23.195 */
 | 
					 | 
				
			||||||
	char 			msisdn[GSM_EXTENSION_LENGTH];
 | 
					 | 
				
			||||||
	struct gprs_ra_id	ra;
 | 
					 | 
				
			||||||
	uint16_t		cell_id;
 | 
					 | 
				
			||||||
	uint32_t		cell_id_age;
 | 
					 | 
				
			||||||
	uint16_t		sac;	/* Iu: Service Area Code */
 | 
					 | 
				
			||||||
	uint32_t		sac_age;/* Iu: Service Area Code age */
 | 
					 | 
				
			||||||
	/* VLR number */
 | 
					 | 
				
			||||||
	uint32_t		new_sgsn_addr;
 | 
					 | 
				
			||||||
	/* Authentication Triplets */
 | 
					 | 
				
			||||||
	/* Kc */
 | 
					 | 
				
			||||||
	/* Iu: CK, IK, KSI */
 | 
					 | 
				
			||||||
	/* CKSN */
 | 
					 | 
				
			||||||
	enum gprs_ciph_algo	ciph_algo;
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		uint8_t	buf[14];	/* 10.5.5.12a */
 | 
					 | 
				
			||||||
		uint8_t	len;
 | 
					 | 
				
			||||||
	} ms_radio_access_capa;
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		uint8_t	buf[4];		/* 10.5.5.12 */
 | 
					 | 
				
			||||||
		uint8_t	len;
 | 
					 | 
				
			||||||
	} ms_network_capa;
 | 
					 | 
				
			||||||
	uint16_t		drx_parms;
 | 
					 | 
				
			||||||
	int			mnrg;	/* MS reported to HLR? */
 | 
					 | 
				
			||||||
	int			ngaf;	/* MS reported to MSC/VLR? */
 | 
					 | 
				
			||||||
	int			ppf;	/* paging for GPRS + non-GPRS? */
 | 
					 | 
				
			||||||
	/* SMS Parameters */
 | 
					 | 
				
			||||||
	int			recovery;
 | 
					 | 
				
			||||||
	uint8_t			radio_prio_sms;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct llist_head	pdp_list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Additional bits not present in the GSM TS */
 | 
					 | 
				
			||||||
	struct gprs_llc_llme	*llme;
 | 
					 | 
				
			||||||
	uint32_t		tlli;
 | 
					 | 
				
			||||||
	uint32_t		tlli_new;
 | 
					 | 
				
			||||||
	uint16_t		nsei;
 | 
					 | 
				
			||||||
	uint16_t		bvci;
 | 
					 | 
				
			||||||
	struct rate_ctr_group	*ctrg;
 | 
					 | 
				
			||||||
	struct timer_list	timer;
 | 
					 | 
				
			||||||
	unsigned int		T;		/* Txxxx number */
 | 
					 | 
				
			||||||
	unsigned int		num_T_exp;	/* number of consecutive T expirations */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	enum gprs_t3350_mode	t3350_mode;
 | 
					 | 
				
			||||||
	uint8_t			t3370_id_type;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* look-up a SGSN MM context based on TLLI + RAI */
 | 
					 | 
				
			||||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
 | 
					 | 
				
			||||||
					const struct gprs_ra_id *raid);
 | 
					 | 
				
			||||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
 | 
					 | 
				
			||||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Allocate a new SGSN MM context */
 | 
					 | 
				
			||||||
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
 | 
					 | 
				
			||||||
					const struct gprs_ra_id *raid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum pdp_ctx_state {
 | 
					 | 
				
			||||||
	PDP_STATE_NONE,
 | 
					 | 
				
			||||||
	PDP_STATE_CR_REQ,
 | 
					 | 
				
			||||||
	PDP_STATE_CR_CONF,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum pdp_type {
 | 
					 | 
				
			||||||
	PDP_TYPE_NONE,
 | 
					 | 
				
			||||||
	PDP_TYPE_ETSI_PPP,
 | 
					 | 
				
			||||||
	PDP_TYPE_IANA_IPv4,
 | 
					 | 
				
			||||||
	PDP_TYPE_IANA_IPv6,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sgsn_pdp_ctx {
 | 
					 | 
				
			||||||
	struct llist_head	list;	/* list_head for mmctx->pdp_list */
 | 
					 | 
				
			||||||
	struct llist_head	g_list;	/* list_head for global list */
 | 
					 | 
				
			||||||
	struct sgsn_mm_ctx	*mm;	/* back pointer to MM CTX */
 | 
					 | 
				
			||||||
	struct sgsn_ggsn_ctx	*ggsn;	/* which GGSN serves this PDP */
 | 
					 | 
				
			||||||
	struct rate_ctr_group	*ctrg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//unsigned int		id;
 | 
					 | 
				
			||||||
	struct pdp_t		*lib;	/* pointer to libgtp PDP ctx */
 | 
					 | 
				
			||||||
	enum pdp_ctx_state	state;
 | 
					 | 
				
			||||||
	enum pdp_type		type;
 | 
					 | 
				
			||||||
	uint32_t		address;
 | 
					 | 
				
			||||||
	char 			*apn_subscribed;
 | 
					 | 
				
			||||||
	//char 			*apn_used;
 | 
					 | 
				
			||||||
	uint16_t		nsapi;	/* SNDCP */
 | 
					 | 
				
			||||||
	uint16_t		sapi;	/* LLC */
 | 
					 | 
				
			||||||
	uint8_t			ti;	/* transaction identifier */
 | 
					 | 
				
			||||||
	int			vplmn_allowed;
 | 
					 | 
				
			||||||
	uint32_t		qos_profile_subscr;
 | 
					 | 
				
			||||||
	//uint32_t		qos_profile_req;
 | 
					 | 
				
			||||||
	//uint32_t		qos_profile_neg;
 | 
					 | 
				
			||||||
	uint8_t			radio_prio;
 | 
					 | 
				
			||||||
	uint32_t		tx_npdu_nr;
 | 
					 | 
				
			||||||
	uint32_t		rx_npdu_nr;
 | 
					 | 
				
			||||||
	uint32_t		tx_gtp_snd;
 | 
					 | 
				
			||||||
	uint32_t		rx_gtp_snu;
 | 
					 | 
				
			||||||
	//uint32_t		charging_id;
 | 
					 | 
				
			||||||
	int			reordering_reqd;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* look up PDP context by MM context and NSAPI */
 | 
					 | 
				
			||||||
struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm,
 | 
					 | 
				
			||||||
					   uint8_t nsapi);
 | 
					 | 
				
			||||||
/* look up PDP context by MM context and transaction ID */
 | 
					 | 
				
			||||||
struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm,
 | 
					 | 
				
			||||||
					 uint8_t tid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
 | 
					 | 
				
			||||||
					uint8_t nsapi);
 | 
					 | 
				
			||||||
void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sgsn_ggsn_ctx {
 | 
					 | 
				
			||||||
	struct llist_head list;
 | 
					 | 
				
			||||||
	uint32_t id;
 | 
					 | 
				
			||||||
	unsigned int gtp_version;
 | 
					 | 
				
			||||||
	struct in_addr remote_addr;
 | 
					 | 
				
			||||||
	struct gsn_t *gsn;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id);
 | 
					 | 
				
			||||||
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_id(uint32_t id);
 | 
					 | 
				
			||||||
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct apn_ctx {
 | 
					 | 
				
			||||||
	struct llist_head list;
 | 
					 | 
				
			||||||
	struct sgsn_ggsn_ctx *ggsn;
 | 
					 | 
				
			||||||
	char *name;
 | 
					 | 
				
			||||||
	char *description;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern struct llist_head sgsn_mm_ctxts;
 | 
					 | 
				
			||||||
extern struct llist_head sgsn_ggsn_ctxts;
 | 
					 | 
				
			||||||
extern struct llist_head sgsn_apn_ctxts;
 | 
					 | 
				
			||||||
extern struct llist_head sgsn_pdp_ctxts;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint32_t sgsn_alloc_ptmsi(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _GPRS_SGSN_H */
 | 
					 | 
				
			||||||
@@ -3,41 +3,770 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <openbsc/meas_rep.h>
 | 
					#include <openbsc/meas_rep.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/protocol/gsm_04_08.h>
 | 
					/* GSM TS 04.08  definitions */
 | 
				
			||||||
#include <osmocore/gsm48.h>
 | 
					struct gsm_lchan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm48_classmark1 {
 | 
				
			||||||
 | 
						u_int8_t spare:1,
 | 
				
			||||||
 | 
							 rev_level:2,
 | 
				
			||||||
 | 
							 es_ind:1,
 | 
				
			||||||
 | 
							 a5_1:1,
 | 
				
			||||||
 | 
							 pwr_lev:3;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 10.5.2.5 */
 | 
				
			||||||
 | 
					struct gsm48_chan_desc {
 | 
				
			||||||
 | 
						u_int8_t chan_nr;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								u_int8_t maio_high:4,
 | 
				
			||||||
 | 
									 h:1,
 | 
				
			||||||
 | 
									 tsc:3;
 | 
				
			||||||
 | 
								u_int8_t hsn:6,
 | 
				
			||||||
 | 
									 maio_low:2;
 | 
				
			||||||
 | 
							} h1;
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								u_int8_t arfcn_high:2,
 | 
				
			||||||
 | 
									 spare:2,
 | 
				
			||||||
 | 
									 h:1,
 | 
				
			||||||
 | 
									 tsc:3;
 | 
				
			||||||
 | 
								u_int8_t arfcn_low;
 | 
				
			||||||
 | 
							} h0;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 10.5.2.21aa */
 | 
				
			||||||
 | 
					struct gsm48_multi_rate_conf {
 | 
				
			||||||
 | 
						u_int8_t smod : 2,
 | 
				
			||||||
 | 
							 spare: 1,
 | 
				
			||||||
 | 
							 icmi : 1,
 | 
				
			||||||
 | 
							 nscb : 1,
 | 
				
			||||||
 | 
							 ver : 3;
 | 
				
			||||||
 | 
						u_int8_t m4_75 : 1,
 | 
				
			||||||
 | 
							 m5_15 : 1,
 | 
				
			||||||
 | 
							 m5_90 : 1,
 | 
				
			||||||
 | 
							 m6_70 : 1,
 | 
				
			||||||
 | 
							 m7_40 : 1,
 | 
				
			||||||
 | 
							 m7_95 : 1,
 | 
				
			||||||
 | 
							 m10_2 : 1,
 | 
				
			||||||
 | 
							 m12_2 : 1;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 10.5.2.30 */
 | 
				
			||||||
 | 
					struct gsm48_req_ref {
 | 
				
			||||||
 | 
						u_int8_t ra;
 | 
				
			||||||
 | 
						u_int8_t t3_high:3,
 | 
				
			||||||
 | 
							 t1_:5;
 | 
				
			||||||
 | 
						u_int8_t t2:5,
 | 
				
			||||||
 | 
							 t3_low:3;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Chapter 9.1.5/9.1.6
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * For 9.1.6 the chan_desc has the meaning of 10.5.2.5a
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct gsm48_chan_mode_modify {
 | 
				
			||||||
 | 
						struct gsm48_chan_desc chan_desc;
 | 
				
			||||||
 | 
						u_int8_t mode;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsm48_chan_mode {
 | 
				
			||||||
 | 
						GSM48_CMODE_SIGN	= 0x00,
 | 
				
			||||||
 | 
						GSM48_CMODE_SPEECH_V1	= 0x01,
 | 
				
			||||||
 | 
						GSM48_CMODE_SPEECH_EFR	= 0x21,
 | 
				
			||||||
 | 
						GSM48_CMODE_SPEECH_AMR	= 0x41,
 | 
				
			||||||
 | 
						GSM48_CMODE_DATA_14k5	= 0x0f,
 | 
				
			||||||
 | 
						GSM48_CMODE_DATA_12k0	= 0x03,
 | 
				
			||||||
 | 
						GSM48_CMODE_DATA_6k0	= 0x0b,
 | 
				
			||||||
 | 
						GSM48_CMODE_DATA_3k6	= 0x23,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.1.2 */
 | 
				
			||||||
 | 
					struct gsm48_ass_cmd {
 | 
				
			||||||
 | 
						/* Semantic is from 10.5.2.5a */
 | 
				
			||||||
 | 
						struct gsm48_chan_desc chan_desc;
 | 
				
			||||||
 | 
						u_int8_t power_command;
 | 
				
			||||||
 | 
						u_int8_t data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 10.5.2.2 */
 | 
				
			||||||
 | 
					struct gsm48_cell_desc {
 | 
				
			||||||
 | 
						u_int8_t bcc:3,
 | 
				
			||||||
 | 
							 ncc:3,
 | 
				
			||||||
 | 
							 arfcn_hi:2;
 | 
				
			||||||
 | 
						u_int8_t arfcn_lo;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.1.15 */
 | 
				
			||||||
 | 
					struct gsm48_ho_cmd {
 | 
				
			||||||
 | 
						struct gsm48_cell_desc cell_desc;
 | 
				
			||||||
 | 
						struct gsm48_chan_desc chan_desc;
 | 
				
			||||||
 | 
						u_int8_t ho_ref;
 | 
				
			||||||
 | 
						u_int8_t power_command;
 | 
				
			||||||
 | 
						u_int8_t data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 9.1.18 */
 | 
				
			||||||
 | 
					struct gsm48_imm_ass {
 | 
				
			||||||
 | 
						u_int8_t l2_plen;
 | 
				
			||||||
 | 
						u_int8_t proto_discr;
 | 
				
			||||||
 | 
						u_int8_t msg_type;
 | 
				
			||||||
 | 
						u_int8_t page_mode;
 | 
				
			||||||
 | 
						struct gsm48_chan_desc chan_desc;
 | 
				
			||||||
 | 
						struct gsm48_req_ref req_ref;
 | 
				
			||||||
 | 
						u_int8_t timing_advance;
 | 
				
			||||||
 | 
						u_int8_t mob_alloc_len;
 | 
				
			||||||
 | 
						u_int8_t mob_alloc[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 10.5.1.3 */
 | 
				
			||||||
 | 
					struct gsm48_loc_area_id {
 | 
				
			||||||
 | 
						u_int8_t digits[3];	/* BCD! */
 | 
				
			||||||
 | 
						u_int16_t lac;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.2.2 */
 | 
				
			||||||
 | 
					struct gsm48_auth_req {
 | 
				
			||||||
 | 
						u_int8_t key_seq:4,
 | 
				
			||||||
 | 
						         spare:4;
 | 
				
			||||||
 | 
						u_int8_t rand[16];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.2.15 */
 | 
				
			||||||
 | 
					struct gsm48_loc_upd_req {
 | 
				
			||||||
 | 
						u_int8_t type:4,
 | 
				
			||||||
 | 
							 key_seq:4;
 | 
				
			||||||
 | 
						struct gsm48_loc_area_id lai;
 | 
				
			||||||
 | 
						struct gsm48_classmark1 classmark1;
 | 
				
			||||||
 | 
						u_int8_t mi_len;
 | 
				
			||||||
 | 
						u_int8_t mi[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.1 */
 | 
				
			||||||
 | 
					struct gsm48_hdr {
 | 
				
			||||||
 | 
						u_int8_t proto_discr;
 | 
				
			||||||
 | 
						u_int8_t msg_type;
 | 
				
			||||||
 | 
						u_int8_t data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1.3x System information Type header */
 | 
				
			||||||
 | 
					struct gsm48_system_information_type_header {
 | 
				
			||||||
 | 
						u_int8_t l2_plen;
 | 
				
			||||||
 | 
						u_int8_t rr_protocol_discriminator :4,
 | 
				
			||||||
 | 
							skip_indicator:4; 
 | 
				
			||||||
 | 
						u_int8_t system_information;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm48_rach_control {
 | 
				
			||||||
 | 
						u_int8_t re :1,
 | 
				
			||||||
 | 
							 cell_bar :1,
 | 
				
			||||||
 | 
							 tx_integer :4,
 | 
				
			||||||
 | 
							 max_trans :2;
 | 
				
			||||||
 | 
						u_int8_t t2;
 | 
				
			||||||
 | 
						u_int8_t t3;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.5.2.4 Cell Selection Parameters */
 | 
				
			||||||
 | 
					struct gsm48_cell_sel_par {
 | 
				
			||||||
 | 
						u_int8_t ms_txpwr_max_ccch:5,	/* GSM 05.08 MS-TXPWR-MAX-CCCH */
 | 
				
			||||||
 | 
							 cell_resel_hyst:3;	/* GSM 05.08 CELL-RESELECT-HYSTERESIS */
 | 
				
			||||||
 | 
						u_int8_t rxlev_acc_min:6,	/* GSM 05.08 RXLEV-ACCESS-MIN */
 | 
				
			||||||
 | 
							 neci:1,
 | 
				
			||||||
 | 
							 acs:1;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.5.2.11 Control Channel Description , Figure 10.5.33 */
 | 
				
			||||||
 | 
					struct gsm48_control_channel_descr {
 | 
				
			||||||
 | 
						u_int8_t ccch_conf :3,
 | 
				
			||||||
 | 
							bs_ag_blks_res :3,
 | 
				
			||||||
 | 
							att :1,
 | 
				
			||||||
 | 
							spare1 :1;
 | 
				
			||||||
 | 
						u_int8_t bs_pa_mfrms : 3,
 | 
				
			||||||
 | 
							spare2 :5;
 | 
				
			||||||
 | 
						u_int8_t t3212;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm48_cell_options {
 | 
				
			||||||
 | 
						u_int8_t radio_link_timeout:4,
 | 
				
			||||||
 | 
							 dtx:2,
 | 
				
			||||||
 | 
							 pwrc:1,
 | 
				
			||||||
 | 
							 spare:1;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.2.9 CM service request */
 | 
				
			||||||
 | 
					struct gsm48_service_request {
 | 
				
			||||||
 | 
						u_int8_t cm_service_type : 4,
 | 
				
			||||||
 | 
							 cipher_key_seq  : 4;
 | 
				
			||||||
 | 
						/* length + 3 bytes */
 | 
				
			||||||
 | 
						u_int32_t classmark;
 | 
				
			||||||
 | 
						u_int8_t mi_len;
 | 
				
			||||||
 | 
						u_int8_t mi[0];
 | 
				
			||||||
 | 
						/* optional priority level */
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1.31 System information Type 1 */
 | 
				
			||||||
 | 
					struct gsm48_system_information_type_1 {
 | 
				
			||||||
 | 
						struct gsm48_system_information_type_header header;
 | 
				
			||||||
 | 
						u_int8_t cell_channel_description[16];
 | 
				
			||||||
 | 
						struct gsm48_rach_control rach_control;
 | 
				
			||||||
 | 
						u_int8_t rest_octets[0]; /* NCH position on the CCCH */
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1.32 System information Type 2 */
 | 
				
			||||||
 | 
					struct gsm48_system_information_type_2 {
 | 
				
			||||||
 | 
						struct gsm48_system_information_type_header header;
 | 
				
			||||||
 | 
						u_int8_t bcch_frequency_list[16];
 | 
				
			||||||
 | 
						u_int8_t ncc_permitted;
 | 
				
			||||||
 | 
						struct gsm48_rach_control rach_control;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1.35 System information Type 3 */
 | 
				
			||||||
 | 
					struct gsm48_system_information_type_3 {
 | 
				
			||||||
 | 
						struct gsm48_system_information_type_header header;
 | 
				
			||||||
 | 
						u_int16_t cell_identity;
 | 
				
			||||||
 | 
						struct gsm48_loc_area_id lai;
 | 
				
			||||||
 | 
						struct gsm48_control_channel_descr control_channel_desc;
 | 
				
			||||||
 | 
						struct gsm48_cell_options cell_options;
 | 
				
			||||||
 | 
						struct gsm48_cell_sel_par cell_sel_par;
 | 
				
			||||||
 | 
						struct gsm48_rach_control rach_control;
 | 
				
			||||||
 | 
						u_int8_t rest_octets[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1.36 System information Type 4 */
 | 
				
			||||||
 | 
					struct gsm48_system_information_type_4 {
 | 
				
			||||||
 | 
						struct gsm48_system_information_type_header header;
 | 
				
			||||||
 | 
						struct gsm48_loc_area_id lai;
 | 
				
			||||||
 | 
						struct gsm48_cell_sel_par cell_sel_par;
 | 
				
			||||||
 | 
						struct gsm48_rach_control rach_control;
 | 
				
			||||||
 | 
						/*	optional CBCH conditional CBCH... followed by
 | 
				
			||||||
 | 
							mandantory SI 4 Reset Octets
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						u_int8_t data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1.37 System information Type 5 */
 | 
				
			||||||
 | 
					struct gsm48_system_information_type_5 {
 | 
				
			||||||
 | 
						u_int8_t rr_protocol_discriminator :4,
 | 
				
			||||||
 | 
							skip_indicator:4; 
 | 
				
			||||||
 | 
						u_int8_t system_information;
 | 
				
			||||||
 | 
						u_int8_t bcch_frequency_list[16];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1.40 System information Type 6 */
 | 
				
			||||||
 | 
					struct gsm48_system_information_type_6 {
 | 
				
			||||||
 | 
						u_int8_t rr_protocol_discriminator :4,
 | 
				
			||||||
 | 
							skip_indicator:4; 
 | 
				
			||||||
 | 
						u_int8_t system_information;
 | 
				
			||||||
 | 
						u_int16_t cell_identity;
 | 
				
			||||||
 | 
						struct gsm48_loc_area_id lai;
 | 
				
			||||||
 | 
						struct gsm48_cell_options cell_options;
 | 
				
			||||||
 | 
						u_int8_t ncc_permitted;
 | 
				
			||||||
 | 
						u_int8_t rest_octets[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1.43a System Information type 13 */
 | 
				
			||||||
 | 
					struct gsm48_system_information_type_13 {
 | 
				
			||||||
 | 
						struct gsm48_system_information_type_header header;
 | 
				
			||||||
 | 
						u_int8_t rest_octets[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.2.12 IMSI Detach Indication */
 | 
				
			||||||
 | 
					struct gsm48_imsi_detach_ind {
 | 
				
			||||||
 | 
						struct gsm48_classmark1 classmark1;
 | 
				
			||||||
 | 
						u_int8_t mi_len;
 | 
				
			||||||
 | 
						u_int8_t mi[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.2 + GSM 04.07 12.2.3.1.1 */
 | 
				
			||||||
 | 
					#define GSM48_PDISC_GROUP_CC	0x00
 | 
				
			||||||
 | 
					#define GSM48_PDISC_BCAST_CC	0x01
 | 
				
			||||||
 | 
					#define GSM48_PDISC_PDSS1	0x02
 | 
				
			||||||
 | 
					#define GSM48_PDISC_CC		0x03
 | 
				
			||||||
 | 
					#define GSM48_PDISC_PDSS2	0x04
 | 
				
			||||||
 | 
					#define GSM48_PDISC_MM		0x05
 | 
				
			||||||
 | 
					#define GSM48_PDISC_RR		0x06
 | 
				
			||||||
 | 
					#define GSM48_PDISC_MM_GPRS	0x08
 | 
				
			||||||
 | 
					#define GSM48_PDISC_SMS		0x09
 | 
				
			||||||
 | 
					#define GSM48_PDISC_SM_GPRS	0x0a
 | 
				
			||||||
 | 
					#define GSM48_PDISC_NC_SS	0x0b
 | 
				
			||||||
 | 
					#define GSM48_PDISC_LOC		0x0c
 | 
				
			||||||
 | 
					#define GSM48_PDISC_MASK	0x0f
 | 
				
			||||||
 | 
					#define GSM48_PDISC_USSD	0x11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.4 */
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_INIT_REQ		0x3c
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_ADD_ASS		0x3b
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_IMM_ASS		0x3f
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_IMM_ASS_EXT		0x39
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_IMM_ASS_REJ		0x3a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CIPH_M_CMD		0x35
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CIPH_M_COMPL	0x32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CFG_CHG_CMD		0x30
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CFG_CHG_ACK		0x31
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CFG_CHG_REJ		0x33
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_ASS_CMD		0x2e
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_ASS_COMPL		0x29
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_ASS_FAIL		0x2f
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_HANDO_CMD		0x2b
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_HANDO_COMPL		0x2c
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_HANDO_FAIL		0x28
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_HANDO_INFO		0x2d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CELL_CHG_ORDER	0x08
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_PDCH_ASS_CMD	0x23
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CHAN_REL		0x0d
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_PART_REL		0x0a
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_PART_REL_COMP	0x0f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_PAG_REQ_1		0x21
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_PAG_REQ_2		0x22
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_PAG_REQ_3		0x24
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_PAG_RESP		0x27
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_NOTIF_NCH		0x20
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_NOTIF_FACCH		0x25
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_NOTIF_RESP		0x26
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_8		0x18
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_1		0x19
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_2		0x1a
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_3		0x1b
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_4		0x1c
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_5		0x1d
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_6		0x1e
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_7		0x1f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_2bis	0x02
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_2ter	0x03
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_5bis	0x05
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_5ter	0x06
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_9		0x04
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_13		0x00
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_16		0x3d
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_SYSINFO_17		0x3e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CHAN_MODE_MODIF	0x10
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_STATUS		0x12
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CHAN_MODE_MODIF_ACK	0x17
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_FREQ_REDEF		0x14
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_MEAS_REP		0x15
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CLSM_CHG		0x16
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_CLSM_ENQ		0x13
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_EXT_MEAS_REP	0x36
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_EXT_MEAS_REP_ORD	0x37
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_GPRS_SUSP_REQ	0x34
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_VGCS_UPL_GRANT	0x08
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_UPLINK_RELEASE	0x0e
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_UPLINK_FREE		0x0c
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_UPLINK_BUSY		0x2a
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_TALKER_IND		0x11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_RR_APP_INFO		0x38
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 10.2/3GPP TS 04.08 */
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_IMSI_DETACH_IND	0x01
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_LOC_UPD_ACCEPT	0x02
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_LOC_UPD_REJECT	0x04
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_LOC_UPD_REQUEST	0x08
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_AUTH_REJ		0x11
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_AUTH_REQ		0x12
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_AUTH_RESP		0x14
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_ID_REQ		0x18
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_ID_RESP		0x19
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_TMSI_REALL_CMD	0x1a
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_TMSI_REALL_COMPL	0x1b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_CM_SERV_ACC		0x21
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_CM_SERV_REJ		0x22
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_CM_SERV_ABORT	0x23
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_CM_SERV_REQ		0x24
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_CM_SERV_PROMPT	0x25
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_CM_REEST_REQ	0x28
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_ABORT		0x29
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_NULL		0x30
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_STATUS		0x31
 | 
				
			||||||
 | 
					#define GSM48_MT_MM_INFO		0x32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 10.3/3GPP TS 04.08 */
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_ALERTING		0x01
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_CALL_CONF		0x08
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_CALL_PROC		0x02
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_CONNECT		0x07
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_CONNECT_ACK		0x0f
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_EMERG_SETUP		0x0e
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_PROGRESS		0x03
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_ESTAB		0x04
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_ESTAB_CONF		0x06
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_RECALL		0x0b
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_START_CC		0x09
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_SETUP		0x05
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_MODIFY		0x17
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_MODIFY_COMPL	0x1f
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_MODIFY_REJECT	0x13
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_USER_INFO		0x10
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_HOLD		0x18
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_HOLD_ACK		0x19
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_HOLD_REJ		0x1a
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_RETR		0x1c
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_RETR_ACK		0x1d
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_RETR_REJ		0x1e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_DISCONNECT		0x25
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_RELEASE		0x2d
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_RELEASE_COMPL	0x2a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_CONG_CTRL		0x39
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_NOTIFY		0x3e
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_STATUS		0x3d
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_STATUS_ENQ		0x34
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_START_DTMF		0x35
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_STOP_DTMF		0x31
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_STOP_DTMF_ACK	0x32
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_START_DTMF_ACK	0x36
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_START_DTMF_REJ	0x37
 | 
				
			||||||
 | 
					#define GSM48_MT_CC_FACILITY		0x3a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* FIXME: Table 10.4 / 10.4a (GPRS) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.5.2.26, Table 10.5.64 */
 | 
				
			||||||
 | 
					#define GSM48_PM_MASK		0x03
 | 
				
			||||||
 | 
					#define GSM48_PM_NORMAL		0x00
 | 
				
			||||||
 | 
					#define GSM48_PM_EXTENDED	0x01
 | 
				
			||||||
 | 
					#define GSM48_PM_REORG		0x02
 | 
				
			||||||
 | 
					#define GSM48_PM_SAME		0x03
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 10.5.3.5 / Table 10.5.93 */
 | 
				
			||||||
 | 
					#define GSM48_LUPD_NORMAL	0x0
 | 
				
			||||||
 | 
					#define GSM48_LUPD_PERIODIC	0x1
 | 
				
			||||||
 | 
					#define GSM48_LUPD_IMSI_ATT	0x2
 | 
				
			||||||
 | 
					#define GSM48_LUPD_RESERVED	0x3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 10.5.4 */
 | 
				
			||||||
 | 
					#define GSM_MI_TYPE_MASK	0x07
 | 
				
			||||||
 | 
					#define GSM_MI_TYPE_NONE	0x00
 | 
				
			||||||
 | 
					#define GSM_MI_TYPE_IMSI	0x01
 | 
				
			||||||
 | 
					#define GSM_MI_TYPE_IMEI	0x02
 | 
				
			||||||
 | 
					#define GSM_MI_TYPE_IMEISV	0x03
 | 
				
			||||||
 | 
					#define GSM_MI_TYPE_TMSI	0x04
 | 
				
			||||||
 | 
					#define GSM_MI_ODD		0x08
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_IE_MUL_RATE_CFG	0x03	/* 10.5.2.21aa */
 | 
				
			||||||
 | 
					#define GSM48_IE_MOBILE_ID	0x17
 | 
				
			||||||
 | 
					#define GSM48_IE_NAME_LONG	0x43	/* 10.5.3.5a */
 | 
				
			||||||
 | 
					#define GSM48_IE_NAME_SHORT	0x45	/* 10.5.3.5a */
 | 
				
			||||||
 | 
					#define GSM48_IE_UTC		0x46	/* 10.5.3.8 */
 | 
				
			||||||
 | 
					#define GSM48_IE_NET_TIME_TZ	0x47	/* 10.5.3.9 */
 | 
				
			||||||
 | 
					#define GSM48_IE_LSA_IDENT	0x48	/* 10.5.3.11 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_IE_BEARER_CAP	0x04	/* 10.5.4.5 */
 | 
				
			||||||
 | 
					#define GSM48_IE_CAUSE		0x08	/* 10.5.4.11 */
 | 
				
			||||||
 | 
					#define GSM48_IE_CC_CAP		0x15	/* 10.5.4.5a */
 | 
				
			||||||
 | 
					#define GSM48_IE_ALERT		0x19	/* 10.5.4.26 */
 | 
				
			||||||
 | 
					#define GSM48_IE_FACILITY	0x1c	/* 10.5.4.15 */
 | 
				
			||||||
 | 
					#define GSM48_IE_PROGR_IND	0x1e	/* 10.5.4.21 */
 | 
				
			||||||
 | 
					#define GSM48_IE_AUX_STATUS	0x24	/* 10.5.4.4 */
 | 
				
			||||||
 | 
					#define GSM48_IE_NOTIFY		0x27	/* 10.5.4.20 */
 | 
				
			||||||
 | 
					#define GSM48_IE_KPD_FACILITY	0x2c	/* 10.5.4.17 */
 | 
				
			||||||
 | 
					#define GSM48_IE_SIGNAL		0x34	/* 10.5.4.23 */
 | 
				
			||||||
 | 
					#define GSM48_IE_CONN_BCD	0x4c	/* 10.5.4.13 */
 | 
				
			||||||
 | 
					#define GSM48_IE_CONN_SUB	0x4d	/* 10.5.4.14 */
 | 
				
			||||||
 | 
					#define GSM48_IE_CALLING_BCD	0x5c	/* 10.5.4.9 */
 | 
				
			||||||
 | 
					#define GSM48_IE_CALLING_SUB	0x5d	/* 10.5.4.10 */
 | 
				
			||||||
 | 
					#define GSM48_IE_CALLED_BCD	0x5e	/* 10.5.4.7 */
 | 
				
			||||||
 | 
					#define GSM48_IE_CALLED_SUB	0x6d	/* 10.5.4.8 */
 | 
				
			||||||
 | 
					#define GSM48_IE_REDIR_BCD	0x74	/* 10.5.4.21a */
 | 
				
			||||||
 | 
					#define GSM48_IE_REDIR_SUB	0x75	/* 10.5.4.21b */
 | 
				
			||||||
 | 
					#define GSM48_IE_LOWL_COMPAT	0x7c	/* 10.5.4.18 */
 | 
				
			||||||
 | 
					#define GSM48_IE_HIGHL_COMPAT	0x7d	/* 10.5.4.16 */
 | 
				
			||||||
 | 
					#define GSM48_IE_USER_USER	0x7e	/* 10.5.4.25 */
 | 
				
			||||||
 | 
					#define GSM48_IE_SS_VERS	0x7f	/* 10.5.4.24 */
 | 
				
			||||||
 | 
					#define GSM48_IE_MORE_DATA	0xa0	/* 10.5.4.19 */
 | 
				
			||||||
 | 
					#define GSM48_IE_CLIR_SUPP	0xa1	/* 10.5.4.11a */
 | 
				
			||||||
 | 
					#define GSM48_IE_CLIR_INVOC	0xa2	/* 10.5.4.11b */
 | 
				
			||||||
 | 
					#define GSM48_IE_REV_C_SETUP	0xa3	/* 10.5.4.22a */
 | 
				
			||||||
 | 
					#define GSM48_IE_REPEAT_CIR	0xd1	/* 10.5.4.22 */
 | 
				
			||||||
 | 
					#define GSM48_IE_REPEAT_SEQ	0xd3	/* 10.5.4.22 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.5.4.11 / Table 10.5.122 */
 | 
				
			||||||
 | 
					#define GSM48_CAUSE_CS_GSM	0x60
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 9.1.2 / Table 9.3 */
 | 
				
			||||||
 | 
					#define GSM48_IE_FRQLIST_AFTER	0x05
 | 
				
			||||||
 | 
					#define GSM48_IE_CELL_CH_DESC	0x62
 | 
				
			||||||
 | 
					#define GSM48_IE_MSLOT_DESC	0x10
 | 
				
			||||||
 | 
					#define GSM48_IE_CHANMODE_1	0x63
 | 
				
			||||||
 | 
					#define GSM48_IE_CHANMODE_2	0x11
 | 
				
			||||||
 | 
					#define GSM48_IE_CHANMODE_3	0x13
 | 
				
			||||||
 | 
					#define GSM48_IE_CHANMODE_4	0x14
 | 
				
			||||||
 | 
					#define GSM48_IE_CHANMODE_5	0x15
 | 
				
			||||||
 | 
					#define GSM48_IE_CHANMODE_6	0x16
 | 
				
			||||||
 | 
					#define GSM48_IE_CHANMODE_7	0x17
 | 
				
			||||||
 | 
					#define GSM48_IE_CHANMODE_8	0x18
 | 
				
			||||||
 | 
					#define GSM48_IE_CHANDESC_2	0x64
 | 
				
			||||||
 | 
					/* FIXME */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.5.4.23 / Table 10.5.130 */
 | 
				
			||||||
 | 
					enum gsm48_signal_val {
 | 
				
			||||||
 | 
						GSM48_SIGNAL_DIALTONE	= 0x00,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_RINGBACK	= 0x01,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_INTERCEPT	= 0x02,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_NET_CONG	= 0x03,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_BUSY	= 0x04,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_CONFIRM	= 0x05,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_ANSWER	= 0x06,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_CALL_WAIT	= 0x07,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_OFF_HOOK	= 0x08,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_OFF	= 0x3f,
 | 
				
			||||||
 | 
						GSM48_SIGNAL_ALERT_OFF	= 0x4f,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsm48_cause_loc {
 | 
				
			||||||
 | 
						GSM48_CAUSE_LOC_USER		= 0x00,
 | 
				
			||||||
 | 
						GSM48_CAUSE_LOC_PRN_S_LU	= 0x01,
 | 
				
			||||||
 | 
						GSM48_CAUSE_LOC_PUN_S_LU	= 0x02,
 | 
				
			||||||
 | 
						GSM48_CAUSE_LOC_TRANS_NET	= 0x03,
 | 
				
			||||||
 | 
						GSM48_CAUSE_LOC_PUN_S_RU	= 0x04,
 | 
				
			||||||
 | 
						GSM48_CAUSE_LOC_PRN_S_RU	= 0x05,
 | 
				
			||||||
 | 
						/* not defined */
 | 
				
			||||||
 | 
						GSM48_CAUSE_LOC_INN_NET		= 0x07,
 | 
				
			||||||
 | 
						GSM48_CAUSE_LOC_NET_BEYOND	= 0x0a,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.5.2.31 RR Cause / Table 10.5.70 */
 | 
				
			||||||
 | 
					enum gsm48_rr_cause {
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_NORMAL		= 0x00,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_ABNORMAL_UNSPEC	= 0x01,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_ABNORMAL_UNACCT	= 0x02,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_ABNORMAL_TIMER	= 0x03,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_ABNORMAL_NOACT	= 0x04,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_PREMPTIVE_REL	= 0x05,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_HNDOVER_IMP	= 0x06,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_CHAN_MODE_UNACCT	= 0x07,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_FREQ_NOT_IMPL	= 0x08,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_CALL_CLEARED	= 0x41,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_SEMANT_INCORR	= 0x5f,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_MSG_TYPE_N	= 0x61,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_COND_IE_ERROR	= 0x64,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_NO_CELL_ALLOC_A	= 0x65,
 | 
				
			||||||
 | 
						GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 10.5.4.11 CC Cause / Table 10.5.123 */
 | 
				
			||||||
 | 
					enum gsm48_cc_cause {
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_UNASSIGNED_NR	= 1,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_NO_ROUTE		= 3,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_CHAN_UNACCEPT	= 6,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_OP_DET_BARRING	= 8,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_NORM_CALL_CLEAR	= 16,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_USER_BUSY	= 17,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_USER_NOTRESPOND	= 18,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_USER_ALERTING_NA	= 19,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_CALL_REJECTED	= 21,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_NUMBER_CHANGED	= 22,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_PRE_EMPTION	= 25,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_NONSE_USER_CLR	= 26,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_DEST_OOO		= 27,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_INV_NR_FORMAT	= 28,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_FACILITY_REJ	= 29,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_RESP_STATUS_INQ	= 30,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_NORMAL_UNSPEC	= 31,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_NO_CIRCUIT_CHAN	= 34,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_NETWORK_OOO	= 38,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_TEMP_FAILURE	= 41,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_SWITCH_CONG	= 42,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_ACC_INF_DISCARD	= 43,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_REQ_CHAN_UNAVAIL	= 44,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_RESOURCE_UNAVAIL	= 47,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_QOS_UNAVAIL	= 49,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_REQ_FAC_NOT_SUBSC= 50,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_INC_BARRED_CUG	= 55,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_BEARER_CAP_UNAUTH= 57,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_BEARER_CA_UNAVAIL= 58,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_SERV_OPT_UNAVAIL	= 63,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_BEARERSERV_UNIMPL= 65,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_ACM_GE_ACM_MAX	= 68,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_REQ_FAC_NOTIMPL	= 69,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_RESTR_BCAP_AVAIL	= 70,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_SERV_OPT_UNIMPL	= 79,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_INVAL_TRANS_ID	= 81,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_USER_NOT_IN_CUG	= 87,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_INCOMPAT_DEST	= 88,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_INVAL_TRANS_NET	= 91,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_SEMANTIC_INCORR	= 95,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_INVAL_MAND_INF	= 96,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_MSGTYPE_NOTEXIST	= 97,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_MSGTYPE_INCOMPAT	= 98,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_IE_NOTEXIST	= 99,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_COND_IE_ERR	= 100,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_MSG_INCOMP_STATE	= 101,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_RECOVERY_TIMER	= 102,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_PROTO_ERR	= 111,
 | 
				
			||||||
 | 
						GSM48_CC_CAUSE_INTERWORKING	= 127,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Annex G, GSM specific cause values for mobility management */
 | 
				
			||||||
 | 
					enum gsm48_reject_value {
 | 
				
			||||||
 | 
						GSM48_REJECT_IMSI_UNKNOWN_IN_HLR	= 2,
 | 
				
			||||||
 | 
						GSM48_REJECT_ILLEGAL_MS			= 3,
 | 
				
			||||||
 | 
						GSM48_REJECT_IMSI_UNKNOWN_IN_VLR	= 4,
 | 
				
			||||||
 | 
						GSM48_REJECT_IMEI_NOT_ACCEPTED		= 5,
 | 
				
			||||||
 | 
						GSM48_REJECT_ILLEGAL_ME			= 6,
 | 
				
			||||||
 | 
						GSM48_REJECT_PLMN_NOT_ALLOWED		= 11,
 | 
				
			||||||
 | 
						GSM48_REJECT_LOC_NOT_ALLOWED		= 12,
 | 
				
			||||||
 | 
						GSM48_REJECT_ROAMING_NOT_ALLOWED	= 13,
 | 
				
			||||||
 | 
						GSM48_REJECT_NETWORK_FAILURE		= 17,
 | 
				
			||||||
 | 
						GSM48_REJECT_CONGESTION			= 22,
 | 
				
			||||||
 | 
						GSM48_REJECT_SRV_OPT_NOT_SUPPORTED	= 32,
 | 
				
			||||||
 | 
						GSM48_REJECT_RQD_SRV_OPT_NOT_SUPPORTED	= 33,
 | 
				
			||||||
 | 
						GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER	= 34,
 | 
				
			||||||
 | 
						GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED	= 38,
 | 
				
			||||||
 | 
						GSM48_REJECT_INCORRECT_MESSAGE		= 95,
 | 
				
			||||||
 | 
						GSM48_REJECT_INVALID_MANDANTORY_INF	= 96,
 | 
				
			||||||
 | 
						GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED	= 97,
 | 
				
			||||||
 | 
						GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE	= 98,
 | 
				
			||||||
 | 
						GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED	= 99,
 | 
				
			||||||
 | 
						GSM48_REJECT_CONDTIONAL_IE_ERROR	= 100,
 | 
				
			||||||
 | 
						GSM48_REJECT_MSG_NOT_COMPATIBLE		= 101,
 | 
				
			||||||
 | 
						GSM48_REJECT_PROTOCOL_ERROR		= 111,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* according to G.6 Additional cause codes for GMM */
 | 
				
			||||||
 | 
						GSM48_REJECT_GPRS_NOT_ALLOWED		= 7,
 | 
				
			||||||
 | 
						GSM48_REJECT_SERVICES_NOT_ALLOWED	= 8,
 | 
				
			||||||
 | 
						GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE = 9,
 | 
				
			||||||
 | 
						GSM48_REJECT_IMPLICITLY_DETACHED	= 10,
 | 
				
			||||||
 | 
						GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN	= 14,
 | 
				
			||||||
 | 
						GSM48_REJECT_MSC_TMP_NOT_REACHABLE	= 16,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum chreq_type {
 | 
				
			||||||
 | 
						CHREQ_T_EMERG_CALL,
 | 
				
			||||||
 | 
						CHREQ_T_CALL_REEST_TCH_F,
 | 
				
			||||||
 | 
						CHREQ_T_CALL_REEST_TCH_H,
 | 
				
			||||||
 | 
						CHREQ_T_CALL_REEST_TCH_H_DBL,
 | 
				
			||||||
 | 
						CHREQ_T_SDCCH,
 | 
				
			||||||
 | 
						CHREQ_T_TCH_F,
 | 
				
			||||||
 | 
						CHREQ_T_VOICE_CALL_TCH_H,
 | 
				
			||||||
 | 
						CHREQ_T_DATA_CALL_TCH_H,
 | 
				
			||||||
 | 
						CHREQ_T_LOCATION_UPD,
 | 
				
			||||||
 | 
						CHREQ_T_PAG_R_ANY_NECI0,
 | 
				
			||||||
 | 
						CHREQ_T_PAG_R_ANY_NECI1,
 | 
				
			||||||
 | 
						CHREQ_T_PAG_R_TCH_F,
 | 
				
			||||||
 | 
						CHREQ_T_PAG_R_TCH_FH,
 | 
				
			||||||
 | 
						CHREQ_T_LMU,
 | 
				
			||||||
 | 
						CHREQ_T_RESERVED_SDCCH,
 | 
				
			||||||
 | 
						CHREQ_T_RESERVED_IGNORE,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 11.3 */
 | 
				
			||||||
 | 
					#define GSM48_T301	180, 0
 | 
				
			||||||
 | 
					#define GSM48_T303	30, 0
 | 
				
			||||||
 | 
					#define GSM48_T305	30, 0
 | 
				
			||||||
 | 
					#define GSM48_T306	30, 0
 | 
				
			||||||
 | 
					#define GSM48_T308	10, 0
 | 
				
			||||||
 | 
					#define GSM48_T310	180, 0
 | 
				
			||||||
 | 
					#define GSM48_T313	30, 0
 | 
				
			||||||
 | 
					#define GSM48_T323	30, 0
 | 
				
			||||||
 | 
					#define GSM48_T331	30, 0
 | 
				
			||||||
 | 
					#define GSM48_T333	30, 0
 | 
				
			||||||
 | 
					#define GSM48_T334	25, 0 /* min 15 */
 | 
				
			||||||
 | 
					#define GSM48_T338	30, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 5.1.2.2 */
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_NULL			0
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_INITIATED		1
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_MO_CALL_PROC		3
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_CALL_DELIVERED	4
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_CALL_PRESENT		6
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_CALL_RECEIVED	7
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_CONNECT_REQUEST	8
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_MO_TERM_CALL_CONF	9
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_ACTIVE		10
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_DISCONNECT_REQ	12
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_DISCONNECT_IND	12
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_RELEASE_REQ		19
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_MO_ORIG_MODIFY	26
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_MO_TERM_MODIFY	27
 | 
				
			||||||
 | 
					#define	GSM_CSTATE_CONNECT_IND		28
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SBIT(a) (1 << a)
 | 
				
			||||||
 | 
					#define ALL_STATES 0xffffffff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 10.5.3/3GPP TS 04.08: Location Area Identification information element */
 | 
				
			||||||
 | 
					#define GSM_LAC_RESERVED_DETACHED       0x0
 | 
				
			||||||
 | 
					#define GSM_LAC_RESERVED_ALL_BTS        0xfffe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 04.08 Bearer Capability: Information Transfer Capability */
 | 
				
			||||||
 | 
					enum gsm48_bcap_itcap {
 | 
				
			||||||
 | 
						GSM48_BCAP_ITCAP_SPEECH		= 0,
 | 
				
			||||||
 | 
						GSM48_BCAP_ITCAP_UNR_DIG_INF	= 1,
 | 
				
			||||||
 | 
						GSM48_BCAP_ITCAP_3k1_AUDIO	= 2,
 | 
				
			||||||
 | 
						GSM48_BCAP_ITCAP_FAX_G3		= 3,
 | 
				
			||||||
 | 
						GSM48_BCAP_ITCAP_OTHER		= 5,
 | 
				
			||||||
 | 
						GSM48_BCAP_ITCAP_RESERVED	= 7,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 04.08 Bearer Capability: Transfer Mode */
 | 
				
			||||||
 | 
					enum gsm48_bcap_tmod {
 | 
				
			||||||
 | 
						GSM48_BCAP_TMOD_CIRCUIT		= 0,
 | 
				
			||||||
 | 
						GSM48_BCAP_TMOD_PACKET		= 1,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 04.08 Bearer Capability: Coding Standard */
 | 
				
			||||||
 | 
					enum gsm48_bcap_coding {
 | 
				
			||||||
 | 
						GSM48_BCAP_CODING_GSM_STD	= 0,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 04.08 Bearer Capability: Radio Channel Requirements */
 | 
				
			||||||
 | 
					enum gsm48_bcap_rrq {
 | 
				
			||||||
 | 
						GSM48_BCAP_RRQ_FR_ONLY	= 1,
 | 
				
			||||||
 | 
						GSM48_BCAP_RRQ_DUAL_HR	= 2,
 | 
				
			||||||
 | 
						GSM48_BCAP_RRQ_DUAL_FR	= 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM48_TMSI_LEN	5
 | 
				
			||||||
 | 
					#define GSM48_MID_TMSI_LEN	(GSM48_TMSI_LEN + 2)
 | 
				
			||||||
 | 
					#define GSM48_MI_SIZE 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct msgb;
 | 
					struct msgb;
 | 
				
			||||||
struct gsm_bts;
 | 
					struct gsm_bts;
 | 
				
			||||||
struct gsm_subscriber;
 | 
					struct gsm_subscriber;
 | 
				
			||||||
struct gsm_network;
 | 
					struct gsm_network;
 | 
				
			||||||
struct gsm_trans;
 | 
					struct gsm_trans;
 | 
				
			||||||
struct gsm_subscriber_connection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define GSM48_ALLOC_SIZE	1024
 | 
					 | 
				
			||||||
#define GSM48_ALLOC_HEADROOM	128
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline struct msgb *gsm48_msgb_alloc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM,
 | 
					 | 
				
			||||||
				   "GSM 04.08");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* config options controlling the behaviour of the lower leves */
 | 
					/* config options controlling the behaviour of the lower leves */
 | 
				
			||||||
void gsm0408_allow_everyone(int allow);
 | 
					void gsm0408_allow_everyone(int allow);
 | 
				
			||||||
void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
 | 
					 | 
				
			||||||
int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
 | 
					int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
 | 
				
			||||||
int gsm0408_new_conn(struct gsm_subscriber_connection *conn);
 | 
					void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc, 
 | 
				
			||||||
 | 
							u_int16_t mnc, u_int16_t lac);
 | 
				
			||||||
enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
 | 
					enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
 | 
				
			||||||
enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
 | 
					enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn);
 | 
					int gsm48_tx_mm_info(struct gsm_lchan *lchan);
 | 
				
			||||||
int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, u_int8_t *rand, int key_seq);
 | 
					int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand);
 | 
				
			||||||
int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn);
 | 
					int gsm48_tx_mm_auth_rej(struct gsm_lchan *lchan);
 | 
				
			||||||
 | 
					struct msgb *gsm48_msgb_alloc(void);
 | 
				
			||||||
 | 
					int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans);
 | 
				
			||||||
 | 
					int gsm48_generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi);
 | 
				
			||||||
 | 
					int gsm48_generate_mid_from_imsi(u_int8_t *buf, const char* imsi);
 | 
				
			||||||
 | 
					int gsm48_mi_to_string(char *string, const int str_len, const u_int8_t *mi, const int mi_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gsm48_send_rr_release(struct gsm_lchan *lchan);
 | 
					int gsm48_send_rr_release(struct gsm_lchan *lchan);
 | 
				
			||||||
int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
 | 
					int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
 | 
				
			||||||
int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, u_int8_t apdu_id,
 | 
					int gsm48_send_rr_app_info(struct gsm_lchan *lchan, u_int8_t apdu_id,
 | 
				
			||||||
			   u_int8_t apdu_len, const u_int8_t *apdu);
 | 
								   u_int8_t apdu_len, const u_int8_t *apdu);
 | 
				
			||||||
int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, u_int8_t power_class);
 | 
					int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, u_int8_t power_class);
 | 
				
			||||||
int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
 | 
					int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
 | 
				
			||||||
@@ -53,18 +782,15 @@ int encode_bcd_number(u_int8_t *bcd_lv, u_int8_t max_len,
 | 
				
			|||||||
int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
 | 
					int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
 | 
				
			||||||
		      int h_len);
 | 
							      int h_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const char *gsm0408_cc_msg_names[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv);
 | 
					int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv);
 | 
				
			||||||
int gsm48_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type);
 | 
					int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type);
 | 
				
			||||||
int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, u_int8_t *mi_type);
 | 
					int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr);
 | 
				
			||||||
int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, struct msgb *msg, struct gsm_subscriber *subscr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode);
 | 
					int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode);
 | 
				
			||||||
int gsm48_rx_rr_modif_ack(struct msgb *msg);
 | 
					int gsm48_rx_rr_modif_ack(struct msgb *msg);
 | 
				
			||||||
int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
 | 
					int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value);
 | 
					 | 
				
			||||||
struct msgb *gsm48_create_loc_upd_rej(uint8_t cause);
 | 
					 | 
				
			||||||
void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
 | 
					 | 
				
			||||||
			   const struct gsm_lchan *lchan);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,383 +0,0 @@
 | 
				
			|||||||
#ifndef _GSM48_GPRS_H
 | 
					 | 
				
			||||||
#define _GSM48_GPRS_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
#include <osmocore/protocol/gsm_04_08.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Table 10.4 / 10.4a, GPRS Mobility Management (GMM) */
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_ATTACH_REQ		0x01
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_ATTACH_ACK		0x02
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_ATTACH_COMPL	0x03
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_ATTACH_REJ		0x04
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_DETACH_REQ		0x05
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_DETACH_ACK		0x06
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_RA_UPD_REQ		0x08
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_RA_UPD_ACK		0x09
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_RA_UPD_COMPL	0x0a
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_RA_UPD_REJ		0x0b
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_PTMSI_REALL_CMD	0x10
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_PTMSI_REALL_COMPL	0x11
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_AUTH_CIPH_REQ	0x12
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_AUTH_CIPH_RESP	0x13
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_AUTH_CIPH_REJ	0x14
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_ID_REQ		0x15
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_ID_RESP		0x16
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_STATUS		0x20
 | 
					 | 
				
			||||||
#define GSM48_MT_GMM_INFO		0x21
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Table 10.4a, GPRS Session Management (GSM) */
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_ACT_PDP_REQ	0x41
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_ACT_PDP_ACK	0x42
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_ACT_PDP_REJ	0x43
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_REQ_PDP_ACT	0x44
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_REQ_PDP_ACT_REJ	0x45
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_DEACT_PDP_REQ	0x46
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_DEACT_PDP_ACK	0x47
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_ACT_AA_PDP_REQ	0x50
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_ACT_AA_PDP_ACK	0x51
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_ACT_AA_PDP_REJ	0x52
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_DEACT_AA_PDP_REQ	0x53
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_DEACT_AA_PDP_ACK	0x54
 | 
					 | 
				
			||||||
#define GSM48_MT_GSM_STATUS		0x55
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 10.5.5.2 / Table 10.5.135 */
 | 
					 | 
				
			||||||
#define GPRS_ATT_T_ATTACH		1
 | 
					 | 
				
			||||||
#define GPRS_ATT_T_ATT_WHILE_IMSI	2
 | 
					 | 
				
			||||||
#define GPRS_ATT_T_COMBINED		3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 10.5.5.5 / Table 10.5.138 */
 | 
					 | 
				
			||||||
#define GPRS_DET_T_MO_GPRS		1
 | 
					 | 
				
			||||||
#define GPRS_DET_T_MO_IMSI		2
 | 
					 | 
				
			||||||
#define GPRS_DET_T_MO_COMBINED		3
 | 
					 | 
				
			||||||
/* Network to MS direction */
 | 
					 | 
				
			||||||
#define GPRS_DET_T_MT_REATT_REQ		1
 | 
					 | 
				
			||||||
#define GPRS_DET_T_MT_REATT_NOTREQ	2
 | 
					 | 
				
			||||||
#define GPRS_DET_T_MT_IMSI		3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 10.5.5.18 / Table 105.150 */
 | 
					 | 
				
			||||||
#define GPRS_UPD_T_RA			0
 | 
					 | 
				
			||||||
#define GPRS_UPD_T_RA_LA		1
 | 
					 | 
				
			||||||
#define GPRS_UPD_T_RA_LA_IMSI_ATT	2
 | 
					 | 
				
			||||||
#define GPRS_UPD_T_PERIODIC		3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gsm48_gprs_ie_mm {
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_CIPH_CKSN		= 0x08, /* 10.5.1.2 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_TIMER_READY	= 0x17,	/* 10.5.7.3 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_ALLOC_PTMSI	= 0x18,	/* 10.5.1.4 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_PTMSI_SIG		= 0x19,	/* 10.5.5.8 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_AUTH_RAND		= 0x21,	/* 10.5.3.1 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_AUTH_SRES		= 0x22,	/* 10.5.3.2 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_IMEISV		= 0x23,	/* 10.5.1.4 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_DRX_PARAM		= 0x27,	/* 10.5.5.6 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_MS_NET_CAPA	= 0x31,	/* 10.5.5.12 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_PDP_CTX_STATUS	= 0x32,	/* 10.5.7.1 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_PS_LCS_CAPA	= 0x33,	/* 10.5.5.22 */
 | 
					 | 
				
			||||||
	GSM48_IE_GMM_GMM_MBMS_CTX_ST	= 0x35,	/* 10.5.7.6 */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gsm48_gprs_ie_sm {
 | 
					 | 
				
			||||||
	GSM48_IE_GSM_APN		= 0x28,	/* 10.5.6.1 */
 | 
					 | 
				
			||||||
	GSM48_IE_GSM_PROTO_CONF_OPT	= 0x27,	/* 10.5.6.3 */
 | 
					 | 
				
			||||||
	GSM48_IE_GSM_PDP_ADDR		= 0x2b, /* 10.5.6.4 */
 | 
					 | 
				
			||||||
	GSM48_IE_GSM_AA_TMR		= 0x29,	/* 10.5.7.3 */
 | 
					 | 
				
			||||||
	GSM48_IE_GSM_NAME_FULL		= 0x43, /* 10.5.3.5a */
 | 
					 | 
				
			||||||
	GSM48_IE_GSM_NAME_SHORT		= 0x45, /* 10.5.3.5a */
 | 
					 | 
				
			||||||
	GSM48_IE_GSM_TIMEZONE		= 0x46, /* 10.5.3.8 */
 | 
					 | 
				
			||||||
	GSM48_IE_GSM_UTC_AND_TZ		= 0x47, /* 10.5.3.9 */
 | 
					 | 
				
			||||||
	GSM48_IE_GSM_LSA_ID		= 0x48, /* 10.5.3.11 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Fake IEs that are not present on the Layer3 air interface,
 | 
					 | 
				
			||||||
	 * but which we use to simplify internal APIs */
 | 
					 | 
				
			||||||
	OSMO_IE_GSM_REQ_QOS		= 0xfd,
 | 
					 | 
				
			||||||
	OSMO_IE_GSM_REQ_PDP_ADDR	= 0xfe,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 9.4.15 / Table 9.4.15 */
 | 
					 | 
				
			||||||
struct gsm48_ra_upd_ack {
 | 
					 | 
				
			||||||
	uint8_t force_stby:4,	/* 10.5.5.7 */
 | 
					 | 
				
			||||||
		 upd_result:4;	/* 10.5.5.17 */
 | 
					 | 
				
			||||||
	uint8_t ra_upd_timer;	/* 10.5.7.3 */
 | 
					 | 
				
			||||||
	struct gsm48_ra_id ra_id; /* 10.5.5.15 */
 | 
					 | 
				
			||||||
	uint8_t data[0];
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 10.5.7.3 */
 | 
					 | 
				
			||||||
enum gsm48_gprs_tmr_unit {
 | 
					 | 
				
			||||||
	GPRS_TMR_2SECONDS	= 0 << 5,
 | 
					 | 
				
			||||||
	GPRS_TMR_MINUTE		= 1 << 5,
 | 
					 | 
				
			||||||
	GPRS_TMR_6MINUTE	= 2 << 5,
 | 
					 | 
				
			||||||
	GPRS_TMR_DEACTIVATED	= 3 << 5,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 9.4.2 / Table 9.4.2 */
 | 
					 | 
				
			||||||
struct gsm48_attach_ack {
 | 
					 | 
				
			||||||
	uint8_t att_result:4,	/* 10.5.5.7 */
 | 
					 | 
				
			||||||
		 force_stby:4;	/* 10.5.5.1 */
 | 
					 | 
				
			||||||
	uint8_t ra_upd_timer;	/* 10.5.7.3 */
 | 
					 | 
				
			||||||
	uint8_t radio_prio;	/* 10.5.7.2 */
 | 
					 | 
				
			||||||
	struct gsm48_ra_id ra_id; /* 10.5.5.15 */
 | 
					 | 
				
			||||||
	uint8_t data[0];
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 9.4.9 / Table 9.4.9 */
 | 
					 | 
				
			||||||
struct gsm48_auth_ciph_req {
 | 
					 | 
				
			||||||
	uint8_t ciph_alg:4,	/* 10.5.5.3 */
 | 
					 | 
				
			||||||
		imeisv_req:4;	/* 10.5.5.10 */
 | 
					 | 
				
			||||||
	uint8_t force_stby:4,	/* 10.5.5.7 */
 | 
					 | 
				
			||||||
		ac_ref_nr:4;	/* 10.5.5.19 */
 | 
					 | 
				
			||||||
	uint8_t data[0];
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
/* optional: TV RAND, TV CKSN */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm48_auth_ciph_resp {
 | 
					 | 
				
			||||||
	uint8_t ac_ref_nr:4,
 | 
					 | 
				
			||||||
		spare:4;
 | 
					 | 
				
			||||||
	uint8_t data[0];
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 9.5.1 / Table 9.5.1 */
 | 
					 | 
				
			||||||
struct gsm48_act_pdp_ctx_req {
 | 
					 | 
				
			||||||
	uint8_t req_nsapi;
 | 
					 | 
				
			||||||
	uint8_t req_llc_sapi;
 | 
					 | 
				
			||||||
	uint8_t data[0];
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 10.5.5.14 / Table 10.5.147 */
 | 
					 | 
				
			||||||
enum gsm48_gmm_cause {
 | 
					 | 
				
			||||||
	GMM_CAUSE_IMSI_UNKNOWN		= 0x02,
 | 
					 | 
				
			||||||
	GMM_CAUSE_ILLEGAL_MS		= 0x03,
 | 
					 | 
				
			||||||
	GMM_CAUSE_ILLEGAL_ME		= 0x06,
 | 
					 | 
				
			||||||
	GMM_CAUSE_GPRS_NOTALLOWED	= 0x07,
 | 
					 | 
				
			||||||
	GMM_CAUSE_GPRS_OTHER_NOTALLOWED	= 0x08,
 | 
					 | 
				
			||||||
	GMM_CAUSE_MS_ID_NOT_DERIVED	= 0x09,
 | 
					 | 
				
			||||||
	GMM_CAUSE_IMPL_DETACHED		= 0x0a,
 | 
					 | 
				
			||||||
	GMM_CAUSE_PLMN_NOTALLOWED	= 0x0b,
 | 
					 | 
				
			||||||
	GMM_CAUSE_LA_NOTALLOWED		= 0x0c,
 | 
					 | 
				
			||||||
	GMM_CAUSE_ROAMING_NOTALLOWED	= 0x0d,
 | 
					 | 
				
			||||||
	GMM_CAUSE_NO_GPRS_PLMN		= 0x0e,
 | 
					 | 
				
			||||||
	GMM_CAUSE_MSC_TEMP_NOTREACH	= 0x10,
 | 
					 | 
				
			||||||
	GMM_CAUSE_NET_FAIL		= 0x11,
 | 
					 | 
				
			||||||
	GMM_CAUSE_CONGESTION		= 0x16,
 | 
					 | 
				
			||||||
	GMM_CAUSE_SEM_INCORR_MSG	= 0x5f,
 | 
					 | 
				
			||||||
	GMM_CAUSE_INV_MAND_INFO		= 0x60,
 | 
					 | 
				
			||||||
	GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL	= 0x61,
 | 
					 | 
				
			||||||
	GMM_CAUSE_MSGT_INCOMP_P_STATE	= 0x62,
 | 
					 | 
				
			||||||
	GMM_CAUSE_IE_NOTEXIST_NOTIMPL	= 0x63,
 | 
					 | 
				
			||||||
	GMM_CAUSE_COND_IE_ERR		= 0x64,
 | 
					 | 
				
			||||||
	GMM_CAUSE_MSG_INCOMP_P_STATE	= 0x65,
 | 
					 | 
				
			||||||
	GMM_CAUSE_PROTO_ERR_UNSPEC	= 0x6f,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Chapter 10.4.6.6 / Table 10.5.157 */
 | 
					 | 
				
			||||||
enum gsm48_gsm_cause {
 | 
					 | 
				
			||||||
	GSM_CAUSE_INSUFF_RSRC		= 0x1a,
 | 
					 | 
				
			||||||
	GSM_CAUSE_MISSING_APN		= 0x1b,
 | 
					 | 
				
			||||||
	GSM_CAUSE_UNKNOWN_PDP		= 0x1c,
 | 
					 | 
				
			||||||
	GSM_CAUSE_AUTH_FAILED		= 0x1d,
 | 
					 | 
				
			||||||
	GSM_CAUSE_ACT_REJ_GGSN		= 0x1e,
 | 
					 | 
				
			||||||
	GSM_CAUSE_ACT_REJ_UNSPEC	= 0x1f,
 | 
					 | 
				
			||||||
	GSM_CAUSE_SERV_OPT_NOTSUPP	= 0x20,
 | 
					 | 
				
			||||||
	GSM_CAUSE_REQ_SERV_OPT_NOTSUB	= 0x21,
 | 
					 | 
				
			||||||
	GSM_CAUSE_SERV_OPT_TEMP_OOO	= 0x22,
 | 
					 | 
				
			||||||
	GSM_CAUSE_NSAPI_IN_USE		= 0x23,
 | 
					 | 
				
			||||||
	GSM_CAUSE_DEACT_REGULAR		= 0x24,
 | 
					 | 
				
			||||||
	GSM_CAUSE_QOS_NOT_ACCEPTED	= 0x25,
 | 
					 | 
				
			||||||
	GSM_CAUSE_NET_FAIL		= 0x26,
 | 
					 | 
				
			||||||
	GSM_CAUSE_REACT_RQD		= 0x27,
 | 
					 | 
				
			||||||
	GSM_CAUSE_FEATURE_NOTSUPP	= 0x28,
 | 
					 | 
				
			||||||
	GSM_CAUSE_INVALID_TRANS_ID	= 0x51,
 | 
					 | 
				
			||||||
	GSM_CAUSE_SEM_INCORR_MSG	= 0x5f,
 | 
					 | 
				
			||||||
	GSM_CAUSE_INV_MAND_INFO		= 0x60,
 | 
					 | 
				
			||||||
	GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL	= 0x61,
 | 
					 | 
				
			||||||
	GSM_CAUSE_MSGT_INCOMP_P_STATE	= 0x62,
 | 
					 | 
				
			||||||
	GSM_CAUSE_IE_NOTEXIST_NOTIMPL	= 0x63,
 | 
					 | 
				
			||||||
	GSM_CAUSE_COND_IE_ERR		= 0x64,
 | 
					 | 
				
			||||||
	GSM_CAUSE_MSG_INCOMP_P_STATE	= 0x65,
 | 
					 | 
				
			||||||
	GSM_CAUSE_PROTO_ERR_UNSPEC	= 0x6f,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Section 6.1.2.2: Session management states on the network side */
 | 
					 | 
				
			||||||
enum gsm48_pdp_state {
 | 
					 | 
				
			||||||
	PDP_S_INACTIVE,
 | 
					 | 
				
			||||||
	PDP_S_ACTIVE_PENDING,
 | 
					 | 
				
			||||||
	PDP_S_ACTIVE,
 | 
					 | 
				
			||||||
	PDP_S_INACTIVE_PENDING,
 | 
					 | 
				
			||||||
	PDP_S_MODIFY_PENDING,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Table 10.5.155/3GPP TS 24.008 */
 | 
					 | 
				
			||||||
enum gsm48_pdp_type_org {
 | 
					 | 
				
			||||||
	PDP_TYPE_ORG_ETSI		= 0x00,
 | 
					 | 
				
			||||||
	PDP_TYPE_ORG_IETF		= 0x01,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
enum gsm48_pdp_type_nr {
 | 
					 | 
				
			||||||
	PDP_TYPE_N_ETSI_RESERVED	= 0x00,
 | 
					 | 
				
			||||||
	PDP_TYPE_N_ETSI_PPP		= 0x01,
 | 
					 | 
				
			||||||
	PDP_TYPE_N_IETF_IPv4		= 0x21,
 | 
					 | 
				
			||||||
	PDP_TYPE_N_IETF_IPv6		= 0x57,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_reliab_class {
 | 
					 | 
				
			||||||
	GSM48_QOS_RC_LLC_ACK_RLC_ACK_DATA_PROT	= 2,
 | 
					 | 
				
			||||||
	GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT	= 3,
 | 
					 | 
				
			||||||
	GSM48_QOS_RC_LLC_UN_RLC_UN_PROT_DATA	= 4,
 | 
					 | 
				
			||||||
	GSM48_QOS_RC_LLC_UN_RLC_UN_DATA_UN	= 5,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_preced_class {
 | 
					 | 
				
			||||||
	GSM48_QOS_PC_HIGH	= 1,
 | 
					 | 
				
			||||||
	GSM48_QOS_PC_NORMAL	= 2,
 | 
					 | 
				
			||||||
	GSM48_QOS_PC_LOW	= 3,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_peak_tput {
 | 
					 | 
				
			||||||
	GSM48_QOS_PEAK_TPUT_1000bps	= 1,
 | 
					 | 
				
			||||||
	GSM48_QOS_PEAK_TPUT_2000bps	= 2,
 | 
					 | 
				
			||||||
	GSM48_QOS_PEAK_TPUT_4000bps	= 3,
 | 
					 | 
				
			||||||
	GSM48_QOS_PEAK_TPUT_8000bps	= 4,
 | 
					 | 
				
			||||||
	GSM48_QOS_PEAK_TPUT_16000bps	= 5,
 | 
					 | 
				
			||||||
	GSM48_QOS_PEAK_TPUT_32000bps	= 6,
 | 
					 | 
				
			||||||
	GSM48_QOS_PEAK_TPUT_64000bps	= 7,
 | 
					 | 
				
			||||||
	GSM48_QOS_PEAK_TPUT_128000bps	= 8,
 | 
					 | 
				
			||||||
	GSM48_QOS_PEAK_TPUT_256000bps	= 9,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_mean_tput {
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_100bph	= 1,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_200bph	= 2,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_500bph	= 3,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_1000bph	= 4,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_2000bph	= 5,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_5000bph	= 6,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_10000bph	= 7,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_20000bph	= 8,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_50000bph	= 9,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_100kbph	= 10,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_200kbph	= 11,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_500kbph	= 0xc,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_1Mbph	= 0xd,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_2Mbph	= 0xe,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_5Mbph	= 0xf,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_10Mbph	= 0x10,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_20Mbph	= 0x11,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_50Mbph	= 0x12,
 | 
					 | 
				
			||||||
	GSM48_QOS_MEAN_TPUT_BEST_EFFORT	= 0x1f,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_err_sdu {
 | 
					 | 
				
			||||||
	GSM48_QOS_ERRSDU_NODETECT	= 1,
 | 
					 | 
				
			||||||
	GSM48_QOS_ERRSDU_YES		= 2,
 | 
					 | 
				
			||||||
	GSM48_QOS_ERRSDU_NO		= 3,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_deliv_order {
 | 
					 | 
				
			||||||
	GSM48_QOS_DO_ORDERED		= 1,
 | 
					 | 
				
			||||||
	GSM48_QOS_DO_UNORDERED		= 2,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_traf_class {
 | 
					 | 
				
			||||||
	GSM48_QOS_TC_CONVERSATIONAL	= 1,
 | 
					 | 
				
			||||||
	GSM48_QOS_TC_STREAMING		= 2,
 | 
					 | 
				
			||||||
	GSM48_QOS_TC_INTERACTIVE	= 3,
 | 
					 | 
				
			||||||
	GSM48_QOS_TC_BACKGROUND		= 4,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_max_sdu_size {
 | 
					 | 
				
			||||||
	/* values below in 10 octet granularity */
 | 
					 | 
				
			||||||
	GSM48_QOS_MAXSDU_1502		= 0x97,
 | 
					 | 
				
			||||||
	GSM48_QOS_MAXSDU_1510		= 0x98,
 | 
					 | 
				
			||||||
	GSM48_QOS_MAXSDU_1520		= 0x99,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_max_bitrate {
 | 
					 | 
				
			||||||
	GSM48_QOS_MBRATE_1k		= 0x01,
 | 
					 | 
				
			||||||
	GSM48_QOS_MBRATE_63k		= 0x3f,
 | 
					 | 
				
			||||||
	GSM48_QOS_MBRATE_64k		= 0x40,
 | 
					 | 
				
			||||||
	GSM48_QOS_MBRATE_568k		= 0x7f,
 | 
					 | 
				
			||||||
	GSM48_QOS_MBRATE_576k		= 0x80,
 | 
					 | 
				
			||||||
	GSM48_QOS_MBRATE_8640k		= 0xfe,
 | 
					 | 
				
			||||||
	GSM48_QOS_MBRATE_0k		= 0xff,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_resid_ber {
 | 
					 | 
				
			||||||
	GSM48_QOS_RBER_5e_2		= 0x01,
 | 
					 | 
				
			||||||
	GSM48_QOS_RBER_1e_2		= 0x02,
 | 
					 | 
				
			||||||
	GSM48_QOS_RBER_5e_3		= 0x03,
 | 
					 | 
				
			||||||
	GSM48_QOS_RBER_4e_3		= 0x04,
 | 
					 | 
				
			||||||
	GSM48_QOS_RBER_1e_3		= 0x05,
 | 
					 | 
				
			||||||
	GSM48_QOS_RBER_1e_4		= 0x06,
 | 
					 | 
				
			||||||
	GSM48_QOS_RBER_1e_5		= 0x07,
 | 
					 | 
				
			||||||
	GSM48_QOS_RBER_1e_6		= 0x08,
 | 
					 | 
				
			||||||
	GSM48_QOS_RBER_6e_8		= 0x09,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
enum gsm48_qos_sdu_err {
 | 
					 | 
				
			||||||
	GSM48_QOS_SERR_1e_2		= 0x01,
 | 
					 | 
				
			||||||
	GSM48_QOS_SERR_7e_2		= 0x02,
 | 
					 | 
				
			||||||
	GSM48_QOS_SERR_1e_3		= 0x03,
 | 
					 | 
				
			||||||
	GSM48_QOS_SERR_1e_4		= 0x04,
 | 
					 | 
				
			||||||
	GSM48_QOS_SERR_1e_5		= 0x05,
 | 
					 | 
				
			||||||
	GSM48_QOS_SERR_1e_6		= 0x06,
 | 
					 | 
				
			||||||
	GSM48_QOS_SERR_1e_1		= 0x07,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
 | 
					 | 
				
			||||||
struct gsm48_qos {
 | 
					 | 
				
			||||||
	/* octet 3 */
 | 
					 | 
				
			||||||
	uint8_t reliab_class:3;
 | 
					 | 
				
			||||||
	uint8_t delay_class:3;
 | 
					 | 
				
			||||||
	uint8_t spare:2;
 | 
					 | 
				
			||||||
	/* octet 4 */
 | 
					 | 
				
			||||||
	uint8_t preced_class:3;
 | 
					 | 
				
			||||||
	uint8_t spare2:1;
 | 
					 | 
				
			||||||
	uint8_t peak_tput:4;
 | 
					 | 
				
			||||||
	/* octet 5 */
 | 
					 | 
				
			||||||
	uint8_t mean_tput:5;
 | 
					 | 
				
			||||||
	uint8_t spare3:3;
 | 
					 | 
				
			||||||
	/* octet 6 */
 | 
					 | 
				
			||||||
	uint8_t deliv_err_sdu:3;
 | 
					 | 
				
			||||||
	uint8_t deliv_order:2;
 | 
					 | 
				
			||||||
	uint8_t traf_class:3;
 | 
					 | 
				
			||||||
	/* octet 7 */
 | 
					 | 
				
			||||||
	uint8_t max_sdu_size;
 | 
					 | 
				
			||||||
	/* octet 8 */
 | 
					 | 
				
			||||||
	uint8_t max_bitrate_up;
 | 
					 | 
				
			||||||
	/* octet 9 */
 | 
					 | 
				
			||||||
	uint8_t max_bitrate_down;
 | 
					 | 
				
			||||||
	/* octet 10 */
 | 
					 | 
				
			||||||
	uint8_t sdu_err_ratio:4;
 | 
					 | 
				
			||||||
	uint8_t resid_ber:4;
 | 
					 | 
				
			||||||
	/* octet 11 */
 | 
					 | 
				
			||||||
	uint8_t handling_prio:2;
 | 
					 | 
				
			||||||
	uint8_t xfer_delay:6;
 | 
					 | 
				
			||||||
	/* octet 12 */
 | 
					 | 
				
			||||||
	uint8_t guar_bitrate_up;
 | 
					 | 
				
			||||||
	/* octet 13 */
 | 
					 | 
				
			||||||
	uint8_t guar_bitrate_down;
 | 
					 | 
				
			||||||
	/* octet 14 */
 | 
					 | 
				
			||||||
	uint8_t src_stats_desc:4;
 | 
					 | 
				
			||||||
	uint8_t sig_ind:1;
 | 
					 | 
				
			||||||
	uint8_t spare5:3;
 | 
					 | 
				
			||||||
	/* octet 15 */
 | 
					 | 
				
			||||||
	uint8_t max_bitrate_down_ext;
 | 
					 | 
				
			||||||
	/* octet 16 */
 | 
					 | 
				
			||||||
	uint8_t guar_bitrate_down_ext;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gprs_tlli_type(uint32_t tlli);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _GSM48_GPRS_H */
 | 
					 | 
				
			||||||
@@ -1,9 +1,187 @@
 | 
				
			|||||||
#ifndef _GSM_04_11_H
 | 
					#ifndef _GSM_04_11_H
 | 
				
			||||||
#define _GSM_04_11_H
 | 
					#define _GSM_04_11_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/protocol/gsm_04_11.h>
 | 
					/* GSM TS 04.11  definitions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define UM_SAPI_SMS 3	/* See GSM 04.05/04.06 */
 | 
					/* Chapter 5.2.3: SMC-CS states at the network side */
 | 
				
			||||||
 | 
					enum gsm411_cp_state {
 | 
				
			||||||
 | 
						GSM411_CPS_IDLE 		= 0,
 | 
				
			||||||
 | 
						GSM411_CPS_MM_CONN_PENDING	= 1,	/* only MT ! */
 | 
				
			||||||
 | 
						GSM411_CPS_WAIT_CP_ACK		= 2,
 | 
				
			||||||
 | 
						GSM411_CPS_MM_ESTABLISHED	= 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 6.2.2: SMR states at the network side */
 | 
				
			||||||
 | 
					enum gsm411_rp_state {
 | 
				
			||||||
 | 
						GSM411_RPS_IDLE			= 0,
 | 
				
			||||||
 | 
						GSM411_RPS_WAIT_FOR_RP_ACK	= 1,
 | 
				
			||||||
 | 
						GSM411_RPS_WAIT_TO_TX_RP_ACK	= 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */
 | 
				
			||||||
 | 
					#define GSM411_PDISC_SMS	0x09
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 8.1.3 */
 | 
				
			||||||
 | 
					#define GSM411_MT_CP_DATA	0x01
 | 
				
			||||||
 | 
					#define GSM411_MT_CP_ACK	0x04
 | 
				
			||||||
 | 
					#define GSM411_MT_CP_ERROR	0x10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsm411_cp_ie {
 | 
				
			||||||
 | 
						GSM411_CP_IE_USER_DATA		= 0x01,	/* 8.1.4.1 */
 | 
				
			||||||
 | 
						GSM411_CP_IE_CAUSE		= 0x02,	/* 8.1.4.2. */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 8.1.4.2 / Table 8.2 */
 | 
				
			||||||
 | 
					enum gsm411_cp_cause {
 | 
				
			||||||
 | 
						GSM411_CP_CAUSE_NET_FAIL	= 17,
 | 
				
			||||||
 | 
						GSM411_CP_CAUSE_CONGESTION	= 22,
 | 
				
			||||||
 | 
						GSM411_CP_CAUSE_INV_TRANS_ID	= 81,
 | 
				
			||||||
 | 
						GSM411_CP_CAUSE_SEMANT_INC_MSG	= 95,
 | 
				
			||||||
 | 
						GSM411_CP_CAUSE_INV_MAND_INF	= 96,
 | 
				
			||||||
 | 
						GSM411_CP_CAUSE_MSGTYPE_NOTEXIST= 97,
 | 
				
			||||||
 | 
						GSM411_CP_CAUSE_MSG_INCOMP_STATE= 98,
 | 
				
			||||||
 | 
						GSM411_CP_CAUSE_IE_NOTEXIST	= 99,
 | 
				
			||||||
 | 
						GSM411_CP_CAUSE_PROTOCOL_ERR	= 111,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 8.2.2 */
 | 
				
			||||||
 | 
					#define GSM411_MT_RP_DATA_MO	0x00
 | 
				
			||||||
 | 
					#define GSM411_MT_RP_DATA_MT	0x01
 | 
				
			||||||
 | 
					#define GSM411_MT_RP_ACK_MO	0x02
 | 
				
			||||||
 | 
					#define GSM411_MT_RP_ACK_MT	0x03
 | 
				
			||||||
 | 
					#define GSM411_MT_RP_ERROR_MO	0x04
 | 
				
			||||||
 | 
					#define GSM411_MT_RP_ERROR_MT	0x05
 | 
				
			||||||
 | 
					#define GSM411_MT_RP_SMMA_MO	0x06
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsm411_rp_ie {
 | 
				
			||||||
 | 
						GSM411_IE_RP_USER_DATA		= 0x41,	/* 8.2.5.3 */
 | 
				
			||||||
 | 
						GSM411_IE_RP_CAUSE		= 0x42,	/* 8.2.5.4 */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 8.2.5.4 Table 8.4 */
 | 
				
			||||||
 | 
					enum gsm411_rp_cause {
 | 
				
			||||||
 | 
						/* valid only for MO */
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_NUM_UNASSIGNED	= 1,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_OP_DET_BARR		= 8,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_CALL_BARRED		= 10,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_SMS_REJECTED		= 21,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER	= 27,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR	= 28,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_FACILITY_REJ		= 29,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR	= 30,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER	= 38,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_TEMP_FAIL		= 41,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_CONGESTION		= 42,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_RES_UNAVAIL		= 47,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR	= 50,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL	= 69,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MO_INTERWORKING		= 127,
 | 
				
			||||||
 | 
						/* valid only for MT */
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MT_MEM_EXCEEDED		= 22,
 | 
				
			||||||
 | 
						/* valid for both directions */
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_INV_TRANS_REF		= 81,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_SEMANT_INC_MSG		= 95,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_INV_MAND_INF		= 96,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MSGTYPE_NOTEXIST	= 97,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_MSG_INCOMP_STATE	= 98,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_IE_NOTEXIST		= 99,
 | 
				
			||||||
 | 
						GSM411_RP_CAUSE_PROTOCOL_ERR		= 111,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 10: Timers */
 | 
				
			||||||
 | 
					#define GSM411_TMR_TR1M		40, 0	/* 35 < x < 45 seconds */
 | 
				
			||||||
 | 
					#define GSM411_TMR_TRAM		30, 0	/* 25 < x < 35 seconds */
 | 
				
			||||||
 | 
					#define GSM411_TMR_TR2M		15, 0	/* 12 < x < 20 seconds */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM411_TMR_TC1A		30, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Chapter 8.2.1 */
 | 
				
			||||||
 | 
					struct gsm411_rp_hdr {
 | 
				
			||||||
 | 
						u_int8_t len;
 | 
				
			||||||
 | 
						u_int8_t msg_type;
 | 
				
			||||||
 | 
						u_int8_t msg_ref;
 | 
				
			||||||
 | 
						u_int8_t data[0];
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* our own enum, not related to on-air protocol */
 | 
				
			||||||
 | 
					enum sms_alphabet {
 | 
				
			||||||
 | 
						DCS_NONE,
 | 
				
			||||||
 | 
						DCS_7BIT_DEFAULT,
 | 
				
			||||||
 | 
						DCS_UCS2,
 | 
				
			||||||
 | 
						DCS_8BIT_DATA,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 03.40 / Chapter 9.2.3.1: TP-Message-Type-Indicator */
 | 
				
			||||||
 | 
					#define GSM340_SMS_DELIVER_SC2MS	0x00
 | 
				
			||||||
 | 
					#define GSM340_SMS_DELIVER_REP_MS2SC	0x00
 | 
				
			||||||
 | 
					#define GSM340_SMS_STATUS_REP_SC2MS	0x02
 | 
				
			||||||
 | 
					#define GSM340_SMS_COMMAND_MS2SC	0x02
 | 
				
			||||||
 | 
					#define GSM340_SMS_SUBMIT_MS2SC		0x01
 | 
				
			||||||
 | 
					#define GSM340_SMS_SUBMIT_REP_SC2MS	0x01
 | 
				
			||||||
 | 
					#define GSM340_SMS_RESSERVED		0x03
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 03.40 / Chapter 9.2.3.2: TP-More-Messages-to-Send */
 | 
				
			||||||
 | 
					#define GSM340_TP_MMS_MORE		0
 | 
				
			||||||
 | 
					#define GSM340_TP_MMS_NO_MORE		1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 03.40 / Chapter 9.2.3.3: TP-Validity-Period-Format */
 | 
				
			||||||
 | 
					#define GSM340_TP_VPF_NONE		0
 | 
				
			||||||
 | 
					#define GSM340_TP_VPF_RELATIVE		2
 | 
				
			||||||
 | 
					#define GSM340_TP_VPF_ENHANCED		1
 | 
				
			||||||
 | 
					#define GSM340_TP_VPF_ABSOLUTE		3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 03.40 / Chapter 9.2.3.4: TP-Status-Report-Indication */
 | 
				
			||||||
 | 
					#define GSM340_TP_SRI_NONE		0
 | 
				
			||||||
 | 
					#define GSM340_TP_SRI_PRESENT		1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 03.40 / Chapter 9.2.3.5: TP-Status-Report-Request */
 | 
				
			||||||
 | 
					#define GSM340_TP_SRR_NONE		0
 | 
				
			||||||
 | 
					#define GSM340_TP_SRR_REQUESTED		1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 03.40 / Chapter 9.2.3.9: TP-Protocol-Identifier */
 | 
				
			||||||
 | 
					/* telematic interworking (001 or 111 in bits 7-5) */
 | 
				
			||||||
 | 
					#define GSM340_TP_PID_IMPLICIT		0x00
 | 
				
			||||||
 | 
					#define GSM340_TP_PID_TELEX		0x01
 | 
				
			||||||
 | 
					#define GSM340_TP_PID_FAX_G3		0x02
 | 
				
			||||||
 | 
					#define GSM340_TP_PID_FAX_G4		0x03
 | 
				
			||||||
 | 
					#define GSM340_TP_PID_VOICE		0x04
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_ERMES		0x05
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_NATIONAL_PAGING	0x06
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_VIDEOTEX		0x07
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_TELETEX_UNSPEC	0x08
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_TELETEX_PSPDN	0x09
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_TELETEX_CSPDN	0x0a
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_TELETEX_PSTN	0x0b
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_TELETEX_ISDN	0x0c
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_TELETEX_UCI	0x0d
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_MSG_HANDLING	0x10
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_MSG_X400		0x11
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_EMAIL		0x12
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_GSM_MS		0x1f
 | 
				
			||||||
 | 
					/* if bit 7 = 0 and bit 6 = 1 */
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_SMS_TYPE_0	0
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_SMS_TYPE_1	1
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_SMS_TYPE_2	2
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_SMS_TYPE_3	3
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_SMS_TYPE_4	4
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_SMS_TYPE_5	5
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_SMS_TYPE_6	6
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_SMS_TYPE_7	7
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_RETURN_CALL_MSG	0x1f
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_ME_DATA_DNLOAD	0x3d
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_ME_DE_PERSONAL	0x3e
 | 
				
			||||||
 | 
					#define GSM430_TP_PID_ME_SIM_DNLOAD	0x3f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM 03.38 Chapter 4: SMS Data Coding Scheme */
 | 
				
			||||||
 | 
					#define GSM338_DCS_00_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM338_DCS_1110_7BIT		(0 << 2)
 | 
				
			||||||
 | 
					#define GSM338_DCS_1111_7BIT		(0 << 2)
 | 
				
			||||||
 | 
					#define GSM338_DCS_1111_8BIT_DATA	(1 << 2)
 | 
				
			||||||
 | 
					#define GSM338_DCS_1111_CLASS0		0
 | 
				
			||||||
 | 
					#define GSM338_DCS_1111_CLASS1_ME	1
 | 
				
			||||||
 | 
					#define GSM338_DCS_1111_CLASS2_SIM	2
 | 
				
			||||||
 | 
					#define GSM338_DCS_1111_CLASS3_TE	3	/* See TS 07.05 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SMS deliver PDU */
 | 
					/* SMS deliver PDU */
 | 
				
			||||||
struct sms_deliver {
 | 
					struct sms_deliver {
 | 
				
			||||||
@@ -25,7 +203,9 @@ struct sms_deliver {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct msgb;
 | 
					struct msgb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, struct msgb *msg);
 | 
					int gsm0411_rcv_sms(struct msgb *msg, u_int8_t link_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_sms *sms_alloc(void);
 | 
					struct gsm_sms *sms_alloc(void);
 | 
				
			||||||
void sms_free(struct gsm_sms *sms);
 | 
					void sms_free(struct gsm_sms *sms);
 | 
				
			||||||
@@ -33,5 +213,4 @@ void sms_free(struct gsm_sms *sms);
 | 
				
			|||||||
void _gsm411_sms_trans_free(struct gsm_trans *trans);
 | 
					void _gsm411_sms_trans_free(struct gsm_trans *trans);
 | 
				
			||||||
int gsm411_send_sms_subscr(struct gsm_subscriber *subscr,
 | 
					int gsm411_send_sms_subscr(struct gsm_subscriber *subscr,
 | 
				
			||||||
			   struct gsm_sms *sms);
 | 
								   struct gsm_sms *sms);
 | 
				
			||||||
void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn);
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,132 @@
 | 
				
			|||||||
#ifndef _GSM_04_80_H
 | 
					#ifndef _GSM_04_80_H
 | 
				
			||||||
#define _GSM_04_80_H
 | 
					#define _GSM_04_80_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					/* GSM TS 04.80  definitions (Supplementary Services Specification, Formats and Coding) */
 | 
				
			||||||
#include <osmocore/protocol/gsm_04_80.h>
 | 
					
 | 
				
			||||||
 | 
					/* Section 3.4 */
 | 
				
			||||||
 | 
					#define GSM0480_MTYPE_RELEASE_COMPLETE	0x2A
 | 
				
			||||||
 | 
					#define GSM0480_MTYPE_FACILITY			0x3A
 | 
				
			||||||
 | 
					#define GSM0480_MTYPE_REGISTER			0x3B
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 3.5 */
 | 
				
			||||||
 | 
					#define GSM0480_IE_FACILITY			0x1C
 | 
				
			||||||
 | 
					#define GSM0480_IE_SS_VERSION			0x7F
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 3.6.2 */
 | 
				
			||||||
 | 
					#define GSM0480_CTYPE_INVOKE			0xA1
 | 
				
			||||||
 | 
					#define GSM0480_CTYPE_RETURN_RESULT		0xA2
 | 
				
			||||||
 | 
					#define GSM0480_CTYPE_RETURN_ERROR		0xA3
 | 
				
			||||||
 | 
					#define GSM0480_CTYPE_REJECT			0xA4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 3.6.3 */
 | 
				
			||||||
 | 
					#define GSM0480_COMPIDTAG_INVOKE_ID		0x02
 | 
				
			||||||
 | 
					#define GSM0480_COMPIDTAG_LINKED_ID		0x80
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 3.6.4 */
 | 
				
			||||||
 | 
					#define GSM0480_OPERATION_CODE			0x02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 3.6.5 */
 | 
				
			||||||
 | 
					#define GSM_0480_SEQUENCE_TAG			0x30
 | 
				
			||||||
 | 
					#define GSM_0480_SET_TAG			0x31
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 3.6.6 */
 | 
				
			||||||
 | 
					#define GSM_0480_ERROR_CODE_TAG			0x02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 3.6.7 */
 | 
				
			||||||
 | 
					/* Table 3.13 */
 | 
				
			||||||
 | 
					#define GSM_0480_PROBLEM_CODE_TAG_GENERAL	0x80
 | 
				
			||||||
 | 
					#define GSM_0480_PROBLEM_CODE_TAG_INVOKE	0x81
 | 
				
			||||||
 | 
					#define GSM_0480_PROBLEM_CODE_TAG_RETURN_RESULT	0x82
 | 
				
			||||||
 | 
					#define GSM_0480_PROBLEM_CODE_TAG_RETURN_ERROR	0x83
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 3.14 */
 | 
				
			||||||
 | 
					#define GSM_0480_GEN_PROB_CODE_UNRECOGNISED	0x00
 | 
				
			||||||
 | 
					#define GSM_0480_GEN_PROB_CODE_MISTYPED		0x01
 | 
				
			||||||
 | 
					#define GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE	0x02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 3.15 */
 | 
				
			||||||
 | 
					#define GSM_0480_INVOKE_PROB_CODE_DUPLICATE_INVOKE_ID		0x00
 | 
				
			||||||
 | 
					#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION	0x01
 | 
				
			||||||
 | 
					#define GSM_0480_INVOKE_PROB_CODE_MISTYPED_PARAMETER		0x02
 | 
				
			||||||
 | 
					#define GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION		0x03
 | 
				
			||||||
 | 
					#define GSM_0480_INVOKE_PROB_CODE_INITIATING_RELEASE		0x04
 | 
				
			||||||
 | 
					#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_LINKED_ID	0x05
 | 
				
			||||||
 | 
					#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_RESPONSE	0x06
 | 
				
			||||||
 | 
					#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_OPERATION	0x07
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 3.16 */
 | 
				
			||||||
 | 
					#define GSM_0480_RESULT_PROB_CODE_UNRECOGNISED_INVOKE_ID	0x00
 | 
				
			||||||
 | 
					#define GSM_0480_RESULT_PROB_CODE_RETURN_RESULT_UNEXPECTED	0x01
 | 
				
			||||||
 | 
					#define GSM_0480_RESULT_PROB_CODE_MISTYPED_PARAMETER		0x02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 3.17 */
 | 
				
			||||||
 | 
					#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_INVOKE_ID		0x00
 | 
				
			||||||
 | 
					#define GSM_0480_ERROR_PROB_CODE_RETURN_ERROR_UNEXPECTED	0x01
 | 
				
			||||||
 | 
					#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_ERROR		0x02
 | 
				
			||||||
 | 
					#define GSM_0480_ERROR_PROB_CODE_UNEXPECTED_ERROR		0x03
 | 
				
			||||||
 | 
					#define GSM_0480_ERROR_PROB_CODE_MISTYPED_PARAMETER		0x04
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section 4.5 */
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_REGISTER_SS		0x0A
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_ERASE_SS		0x0B
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_ACTIVATE_SS		0x0C
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_DEACTIVATE_SS		0x0D
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_INTERROGATE_SS		0x0E
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_NOTIFY_SS		0x10
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_REGISTER_PASSWORD	0x11
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_GET_PASSWORD		0x12
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_PROCESS_USS_DATA	0x13
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_FORWARD_CHECK_SS_IND	0x26
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_PROCESS_USS_REQ		0x3B
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_USS_REQUEST		0x3C
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_USS_NOTIFY		0x3D
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_FORWARD_CUG_INFO	0x78
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_SPLIT_MPTY		0x79
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_RETRIEVE_MPTY		0x7A
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_HOLD_MPTY		0x7B
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_BUILD_MPTY		0x7C
 | 
				
			||||||
 | 
					#define GSM0480_OP_CODE_FORWARD_CHARGE_ADVICE	0x7D
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER			0x01
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER			0x09
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED		0x0A
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED		0x0B
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT			0x0C
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_CALL_BARRED				0x0D
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION			0x10
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_SS_ERROR_STATUS			0x11
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_SS_NOT_AVAILABLE			0x12
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION		0x13
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_SS_INCOMPATIBILITY			0x14
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED			0x15
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_ABSENT_SUBSCRIBER			0x1B
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_SYSTEM_FAILURE				0x22
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_DATA_MISSING				0x23
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE			0x24
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE		0x25
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_NEGATIVE_PW_CHECK			0x26
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION		0x2B
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_UNKNOWN_ALPHABET			0x47
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_USSD_BUSY				0x48
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS			0x7E
 | 
				
			||||||
 | 
					#define GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE		0x7F
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ASN.1 type-tags */
 | 
				
			||||||
 | 
					#define ASN1_BOOLEAN_TAG		0x01
 | 
				
			||||||
 | 
					#define ASN1_INTEGER_TAG		0x02
 | 
				
			||||||
 | 
					#define ASN1_BIT_STRING_TAG		0x03
 | 
				
			||||||
 | 
					#define ASN1_OCTET_STRING_TAG		0x04
 | 
				
			||||||
 | 
					#define ASN1_NULL_TYPE_TAG		0x05
 | 
				
			||||||
 | 
					#define ASN1_OBJECT_ID_TAG		0x06
 | 
				
			||||||
 | 
					#define ASN1_UTF8_STRING_TAG		0x0C
 | 
				
			||||||
 | 
					#define ASN1_PRINTABLE_STRING_TAG	0x13
 | 
				
			||||||
 | 
					#define ASN1_IA5_STRING_TAG		0x16
 | 
				
			||||||
 | 
					#define ASN1_UNICODE_STRING_TAG		0x1E
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openbsc/msgb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_LEN_USSD_STRING	31
 | 
					#define MAX_LEN_USSD_STRING	31
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_subscriber_connection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct ussd_request {
 | 
					struct ussd_request {
 | 
				
			||||||
			char text[MAX_LEN_USSD_STRING + 1];
 | 
								char text[MAX_LEN_USSD_STRING + 1];
 | 
				
			||||||
			u_int8_t transaction_id;
 | 
								u_int8_t transaction_id;
 | 
				
			||||||
@@ -16,20 +135,9 @@ struct ussd_request {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int gsm0480_decode_ussd_request(const struct msgb *msg, 
 | 
					int gsm0480_decode_ussd_request(const struct msgb *msg, 
 | 
				
			||||||
				struct ussd_request *request); 
 | 
									struct ussd_request *request); 
 | 
				
			||||||
int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
 | 
					int gsm0480_send_ussd_response(const struct msgb *in_msg, const char* response_text, 
 | 
				
			||||||
			       const struct msgb *in_msg, const char* response_text, 
 | 
											const struct ussd_request *req);
 | 
				
			||||||
			       const struct ussd_request *req);
 | 
					int gsm0480_send_ussd_reject(const struct msgb *msg, 
 | 
				
			||||||
int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
 | 
									const struct ussd_request *request);
 | 
				
			||||||
			     const struct msgb *msg, 
 | 
					 | 
				
			||||||
			     const struct ussd_request *request);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct msgb *gsm0480_create_notifySS(const char *text);
 | 
					 | 
				
			||||||
struct msgb *gsm0480_create_unstructuredSS_Notify(int alertLevel, const char *text);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gsm0480_wrap_invoke(struct msgb *msg, int op, int link_id);
 | 
					 | 
				
			||||||
int gsm0480_wrap_facility(struct msgb *msg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gsm0480_send_ussdNotify(struct gsm_subscriber_connection *conn, int level, const char *text);
 | 
					 | 
				
			||||||
int gsm0480_send_releaseComplete(struct gsm_subscriber_connection *conn);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,21 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct value_string {
 | 
				
			||||||
 | 
						unsigned int value;
 | 
				
			||||||
 | 
						const char *str;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *get_value_string(const struct value_string *vs, u_int32_t val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum gsm_band {
 | 
				
			||||||
 | 
						GSM_BAND_400,
 | 
				
			||||||
 | 
						GSM_BAND_850,
 | 
				
			||||||
 | 
						GSM_BAND_900,
 | 
				
			||||||
 | 
						GSM_BAND_1800,
 | 
				
			||||||
 | 
						GSM_BAND_1900,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum gsm_phys_chan_config {
 | 
					enum gsm_phys_chan_config {
 | 
				
			||||||
	GSM_PCHAN_NONE,
 | 
						GSM_PCHAN_NONE,
 | 
				
			||||||
	GSM_PCHAN_CCCH,
 | 
						GSM_PCHAN_CCCH,
 | 
				
			||||||
@@ -40,18 +55,14 @@ enum gsm_chreq_reason_t {
 | 
				
			|||||||
	GSM_CHREQ_REASON_OTHER,
 | 
						GSM_CHREQ_REASON_OTHER,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/timer.h>
 | 
					#include <openbsc/timer.h>
 | 
				
			||||||
#include <openbsc/gsm_04_08.h>
 | 
					#include <openbsc/gsm_04_08.h>
 | 
				
			||||||
#include <openbsc/abis_rsl.h>
 | 
					#include <openbsc/abis_rsl.h>
 | 
				
			||||||
#include <openbsc/system_information.h>
 | 
					 | 
				
			||||||
#include <openbsc/mncc.h>
 | 
					#include <openbsc/mncc.h>
 | 
				
			||||||
 | 
					#include <openbsc/tlv.h>
 | 
				
			||||||
 | 
					#include <openbsc/bitvec.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/tlv.h>
 | 
					#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 | 
				
			||||||
#include <osmocore/bitvec.h>
 | 
					 | 
				
			||||||
#include <osmocore/statistics.h>
 | 
					 | 
				
			||||||
#include <osmocore/gsm_utils.h>
 | 
					 | 
				
			||||||
#include <osmocore/utils.h>
 | 
					 | 
				
			||||||
#include <osmocore/rxlev_stat.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TRX_NR_TS	8
 | 
					#define TRX_NR_TS	8
 | 
				
			||||||
#define TS_MAX_LCHAN	8
 | 
					#define TS_MAX_LCHAN	8
 | 
				
			||||||
@@ -68,7 +79,6 @@ enum gsm_chreq_reason_t {
 | 
				
			|||||||
enum gsm_hooks {
 | 
					enum gsm_hooks {
 | 
				
			||||||
	GSM_HOOK_NM_SWLOAD,
 | 
						GSM_HOOK_NM_SWLOAD,
 | 
				
			||||||
	GSM_HOOK_RR_PAGING,
 | 
						GSM_HOOK_RR_PAGING,
 | 
				
			||||||
	GSM_HOOK_RR_SECURITY,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum gsm_paging_event {
 | 
					enum gsm_paging_event {
 | 
				
			||||||
@@ -77,79 +87,56 @@ enum gsm_paging_event {
 | 
				
			|||||||
	GSM_PAGING_OOM,
 | 
						GSM_PAGING_OOM,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum bts_gprs_mode {
 | 
					 | 
				
			||||||
	BTS_GPRS_NONE = 0,
 | 
					 | 
				
			||||||
	BTS_GPRS_GPRS = 1,
 | 
					 | 
				
			||||||
	BTS_GPRS_EGPRS = 2,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* the data structure stored in msgb->cb for openbsc apps */
 | 
					 | 
				
			||||||
struct openbsc_msgb_cb {
 | 
					 | 
				
			||||||
	unsigned char *bssgph;
 | 
					 | 
				
			||||||
	unsigned char *llch;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Cell Identifier */
 | 
					 | 
				
			||||||
	unsigned char *bssgp_cell_id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Identifiers of a BTS, equal to 'struct bssgp_bts_ctx' */
 | 
					 | 
				
			||||||
	u_int16_t nsei;
 | 
					 | 
				
			||||||
	u_int16_t bvci;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Identifier of a MS (inside BTS), equal to 'struct sgsn_mm_ctx' */
 | 
					 | 
				
			||||||
	u_int32_t tlli;
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
#define OBSC_MSGB_CB(__msgb)	((struct openbsc_msgb_cb *)&((__msgb)->cb[0]))
 | 
					 | 
				
			||||||
#define msgb_tlli(__x)		OBSC_MSGB_CB(__x)->tlli
 | 
					 | 
				
			||||||
#define msgb_nsei(__x)		OBSC_MSGB_CB(__x)->nsei
 | 
					 | 
				
			||||||
#define msgb_bvci(__x)		OBSC_MSGB_CB(__x)->bvci
 | 
					 | 
				
			||||||
#define msgb_gmmh(__x)		(__x)->l3h
 | 
					 | 
				
			||||||
#define msgb_bssgph(__x)	OBSC_MSGB_CB(__x)->bssgph
 | 
					 | 
				
			||||||
#define msgb_bssgp_len(__x)	((__x)->tail - (uint8_t *)msgb_bssgph(__x))
 | 
					 | 
				
			||||||
#define msgb_bcid(__x)		OBSC_MSGB_CB(__x)->bssgp_cell_id
 | 
					 | 
				
			||||||
#define msgb_llch(__x)		OBSC_MSGB_CB(__x)->llch
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define OBSC_LINKID_CB(__msgb)	(__msgb)->cb[3]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gsm_security_event {
 | 
					 | 
				
			||||||
	GSM_SECURITY_NOAVAIL,
 | 
					 | 
				
			||||||
	GSM_SECURITY_AUTH_FAILED,
 | 
					 | 
				
			||||||
	GSM_SECURITY_SUCCEEDED,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct msgb;
 | 
					struct msgb;
 | 
				
			||||||
typedef int gsm_cbfn(unsigned int hooknum,
 | 
					typedef int gsm_cbfn(unsigned int hooknum,
 | 
				
			||||||
		     unsigned int event,
 | 
							     unsigned int event,
 | 
				
			||||||
		     struct msgb *msg,
 | 
							     struct msgb *msg,
 | 
				
			||||||
		     void *data, void *param);
 | 
							     void *data, void *param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Real authentication information containing Ki */
 | 
					/* communications link with a BTS */
 | 
				
			||||||
enum gsm_auth_algo {
 | 
					struct gsm_bts_link {
 | 
				
			||||||
	AUTH_ALGO_NONE,
 | 
						struct gsm_bts *bts;
 | 
				
			||||||
	AUTH_ALGO_XOR,
 | 
					 | 
				
			||||||
	AUTH_ALGO_COMP128v1,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_auth_info {
 | 
					struct sccp_connection;
 | 
				
			||||||
	enum gsm_auth_algo auth_algo;
 | 
					 | 
				
			||||||
	unsigned int a3a8_ki_len;
 | 
					 | 
				
			||||||
	u_int8_t a3a8_ki[16];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_auth_tuple {
 | 
					 | 
				
			||||||
	int use_count;
 | 
					 | 
				
			||||||
	int key_seq;
 | 
					 | 
				
			||||||
	u_int8_t rand[16];
 | 
					 | 
				
			||||||
	u_int8_t sres[4];
 | 
					 | 
				
			||||||
	u_int8_t kc[8];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
#define GSM_KEY_SEQ_INVAL	7	/* GSM 04.08 - 10.5.1.2 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_lchan;
 | 
					struct gsm_lchan;
 | 
				
			||||||
struct gsm_subscriber;
 | 
					struct gsm_subscriber;
 | 
				
			||||||
struct gsm_mncc;
 | 
					struct gsm_mncc;
 | 
				
			||||||
struct rtp_socket;
 | 
					struct rtp_socket;
 | 
				
			||||||
struct bsc_api;
 | 
					
 | 
				
			||||||
 | 
					/* BSC/MSC data holding them together */
 | 
				
			||||||
 | 
					struct bss_sccp_connection_data {
 | 
				
			||||||
 | 
						struct gsm_lchan *lchan;
 | 
				
			||||||
 | 
						struct gsm_lchan *secondary_lchan;
 | 
				
			||||||
 | 
						struct sccp_connection *sccp;
 | 
				
			||||||
 | 
						int ciphering_handled : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Timers... */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* for assginment command */
 | 
				
			||||||
 | 
					        struct timer_list T10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* for SCCP ... */
 | 
				
			||||||
 | 
						struct timer_list sccp_it;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* audio handling */
 | 
				
			||||||
 | 
						int rtp_port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Queue SCCP and GSM0408 messages */
 | 
				
			||||||
 | 
						int block_gsm;
 | 
				
			||||||
 | 
						struct llist_head gsm_queue;
 | 
				
			||||||
 | 
						unsigned int gsm_queue_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct llist_head sccp_queue;
 | 
				
			||||||
 | 
						unsigned int sccp_queue_size;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GSM0808_T10_VALUE	6, 0
 | 
				
			||||||
 | 
					#define sccp_get_lchan(data_ctx) ((struct bss_sccp_connection_data *)data_ctx)->lchan
 | 
				
			||||||
 | 
					#define lchan_get_sccp(lchan) lchan->msc_data->sccp
 | 
				
			||||||
 | 
					struct bss_sccp_connection_data *bss_sccp_create_data();
 | 
				
			||||||
 | 
					void bss_sccp_free_data(struct bss_sccp_connection_data *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Network Management State */
 | 
					/* Network Management State */
 | 
				
			||||||
struct gsm_nm_state {
 | 
					struct gsm_nm_state {
 | 
				
			||||||
@@ -169,24 +156,6 @@ struct gsm_loc_updating_operation {
 | 
				
			|||||||
        struct timer_list updating_timer;
 | 
					        struct timer_list updating_timer;
 | 
				
			||||||
	unsigned int waiting_for_imsi : 1;
 | 
						unsigned int waiting_for_imsi : 1;
 | 
				
			||||||
	unsigned int waiting_for_imei : 1;
 | 
						unsigned int waiting_for_imei : 1;
 | 
				
			||||||
	unsigned int key_seq : 4;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * AUTHENTICATION/CIPHERING state
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct gsm_security_operation {
 | 
					 | 
				
			||||||
	struct gsm_auth_tuple atuple;
 | 
					 | 
				
			||||||
	gsm_cbfn *cb;
 | 
					 | 
				
			||||||
	void *cb_data;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * A dummy to keep a connection up for at least
 | 
					 | 
				
			||||||
 * a couple of seconds to work around MSC issues.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct gsm_anchor_operation {
 | 
					 | 
				
			||||||
	struct timer_list timeout;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Maximum number of neighbor cells whose average we track */
 | 
					/* Maximum number of neighbor cells whose average we track */
 | 
				
			||||||
@@ -204,9 +173,6 @@ struct neigh_meas_proc {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_A5_KEY_LEN	(128/8)
 | 
					#define MAX_A5_KEY_LEN	(128/8)
 | 
				
			||||||
#define A38_XOR_MIN_KEY_LEN	12
 | 
					 | 
				
			||||||
#define A38_XOR_MAX_KEY_LEN	16
 | 
					 | 
				
			||||||
#define A38_COMP128_KEY_LEN	16
 | 
					 | 
				
			||||||
#define RSL_ENC_ALG_A5(x)	(x+1)
 | 
					#define RSL_ENC_ALG_A5(x)	(x+1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* is the data link established? who established it? */
 | 
					/* is the data link established? who established it? */
 | 
				
			||||||
@@ -217,35 +183,10 @@ struct neigh_meas_proc {
 | 
				
			|||||||
/* state of a logical channel */
 | 
					/* state of a logical channel */
 | 
				
			||||||
enum gsm_lchan_state {
 | 
					enum gsm_lchan_state {
 | 
				
			||||||
	LCHAN_S_NONE,		/* channel is not active */
 | 
						LCHAN_S_NONE,		/* channel is not active */
 | 
				
			||||||
	LCHAN_S_ACT_REQ,	/* channel activatin requested */
 | 
					 | 
				
			||||||
	LCHAN_S_ACTIVE,		/* channel is active and operational */
 | 
						LCHAN_S_ACTIVE,		/* channel is active and operational */
 | 
				
			||||||
	LCHAN_S_REL_REQ,	/* channel release has been requested */
 | 
					 | 
				
			||||||
	LCHAN_S_REL_ERR,	/* channel is in an error state */
 | 
					 | 
				
			||||||
	LCHAN_S_INACTIVE,	/* channel is set inactive */
 | 
						LCHAN_S_INACTIVE,	/* channel is set inactive */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* the per subscriber data for lchan */
 | 
					 | 
				
			||||||
struct gsm_subscriber_connection {
 | 
					 | 
				
			||||||
	/* To whom we are allocated at the moment */
 | 
					 | 
				
			||||||
	struct gsm_subscriber *subscr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Operations that have a state and might be pending
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	struct gsm_loc_updating_operation *loc_operation;
 | 
					 | 
				
			||||||
	struct gsm_security_operation *sec_operation;
 | 
					 | 
				
			||||||
	struct gsm_anchor_operation *anch_operation;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Are we part of a special "silent" call */
 | 
					 | 
				
			||||||
	int silent_call;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* back pointers */
 | 
					 | 
				
			||||||
	int in_release;
 | 
					 | 
				
			||||||
	struct gsm_lchan *lchan;
 | 
					 | 
				
			||||||
	struct gsm_lchan *ho_lchan;
 | 
					 | 
				
			||||||
	struct gsm_bts *bts;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_lchan {
 | 
					struct gsm_lchan {
 | 
				
			||||||
	/* The TS that we're part of */
 | 
						/* The TS that we're part of */
 | 
				
			||||||
	struct gsm_bts_trx_ts *ts;
 | 
						struct gsm_bts_trx_ts *ts;
 | 
				
			||||||
@@ -269,21 +210,30 @@ struct gsm_lchan {
 | 
				
			|||||||
		u_int8_t key[MAX_A5_KEY_LEN];
 | 
							u_int8_t key[MAX_A5_KEY_LEN];
 | 
				
			||||||
	} encr;
 | 
						} encr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct timer_list T3101;
 | 
					 | 
				
			||||||
	struct timer_list T3111;
 | 
					 | 
				
			||||||
	struct timer_list error_timer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* AMR bits */
 | 
						/* AMR bits */
 | 
				
			||||||
	struct gsm48_multi_rate_conf mr_conf;
 | 
						struct gsm48_multi_rate_conf mr_conf;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						/* To whom we are allocated at the moment */
 | 
				
			||||||
 | 
						struct gsm_subscriber *subscr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct timer_list T3101;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Established data link layer services */
 | 
						/* Established data link layer services */
 | 
				
			||||||
	u_int8_t sapis[8];
 | 
						u_int8_t sapis[8];
 | 
				
			||||||
	int sach_deact;
 | 
					 | 
				
			||||||
	int release_reason;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* GSM Random Access data */
 | 
						/*
 | 
				
			||||||
	struct gsm48_req_ref *rqd_ref;
 | 
						 * Operations that have a state and might be pending
 | 
				
			||||||
	uint8_t rqd_ta;
 | 
						 */
 | 
				
			||||||
 | 
						struct gsm_loc_updating_operation *loc_operation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * MSC handling...
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						struct bss_sccp_connection_data *msc_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* use count. how many users use this channel */
 | 
				
			||||||
 | 
						unsigned int use_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* cache of last measurement reports on this lchan */
 | 
						/* cache of last measurement reports on this lchan */
 | 
				
			||||||
	struct gsm_meas_rep meas_rep[6];
 | 
						struct gsm_meas_rep meas_rep[6];
 | 
				
			||||||
@@ -298,13 +248,10 @@ struct gsm_lchan {
 | 
				
			|||||||
		u_int16_t bound_port;
 | 
							u_int16_t bound_port;
 | 
				
			||||||
		u_int16_t connect_port;
 | 
							u_int16_t connect_port;
 | 
				
			||||||
		u_int16_t conn_id;
 | 
							u_int16_t conn_id;
 | 
				
			||||||
		u_int8_t rtp_payload;
 | 
					 | 
				
			||||||
		u_int8_t rtp_payload2;
 | 
							u_int8_t rtp_payload2;
 | 
				
			||||||
		u_int8_t speech_mode;
 | 
							u_int8_t speech_mode;
 | 
				
			||||||
		struct rtp_socket *rtp_socket;
 | 
							struct rtp_socket *rtp_socket;
 | 
				
			||||||
	} abis_ip;
 | 
						} abis_ip;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct gsm_subscriber_connection *conn;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_e1_subslot {
 | 
					struct gsm_e1_subslot {
 | 
				
			||||||
@@ -316,7 +263,7 @@ struct gsm_e1_subslot {
 | 
				
			|||||||
	u_int8_t	e1_ts_ss;
 | 
						u_int8_t	e1_ts_ss;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TS_F_PDCH_MODE	0x1000
 | 
					#define BTS_TRX_F_ACTIVATED	0x0001
 | 
				
			||||||
/* One Timeslot in a TRX */
 | 
					/* One Timeslot in a TRX */
 | 
				
			||||||
struct gsm_bts_trx_ts {
 | 
					struct gsm_bts_trx_ts {
 | 
				
			||||||
	struct gsm_bts_trx *trx;
 | 
						struct gsm_bts_trx *trx;
 | 
				
			||||||
@@ -330,19 +277,6 @@ struct gsm_bts_trx_ts {
 | 
				
			|||||||
	struct tlv_parsed nm_attr;
 | 
						struct tlv_parsed nm_attr;
 | 
				
			||||||
	u_int8_t nm_chan_comb;
 | 
						u_int8_t nm_chan_comb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		/* Parameters below are configured by VTY */
 | 
					 | 
				
			||||||
		int enabled;
 | 
					 | 
				
			||||||
		u_int8_t maio;
 | 
					 | 
				
			||||||
		u_int8_t hsn;
 | 
					 | 
				
			||||||
		struct bitvec arfcns;
 | 
					 | 
				
			||||||
		u_int8_t arfcns_data[1024/8];
 | 
					 | 
				
			||||||
		/* This is the pre-computed MA for channel assignments */
 | 
					 | 
				
			||||||
		struct bitvec ma;
 | 
					 | 
				
			||||||
		u_int8_t ma_len;	/* part of ma_data that is used */
 | 
					 | 
				
			||||||
		u_int8_t ma_data[8];	/* 10.5.2.21: max 8 bytes value part */
 | 
					 | 
				
			||||||
	} hopping;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* To which E1 subslot are we connected */
 | 
						/* To which E1 subslot are we connected */
 | 
				
			||||||
	struct gsm_e1_subslot e1_link;
 | 
						struct gsm_e1_subslot e1_link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -357,8 +291,6 @@ struct gsm_bts_trx {
 | 
				
			|||||||
	struct gsm_bts *bts;
 | 
						struct gsm_bts *bts;
 | 
				
			||||||
	/* number of this TRX in the BTS */
 | 
						/* number of this TRX in the BTS */
 | 
				
			||||||
	u_int8_t nr;
 | 
						u_int8_t nr;
 | 
				
			||||||
	/* human readable name / description */
 | 
					 | 
				
			||||||
	char *description;
 | 
					 | 
				
			||||||
	/* how do we talk RSL with this TRX? */
 | 
						/* how do we talk RSL with this TRX? */
 | 
				
			||||||
	struct gsm_e1_subslot rsl_e1_link;
 | 
						struct gsm_e1_subslot rsl_e1_link;
 | 
				
			||||||
	u_int8_t rsl_tei;
 | 
						u_int8_t rsl_tei;
 | 
				
			||||||
@@ -383,16 +315,12 @@ struct gsm_bts_trx {
 | 
				
			|||||||
				struct gsm_nm_state nm_state;
 | 
									struct gsm_nm_state nm_state;
 | 
				
			||||||
			} pa;
 | 
								} pa;
 | 
				
			||||||
		} bs11;
 | 
							} bs11;
 | 
				
			||||||
		struct {
 | 
					 | 
				
			||||||
			unsigned int test_state;
 | 
					 | 
				
			||||||
			u_int8_t test_nr;
 | 
					 | 
				
			||||||
			struct rxlev_stats rxlev_stat;
 | 
					 | 
				
			||||||
		} ipaccess;
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	struct gsm_bts_trx_ts ts[TRX_NR_TS];
 | 
						struct gsm_bts_trx_ts ts[TRX_NR_TS];
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GSM_BTS_SI(bts, i)	(void *)(bts->si_buf[i])
 | 
						/* NM state */
 | 
				
			||||||
 | 
						int rf_locked;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum gsm_bts_type {
 | 
					enum gsm_bts_type {
 | 
				
			||||||
	GSM_BTS_TYPE_UNKNOWN,
 | 
						GSM_BTS_TYPE_UNKNOWN,
 | 
				
			||||||
@@ -400,26 +328,6 @@ enum gsm_bts_type {
 | 
				
			|||||||
	GSM_BTS_TYPE_NANOBTS,
 | 
						GSM_BTS_TYPE_NANOBTS,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_bts_model {
 | 
					 | 
				
			||||||
	struct llist_head list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	enum gsm_bts_type type;
 | 
					 | 
				
			||||||
	const char *name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct tlv_definition nm_att_tlvdef;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct bitvec features;
 | 
					 | 
				
			||||||
	uint8_t _features_data[128/8];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum gsm_bts_features {
 | 
					 | 
				
			||||||
	BTS_FEAT_HSCSD,
 | 
					 | 
				
			||||||
	BTS_FEAT_GPRS,
 | 
					 | 
				
			||||||
	BTS_FEAT_EGPRS,
 | 
					 | 
				
			||||||
	BTS_FEAT_ECSD,
 | 
					 | 
				
			||||||
	BTS_FEAT_HOPPING,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A pending paging request 
 | 
					 * A pending paging request 
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -450,6 +358,7 @@ struct gsm_paging_request {
 | 
				
			|||||||
struct gsm_bts_paging_state {
 | 
					struct gsm_bts_paging_state {
 | 
				
			||||||
	/* pending requests */
 | 
						/* pending requests */
 | 
				
			||||||
	struct llist_head pending_requests;
 | 
						struct llist_head pending_requests;
 | 
				
			||||||
 | 
						struct gsm_paging_request *last_request;
 | 
				
			||||||
	struct gsm_bts *bts;
 | 
						struct gsm_bts *bts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct timer_list work_timer;
 | 
						struct timer_list work_timer;
 | 
				
			||||||
@@ -464,14 +373,7 @@ struct gsm_envabtse {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct gsm_bts_gprs_nsvc {
 | 
					struct gsm_bts_gprs_nsvc {
 | 
				
			||||||
	struct gsm_bts *bts;
 | 
						struct gsm_bts *bts;
 | 
				
			||||||
	/* data read via VTY config file, to configure the BTS
 | 
					 | 
				
			||||||
	 * via OML from BSC */
 | 
					 | 
				
			||||||
	int id;
 | 
						int id;
 | 
				
			||||||
	u_int16_t nsvci;
 | 
					 | 
				
			||||||
	u_int16_t local_port;	/* on the BTS */
 | 
					 | 
				
			||||||
	u_int16_t remote_port;	/* on the SGSN */
 | 
					 | 
				
			||||||
	u_int32_t remote_ip;	/* on the SGSN */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct gsm_nm_state nm_state;
 | 
						struct gsm_nm_state nm_state;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -483,8 +385,6 @@ struct gsm_bts {
 | 
				
			|||||||
	struct gsm_network *network;
 | 
						struct gsm_network *network;
 | 
				
			||||||
	/* number of ths BTS in network */
 | 
						/* number of ths BTS in network */
 | 
				
			||||||
	u_int8_t nr;
 | 
						u_int8_t nr;
 | 
				
			||||||
	/* human readable name / description */
 | 
					 | 
				
			||||||
	char *description;
 | 
					 | 
				
			||||||
	/* Cell Identity */
 | 
						/* Cell Identity */
 | 
				
			||||||
	u_int16_t cell_identity;
 | 
						u_int16_t cell_identity;
 | 
				
			||||||
	/* location area code of this BTS */
 | 
						/* location area code of this BTS */
 | 
				
			||||||
@@ -495,7 +395,6 @@ struct gsm_bts {
 | 
				
			|||||||
	u_int8_t bsic;
 | 
						u_int8_t bsic;
 | 
				
			||||||
	/* type of BTS */
 | 
						/* type of BTS */
 | 
				
			||||||
	enum gsm_bts_type type;
 | 
						enum gsm_bts_type type;
 | 
				
			||||||
	struct gsm_bts_model *model;
 | 
					 | 
				
			||||||
	enum gsm_band band;
 | 
						enum gsm_band band;
 | 
				
			||||||
	/* should the channel allocator allocate channels from high TRX to TRX0,
 | 
						/* should the channel allocator allocate channels from high TRX to TRX0,
 | 
				
			||||||
	 * rather than starting from TRX0 and go upwards? */
 | 
						 * rather than starting from TRX0 and go upwards? */
 | 
				
			||||||
@@ -542,13 +441,6 @@ struct gsm_bts {
 | 
				
			|||||||
		} data;
 | 
							} data;
 | 
				
			||||||
	} si_common;
 | 
						} si_common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* do we use static (user-defined) system information messages? (bitmask) */
 | 
					 | 
				
			||||||
	uint32_t si_mode_static;
 | 
					 | 
				
			||||||
	/* bitmask of all SI that are present/valid in si_buf */
 | 
					 | 
				
			||||||
	uint32_t si_valid;
 | 
					 | 
				
			||||||
	/* buffers where we put the pre-computed SI */
 | 
					 | 
				
			||||||
	sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* ip.accesss Unit ID's have Site/BTS/TRX layout */
 | 
						/* ip.accesss Unit ID's have Site/BTS/TRX layout */
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		struct {
 | 
							struct {
 | 
				
			||||||
@@ -569,24 +461,14 @@ struct gsm_bts {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Not entirely sure how ip.access specific this is */
 | 
						/* Not entirely sure how ip.access specific this is */
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		enum bts_gprs_mode mode;
 | 
					 | 
				
			||||||
		struct {
 | 
							struct {
 | 
				
			||||||
			struct gsm_nm_state nm_state;
 | 
								struct gsm_nm_state nm_state;
 | 
				
			||||||
			u_int16_t nsei;
 | 
					 | 
				
			||||||
			uint8_t timer[7];
 | 
					 | 
				
			||||||
		} nse;
 | 
							} nse;
 | 
				
			||||||
		struct {
 | 
							struct {
 | 
				
			||||||
			struct gsm_nm_state nm_state;
 | 
								struct gsm_nm_state nm_state;
 | 
				
			||||||
			u_int16_t bvci;
 | 
					 | 
				
			||||||
			uint8_t timer[11];
 | 
					 | 
				
			||||||
		} cell;
 | 
							} cell;
 | 
				
			||||||
		struct gsm_bts_gprs_nsvc nsvc[2];
 | 
							struct gsm_bts_gprs_nsvc nsvc[2];
 | 
				
			||||||
		u_int8_t rac;
 | 
					 | 
				
			||||||
	} gprs;
 | 
						} gprs;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* RACH NM values */
 | 
					 | 
				
			||||||
	int rach_b_thresh;
 | 
					 | 
				
			||||||
	int rach_ldavg_slots;
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/* transceivers */
 | 
						/* transceivers */
 | 
				
			||||||
	int num_trx;
 | 
						int num_trx;
 | 
				
			||||||
@@ -596,52 +478,44 @@ struct gsm_bts {
 | 
				
			|||||||
/* Some statistics of our network */
 | 
					/* Some statistics of our network */
 | 
				
			||||||
struct gsmnet_stats {
 | 
					struct gsmnet_stats {
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct counter *total;
 | 
							unsigned long total;
 | 
				
			||||||
		struct counter *no_channel;
 | 
							unsigned long no_channel;
 | 
				
			||||||
	} chreq;
 | 
						} chreq;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct counter *attempted;
 | 
							unsigned long attempted;
 | 
				
			||||||
		struct counter *no_channel;	/* no channel available */
 | 
							unsigned long no_channel;	/* no channel available */
 | 
				
			||||||
		struct counter *timeout;		/* T3103 timeout */
 | 
							unsigned long timeout;		/* T3103 timeout */
 | 
				
			||||||
		struct counter *completed;	/* HO COMPL received */
 | 
							unsigned long completed;	/* HO COMPL received */
 | 
				
			||||||
		struct counter *failed;		/* HO FAIL received */
 | 
							unsigned long failed;		/* HO FAIL received */
 | 
				
			||||||
	} handover;
 | 
						} handover;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct counter *attach;
 | 
							unsigned long attach;
 | 
				
			||||||
		struct counter *normal;
 | 
							unsigned long normal;
 | 
				
			||||||
		struct counter *periodic;
 | 
							unsigned long periodic;
 | 
				
			||||||
		struct counter *detach;
 | 
							unsigned long detach;
 | 
				
			||||||
	} loc_upd_type;
 | 
						} loc_upd_type;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct counter *reject;
 | 
							unsigned long reject;
 | 
				
			||||||
		struct counter *accept;
 | 
							unsigned long accept;
 | 
				
			||||||
	} loc_upd_resp;
 | 
						} loc_upd_resp;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct counter *attempted;
 | 
							unsigned long attempted;
 | 
				
			||||||
		struct counter *detached;
 | 
							unsigned long detached;
 | 
				
			||||||
		struct counter *completed;
 | 
							unsigned long completed;
 | 
				
			||||||
		struct counter *expired;
 | 
							unsigned long expired;
 | 
				
			||||||
	} paging;
 | 
						} paging;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct counter *submitted; /* MO SMS submissions */
 | 
							unsigned long submitted; /* MO SMS submissions */
 | 
				
			||||||
		struct counter *no_receiver;
 | 
							unsigned long no_receiver;
 | 
				
			||||||
		struct counter *delivered; /* MT SMS deliveries */
 | 
							unsigned long delivered; /* MT SMS deliveries */
 | 
				
			||||||
		struct counter *rp_err_mem;
 | 
							unsigned long rp_err_mem;
 | 
				
			||||||
		struct counter *rp_err_other;
 | 
							unsigned long rp_err_other;
 | 
				
			||||||
	} sms;
 | 
						} sms;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct counter *dialled;	/* total number of dialled calls */
 | 
							unsigned long dialled;	/* total number of dialled calls */
 | 
				
			||||||
		struct counter *alerted;	/* we alerted the other end */
 | 
							unsigned long alerted;	/* we alerted the other end */
 | 
				
			||||||
		struct counter *connected;/* how many calls were accepted */
 | 
							unsigned long connected;/* how many calls were accepted */
 | 
				
			||||||
	} call;
 | 
						} call;
 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		struct counter *rf_fail;
 | 
					 | 
				
			||||||
		struct counter *rll_err;
 | 
					 | 
				
			||||||
	} chan;
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		struct counter *oml_fail;
 | 
					 | 
				
			||||||
		struct counter *rsl_fail;
 | 
					 | 
				
			||||||
	} bts;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum gsm_auth_policy {
 | 
					enum gsm_auth_policy {
 | 
				
			||||||
@@ -653,6 +527,14 @@ enum gsm_auth_policy {
 | 
				
			|||||||
#define GSM_T3101_DEFAULT 10
 | 
					#define GSM_T3101_DEFAULT 10
 | 
				
			||||||
#define GSM_T3113_DEFAULT 60
 | 
					#define GSM_T3113_DEFAULT 60
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * internal data for audio management
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct gsm_audio_support {
 | 
				
			||||||
 | 
						u_int8_t hr  : 1,
 | 
				
			||||||
 | 
							 ver : 7;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_network {
 | 
					struct gsm_network {
 | 
				
			||||||
	/* global parameters */
 | 
						/* global parameters */
 | 
				
			||||||
	u_int16_t country_code;
 | 
						u_int16_t country_code;
 | 
				
			||||||
@@ -683,11 +565,15 @@ struct gsm_network {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	struct gsmnet_stats stats;
 | 
						struct gsmnet_stats stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct gsm_audio_support **audio_support;
 | 
				
			||||||
 | 
						int audio_length;
 | 
				
			||||||
 | 
						int rtp_payload;
 | 
				
			||||||
 | 
						int rtp_base_port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* layer 4 */
 | 
						/* layer 4 */
 | 
				
			||||||
	int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg);
 | 
						int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg);
 | 
				
			||||||
	struct llist_head upqueue;
 | 
						struct llist_head upqueue;
 | 
				
			||||||
	struct llist_head trans_list;
 | 
						struct llist_head trans_list;
 | 
				
			||||||
	struct bsc_api *bsc_api;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned int num_bts;
 | 
						unsigned int num_bts;
 | 
				
			||||||
	struct llist_head bts_list;
 | 
						struct llist_head bts_list;
 | 
				
			||||||
@@ -709,7 +595,10 @@ struct gsm_network {
 | 
				
			|||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		enum rrlp_mode mode;
 | 
							enum rrlp_mode mode;
 | 
				
			||||||
	} rrlp;
 | 
						} rrlp;
 | 
				
			||||||
	int msc_prio;
 | 
					
 | 
				
			||||||
 | 
						/* a hack for On Waves. It must be signed */
 | 
				
			||||||
 | 
						int32_t core_country_code;
 | 
				
			||||||
 | 
						int32_t core_network_code;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SMS_HDR_SIZE	128
 | 
					#define SMS_HDR_SIZE	128
 | 
				
			||||||
@@ -734,13 +623,11 @@ struct gsm_sms {
 | 
				
			|||||||
	char text[SMS_TEXT_SIZE];
 | 
						char text[SMS_TEXT_SIZE];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_code,
 | 
					struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_code,
 | 
				
			||||||
				     int (*mncc_recv)(struct gsm_network *, int, void *));
 | 
									     int (*mncc_recv)(struct gsm_network *, int, void *));
 | 
				
			||||||
struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
 | 
					struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
 | 
				
			||||||
			      u_int8_t tsc, u_int8_t bsic);
 | 
								      u_int8_t tsc, u_int8_t bsic);
 | 
				
			||||||
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
 | 
					struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
 | 
				
			||||||
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
 | 
					struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -752,12 +639,9 @@ struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
 | 
					const char *gsm_pchan_name(enum gsm_phys_chan_config c);
 | 
				
			||||||
enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
 | 
					enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
 | 
				
			||||||
const char *gsm_lchant_name(enum gsm_chan_t c);
 | 
					const char *gsm_lchan_name(enum gsm_chan_t c);
 | 
				
			||||||
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
 | 
					const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
 | 
				
			||||||
char *gsm_trx_name(struct gsm_bts_trx *trx);
 | 
					 | 
				
			||||||
char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
 | 
					char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
 | 
				
			||||||
char *gsm_lchan_name(struct gsm_lchan *lchan);
 | 
					 | 
				
			||||||
const char *gsm_lchans_name(enum gsm_lchan_state s);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum gsm_e1_event {
 | 
					enum gsm_e1_event {
 | 
				
			||||||
	EVT_E1_NONE,
 | 
						EVT_E1_NONE,
 | 
				
			||||||
@@ -769,10 +653,12 @@ void set_ts_e1link(struct gsm_bts_trx_ts *ts, u_int8_t e1_nr,
 | 
				
			|||||||
		   u_int8_t e1_ts, u_int8_t e1_ts_ss);
 | 
							   u_int8_t e1_ts, u_int8_t e1_ts_ss);
 | 
				
			||||||
enum gsm_bts_type parse_btstype(const char *arg);
 | 
					enum gsm_bts_type parse_btstype(const char *arg);
 | 
				
			||||||
const char *btstype2str(enum gsm_bts_type type);
 | 
					const char *btstype2str(enum gsm_bts_type type);
 | 
				
			||||||
struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
 | 
					 | 
				
			||||||
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
 | 
					struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
 | 
				
			||||||
				struct gsm_bts *start_bts);
 | 
									struct gsm_bts *start_bts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *gsm_band_name(enum gsm_band band);
 | 
				
			||||||
 | 
					enum gsm_band gsm_band_parse(const char *mhz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void *tall_bsc_ctx;
 | 
					extern void *tall_bsc_ctx;
 | 
				
			||||||
extern int ipacc_rtp_direct;
 | 
					extern int ipacc_rtp_direct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -806,20 +692,8 @@ const char *gsm_auth_policy_name(enum gsm_auth_policy policy);
 | 
				
			|||||||
enum rrlp_mode rrlp_mode_parse(const char *arg);
 | 
					enum rrlp_mode rrlp_mode_parse(const char *arg);
 | 
				
			||||||
const char *rrlp_mode_name(enum rrlp_mode mode);
 | 
					const char *rrlp_mode_name(enum rrlp_mode mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum bts_gprs_mode bts_gprs_mode_parse(const char *arg);
 | 
					 | 
				
			||||||
const char *bts_gprs_mode_name(enum bts_gprs_mode mode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
 | 
					void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gsm48_ra_id_by_bts(u_int8_t *buf, struct gsm_bts *bts);
 | 
					 | 
				
			||||||
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
 | 
					 | 
				
			||||||
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
 | 
					struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat);
 | 
					 | 
				
			||||||
int gsm_bts_has_feature(struct gsm_bts *bts, enum gsm_bts_features feat);
 | 
					 | 
				
			||||||
int gsm_bts_model_register(struct gsm_bts_model *model);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan);
 | 
					 | 
				
			||||||
void subscr_con_free(struct gsm_subscriber_connection *conn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,11 +3,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include "gsm_data.h"
 | 
					#include "gsm_data.h"
 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					#include "linuxlist.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GSM_IMEI_LENGTH 17
 | 
					#define GSM_IMEI_LENGTH 17
 | 
				
			||||||
#define GSM_IMSI_LENGTH 17
 | 
					#define GSM_IMSI_LENGTH 17
 | 
				
			||||||
#define GSM_NAME_LENGTH 160
 | 
					#define GSM_NAME_LENGTH 128
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */
 | 
					#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */
 | 
				
			||||||
#define GSM_MIN_EXTEN 20000
 | 
					#define GSM_MIN_EXTEN 20000
 | 
				
			||||||
@@ -81,13 +81,13 @@ struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net,
 | 
				
			|||||||
					       const char *ext);
 | 
										       const char *ext);
 | 
				
			||||||
struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net,
 | 
					struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net,
 | 
				
			||||||
					unsigned long long id);
 | 
										unsigned long long id);
 | 
				
			||||||
 | 
					struct gsm_subscriber *subscr_get_or_create(struct gsm_network *net,
 | 
				
			||||||
 | 
										    const char *imsi);
 | 
				
			||||||
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
 | 
					int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
 | 
				
			||||||
void subscr_put_channel(struct gsm_subscriber_connection *conn);
 | 
					void subscr_put_channel(struct gsm_lchan *lchan);
 | 
				
			||||||
void subscr_get_channel(struct gsm_subscriber *subscr,
 | 
					void subscr_get_channel(struct gsm_subscriber *subscr,
 | 
				
			||||||
                        int type, gsm_cbfn *cbfn, void *param);
 | 
					                        int type, gsm_cbfn *cbfn, void *param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *subscr_name(struct gsm_subscriber *subscr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* internal */
 | 
					/* internal */
 | 
				
			||||||
struct gsm_subscriber *subscr_alloc(void);
 | 
					struct gsm_subscriber *subscr_alloc(void);
 | 
				
			||||||
extern struct llist_head active_subscribers;
 | 
					extern struct llist_head active_subscribers;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,9 @@
 | 
				
			|||||||
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					/* GSM utility functions, e.g. coding and decoding */
 | 
				
			||||||
 * (C) 2009-2010 by On-Waves
 | 
					/*
 | 
				
			||||||
 | 
					 * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
 | 
				
			||||||
 | 
					 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 | 
					 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
@@ -18,9 +22,20 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <openbsc/osmo_bsc.h>
 | 
					#ifndef GSM_UTILS_H
 | 
				
			||||||
 | 
					#define GSM_UTILS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct bsc_api *osmo_bsc_api()
 | 
					#include <sys/types.h>
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
	return NULL;
 | 
					int gsm_7bit_decode(char *decoded, const u_int8_t *user_data, u_int8_t length);
 | 
				
			||||||
}
 | 
					int gsm_7bit_encode(u_int8_t *result, const char *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
 | 
				
			||||||
 | 
					int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* According to TS 08.05 Chapter 8.1.4 */
 | 
				
			||||||
 | 
					int rxlev2dbm(u_int8_t rxlev);
 | 
				
			||||||
 | 
					u_int8_t dbm2rxlev(int dbm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void generate_backtrace();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -1,14 +1,8 @@
 | 
				
			|||||||
#ifndef _HANDOVER_H
 | 
					#ifndef _HANDOVER_H
 | 
				
			||||||
#define _HANDOVER_H
 | 
					#define _HANDOVER_H
 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_subscriber_connection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Hand over the specified logical channel to the specified new BTS.
 | 
					/* Hand over the specified logical channel to the specified new BTS.
 | 
				
			||||||
 * This is the main entry point for the actual handover algorithm,
 | 
					 * This is the main entry point for the actual handover algorithm,
 | 
				
			||||||
 * after it has decided it wants to initiate HO to a specific BTS */
 | 
					 * after it has decided it wants to initiate HO to a specific BTS */
 | 
				
			||||||
int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts);
 | 
					int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* clear any operation for this connection */
 | 
					 | 
				
			||||||
void bsc_clear_handover(struct gsm_subscriber_connection *conn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _HANDOVER_H */
 | 
					#endif /* _HANDOVER_H */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,10 +2,6 @@
 | 
				
			|||||||
#define _IPACCESS_H
 | 
					#define _IPACCESS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "e1_input.h"
 | 
					#include "e1_input.h"
 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define IPA_TCP_PORT_OML	3002
 | 
					 | 
				
			||||||
#define IPA_TCP_PORT_RSL	3003
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ipaccess_head {
 | 
					struct ipaccess_head {
 | 
				
			||||||
	u_int16_t len;	/* network byte order */
 | 
						u_int16_t len;	/* network byte order */
 | 
				
			||||||
@@ -49,61 +45,5 @@ int ipaccess_rcvmsg_base(struct msgb *msg, struct bsc_fd *bfd);
 | 
				
			|||||||
struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error);
 | 
					struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error);
 | 
				
			||||||
void ipaccess_prepend_header(struct msgb *msg, int proto);
 | 
					void ipaccess_prepend_header(struct msgb *msg, int proto);
 | 
				
			||||||
int ipaccess_send_id_ack(int fd);
 | 
					int ipaccess_send_id_ack(int fd);
 | 
				
			||||||
int ipaccess_send_id_req(int fd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ipaccess_drop_oml(struct gsm_bts *bts);
 | 
					 | 
				
			||||||
int ipaccess_drop_rsl(struct gsm_bts_trx *trx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Firmware specific header
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct sdp_firmware {
 | 
					 | 
				
			||||||
	char magic[4];
 | 
					 | 
				
			||||||
	char more_magic[2];
 | 
					 | 
				
			||||||
	u_int16_t more_more_magic;
 | 
					 | 
				
			||||||
	u_int32_t header_length;
 | 
					 | 
				
			||||||
	u_int32_t file_length;
 | 
					 | 
				
			||||||
	char sw_part[20];
 | 
					 | 
				
			||||||
	char text1[64];
 | 
					 | 
				
			||||||
	char time[12];
 | 
					 | 
				
			||||||
	char date[14];
 | 
					 | 
				
			||||||
	char text2[10];
 | 
					 | 
				
			||||||
	char version[20];
 | 
					 | 
				
			||||||
	u_int16_t table_offset;
 | 
					 | 
				
			||||||
	/* stuff i don't know */
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sdp_header_entry {
 | 
					 | 
				
			||||||
	u_int16_t something1;
 | 
					 | 
				
			||||||
	char text1[64];
 | 
					 | 
				
			||||||
	char time[12];
 | 
					 | 
				
			||||||
	char date[14];
 | 
					 | 
				
			||||||
	char text2[10];
 | 
					 | 
				
			||||||
	char version[20];
 | 
					 | 
				
			||||||
	u_int32_t length;
 | 
					 | 
				
			||||||
	u_int32_t addr1;
 | 
					 | 
				
			||||||
	u_int32_t addr2;
 | 
					 | 
				
			||||||
	u_int32_t start;
 | 
					 | 
				
			||||||
} __attribute__((packed));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sdp_header_item {
 | 
					 | 
				
			||||||
	struct sdp_header_entry header_entry;
 | 
					 | 
				
			||||||
	struct llist_head entry;
 | 
					 | 
				
			||||||
	off_t absolute_offset;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sdp_header {
 | 
					 | 
				
			||||||
	struct sdp_firmware firmware_info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* for more_magic a list of sdp_header_entry_list */
 | 
					 | 
				
			||||||
	struct llist_head header_list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* the entry of the sdp_header */
 | 
					 | 
				
			||||||
	struct llist_head entry;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ipaccess_analyze_file(int fd, const unsigned int st_size, const unsigned base_offset, struct llist_head *list);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _IPACCESS_H */
 | 
					#endif /* _IPACCESS_H */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										360
									
								
								openbsc/include/openbsc/linuxlist.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								openbsc/include/openbsc/linuxlist.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,360 @@
 | 
				
			|||||||
 | 
					#ifndef _LINUX_LLIST_H
 | 
				
			||||||
 | 
					#define _LINUX_LLIST_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef inline
 | 
				
			||||||
 | 
					#define inline __inline__
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void prefetch(const void *x) {;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * container_of - cast a member of a structure out to the containing structure
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @ptr:	the pointer to the member.
 | 
				
			||||||
 | 
					 * @type:	the type of the container struct this is embedded in.
 | 
				
			||||||
 | 
					 * @member:	the name of the member within the struct.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define container_of(ptr, type, member) ({			\
 | 
				
			||||||
 | 
					        const typeof( ((type *)0)->member ) *__mptr = (typeof( ((type *)0)->member ) *)(ptr);	\
 | 
				
			||||||
 | 
					        (type *)( (char *)__mptr - offsetof(type, member) );})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * These are non-NULL pointers that will result in page faults
 | 
				
			||||||
 | 
					 * under normal circumstances, used to verify that nobody uses
 | 
				
			||||||
 | 
					 * non-initialized llist entries.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define LLIST_POISON1  ((void *) 0x00100100)
 | 
				
			||||||
 | 
					#define LLIST_POISON2  ((void *) 0x00200200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Simple doubly linked llist implementation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Some of the internal functions ("__xxx") are useful when
 | 
				
			||||||
 | 
					 * manipulating whole llists rather than single entries, as
 | 
				
			||||||
 | 
					 * sometimes we already know the next/prev entries and we can
 | 
				
			||||||
 | 
					 * generate better code by using them directly rather than
 | 
				
			||||||
 | 
					 * using the generic single-entry routines.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct llist_head {
 | 
				
			||||||
 | 
						struct llist_head *next, *prev;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LLIST_HEAD_INIT(name) { &(name), &(name) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LLIST_HEAD(name) \
 | 
				
			||||||
 | 
						struct llist_head name = LLIST_HEAD_INIT(name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define INIT_LLIST_HEAD(ptr) do { \
 | 
				
			||||||
 | 
						(ptr)->next = (ptr); (ptr)->prev = (ptr); \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Insert a new entry between two known consecutive entries. 
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This is only for internal llist manipulation where we know
 | 
				
			||||||
 | 
					 * the prev/next entries already!
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void __llist_add(struct llist_head *_new,
 | 
				
			||||||
 | 
								      struct llist_head *prev,
 | 
				
			||||||
 | 
								      struct llist_head *next)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						next->prev = _new;
 | 
				
			||||||
 | 
						_new->next = next;
 | 
				
			||||||
 | 
						_new->prev = prev;
 | 
				
			||||||
 | 
						prev->next = _new;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_add - add a new entry
 | 
				
			||||||
 | 
					 * @new: new entry to be added
 | 
				
			||||||
 | 
					 * @head: llist head to add it after
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Insert a new entry after the specified head.
 | 
				
			||||||
 | 
					 * This is good for implementing stacks.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void llist_add(struct llist_head *_new, struct llist_head *head)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						__llist_add(_new, head, head->next);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_add_tail - add a new entry
 | 
				
			||||||
 | 
					 * @new: new entry to be added
 | 
				
			||||||
 | 
					 * @head: llist head to add it before
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Insert a new entry before the specified head.
 | 
				
			||||||
 | 
					 * This is useful for implementing queues.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void llist_add_tail(struct llist_head *_new, struct llist_head *head)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						__llist_add(_new, head->prev, head);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Delete a llist entry by making the prev/next entries
 | 
				
			||||||
 | 
					 * point to each other.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This is only for internal llist manipulation where we know
 | 
				
			||||||
 | 
					 * the prev/next entries already!
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void __llist_del(struct llist_head * prev, struct llist_head * next)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						next->prev = prev;
 | 
				
			||||||
 | 
						prev->next = next;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_del - deletes entry from llist.
 | 
				
			||||||
 | 
					 * @entry: the element to delete from the llist.
 | 
				
			||||||
 | 
					 * Note: llist_empty on entry does not return true after this, the entry is
 | 
				
			||||||
 | 
					 * in an undefined state.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void llist_del(struct llist_head *entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						__llist_del(entry->prev, entry->next);
 | 
				
			||||||
 | 
						entry->next = (struct llist_head *)LLIST_POISON1;
 | 
				
			||||||
 | 
						entry->prev = (struct llist_head *)LLIST_POISON2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_del_init - deletes entry from llist and reinitialize it.
 | 
				
			||||||
 | 
					 * @entry: the element to delete from the llist.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void llist_del_init(struct llist_head *entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						__llist_del(entry->prev, entry->next);
 | 
				
			||||||
 | 
						INIT_LLIST_HEAD(entry); 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_move - delete from one llist and add as another's head
 | 
				
			||||||
 | 
					 * @llist: the entry to move
 | 
				
			||||||
 | 
					 * @head: the head that will precede our entry
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void llist_move(struct llist_head *llist, struct llist_head *head)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					        __llist_del(llist->prev, llist->next);
 | 
				
			||||||
 | 
					        llist_add(llist, head);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_move_tail - delete from one llist and add as another's tail
 | 
				
			||||||
 | 
					 * @llist: the entry to move
 | 
				
			||||||
 | 
					 * @head: the head that will follow our entry
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void llist_move_tail(struct llist_head *llist,
 | 
				
			||||||
 | 
									  struct llist_head *head)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					        __llist_del(llist->prev, llist->next);
 | 
				
			||||||
 | 
					        llist_add_tail(llist, head);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_empty - tests whether a llist is empty
 | 
				
			||||||
 | 
					 * @head: the llist to test.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline int llist_empty(const struct llist_head *head)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return head->next == head;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void __llist_splice(struct llist_head *llist,
 | 
				
			||||||
 | 
									 struct llist_head *head)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct llist_head *first = llist->next;
 | 
				
			||||||
 | 
						struct llist_head *last = llist->prev;
 | 
				
			||||||
 | 
						struct llist_head *at = head->next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						first->prev = head;
 | 
				
			||||||
 | 
						head->next = first;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						last->next = at;
 | 
				
			||||||
 | 
						at->prev = last;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_splice - join two llists
 | 
				
			||||||
 | 
					 * @llist: the new llist to add.
 | 
				
			||||||
 | 
					 * @head: the place to add it in the first llist.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void llist_splice(struct llist_head *llist, struct llist_head *head)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!llist_empty(llist))
 | 
				
			||||||
 | 
							__llist_splice(llist, head);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_splice_init - join two llists and reinitialise the emptied llist.
 | 
				
			||||||
 | 
					 * @llist: the new llist to add.
 | 
				
			||||||
 | 
					 * @head: the place to add it in the first llist.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The llist at @llist is reinitialised
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void llist_splice_init(struct llist_head *llist,
 | 
				
			||||||
 | 
									    struct llist_head *head)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!llist_empty(llist)) {
 | 
				
			||||||
 | 
							__llist_splice(llist, head);
 | 
				
			||||||
 | 
							INIT_LLIST_HEAD(llist);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_entry - get the struct for this entry
 | 
				
			||||||
 | 
					 * @ptr:	the &struct llist_head pointer.
 | 
				
			||||||
 | 
					 * @type:	the type of the struct this is embedded in.
 | 
				
			||||||
 | 
					 * @member:	the name of the llist_struct within the struct.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_entry(ptr, type, member) \
 | 
				
			||||||
 | 
						container_of(ptr, type, member)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each	-	iterate over a llist
 | 
				
			||||||
 | 
					 * @pos:	the &struct llist_head to use as a loop counter.
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each(pos, head) \
 | 
				
			||||||
 | 
						for (pos = (head)->next, prefetch(pos->next); pos != (head); \
 | 
				
			||||||
 | 
					        	pos = pos->next, prefetch(pos->next))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * __llist_for_each	-	iterate over a llist
 | 
				
			||||||
 | 
					 * @pos:	the &struct llist_head to use as a loop counter.
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This variant differs from llist_for_each() in that it's the
 | 
				
			||||||
 | 
					 * simplest possible llist iteration code, no prefetching is done.
 | 
				
			||||||
 | 
					 * Use this for code that knows the llist to be very short (empty
 | 
				
			||||||
 | 
					 * or 1 entry) most of the time.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define __llist_for_each(pos, head) \
 | 
				
			||||||
 | 
						for (pos = (head)->next; pos != (head); pos = pos->next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_prev	-	iterate over a llist backwards
 | 
				
			||||||
 | 
					 * @pos:	the &struct llist_head to use as a loop counter.
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_prev(pos, head) \
 | 
				
			||||||
 | 
						for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
 | 
				
			||||||
 | 
					        	pos = pos->prev, prefetch(pos->prev))
 | 
				
			||||||
 | 
					        	
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_safe	-	iterate over a llist safe against removal of llist entry
 | 
				
			||||||
 | 
					 * @pos:	the &struct llist_head to use as a loop counter.
 | 
				
			||||||
 | 
					 * @n:		another &struct llist_head to use as temporary storage
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_safe(pos, n, head) \
 | 
				
			||||||
 | 
						for (pos = (head)->next, n = pos->next; pos != (head); \
 | 
				
			||||||
 | 
							pos = n, n = pos->next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_entry	-	iterate over llist of given type
 | 
				
			||||||
 | 
					 * @pos:	the type * to use as a loop counter.
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 * @member:	the name of the llist_struct within the struct.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_entry(pos, head, member)				\
 | 
				
			||||||
 | 
						for (pos = llist_entry((head)->next, typeof(*pos), member),	\
 | 
				
			||||||
 | 
							     prefetch(pos->member.next);			\
 | 
				
			||||||
 | 
						     &pos->member != (head); 					\
 | 
				
			||||||
 | 
						     pos = llist_entry(pos->member.next, typeof(*pos), member),	\
 | 
				
			||||||
 | 
							     prefetch(pos->member.next))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_entry_reverse - iterate backwards over llist of given type.
 | 
				
			||||||
 | 
					 * @pos:	the type * to use as a loop counter.
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 * @member:	the name of the llist_struct within the struct.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_entry_reverse(pos, head, member)			\
 | 
				
			||||||
 | 
						for (pos = llist_entry((head)->prev, typeof(*pos), member),	\
 | 
				
			||||||
 | 
							     prefetch(pos->member.prev);			\
 | 
				
			||||||
 | 
						     &pos->member != (head); 					\
 | 
				
			||||||
 | 
						     pos = llist_entry(pos->member.prev, typeof(*pos), member),	\
 | 
				
			||||||
 | 
							     prefetch(pos->member.prev))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_entry_continue -	iterate over llist of given type
 | 
				
			||||||
 | 
					 *			continuing after existing point
 | 
				
			||||||
 | 
					 * @pos:	the type * to use as a loop counter.
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 * @member:	the name of the llist_struct within the struct.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_entry_continue(pos, head, member) 		\
 | 
				
			||||||
 | 
						for (pos = llist_entry(pos->member.next, typeof(*pos), member),	\
 | 
				
			||||||
 | 
							     prefetch(pos->member.next);			\
 | 
				
			||||||
 | 
						     &pos->member != (head);					\
 | 
				
			||||||
 | 
						     pos = llist_entry(pos->member.next, typeof(*pos), member),	\
 | 
				
			||||||
 | 
							     prefetch(pos->member.next))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_entry_safe - iterate over llist of given type safe against removal of llist entry
 | 
				
			||||||
 | 
					 * @pos:	the type * to use as a loop counter.
 | 
				
			||||||
 | 
					 * @n:		another type * to use as temporary storage
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 * @member:	the name of the llist_struct within the struct.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_entry_safe(pos, n, head, member)			\
 | 
				
			||||||
 | 
						for (pos = llist_entry((head)->next, typeof(*pos), member),	\
 | 
				
			||||||
 | 
							n = llist_entry(pos->member.next, typeof(*pos), member);	\
 | 
				
			||||||
 | 
						     &pos->member != (head); 					\
 | 
				
			||||||
 | 
						     pos = n, n = llist_entry(n->member.next, typeof(*n), member))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_rcu	-	iterate over an rcu-protected llist
 | 
				
			||||||
 | 
					 * @pos:	the &struct llist_head to use as a loop counter.
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_rcu(pos, head) \
 | 
				
			||||||
 | 
						for (pos = (head)->next, prefetch(pos->next); pos != (head); \
 | 
				
			||||||
 | 
					        	pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next))
 | 
				
			||||||
 | 
					        	
 | 
				
			||||||
 | 
					#define __llist_for_each_rcu(pos, head) \
 | 
				
			||||||
 | 
						for (pos = (head)->next; pos != (head); \
 | 
				
			||||||
 | 
					        	pos = pos->next, ({ smp_read_barrier_depends(); 0;}))
 | 
				
			||||||
 | 
					        	
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_safe_rcu	-	iterate over an rcu-protected llist safe
 | 
				
			||||||
 | 
					 *					against removal of llist entry
 | 
				
			||||||
 | 
					 * @pos:	the &struct llist_head to use as a loop counter.
 | 
				
			||||||
 | 
					 * @n:		another &struct llist_head to use as temporary storage
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_safe_rcu(pos, n, head) \
 | 
				
			||||||
 | 
						for (pos = (head)->next, n = pos->next; pos != (head); \
 | 
				
			||||||
 | 
							pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_entry_rcu	-	iterate over rcu llist of given type
 | 
				
			||||||
 | 
					 * @pos:	the type * to use as a loop counter.
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 * @member:	the name of the llist_struct within the struct.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_entry_rcu(pos, head, member)			\
 | 
				
			||||||
 | 
						for (pos = llist_entry((head)->next, typeof(*pos), member),	\
 | 
				
			||||||
 | 
							     prefetch(pos->member.next);			\
 | 
				
			||||||
 | 
						     &pos->member != (head); 					\
 | 
				
			||||||
 | 
						     pos = llist_entry(pos->member.next, typeof(*pos), member),	\
 | 
				
			||||||
 | 
							     ({ smp_read_barrier_depends(); 0;}),		\
 | 
				
			||||||
 | 
							     prefetch(pos->member.next))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * llist_for_each_continue_rcu	-	iterate over an rcu-protected llist 
 | 
				
			||||||
 | 
					 *			continuing after existing point.
 | 
				
			||||||
 | 
					 * @pos:	the &struct llist_head to use as a loop counter.
 | 
				
			||||||
 | 
					 * @head:	the head for your llist.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define llist_for_each_continue_rcu(pos, head) \
 | 
				
			||||||
 | 
						for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \
 | 
				
			||||||
 | 
					        	(pos) = (pos)->next, ({ smp_read_barrier_depends(); 0;}), prefetch((pos)->next))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
struct gsm_meas_rep_cell {
 | 
					struct gsm_meas_rep_cell {
 | 
				
			||||||
	u_int8_t rxlev;
 | 
						u_int8_t rxlev;
 | 
				
			||||||
	u_int8_t bsic;
 | 
						u_int8_t bsic;
 | 
				
			||||||
	u_int8_t neigh_idx;
 | 
					 | 
				
			||||||
	u_int16_t arfcn;
 | 
						u_int16_t arfcn;
 | 
				
			||||||
	unsigned int flags;
 | 
						unsigned int flags;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
 | 
					/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 * (C) 2009-2010 by On-Waves
 | 
					 * (C) 2009 by on-waves.com
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
@@ -21,15 +21,6 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef OPENBSC_MGCP_H
 | 
					 | 
				
			||||||
#define OPENBSC_MGCP_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RTP_PORT_DEFAULT 4000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Calculate the RTP audio port for the given multiplex
 | 
					 * Calculate the RTP audio port for the given multiplex
 | 
				
			||||||
 * and the direction. This allows a semi static endpoint
 | 
					 * and the direction. This allows a semi static endpoint
 | 
				
			||||||
@@ -49,88 +40,7 @@
 | 
				
			|||||||
 * network and BTS.
 | 
					 * network and BTS.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static inline int rtp_calculate_port(int multiplex, int base)
 | 
					int rtp_calculate_port(int multiplex, int base)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return base + (multiplex * 2);
 | 
						return base + (multiplex * 2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Handling of MGCP Endpoints and the MGCP Config
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct mgcp_endpoint;
 | 
					 | 
				
			||||||
struct mgcp_config;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MGCP_ENDP_CRCX 1
 | 
					 | 
				
			||||||
#define MGCP_ENDP_DLCX 2
 | 
					 | 
				
			||||||
#define MGCP_ENDP_MDCX 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * what to do with the msg?
 | 
					 | 
				
			||||||
 *	- continue as usual?
 | 
					 | 
				
			||||||
 *	- reject and send a failure code?
 | 
					 | 
				
			||||||
 *	- defer? do not send anything
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define MGCP_POLICY_CONT	4
 | 
					 | 
				
			||||||
#define MGCP_POLICY_REJECT	5
 | 
					 | 
				
			||||||
#define MGCP_POLICY_DEFER	6
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state, int local_rtp);
 | 
					 | 
				
			||||||
typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id);
 | 
					 | 
				
			||||||
typedef int (*mgcp_reset)(struct mgcp_config *cfg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct mgcp_config {
 | 
					 | 
				
			||||||
	int source_port;
 | 
					 | 
				
			||||||
	char *local_ip;
 | 
					 | 
				
			||||||
	char *source_addr;
 | 
					 | 
				
			||||||
	unsigned int number_endpoints;
 | 
					 | 
				
			||||||
	char *bts_ip;
 | 
					 | 
				
			||||||
	char *call_agent_addr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct in_addr bts_in;
 | 
					 | 
				
			||||||
	char *audio_name;
 | 
					 | 
				
			||||||
	int audio_payload;
 | 
					 | 
				
			||||||
	int audio_loop;
 | 
					 | 
				
			||||||
	int early_bind;
 | 
					 | 
				
			||||||
	int rtp_base_port;
 | 
					 | 
				
			||||||
	int endp_dscp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	char *forward_ip;
 | 
					 | 
				
			||||||
	int forward_port;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* spec handling */
 | 
					 | 
				
			||||||
	int force_realloc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mgcp_change change_cb;
 | 
					 | 
				
			||||||
	mgcp_policy policy_cb;
 | 
					 | 
				
			||||||
	mgcp_reset reset_cb;
 | 
					 | 
				
			||||||
	void *data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct mgcp_endpoint *endpoints;
 | 
					 | 
				
			||||||
	unsigned int last_call_id;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* config management */
 | 
					 | 
				
			||||||
struct mgcp_config *mgcp_config_alloc(void);
 | 
					 | 
				
			||||||
int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg);
 | 
					 | 
				
			||||||
int mgcp_vty_init(void);
 | 
					 | 
				
			||||||
int mgcp_endpoints_allocate(struct mgcp_config *cfg);
 | 
					 | 
				
			||||||
int mgcp_bind_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
 | 
					 | 
				
			||||||
void mgcp_free_endp(struct mgcp_endpoint *endp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * format helper functions
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
 | 
					 | 
				
			||||||
struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans, const char *data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* adc helper */
 | 
					 | 
				
			||||||
static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (timeslot == 0)
 | 
					 | 
				
			||||||
		timeslot = 1;
 | 
					 | 
				
			||||||
	return timeslot + (31 * multiplex);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,104 +0,0 @@
 | 
				
			|||||||
/* MGCP Private Data */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 | 
				
			||||||
 * (C) 2009-2010 by On-Waves
 | 
					 | 
				
			||||||
 * All Rights Reserved
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License along
 | 
					 | 
				
			||||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef OPENBSC_MGCP_DATA_H
 | 
					 | 
				
			||||||
#define OPENBSC_MGCP_DATA_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/select.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CI_UNUSED 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum mgcp_connection_mode {
 | 
					 | 
				
			||||||
	MGCP_CONN_NONE = 0,
 | 
					 | 
				
			||||||
	MGCP_CONN_RECV_ONLY = 1,
 | 
					 | 
				
			||||||
	MGCP_CONN_SEND_ONLY = 2,
 | 
					 | 
				
			||||||
	MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
 | 
					 | 
				
			||||||
	MGCP_CONN_LOOPBACK  = 4,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct mgcp_rtp_state {
 | 
					 | 
				
			||||||
	int initialized;
 | 
					 | 
				
			||||||
	int patch;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t orig_ssrc;
 | 
					 | 
				
			||||||
	uint32_t ssrc;
 | 
					 | 
				
			||||||
	uint16_t seq_no;
 | 
					 | 
				
			||||||
	int lost_no;
 | 
					 | 
				
			||||||
	int seq_offset;
 | 
					 | 
				
			||||||
	uint32_t last_timestamp;
 | 
					 | 
				
			||||||
	int32_t  timestamp_offset;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct mgcp_endpoint {
 | 
					 | 
				
			||||||
	int ci;
 | 
					 | 
				
			||||||
	char *callid;
 | 
					 | 
				
			||||||
	char *local_options;
 | 
					 | 
				
			||||||
	int conn_mode;
 | 
					 | 
				
			||||||
	int orig_mode;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int bts_payload_type;
 | 
					 | 
				
			||||||
	int net_payload_type;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* the local rtp port we are binding to */
 | 
					 | 
				
			||||||
	int rtp_port;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * RTP mangling:
 | 
					 | 
				
			||||||
	 *  - we get RTP and RTCP to us and need to forward to the BTS
 | 
					 | 
				
			||||||
	 *  - we get RTP and RTCP from the BTS and forward to the network
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	struct bsc_fd local_rtp;
 | 
					 | 
				
			||||||
	struct bsc_fd local_rtcp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct in_addr remote;
 | 
					 | 
				
			||||||
	struct in_addr bts;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* in network byte order */
 | 
					 | 
				
			||||||
	int net_rtp, net_rtcp;
 | 
					 | 
				
			||||||
	int bts_rtp, bts_rtcp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* backpointer */
 | 
					 | 
				
			||||||
	struct mgcp_config *cfg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* statistics */
 | 
					 | 
				
			||||||
	unsigned int in_bts;
 | 
					 | 
				
			||||||
	unsigned int in_remote;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* sequence bits */
 | 
					 | 
				
			||||||
	struct mgcp_rtp_state net_state;
 | 
					 | 
				
			||||||
	struct mgcp_rtp_state bts_state;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct mgcp_msg_ptr {
 | 
					 | 
				
			||||||
	unsigned int start;
 | 
					 | 
				
			||||||
	unsigned int length;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
 | 
					 | 
				
			||||||
			struct mgcp_msg_ptr *ptr, int size,
 | 
					 | 
				
			||||||
			const char **transaction_id, struct mgcp_endpoint **endp);
 | 
					 | 
				
			||||||
int mgcp_send_dummy(struct mgcp_endpoint *endp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -25,8 +25,7 @@
 | 
				
			|||||||
#ifndef _MNCC_H
 | 
					#ifndef _MNCC_H
 | 
				
			||||||
#define _MNCC_H
 | 
					#define _MNCC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					#include <openbsc/linuxlist.h>
 | 
				
			||||||
#include <osmocore/mncc.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* One end of a call */
 | 
					/* One end of a call */
 | 
				
			||||||
struct gsm_call {
 | 
					struct gsm_call {
 | 
				
			||||||
@@ -110,6 +109,69 @@ struct gsm_call {
 | 
				
			|||||||
#define MNCC_F_KEYPAD		0x1000
 | 
					#define MNCC_F_KEYPAD		0x1000
 | 
				
			||||||
#define MNCC_F_SIGNAL		0x2000
 | 
					#define MNCC_F_SIGNAL		0x2000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Expanded fields from GSM TS 04.08, Table 10.5.102 */
 | 
				
			||||||
 | 
					struct gsm_mncc_bearer_cap {
 | 
				
			||||||
 | 
						int		transfer;	/* Information Transfer Capability */
 | 
				
			||||||
 | 
						int 		mode;		/* Transfer Mode */
 | 
				
			||||||
 | 
						int		coding;		/* Coding Standard */
 | 
				
			||||||
 | 
						int		radio;		/* Radio Channel Requirement */
 | 
				
			||||||
 | 
						int		speech_ctm;	/* CTM text telephony indication */
 | 
				
			||||||
 | 
						int		speech_ver[8];	/* Speech version indication */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm_mncc_number {
 | 
				
			||||||
 | 
						int 		type;
 | 
				
			||||||
 | 
						int 		plan;
 | 
				
			||||||
 | 
						int		present;
 | 
				
			||||||
 | 
						int		screen;
 | 
				
			||||||
 | 
						char		number[33];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm_mncc_cause {
 | 
				
			||||||
 | 
						int		location;
 | 
				
			||||||
 | 
						int		coding;
 | 
				
			||||||
 | 
						int		rec;
 | 
				
			||||||
 | 
						int		rec_val;
 | 
				
			||||||
 | 
						int		value;
 | 
				
			||||||
 | 
						int		diag_len;
 | 
				
			||||||
 | 
						char		diag[32];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm_mncc_useruser {
 | 
				
			||||||
 | 
						int		proto;
 | 
				
			||||||
 | 
						char		info[GSM_MAX_USERUSER + 1]; /* + termination char */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm_mncc_progress {
 | 
				
			||||||
 | 
						int		coding;
 | 
				
			||||||
 | 
						int		location;
 | 
				
			||||||
 | 
						int 		descr;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm_mncc_facility {
 | 
				
			||||||
 | 
						int		len;
 | 
				
			||||||
 | 
						char		info[GSM_MAX_FACILITY];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm_mncc_ssversion {
 | 
				
			||||||
 | 
						int		len;
 | 
				
			||||||
 | 
						char		info[GSM_MAX_SSVERSION];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gsm_mncc_cccap {
 | 
				
			||||||
 | 
						int		dtmf;
 | 
				
			||||||
 | 
						int		pcp;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						GSM_MNCC_BCAP_SPEECH	= 0,
 | 
				
			||||||
 | 
						GSM_MNCC_BCAP_UNR_DIG	= 1,
 | 
				
			||||||
 | 
						GSM_MNCC_BCAP_AUDIO	= 2,
 | 
				
			||||||
 | 
						GSM_MNCC_BCAP_FAX_G3	= 3,
 | 
				
			||||||
 | 
						GSM_MNCC_BCAP_OTHER_ITC = 5,
 | 
				
			||||||
 | 
						GSM_MNCC_BCAP_RESERVED	= 7,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_mncc {
 | 
					struct gsm_mncc {
 | 
				
			||||||
	/* context based information */
 | 
						/* context based information */
 | 
				
			||||||
	u_int32_t	msg_type;
 | 
						u_int32_t	msg_type;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										115
									
								
								openbsc/include/openbsc/msgb.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								openbsc/include/openbsc/msgb.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
				
			|||||||
 | 
					#ifndef _MSGB_H
 | 
				
			||||||
 | 
					#define _MSGB_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openbsc/linuxlist.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bts_link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct msgb {
 | 
				
			||||||
 | 
						struct llist_head list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ptr to the physical E1 link to the BTS(s) */
 | 
				
			||||||
 | 
						struct gsm_bts_link *bts_link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Part of which TRX logical channel we were received / transmitted */
 | 
				
			||||||
 | 
						struct gsm_bts_trx *trx;
 | 
				
			||||||
 | 
						struct gsm_lchan *lchan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned char *l2h;
 | 
				
			||||||
 | 
						unsigned char *l3h;
 | 
				
			||||||
 | 
						unsigned char *smsh;
 | 
				
			||||||
 | 
						unsigned char *l4h;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int16_t data_len;
 | 
				
			||||||
 | 
						u_int16_t len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned char *head;
 | 
				
			||||||
 | 
						unsigned char *tail;
 | 
				
			||||||
 | 
						unsigned char *data;
 | 
				
			||||||
 | 
						unsigned char _data[0];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct msgb *msgb_alloc(u_int16_t size, const char *name);
 | 
				
			||||||
 | 
					extern void msgb_free(struct msgb *m);
 | 
				
			||||||
 | 
					extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg);
 | 
				
			||||||
 | 
					extern struct msgb *msgb_dequeue(struct llist_head *queue);
 | 
				
			||||||
 | 
					extern void msgb_reset(struct msgb *m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define msgb_l2(m)	((void *)(m->l2h))
 | 
				
			||||||
 | 
					#define msgb_l3(m)	((void *)(m->l3h))
 | 
				
			||||||
 | 
					#define msgb_l4(m)	((void *)(m->l4h))
 | 
				
			||||||
 | 
					#define msgb_sms(m)	((void *)(m->smsh))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned int msgb_l2len(const struct msgb *msgb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return msgb->tail - (u_int8_t *)msgb_l2(msgb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned int msgb_l3len(const struct msgb *msgb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return msgb->tail - (u_int8_t *)msgb_l3(msgb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned int msgb_headlen(const struct msgb *msgb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return msgb->len - msgb->data_len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned char *tmp = msgb->tail;
 | 
				
			||||||
 | 
						msgb->tail += len;
 | 
				
			||||||
 | 
						msgb->len += len;
 | 
				
			||||||
 | 
						return tmp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						msgb->data -= len;
 | 
				
			||||||
 | 
						msgb->len += len;
 | 
				
			||||||
 | 
						return msgb->data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						msgb->len -= len;
 | 
				
			||||||
 | 
						return msgb->data += len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static inline int msgb_tailroom(const struct msgb *msgb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (msgb->data + msgb->data_len) - msgb->tail;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* increase the headroom of an empty msgb, reducing the tailroom */
 | 
				
			||||||
 | 
					static inline void msgb_reserve(struct msgb *msg, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						msg->data += len;
 | 
				
			||||||
 | 
						msg->tail += len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline struct msgb *msgb_alloc_headroom(int size, int headroom,
 | 
				
			||||||
 | 
											const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct msgb *msg = msgb_alloc(size, name);
 | 
				
			||||||
 | 
						if (msg)
 | 
				
			||||||
 | 
							msgb_reserve(msg, headroom);
 | 
				
			||||||
 | 
						return msg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* _MSGB_H */
 | 
				
			||||||
@@ -1,16 +0,0 @@
 | 
				
			|||||||
#ifndef _OPENBSC_NWL_H
 | 
					 | 
				
			||||||
#define _OPENBSC_NWL_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ipac_nwl_init(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Start a NWL test.  It will raise the S_IPAC_TEST_COMPLETE signal. */
 | 
					 | 
				
			||||||
int ipac_nwl_test_start(struct gsm_bts_trx *trx, uint8_t testnr,
 | 
					 | 
				
			||||||
			const uint8_t *phys_conf, unsigned int phys_conf_len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ipac_rxlevstat2whitelist(uint16_t *buf, const struct rxlev_stats *st, uint8_t min_rxlev,
 | 
					 | 
				
			||||||
			     uint16_t max_num_arfcns);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _OPENBSC_NWL_H */
 | 
					 | 
				
			||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
/* OpenBSC BSC code */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef OSMO_BSC_H
 | 
					 | 
				
			||||||
#define OSMO_BSC_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "bsc_api.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bsc_api *osmo_bsc_api();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,20 +0,0 @@
 | 
				
			|||||||
#ifndef OSMO_BSC_RF
 | 
					 | 
				
			||||||
#define OSMO_BSC_RF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/write_queue.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_network;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct osmo_bsc_rf {
 | 
					 | 
				
			||||||
	struct bsc_fd listen;
 | 
					 | 
				
			||||||
	struct gsm_network *gsm_network;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct osmo_bsc_rf_conn {
 | 
					 | 
				
			||||||
	struct write_queue queue;
 | 
					 | 
				
			||||||
	struct gsm_network *gsm_network;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct osmo_bsc_rf *osmo_bsc_rf_create(const char *path, struct gsm_network *net);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
/* Routines for the MSC handling */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef OSMO_MSC_H
 | 
					 | 
				
			||||||
#define OSMO_MSC_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "bsc_api.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bsc_api *msc_bsc_api();
 | 
					 | 
				
			||||||
void msc_release_connection(struct gsm_subscriber_connection *conn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -24,10 +24,10 @@
 | 
				
			|||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					#include "linuxlist.h"
 | 
				
			||||||
#include "gsm_data.h"
 | 
					#include "gsm_data.h"
 | 
				
			||||||
#include "gsm_subscriber.h"
 | 
					#include "gsm_subscriber.h"
 | 
				
			||||||
#include <osmocore/timer.h>
 | 
					#include "timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* call once for every gsm_bts... */
 | 
					/* call once for every gsm_bts... */
 | 
				
			||||||
void paging_init(struct gsm_bts *bts);
 | 
					void paging_init(struct gsm_bts *bts);
 | 
				
			||||||
@@ -38,7 +38,7 @@ int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* stop paging requests */
 | 
					/* stop paging requests */
 | 
				
			||||||
void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr,
 | 
					void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr,
 | 
				
			||||||
			 struct gsm_subscriber_connection *conn);
 | 
								 struct gsm_lchan *lchan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* update paging load */
 | 
					/* update paging load */
 | 
				
			||||||
void paging_update_buffer_space(struct gsm_bts *bts, u_int16_t);
 | 
					void paging_update_buffer_space(struct gsm_bts *bts, u_int16_t);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,7 +71,6 @@ enum gprs_nmo {
 | 
				
			|||||||
	GPRS_NMO_III	= 2,	/* no paging coordination */
 | 
						GPRS_NMO_III	= 2,	/* no paging coordination */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* TS 04.60 12.24 */
 | 
					 | 
				
			||||||
struct gprs_cell_options {
 | 
					struct gprs_cell_options {
 | 
				
			||||||
	enum gprs_nmo nmo;
 | 
						enum gprs_nmo nmo;
 | 
				
			||||||
	/* T3168: wait for packet uplink assignment message */
 | 
						/* T3168: wait for packet uplink assignment message */
 | 
				
			||||||
@@ -80,16 +79,6 @@ struct gprs_cell_options {
 | 
				
			|||||||
	u_int32_t t3192;	/* in milliseconds */
 | 
						u_int32_t t3192;	/* in milliseconds */
 | 
				
			||||||
	u_int32_t drx_timer_max;/* in seconds */
 | 
						u_int32_t drx_timer_max;/* in seconds */
 | 
				
			||||||
	u_int32_t bs_cv_max;
 | 
						u_int32_t bs_cv_max;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	u_int8_t ext_info_present;
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		u_int8_t egprs_supported;
 | 
					 | 
				
			||||||
			u_int8_t use_egprs_p_ch_req;
 | 
					 | 
				
			||||||
			u_int8_t bep_period;
 | 
					 | 
				
			||||||
		u_int8_t pfc_supported;
 | 
					 | 
				
			||||||
		u_int8_t dtm_supported;
 | 
					 | 
				
			||||||
		u_int8_t bss_paging_coordination;
 | 
					 | 
				
			||||||
	} ext_info;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* TS 04.60 Table 12.9.2 */
 | 
					/* TS 04.60 Table 12.9.2 */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,14 +25,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					#include <openbsc/linuxlist.h>
 | 
				
			||||||
#include <osmocore/select.h>
 | 
					#include <openbsc/select.h>
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RTP_PT_GSM_FULL 3
 | 
					 | 
				
			||||||
#define RTP_PT_GSM_HALF 96
 | 
					 | 
				
			||||||
#define RTP_PT_GSM_EFR 97
 | 
					 | 
				
			||||||
#define RTP_PT_AMR_FULL 98
 | 
					 | 
				
			||||||
#define RTP_PT_AMR_HALF 99
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum rtp_rx_action {
 | 
					enum rtp_rx_action {
 | 
				
			||||||
	RTP_NONE,
 | 
						RTP_NONE,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								openbsc/include/openbsc/select.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								openbsc/include/openbsc/select.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					#ifndef _BSC_SELECT_H
 | 
				
			||||||
 | 
					#define _BSC_SELECT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openbsc/linuxlist.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BSC_FD_READ	0x0001
 | 
				
			||||||
 | 
					#define BSC_FD_WRITE	0x0002
 | 
				
			||||||
 | 
					#define BSC_FD_EXCEPT	0x0004
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bsc_fd {
 | 
				
			||||||
 | 
						struct llist_head list;
 | 
				
			||||||
 | 
						int fd;
 | 
				
			||||||
 | 
						unsigned int when;
 | 
				
			||||||
 | 
						int (*cb)(struct bsc_fd *fd, unsigned int what);
 | 
				
			||||||
 | 
						void *data;
 | 
				
			||||||
 | 
						unsigned int priv_nr;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int bsc_register_fd(struct bsc_fd *fd);
 | 
				
			||||||
 | 
					void bsc_unregister_fd(struct bsc_fd *fd);
 | 
				
			||||||
 | 
					int bsc_select_main(int polling);
 | 
				
			||||||
 | 
					#endif /* _BSC_SELECT_H */
 | 
				
			||||||
@@ -1,65 +0,0 @@
 | 
				
			|||||||
#ifndef _SGSN_H
 | 
					 | 
				
			||||||
#define _SGSN_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <openbsc/gprs_ns.h>
 | 
					 | 
				
			||||||
#include <openbsc/gprs_sgsn.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sgsn_config {
 | 
					 | 
				
			||||||
	/* parsed from config file */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	char *gtp_statedir;
 | 
					 | 
				
			||||||
	struct sockaddr_in gtp_listenaddr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* misc */
 | 
					 | 
				
			||||||
	struct gprs_ns_inst *nsi;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sgsn_instance {
 | 
					 | 
				
			||||||
	char *config_file;
 | 
					 | 
				
			||||||
	struct sgsn_config cfg;
 | 
					 | 
				
			||||||
	/* File descriptor wrappers for LibGTP */
 | 
					 | 
				
			||||||
	struct bsc_fd gtp_fd0;
 | 
					 | 
				
			||||||
	struct bsc_fd gtp_fd1c;
 | 
					 | 
				
			||||||
	struct bsc_fd gtp_fd1u;
 | 
					 | 
				
			||||||
	/* Timer for libGTP */
 | 
					 | 
				
			||||||
	struct timer_list gtp_timer;
 | 
					 | 
				
			||||||
	/* GSN instance for libgtp */
 | 
					 | 
				
			||||||
	struct gsn_t *gsn;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern struct sgsn_instance *sgsn;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* sgsn_vty.c */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sgsn_vty_init(void);
 | 
					 | 
				
			||||||
int sgsn_parse_config(const char *config_file, struct sgsn_config *cfg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* sgsn.c */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Main input function for Gb proxy */
 | 
					 | 
				
			||||||
int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
 | 
					 | 
				
			||||||
					 struct sgsn_mm_ctx *mmctx,
 | 
					 | 
				
			||||||
					 uint16_t nsapi,
 | 
					 | 
				
			||||||
					 struct tlv_parsed *tp);
 | 
					 | 
				
			||||||
int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* gprs_sndcp.c */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Entry point for the SNSM-ACTIVATE.indication */
 | 
					 | 
				
			||||||
int sndcp_sm_activate_ind(struct gprs_llc_lle *lle, uint8_t nsapi);
 | 
					 | 
				
			||||||
/* Entry point for the SNSM-DEACTIVATE.indication */
 | 
					 | 
				
			||||||
int sndcp_sm_deactivate_ind(struct gprs_llc_lle *lle, uint8_t nsapi);
 | 
					 | 
				
			||||||
/* Called by SNDCP when it has received/re-assembled a N-PDU */
 | 
					 | 
				
			||||||
int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi,
 | 
					 | 
				
			||||||
			 struct msgb *msg, uint32_t npdu_len, uint8_t *npdu);
 | 
					 | 
				
			||||||
int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi,
 | 
					 | 
				
			||||||
			void *mmcontext);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/* Generic signalling/notification infrastructure */
 | 
					/* Generic signalling/notification infrastructure */
 | 
				
			||||||
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
 | 
					 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -26,8 +26,8 @@
 | 
				
			|||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					#include <openbsc/gsm_data.h>
 | 
				
			||||||
 | 
					#include <openbsc/gsm_subscriber.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/signal.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Signalling subsystems
 | 
					 * Signalling subsystems
 | 
				
			||||||
@@ -41,16 +41,11 @@ enum signal_subsystems {
 | 
				
			|||||||
	SS_SUBSCR,
 | 
						SS_SUBSCR,
 | 
				
			||||||
	SS_SCALL,
 | 
						SS_SCALL,
 | 
				
			||||||
	SS_GLOBAL,
 | 
						SS_GLOBAL,
 | 
				
			||||||
	SS_CHALLOC,
 | 
					 | 
				
			||||||
	SS_NS,
 | 
					 | 
				
			||||||
	SS_IPAC_NWL,
 | 
					 | 
				
			||||||
	SS_RF,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SS_PAGING signals */
 | 
					/* SS_PAGING signals */
 | 
				
			||||||
enum signal_paging {
 | 
					enum signal_paging {
 | 
				
			||||||
	S_PAGING_SUCCEEDED,
 | 
						S_PAGING_COMPLETED,
 | 
				
			||||||
	S_PAGING_EXPIRED,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SS_SMS signals */
 | 
					/* SS_SMS signals */
 | 
				
			||||||
@@ -74,9 +69,6 @@ enum signal_nm {
 | 
				
			|||||||
	S_NM_FAIL_REP,		/* GSM 12.21 failure event report */
 | 
						S_NM_FAIL_REP,		/* GSM 12.21 failure event report */
 | 
				
			||||||
	S_NM_NACK,		/* GSM 12.21 various NM_MT_*_NACK happened */
 | 
						S_NM_NACK,		/* GSM 12.21 various NM_MT_*_NACK happened */
 | 
				
			||||||
	S_NM_IPACC_NACK,	/* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_NACK happened */
 | 
						S_NM_IPACC_NACK,	/* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_NACK happened */
 | 
				
			||||||
	S_NM_IPACC_ACK,		/* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_ACK happened */
 | 
					 | 
				
			||||||
	S_NM_IPACC_RESTART_ACK, /* nanoBTS has send a restart ack */
 | 
					 | 
				
			||||||
	S_NM_IPACC_RESTART_NACK,/* nanoBTS has send a restart ack */
 | 
					 | 
				
			||||||
	S_NM_TEST_REP,		/* GSM 12.21 Test Report */
 | 
						S_NM_TEST_REP,		/* GSM 12.21 Test Report */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -96,12 +88,6 @@ enum signal_lchan {
 | 
				
			|||||||
	S_LCHAN_MEAS_REP,		/* 08.58 Measurement Report */
 | 
						S_LCHAN_MEAS_REP,		/* 08.58 Measurement Report */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SS_CHALLOC signals */
 | 
					 | 
				
			||||||
enum signal_challoc {
 | 
					 | 
				
			||||||
	S_CHALLOC_ALLOC_FAIL,	/* allocation of lchan has failed */
 | 
					 | 
				
			||||||
	S_CHALLOC_FREED,	/* lchan has been successfully freed */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* SS_SUBSCR signals */
 | 
					/* SS_SUBSCR signals */
 | 
				
			||||||
enum signal_subscr {
 | 
					enum signal_subscr {
 | 
				
			||||||
	S_SUBSCR_ATTACHED,
 | 
						S_SUBSCR_ATTACHED,
 | 
				
			||||||
@@ -116,68 +102,33 @@ enum signal_scall {
 | 
				
			|||||||
	S_SCALL_DETACHED,
 | 
						S_SCALL_DETACHED,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SS_IPAC_NWL signals */
 | 
					 | 
				
			||||||
enum signal_ipaccess {
 | 
					 | 
				
			||||||
	S_IPAC_NWL_COMPLETE,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum signal_global {
 | 
					enum signal_global {
 | 
				
			||||||
	S_GLOBAL_SHUTDOWN,
 | 
						S_GLOBAL_SHUTDOWN,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SS_RF signals */
 | 
					typedef int signal_cbfn(unsigned int subsys, unsigned int signal,
 | 
				
			||||||
enum signal_rf {
 | 
								void *handler_data, void *signal_data);
 | 
				
			||||||
	S_RF_OFF,
 | 
					 | 
				
			||||||
	S_RF_ON,
 | 
					 | 
				
			||||||
	S_RF_GRACE,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_subscriber;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct paging_signal_data {
 | 
					struct paging_signal_data {
 | 
				
			||||||
	struct gsm_subscriber *subscr;
 | 
						struct gsm_subscriber *subscr;
 | 
				
			||||||
	struct gsm_bts *bts;
 | 
						struct gsm_bts *bts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* NULL in case the paging didn't work */
 | 
						/* NULL in case the paging didn't work */
 | 
				
			||||||
	struct gsm_subscriber_connection *conn;
 | 
						struct gsm_lchan *lchan;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct scall_signal_data {
 | 
					struct scall_signal_data {
 | 
				
			||||||
	struct gsm_subscriber *subscr;
 | 
						struct gsm_subscriber *subscr;
 | 
				
			||||||
	struct gsm_subscriber_connection *conn;
 | 
						struct gsm_lchan *lchan;
 | 
				
			||||||
	void *data;
 | 
						void *data;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ipacc_ack_signal_data {
 | 
					/* Management */
 | 
				
			||||||
	struct gsm_bts_trx *trx;
 | 
					int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
 | 
				
			||||||
	u_int8_t msg_type;	
 | 
					void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct nm_nack_signal_data {
 | 
					/* Dispatch */
 | 
				
			||||||
	struct msgb *msg;
 | 
					void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data);
 | 
				
			||||||
	uint8_t mt;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct challoc_signal_data {
 | 
					 | 
				
			||||||
	struct gsm_bts *bts;
 | 
					 | 
				
			||||||
	struct gsm_lchan *lchan;
 | 
					 | 
				
			||||||
	enum gsm_chan_t type;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct rf_signal_data {
 | 
					 | 
				
			||||||
	struct gsm_network *net;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum signal_ns {
 | 
					 | 
				
			||||||
	S_NS_RESET,
 | 
					 | 
				
			||||||
	S_NS_BLOCK,
 | 
					 | 
				
			||||||
	S_NS_UNBLOCK,
 | 
					 | 
				
			||||||
	S_NS_ALIVE_EXP,	/* Tns-alive expired more than N times */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct ns_signal_data {
 | 
					 | 
				
			||||||
	struct gprs_nsvc *nsvc;
 | 
					 | 
				
			||||||
	uint8_t cause;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,7 @@
 | 
				
			|||||||
#ifndef _SILENT_CALL_H
 | 
					#ifndef _SILENT_CALL_H
 | 
				
			||||||
#define _SILENT_CALL_H
 | 
					#define _SILENT_CALL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gsm_subscriber_connection;
 | 
					extern int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int gsm_silent_call_start(struct gsm_subscriber *subscr,
 | 
					 | 
				
			||||||
                                 void *data, int type);
 | 
					 | 
				
			||||||
extern int gsm_silent_call_stop(struct gsm_subscriber *subscr);
 | 
					extern int gsm_silent_call_stop(struct gsm_subscriber *subscr);
 | 
				
			||||||
extern int silent_call_rx(struct gsm_subscriber_connection *conn, struct msgb *msg);
 | 
					 | 
				
			||||||
extern int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _SILENT_CALL_H */
 | 
					#endif /* _SILENT_CALL_H */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +0,0 @@
 | 
				
			|||||||
#ifndef _BSC_SOCKET_H
 | 
					 | 
				
			||||||
#define _BSC_SOCKET_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
#include <osmocore/select.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef IPPROTO_GRE
 | 
					 | 
				
			||||||
#define IPPROTO_GRE 47
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int make_sock(struct bsc_fd *bfd, int proto, u_int32_t ip, u_int16_t port,
 | 
					 | 
				
			||||||
	      int (*cb)(struct bsc_fd *fd, unsigned int what));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* _BSC_SOCKET_H */
 | 
					 | 
				
			||||||
@@ -22,7 +22,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					#include <openbsc/linuxlist.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NR_SUBCH	4
 | 
					#define NR_SUBCH	4
 | 
				
			||||||
#define TRAU_FRAME_SIZE	40
 | 
					#define TRAU_FRAME_SIZE	40
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,42 +1,6 @@
 | 
				
			|||||||
#ifndef _SYSTEM_INFO_H
 | 
					#ifndef _SYSTEM_INFO_H
 | 
				
			||||||
#define _SYSTEM_INFO_H
 | 
					#define _SYSTEM_INFO_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/utils.h>
 | 
					int gsm_generate_si(u_int8_t *output, struct gsm_bts *bts, int type);
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define GSM_MACBLOCK_LEN 		23
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum osmo_sysinfo_type {
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_NONE,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_1,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_2,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_3,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_4,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_5,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_6,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_7,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_8,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_9,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_10,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_13,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_16,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_17,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_18,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_19,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_20,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_2bis,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_2ter,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_2quater,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_5bis,
 | 
					 | 
				
			||||||
	SYSINFO_TYPE_5ter,
 | 
					 | 
				
			||||||
	/* FIXME all the various bis and ter */
 | 
					 | 
				
			||||||
	_MAX_SYSINFO_TYPE
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef u_int8_t sysinfo_buf_t[GSM_MACBLOCK_LEN];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const struct value_string osmo_sitype_strs[_MAX_SYSINFO_TYPE];
 | 
					 | 
				
			||||||
uint8_t gsm_sitype2rsl(enum osmo_sysinfo_type si_type);
 | 
					 | 
				
			||||||
const char *gsm_sitype_name(enum osmo_sysinfo_type si_type);
 | 
					 | 
				
			||||||
int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										192
									
								
								openbsc/include/openbsc/talloc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								openbsc/include/openbsc/talloc.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
				
			|||||||
 | 
					#ifndef _TALLOC_H_
 | 
				
			||||||
 | 
					#define _TALLOC_H_
 | 
				
			||||||
 | 
					/* 
 | 
				
			||||||
 | 
					   Unix SMB/CIFS implementation.
 | 
				
			||||||
 | 
					   Samba temporary memory allocation functions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Copyright (C) Andrew Tridgell 2004-2005
 | 
				
			||||||
 | 
					   Copyright (C) Stefan Metzmacher 2006
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					     ** NOTE! The following LGPL license applies to the talloc
 | 
				
			||||||
 | 
					     ** library. This does NOT imply that all of Samba is released
 | 
				
			||||||
 | 
					     ** under the LGPL
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					   modify it under the terms of the GNU Lesser General Public
 | 
				
			||||||
 | 
					   License as published by the Free Software Foundation; either
 | 
				
			||||||
 | 
					   version 3 of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   This library is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					   Lesser General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					   License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HAVE_VA_COPY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* this is only needed for compatibility with the old talloc */
 | 
				
			||||||
 | 
					typedef void TALLOC_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					  this uses a little trick to allow __LINE__ to be stringified
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#ifndef __location__
 | 
				
			||||||
 | 
					#define __TALLOC_STRING_LINE1__(s)    #s
 | 
				
			||||||
 | 
					#define __TALLOC_STRING_LINE2__(s)   __TALLOC_STRING_LINE1__(s)
 | 
				
			||||||
 | 
					#define __TALLOC_STRING_LINE3__  __TALLOC_STRING_LINE2__(__LINE__)
 | 
				
			||||||
 | 
					#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TALLOC_DEPRECATED
 | 
				
			||||||
 | 
					#define TALLOC_DEPRECATED 0
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef PRINTF_ATTRIBUTE
 | 
				
			||||||
 | 
					#if (__GNUC__ >= 3)
 | 
				
			||||||
 | 
					/** Use gcc attribute to check printf fns.  a1 is the 1-based index of
 | 
				
			||||||
 | 
					 * the parameter containing the format, and a2 the index of the first
 | 
				
			||||||
 | 
					 * argument. Note that some gcc 2.x versions don't handle this
 | 
				
			||||||
 | 
					 * properly **/
 | 
				
			||||||
 | 
					#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define PRINTF_ATTRIBUTE(a1, a2)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* try to make talloc_set_destructor() and talloc_steal() type safe,
 | 
				
			||||||
 | 
					   if we have a recent gcc */
 | 
				
			||||||
 | 
					#if (__GNUC__ >= 3)
 | 
				
			||||||
 | 
					#define _TALLOC_TYPEOF(ptr) __typeof__(ptr)
 | 
				
			||||||
 | 
					#define talloc_set_destructor(ptr, function)				      \
 | 
				
			||||||
 | 
						do {								      \
 | 
				
			||||||
 | 
							int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function);	      \
 | 
				
			||||||
 | 
							_talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \
 | 
				
			||||||
 | 
						} while(0)
 | 
				
			||||||
 | 
					/* this extremely strange macro is to avoid some braindamaged warning
 | 
				
			||||||
 | 
					   stupidity in gcc 4.1.x */
 | 
				
			||||||
 | 
					#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)); __talloc_steal_ret; })
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define talloc_set_destructor(ptr, function) \
 | 
				
			||||||
 | 
						_talloc_set_destructor((ptr), (int (*)(void *))(function))
 | 
				
			||||||
 | 
					#define _TALLOC_TYPEOF(ptr) void *
 | 
				
			||||||
 | 
					#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr))
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr))
 | 
				
			||||||
 | 
					#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* useful macros for creating type checked pointers */
 | 
				
			||||||
 | 
					#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
 | 
				
			||||||
 | 
					#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)
 | 
				
			||||||
 | 
					#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
 | 
				
			||||||
 | 
					#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
 | 
				
			||||||
 | 
					#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
 | 
				
			||||||
 | 
					#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__)
 | 
				
			||||||
 | 
					#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count)
 | 
				
			||||||
 | 
					#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type)
 | 
				
			||||||
 | 
					#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
 | 
				
			||||||
 | 
					#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
 | 
				
			||||||
 | 
					#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if TALLOC_DEPRECATED
 | 
				
			||||||
 | 
					#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
 | 
				
			||||||
 | 
					#define talloc_p(ctx, type) talloc(ctx, type)
 | 
				
			||||||
 | 
					#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)
 | 
				
			||||||
 | 
					#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)
 | 
				
			||||||
 | 
					#define talloc_destroy(ctx) talloc_free(ctx)
 | 
				
			||||||
 | 
					#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The following definitions come from talloc.c  */
 | 
				
			||||||
 | 
					void *_talloc(const void *context, size_t size);
 | 
				
			||||||
 | 
					void *talloc_pool(const void *context, size_t size);
 | 
				
			||||||
 | 
					void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *));
 | 
				
			||||||
 | 
					int talloc_increase_ref_count(const void *ptr);
 | 
				
			||||||
 | 
					size_t talloc_reference_count(const void *ptr);
 | 
				
			||||||
 | 
					void *_talloc_reference(const void *context, const void *ptr);
 | 
				
			||||||
 | 
					int talloc_unlink(const void *context, void *ptr);
 | 
				
			||||||
 | 
					const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
 | 
				
			||||||
 | 
					void talloc_set_name_const(const void *ptr, const char *name);
 | 
				
			||||||
 | 
					void *talloc_named(const void *context, size_t size, 
 | 
				
			||||||
 | 
							   const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
 | 
				
			||||||
 | 
					void *talloc_named_const(const void *context, size_t size, const char *name);
 | 
				
			||||||
 | 
					const char *talloc_get_name(const void *ptr);
 | 
				
			||||||
 | 
					void *talloc_check_name(const void *ptr, const char *name);
 | 
				
			||||||
 | 
					void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);
 | 
				
			||||||
 | 
					void *talloc_parent(const void *ptr);
 | 
				
			||||||
 | 
					const char *talloc_parent_name(const void *ptr);
 | 
				
			||||||
 | 
					void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
 | 
				
			||||||
 | 
					int talloc_free(void *ptr);
 | 
				
			||||||
 | 
					void talloc_free_children(void *ptr);
 | 
				
			||||||
 | 
					void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);
 | 
				
			||||||
 | 
					void *_talloc_steal(const void *new_ctx, const void *ptr);
 | 
				
			||||||
 | 
					void *_talloc_move(const void *new_ctx, const void *pptr);
 | 
				
			||||||
 | 
					size_t talloc_total_size(const void *ptr);
 | 
				
			||||||
 | 
					size_t talloc_total_blocks(const void *ptr);
 | 
				
			||||||
 | 
					void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
 | 
				
			||||||
 | 
								    void (*callback)(const void *ptr,
 | 
				
			||||||
 | 
								  		     int depth, int max_depth,
 | 
				
			||||||
 | 
										     int is_ref,
 | 
				
			||||||
 | 
										     void *private_data),
 | 
				
			||||||
 | 
								    void *private_data);
 | 
				
			||||||
 | 
					void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f);
 | 
				
			||||||
 | 
					void talloc_report_full(const void *ptr, FILE *f);
 | 
				
			||||||
 | 
					void talloc_report(const void *ptr, FILE *f);
 | 
				
			||||||
 | 
					void talloc_enable_null_tracking(void);
 | 
				
			||||||
 | 
					void talloc_disable_null_tracking(void);
 | 
				
			||||||
 | 
					void talloc_enable_leak_report(void);
 | 
				
			||||||
 | 
					void talloc_enable_leak_report_full(void);
 | 
				
			||||||
 | 
					void *_talloc_zero(const void *ctx, size_t size, const char *name);
 | 
				
			||||||
 | 
					void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
 | 
				
			||||||
 | 
					void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
 | 
				
			||||||
 | 
					void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name);
 | 
				
			||||||
 | 
					void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
 | 
				
			||||||
 | 
					void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
 | 
				
			||||||
 | 
					void *talloc_autofree_context(void);
 | 
				
			||||||
 | 
					size_t talloc_get_size(const void *ctx);
 | 
				
			||||||
 | 
					void *talloc_find_parent_byname(const void *ctx, const char *name);
 | 
				
			||||||
 | 
					void talloc_show_parents(const void *context, FILE *file);
 | 
				
			||||||
 | 
					int talloc_is_parent(const void *context, const void *ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *talloc_strdup(const void *t, const char *p);
 | 
				
			||||||
 | 
					char *talloc_strdup_append(char *s, const char *a);
 | 
				
			||||||
 | 
					char *talloc_strdup_append_buffer(char *s, const char *a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *talloc_strndup(const void *t, const char *p, size_t n);
 | 
				
			||||||
 | 
					char *talloc_strndup_append(char *s, const char *a, size_t n);
 | 
				
			||||||
 | 
					char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
 | 
				
			||||||
 | 
					char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
 | 
				
			||||||
 | 
					char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
 | 
				
			||||||
 | 
					char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
 | 
				
			||||||
 | 
					char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/* Hold the copyright and version string */
 | 
					/* minimalistic telnet/network interface it might turn into a wire interface */
 | 
				
			||||||
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
 | 
					/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
@@ -18,14 +18,28 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "bscconfig.h"
 | 
					#ifndef TELNET_INTERFACE_H
 | 
				
			||||||
 | 
					#define TELNET_INTERFACE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *openbsc_copyright =
 | 
					#include "gsm_data.h"
 | 
				
			||||||
	"Copyright (C) 2008-2010 Harald Welte, Holger Freyther\n"
 | 
					#include "linuxlist.h"
 | 
				
			||||||
	"Contributions by Daniel Willmann, Jan Lübbe,Stefan Schmidt\n"
 | 
					#include "select.h"
 | 
				
			||||||
	"Dieter Spaar, Andreas Eversberg\n\n"
 | 
					
 | 
				
			||||||
	"License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>\n"
 | 
					#include <vty/vty.h>
 | 
				
			||||||
	"This is free software: you are free to change and redistribute it.\n"
 | 
					
 | 
				
			||||||
	"There is NO WARRANTY, to the extent permitted by law.\n";
 | 
					#define TELNET_COMMAND_48	1
 | 
				
			||||||
 | 
					#define TELNET_COMMAND_11	2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct telnet_connection {
 | 
				
			||||||
 | 
						struct llist_head entry;
 | 
				
			||||||
 | 
						struct gsm_network *network;
 | 
				
			||||||
 | 
						struct bsc_fd fd;
 | 
				
			||||||
 | 
						struct vty *vty;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void telnet_init(struct gsm_network *network, int port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int bsc_vty_init(struct gsm_network *net);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										72
									
								
								openbsc/include/openbsc/timer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								openbsc/include/openbsc/timer.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TIMER_H
 | 
				
			||||||
 | 
					#define TIMER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "linuxlist.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Timer management:
 | 
				
			||||||
 | 
					 *      - Create a struct timer_list
 | 
				
			||||||
 | 
					 *      - Fill out timeout and use add_timer or
 | 
				
			||||||
 | 
					 *        use schedule_timer to schedule a timer in
 | 
				
			||||||
 | 
					 *        x seconds and microseconds from now...
 | 
				
			||||||
 | 
					 *      - Use del_timer to remove the timer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Internally:
 | 
				
			||||||
 | 
					 *      - We hook into select.c to give a timeval of the
 | 
				
			||||||
 | 
					 *        nearest timer. On already passed timers we give
 | 
				
			||||||
 | 
					 *        it a 0 to immediately fire after the select
 | 
				
			||||||
 | 
					 *      - update_timers will call the callbacks and remove
 | 
				
			||||||
 | 
					 *        the timers.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct timer_list {
 | 
				
			||||||
 | 
						struct llist_head entry;
 | 
				
			||||||
 | 
						struct timeval timeout;
 | 
				
			||||||
 | 
						unsigned int active  : 1;
 | 
				
			||||||
 | 
						unsigned int handled : 1;
 | 
				
			||||||
 | 
						unsigned int in_list : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void (*cb)(void*);
 | 
				
			||||||
 | 
						void *data;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * timer management
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void bsc_add_timer(struct timer_list *timer);
 | 
				
			||||||
 | 
					void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds);
 | 
				
			||||||
 | 
					void bsc_del_timer(struct timer_list *timer);
 | 
				
			||||||
 | 
					int bsc_timer_pending(struct timer_list *timer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * internal timer list management
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct timeval *bsc_nearest_timer();
 | 
				
			||||||
 | 
					void bsc_prepare_timers();
 | 
				
			||||||
 | 
					int bsc_update_timers();
 | 
				
			||||||
 | 
					int bsc_timer_check(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										221
									
								
								openbsc/include/openbsc/tlv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								openbsc/include/openbsc/tlv.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,221 @@
 | 
				
			|||||||
 | 
					#ifndef _TLV_H
 | 
				
			||||||
 | 
					#define _TLV_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openbsc/msgb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Terminology / wording
 | 
				
			||||||
 | 
							tag	length		value	(in bits)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    V	-	-		8
 | 
				
			||||||
 | 
						   LV	-	8		N * 8
 | 
				
			||||||
 | 
						  TLV	8	8		N * 8
 | 
				
			||||||
 | 
						TL16V	8	16		N * 8
 | 
				
			||||||
 | 
						TLV16	8	8		N * 16
 | 
				
			||||||
 | 
						 TvLV	8	8/16		N * 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LV_GROSS_LEN(x)		(x+1)
 | 
				
			||||||
 | 
					#define TLV_GROSS_LEN(x)	(x+2)
 | 
				
			||||||
 | 
					#define TLV16_GROSS_LEN(x)	((2*x)+2)
 | 
				
			||||||
 | 
					#define TL16V_GROSS_LEN(x)	(x+3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TVLV_MAX_ONEBYTE	0x7f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int16_t TVLV_GROSS_LEN(u_int16_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (len <= TVLV_MAX_ONEBYTE)
 | 
				
			||||||
 | 
							return TLV_GROSS_LEN(len);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return TL16V_GROSS_LEN(len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TLV generation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *lv_put(u_int8_t *buf, u_int8_t len,
 | 
				
			||||||
 | 
									const u_int8_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*buf++ = len;
 | 
				
			||||||
 | 
						memcpy(buf, val, len);
 | 
				
			||||||
 | 
						return buf + len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
 | 
				
			||||||
 | 
									const u_int8_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*buf++ = tag;
 | 
				
			||||||
 | 
						*buf++ = len;
 | 
				
			||||||
 | 
						memcpy(buf, val, len);
 | 
				
			||||||
 | 
						return buf + len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *tlv16_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
 | 
				
			||||||
 | 
									const u_int16_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*buf++ = tag;
 | 
				
			||||||
 | 
						*buf++ = len;
 | 
				
			||||||
 | 
						memcpy(buf, val, len*2);
 | 
				
			||||||
 | 
						return buf + len*2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
 | 
				
			||||||
 | 
									const u_int8_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*buf++ = tag;
 | 
				
			||||||
 | 
						*buf++ = len >> 8;
 | 
				
			||||||
 | 
						*buf++ = len & 0xff;
 | 
				
			||||||
 | 
						memcpy(buf, val, len);
 | 
				
			||||||
 | 
						return buf + len*2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *tvlv_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
 | 
				
			||||||
 | 
									 const u_int8_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len <= TVLV_MAX_ONEBYTE) {
 | 
				
			||||||
 | 
							ret = tlv_put(buf, tag, len, val);
 | 
				
			||||||
 | 
							buf[1] |= 0x80;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							ret = tl16v_put(buf, tag, len, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_tlv16_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int16_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len));
 | 
				
			||||||
 | 
						return tlv16_put(buf, tag, len, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
 | 
				
			||||||
 | 
										const u_int8_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len));
 | 
				
			||||||
 | 
						return tl16v_put(buf, tag, len, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_tvlv_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
 | 
				
			||||||
 | 
									      const u_int8_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len));
 | 
				
			||||||
 | 
						return tvlv_put(buf, tag, len, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *v_put(u_int8_t *buf, u_int8_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*buf++ = val;
 | 
				
			||||||
 | 
						return buf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag, 
 | 
				
			||||||
 | 
									u_int8_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*buf++ = tag;
 | 
				
			||||||
 | 
						*buf++ = val;
 | 
				
			||||||
 | 
						return buf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 'val' is still in host byte order! */
 | 
				
			||||||
 | 
					static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag, 
 | 
				
			||||||
 | 
									 u_int16_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*buf++ = tag;
 | 
				
			||||||
 | 
						*buf++ = val >> 8;
 | 
				
			||||||
 | 
						*buf++ = val & 0xff;
 | 
				
			||||||
 | 
						return buf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_lv_put(struct msgb *msg, u_int8_t len, const u_int8_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_put(msg, LV_GROSS_LEN(len));
 | 
				
			||||||
 | 
						return lv_put(buf, len, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
 | 
				
			||||||
 | 
						return tlv_put(buf, tag, len, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_put(msg, 2);
 | 
				
			||||||
 | 
						return tv_put(buf, tag, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_v_put(struct msgb *msg, u_int8_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_put(msg, 1);
 | 
				
			||||||
 | 
						return v_put(buf, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_put(msg, 3);
 | 
				
			||||||
 | 
						return tv16_put(buf, tag, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_tlv_push(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
 | 
				
			||||||
 | 
						return tlv_put(buf, tag, len, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_tv_push(struct msgb *msg, u_int8_t tag, u_int8_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_push(msg, 2);
 | 
				
			||||||
 | 
						return tv_put(buf, tag, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline u_int8_t *msgb_tv16_push(struct msgb *msg, u_int8_t tag, u_int16_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int8_t *buf = msgb_push(msg, 3);
 | 
				
			||||||
 | 
						return tv16_put(buf, tag, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TLV parsing */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct tlv_p_entry {
 | 
				
			||||||
 | 
						u_int16_t len;
 | 
				
			||||||
 | 
						const u_int8_t *val;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum tlv_type {
 | 
				
			||||||
 | 
						TLV_TYPE_FIXED,
 | 
				
			||||||
 | 
						TLV_TYPE_T,
 | 
				
			||||||
 | 
						TLV_TYPE_TV,
 | 
				
			||||||
 | 
						TLV_TYPE_TLV,
 | 
				
			||||||
 | 
						TLV_TYPE_TL16V,
 | 
				
			||||||
 | 
						TLV_TYPE_TvLV,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct tlv_def {
 | 
				
			||||||
 | 
						enum tlv_type type;
 | 
				
			||||||
 | 
						u_int8_t fixed_len;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct tlv_definition {
 | 
				
			||||||
 | 
						struct tlv_def def[0xff];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct tlv_parsed {
 | 
				
			||||||
 | 
						struct tlv_p_entry lv[0xff];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct tlv_definition tvlv_att_def;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int tlv_parse_one(u_int8_t *o_tag, u_int16_t *o_len, const u_int8_t **o_val,
 | 
				
			||||||
 | 
					                  const struct tlv_definition *def,
 | 
				
			||||||
 | 
					                  const u_int8_t *buf, int buf_len);
 | 
				
			||||||
 | 
					int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
 | 
				
			||||||
 | 
						      const u_int8_t *buf, int buf_len, u_int8_t lv_tag, u_int8_t lv_tag2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TLVP_PRESENT(x, y)	((x)->lv[y].val)
 | 
				
			||||||
 | 
					#define TLVP_LEN(x, y)		(x)->lv[y].len
 | 
				
			||||||
 | 
					#define TLVP_VAL(x, y)		(x)->lv[y].val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* _TLV_H */
 | 
				
			||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					#include <openbsc/gsm_data.h>
 | 
				
			||||||
#include <openbsc/gsm_subscriber.h>
 | 
					#include <openbsc/gsm_subscriber.h>
 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					#include <openbsc/linuxlist.h>
 | 
				
			||||||
#include <openbsc/gsm_04_11.h>
 | 
					#include <openbsc/gsm_04_11.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* One transaction */
 | 
					/* One transaction */
 | 
				
			||||||
@@ -20,8 +20,8 @@ struct gsm_trans {
 | 
				
			|||||||
	/* To whom we belong, unique identifier of remote MM entity */
 | 
						/* To whom we belong, unique identifier of remote MM entity */
 | 
				
			||||||
	struct gsm_subscriber *subscr;
 | 
						struct gsm_subscriber *subscr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* The associated connection we are using to transmit messages */
 | 
						/* The LCHAN that we're currently using to transmit messages */
 | 
				
			||||||
	struct gsm_subscriber_connection *conn;
 | 
						struct gsm_lchan *lchan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* reference from MNCC or other application */
 | 
						/* reference from MNCC or other application */
 | 
				
			||||||
	u_int32_t callref;
 | 
						u_int32_t callref;
 | 
				
			||||||
@@ -69,4 +69,8 @@ void trans_free(struct gsm_trans *trans);
 | 
				
			|||||||
int trans_assign_trans_id(struct gsm_subscriber *subscr,
 | 
					int trans_assign_trans_id(struct gsm_subscriber *subscr,
 | 
				
			||||||
			  u_int8_t protocol, u_int8_t ti_flag);
 | 
								  u_int8_t protocol, u_int8_t ti_flag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* update all transactions to use a different LCHAN, e.g.
 | 
				
			||||||
 | 
					 * after handover has succeeded */
 | 
				
			||||||
 | 
					int trans_lchan_change(struct gsm_lchan *lchan_old,
 | 
				
			||||||
 | 
							       struct gsm_lchan *lchan_new);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,8 +3,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Handler function for mobile-originated USSD messages */
 | 
					/* Handler function for mobile-originated USSD messages */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					#include <openbsc/msgb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg);
 | 
					int handle_rcv_ussd(struct msgb *msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,37 +0,0 @@
 | 
				
			|||||||
#ifndef OPENBSC_VTY_H
 | 
					 | 
				
			||||||
#define OPENBSC_VTY_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocom/vty/vty.h>
 | 
					 | 
				
			||||||
#include <osmocom/vty/buffer.h>
 | 
					 | 
				
			||||||
#include <osmocom/vty/command.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct gsm_network;
 | 
					 | 
				
			||||||
struct vty;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void logging_vty_add_cmds(void);
 | 
					 | 
				
			||||||
void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct buffer *vty_argv_to_buffer(int argc, const char *argv[], int base);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern struct cmd_element cfg_description_cmd;
 | 
					 | 
				
			||||||
extern struct cmd_element cfg_no_description_cmd;
 | 
					 | 
				
			||||||
extern struct cmd_element ournode_exit_cmd;
 | 
					 | 
				
			||||||
extern struct cmd_element ournode_end_cmd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum bsc_vty_node {
 | 
					 | 
				
			||||||
	GSMNET_NODE = _LAST_OSMOVTY_NODE + 1,
 | 
					 | 
				
			||||||
	BTS_NODE,
 | 
					 | 
				
			||||||
	TRX_NODE,
 | 
					 | 
				
			||||||
	TS_NODE,
 | 
					 | 
				
			||||||
	SUBSCR_NODE,
 | 
					 | 
				
			||||||
	MGCP_NODE,
 | 
					 | 
				
			||||||
	GBPROXY_NODE,
 | 
					 | 
				
			||||||
	SGSN_NODE,
 | 
					 | 
				
			||||||
	NS_NODE,
 | 
					 | 
				
			||||||
	BSSGP_NODE,
 | 
					 | 
				
			||||||
	OML_NODE,
 | 
					 | 
				
			||||||
	NAT_NODE,
 | 
					 | 
				
			||||||
	NAT_BSC_NODE,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								openbsc/include/sccp/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								openbsc/include/sccp/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					noinst_HEADERS = sccp_types.h sccp.h
 | 
				
			||||||
							
								
								
									
										167
									
								
								openbsc/include/sccp/sccp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								openbsc/include/sccp/sccp.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,167 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SCCP management code
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * (C) 2009, 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef SCCP_H
 | 
				
			||||||
 | 
					#define SCCP_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openbsc/msgb.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "sccp_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_system;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						SCCP_CONNECTION_STATE_NONE,
 | 
				
			||||||
 | 
						SCCP_CONNECTION_STATE_REQUEST,
 | 
				
			||||||
 | 
						SCCP_CONNECTION_STATE_CONFIRM,
 | 
				
			||||||
 | 
						SCCP_CONNECTION_STATE_ESTABLISHED,
 | 
				
			||||||
 | 
						SCCP_CONNECTION_STATE_RELEASE,
 | 
				
			||||||
 | 
						SCCP_CONNECTION_STATE_RELEASE_COMPLETE,
 | 
				
			||||||
 | 
						SCCP_CONNECTION_STATE_REFUSED,
 | 
				
			||||||
 | 
						SCCP_CONNECTION_STATE_SETUP_ERROR,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sockaddr_sccp {
 | 
				
			||||||
 | 
						sa_family_t	sccp_family;		/* AF_SCCP in the future??? */
 | 
				
			||||||
 | 
						u_int8_t	sccp_ssn;		/* subssystem number for routing */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TODO fill in address indicator... if that is ever needed */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* not sure about these */
 | 
				
			||||||
 | 
						/* u_int8_t    sccp_class; */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * parsed structure of an address
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct sccp_address {
 | 
				
			||||||
 | 
						struct sccp_called_party_address    address;
 | 
				
			||||||
 | 
						u_int8_t			    ssn;
 | 
				
			||||||
 | 
						u_int8_t			    poi[2];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_optional_data {
 | 
				
			||||||
 | 
						u_int8_t			    data_len;
 | 
				
			||||||
 | 
						u_int8_t			    data_start;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_connection {
 | 
				
			||||||
 | 
						/* public */
 | 
				
			||||||
 | 
						void *data_ctx;
 | 
				
			||||||
 | 
						void (*data_cb)(struct sccp_connection *conn, struct msgb *msg, unsigned int len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *state_ctx;
 | 
				
			||||||
 | 
						void (*state_cb)(struct sccp_connection *, int old_state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct sccp_source_reference source_local_reference;
 | 
				
			||||||
 | 
						struct sccp_source_reference destination_local_reference;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int connection_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* private */
 | 
				
			||||||
 | 
						/* list of active connections */
 | 
				
			||||||
 | 
						struct llist_head list;
 | 
				
			||||||
 | 
						struct sccp_system *system;
 | 
				
			||||||
 | 
						int incoming;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * system functionality to implement on top of any other transport layer:
 | 
				
			||||||
 | 
					 *   call sccp_system_incoming for incoming data (from the network)
 | 
				
			||||||
 | 
					 *   sccp will call outgoing whenever outgoing data exists
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sccp_system_init(int (*outgoing)(struct msgb *data, void *ctx), void *context);
 | 
				
			||||||
 | 
					int sccp_system_incoming(struct msgb *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Send data on an existing connection
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sccp_connection_write(struct sccp_connection *connection, struct msgb *data);
 | 
				
			||||||
 | 
					int sccp_connection_send_it(struct sccp_connection *connection);
 | 
				
			||||||
 | 
					int sccp_connection_close(struct sccp_connection *connection, int cause);
 | 
				
			||||||
 | 
					int sccp_connection_free(struct sccp_connection *connection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Create a new socket. Set your callbacks and then call bind to open
 | 
				
			||||||
 | 
					 * the connection.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct sccp_connection *sccp_connection_socket(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Open the connection and send additional data
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sccp_connection_connect(struct sccp_connection *conn,
 | 
				
			||||||
 | 
								    const struct sockaddr_sccp *sccp_called,
 | 
				
			||||||
 | 
								    struct msgb *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * mostly for testing purposes only. Set the accept callback.
 | 
				
			||||||
 | 
					 * TODO: add true routing information... in analogy to socket, bind, accept
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sccp_connection_set_incoming(const struct sockaddr_sccp *sock,
 | 
				
			||||||
 | 
									 int (*accept_cb)(struct sccp_connection *connection, void *data),
 | 
				
			||||||
 | 
									 void *user_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Send data in terms of unit data. A fixed address indicator will be used.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sccp_write(struct msgb *data,
 | 
				
			||||||
 | 
						       const struct sockaddr_sccp *sock_sender,
 | 
				
			||||||
 | 
						       const struct sockaddr_sccp *sock_target, int class);
 | 
				
			||||||
 | 
					int sccp_set_read(const struct sockaddr_sccp *sock,
 | 
				
			||||||
 | 
							  int (*read_cb)(struct msgb *msgb, unsigned int, void *user_data),
 | 
				
			||||||
 | 
							  void *user_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* generic sock addresses */
 | 
				
			||||||
 | 
					extern const struct sockaddr_sccp sccp_ssn_bssap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* helpers */
 | 
				
			||||||
 | 
					u_int32_t sccp_src_ref_to_int(struct sccp_source_reference *ref);
 | 
				
			||||||
 | 
					struct sccp_source_reference sccp_src_ref_from_int(u_int32_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Below this are helper functions and structs for parsing SCCP messages
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct sccp_parse_result {
 | 
				
			||||||
 | 
						struct sccp_address called;
 | 
				
			||||||
 | 
						struct sccp_address calling;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* point to the msg packet */
 | 
				
			||||||
 | 
						struct sccp_source_reference *source_local_reference;
 | 
				
			||||||
 | 
						struct sccp_source_reference *destination_local_reference;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* data pointer */
 | 
				
			||||||
 | 
						int data_len;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * helper functions for the nat code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int sccp_determine_msg_type(struct msgb *msg);
 | 
				
			||||||
 | 
					int sccp_parse_header(struct msgb *msg, struct sccp_parse_result *result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										394
									
								
								openbsc/include/sccp/sccp_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										394
									
								
								openbsc/include/sccp/sccp_types.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,394 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * ITU Q.713 defined types for SCCP
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef SCCP_TYPES_H
 | 
				
			||||||
 | 
					#define SCCP_TYPES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 1/Q.713 - SCCP message types */
 | 
				
			||||||
 | 
					enum sccp_message_types {
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_CR	= 1,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_CC	= 2,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_CREF	= 3,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_RLSD	= 4,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_RLC	= 5,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_DT1	= 6,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_DT2	= 7,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_AK	= 8,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_UDT	= 9,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_UDTS	= 10,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_ED	= 11,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_EA	= 12,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_RSR	= 13,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_RSC	= 14,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_ERR	= 15,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_IT	= 16,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_XUDT	= 17,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_XUDTS	= 18,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_LUDT	= 19,
 | 
				
			||||||
 | 
						SCCP_MSG_TYPE_LUDTS	= 20
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Table 2/Q.713 - SCCP parameter name codes */
 | 
				
			||||||
 | 
					enum sccp_parameter_name_codes {
 | 
				
			||||||
 | 
						SCCP_PNC_END_OF_OPTIONAL		= 0,
 | 
				
			||||||
 | 
						SCCP_PNC_DESTINATION_LOCAL_REFERENCE	= 1,
 | 
				
			||||||
 | 
						SCCP_PNC_SOURCE_LOCAL_REFERENCE		= 2,
 | 
				
			||||||
 | 
						SCCP_PNC_CALLED_PARTY_ADDRESS		= 3,
 | 
				
			||||||
 | 
						SCCP_PNC_CALLING_PARTY_ADDRESS		= 4,
 | 
				
			||||||
 | 
						SCCP_PNC_PROTOCOL_CLASS			= 5,
 | 
				
			||||||
 | 
						SCCP_PNC_SEGMENTING			= 6,
 | 
				
			||||||
 | 
						SCCP_PNC_RECEIVE_SEQ_NUMBER		= 7,
 | 
				
			||||||
 | 
						SCCP_PNC_SEQUENCING			= 8,
 | 
				
			||||||
 | 
						SCCP_PNC_CREDIT				= 9,
 | 
				
			||||||
 | 
						SCCP_PNC_RELEASE_CAUSE			= 10,
 | 
				
			||||||
 | 
						SCCP_PNC_RETURN_CAUSE			= 11,
 | 
				
			||||||
 | 
						SCCP_PNC_RESET_CAUSE			= 12,
 | 
				
			||||||
 | 
						SCCP_PNC_ERROR_CAUSE			= 13,
 | 
				
			||||||
 | 
						SCCP_PNC_REFUSAL_CAUSE			= 14,
 | 
				
			||||||
 | 
						SCCP_PNC_DATA				= 15,
 | 
				
			||||||
 | 
						SCCP_PNC_SEGMENTATION			= 16,
 | 
				
			||||||
 | 
						SCCP_PNC_HOP_COUNTER			= 17,
 | 
				
			||||||
 | 
						SCCP_PNC_IMPORTANCE			= 18,
 | 
				
			||||||
 | 
						SCCP_PNC_LONG_DATA			= 19,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Figure 3/Q.713 Called/calling party address */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						SCCP_TITLE_IND_NONE			= 0,
 | 
				
			||||||
 | 
						SCCP_TITLE_IND_NATURE_ONLY		= 1,
 | 
				
			||||||
 | 
						SCCP_TITLE_IND_TRANSLATION_ONLY		= 2,
 | 
				
			||||||
 | 
						SCCP_TITLE_IND_TRANS_NUM_ENC		= 3,
 | 
				
			||||||
 | 
						SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE	= 4,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						SCCP_CALL_ROUTE_ON_SSN			= 1,
 | 
				
			||||||
 | 
						SCCP_CALL_ROUTE_ON_GT			= 0,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_called_party_address {
 | 
				
			||||||
 | 
						u_int8_t	point_code_indicator : 1,
 | 
				
			||||||
 | 
								ssn_indicator	     : 1,
 | 
				
			||||||
 | 
								global_title_indicator : 4,
 | 
				
			||||||
 | 
								routing_indicator    : 1,
 | 
				
			||||||
 | 
								reserved	     : 1;
 | 
				
			||||||
 | 
						u_int8_t	data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* indicator indicates presence in the above order */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Figure 6/Q.713 */
 | 
				
			||||||
 | 
					struct sccp_signalling_point_code {
 | 
				
			||||||
 | 
						u_int8_t	lsb;
 | 
				
			||||||
 | 
						u_int8_t	msb : 6,
 | 
				
			||||||
 | 
								reserved : 2;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* SSN == subsystem number */
 | 
				
			||||||
 | 
					enum sccp_subsystem_number {
 | 
				
			||||||
 | 
						SCCP_SSN_NOT_KNOWN_OR_USED	    = 0,
 | 
				
			||||||
 | 
						SCCP_SSN_MANAGEMENT		    = 1,
 | 
				
			||||||
 | 
						SCCP_SSN_RESERVED_ITU		    = 2,
 | 
				
			||||||
 | 
						SCCP_SSN_ISDN_USER_PART		    = 3,
 | 
				
			||||||
 | 
						SCCP_SSN_OMAP			    = 4, /* operation, maint and administration part */
 | 
				
			||||||
 | 
						SCCP_SSN_MAP			    = 5, /* mobile application part */
 | 
				
			||||||
 | 
						SCCP_SSN_HLR			    = 6,
 | 
				
			||||||
 | 
						SCCP_SSN_VLR			    = 7,
 | 
				
			||||||
 | 
						SCCP_SSN_MSC			    = 8,
 | 
				
			||||||
 | 
						SCCP_SSN_EIC			    = 9, /* equipent identifier centre */
 | 
				
			||||||
 | 
						SCCP_SSN_AUC			    = 10, /* authentication centre */
 | 
				
			||||||
 | 
						SCCP_SSN_ISDN_SUPPL_SERVICES	    = 11,
 | 
				
			||||||
 | 
						SCCP_SSN_RESERVED_INTL		    = 12,
 | 
				
			||||||
 | 
						SCCP_SSN_ISDN_EDGE_TO_EDGE	    = 13,
 | 
				
			||||||
 | 
						SCCP_SSN_TC_TEST_RESPONDER	    = 14,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* From GSM 03.03 8.2 */
 | 
				
			||||||
 | 
						SCCP_SSN_BSSAP			    = 254,
 | 
				
			||||||
 | 
						SCCP_SSN_BSSOM			    = 253,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Q.713, 3.4.2.3 */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						SCCP_NAI_UNKNOWN		    = 0,
 | 
				
			||||||
 | 
						SCCP_NAI_SUBSCRIBER_NUMBER	    = 1,
 | 
				
			||||||
 | 
						SCCP_NAI_RESERVED_NATIONAL	    = 2,
 | 
				
			||||||
 | 
						SCCP_NAI_NATIONAL_SIGNIFICANT	    = 3,
 | 
				
			||||||
 | 
						SCCP_NAI_INTERNATIONAL		    = 4,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_global_title {
 | 
				
			||||||
 | 
						u_int8_t	nature_of_addr_ind : 7,
 | 
				
			||||||
 | 
								odd_even : 1;
 | 
				
			||||||
 | 
						u_int8_t	data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Q.713, 3.3 */
 | 
				
			||||||
 | 
					struct sccp_source_reference {
 | 
				
			||||||
 | 
						u_int8_t    octet1;
 | 
				
			||||||
 | 
						u_int8_t    octet2;
 | 
				
			||||||
 | 
						u_int8_t    octet3;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Q.714, 3.6 */
 | 
				
			||||||
 | 
					enum sccp_protocol_class {
 | 
				
			||||||
 | 
						SCCP_PROTOCOL_CLASS_0		    = 0,
 | 
				
			||||||
 | 
						SCCP_PROTOCOL_CLASS_1		    = 1,
 | 
				
			||||||
 | 
						SCCP_PROTOCOL_CLASS_2		    = 2,
 | 
				
			||||||
 | 
						SCCP_PROTOCOL_CLASS_3		    = 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* bits 5-8 when class0, class1 is used */
 | 
				
			||||||
 | 
					enum sccp_protocol_options {
 | 
				
			||||||
 | 
						SCCP_PROTOCOL_NO_SPECIAL	    = 0,
 | 
				
			||||||
 | 
						SCCP_PROTOCOL_RETURN_MESSAGE	    = 8,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum sccp_release_cause {
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_END_USER_ORIGINATED	    = 0,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_END_USER_CONGESTION	    = 1,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_END_USER_FAILURE	    = 2,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_SCCP_USER_ORIGINATED	    = 3,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_REMOTE_PROCEDURE_ERROR   = 4,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_INCONSISTENT_CONN_DATA   = 5,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_ACCESS_FAILURE	    = 6,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_ACCESS_CONGESTION	    = 7,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_SUBSYSTEM_FAILURE	    = 8,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_SUBSYSTEM_CONGESTION	    = 9,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_MTP_FAILURE		    = 10,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_NETWORK_CONGESTION	    = 11,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_EXPIRATION_RESET	    = 12,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_EXPIRATION_INACTIVE	    = 13,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_RESERVED		    = 14,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_UNQUALIFIED		    = 15,
 | 
				
			||||||
 | 
						SCCP_RELEASE_CAUSE_SCCP_FAILURE		    = 16,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum sccp_return_cause {
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_NO_TRANSLATION_NATURE	    = 0,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_NO_TRANSLATION	    = 1,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION	    = 2,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE	    = 3,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_UNEQUIPPED_USER	    = 4,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_MTP_FAILURE		    = 5,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_NETWORK_CONGESTION	    = 6,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_UNQUALIFIED		    = 7,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_ERROR_IN_MSG_TRANSPORT    = 8,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_ERROR_IN_LOCAL_PROCESSING = 9,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_DEST_CANNOT_PERFORM_REASSEMBLY = 10,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_SCCP_FAILURE		    = 11,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION	    = 12,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_SEGMENTATION_NOT_SUPPORTED= 13,
 | 
				
			||||||
 | 
						SCCP_RETURN_CAUSE_SEGMENTATION_FAOLURE	    = 14
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum sccp_reset_cause {
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_END_USER_ORIGINATED	    = 0,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_SCCP_USER_ORIGINATED	    = 1,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_MSG_OUT_OF_ORDER_PS	    = 2,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_MSG_OUT_OF_ORDER_PR	    = 3,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_RPC_OUT_OF_WINDOW	    = 4,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_RPC_INCORRECT_PS	    = 5,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_RPC_GENERAL		    = 6,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_REMOTE_END_USER_OPERATIONAL= 7,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_NETWORK_OPERATIONAL	    = 8,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_ACCESS_OPERATIONAL	    = 9,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_NETWORK_CONGESTION	    = 10,
 | 
				
			||||||
 | 
						SCCP_RESET_CAUSE_RESERVED		    = 11,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum sccp_error_cause {
 | 
				
			||||||
 | 
						SCCP_ERROR_LRN_MISMATCH_UNASSIGNED	    = 0, /* local reference number */
 | 
				
			||||||
 | 
						SCCP_ERROR_LRN_MISMATCH_INCONSISTENT	    = 1,
 | 
				
			||||||
 | 
						SCCP_ERROR_POINT_CODE_MISMATCH		    = 2,
 | 
				
			||||||
 | 
						SCCP_ERROR_SERVICE_CLASS_MISMATCH	    = 3,
 | 
				
			||||||
 | 
						SCCP_ERROR_UNQUALIFIED			    = 4,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum sccp_refusal_cause {
 | 
				
			||||||
 | 
						SCCP_REFUSAL_END_USER_ORIGINATED	    = 0,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_END_USER_CONGESTION	    = 1,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_END_USER_FAILURE		    = 2,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_SCCP_USER_ORIGINATED	    = 3,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_DESTINATION_ADDRESS_UKNOWN	    = 4,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_DESTINATION_INACCESSIBLE	    = 5,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_NET_QOS_NON_TRANSIENT	    = 6,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_NET_QOS_TRANSIENT		    = 7,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_ACCESS_FAILURE		    = 8,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_ACCESS_CONGESTION		    = 9,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_SUBSYSTEM_FAILURE		    = 10,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_SUBSYTEM_CONGESTION	    = 11,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_EXPIRATION			    = 12,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_INCOMPATIBLE_USER_DATA	    = 13,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_RESERVED			    = 14,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_UNQUALIFIED		    = 15,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_HOP_COUNTER_VIOLATION	    = 16,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_SCCP_FAILURE		    = 17,
 | 
				
			||||||
 | 
						SCCP_REFUSAL_UNEQUIPPED_USER		    = 18,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * messages... as of Q.713 Chapter 4
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct sccp_connection_request {
 | 
				
			||||||
 | 
						/* mandantory */
 | 
				
			||||||
 | 
						u_int8_t			type;
 | 
				
			||||||
 | 
						struct sccp_source_reference	source_local_reference;
 | 
				
			||||||
 | 
						u_int8_t			proto_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* variable */
 | 
				
			||||||
 | 
						u_int8_t			variable_called;
 | 
				
			||||||
 | 
					#if VARIABLE
 | 
				
			||||||
 | 
						called_party_address
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* optional */
 | 
				
			||||||
 | 
						u_int8_t			optional_start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if OPTIONAL
 | 
				
			||||||
 | 
						credit 3
 | 
				
			||||||
 | 
						callingparty var 4-n
 | 
				
			||||||
 | 
						data            3-130
 | 
				
			||||||
 | 
						hop_counter     3
 | 
				
			||||||
 | 
						importance      3
 | 
				
			||||||
 | 
						end_of_optional 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int8_t			data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_connection_confirm {
 | 
				
			||||||
 | 
						/* mandantory */
 | 
				
			||||||
 | 
						u_int8_t			type;
 | 
				
			||||||
 | 
						struct sccp_source_reference	destination_local_reference;
 | 
				
			||||||
 | 
						struct sccp_source_reference	source_local_reference;
 | 
				
			||||||
 | 
						u_int8_t			proto_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* optional */
 | 
				
			||||||
 | 
						u_int8_t			optional_start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* optional */
 | 
				
			||||||
 | 
					#if OPTIONAL
 | 
				
			||||||
 | 
						credit 3
 | 
				
			||||||
 | 
						called party 4
 | 
				
			||||||
 | 
						data            3-130
 | 
				
			||||||
 | 
						importance      3
 | 
				
			||||||
 | 
						end_of_optional 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int8_t			data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_connection_refused {
 | 
				
			||||||
 | 
						/* mandantory */
 | 
				
			||||||
 | 
						u_int8_t			type;
 | 
				
			||||||
 | 
						struct sccp_source_reference	destination_local_reference;
 | 
				
			||||||
 | 
						u_int8_t			cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* optional */
 | 
				
			||||||
 | 
						u_int8_t			optional_start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* optional */
 | 
				
			||||||
 | 
					#if OPTIONAL
 | 
				
			||||||
 | 
						called party 4
 | 
				
			||||||
 | 
						data            3-130
 | 
				
			||||||
 | 
						importance      3
 | 
				
			||||||
 | 
						end_of_optional 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int8_t			data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_connection_released {
 | 
				
			||||||
 | 
						/* mandantory */
 | 
				
			||||||
 | 
						u_int8_t			type;
 | 
				
			||||||
 | 
						struct sccp_source_reference	destination_local_reference;
 | 
				
			||||||
 | 
						struct sccp_source_reference	source_local_reference;
 | 
				
			||||||
 | 
						u_int8_t			release_cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* optional */
 | 
				
			||||||
 | 
						u_int8_t			optional_start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if OPTIONAL
 | 
				
			||||||
 | 
						data            3-130
 | 
				
			||||||
 | 
						importance      3
 | 
				
			||||||
 | 
						end_of_optional 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						u_int8_t			data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_connection_release_complete {
 | 
				
			||||||
 | 
						u_int8_t			type;
 | 
				
			||||||
 | 
						struct sccp_source_reference	destination_local_reference;
 | 
				
			||||||
 | 
						struct sccp_source_reference	source_local_reference;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_data_form1 {
 | 
				
			||||||
 | 
						/* mandantory */
 | 
				
			||||||
 | 
						u_int8_t			type;
 | 
				
			||||||
 | 
						struct sccp_source_reference	destination_local_reference;
 | 
				
			||||||
 | 
						u_int8_t			segmenting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* variable */
 | 
				
			||||||
 | 
						u_int8_t			variable_start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if VARIABLE
 | 
				
			||||||
 | 
						data 2-256;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int8_t			data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_data_unitdata {
 | 
				
			||||||
 | 
						/* mandantory */
 | 
				
			||||||
 | 
						u_int8_t			type;
 | 
				
			||||||
 | 
						u_int8_t			proto_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* variable */
 | 
				
			||||||
 | 
						u_int8_t			variable_called;
 | 
				
			||||||
 | 
						u_int8_t			variable_calling;
 | 
				
			||||||
 | 
						u_int8_t			variable_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if VARIABLE
 | 
				
			||||||
 | 
						called party address
 | 
				
			||||||
 | 
						calling party address
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int8_t			data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sccp_data_it {
 | 
				
			||||||
 | 
						/* mandantory */
 | 
				
			||||||
 | 
						u_int8_t			type;
 | 
				
			||||||
 | 
						struct sccp_source_reference	destination_local_reference;
 | 
				
			||||||
 | 
						struct sccp_source_reference	source_local_reference;
 | 
				
			||||||
 | 
						u_int8_t			proto_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int8_t			sequencing[2];
 | 
				
			||||||
 | 
						u_int8_t			credit;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										1
									
								
								openbsc/include/vty/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								openbsc/include/vty/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					noinst_HEADERS = buffer.h command.h  vector.h vty.h
 | 
				
			||||||
							
								
								
									
										102
									
								
								openbsc/include/vty/buffer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								openbsc/include/vty/buffer.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Buffering to output and input.
 | 
				
			||||||
 | 
					 * Copyright (C) 1998 Kunihiro Ishiguro
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is part of GNU Zebra.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * GNU Zebra is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published
 | 
				
			||||||
 | 
					 * by the Free Software Foundation; either version 2, or (at your
 | 
				
			||||||
 | 
					 * option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the
 | 
				
			||||||
 | 
					 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
				
			||||||
 | 
					 * Boston, MA 02111-1307, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _ZEBRA_BUFFER_H
 | 
				
			||||||
 | 
					#define _ZEBRA_BUFFER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Create a new buffer.  Memory will be allocated in chunks of the given
 | 
				
			||||||
 | 
					   size.  If the argument is 0, the library will supply a reasonable
 | 
				
			||||||
 | 
					   default size suitable for buffering socket I/O. */
 | 
				
			||||||
 | 
					struct buffer *buffer_new(size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Free all data in the buffer. */
 | 
				
			||||||
 | 
					void buffer_reset(struct buffer *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function first calls buffer_reset to release all buffered data.
 | 
				
			||||||
 | 
					   Then it frees the struct buffer itself. */
 | 
				
			||||||
 | 
					void buffer_free(struct buffer *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add the given data to the end of the buffer. */
 | 
				
			||||||
 | 
					extern void buffer_put(struct buffer *, const void *, size_t);
 | 
				
			||||||
 | 
					/* Add a single character to the end of the buffer. */
 | 
				
			||||||
 | 
					extern void buffer_putc(struct buffer *, u_char);
 | 
				
			||||||
 | 
					/* Add a NUL-terminated string to the end of the buffer. */
 | 
				
			||||||
 | 
					extern void buffer_putstr(struct buffer *, const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Combine all accumulated (and unflushed) data inside the buffer into a
 | 
				
			||||||
 | 
					   single NUL-terminated string allocated using XMALLOC(MTYPE_TMP).  Note
 | 
				
			||||||
 | 
					   that this function does not alter the state of the buffer, so the data
 | 
				
			||||||
 | 
					   is still inside waiting to be flushed. */
 | 
				
			||||||
 | 
					char *buffer_getstr(struct buffer *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Returns 1 if there is no pending data in the buffer.  Otherwise returns 0. */
 | 
				
			||||||
 | 
					int buffer_empty(struct buffer *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
						/* An I/O error occurred.  The buffer should be destroyed and the
 | 
				
			||||||
 | 
						   file descriptor should be closed. */
 | 
				
			||||||
 | 
						BUFFER_ERROR = -1,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The data was written successfully, and the buffer is now empty
 | 
				
			||||||
 | 
						   (there is no pending data waiting to be flushed). */
 | 
				
			||||||
 | 
						BUFFER_EMPTY = 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* There is pending data in the buffer waiting to be flushed.  Please
 | 
				
			||||||
 | 
						   try flushing the buffer when select indicates that the file descriptor
 | 
				
			||||||
 | 
						   is writeable. */
 | 
				
			||||||
 | 
						BUFFER_PENDING = 1
 | 
				
			||||||
 | 
					} buffer_status_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Try to write this data to the file descriptor.  Any data that cannot
 | 
				
			||||||
 | 
					   be written immediately is added to the buffer queue. */
 | 
				
			||||||
 | 
					extern buffer_status_t buffer_write(struct buffer *, int fd,
 | 
				
			||||||
 | 
									    const void *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function attempts to flush some (but perhaps not all) of
 | 
				
			||||||
 | 
					   the queued data to the given file descriptor. */
 | 
				
			||||||
 | 
					extern buffer_status_t buffer_flush_available(struct buffer *, int fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The following 2 functions (buffer_flush_all and buffer_flush_window)
 | 
				
			||||||
 | 
					   are for use in lib/vty.c only.  They should not be used elsewhere. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Call buffer_flush_available repeatedly until either all data has been
 | 
				
			||||||
 | 
					   flushed, or an I/O error has been encountered, or the operation would
 | 
				
			||||||
 | 
					   block. */
 | 
				
			||||||
 | 
					extern buffer_status_t buffer_flush_all(struct buffer *, int fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Attempt to write enough data to the given fd to fill a window of the
 | 
				
			||||||
 | 
					   given width and height (and remove the data written from the buffer).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   If !no_more, then a message saying " --More-- " is appended.
 | 
				
			||||||
 | 
					   If erase is true, then first overwrite the previous " --More-- " message
 | 
				
			||||||
 | 
					   with spaces.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Any write error (including EAGAIN or EINTR) will cause this function
 | 
				
			||||||
 | 
					   to return -1 (because the logic for handling the erase and more features
 | 
				
			||||||
 | 
					   is too complicated to retry the write later).
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					extern buffer_status_t buffer_flush_window(struct buffer *, int fd, int width,
 | 
				
			||||||
 | 
										   int height, int erase, int no_more);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif				/* _ZEBRA_BUFFER_H */
 | 
				
			||||||
							
								
								
									
										359
									
								
								openbsc/include/vty/command.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										359
									
								
								openbsc/include/vty/command.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,359 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Zebra configuration command interface routine
 | 
				
			||||||
 | 
					 * Copyright (C) 1997, 98 Kunihiro Ishiguro
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is part of GNU Zebra.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * GNU Zebra is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published
 | 
				
			||||||
 | 
					 * by the Free Software Foundation; either version 2, or (at your
 | 
				
			||||||
 | 
					 * option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the
 | 
				
			||||||
 | 
					 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
				
			||||||
 | 
					 * Boston, MA 02111-1307, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _ZEBRA_COMMAND_H
 | 
				
			||||||
 | 
					#define _ZEBRA_COMMAND_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include "vector.h"
 | 
				
			||||||
 | 
					#include "vty.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Host configuration variable */
 | 
				
			||||||
 | 
					struct host {
 | 
				
			||||||
 | 
						/* Host name of this router. */
 | 
				
			||||||
 | 
						char *name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Password for vty interface. */
 | 
				
			||||||
 | 
						char *password;
 | 
				
			||||||
 | 
						char *password_encrypt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Enable password */
 | 
				
			||||||
 | 
						char *enable;
 | 
				
			||||||
 | 
						char *enable_encrypt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* System wide terminal lines. */
 | 
				
			||||||
 | 
						int lines;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Log filename. */
 | 
				
			||||||
 | 
						char *logfile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* config file name of this host */
 | 
				
			||||||
 | 
						char *config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Flags for services */
 | 
				
			||||||
 | 
						int advanced;
 | 
				
			||||||
 | 
						int encrypt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Banner configuration. */
 | 
				
			||||||
 | 
						const char *motd;
 | 
				
			||||||
 | 
						char *motdfile;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* There are some command levels which called from command node. */
 | 
				
			||||||
 | 
					enum node_type {
 | 
				
			||||||
 | 
						AUTH_NODE,		/* Authentication mode of vty interface. */
 | 
				
			||||||
 | 
						VIEW_NODE,		/* View node. Default mode of vty interface. */
 | 
				
			||||||
 | 
						AUTH_ENABLE_NODE,	/* Authentication mode for change enable. */
 | 
				
			||||||
 | 
						ENABLE_NODE,		/* Enable node. */
 | 
				
			||||||
 | 
						CONFIG_NODE,		/* Config node. Default mode of config file. */
 | 
				
			||||||
 | 
						SERVICE_NODE,		/* Service node. */
 | 
				
			||||||
 | 
						DEBUG_NODE,		/* Debug node. */
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
						AAA_NODE,		/* AAA node. */
 | 
				
			||||||
 | 
						KEYCHAIN_NODE,		/* Key-chain node. */
 | 
				
			||||||
 | 
						KEYCHAIN_KEY_NODE,	/* Key-chain key node. */
 | 
				
			||||||
 | 
						INTERFACE_NODE,		/* Interface mode node. */
 | 
				
			||||||
 | 
						ZEBRA_NODE,		/* zebra connection node. */
 | 
				
			||||||
 | 
						TABLE_NODE,		/* rtm_table selection node. */
 | 
				
			||||||
 | 
						RIP_NODE,		/* RIP protocol mode node. */
 | 
				
			||||||
 | 
						RIPNG_NODE,		/* RIPng protocol mode node. */
 | 
				
			||||||
 | 
						BGP_NODE,		/* BGP protocol mode which includes BGP4+ */
 | 
				
			||||||
 | 
						BGP_VPNV4_NODE,		/* BGP MPLS-VPN PE exchange. */
 | 
				
			||||||
 | 
						BGP_IPV4_NODE,		/* BGP IPv4 unicast address family.  */
 | 
				
			||||||
 | 
						BGP_IPV4M_NODE,		/* BGP IPv4 multicast address family.  */
 | 
				
			||||||
 | 
						BGP_IPV6_NODE,		/* BGP IPv6 address family */
 | 
				
			||||||
 | 
						OSPF_NODE,		/* OSPF protocol mode */
 | 
				
			||||||
 | 
						OSPF6_NODE,		/* OSPF protocol for IPv6 mode */
 | 
				
			||||||
 | 
						ISIS_NODE,		/* ISIS protocol mode */
 | 
				
			||||||
 | 
						MASC_NODE,		/* MASC for multicast.  */
 | 
				
			||||||
 | 
						IRDP_NODE,		/* ICMP Router Discovery Protocol mode. */
 | 
				
			||||||
 | 
						IP_NODE,		/* Static ip route node. */
 | 
				
			||||||
 | 
						ACCESS_NODE,		/* Access list node. */
 | 
				
			||||||
 | 
						PREFIX_NODE,		/* Prefix list node. */
 | 
				
			||||||
 | 
						ACCESS_IPV6_NODE,	/* Access list node. */
 | 
				
			||||||
 | 
						PREFIX_IPV6_NODE,	/* Prefix list node. */
 | 
				
			||||||
 | 
						AS_LIST_NODE,		/* AS list node. */
 | 
				
			||||||
 | 
						COMMUNITY_LIST_NODE,	/* Community list node. */
 | 
				
			||||||
 | 
						RMAP_NODE,		/* Route map node. */
 | 
				
			||||||
 | 
						SMUX_NODE,		/* SNMP configuration node. */
 | 
				
			||||||
 | 
						DUMP_NODE,		/* Packet dump node. */
 | 
				
			||||||
 | 
						FORWARDING_NODE,	/* IP forwarding node. */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						VTY_NODE,		/* Vty node. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GSMNET_NODE,
 | 
				
			||||||
 | 
						BTS_NODE,
 | 
				
			||||||
 | 
						TRX_NODE,
 | 
				
			||||||
 | 
						TS_NODE,
 | 
				
			||||||
 | 
						SUBSCR_NODE,
 | 
				
			||||||
 | 
						MGCP_NODE,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Node which has some commands and prompt string and configuration
 | 
				
			||||||
 | 
					   function pointer . */
 | 
				
			||||||
 | 
					struct cmd_node {
 | 
				
			||||||
 | 
						/* Node index. */
 | 
				
			||||||
 | 
						enum node_type node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Prompt character at vty interface. */
 | 
				
			||||||
 | 
						const char *prompt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Is this node's configuration goes to vtysh ? */
 | 
				
			||||||
 | 
						int vtysh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Node's configuration write function */
 | 
				
			||||||
 | 
						int (*func) (struct vty *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Vector of this node's command list. */
 | 
				
			||||||
 | 
						vector cmd_vector;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						CMD_ATTR_DEPRECATED = 1,
 | 
				
			||||||
 | 
						CMD_ATTR_HIDDEN,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Structure of command element. */
 | 
				
			||||||
 | 
					struct cmd_element {
 | 
				
			||||||
 | 
						const char *string;	/* Command specification by string. */
 | 
				
			||||||
 | 
						int (*func) (struct cmd_element *, struct vty *, int, const char *[]);
 | 
				
			||||||
 | 
						const char *doc;	/* Documentation of this command. */
 | 
				
			||||||
 | 
						int daemon;		/* Daemon to which this command belong. */
 | 
				
			||||||
 | 
						vector strvec;		/* Pointing out each description vector. */
 | 
				
			||||||
 | 
						unsigned int cmdsize;	/* Command index count. */
 | 
				
			||||||
 | 
						char *config;		/* Configuration string */
 | 
				
			||||||
 | 
						vector subconfig;	/* Sub configuration string */
 | 
				
			||||||
 | 
						u_char attr;		/* Command attributes */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Command description structure. */
 | 
				
			||||||
 | 
					struct desc {
 | 
				
			||||||
 | 
						const char *cmd;	/* Command string. */
 | 
				
			||||||
 | 
						const char *str;	/* Command's description. */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Return value of the commands. */
 | 
				
			||||||
 | 
					#define CMD_SUCCESS              0
 | 
				
			||||||
 | 
					#define CMD_WARNING              1
 | 
				
			||||||
 | 
					#define CMD_ERR_NO_MATCH         2
 | 
				
			||||||
 | 
					#define CMD_ERR_AMBIGUOUS        3
 | 
				
			||||||
 | 
					#define CMD_ERR_INCOMPLETE       4
 | 
				
			||||||
 | 
					#define CMD_ERR_EXEED_ARGC_MAX   5
 | 
				
			||||||
 | 
					#define CMD_ERR_NOTHING_TODO     6
 | 
				
			||||||
 | 
					#define CMD_COMPLETE_FULL_MATCH  7
 | 
				
			||||||
 | 
					#define CMD_COMPLETE_MATCH       8
 | 
				
			||||||
 | 
					#define CMD_COMPLETE_LIST_MATCH  9
 | 
				
			||||||
 | 
					#define CMD_SUCCESS_DAEMON      10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Argc max counts. */
 | 
				
			||||||
 | 
					#define CMD_ARGC_MAX   25
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Turn off these macros when uisng cpp with extract.pl */
 | 
				
			||||||
 | 
					#ifndef VTYSH_EXTRACT_PL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* helper defines for end-user DEFUN* macros */
 | 
				
			||||||
 | 
					#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
 | 
				
			||||||
 | 
					  struct cmd_element cmdname = \
 | 
				
			||||||
 | 
					  { \
 | 
				
			||||||
 | 
					    .string = cmdstr, \
 | 
				
			||||||
 | 
					    .func = funcname, \
 | 
				
			||||||
 | 
					    .doc = helpstr, \
 | 
				
			||||||
 | 
					    .attr = attrs, \
 | 
				
			||||||
 | 
					    .daemon = dnum, \
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFUN_CMD_FUNC_DECL(funcname) \
 | 
				
			||||||
 | 
					  static int funcname (struct cmd_element *, struct vty *, int, const char *[]); \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFUN_CMD_FUNC_TEXT(funcname) \
 | 
				
			||||||
 | 
					  static int funcname \
 | 
				
			||||||
 | 
					    (struct cmd_element *self, struct vty *vty, int argc, const char *argv[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DEFUN for vty command interafce. Little bit hacky ;-). */
 | 
				
			||||||
 | 
					#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_FUNC_DECL(funcname) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_FUNC_TEXT(funcname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_FUNC_DECL(funcname) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_FUNC_TEXT(funcname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFUN_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFUN_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED) \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DEFUN_NOSH for commands that vtysh should ignore */
 | 
				
			||||||
 | 
					#define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN(funcname, cmdname, cmdstr, helpstr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DEFSH for vtysh. */
 | 
				
			||||||
 | 
					#define DEFSH(daemon, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, 0, daemon) \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DEFUN + DEFSH */
 | 
				
			||||||
 | 
					#define DEFUNSH(daemon, funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_FUNC_DECL(funcname) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_FUNC_TEXT(funcname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DEFUN + DEFSH with attributes */
 | 
				
			||||||
 | 
					#define DEFUNSH_ATTR(daemon, funcname, cmdname, cmdstr, helpstr, attr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_FUNC_DECL(funcname) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, daemon) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_FUNC_TEXT(funcname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFUNSH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFUNSH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ALIAS macro which define existing command's alias. */
 | 
				
			||||||
 | 
					#define ALIAS(funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALIAS_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALIAS_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALIAS_SH(daemon, funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALIAS_SH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, daemon)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALIAS_SH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \
 | 
				
			||||||
 | 
					  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, daemon)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif				/* VTYSH_EXTRACT_PL */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Some macroes */
 | 
				
			||||||
 | 
					#define CMD_OPTION(S)   ((S[0]) == '[')
 | 
				
			||||||
 | 
					#define CMD_VARIABLE(S) (((S[0]) >= 'A' && (S[0]) <= 'Z') || ((S[0]) == '<'))
 | 
				
			||||||
 | 
					#define CMD_VARARG(S)   ((S[0]) == '.')
 | 
				
			||||||
 | 
					#define CMD_RANGE(S)	((S[0] == '<'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CMD_IPV4(S)	   ((strcmp ((S), "A.B.C.D") == 0))
 | 
				
			||||||
 | 
					#define CMD_IPV4_PREFIX(S) ((strcmp ((S), "A.B.C.D/M") == 0))
 | 
				
			||||||
 | 
					#define CMD_IPV6(S)        ((strcmp ((S), "X:X::X:X") == 0))
 | 
				
			||||||
 | 
					#define CMD_IPV6_PREFIX(S) ((strcmp ((S), "X:X::X:X/M") == 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Common descriptions. */
 | 
				
			||||||
 | 
					#define SHOW_STR "Show running system information\n"
 | 
				
			||||||
 | 
					#define IP_STR "IP information\n"
 | 
				
			||||||
 | 
					#define IPV6_STR "IPv6 information\n"
 | 
				
			||||||
 | 
					#define NO_STR "Negate a command or set its defaults\n"
 | 
				
			||||||
 | 
					#define CLEAR_STR "Reset functions\n"
 | 
				
			||||||
 | 
					#define RIP_STR "RIP information\n"
 | 
				
			||||||
 | 
					#define BGP_STR "BGP information\n"
 | 
				
			||||||
 | 
					#define OSPF_STR "OSPF information\n"
 | 
				
			||||||
 | 
					#define NEIGHBOR_STR "Specify neighbor router\n"
 | 
				
			||||||
 | 
					#define DEBUG_STR "Debugging functions (see also 'undebug')\n"
 | 
				
			||||||
 | 
					#define UNDEBUG_STR "Disable debugging functions (see also 'debug')\n"
 | 
				
			||||||
 | 
					#define ROUTER_STR "Enable a routing process\n"
 | 
				
			||||||
 | 
					#define AS_STR "AS number\n"
 | 
				
			||||||
 | 
					#define MBGP_STR "MBGP information\n"
 | 
				
			||||||
 | 
					#define MATCH_STR "Match values from routing table\n"
 | 
				
			||||||
 | 
					#define SET_STR "Set values in destination routing protocol\n"
 | 
				
			||||||
 | 
					#define OUT_STR "Filter outgoing routing updates\n"
 | 
				
			||||||
 | 
					#define IN_STR  "Filter incoming routing updates\n"
 | 
				
			||||||
 | 
					#define V4NOTATION_STR "specify by IPv4 address notation(e.g. 0.0.0.0)\n"
 | 
				
			||||||
 | 
					#define OSPF6_NUMBER_STR "Specify by number\n"
 | 
				
			||||||
 | 
					#define INTERFACE_STR "Interface infomation\n"
 | 
				
			||||||
 | 
					#define IFNAME_STR "Interface name(e.g. ep0)\n"
 | 
				
			||||||
 | 
					#define IP6_STR "IPv6 Information\n"
 | 
				
			||||||
 | 
					#define OSPF6_STR "Open Shortest Path First (OSPF) for IPv6\n"
 | 
				
			||||||
 | 
					#define OSPF6_ROUTER_STR "Enable a routing process\n"
 | 
				
			||||||
 | 
					#define OSPF6_INSTANCE_STR "<1-65535> Instance ID\n"
 | 
				
			||||||
 | 
					#define SECONDS_STR "<1-65535> Seconds\n"
 | 
				
			||||||
 | 
					#define ROUTE_STR "Routing Table\n"
 | 
				
			||||||
 | 
					#define PREFIX_LIST_STR "Build a prefix list\n"
 | 
				
			||||||
 | 
					#define OSPF6_DUMP_TYPE_LIST \
 | 
				
			||||||
 | 
					"(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
 | 
				
			||||||
 | 
					#define ISIS_STR "IS-IS information\n"
 | 
				
			||||||
 | 
					#define AREA_TAG_STR "[area tag]\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CONF_BACKUP_EXT ".sav"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* IPv4 only machine should not accept IPv6 address for peer's IP
 | 
				
			||||||
 | 
					   address.  So we replace VTY command string like below. */
 | 
				
			||||||
 | 
					#ifdef HAVE_IPV6
 | 
				
			||||||
 | 
					#define NEIGHBOR_CMD       "neighbor (A.B.C.D|X:X::X:X) "
 | 
				
			||||||
 | 
					#define NO_NEIGHBOR_CMD    "no neighbor (A.B.C.D|X:X::X:X) "
 | 
				
			||||||
 | 
					#define NEIGHBOR_ADDR_STR  "Neighbor address\nIPv6 address\n"
 | 
				
			||||||
 | 
					#define NEIGHBOR_CMD2      "neighbor (A.B.C.D|X:X::X:X|WORD) "
 | 
				
			||||||
 | 
					#define NO_NEIGHBOR_CMD2   "no neighbor (A.B.C.D|X:X::X:X|WORD) "
 | 
				
			||||||
 | 
					#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor IPv6 address\nNeighbor tag\n"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define NEIGHBOR_CMD       "neighbor A.B.C.D "
 | 
				
			||||||
 | 
					#define NO_NEIGHBOR_CMD    "no neighbor A.B.C.D "
 | 
				
			||||||
 | 
					#define NEIGHBOR_ADDR_STR  "Neighbor address\n"
 | 
				
			||||||
 | 
					#define NEIGHBOR_CMD2      "neighbor (A.B.C.D|WORD) "
 | 
				
			||||||
 | 
					#define NO_NEIGHBOR_CMD2   "no neighbor (A.B.C.D|WORD) "
 | 
				
			||||||
 | 
					#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor tag\n"
 | 
				
			||||||
 | 
					#endif				/* HAVE_IPV6 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Prototypes. */
 | 
				
			||||||
 | 
					void install_node(struct cmd_node *, int (*)(struct vty *));
 | 
				
			||||||
 | 
					void install_default(enum node_type);
 | 
				
			||||||
 | 
					void install_element(enum node_type, struct cmd_element *);
 | 
				
			||||||
 | 
					void sort_node();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated
 | 
				
			||||||
 | 
					   string with a space between each element (allocated using
 | 
				
			||||||
 | 
					   XMALLOC(MTYPE_TMP)).  Returns NULL if shift >= argc. */
 | 
				
			||||||
 | 
					char *argv_concat(const char **argv, int argc, int shift);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vector cmd_make_strvec(const char *);
 | 
				
			||||||
 | 
					void cmd_free_strvec(vector);
 | 
				
			||||||
 | 
					vector cmd_describe_command();
 | 
				
			||||||
 | 
					char **cmd_complete_command();
 | 
				
			||||||
 | 
					const char *cmd_prompt(enum node_type);
 | 
				
			||||||
 | 
					int config_from_file(struct vty *, FILE *);
 | 
				
			||||||
 | 
					enum node_type node_parent(enum node_type);
 | 
				
			||||||
 | 
					int cmd_execute_command(vector, struct vty *, struct cmd_element **, int);
 | 
				
			||||||
 | 
					int cmd_execute_command_strict(vector, struct vty *, struct cmd_element **);
 | 
				
			||||||
 | 
					void config_replace_string(struct cmd_element *, char *, ...);
 | 
				
			||||||
 | 
					void cmd_init(int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Export typical functions. */
 | 
				
			||||||
 | 
					extern struct cmd_element config_end_cmd;
 | 
				
			||||||
 | 
					extern struct cmd_element config_exit_cmd;
 | 
				
			||||||
 | 
					extern struct cmd_element config_quit_cmd;
 | 
				
			||||||
 | 
					extern struct cmd_element config_help_cmd;
 | 
				
			||||||
 | 
					extern struct cmd_element config_list_cmd;
 | 
				
			||||||
 | 
					char *host_config_file();
 | 
				
			||||||
 | 
					void host_config_set(const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void print_version(const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif				/* _ZEBRA_COMMAND_H */
 | 
				
			||||||
							
								
								
									
										62
									
								
								openbsc/include/vty/vector.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								openbsc/include/vty/vector.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Generic vector interface header.
 | 
				
			||||||
 | 
					 * Copyright (C) 1997, 98 Kunihiro Ishiguro
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is part of GNU Zebra.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * GNU Zebra is free software; you can redistribute it and/or modify it
 | 
				
			||||||
 | 
					 * under the terms of the GNU General Public License as published by the
 | 
				
			||||||
 | 
					 * Free Software Foundation; either version 2, or (at your option) any
 | 
				
			||||||
 | 
					 * later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the Free
 | 
				
			||||||
 | 
					 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
				
			||||||
 | 
					 * 02111-1307, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _ZEBRA_VECTOR_H
 | 
				
			||||||
 | 
					#define _ZEBRA_VECTOR_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* struct for vector */
 | 
				
			||||||
 | 
					struct _vector {
 | 
				
			||||||
 | 
						unsigned int active;	/* number of active slots */
 | 
				
			||||||
 | 
						unsigned int alloced;	/* number of allocated slot */
 | 
				
			||||||
 | 
						void **index;		/* index to data */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct _vector *vector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VECTOR_MIN_SIZE 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* (Sometimes) usefull macros.  This macro convert index expression to
 | 
				
			||||||
 | 
					 array expression. */
 | 
				
			||||||
 | 
					/* Reference slot at given index, caller must ensure slot is active */
 | 
				
			||||||
 | 
					#define vector_slot(V,I)  ((V)->index[(I)])
 | 
				
			||||||
 | 
					/* Number of active slots.
 | 
				
			||||||
 | 
					 * Note that this differs from vector_count() as it the count returned
 | 
				
			||||||
 | 
					 * will include any empty slots
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define vector_active(V) ((V)->active)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Prototypes. */
 | 
				
			||||||
 | 
					vector vector_init(unsigned int size);
 | 
				
			||||||
 | 
					void vector_ensure(vector v, unsigned int num);
 | 
				
			||||||
 | 
					int vector_empty_slot(vector v);
 | 
				
			||||||
 | 
					int vector_set(vector v, void *val);
 | 
				
			||||||
 | 
					int vector_set_index(vector v, unsigned int i, void *val);
 | 
				
			||||||
 | 
					void vector_unset(vector v, unsigned int i);
 | 
				
			||||||
 | 
					unsigned int vector_count(vector v);
 | 
				
			||||||
 | 
					void vector_only_wrapper_free(vector v);
 | 
				
			||||||
 | 
					void vector_only_index_free(void *index);
 | 
				
			||||||
 | 
					void vector_free(vector v);
 | 
				
			||||||
 | 
					vector vector_copy(vector v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *vector_lookup(vector, unsigned int);
 | 
				
			||||||
 | 
					void *vector_lookup_ensure(vector, unsigned int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif				/* _ZEBRA_VECTOR_H */
 | 
				
			||||||
							
								
								
									
										151
									
								
								openbsc/include/vty/vty.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								openbsc/include/vty/vty.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
				
			|||||||
 | 
					#ifndef _VTY_H
 | 
				
			||||||
 | 
					#define _VTY_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GCC have printf type attribute check.  */
 | 
				
			||||||
 | 
					#ifdef __GNUC__
 | 
				
			||||||
 | 
					#define VTY_PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define VTY_PRINTF_ATTRIBUTE(a,b)
 | 
				
			||||||
 | 
					#endif				/* __GNUC__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Does the I/O error indicate that the operation should be retried later? */
 | 
				
			||||||
 | 
					#define ERRNO_IO_RETRY(EN) \
 | 
				
			||||||
 | 
						(((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Vty read buffer size. */
 | 
				
			||||||
 | 
					#define VTY_READ_BUFSIZ 512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VTY_BUFSIZ 512
 | 
				
			||||||
 | 
					#define VTY_MAXHIST 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Vty events */
 | 
				
			||||||
 | 
					enum event {
 | 
				
			||||||
 | 
						VTY_SERV,
 | 
				
			||||||
 | 
						VTY_READ,
 | 
				
			||||||
 | 
						VTY_WRITE,
 | 
				
			||||||
 | 
						VTY_CLOSED,
 | 
				
			||||||
 | 
						VTY_TIMEOUT_RESET,
 | 
				
			||||||
 | 
					#ifdef VTYSH
 | 
				
			||||||
 | 
						VTYSH_SERV,
 | 
				
			||||||
 | 
						VTYSH_READ,
 | 
				
			||||||
 | 
						VTYSH_WRITE
 | 
				
			||||||
 | 
					#endif				/* VTYSH */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct vty {
 | 
				
			||||||
 | 
						FILE *file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* private data, specified by creator */
 | 
				
			||||||
 | 
						void *priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* File descripter of this vty. */
 | 
				
			||||||
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Is this vty connect to file or not */
 | 
				
			||||||
 | 
						enum { VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV } type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Node status of this vty */
 | 
				
			||||||
 | 
						int node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Failure count */
 | 
				
			||||||
 | 
						int fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Output buffer. */
 | 
				
			||||||
 | 
						struct buffer *obuf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Command input buffer */
 | 
				
			||||||
 | 
						char *buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Command cursor point */
 | 
				
			||||||
 | 
						int cp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Command length */
 | 
				
			||||||
 | 
						int length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Command max length. */
 | 
				
			||||||
 | 
						int max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Histry of command */
 | 
				
			||||||
 | 
						char *hist[VTY_MAXHIST];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* History lookup current point */
 | 
				
			||||||
 | 
						int hp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* History insert end point */
 | 
				
			||||||
 | 
						int hindex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* For current referencing point of interface, route-map,
 | 
				
			||||||
 | 
						   access-list etc... */
 | 
				
			||||||
 | 
						void *index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* For multiple level index treatment such as key chain and key. */
 | 
				
			||||||
 | 
						void *index_sub;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* For escape character. */
 | 
				
			||||||
 | 
						unsigned char escape;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Current vty status. */
 | 
				
			||||||
 | 
						enum { VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE } status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* IAC handling: was the last character received the IAC
 | 
				
			||||||
 | 
						 * (interpret-as-command) escape character (and therefore the next
 | 
				
			||||||
 | 
						 * character will be the command code)?  Refer to Telnet RFC 854. */
 | 
				
			||||||
 | 
						unsigned char iac;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* IAC SB (option subnegotiation) handling */
 | 
				
			||||||
 | 
						unsigned char iac_sb_in_progress;
 | 
				
			||||||
 | 
						/* At the moment, we care only about the NAWS (window size) negotiation,
 | 
				
			||||||
 | 
						 * and that requires just a 5-character buffer (RFC 1073):
 | 
				
			||||||
 | 
						 * <NAWS char> <16-bit width> <16-bit height> */
 | 
				
			||||||
 | 
					#define TELNET_NAWS_SB_LEN 5
 | 
				
			||||||
 | 
						unsigned char sb_buf[TELNET_NAWS_SB_LEN];
 | 
				
			||||||
 | 
						/* How many subnegotiation characters have we received?  We just drop
 | 
				
			||||||
 | 
						 * those that do not fit in the buffer. */
 | 
				
			||||||
 | 
						size_t sb_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Window width/height. */
 | 
				
			||||||
 | 
						int width;
 | 
				
			||||||
 | 
						int height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Configure lines. */
 | 
				
			||||||
 | 
						int lines;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int monitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* In configure mode. */
 | 
				
			||||||
 | 
						int config;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Small macro to determine newline is newline only or linefeed needed. */
 | 
				
			||||||
 | 
					#define VTY_NEWLINE  ((vty->type == VTY_TERM) ? "\r\n" : "\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline char *vty_newline(struct vty *vty)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return VTY_NEWLINE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Prototypes. */
 | 
				
			||||||
 | 
					void vty_init (void);
 | 
				
			||||||
 | 
					int vty_read_config_file(const char *file_name);
 | 
				
			||||||
 | 
					void vty_init_vtysh (void);
 | 
				
			||||||
 | 
					void vty_reset (void);
 | 
				
			||||||
 | 
					struct vty *vty_new (void);
 | 
				
			||||||
 | 
					struct vty *vty_create (int vty_sock, void *priv);
 | 
				
			||||||
 | 
					int vty_out (struct vty *, const char *, ...) VTY_PRINTF_ATTRIBUTE(2, 3);
 | 
				
			||||||
 | 
					int vty_out_newline(struct vty *);
 | 
				
			||||||
 | 
					int vty_read(struct vty *vty);
 | 
				
			||||||
 | 
					//void vty_time_print (struct vty *, int);
 | 
				
			||||||
 | 
					void vty_close (struct vty *);
 | 
				
			||||||
 | 
					char *vty_get_cwd (void);
 | 
				
			||||||
 | 
					void vty_log (const char *level, const char *proto, const char *fmt, va_list);
 | 
				
			||||||
 | 
					int vty_config_lock (struct vty *);
 | 
				
			||||||
 | 
					int vty_config_unlock (struct vty *);
 | 
				
			||||||
 | 
					int vty_shell (struct vty *);
 | 
				
			||||||
 | 
					int vty_shell_serv (struct vty *);
 | 
				
			||||||
 | 
					void vty_hello (struct vty *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *tall_vty_ctx;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
prefix=@prefix@
 | 
					prefix=@prefix@
 | 
				
			||||||
exec_prefix=@exec_prefix@
 | 
					exec_prefix=@exec_prefix@
 | 
				
			||||||
libdir=@libdir@
 | 
					libdir=@libdir@
 | 
				
			||||||
includedir=@includedir@/
 | 
					includedir=@includedir@/openbsc-1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Name: OpenBSC
 | 
					Name: OpenBSC
 | 
				
			||||||
Description: OpenBSC base station controller
 | 
					Description: OpenBSC base station controller
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,48 +1,47 @@
 | 
				
			|||||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
 | 
					INCLUDES = $(all_includes) -I$(top_srcdir)/include
 | 
				
			||||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS)
 | 
					AM_CFLAGS=-Wall
 | 
				
			||||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# build current directory before building gprs
 | 
					sbin_PROGRAMS = bsc_hack bs11_config ipaccess-find ipaccess-config \
 | 
				
			||||||
SUBDIRS = . ipaccess gprs
 | 
					                isdnsync bsc_mgcp bsc_msc_ip bsc_nat
 | 
				
			||||||
 | 
					noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libsccp.a
 | 
				
			||||||
# Conditional modules
 | 
					noinst_HEADERS = vty/cardshell.h
 | 
				
			||||||
if BUILD_NAT
 | 
					 | 
				
			||||||
SUBDIRS += nat
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
if BUILD_BSC
 | 
					 | 
				
			||||||
SUBDIRS += bsc
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sbin_PROGRAMS = bsc_hack bs11_config isdnsync bsc_mgcp
 | 
					 | 
				
			||||||
noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libmgcp.a
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \
 | 
					libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \
 | 
				
			||||||
		chan_alloc.c debug.c socket.c abis_nm_vty.c \
 | 
							msgb.c select.c chan_alloc.c timer.c debug.c \
 | 
				
			||||||
		gsm_subscriber_base.c subchan_demux.c bsc_rll.c transaction.c \
 | 
							gsm_subscriber_base.c subchan_demux.c bsc_rll.c transaction.c \
 | 
				
			||||||
		trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c \
 | 
							trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c tlv_parser.c \
 | 
				
			||||||
		input/misdn.c input/ipaccess.c handover_logic.c \
 | 
							input/misdn.c input/ipaccess.c signal.c gsm_utils.c talloc.c \
 | 
				
			||||||
		talloc_ctx.c system_information.c rest_octets.c \
 | 
							talloc_ctx.c system_information.c bitvec.c rest_octets.c \
 | 
				
			||||||
		rtp_proxy.c bts_siemens_bs11.c bts_ipaccess_nanobts.c \
 | 
							rtp_proxy.c telnet_interface.c
 | 
				
			||||||
		bts_unknown.c bsc_version.c bsc_api.c bsc_vty.c meas_rep.c
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
libmsc_a_SOURCES = gsm_subscriber.c db.c \
 | 
					libmsc_a_SOURCES = gsm_subscriber.c db.c \
 | 
				
			||||||
		mncc.c gsm_04_08.c gsm_04_11.c transaction.c \
 | 
							mncc.c gsm_04_08.c gsm_04_11.c transaction.c \
 | 
				
			||||||
		token_auth.c rrlp.c gsm_04_80.c ussd.c silent_call.c \
 | 
							token_auth.c rrlp.c gsm_04_80.c ussd.c silent_call.c \
 | 
				
			||||||
		handover_decision.c auth.c \
 | 
					                handover_logic.c handover_decision.c meas_rep.c
 | 
				
			||||||
		osmo_msc.c
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
libvty_a_SOURCES = common_vty.c
 | 
					libvty_a_SOURCES = vty/buffer.c vty/command.c vty/vector.c vty/vty.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libmgcp_a_SOURCES = mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c
 | 
					libsccp_a_SOURCES = sccp/sccp.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bsc_hack_SOURCES = bsc_hack.c bsc_init.c bsc_vty.c vty_interface_layer3.c
 | 
					bsc_hack_SOURCES = bsc_hack.c bsc_init.c vty_interface.c vty_interface_layer3.c
 | 
				
			||||||
bsc_hack_LDADD = libmsc.a libbsc.a libvty.a libmsc.a \
 | 
					bsc_hack_LDADD = libmsc.a libbsc.a libmsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
 | 
				
			||||||
		-ldl -ldbi $(LIBCRYPT) $(LIBOSMOVTY_LIBS)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c debug.c \
 | 
					bsc_msc_ip_SOURCES = bssap.c bsc_msc_ip.c bsc_init.c vty_interface.c vty_interface_bsc.c \
 | 
				
			||||||
		      rs232.c bts_siemens_bs11.c
 | 
							bsc_msc.c
 | 
				
			||||||
 | 
					bsc_msc_ip_LDADD = libbsc.a libvty.a libsccp.a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c msgb.c debug.c \
 | 
				
			||||||
 | 
							      select.c timer.c rs232.c tlv_parser.c signal.c talloc.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ipaccess_find_SOURCES = ipaccess-find.c select.c timer.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ipaccess_config_SOURCES = ipaccess-config.c
 | 
				
			||||||
 | 
					ipaccess_config_LDADD = libbsc.a libmsc.a libbsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
isdnsync_SOURCES = isdnsync.c
 | 
					isdnsync_SOURCES = isdnsync.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bsc_mgcp_SOURCES = mgcp/mgcp_main.c debug.c
 | 
					bsc_mgcp_SOURCES = bsc_mgcp.c msgb.c talloc.c debug.c select.c timer.c telnet_interface.c
 | 
				
			||||||
bsc_mgcp_LDADD = libvty.a libmgcp.a $(LIBOSMOVTY_LIBS)
 | 
					bsc_mgcp_LDADD = libvty.a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bsc_nat_SOURCES = nat/bsc_nat.c nat/bsc_filter.c bsc_msc.c
 | 
				
			||||||
 | 
					bsc_nat_LDADD = libbsc.a libsccp.a
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,198 +0,0 @@
 | 
				
			|||||||
/* VTY interface for A-bis OML (Netowrk Management) */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * All Rights Reserved
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License along
 | 
					 | 
				
			||||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#include <errno.h>
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					 | 
				
			||||||
#include <osmocore/tlv.h>
 | 
					 | 
				
			||||||
#include <osmocore/talloc.h>
 | 
					 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					 | 
				
			||||||
#include <openbsc/signal.h>
 | 
					 | 
				
			||||||
#include <openbsc/abis_nm.h>
 | 
					 | 
				
			||||||
#include <openbsc/vty.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocom/vty/vty.h>
 | 
					 | 
				
			||||||
#include <osmocom/vty/command.h>
 | 
					 | 
				
			||||||
#include <osmocom/vty/logging.h>
 | 
					 | 
				
			||||||
#include <osmocom/vty/telnet_interface.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern struct gsm_network *bsc_gsmnet;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct cmd_node oml_node = {
 | 
					 | 
				
			||||||
	OML_NODE,
 | 
					 | 
				
			||||||
	"%s(oml)# ",
 | 
					 | 
				
			||||||
	1,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct oml_node_state {
 | 
					 | 
				
			||||||
	struct gsm_bts *bts;
 | 
					 | 
				
			||||||
	uint8_t obj_class;
 | 
					 | 
				
			||||||
	uint8_t obj_inst[3];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int dummy_config_write(struct vty *v)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return CMD_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* FIXME: auto-generate those strings from the value_string lists */
 | 
					 | 
				
			||||||
#define NM_OBJCLASS_VTY "(site-manager|bts|radio-carrier|baseband-transceiver|channel|adjc|handover|power-contorl|btse|rack|test|envabtse|bport|gprs-nse|gprs-cell|gprs-nsvc|siemenshw)"
 | 
					 | 
				
			||||||
#define NM_OBJCLASS_VTY_HELP "FIXME"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DEFUN(oml_class_inst, oml_class_inst_cmd,
 | 
					 | 
				
			||||||
	"bts <0-255> oml class " NM_OBJCLASS_VTY
 | 
					 | 
				
			||||||
					" instance <0-255> <0-255> <0-255>",
 | 
					 | 
				
			||||||
	"BTS related commands\n" "BTS Number\n"
 | 
					 | 
				
			||||||
	"Manipulate the OML managed objects\n"
 | 
					 | 
				
			||||||
	"Object Class\n" 	NM_OBJCLASS_VTY_HELP
 | 
					 | 
				
			||||||
	"Object Instance\n" "BTS Number\n" "TRX Number\n" "TS Number\n")
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gsm_bts *bts;
 | 
					 | 
				
			||||||
	struct oml_node_state *oms;
 | 
					 | 
				
			||||||
	int bts_nr = atoi(argv[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bts = gsm_bts_num(bsc_gsmnet, bts_nr);
 | 
					 | 
				
			||||||
	if (!bts) {
 | 
					 | 
				
			||||||
		vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
 | 
					 | 
				
			||||||
		return CMD_WARNING;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	oms = talloc_zero(tall_bsc_ctx, struct oml_node_state);
 | 
					 | 
				
			||||||
	if (!oms)
 | 
					 | 
				
			||||||
		return CMD_WARNING;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	oms->bts = bts;
 | 
					 | 
				
			||||||
	oms->obj_class = get_string_value(abis_nm_obj_class_names, argv[1]);
 | 
					 | 
				
			||||||
	oms->obj_inst[0] = atoi(argv[2]);
 | 
					 | 
				
			||||||
	oms->obj_inst[1] = atoi(argv[3]);
 | 
					 | 
				
			||||||
	oms->obj_inst[2] = atoi(argv[4]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	vty->index = oms;
 | 
					 | 
				
			||||||
	vty->node = OML_NODE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return CMD_SUCCESS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DEFUN(oml_classnum_inst, oml_classnum_inst_cmd,
 | 
					 | 
				
			||||||
	"bts <0-255> oml class <0-255> instance <0-255> <0-255> <0-255>",
 | 
					 | 
				
			||||||
	"BTS related commands\n" "BTS Number\n"
 | 
					 | 
				
			||||||
	"Manipulate the OML managed objects\n"
 | 
					 | 
				
			||||||
	"Object Class\n" "Object Class\n"
 | 
					 | 
				
			||||||
	"Object Instance\n" "BTS Number\n" "TRX Number\n" "TS Number\n")
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gsm_bts *bts;
 | 
					 | 
				
			||||||
	struct oml_node_state *oms;
 | 
					 | 
				
			||||||
	int bts_nr = atoi(argv[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bts = gsm_bts_num(bsc_gsmnet, bts_nr);
 | 
					 | 
				
			||||||
	if (!bts) {
 | 
					 | 
				
			||||||
		vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
 | 
					 | 
				
			||||||
		return CMD_WARNING;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	oms = talloc_zero(tall_bsc_ctx, struct oml_node_state);
 | 
					 | 
				
			||||||
	if (!oms)
 | 
					 | 
				
			||||||
		return CMD_WARNING;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	oms->bts = bts;
 | 
					 | 
				
			||||||
	oms->obj_class = atoi(argv[1]);
 | 
					 | 
				
			||||||
	oms->obj_inst[0] = atoi(argv[2]);
 | 
					 | 
				
			||||||
	oms->obj_inst[1] = atoi(argv[3]);
 | 
					 | 
				
			||||||
	oms->obj_inst[2] = atoi(argv[4]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	vty->index = oms;
 | 
					 | 
				
			||||||
	vty->node = OML_NODE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return CMD_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DEFUN(oml_attrib_get, oml_attrib_get_cmd,
 | 
					 | 
				
			||||||
	"attribute get <0-255>",
 | 
					 | 
				
			||||||
	"OML Attribute Actions\n" "Get a single OML Attribute\n"
 | 
					 | 
				
			||||||
	"OML Attribute Number\n")
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct oml_node_state *oms = vty->index;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* FIXME */
 | 
					 | 
				
			||||||
	return CMD_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DEFUN(oml_attrib_set, oml_attrib_set_cmd,
 | 
					 | 
				
			||||||
	"attribute set <0-255> .HEX",
 | 
					 | 
				
			||||||
	"OML Attribute Actions\n" "Set a single OML Attribute\n"
 | 
					 | 
				
			||||||
	"OML Attribute Number\n")
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct oml_node_state *oms = vty->index;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* FIXME */
 | 
					 | 
				
			||||||
	return CMD_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DEFUN(oml_chg_adm_state, oml_chg_adm_state_cmd,
 | 
					 | 
				
			||||||
	"change-adm-state (locked|unlocked|shutdown|null)",
 | 
					 | 
				
			||||||
	"Change the Administrative State\n"
 | 
					 | 
				
			||||||
	"Locked\n" "Unlocked\n" "Shutdown\n" "NULL\n")
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct oml_node_state *oms = vty->index;
 | 
					 | 
				
			||||||
	enum abis_nm_adm_state state;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	state = get_string_value(abis_nm_adm_state_names, argv[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	abis_nm_chg_adm_state(oms->bts, oms->obj_class, oms->obj_inst[0],
 | 
					 | 
				
			||||||
			      oms->obj_inst[1], oms->obj_inst[2], state);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return CMD_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DEFUN(oml_opstart, oml_opstart_cmd,
 | 
					 | 
				
			||||||
	"opstart", "Send an OPSTART message to the object")
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct oml_node_state *oms = vty->index;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	abis_nm_opstart(oms->bts, oms->obj_class, oms->obj_inst[0],
 | 
					 | 
				
			||||||
			oms->obj_inst[1], oms->obj_inst[2]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return CMD_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int abis_nm_vty_init(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	install_element(ENABLE_NODE, &oml_class_inst_cmd);
 | 
					 | 
				
			||||||
	install_element(ENABLE_NODE, &oml_classnum_inst_cmd);
 | 
					 | 
				
			||||||
	install_node(&oml_node, dummy_config_write);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	install_default(OML_NODE);
 | 
					 | 
				
			||||||
	install_element(OML_NODE, &ournode_exit_cmd);
 | 
					 | 
				
			||||||
	install_element(OML_NODE, &oml_attrib_get_cmd);
 | 
					 | 
				
			||||||
	install_element(OML_NODE, &oml_attrib_set_cmd);
 | 
					 | 
				
			||||||
	install_element(OML_NODE, &oml_chg_adm_state_cmd);
 | 
					 | 
				
			||||||
	install_element(OML_NODE, &oml_opstart_cmd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,128 +0,0 @@
 | 
				
			|||||||
/* Authentication related functions */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * (C) 2010 by Sylvain Munaut <tnt@246tNt.com>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * All Rights Reserved
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License along
 | 
					 | 
				
			||||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <openbsc/db.h>
 | 
					 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/comp128.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
_use_xor(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int i, l = ainfo->a3a8_ki_len;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((l > A38_XOR_MAX_KEY_LEN) || (l < A38_XOR_MIN_KEY_LEN)) {
 | 
					 | 
				
			||||||
		DEBUGP(DMM, "Invalid XOR key (len=%d) %s",
 | 
					 | 
				
			||||||
			ainfo->a3a8_ki_len,
 | 
					 | 
				
			||||||
			hexdump(ainfo->a3a8_ki, ainfo->a3a8_ki_len));
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i=0; i<4; i++)
 | 
					 | 
				
			||||||
		atuple->sres[i] = atuple->rand[i] ^ ainfo->a3a8_ki[i];
 | 
					 | 
				
			||||||
	for (i=8; i<12; i++)
 | 
					 | 
				
			||||||
		atuple->kc[i-4] = atuple->rand[i] ^ ainfo->a3a8_ki[i];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
_use_comp128_v1(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (ainfo->a3a8_ki_len != A38_COMP128_KEY_LEN) {
 | 
					 | 
				
			||||||
		DEBUGP(DMM, "Invalid COMP128v1 key (len=%d) %s",
 | 
					 | 
				
			||||||
			ainfo->a3a8_ki_len,
 | 
					 | 
				
			||||||
			hexdump(ainfo->a3a8_ki, ainfo->a3a8_ki_len));
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	comp128(ainfo->a3a8_ki, atuple->rand, atuple->sres, atuple->kc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Return values 
 | 
					 | 
				
			||||||
 *  -1 -> Internal error
 | 
					 | 
				
			||||||
 *   0 -> Not available
 | 
					 | 
				
			||||||
 *   1 -> Tuple returned, need to do auth, then enable cipher
 | 
					 | 
				
			||||||
 *   2 -> Tuple returned, need to enable cipher
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple,
 | 
					 | 
				
			||||||
                              struct gsm_subscriber *subscr, int key_seq)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gsm_auth_info ainfo;
 | 
					 | 
				
			||||||
	int i, rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Get subscriber info (if any) */
 | 
					 | 
				
			||||||
	rc = db_get_authinfo_for_subscr(&ainfo, subscr);
 | 
					 | 
				
			||||||
	if (rc < 0) {
 | 
					 | 
				
			||||||
		DEBUGP(DMM, "No retrievable Ki for subscriber, skipping auth");
 | 
					 | 
				
			||||||
		return rc == -ENOENT ? 0 : -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* If possible, re-use the last tuple and skip auth */
 | 
					 | 
				
			||||||
	rc = db_get_lastauthtuple_for_subscr(atuple, subscr);
 | 
					 | 
				
			||||||
	if ((rc == 0) &&
 | 
					 | 
				
			||||||
	    (atuple->key_seq != GSM_KEY_SEQ_INVAL) &&
 | 
					 | 
				
			||||||
	    (atuple->use_count < 3))
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		atuple->use_count++;
 | 
					 | 
				
			||||||
		db_sync_lastauthtuple_for_subscr(atuple, subscr);
 | 
					 | 
				
			||||||
		return 2;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Generate a new one */
 | 
					 | 
				
			||||||
	atuple->use_count = 1;
 | 
					 | 
				
			||||||
	atuple->key_seq = (atuple->key_seq + 1) % 7;
 | 
					 | 
				
			||||||
        for (i=0; i<sizeof(atuple->rand); i++)
 | 
					 | 
				
			||||||
                atuple->rand[i] = random() & 0xff;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (ainfo.auth_algo) {
 | 
					 | 
				
			||||||
		case AUTH_ALGO_NONE:
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case AUTH_ALGO_XOR:
 | 
					 | 
				
			||||||
			if (_use_xor(&ainfo, atuple))
 | 
					 | 
				
			||||||
				return 0;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case AUTH_ALGO_COMP128v1:
 | 
					 | 
				
			||||||
			if (_use_comp128_v1(&ainfo, atuple))
 | 
					 | 
				
			||||||
				return 0;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			DEBUGP(DMM, "Unsupported auth type algo_id=%d\n",
 | 
					 | 
				
			||||||
				ainfo.auth_algo);
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        db_sync_lastauthtuple_for_subscr(atuple, subscr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										170
									
								
								openbsc/src/bitvec.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								openbsc/src/bitvec.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
				
			|||||||
 | 
					/* bit vector utility routines */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openbsc/bitvec.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BITNUM_FROM_COMP(byte, bit)	((byte*8)+bit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned int bytenum_from_bitnum(unsigned int bitnum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int bytenum = bitnum / 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return bytenum;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* convert ZERO/ONE/L/H to a bitmask at given pos in a byte */
 | 
				
			||||||
 | 
					static u_int8_t bitval2mask(enum bit_value bit, u_int8_t bitnum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int bitval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (bit) {
 | 
				
			||||||
 | 
						case ZERO:
 | 
				
			||||||
 | 
							bitval = (0 << bitnum);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ONE:
 | 
				
			||||||
 | 
							bitval = (1 << bitnum);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case L:
 | 
				
			||||||
 | 
							bitval = ((0x2b ^ (0 << bitnum)) & (1 << bitnum));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case H:
 | 
				
			||||||
 | 
							bitval = ((0x2b ^ (1 << bitnum)) & (1 << bitnum));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return bitval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* check if the bit is 0 or 1 for a given position inside a bitvec */
 | 
				
			||||||
 | 
					enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int bytenum = bytenum_from_bitnum(bitnr);
 | 
				
			||||||
 | 
						unsigned int bitnum = 7 - (bitnr % 8);
 | 
				
			||||||
 | 
						u_int8_t bitval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bytenum >= bv->data_len)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bitval = bitval2mask(ONE, bitnum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bv->data[bytenum] & bitval)
 | 
				
			||||||
 | 
							return ONE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ZERO;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* get the Nth set bit inside the bit vector */
 | 
				
			||||||
 | 
					unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int i, k = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < bv->data_len*8; i++) {
 | 
				
			||||||
 | 
							if (bitvec_get_bit_pos(bv, i) == ONE) {
 | 
				
			||||||
 | 
								k++;
 | 
				
			||||||
 | 
								if (k == n)
 | 
				
			||||||
 | 
									return i;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* set the bit at a given position inside a bitvec */
 | 
				
			||||||
 | 
					int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr,
 | 
				
			||||||
 | 
								enum bit_value bit)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int bytenum = bytenum_from_bitnum(bitnr);
 | 
				
			||||||
 | 
						unsigned int bitnum = 7 - (bitnr % 8);
 | 
				
			||||||
 | 
						u_int8_t bitval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bytenum >= bv->data_len)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* first clear the bit */
 | 
				
			||||||
 | 
						bitval = bitval2mask(ONE, bitnum);
 | 
				
			||||||
 | 
						bv->data[bytenum] &= ~bitval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* then set it to desired value */
 | 
				
			||||||
 | 
						bitval = bitval2mask(bit, bitnum);
 | 
				
			||||||
 | 
						bv->data[bytenum] |= bitval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* set the next bit inside a bitvec */
 | 
				
			||||||
 | 
					int bitvec_set_bit(struct bitvec *bv, enum bit_value bit)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = bitvec_set_bit_pos(bv, bv->cur_bit, bit);
 | 
				
			||||||
 | 
						if (!rc)
 | 
				
			||||||
 | 
							bv->cur_bit++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* set multiple bits (based on array of bitvals) at current pos */
 | 
				
			||||||
 | 
					int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i, rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < count; i++) {
 | 
				
			||||||
 | 
							rc = bitvec_set_bit(bv, bits[i]);
 | 
				
			||||||
 | 
							if (rc)
 | 
				
			||||||
 | 
								return rc;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* set multiple bits (based on numeric value) at current pos */
 | 
				
			||||||
 | 
					int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i, rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < num_bits; i++) {
 | 
				
			||||||
 | 
							int bit = 0;
 | 
				
			||||||
 | 
							if (ui & (1 << (num_bits - i - 1)))
 | 
				
			||||||
 | 
								bit = 1;
 | 
				
			||||||
 | 
							rc = bitvec_set_bit(bv, bit);
 | 
				
			||||||
 | 
							if (rc)
 | 
				
			||||||
 | 
								return rc;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* pad all remaining bits up to num_bits */
 | 
				
			||||||
 | 
					int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = bv->cur_bit; i <= up_to_bit; i++)
 | 
				
			||||||
 | 
							bitvec_set_bit(bv, L);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
 | 
					/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This software is based on ideas (but not code) of BS11Config
 | 
					 * This software is based on ideas (but not code) of BS11Config 
 | 
				
			||||||
 * (C) 2009 by Dieter Spaar <spaar@mirider.augusta.de>
 | 
					 * (C) 2009 by Dieter Spaar <spaar@mirider.augusta.de>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
@@ -36,10 +36,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					#include <openbsc/gsm_data.h>
 | 
				
			||||||
#include <openbsc/abis_nm.h>
 | 
					#include <openbsc/abis_nm.h>
 | 
				
			||||||
#include <osmocore/msgb.h>
 | 
					#include <openbsc/msgb.h>
 | 
				
			||||||
#include <osmocore/tlv.h>
 | 
					#include <openbsc/tlv.h>
 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					#include <openbsc/debug.h>
 | 
				
			||||||
#include <osmocore/select.h>
 | 
					#include <openbsc/select.h>
 | 
				
			||||||
#include <openbsc/rs232.h>
 | 
					#include <openbsc/rs232.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* state of our bs11_config application */
 | 
					/* state of our bs11_config application */
 | 
				
			||||||
@@ -51,12 +51,12 @@ enum bs11cfg_state {
 | 
				
			|||||||
	STATE_QUERY,
 | 
						STATE_QUERY,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
static enum bs11cfg_state bs11cfg_state = STATE_NONE;
 | 
					static enum bs11cfg_state bs11cfg_state = STATE_NONE;
 | 
				
			||||||
static char *command, *value;
 | 
					static char *command;
 | 
				
			||||||
struct timer_list status_timer;
 | 
					struct timer_list status_timer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const u_int8_t obj_li_attr[] = {
 | 
					static const u_int8_t obj_li_attr[] = { 
 | 
				
			||||||
	NM_ATT_BS11_BIT_ERR_THESH, 0x09, 0x00,
 | 
						NM_ATT_BS11_BIT_ERR_THESH, 0x09, 0x00,
 | 
				
			||||||
	NM_ATT_BS11_L1_PROT_TYPE, 0x00,
 | 
						NM_ATT_BS11_L1_PROT_TYPE, 0x00, 
 | 
				
			||||||
	NM_ATT_BS11_LINE_CFG, 0x00,
 | 
						NM_ATT_BS11_LINE_CFG, 0x00,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
static const u_int8_t obj_bbsig0_attr[] = {
 | 
					static const u_int8_t obj_bbsig0_attr[] = {
 | 
				
			||||||
@@ -71,13 +71,6 @@ static const char *trx1_password = "1111111111";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static const u_int8_t too_fast[] = { 0x12, 0x80, 0x00, 0x00, 0x02, 0x02 };
 | 
					static const u_int8_t too_fast[] = { 0x12, 0x80, 0x00, 0x00, 0x02, 0x02 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct log_target *stderr_target;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* dummy function to keep gsm_data.c happy */
 | 
					 | 
				
			||||||
struct counter *counter_alloc(const char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int handle_serial_msg(struct msgb *rx_msg);
 | 
					int handle_serial_msg(struct msgb *rx_msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -481,7 +474,7 @@ static int handle_state_resp(enum abis_bs11_phase state)
 | 
				
			|||||||
		 * argument, so our swload_cbfn can distinguish
 | 
							 * argument, so our swload_cbfn can distinguish
 | 
				
			||||||
		 * a safety load from a regular software */
 | 
							 * a safety load from a regular software */
 | 
				
			||||||
		if (file_is_readable(fname_safety))
 | 
							if (file_is_readable(fname_safety))
 | 
				
			||||||
			rc = abis_nm_software_load(g_bts, 0xff, fname_safety,
 | 
								rc = abis_nm_software_load(g_bts, fname_safety,
 | 
				
			||||||
						   win_size, param_forced,
 | 
											   win_size, param_forced,
 | 
				
			||||||
						   swload_cbfn, g_bts);
 | 
											   swload_cbfn, g_bts);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
@@ -540,21 +533,6 @@ static int handle_state_resp(enum abis_bs11_phase state)
 | 
				
			|||||||
				sleep(1);
 | 
									sleep(1);
 | 
				
			||||||
				abis_nm_bs11_factory_logon(g_bts, 0);
 | 
									abis_nm_bs11_factory_logon(g_bts, 0);
 | 
				
			||||||
				command = NULL;
 | 
									command = NULL;
 | 
				
			||||||
			} else if (!strcmp(command, "pll-setvalue")) {
 | 
					 | 
				
			||||||
				abis_nm_bs11_set_pll(g_bts, atoi(value));
 | 
					 | 
				
			||||||
				sleep(1);
 | 
					 | 
				
			||||||
				abis_nm_bs11_factory_logon(g_bts, 0);
 | 
					 | 
				
			||||||
				command = NULL;
 | 
					 | 
				
			||||||
			} else if (!strcmp(command, "pll-workvalue")) {
 | 
					 | 
				
			||||||
				/* To set the work value we need to login as FIELD */
 | 
					 | 
				
			||||||
				abis_nm_bs11_factory_logon(g_bts, 0);
 | 
					 | 
				
			||||||
				sleep(1);
 | 
					 | 
				
			||||||
				abis_nm_bs11_infield_logon(g_bts, 1);
 | 
					 | 
				
			||||||
				sleep(1);
 | 
					 | 
				
			||||||
				abis_nm_bs11_set_pll(g_bts, atoi(value));
 | 
					 | 
				
			||||||
				sleep(1);
 | 
					 | 
				
			||||||
				abis_nm_bs11_infield_logon(g_bts, 0);
 | 
					 | 
				
			||||||
				command = NULL;
 | 
					 | 
				
			||||||
			} else if (!strcmp(command, "oml-tei")) {
 | 
								} else if (!strcmp(command, "oml-tei")) {
 | 
				
			||||||
				abis_nm_bs11_conn_oml_tei(g_bts, 0, 1, 0xff, TEI_OML);
 | 
									abis_nm_bs11_conn_oml_tei(g_bts, 0, 1, 0xff, TEI_OML);
 | 
				
			||||||
				command = NULL;
 | 
									command = NULL;
 | 
				
			||||||
@@ -649,7 +627,7 @@ int handle_serial_msg(struct msgb *rx_msg)
 | 
				
			|||||||
		exit(0);
 | 
							exit(0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case NM_MT_BS11_GET_STATE_ACK:
 | 
						case NM_MT_BS11_GET_STATE_ACK:
 | 
				
			||||||
		rc = abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
 | 
							rc = abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
 | 
				
			||||||
		print_state(&tp);
 | 
							print_state(&tp);
 | 
				
			||||||
		if (TLVP_PRESENT(&tp, NM_ATT_BS11_BTS_STATE) &&
 | 
							if (TLVP_PRESENT(&tp, NM_ATT_BS11_BTS_STATE) &&
 | 
				
			||||||
		    TLVP_LEN(&tp, NM_ATT_BS11_BTS_STATE) >= 1)
 | 
							    TLVP_LEN(&tp, NM_ATT_BS11_BTS_STATE) >= 1)
 | 
				
			||||||
@@ -657,7 +635,7 @@ int handle_serial_msg(struct msgb *rx_msg)
 | 
				
			|||||||
		break;
 | 
							break;
 | 
				
			||||||
	case NM_MT_GET_ATTR_RESP:
 | 
						case NM_MT_GET_ATTR_RESP:
 | 
				
			||||||
		printf("\n%sATTRIBUTES:\n", obj_name(foh));
 | 
							printf("\n%sATTRIBUTES:\n", obj_name(foh));
 | 
				
			||||||
		abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
 | 
							abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
 | 
				
			||||||
		rc = print_attr(&tp);
 | 
							rc = print_attr(&tp);
 | 
				
			||||||
		//hexdump(foh->data, oh->length-sizeof(*foh));
 | 
							//hexdump(foh->data, oh->length-sizeof(*foh));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
@@ -697,8 +675,7 @@ int handle_serial_msg(struct msgb *rx_msg)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
 | 
					int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
 | 
				
			||||||
		   struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,
 | 
							   struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
 | 
				
			||||||
		   struct abis_om_obj_inst *obj_ins)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -722,27 +699,25 @@ static void print_help(void)
 | 
				
			|||||||
	printf("\t-p --port </dev/ttyXXX>\t\tSpecify serial port\n");
 | 
						printf("\t-p --port </dev/ttyXXX>\t\tSpecify serial port\n");
 | 
				
			||||||
	printf("\t-s --software <file>\t\tSpecify Software file\n");
 | 
						printf("\t-s --software <file>\t\tSpecify Software file\n");
 | 
				
			||||||
	printf("\t-S --safety <file>\t\tSpecify Safety Load file\n");
 | 
						printf("\t-S --safety <file>\t\tSpecify Safety Load file\n");
 | 
				
			||||||
	printf("\t-d --delay <ms>\t\t\tSpecify delay in milliseconds\n");
 | 
						printf("\t-d --delay <ms>\t\tSpecify delay in milliseconds\n");
 | 
				
			||||||
	printf("\t-D --disconnect\t\t\tDisconnect BTS from BSC\n");
 | 
						printf("\t-D --disconnect\t\t\tDisconnect BTS from BSC\n");
 | 
				
			||||||
	printf("\t-w --win-size <num>\t\tSpecify Window Size\n");
 | 
						printf("\t-w --win-size <num>\t\tSpecify Window Size\n");
 | 
				
			||||||
	printf("\t-f --forced\t\t\tForce Software Load\n");
 | 
						printf("\t-f --forced\t\t\tForce Software Load\n");
 | 
				
			||||||
	printf("\nSupported commands:\n");
 | 
						printf("\nSupported commands:\n");
 | 
				
			||||||
	printf("\tquery\t\t\tQuery the BS-11 about serial number and configuration\n");
 | 
						printf("\tquery\t\tQuery the BS-11 about serial number and configuration\n");
 | 
				
			||||||
	printf("\tdisconnect\t\tDisconnect A-bis link (go into administrative state)\n");
 | 
						printf("\tdisconnect\tDisconnect A-bis link (go into administrative state)\n");
 | 
				
			||||||
	printf("\tresconnect\t\tReconnect A-bis link (go into normal state)\n");
 | 
						printf("\tresconnect\tReconnect A-bis link (go into normal state)\n");
 | 
				
			||||||
	printf("\trestart\t\t\tRestart the BTS\n");
 | 
						printf("\trestart\t\tRestart the BTS\n");
 | 
				
			||||||
	printf("\tsoftware\t\tDownload Software (only in administrative state)\n");
 | 
						printf("\tsoftware\tDownload Software (only in administrative state)\n");
 | 
				
			||||||
	printf("\tcreate-trx1\t\tCreate objects for TRX1 (Danger: Your BS-11 might overheat)\n");
 | 
						printf("\tcreate-trx1\tCreate objects for TRX1 (Danger: Your BS-11 might overheat)\n");
 | 
				
			||||||
	printf("\tdelete-trx1\t\tDelete objects for TRX1\n");
 | 
						printf("\tdelete-trx1\tDelete objects for TRX1\n");
 | 
				
			||||||
	printf("\tpll-e1-locked\t\tSet the PLL to be locked to E1 clock\n");
 | 
						printf("\tpll-e1-locked\tSet the PLL to be locked to E1 clock\n");
 | 
				
			||||||
	printf("\tpll-standalone\t\tSet the PLL to be in standalone mode\n");
 | 
						printf("\tpll-standalone\tSet the PLL to be in standalone mode\n");
 | 
				
			||||||
	printf("\tpll-setvalue <value>\tSet the PLL set value\n");
 | 
						printf("\toml-tei\tSet OML E1 TS and TEI\n");
 | 
				
			||||||
	printf("\tpll-workvalue <value>\tSet the PLL work value\n");
 | 
						printf("\tbport0-star\tSet BPORT0 line config to star\n");
 | 
				
			||||||
	printf("\toml-tei\t\t\tSet OML E1 TS and TEI\n");
 | 
					 | 
				
			||||||
	printf("\tbport0-star\t\tSet BPORT0 line config to star\n");
 | 
					 | 
				
			||||||
	printf("\tbport0-multiport\tSet BPORT0 line config to multiport\n");
 | 
						printf("\tbport0-multiport\tSet BPORT0 line config to multiport\n");
 | 
				
			||||||
	printf("\tcreate-bport1\t\tCreate BPORT1 object\n");
 | 
						printf("\tcreate-bport1\tCreate BPORT1 object\n");
 | 
				
			||||||
	printf("\tdelete-bport1\t\tDelete BPORT1 object\n");
 | 
						printf("\tdelete-bport1\tDelete BPORT1 object\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_options(int argc, char **argv)
 | 
					static void handle_options(int argc, char **argv)
 | 
				
			||||||
@@ -779,7 +754,7 @@ static void handle_options(int argc, char **argv)
 | 
				
			|||||||
			serial_port = optarg;
 | 
								serial_port = optarg;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'b':
 | 
							case 'b':
 | 
				
			||||||
			log_parse_category_mask(stderr_target, optarg);
 | 
								debug_parse_category_mask(optarg);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 's':
 | 
							case 's':
 | 
				
			||||||
			fname_software = optarg;
 | 
								fname_software = optarg;
 | 
				
			||||||
@@ -809,9 +784,6 @@ static void handle_options(int argc, char **argv)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if (optind < argc)
 | 
						if (optind < argc)
 | 
				
			||||||
		command = argv[optind];
 | 
							command = argv[optind];
 | 
				
			||||||
	        if (optind+1 < argc)
 | 
					 | 
				
			||||||
			value = argv[optind+1];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int num_sigint;
 | 
					static int num_sigint;
 | 
				
			||||||
@@ -830,18 +802,12 @@ static void signal_handler(int signal)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int bts_model_bs11_init(void);
 | 
					 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct gsm_network *gsmnet;
 | 
						struct gsm_network *gsmnet;
 | 
				
			||||||
	int rc;
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log_init(&log_info);
 | 
					 | 
				
			||||||
	stderr_target = log_target_create_stderr();
 | 
					 | 
				
			||||||
	log_add_target(stderr_target);
 | 
					 | 
				
			||||||
	log_set_all_filter(stderr_target, 1);
 | 
					 | 
				
			||||||
	handle_options(argc, argv);
 | 
						handle_options(argc, argv);
 | 
				
			||||||
	bts_model_bs11_init();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gsmnet = gsm_network_init(1, 1, NULL);
 | 
						gsmnet = gsm_network_init(1, 1, NULL);
 | 
				
			||||||
	if (!gsmnet) {
 | 
						if (!gsmnet) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
 | 
					 | 
				
			||||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOSCCP_CFLAGS)
 | 
					 | 
				
			||||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bin_PROGRAMS = osmo-bsc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_rf.c osmo_bsc_vty.c osmo_bsc_api.c \
 | 
					 | 
				
			||||||
		   $(top_srcdir)/src/debug.c $(top_srcdir)/src/bsc_msc.c \
 | 
					 | 
				
			||||||
		   $(top_srcdir)/src/bsc_init.c
 | 
					 | 
				
			||||||
osmo_bsc_LDADD = $(top_builddir)/src/libvty.a \
 | 
					 | 
				
			||||||
		 $(top_builddir)/src/libmgcp.a $(top_builddir)/src/libbsc.a \
 | 
					 | 
				
			||||||
		 $(LIBOSMOSCCP_LIBS)
 | 
					 | 
				
			||||||
@@ -1,188 +0,0 @@
 | 
				
			|||||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
 | 
					 | 
				
			||||||
 * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 | 
				
			||||||
 * (C) 2009-2010 by On-Waves
 | 
					 | 
				
			||||||
 * All Rights Reserved
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License along
 | 
					 | 
				
			||||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					 | 
				
			||||||
#include <openbsc/osmo_bsc_rf.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocom/vty/command.h>
 | 
					 | 
				
			||||||
#include <osmocore/talloc.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocom/sccp/sccp.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define _GNU_SOURCE
 | 
					 | 
				
			||||||
#include <getopt.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "bscconfig.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct log_target *stderr_target;
 | 
					 | 
				
			||||||
struct gsm_network *bsc_gsmnet = 0;
 | 
					 | 
				
			||||||
static const char *config_file = "openbsc.cfg";
 | 
					 | 
				
			||||||
static const char *rf_ctl = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern void bsc_vty_init(void);
 | 
					 | 
				
			||||||
extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, int, void *), const char *cfg_file);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void print_usage()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	printf("Usage: bsc_msc_ip\n");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void print_help()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	printf("  Some useful help...\n");
 | 
					 | 
				
			||||||
	printf("  -h --help this text\n");
 | 
					 | 
				
			||||||
	printf("  -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
 | 
					 | 
				
			||||||
	printf("  -s --disable-color\n");
 | 
					 | 
				
			||||||
	printf("  -T --timestamp. Print a timestamp in the debug output.\n");
 | 
					 | 
				
			||||||
	printf("  -c --config-file filename The config file to use.\n");
 | 
					 | 
				
			||||||
	printf("  -l --local=IP. The local address of the MGCP.\n");
 | 
					 | 
				
			||||||
	printf("  -e --log-level number. Set a global loglevel.\n");
 | 
					 | 
				
			||||||
	printf("  -r --rf-ctl NAME. A unix domain socket to listen for cmds.\n");
 | 
					 | 
				
			||||||
	printf("  -t --testmode. A special mode to provoke failures at the MSC.\n");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void handle_options(int argc, char** argv)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	while (1) {
 | 
					 | 
				
			||||||
		int option_index = 0, c;
 | 
					 | 
				
			||||||
		static struct option long_options[] = {
 | 
					 | 
				
			||||||
			{"help", 0, 0, 'h'},
 | 
					 | 
				
			||||||
			{"debug", 1, 0, 'd'},
 | 
					 | 
				
			||||||
			{"config-file", 1, 0, 'c'},
 | 
					 | 
				
			||||||
			{"disable-color", 0, 0, 's'},
 | 
					 | 
				
			||||||
			{"timestamp", 0, 0, 'T'},
 | 
					 | 
				
			||||||
			{"msc", 1, 0, 'm'},
 | 
					 | 
				
			||||||
			{"local", 1, 0, 'l'},
 | 
					 | 
				
			||||||
			{"log-level", 1, 0, 'e'},
 | 
					 | 
				
			||||||
			{"rf-ctl", 1, 0, 'r'},
 | 
					 | 
				
			||||||
			{"testmode", 0, 0, 't'},
 | 
					 | 
				
			||||||
			{0, 0, 0, 0}
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		c = getopt_long(argc, argv, "hd:sTc:e:r:t",
 | 
					 | 
				
			||||||
				long_options, &option_index);
 | 
					 | 
				
			||||||
		if (c == -1)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		switch (c) {
 | 
					 | 
				
			||||||
		case 'h':
 | 
					 | 
				
			||||||
			print_usage();
 | 
					 | 
				
			||||||
			print_help();
 | 
					 | 
				
			||||||
			exit(0);
 | 
					 | 
				
			||||||
		case 's':
 | 
					 | 
				
			||||||
			log_set_use_color(stderr_target, 0);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'd':
 | 
					 | 
				
			||||||
			log_parse_category_mask(stderr_target, optarg);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'c':
 | 
					 | 
				
			||||||
			config_file = strdup(optarg);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'T':
 | 
					 | 
				
			||||||
			log_set_print_timestamp(stderr_target, 1);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'P':
 | 
					 | 
				
			||||||
			ipacc_rtp_direct = 0;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'e':
 | 
					 | 
				
			||||||
			log_set_log_level(stderr_target, atoi(optarg));
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'r':
 | 
					 | 
				
			||||||
			rf_ctl = optarg;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			/* ignore */
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int bts_model_unknown_init(void);
 | 
					 | 
				
			||||||
extern int bts_model_bs11_init(void);
 | 
					 | 
				
			||||||
extern int bts_model_nanobts_init(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern enum node_type bsc_vty_go_parent(struct vty *vty);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct vty_app_info vty_info = {
 | 
					 | 
				
			||||||
	.name 		= "OpenBSC Osmo BSC",
 | 
					 | 
				
			||||||
	.version	= PACKAGE_VERSION,
 | 
					 | 
				
			||||||
	.go_parent_cb	= bsc_vty_go_parent,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, char **argv)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char *msc;
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	log_init(&log_info);
 | 
					 | 
				
			||||||
	tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
 | 
					 | 
				
			||||||
	stderr_target = log_target_create_stderr();
 | 
					 | 
				
			||||||
	log_add_target(stderr_target);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bts_model_unknown_init();
 | 
					 | 
				
			||||||
	bts_model_bs11_init();
 | 
					 | 
				
			||||||
	bts_model_nanobts_init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* enable filters */
 | 
					 | 
				
			||||||
	log_set_all_filter(stderr_target, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* This needs to precede handle_options() */
 | 
					 | 
				
			||||||
	vty_init(&vty_info);
 | 
					 | 
				
			||||||
	bsc_vty_init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* parse options */
 | 
					 | 
				
			||||||
	handle_options(argc, argv);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* seed the PRNG */
 | 
					 | 
				
			||||||
	srand(time(NULL));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* initialize SCCP */
 | 
					 | 
				
			||||||
	sccp_set_log_area(DSCCP);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rc = bsc_bootstrap_network(NULL, config_file);
 | 
					 | 
				
			||||||
	if (rc < 0) {
 | 
					 | 
				
			||||||
		fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
 | 
					 | 
				
			||||||
		exit(1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (rf_ctl) {
 | 
					 | 
				
			||||||
		struct osmo_bsc_rf *rf;
 | 
					 | 
				
			||||||
		rf = osmo_bsc_rf_create(rf_ctl, bsc_gsmnet);
 | 
					 | 
				
			||||||
		if (!rf) {
 | 
					 | 
				
			||||||
			fprintf(stderr, "Failed to create the RF service.\n");
 | 
					 | 
				
			||||||
			exit(1);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while (1) {
 | 
					 | 
				
			||||||
		bsc_select_main(0);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,264 +0,0 @@
 | 
				
			|||||||
/* RF Ctl handling socket */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
 | 
					 | 
				
			||||||
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 | 
				
			||||||
 * (C) 2010 by On-Waves
 | 
					 | 
				
			||||||
 * All Rights Reserved
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License along
 | 
					 | 
				
			||||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <openbsc/osmo_bsc_rf.h>
 | 
					 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					 | 
				
			||||||
#include <openbsc/signal.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/talloc.h>
 | 
					 | 
				
			||||||
#include <osmocore/protocol/gsm_12_21.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/socket.h>
 | 
					 | 
				
			||||||
#include <sys/un.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <errno.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RF_CMD_QUERY '?'
 | 
					 | 
				
			||||||
#define RF_CMD_OFF   '0'
 | 
					 | 
				
			||||||
#define RF_CMD_ON    '1'
 | 
					 | 
				
			||||||
#define RF_CMD_GRACE 'g'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int lock_each_trx(struct gsm_network *net, int lock)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gsm_bts *bts;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	llist_for_each_entry(bts, &net->bts_list, list) {
 | 
					 | 
				
			||||||
		struct gsm_bts_trx *trx;
 | 
					 | 
				
			||||||
		llist_for_each_entry(trx, &bts->trx_list, list) {
 | 
					 | 
				
			||||||
			gsm_trx_lock_rf(trx, lock);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Send a '1' when one TRX is online, otherwise send 0
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void handle_query(struct osmo_bsc_rf_conn *conn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct msgb *msg;
 | 
					 | 
				
			||||||
	struct gsm_bts *bts;
 | 
					 | 
				
			||||||
	char send = RF_CMD_OFF;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	llist_for_each_entry(bts, &conn->gsm_network->bts_list, list) {
 | 
					 | 
				
			||||||
		struct gsm_bts_trx *trx;
 | 
					 | 
				
			||||||
		llist_for_each_entry(trx, &bts->trx_list, list) {
 | 
					 | 
				
			||||||
			if (trx->nm_state.availability == NM_AVSTATE_OK &&
 | 
					 | 
				
			||||||
			    trx->nm_state.operational != NM_STATE_LOCKED) {
 | 
					 | 
				
			||||||
					send = RF_CMD_ON;
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msg = msgb_alloc(10, "RF Query");
 | 
					 | 
				
			||||||
	if (!msg) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Failed to allocate response msg.\n");
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msg->l2h = msgb_put(msg, 1);
 | 
					 | 
				
			||||||
	msg->l2h[0] = send;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (write_queue_enqueue(&conn->queue, msg) != 0) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Failed to enqueue the answer.\n");
 | 
					 | 
				
			||||||
		msgb_free(msg);
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void send_signal(struct osmo_bsc_rf_conn *conn, int val)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct rf_signal_data sig;
 | 
					 | 
				
			||||||
	sig.net = conn->gsm_network;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dispatch_signal(SS_RF, val, &sig);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int rf_read_cmd(struct bsc_fd *fd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct osmo_bsc_rf_conn *conn = fd->data;
 | 
					 | 
				
			||||||
	char buf[1];
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rc = read(fd->fd, buf, sizeof(buf));
 | 
					 | 
				
			||||||
	if (rc != sizeof(buf)) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Short read %d/%s\n", errno, strerror(errno));
 | 
					 | 
				
			||||||
		bsc_unregister_fd(fd);
 | 
					 | 
				
			||||||
		close(fd->fd);
 | 
					 | 
				
			||||||
		write_queue_clear(&conn->queue);
 | 
					 | 
				
			||||||
		talloc_free(conn);
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (buf[0]) {
 | 
					 | 
				
			||||||
	case RF_CMD_QUERY:
 | 
					 | 
				
			||||||
		handle_query(conn);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case RF_CMD_OFF:
 | 
					 | 
				
			||||||
		lock_each_trx(conn->gsm_network, 1);
 | 
					 | 
				
			||||||
		send_signal(conn, S_RF_OFF);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case RF_CMD_ON:
 | 
					 | 
				
			||||||
		lock_each_trx(conn->gsm_network, 0);
 | 
					 | 
				
			||||||
		send_signal(conn, S_RF_ON);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case RF_CMD_GRACE:
 | 
					 | 
				
			||||||
		send_signal(conn, S_RF_GRACE);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Unknown command %d\n", buf[0]);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int rf_write_cmd(struct bsc_fd *fd, struct msgb *msg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rc = write(fd->fd, msg->data, msg->len);
 | 
					 | 
				
			||||||
	if (rc != msg->len) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Short write %d/%s\n", errno, strerror(errno));
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int rf_ctl_accept(struct bsc_fd *bfd, unsigned int what)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct osmo_bsc_rf_conn *conn;
 | 
					 | 
				
			||||||
	struct osmo_bsc_rf *rf = bfd->data;
 | 
					 | 
				
			||||||
	struct sockaddr_un addr;
 | 
					 | 
				
			||||||
	socklen_t len = sizeof(addr);
 | 
					 | 
				
			||||||
	int fd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fd = accept(bfd->fd, (struct sockaddr *) &addr, &len);
 | 
					 | 
				
			||||||
	if (fd < 0) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Failed to accept. errno: %d/%s\n",
 | 
					 | 
				
			||||||
		     errno, strerror(errno));
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	conn = talloc_zero(rf, struct osmo_bsc_rf_conn);
 | 
					 | 
				
			||||||
	if (!conn) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Failed to allocate mem.\n");
 | 
					 | 
				
			||||||
		close(fd);
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	write_queue_init(&conn->queue, 10);
 | 
					 | 
				
			||||||
	conn->queue.bfd.data = conn;
 | 
					 | 
				
			||||||
	conn->queue.bfd.fd = fd;
 | 
					 | 
				
			||||||
	conn->queue.bfd.when = BSC_FD_READ | BSC_FD_WRITE;
 | 
					 | 
				
			||||||
	conn->queue.read_cb = rf_read_cmd;
 | 
					 | 
				
			||||||
	conn->queue.write_cb = rf_write_cmd;
 | 
					 | 
				
			||||||
	conn->gsm_network = rf->gsm_network;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (bsc_register_fd(&conn->queue.bfd) != 0) {
 | 
					 | 
				
			||||||
		close(fd);
 | 
					 | 
				
			||||||
		talloc_free(conn);
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct osmo_bsc_rf *osmo_bsc_rf_create(const char *path, struct gsm_network *net)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	unsigned int namelen;
 | 
					 | 
				
			||||||
	struct sockaddr_un local;
 | 
					 | 
				
			||||||
	struct bsc_fd *bfd;
 | 
					 | 
				
			||||||
	struct osmo_bsc_rf *rf;
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rf = talloc_zero(NULL, struct osmo_bsc_rf);
 | 
					 | 
				
			||||||
	if (!rf) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Failed to create osmo_bsc_rf.\n");
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bfd = &rf->listen;
 | 
					 | 
				
			||||||
	bfd->fd = socket(AF_UNIX, SOCK_STREAM, 0);
 | 
					 | 
				
			||||||
	if (bfd->fd < 0) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Can not create socket. %d/%s\n",
 | 
					 | 
				
			||||||
		     errno, strerror(errno));
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	local.sun_family = AF_UNIX;
 | 
					 | 
				
			||||||
	strncpy(local.sun_path, path, sizeof(local.sun_path));
 | 
					 | 
				
			||||||
	local.sun_path[sizeof(local.sun_path) - 1] = '\0';
 | 
					 | 
				
			||||||
	unlink(local.sun_path);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* we use the same magic that X11 uses in Xtranssock.c for
 | 
					 | 
				
			||||||
	 * calculating the proper length of the sockaddr */
 | 
					 | 
				
			||||||
#if defined(BSD44SOCKETS) || defined(__UNIXWARE__)
 | 
					 | 
				
			||||||
	local.sun_len = strlen(local.sun_path);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#if defined(BSD44SOCKETS) || defined(SUN_LEN)
 | 
					 | 
				
			||||||
	namelen = SUN_LEN(&local);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	namelen = strlen(local.sun_path) +
 | 
					 | 
				
			||||||
		  offsetof(struct sockaddr_un, sun_path);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rc = bind(bfd->fd, (struct sockaddr *) &local, namelen);
 | 
					 | 
				
			||||||
	if (rc != 0) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Failed to bind '%s' errno: %d/%s\n",
 | 
					 | 
				
			||||||
		     local.sun_path, errno, strerror(errno));
 | 
					 | 
				
			||||||
		close(bfd->fd);
 | 
					 | 
				
			||||||
		talloc_free(rf);
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (listen(bfd->fd, 0) != 0) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Failed to listen: %d/%s\n", errno, strerror(errno));
 | 
					 | 
				
			||||||
		close(bfd->fd);
 | 
					 | 
				
			||||||
		talloc_free(rf);
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bfd->when = BSC_FD_READ;
 | 
					 | 
				
			||||||
	bfd->cb = rf_ctl_accept;
 | 
					 | 
				
			||||||
	bfd->data = rf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (bsc_register_fd(bfd) != 0) {
 | 
					 | 
				
			||||||
		LOGP(DINP, LOGL_ERROR, "Failed to register bfd.\n");
 | 
					 | 
				
			||||||
		close(bfd->fd);
 | 
					 | 
				
			||||||
		talloc_free(rf);
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rf->gsm_network = net;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rf;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
/* Osmo BSC VTY Configuration */
 | 
					 | 
				
			||||||
/* (C) 2009-2010 by Holger Hans Peter Freyther
 | 
					 | 
				
			||||||
 * (C) 2009-2010 by On Waves
 | 
					 | 
				
			||||||
 * All Rights Reserved
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License along
 | 
					 | 
				
			||||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocom/vty/vty.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bsc_vty_init_extra(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,209 +0,0 @@
 | 
				
			|||||||
/* GSM 08.08 like API for OpenBSC. The bridge from MSC to BSC */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* (C) 2010 by Holger Hans Peter Freyther
 | 
					 | 
				
			||||||
 * (C) 2010 by On Waves
 | 
					 | 
				
			||||||
 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * All Rights Reserved
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License along
 | 
					 | 
				
			||||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <openbsc/bsc_api.h>
 | 
					 | 
				
			||||||
#include <openbsc/bsc_rll.h>
 | 
					 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					 | 
				
			||||||
#include <openbsc/signal.h>
 | 
					 | 
				
			||||||
#include <openbsc/abis_rsl.h>
 | 
					 | 
				
			||||||
#include <openbsc/chan_alloc.h>
 | 
					 | 
				
			||||||
#include <openbsc/handover.h>
 | 
					 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/talloc.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind);
 | 
					 | 
				
			||||||
static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bsc_api_init(struct gsm_network *network, struct bsc_api *api)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	network->bsc_api = api;
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn,
 | 
					 | 
				
			||||||
			struct msgb *msg, int link_id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint8_t sapi = link_id & 0x7;
 | 
					 | 
				
			||||||
	msg->lchan = conn->lchan;
 | 
					 | 
				
			||||||
	msg->trx = msg->lchan->ts->trx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msg->l3h = msg->data;
 | 
					 | 
				
			||||||
	if (conn->lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) {
 | 
					 | 
				
			||||||
		OBSC_LINKID_CB(msg) = link_id;
 | 
					 | 
				
			||||||
		if (rll_establish(msg->lchan, sapi, rll_ind_cb, msg) != 0) {
 | 
					 | 
				
			||||||
			msgb_free(msg);
 | 
					 | 
				
			||||||
			send_sapi_reject(conn, link_id);
 | 
					 | 
				
			||||||
			return -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		return rsl_data_request(msg, link_id);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Send a GSM08.08 Assignment Request. Right now this does not contain the
 | 
					 | 
				
			||||||
 * audio codec type or the allowed rates for the config.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_type, int audio)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bsc_api *api;
 | 
					 | 
				
			||||||
	api = conn->bts->network->bsc_api;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	api->assign_fail(conn, 0);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gsm0808_page(struct gsm_bts *bts, unsigned int page_group, unsigned int mi_len,
 | 
					 | 
				
			||||||
		 uint8_t *mi, int chan_type)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return rsl_paging_cmd(bts, page_group, mi_len, mi, chan_type);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* dequeue messages to layer 4 */
 | 
					 | 
				
			||||||
int bsc_upqueue(struct gsm_network *net)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gsm_mncc *mncc;
 | 
					 | 
				
			||||||
	struct msgb *msg;
 | 
					 | 
				
			||||||
	int work = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (net)
 | 
					 | 
				
			||||||
		while ((msg = msgb_dequeue(&net->upqueue))) {
 | 
					 | 
				
			||||||
			mncc = (struct gsm_mncc *)msg->data;
 | 
					 | 
				
			||||||
			if (net->mncc_recv)
 | 
					 | 
				
			||||||
				net->mncc_recv(net, mncc->msg_type, mncc);
 | 
					 | 
				
			||||||
			work = 1; /* work done */
 | 
					 | 
				
			||||||
			talloc_free(msg);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return work;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
	struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
 | 
					 | 
				
			||||||
	struct gsm_lchan *lchan;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lchan = msg->lchan;
 | 
					 | 
				
			||||||
	if (lchan->state != LCHAN_S_ACTIVE) {
 | 
					 | 
				
			||||||
		LOGP(DRSL, LOGL_ERROR, "Got data in non active state. discarding.\n");
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (lchan->conn) {
 | 
					 | 
				
			||||||
		api->dtap(lchan->conn, msg);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		rc = BSC_API_CONN_POL_REJECT;
 | 
					 | 
				
			||||||
		lchan->conn = subscr_con_allocate(msg->lchan);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (lchan->conn)
 | 
					 | 
				
			||||||
			rc = api->compl_l3(lchan->conn, msg, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (rc != BSC_API_CONN_POL_ACCEPT) {
 | 
					 | 
				
			||||||
			subscr_con_free(lchan->conn);
 | 
					 | 
				
			||||||
			lchan_release(lchan, 0, 0);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
 | 
					 | 
				
			||||||
			uint8_t *key, int len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gsm0808_clear(struct gsm_subscriber_connection* conn)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gsm_lchan *lchan;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bsc_clear_handover(conn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lchan = conn->lchan;
 | 
					 | 
				
			||||||
	subscr_con_free(conn);
 | 
					 | 
				
			||||||
	lchan_release(lchan, 1, 0);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bsc_api *api;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!conn)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	api = conn->bts->network->bsc_api;
 | 
					 | 
				
			||||||
	if (!api || !api->sapi_n_reject)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	api->sapi_n_reject(conn, link_id);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void rll_ind_cb(struct gsm_lchan *lchan, uint8_t link_id, void *_data, enum bsc_rllr_ind rllr_ind)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct msgb *msg = _data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (rllr_ind) {
 | 
					 | 
				
			||||||
	case BSC_RLLR_IND_EST_CONF:
 | 
					 | 
				
			||||||
		rsl_data_request(msg, OBSC_LINKID_CB(msg));
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case BSC_RLLR_IND_REL_IND:
 | 
					 | 
				
			||||||
	case BSC_RLLR_IND_ERR_IND:
 | 
					 | 
				
			||||||
	case BSC_RLLR_IND_TIMEOUT:
 | 
					 | 
				
			||||||
		send_sapi_reject(lchan->conn, OBSC_LINKID_CB(msg));
 | 
					 | 
				
			||||||
		msgb_free(msg);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal,
 | 
					 | 
				
			||||||
				   void *handler_data, void *signal_data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bsc_api *bsc;
 | 
					 | 
				
			||||||
	struct gsm_lchan *lchan;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (subsys != SS_LCHAN || signal != S_LCHAN_UNEXPECTED_RELEASE)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lchan = (struct gsm_lchan *)signal_data;
 | 
					 | 
				
			||||||
	if (!lchan || !lchan->conn)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bsc = lchan->ts->trx->bts->network->bsc_api;
 | 
					 | 
				
			||||||
	if (!bsc || !bsc->clear_request)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bsc->clear_request(lchan->conn, 0);
 | 
					 | 
				
			||||||
	subscr_con_free(lchan->conn);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static __attribute__((constructor)) void on_dso_load_bsc(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	register_signal_handler(SS_LCHAN, bsc_handle_lchan_signal, NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
/* A hackish minimal BSC (+MSC +HLR) implementation */
 | 
					/* A hackish minimal BSC (+MSC +HLR) implementation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
 | 
					/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -31,27 +31,16 @@
 | 
				
			|||||||
#include <getopt.h>
 | 
					#include <getopt.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <openbsc/db.h>
 | 
					#include <openbsc/db.h>
 | 
				
			||||||
#include <osmocore/select.h>
 | 
					#include <openbsc/select.h>
 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					#include <openbsc/debug.h>
 | 
				
			||||||
#include <openbsc/e1_input.h>
 | 
					#include <openbsc/e1_input.h>
 | 
				
			||||||
#include <osmocore/talloc.h>
 | 
					#include <openbsc/talloc.h>
 | 
				
			||||||
#include <openbsc/signal.h>
 | 
					#include <openbsc/signal.h>
 | 
				
			||||||
#include <openbsc/osmo_msc.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocom/vty/command.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "../bscconfig.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* MCC and MNC for the Location Area Identifier */
 | 
					/* MCC and MNC for the Location Area Identifier */
 | 
				
			||||||
static struct log_target *stderr_target;
 | 
					 | 
				
			||||||
struct gsm_network *bsc_gsmnet = 0;
 | 
					struct gsm_network *bsc_gsmnet = 0;
 | 
				
			||||||
static const char *database_name = "hlr.sqlite3";
 | 
					static const char *database_name = "hlr.sqlite3";
 | 
				
			||||||
static const char *config_file = "openbsc.cfg";
 | 
					static const char *config_file = "openbsc.cfg";
 | 
				
			||||||
extern const char *openbsc_copyright;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* timer to store statistics */
 | 
					 | 
				
			||||||
#define DB_SYNC_INTERVAL	60, 0
 | 
					 | 
				
			||||||
static struct timer_list db_sync_timer;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int bsc_bootstrap_network(int (*mmc_rev)(struct gsm_network *, int, void *),
 | 
					extern int bsc_bootstrap_network(int (*mmc_rev)(struct gsm_network *, int, void *),
 | 
				
			||||||
				 const char *cfg_file);
 | 
									 const char *cfg_file);
 | 
				
			||||||
@@ -80,15 +69,12 @@ static void print_help()
 | 
				
			|||||||
	printf("  Some useful help...\n");
 | 
						printf("  Some useful help...\n");
 | 
				
			||||||
	printf("  -h --help this text\n");
 | 
						printf("  -h --help this text\n");
 | 
				
			||||||
	printf("  -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
 | 
						printf("  -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
 | 
				
			||||||
	printf("  -c --config-file filename The config file to use.\n");
 | 
					 | 
				
			||||||
	printf("  -s --disable-color\n");
 | 
						printf("  -s --disable-color\n");
 | 
				
			||||||
 | 
						printf("  -c --config-file filename The config file to use.\n");
 | 
				
			||||||
	printf("  -l --database db-name The database to use\n");
 | 
						printf("  -l --database db-name The database to use\n");
 | 
				
			||||||
	printf("  -a --authorize-everyone. Authorize every new subscriber. Dangerous!.\n");
 | 
					 | 
				
			||||||
	printf("  -p --pcap file  The filename of the pcap file\n");
 | 
						printf("  -p --pcap file  The filename of the pcap file\n");
 | 
				
			||||||
	printf("  -T --timestamp Prefix every log line with a timestamp\n");
 | 
						printf("  -T --timestamp Prefix every log line with a timestamp\n");
 | 
				
			||||||
	printf("  -V --version. Print the version of OpenBSC.\n");
 | 
					 | 
				
			||||||
	printf("  -P --rtp-proxy Enable the RTP Proxy code inside OpenBSC\n");
 | 
						printf("  -P --rtp-proxy Enable the RTP Proxy code inside OpenBSC\n");
 | 
				
			||||||
	printf("  -e --log-level number. Set a global loglevel.\n");
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_options(int argc, char** argv)
 | 
					static void handle_options(int argc, char** argv)
 | 
				
			||||||
@@ -104,13 +90,11 @@ static void handle_options(int argc, char** argv)
 | 
				
			|||||||
			{"authorize-everyone", 0, 0, 'a'},
 | 
								{"authorize-everyone", 0, 0, 'a'},
 | 
				
			||||||
			{"pcap", 1, 0, 'p'},
 | 
								{"pcap", 1, 0, 'p'},
 | 
				
			||||||
			{"timestamp", 0, 0, 'T'},
 | 
								{"timestamp", 0, 0, 'T'},
 | 
				
			||||||
			{"version", 0, 0, 'V' },
 | 
					 | 
				
			||||||
			{"rtp-proxy", 0, 0, 'P'},
 | 
								{"rtp-proxy", 0, 0, 'P'},
 | 
				
			||||||
			{"log-level", 1, 0, 'e'},
 | 
					 | 
				
			||||||
			{0, 0, 0, 0}
 | 
								{0, 0, 0, 0}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		c = getopt_long(argc, argv, "hd:sl:ar:p:TPVc:e:",
 | 
							c = getopt_long(argc, argv, "hd:sl:ar:p:TPc:",
 | 
				
			||||||
				long_options, &option_index);
 | 
									long_options, &option_index);
 | 
				
			||||||
		if (c == -1)
 | 
							if (c == -1)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -121,10 +105,10 @@ static void handle_options(int argc, char** argv)
 | 
				
			|||||||
			print_help();
 | 
								print_help();
 | 
				
			||||||
			exit(0);
 | 
								exit(0);
 | 
				
			||||||
		case 's':
 | 
							case 's':
 | 
				
			||||||
			log_set_use_color(stderr_target, 0);
 | 
								debug_use_color(0);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'd':
 | 
							case 'd':
 | 
				
			||||||
			log_parse_category_mask(stderr_target, optarg);
 | 
								debug_parse_category_mask(optarg);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'l':
 | 
							case 'l':
 | 
				
			||||||
			database_name = strdup(optarg);
 | 
								database_name = strdup(optarg);
 | 
				
			||||||
@@ -136,18 +120,11 @@ static void handle_options(int argc, char** argv)
 | 
				
			|||||||
			create_pcap_file(optarg);
 | 
								create_pcap_file(optarg);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'T':
 | 
							case 'T':
 | 
				
			||||||
			log_set_print_timestamp(stderr_target, 1);
 | 
								debug_timestamp(1);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'P':
 | 
							case 'P':
 | 
				
			||||||
			ipacc_rtp_direct = 0;
 | 
								ipacc_rtp_direct = 0;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'e':
 | 
					 | 
				
			||||||
			log_set_log_level(stderr_target, atoi(optarg));
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'V':
 | 
					 | 
				
			||||||
			print_version(1);
 | 
					 | 
				
			||||||
			exit(0);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			/* ignore */
 | 
								/* ignore */
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -155,7 +132,6 @@ static void handle_options(int argc, char** argv)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void *tall_vty_ctx;
 | 
					 | 
				
			||||||
static void signal_handler(int signal)
 | 
					static void signal_handler(int signal)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	fprintf(stdout, "signal %u received\n", signal);
 | 
						fprintf(stdout, "signal %u received\n", signal);
 | 
				
			||||||
@@ -171,76 +147,26 @@ static void signal_handler(int signal)
 | 
				
			|||||||
		/* in case of abort, we want to obtain a talloc report
 | 
							/* in case of abort, we want to obtain a talloc report
 | 
				
			||||||
		 * and then return to the caller, who will abort the process */
 | 
							 * and then return to the caller, who will abort the process */
 | 
				
			||||||
	case SIGUSR1:
 | 
						case SIGUSR1:
 | 
				
			||||||
		talloc_report(tall_vty_ctx, stderr);
 | 
					 | 
				
			||||||
		talloc_report_full(tall_bsc_ctx, stderr);
 | 
							talloc_report_full(tall_bsc_ctx, stderr);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SIGUSR2:
 | 
					 | 
				
			||||||
		talloc_report_full(tall_vty_ctx, stderr);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* timer handling */
 | 
					 | 
				
			||||||
static int _db_store_counter(struct counter *counter, void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return db_store_counter(counter);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void db_sync_timer_cb(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* store counters to database and re-schedule */
 | 
					 | 
				
			||||||
	counters_for_each(_db_store_counter, NULL);
 | 
					 | 
				
			||||||
	bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int bts_model_unknown_init(void);
 | 
					 | 
				
			||||||
extern int bts_model_bs11_init(void);
 | 
					 | 
				
			||||||
extern int bts_model_nanobts_init(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern enum node_type bsc_vty_go_parent(struct vty *vty);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct vty_app_info vty_info = {
 | 
					 | 
				
			||||||
	.name 		= "OpenBSC",
 | 
					 | 
				
			||||||
	.version	= PACKAGE_VERSION,
 | 
					 | 
				
			||||||
	.go_parent_cb	= bsc_vty_go_parent,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc;
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vty_info.copyright = openbsc_copyright;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	log_init(&log_info);
 | 
					 | 
				
			||||||
	tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
 | 
						tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
 | 
				
			||||||
	talloc_ctx_init();
 | 
						talloc_ctx_init();
 | 
				
			||||||
	on_dso_load_token();
 | 
						on_dso_load_token();
 | 
				
			||||||
	on_dso_load_rrlp();
 | 
						on_dso_load_rrlp();
 | 
				
			||||||
	on_dso_load_ho_dec();
 | 
						on_dso_load_ho_dec();
 | 
				
			||||||
	stderr_target = log_target_create_stderr();
 | 
					 | 
				
			||||||
	log_add_target(stderr_target);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bts_model_unknown_init();
 | 
					 | 
				
			||||||
	bts_model_bs11_init();
 | 
					 | 
				
			||||||
	bts_model_nanobts_init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* enable filters */
 | 
					 | 
				
			||||||
	log_set_all_filter(stderr_target, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* This needs to precede handle_options() */
 | 
					 | 
				
			||||||
	vty_init(&vty_info);
 | 
					 | 
				
			||||||
	bsc_vty_init();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* parse options */
 | 
						/* parse options */
 | 
				
			||||||
	handle_options(argc, argv);
 | 
						handle_options(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = bsc_bootstrap_network(mncc_recv, config_file);
 | 
					 | 
				
			||||||
	if (rc < 0)
 | 
					 | 
				
			||||||
		exit(1);
 | 
					 | 
				
			||||||
	bsc_api_init(bsc_gsmnet, msc_bsc_api());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* seed the PRNG */
 | 
						/* seed the PRNG */
 | 
				
			||||||
	srand(time(NULL));
 | 
						srand(time(NULL));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -256,20 +182,17 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	printf("DB: Database prepared.\n");
 | 
						printf("DB: Database prepared.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* setup the timer */
 | 
						rc = bsc_bootstrap_network(mncc_recv, config_file);
 | 
				
			||||||
	db_sync_timer.cb = db_sync_timer_cb;
 | 
						if (rc < 0)
 | 
				
			||||||
	db_sync_timer.data = NULL;
 | 
							exit(1);
 | 
				
			||||||
	bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	signal(SIGINT, &signal_handler);
 | 
						signal(SIGINT, &signal_handler);
 | 
				
			||||||
	signal(SIGABRT, &signal_handler);
 | 
						signal(SIGABRT, &signal_handler);
 | 
				
			||||||
	signal(SIGUSR1, &signal_handler);
 | 
						signal(SIGUSR1, &signal_handler);
 | 
				
			||||||
	signal(SIGUSR2, &signal_handler);
 | 
					 | 
				
			||||||
	signal(SIGPIPE, SIG_IGN);
 | 
						signal(SIGPIPE, SIG_IGN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (1) {
 | 
						while (1) {
 | 
				
			||||||
		bsc_upqueue(bsc_gsmnet);
 | 
							bsc_upqueue(bsc_gsmnet);
 | 
				
			||||||
		log_reset_context();
 | 
					 | 
				
			||||||
		bsc_select_main(0);
 | 
							bsc_select_main(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
/* A hackish minimal BSC (+MSC +HLR) implementation */
 | 
					/* A hackish minimal BSC (+MSC +HLR) implementation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
 | 
					/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -21,18 +21,17 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					#include <openbsc/gsm_data.h>
 | 
				
			||||||
#include <osmocore/gsm_utils.h>
 | 
					#include <openbsc/gsm_utils.h>
 | 
				
			||||||
#include <openbsc/gsm_04_08.h>
 | 
					#include <openbsc/gsm_04_08.h>
 | 
				
			||||||
#include <openbsc/abis_rsl.h>
 | 
					#include <openbsc/abis_rsl.h>
 | 
				
			||||||
#include <openbsc/abis_nm.h>
 | 
					#include <openbsc/abis_nm.h>
 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					#include <openbsc/debug.h>
 | 
				
			||||||
#include <openbsc/misdn.h>
 | 
					#include <openbsc/misdn.h>
 | 
				
			||||||
#include <osmocom/vty/telnet_interface.h>
 | 
					#include <openbsc/telnet_interface.h>
 | 
				
			||||||
#include <openbsc/system_information.h>
 | 
					#include <openbsc/system_information.h>
 | 
				
			||||||
#include <openbsc/paging.h>
 | 
					#include <openbsc/paging.h>
 | 
				
			||||||
#include <openbsc/signal.h>
 | 
					#include <openbsc/signal.h>
 | 
				
			||||||
#include <openbsc/chan_alloc.h>
 | 
					#include <openbsc/talloc.h>
 | 
				
			||||||
#include <osmocore/talloc.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* global pointer to the gsm network data structure */
 | 
					/* global pointer to the gsm network data structure */
 | 
				
			||||||
extern struct gsm_network *bsc_gsmnet;
 | 
					extern struct gsm_network *bsc_gsmnet;
 | 
				
			||||||
@@ -331,7 +330,6 @@ static unsigned char nanobts_attr_bts[] = {
 | 
				
			|||||||
	NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
 | 
						NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
 | 
				
			||||||
	NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
 | 
						NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
 | 
				
			||||||
	NM_ATT_BSIC, HARDCODED_BSIC,
 | 
						NM_ATT_BSIC, HARDCODED_BSIC,
 | 
				
			||||||
	NM_ATT_IPACC_CGI, 0, 7,  0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x00,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned char nanobts_attr_radio[] = {
 | 
					static unsigned char nanobts_attr_radio[] = {
 | 
				
			||||||
@@ -339,75 +337,13 @@ static unsigned char nanobts_attr_radio[] = {
 | 
				
			|||||||
	NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
 | 
						NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned char nanobts_attr_nse[] = {
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_NSEI, 0, 2,  0x03, 0x9d, /* NSEI 925 */
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_NS_CFG, 0, 7,  3,  /* (un)blocking timer (Tns-block) */
 | 
					 | 
				
			||||||
				    3,  /* (un)blocking retries */
 | 
					 | 
				
			||||||
				    3,  /* reset timer (Tns-reset) */
 | 
					 | 
				
			||||||
				    3,  /* reset retries */
 | 
					 | 
				
			||||||
				    30,  /* test timer (Tns-test) */
 | 
					 | 
				
			||||||
				    3,  /* alive timer (Tns-alive) */
 | 
					 | 
				
			||||||
				    10, /* alive retrires */
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_BSSGP_CFG, 0, 11,
 | 
					 | 
				
			||||||
				    3,  /* blockimg timer (T1) */
 | 
					 | 
				
			||||||
				    3,  /* blocking retries */
 | 
					 | 
				
			||||||
				    3,  /* unblocking retries */
 | 
					 | 
				
			||||||
				    3,  /* reset timer */
 | 
					 | 
				
			||||||
				    3,  /* reset retries */
 | 
					 | 
				
			||||||
				    10, /* suspend timer (T3) in 100ms */
 | 
					 | 
				
			||||||
				    3,  /* suspend retries */
 | 
					 | 
				
			||||||
				    10, /* resume timer (T4) in 100ms */
 | 
					 | 
				
			||||||
				    3,  /* resume retries */
 | 
					 | 
				
			||||||
				    10, /* capability update timer (T5) */
 | 
					 | 
				
			||||||
				    3,  /* capability update retries */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static unsigned char nanobts_attr_cell[] = {
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_RAC, 0, 1,  1, /* routing area code */
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_GPRS_PAGING_CFG, 0, 2,
 | 
					 | 
				
			||||||
		5,	/* repeat time (50ms) */
 | 
					 | 
				
			||||||
		3,	/* repeat count */
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_BVCI, 0, 2,  0x03, 0x9d, /* BVCI 925 */
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_RLC_CFG, 0, 9,
 | 
					 | 
				
			||||||
		20, 	/* T3142 */
 | 
					 | 
				
			||||||
		5, 	/* T3169 */
 | 
					 | 
				
			||||||
		5,	/* T3191 */
 | 
					 | 
				
			||||||
		200,	/* T3193 */
 | 
					 | 
				
			||||||
		5,	/* T3195 */
 | 
					 | 
				
			||||||
		10,	/* N3101 */
 | 
					 | 
				
			||||||
		4,	/* N3103 */
 | 
					 | 
				
			||||||
		8,	/* N3105 */
 | 
					 | 
				
			||||||
		15,	/* RLC CV countdown */
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_CODING_SCHEMES, 0, 2,  0x0f, 0x00,	/* CS1..CS4 */
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_RLC_CFG_2, 0, 5,
 | 
					 | 
				
			||||||
		0x00, 250,	/* T downlink TBF extension (0..500) */
 | 
					 | 
				
			||||||
		0x00, 250,	/* T uplink TBF extension (0..500) */
 | 
					 | 
				
			||||||
		2,	/* CS2 */
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
	/* EDGE model only, breaks older models.
 | 
					 | 
				
			||||||
	 * Should inquire the BTS capabilities */
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_RLC_CFG_3, 0, 1,
 | 
					 | 
				
			||||||
		2,	/* MCS2 */
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static unsigned char nanobts_attr_nsvc0[] = {
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_NSVCI, 0, 2,  0x03, 0x9d, /* 925 */
 | 
					 | 
				
			||||||
	NM_ATT_IPACC_NS_LINK_CFG, 0, 8,
 | 
					 | 
				
			||||||
		0x59, 0xd8, /* remote udp port (23000) */
 | 
					 | 
				
			||||||
		192, 168, 100, 11, /* remote ip address */
 | 
					 | 
				
			||||||
		0x59, 0xd8, /* local udp port (23000) */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Callback function to be called whenever we get a GSM 12.21 state change event */
 | 
					/* Callback function to be called whenever we get a GSM 12.21 state change event */
 | 
				
			||||||
int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
 | 
					int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
 | 
				
			||||||
		   struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,
 | 
							   struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
 | 
				
			||||||
		   struct abis_om_obj_inst *obj_inst)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct gsm_bts *bts;
 | 
						struct gsm_bts *bts;
 | 
				
			||||||
	struct gsm_bts_trx *trx;
 | 
						struct gsm_bts_trx *trx;
 | 
				
			||||||
	struct gsm_bts_trx_ts *ts;
 | 
						struct gsm_bts_trx_ts *ts;
 | 
				
			||||||
	struct gsm_bts_gprs_nsvc *nsvc;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* This event-driven BTS setup is currently only required on nanoBTS */
 | 
						/* This event-driven BTS setup is currently only required on nanoBTS */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -419,15 +355,16 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
 | 
				
			|||||||
	switch (obj_class) {
 | 
						switch (obj_class) {
 | 
				
			||||||
	case NM_OC_SITE_MANAGER:
 | 
						case NM_OC_SITE_MANAGER:
 | 
				
			||||||
		bts = container_of(obj, struct gsm_bts, site_mgr);
 | 
							bts = container_of(obj, struct gsm_bts, site_mgr);
 | 
				
			||||||
		if ((new_state->operational == NM_OPSTATE_ENABLED &&
 | 
							if (new_state->operational == 2 &&
 | 
				
			||||||
		     new_state->availability == NM_AVSTATE_OK) ||
 | 
							    new_state->availability == NM_AVSTATE_OK) {
 | 
				
			||||||
		    (new_state->operational == NM_OPSTATE_DISABLED &&
 | 
								printf("STARTING SITE MANAGER\n");
 | 
				
			||||||
		     new_state->availability == NM_AVSTATE_OFF_LINE))
 | 
					 | 
				
			||||||
			abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
 | 
								abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case NM_OC_BTS:
 | 
						case NM_OC_BTS:
 | 
				
			||||||
		bts = obj;
 | 
							bts = obj;
 | 
				
			||||||
		if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
 | 
							if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
 | 
				
			||||||
 | 
								printf("STARTING BTS...\n");
 | 
				
			||||||
			patch_nm_tables(bts);
 | 
								patch_nm_tables(bts);
 | 
				
			||||||
			abis_nm_set_bts_attr(bts, nanobts_attr_bts,
 | 
								abis_nm_set_bts_attr(bts, nanobts_attr_bts,
 | 
				
			||||||
					     sizeof(nanobts_attr_bts));
 | 
										     sizeof(nanobts_attr_bts));
 | 
				
			||||||
@@ -441,8 +378,9 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
 | 
				
			|||||||
	case NM_OC_CHANNEL:
 | 
						case NM_OC_CHANNEL:
 | 
				
			||||||
		ts = obj;
 | 
							ts = obj;
 | 
				
			||||||
		trx = ts->trx;
 | 
							trx = ts->trx;
 | 
				
			||||||
		if (new_state->operational == NM_OPSTATE_DISABLED &&
 | 
							if (new_state->operational == 1 &&
 | 
				
			||||||
		    new_state->availability == NM_AVSTATE_DEPENDENCY) {
 | 
							    new_state->availability == NM_AVSTATE_DEPENDENCY) {
 | 
				
			||||||
 | 
								printf("STARTING OC Channel...\n");
 | 
				
			||||||
			patch_nm_tables(trx->bts);
 | 
								patch_nm_tables(trx->bts);
 | 
				
			||||||
			enum abis_nm_chan_comb ccomb =
 | 
								enum abis_nm_chan_comb ccomb =
 | 
				
			||||||
						abis_nm_chcomb4pchan(ts->pchan);
 | 
											abis_nm_chcomb4pchan(ts->pchan);
 | 
				
			||||||
@@ -456,58 +394,11 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
 | 
				
			|||||||
		break;
 | 
							break;
 | 
				
			||||||
	case NM_OC_RADIO_CARRIER:
 | 
						case NM_OC_RADIO_CARRIER:
 | 
				
			||||||
		trx = obj;
 | 
							trx = obj;
 | 
				
			||||||
		if (new_state->operational == NM_OPSTATE_DISABLED &&
 | 
							if (new_state->operational == 1 &&
 | 
				
			||||||
		    new_state->availability == NM_AVSTATE_OK)
 | 
							    new_state->availability == NM_AVSTATE_OK)
 | 
				
			||||||
			abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
 | 
								abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
 | 
				
			||||||
					trx->nr, 0xff);
 | 
										trx->nr, 0xff);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case NM_OC_GPRS_NSE:
 | 
					 | 
				
			||||||
		bts = container_of(obj, struct gsm_bts, gprs.nse);
 | 
					 | 
				
			||||||
		if (bts->gprs.mode == BTS_GPRS_NONE)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
 | 
					 | 
				
			||||||
			abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
 | 
					 | 
				
			||||||
						  0xff, 0xff, nanobts_attr_nse,
 | 
					 | 
				
			||||||
						  sizeof(nanobts_attr_nse));
 | 
					 | 
				
			||||||
			abis_nm_opstart(bts, obj_class, bts->bts_nr,
 | 
					 | 
				
			||||||
					0xff, 0xff);
 | 
					 | 
				
			||||||
			abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
 | 
					 | 
				
			||||||
					      0xff, 0xff, NM_STATE_UNLOCKED);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case NM_OC_GPRS_CELL:
 | 
					 | 
				
			||||||
		bts = container_of(obj, struct gsm_bts, gprs.cell);
 | 
					 | 
				
			||||||
		if (bts->gprs.mode == BTS_GPRS_NONE)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
 | 
					 | 
				
			||||||
			abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
 | 
					 | 
				
			||||||
						  0, 0xff, nanobts_attr_cell,
 | 
					 | 
				
			||||||
						  sizeof(nanobts_attr_cell));
 | 
					 | 
				
			||||||
			abis_nm_opstart(bts, obj_class, bts->bts_nr,
 | 
					 | 
				
			||||||
					0, 0xff);
 | 
					 | 
				
			||||||
			abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
 | 
					 | 
				
			||||||
					      0, 0xff, NM_STATE_UNLOCKED);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case NM_OC_GPRS_NSVC:
 | 
					 | 
				
			||||||
		nsvc = obj;
 | 
					 | 
				
			||||||
		bts = nsvc->bts;
 | 
					 | 
				
			||||||
		if (bts->gprs.mode == BTS_GPRS_NONE)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		/* We skip NSVC1 since we only use NSVC0 */
 | 
					 | 
				
			||||||
		if (nsvc->id == 1)
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		if (new_state->availability == NM_AVSTATE_OFF_LINE) {
 | 
					 | 
				
			||||||
			abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
 | 
					 | 
				
			||||||
						  nsvc->id, 0xff,
 | 
					 | 
				
			||||||
						  nanobts_attr_nsvc0,
 | 
					 | 
				
			||||||
						  sizeof(nanobts_attr_nsvc0));
 | 
					 | 
				
			||||||
			abis_nm_opstart(bts, obj_class, bts->bts_nr,
 | 
					 | 
				
			||||||
					nsvc->id, 0xff);
 | 
					 | 
				
			||||||
			abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
 | 
					 | 
				
			||||||
					      nsvc->id, 0xff,
 | 
					 | 
				
			||||||
					      NM_STATE_UNLOCKED);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -521,8 +412,6 @@ static int sw_activ_rep(struct msgb *mb)
 | 
				
			|||||||
	struct gsm_bts *bts = mb->trx->bts;
 | 
						struct gsm_bts *bts = mb->trx->bts;
 | 
				
			||||||
	struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
 | 
						struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!trx)
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (foh->obj_class) {
 | 
						switch (foh->obj_class) {
 | 
				
			||||||
	case NM_OC_BASEB_TRANSC:
 | 
						case NM_OC_BASEB_TRANSC:
 | 
				
			||||||
@@ -544,7 +433,8 @@ static int sw_activ_rep(struct msgb *mb)
 | 
				
			|||||||
		 * This code is here to make sure that on start
 | 
							 * This code is here to make sure that on start
 | 
				
			||||||
		 * a TRX remains locked.
 | 
							 * a TRX remains locked.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		int rc_state = trx->nm_state.administrative;
 | 
							int rc_state = trx->rf_locked ?
 | 
				
			||||||
 | 
										NM_STATE_LOCKED : NM_STATE_UNLOCKED;
 | 
				
			||||||
		/* Patch ARFCN into radio attribute */
 | 
							/* Patch ARFCN into radio attribute */
 | 
				
			||||||
		nanobts_attr_radio[5] &= 0xf0;
 | 
							nanobts_attr_radio[5] &= 0xf0;
 | 
				
			||||||
		nanobts_attr_radio[5] |= trx->arfcn >> 8;
 | 
							nanobts_attr_radio[5] |= trx->arfcn >> 8;
 | 
				
			||||||
@@ -563,9 +453,9 @@ static int sw_activ_rep(struct msgb *mb)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Callback function for NACK on the OML NM */
 | 
					/* Callback function for NACK on the OML NM */
 | 
				
			||||||
static int oml_msg_nack(struct nm_nack_signal_data *nack)
 | 
					static int oml_msg_nack(u_int8_t mt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (nack->mt == NM_MT_SET_BTS_ATTR_NACK) {
 | 
						if (mt == NM_MT_SET_BTS_ATTR_NACK) {
 | 
				
			||||||
		LOGP(DNM, LOGL_FATAL, "Failed to set BTS attributes. That is fatal. "
 | 
							LOGP(DNM, LOGL_FATAL, "Failed to set BTS attributes. That is fatal. "
 | 
				
			||||||
				"Was the bts type and frequency properly specified?\n");
 | 
									"Was the bts type and frequency properly specified?\n");
 | 
				
			||||||
		exit(-1);
 | 
							exit(-1);
 | 
				
			||||||
@@ -578,15 +468,14 @@ static int oml_msg_nack(struct nm_nack_signal_data *nack)
 | 
				
			|||||||
static int nm_sig_cb(unsigned int subsys, unsigned int signal,
 | 
					static int nm_sig_cb(unsigned int subsys, unsigned int signal,
 | 
				
			||||||
		     void *handler_data, void *signal_data)
 | 
							     void *handler_data, void *signal_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nm_nack_signal_data *nack;
 | 
					 | 
				
			||||||
	u_int8_t *msg_type;
 | 
						u_int8_t *msg_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (signal) {
 | 
						switch (signal) {
 | 
				
			||||||
	case S_NM_SW_ACTIV_REP:
 | 
						case S_NM_SW_ACTIV_REP:
 | 
				
			||||||
		return sw_activ_rep(signal_data);
 | 
							return sw_activ_rep(signal_data);
 | 
				
			||||||
	case S_NM_NACK:
 | 
						case S_NM_NACK:
 | 
				
			||||||
		nack = signal_data;
 | 
							msg_type = signal_data;
 | 
				
			||||||
		return oml_msg_nack(nack);
 | 
							return oml_msg_nack(*msg_type);
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -782,92 +671,57 @@ int bsc_shutdown_net(struct gsm_network *net)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int generate_and_rsl_si(struct gsm_bts_trx *trx, enum osmo_sysinfo_type i)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gsm_bts *bts = trx->bts;
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Only generate SI if this SI is not in "static" (user-defined) mode */
 | 
					 | 
				
			||||||
	if (!(bts->si_mode_static & (1 << i))) {
 | 
					 | 
				
			||||||
		rc = gsm_generate_si(bts, i);
 | 
					 | 
				
			||||||
		if (rc < 0)
 | 
					 | 
				
			||||||
			return rc;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	DEBUGP(DRR, "SI%s: %s\n", gsm_sitype_name(i),
 | 
					 | 
				
			||||||
		hexdump(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (i) {
 | 
					 | 
				
			||||||
	case SYSINFO_TYPE_5:
 | 
					 | 
				
			||||||
	case SYSINFO_TYPE_5bis:
 | 
					 | 
				
			||||||
	case SYSINFO_TYPE_5ter:
 | 
					 | 
				
			||||||
	case SYSINFO_TYPE_6:
 | 
					 | 
				
			||||||
		rc = rsl_sacch_filling(trx, gsm_sitype2rsl(i),
 | 
					 | 
				
			||||||
				       GSM_BTS_SI(bts, i), rc);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		rc = rsl_bcch_info(trx, gsm_sitype2rsl(i),
 | 
					 | 
				
			||||||
				   GSM_BTS_SI(bts, i), rc);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* set all system information types */
 | 
					/* set all system information types */
 | 
				
			||||||
static int set_system_infos(struct gsm_bts_trx *trx)
 | 
					static int set_system_infos(struct gsm_bts_trx *trx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, rc;
 | 
						int i, rc;
 | 
				
			||||||
 | 
						u_int8_t si_tmp[23];
 | 
				
			||||||
	struct gsm_bts *bts = trx->bts;
 | 
						struct gsm_bts *bts = trx->bts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
 | 
						bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
 | 
				
			||||||
			ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
 | 
								ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
 | 
				
			||||||
	bts->si_common.cell_sel_par.neci = bts->network->neci;
 | 
						bts->si_common.cell_sel_par.neci = bts->network->neci;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* First, we determine which of the SI messages we actually need */
 | 
						if (trx == trx->bts->c0) {
 | 
				
			||||||
 | 
							for (i = 1; i <= 4; i++) {
 | 
				
			||||||
	if (trx == bts->c0) {
 | 
								rc = gsm_generate_si(si_tmp, trx->bts, i);
 | 
				
			||||||
		/* 1...4 are always present on a C0 TRX */
 | 
								if (rc < 0)
 | 
				
			||||||
		for (i = SYSINFO_TYPE_1; i <= SYSINFO_TYPE_4; i++)
 | 
									goto err_out;
 | 
				
			||||||
			bts->si_valid |= (1 << i);
 | 
								DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
 | 
				
			||||||
 | 
								rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp));
 | 
				
			||||||
		/* 13 is always present on a C0 TRX of a GPRS BTS */
 | 
							}
 | 
				
			||||||
		if (bts->gprs.mode != BTS_GPRS_NONE)
 | 
					#ifdef GPRS
 | 
				
			||||||
			bts->si_valid |= (1 << SYSINFO_TYPE_13);
 | 
							i = 13
 | 
				
			||||||
	}
 | 
							rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* 5 and 6 are always present on every TRX */
 | 
					 | 
				
			||||||
	bts->si_valid |= (1 << SYSINFO_TYPE_5);
 | 
					 | 
				
			||||||
	bts->si_valid |= (1 << SYSINFO_TYPE_6);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Second, we generate and send the selected SI via RSL */
 | 
					 | 
				
			||||||
	for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
 | 
					 | 
				
			||||||
		if (!(bts->si_valid & (1 << i)))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		rc = generate_and_rsl_si(trx, i);
 | 
					 | 
				
			||||||
		if (rc < 0)
 | 
							if (rc < 0)
 | 
				
			||||||
			goto err_out;
 | 
								goto err_out;
 | 
				
			||||||
 | 
							DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
 | 
				
			||||||
 | 
							rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						i = 5;
 | 
				
			||||||
 | 
						rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_5);
 | 
				
			||||||
 | 
						if (rc < 0)
 | 
				
			||||||
 | 
							goto err_out;
 | 
				
			||||||
 | 
						DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
 | 
				
			||||||
 | 
						rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si_tmp, rc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						i = 6;
 | 
				
			||||||
 | 
						rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_6);
 | 
				
			||||||
 | 
						if (rc < 0)
 | 
				
			||||||
 | 
							goto err_out;
 | 
				
			||||||
 | 
						DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
 | 
				
			||||||
 | 
						rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si_tmp, rc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
err_out:
 | 
					err_out:
 | 
				
			||||||
	LOGP(DRR, LOGL_ERROR, "Cannot generate SI %u for BTS %u, most likely "
 | 
						LOGP(DRR, LOGL_ERROR, "Cannot generate SI %u for BTS %u, most likely "
 | 
				
			||||||
		"a problem with neighbor cell list generation\n",
 | 
							"a problem with neighbor cell list generation\n",
 | 
				
			||||||
		i, bts->nr);
 | 
							i, trx->bts->nr);
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void patch_16(uint8_t *data, const uint16_t val)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	memcpy(data, &val, sizeof(val));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void patch_32(uint8_t *data, const uint32_t val)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	memcpy(data, &val, sizeof(val));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Patch the various SYSTEM INFORMATION tables to update
 | 
					 * Patch the various SYSTEM INFORMATION tables to update
 | 
				
			||||||
 * the LAI
 | 
					 * the LAI
 | 
				
			||||||
@@ -890,143 +744,26 @@ static void patch_nm_tables(struct gsm_bts *bts)
 | 
				
			|||||||
	bs11_attr_radio[2] |= arfcn_high;
 | 
						bs11_attr_radio[2] |= arfcn_high;
 | 
				
			||||||
	bs11_attr_radio[3] = arfcn_low;
 | 
						bs11_attr_radio[3] = arfcn_low;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* patch the RACH attributes */
 | 
					 | 
				
			||||||
	if (bts->rach_b_thresh != -1) {
 | 
					 | 
				
			||||||
		nanobts_attr_bts[33] = bts->rach_b_thresh & 0xff;
 | 
					 | 
				
			||||||
		bs11_attr_bts[33] = bts->rach_b_thresh & 0xff;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (bts->rach_ldavg_slots != -1) {
 | 
					 | 
				
			||||||
		u_int8_t avg_high = bts->rach_ldavg_slots & 0xff;
 | 
					 | 
				
			||||||
		u_int8_t avg_low = (bts->rach_ldavg_slots >> 8) & 0x0f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		nanobts_attr_bts[35] = avg_high;
 | 
					 | 
				
			||||||
		nanobts_attr_bts[36] = avg_low;
 | 
					 | 
				
			||||||
		bs11_attr_bts[35] = avg_high;
 | 
					 | 
				
			||||||
		bs11_attr_bts[36] = avg_low;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* patch BSIC */
 | 
						/* patch BSIC */
 | 
				
			||||||
	bs11_attr_bts[1] = bts->bsic;
 | 
						bs11_attr_bts[1] = bts->bsic;
 | 
				
			||||||
	nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic;
 | 
						nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* patch CGI */
 | 
					 | 
				
			||||||
	abis_nm_ipaccess_cgi(nanobts_attr_bts+sizeof(nanobts_attr_bts)-7, bts);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* patch the power reduction */
 | 
						/* patch the power reduction */
 | 
				
			||||||
	bs11_attr_radio[5] = bts->c0->max_power_red / 2;
 | 
						bs11_attr_radio[5] = bts->c0->max_power_red / 2;
 | 
				
			||||||
	nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
 | 
						nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* patch NSEI */
 | 
					 | 
				
			||||||
	nanobts_attr_nse[3] = bts->gprs.nse.nsei >> 8;
 | 
					 | 
				
			||||||
	nanobts_attr_nse[4] = bts->gprs.nse.nsei & 0xff;
 | 
					 | 
				
			||||||
	memcpy(nanobts_attr_nse+8, bts->gprs.nse.timer,
 | 
					 | 
				
			||||||
		ARRAY_SIZE(bts->gprs.nse.timer));
 | 
					 | 
				
			||||||
	memcpy(nanobts_attr_nse+18, bts->gprs.cell.timer,
 | 
					 | 
				
			||||||
		ARRAY_SIZE(bts->gprs.cell.timer));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* patch NSVCI */
 | 
					 | 
				
			||||||
	nanobts_attr_nsvc0[3] = bts->gprs.nsvc[0].nsvci >> 8;
 | 
					 | 
				
			||||||
	nanobts_attr_nsvc0[4] = bts->gprs.nsvc[0].nsvci & 0xff;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* patch IP address as SGSN IP */
 | 
					 | 
				
			||||||
	patch_16(nanobts_attr_nsvc0 + 8, 
 | 
					 | 
				
			||||||
			htons(bts->gprs.nsvc[0].remote_port));
 | 
					 | 
				
			||||||
	patch_32(nanobts_attr_nsvc0 + 10,
 | 
					 | 
				
			||||||
			htonl(bts->gprs.nsvc[0].remote_ip));
 | 
					 | 
				
			||||||
	patch_16(nanobts_attr_nsvc0 + 14,
 | 
					 | 
				
			||||||
			htons(bts->gprs.nsvc[0].local_port));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* patch BVCI */
 | 
					 | 
				
			||||||
	nanobts_attr_cell[12] = bts->gprs.cell.bvci >> 8;
 | 
					 | 
				
			||||||
	nanobts_attr_cell[13] = bts->gprs.cell.bvci & 0xff;
 | 
					 | 
				
			||||||
	/* patch RAC */
 | 
					 | 
				
			||||||
	nanobts_attr_cell[3] = bts->gprs.rac;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (bts->gprs.mode == BTS_GPRS_EGPRS) {
 | 
					 | 
				
			||||||
		/* patch EGPRS coding schemes MCS 1..9 */
 | 
					 | 
				
			||||||
		nanobts_attr_cell[29] = 0x8f;
 | 
					 | 
				
			||||||
		nanobts_attr_cell[30] = 0xff;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Produce a MA as specified in 10.5.2.21 */
 | 
					 | 
				
			||||||
static int generate_ma_for_ts(struct gsm_bts_trx_ts *ts)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* we have three bitvecs: the per-timeslot ARFCNs, the cell chan ARFCNs
 | 
					 | 
				
			||||||
	 * and the MA */
 | 
					 | 
				
			||||||
	struct bitvec *cell_chan = &ts->trx->bts->si_common.cell_alloc;
 | 
					 | 
				
			||||||
	struct bitvec *ts_arfcn = &ts->hopping.arfcns;
 | 
					 | 
				
			||||||
	struct bitvec *ma = &ts->hopping.ma;
 | 
					 | 
				
			||||||
	unsigned int num_cell_arfcns, bitnum, n_chan;
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* re-set the MA to all-zero */
 | 
					 | 
				
			||||||
	ma->cur_bit = 0;
 | 
					 | 
				
			||||||
	ts->hopping.ma_len = 0;
 | 
					 | 
				
			||||||
	memset(ma->data, 0, ma->data_len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!ts->hopping.enabled)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* count the number of ARFCNs in the cell channel allocation */
 | 
					 | 
				
			||||||
	num_cell_arfcns = 0;
 | 
					 | 
				
			||||||
	for (i = 1; i < 1024; i++) {
 | 
					 | 
				
			||||||
		if (bitvec_get_bit_pos(cell_chan, i))
 | 
					 | 
				
			||||||
			num_cell_arfcns++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* pad it to octet-aligned number of bits */
 | 
					 | 
				
			||||||
	ts->hopping.ma_len = num_cell_arfcns / 8;
 | 
					 | 
				
			||||||
	if (num_cell_arfcns % 8)
 | 
					 | 
				
			||||||
		ts->hopping.ma_len++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	n_chan = 0;
 | 
					 | 
				
			||||||
	for (i = 1; i < 1024; i++) {
 | 
					 | 
				
			||||||
		if (!bitvec_get_bit_pos(cell_chan, i))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		/* set the corresponding bit in the MA */
 | 
					 | 
				
			||||||
		bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
 | 
					 | 
				
			||||||
		if (bitvec_get_bit_pos(ts_arfcn, i))
 | 
					 | 
				
			||||||
			bitvec_set_bit_pos(ma, bitnum, 1);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			bitvec_set_bit_pos(ma, bitnum, 0);
 | 
					 | 
				
			||||||
		n_chan++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* ARFCN 0 is special: It is coded last in the bitmask */
 | 
					 | 
				
			||||||
	if (bitvec_get_bit_pos(cell_chan, 0)) {
 | 
					 | 
				
			||||||
		n_chan++;
 | 
					 | 
				
			||||||
		/* set the corresponding bit in the MA */
 | 
					 | 
				
			||||||
		bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
 | 
					 | 
				
			||||||
		if (bitvec_get_bit_pos(ts_arfcn, 0))
 | 
					 | 
				
			||||||
			bitvec_set_bit_pos(ma, bitnum, 1);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			bitvec_set_bit_pos(ma, bitnum, 0);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bootstrap_rsl(struct gsm_bts_trx *trx)
 | 
					static void bootstrap_rsl(struct gsm_bts_trx *trx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
 | 
						LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
 | 
				
			||||||
		"on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u TSC=%u\n",
 | 
							"using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
 | 
				
			||||||
		trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
 | 
							trx->bts->nr, trx->nr, bsc_gsmnet->country_code,
 | 
				
			||||||
		bsc_gsmnet->network_code, trx->bts->location_area_code,
 | 
							bsc_gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
 | 
				
			||||||
		trx->bts->cell_identity, trx->bts->bsic, trx->bts->tsc);
 | 
					 | 
				
			||||||
	set_system_infos(trx);
 | 
						set_system_infos(trx);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
 | 
					 | 
				
			||||||
		generate_ma_for_ts(&trx->ts[i]);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
 | 
					void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ts_no, lchan_no;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (event) {
 | 
						switch (event) {
 | 
				
			||||||
	case EVT_E1_TEI_UP:
 | 
						case EVT_E1_TEI_UP:
 | 
				
			||||||
		switch (type) {
 | 
							switch (type) {
 | 
				
			||||||
@@ -1041,35 +778,8 @@ void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case EVT_E1_TEI_DN:
 | 
						case EVT_E1_TEI_DN:
 | 
				
			||||||
		LOGP(DMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", type, trx);
 | 
							LOGP(DMI, LOGL_NOTICE, "Lost some E1 TEI link\n");
 | 
				
			||||||
 | 
							/* FIXME: deal with TEI or L1 link loss */
 | 
				
			||||||
		if (type == E1INP_SIGN_OML)
 | 
					 | 
				
			||||||
			counter_inc(trx->bts->network->stats.bts.oml_fail);
 | 
					 | 
				
			||||||
		else if (type == E1INP_SIGN_RSL)
 | 
					 | 
				
			||||||
			counter_inc(trx->bts->network->stats.bts.rsl_fail);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * free all allocated channels. change the nm_state so the
 | 
					 | 
				
			||||||
		 * trx and trx_ts becomes unusable and chan_alloc.c can not
 | 
					 | 
				
			||||||
		 * allocate from it.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		for (ts_no = 0; ts_no < ARRAY_SIZE(trx->ts); ++ts_no) {
 | 
					 | 
				
			||||||
			struct gsm_bts_trx_ts *ts = &trx->ts[ts_no];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			for (lchan_no = 0; lchan_no < ARRAY_SIZE(ts->lchan); ++lchan_no) {
 | 
					 | 
				
			||||||
				if (ts->lchan[lchan_no].state != GSM_LCHAN_NONE)
 | 
					 | 
				
			||||||
					lchan_free(&ts->lchan[lchan_no]);
 | 
					 | 
				
			||||||
				lchan_reset(&ts->lchan[lchan_no]);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			ts->nm_state.operational = 0;
 | 
					 | 
				
			||||||
			ts->nm_state.availability = 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		trx->nm_state.operational = 0;
 | 
					 | 
				
			||||||
		trx->nm_state.availability = 0;
 | 
					 | 
				
			||||||
		trx->bb_transc.nm_state.operational = 0;
 | 
					 | 
				
			||||||
		trx->bb_transc.nm_state.availability = 0;
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
@@ -1078,10 +788,6 @@ void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static int bootstrap_bts(struct gsm_bts *bts)
 | 
					static int bootstrap_bts(struct gsm_bts *bts)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, n;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* FIXME: What about secondary TRX of a BTS?  What about a BTS that has TRX
 | 
					 | 
				
			||||||
	 * in different bands? Why is 'band' a parameter of the BTS and not of the TRX? */
 | 
					 | 
				
			||||||
	switch (bts->band) {
 | 
						switch (bts->band) {
 | 
				
			||||||
	case GSM_BAND_1800:
 | 
						case GSM_BAND_1800:
 | 
				
			||||||
		if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
 | 
							if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
 | 
				
			||||||
@@ -1096,16 +802,8 @@ static int bootstrap_bts(struct gsm_bts *bts)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case GSM_BAND_900:
 | 
						case GSM_BAND_900:
 | 
				
			||||||
		if (bts->c0->arfcn < 1 ||
 | 
							if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
 | 
				
			||||||
		   (bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
 | 
								LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124.\n");
 | 
				
			||||||
		    bts->c0->arfcn > 1023)  {
 | 
					 | 
				
			||||||
			LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n");
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case GSM_BAND_850:
 | 
					 | 
				
			||||||
		if (bts->c0->arfcn < 128 || bts->c0->arfcn > 251) {
 | 
					 | 
				
			||||||
			LOGP(DNM, LOGL_ERROR, "GSM850 channel must be between 128-251.\n");
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
@@ -1124,35 +822,16 @@ static int bootstrap_bts(struct gsm_bts *bts)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Control Channel Description */
 | 
						/* Control Channel Description */
 | 
				
			||||||
	bts->si_common.chan_desc.att = 1;
 | 
						bts->si_common.chan_desc.att = 1;
 | 
				
			||||||
 | 
						bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
 | 
				
			||||||
	bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
 | 
						bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
 | 
				
			||||||
	/* T3212 is set from vty/config */
 | 
						/* T3212 is set from vty/config */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set ccch config by looking at ts config */
 | 
					 | 
				
			||||||
	for (n=0, i=0; i<8; i++)
 | 
					 | 
				
			||||||
		n += bts->c0->ts[i].pchan == GSM_PCHAN_CCCH ? 1 : 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (n) {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_NC;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case 2:
 | 
					 | 
				
			||||||
		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_2_NC;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case 3:
 | 
					 | 
				
			||||||
		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_3_NC;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case 4:
 | 
					 | 
				
			||||||
		bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_4_NC;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		LOGP(DNM, LOGL_ERROR, "Unsupported CCCH timeslot configuration\n");
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* some defaults for our system information */
 | 
						/* some defaults for our system information */
 | 
				
			||||||
 | 
						bts->si_common.rach_control.re = 1; /* no re-establishment */
 | 
				
			||||||
 | 
						bts->si_common.rach_control.tx_integer = 5; /* 8 slots spread */
 | 
				
			||||||
 | 
						bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */
 | 
				
			||||||
 | 
						bts->si_common.rach_control.t2 = 4; /* no emergency calls */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */
 | 
						bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */
 | 
				
			||||||
	bts->si_common.cell_options.dtx = 2; /* MS shall not use upplink DTX */
 | 
						bts->si_common.cell_options.dtx = 2; /* MS shall not use upplink DTX */
 | 
				
			||||||
	bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
 | 
						bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
 | 
				
			||||||
@@ -1169,7 +848,6 @@ static int bootstrap_bts(struct gsm_bts *bts)
 | 
				
			|||||||
int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
 | 
					int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
 | 
				
			||||||
			  const char *config_file)
 | 
								  const char *config_file)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct telnet_connection dummy_conn;
 | 
					 | 
				
			||||||
	struct gsm_bts *bts;
 | 
						struct gsm_bts *bts;
 | 
				
			||||||
	int rc;
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1181,18 +859,13 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
 | 
				
			|||||||
	bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
 | 
						bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
 | 
				
			||||||
	bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
 | 
						bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* our vty command code expects vty->priv to point to a telnet_connection */
 | 
						telnet_init(bsc_gsmnet, 4242);
 | 
				
			||||||
	dummy_conn.priv = bsc_gsmnet;
 | 
						rc = vty_read_config_file(config_file);
 | 
				
			||||||
	rc = vty_read_config_file(config_file, &dummy_conn);
 | 
					 | 
				
			||||||
	if (rc < 0) {
 | 
						if (rc < 0) {
 | 
				
			||||||
		LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
 | 
							LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
 | 
				
			||||||
		return rc;
 | 
							return rc;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = telnet_init(tall_bsc_ctx, bsc_gsmnet, 4242);
 | 
					 | 
				
			||||||
	if (rc < 0)
 | 
					 | 
				
			||||||
		return rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	register_signal_handler(SS_NM, nm_sig_cb, NULL);
 | 
						register_signal_handler(SS_NM, nm_sig_cb, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
 | 
						llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1237
									
								
								openbsc/src/bsc_mgcp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1237
									
								
								openbsc/src/bsc_mgcp.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,7 +1,7 @@
 | 
				
			|||||||
/* Routines to talk to the MSC using the IPA Protocol */
 | 
					/* Routines to talk to the MSC using the IPA Protocol */
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
					 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 * (C) 2010 by On-Waves
 | 
					 * (C) 2010 by on-waves.com
 | 
				
			||||||
 * All Rights Reserved
 | 
					 * All Rights Reserved
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This program is free software; you can redistribute it and/or modify
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
@@ -21,138 +21,23 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <openbsc/bsc_msc.h>
 | 
					#include <openbsc/bsc_msc.h>
 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					 | 
				
			||||||
#include <openbsc/ipaccess.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <osmocore/write_queue.h>
 | 
					 | 
				
			||||||
#include <osmocore/talloc.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <errno.h>
 | 
					 | 
				
			||||||
#include <fcntl.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void connection_loss(struct bsc_msc_connection *con)
 | 
					int connect_to_msc(struct bsc_fd *fd, const char *ip, int port)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct bsc_fd *fd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fd = &con->write_queue.bfd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	close(fd->fd);
 | 
					 | 
				
			||||||
	fd->fd = -1;
 | 
					 | 
				
			||||||
	fd->cb = write_queue_bfd_cb;
 | 
					 | 
				
			||||||
	fd->when = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	con->is_connected = 0;
 | 
					 | 
				
			||||||
	con->first_contact = 0;
 | 
					 | 
				
			||||||
	con->connection_loss(con);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void msc_con_timeout(void *_con)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bsc_msc_connection *con = _con;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	LOGP(DMSC, LOGL_ERROR, "MSC Connection timeout.\n");
 | 
					 | 
				
			||||||
	bsc_msc_lost(con);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int bsc_msc_except(struct bsc_fd *bfd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct write_queue *wrt;
 | 
					 | 
				
			||||||
	struct bsc_msc_connection *con;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	LOGP(DMSC, LOGL_ERROR, "Exception on the BFD. Closing down.\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wrt = container_of(bfd, struct write_queue, bfd);
 | 
					 | 
				
			||||||
	con = container_of(wrt, struct bsc_msc_connection, write_queue);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	connection_loss(con);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* called in the case of a non blocking connect */
 | 
					 | 
				
			||||||
static int msc_connection_connect(struct bsc_fd *fd, unsigned int what)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
	int val;
 | 
					 | 
				
			||||||
	struct bsc_msc_connection *con;
 | 
					 | 
				
			||||||
	struct write_queue *queue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	socklen_t len = sizeof(val);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((what & BSC_FD_WRITE) == 0) {
 | 
					 | 
				
			||||||
		LOGP(DMSC, LOGL_ERROR, "Callback but not readable.\n");
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	queue = container_of(fd, struct write_queue, bfd);
 | 
					 | 
				
			||||||
	con = container_of(queue, struct bsc_msc_connection, write_queue);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* check the socket state */
 | 
					 | 
				
			||||||
	rc = getsockopt(fd->fd, SOL_SOCKET, SO_ERROR, &val, &len);
 | 
					 | 
				
			||||||
	if (rc != 0) {
 | 
					 | 
				
			||||||
		LOGP(DMSC, LOGL_ERROR, "getsockopt for the MSC socket failed.\n");
 | 
					 | 
				
			||||||
		goto error;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (val != 0) {
 | 
					 | 
				
			||||||
		LOGP(DMSC, LOGL_ERROR, "Not connected to the MSC: %d\n", val);
 | 
					 | 
				
			||||||
		goto error;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* go to full operation */
 | 
					 | 
				
			||||||
	fd->cb = write_queue_bfd_cb;
 | 
					 | 
				
			||||||
	fd->when = BSC_FD_READ | BSC_FD_EXCEPT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	con->is_connected = 1;
 | 
					 | 
				
			||||||
	bsc_del_timer(&con->timeout_timer);
 | 
					 | 
				
			||||||
	LOGP(DMSC, LOGL_NOTICE, "(Re)Connected to the MSC.\n");
 | 
					 | 
				
			||||||
	if (con->connected)
 | 
					 | 
				
			||||||
		con->connected(con);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
error:
 | 
					 | 
				
			||||||
	bsc_unregister_fd(fd);
 | 
					 | 
				
			||||||
	connection_loss(con);
 | 
					 | 
				
			||||||
	return -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static void setnonblocking(struct bsc_fd *fd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int flags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	flags = fcntl(fd->fd, F_GETFL);
 | 
					 | 
				
			||||||
	if (flags < 0) {
 | 
					 | 
				
			||||||
		perror("fcntl get failed");
 | 
					 | 
				
			||||||
		close(fd->fd);
 | 
					 | 
				
			||||||
		fd->fd = -1;
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	flags |= O_NONBLOCK;
 | 
					 | 
				
			||||||
	flags = fcntl(fd->fd, F_SETFL, flags);
 | 
					 | 
				
			||||||
	if (flags < 0) {
 | 
					 | 
				
			||||||
		perror("fcntl get failed");
 | 
					 | 
				
			||||||
		close(fd->fd);
 | 
					 | 
				
			||||||
		fd->fd = -1;
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int bsc_msc_connect(struct bsc_msc_connection *con)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bsc_fd *fd;
 | 
					 | 
				
			||||||
	struct sockaddr_in sin;
 | 
						struct sockaddr_in sin;
 | 
				
			||||||
	int on = 1, ret;
 | 
						int on = 1, ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	LOGP(DMSC, LOGL_NOTICE, "Attempting to connect MSC at %s:%d\n", con->ip, con->port);
 | 
						printf("Attempting to connect MSC at %s:%d\n", ip, port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	con->is_connected = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fd = &con->write_queue.bfd;
 | 
					 | 
				
			||||||
	fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 | 
						fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 | 
				
			||||||
 | 
						fd->when = BSC_FD_READ;
 | 
				
			||||||
 | 
						fd->data = NULL;
 | 
				
			||||||
	fd->priv_nr = 1;
 | 
						fd->priv_nr = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fd->fd < 0) {
 | 
						if (fd->fd < 0) {
 | 
				
			||||||
@@ -160,41 +45,18 @@ int bsc_msc_connect(struct bsc_msc_connection *con)
 | 
				
			|||||||
		return fd->fd;
 | 
							return fd->fd;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* make it non blocking */
 | 
					 | 
				
			||||||
	setnonblocking(fd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* set the socket priority */
 | 
					 | 
				
			||||||
	ret = setsockopt(fd->fd, IPPROTO_IP, IP_TOS,
 | 
					 | 
				
			||||||
			 &con->prio, sizeof(con->prio));
 | 
					 | 
				
			||||||
	if (ret != 0)
 | 
					 | 
				
			||||||
		LOGP(DMSC, LOGL_ERROR, "Failed to set prio to %d. %s\n",
 | 
					 | 
				
			||||||
		     con->prio, strerror(errno));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&sin, 0, sizeof(sin));
 | 
						memset(&sin, 0, sizeof(sin));
 | 
				
			||||||
	sin.sin_family = AF_INET;
 | 
						sin.sin_family = AF_INET;
 | 
				
			||||||
	sin.sin_port = htons(con->port);
 | 
						sin.sin_port = htons(port);
 | 
				
			||||||
	inet_aton(con->ip, &sin.sin_addr);
 | 
					        inet_aton(ip, &sin.sin_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
 | 
						setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
 | 
				
			||||||
	ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));
 | 
						ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret == -1 && errno == EINPROGRESS) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		LOGP(DMSC, LOGL_ERROR, "MSC Connection in progress\n");
 | 
					 | 
				
			||||||
		fd->when = BSC_FD_WRITE;
 | 
					 | 
				
			||||||
		fd->cb = msc_connection_connect;
 | 
					 | 
				
			||||||
		con->timeout_timer.cb = msc_con_timeout;
 | 
					 | 
				
			||||||
		con->timeout_timer.data = con;
 | 
					 | 
				
			||||||
		bsc_schedule_timer(&con->timeout_timer, 20, 0);
 | 
					 | 
				
			||||||
	} else if (ret < 0) {
 | 
					 | 
				
			||||||
		perror("Connection failed");
 | 
							perror("Connection failed");
 | 
				
			||||||
		connection_loss(con);
 | 
					 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		fd->when = BSC_FD_READ | BSC_FD_EXCEPT;
 | 
					 | 
				
			||||||
		fd->cb = write_queue_bfd_cb;
 | 
					 | 
				
			||||||
		con->is_connected = 1;
 | 
					 | 
				
			||||||
		if (con->connected)
 | 
					 | 
				
			||||||
			con->connected(con);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = bsc_register_fd(fd);
 | 
						ret = bsc_register_fd(fd);
 | 
				
			||||||
@@ -207,64 +69,4 @@ int bsc_msc_connect(struct bsc_msc_connection *con)
 | 
				
			|||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct bsc_msc_connection *bsc_msc_create(const char *ip, int port, int prio)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bsc_msc_connection *con;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	con = talloc_zero(NULL, struct bsc_msc_connection);
 | 
					 | 
				
			||||||
	if (!con) {
 | 
					 | 
				
			||||||
		LOGP(DMSC, LOGL_FATAL, "Failed to create the MSC connection.\n");
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	con->ip = ip;
 | 
					 | 
				
			||||||
	con->port = port;
 | 
					 | 
				
			||||||
	con->prio = prio;
 | 
					 | 
				
			||||||
	write_queue_init(&con->write_queue, 100);
 | 
					 | 
				
			||||||
	con->write_queue.except_cb = bsc_msc_except;
 | 
					 | 
				
			||||||
	return con;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void bsc_msc_lost(struct bsc_msc_connection *con)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	write_queue_clear(&con->write_queue);
 | 
					 | 
				
			||||||
	bsc_unregister_fd(&con->write_queue.bfd);
 | 
					 | 
				
			||||||
	connection_loss(con);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void reconnect_msc(void *_msc)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bsc_msc_connection *con = _msc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	LOGP(DMSC, LOGL_NOTICE, "Attempting to reconnect to the MSC.\n");
 | 
					 | 
				
			||||||
	bsc_msc_connect(con);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void bsc_msc_schedule_connect(struct bsc_msc_connection *con)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	LOGP(DMSC, LOGL_NOTICE, "Attempting to reconnect to the MSC.\n");
 | 
					 | 
				
			||||||
	con->reconnect_timer.cb = reconnect_msc;
 | 
					 | 
				
			||||||
	con->reconnect_timer.data = con;
 | 
					 | 
				
			||||||
	bsc_schedule_timer(&con->reconnect_timer, 5, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct msgb *bsc_msc_id_get_resp(const char *token)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct msgb *msg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!token) {
 | 
					 | 
				
			||||||
		LOGP(DMSC, LOGL_ERROR, "No token specified.\n");
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msg = msgb_alloc_headroom(4096, 128, "id resp");
 | 
					 | 
				
			||||||
	if (!msg) {
 | 
					 | 
				
			||||||
		LOGP(DMSC, LOGL_ERROR, "Failed to create the message.\n");
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msg->l2h = msgb_v_put(msg, IPAC_MSGT_ID_RESP);
 | 
					 | 
				
			||||||
	msgb_l16tv_put(msg, strlen(token) + 1,
 | 
					 | 
				
			||||||
			IPAC_IDTAG_UNITNAME, (u_int8_t *) token);
 | 
					 | 
				
			||||||
	return msg;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										809
									
								
								openbsc/src/bsc_msc_ip.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										809
									
								
								openbsc/src/bsc_msc_ip.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,809 @@
 | 
				
			|||||||
 | 
					/* A hackish minimal BSC (+MSC +HLR) implementation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
 | 
				
			||||||
 | 
					 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
				
			||||||
 | 
					 * (C) 2009 by on-waves.com
 | 
				
			||||||
 | 
					 * All Rights Reserved
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _GNU_SOURCE
 | 
				
			||||||
 | 
					#include <getopt.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openbsc/select.h>
 | 
				
			||||||
 | 
					#include <openbsc/debug.h>
 | 
				
			||||||
 | 
					#include <openbsc/e1_input.h>
 | 
				
			||||||
 | 
					#include <openbsc/talloc.h>
 | 
				
			||||||
 | 
					#include <openbsc/select.h>
 | 
				
			||||||
 | 
					#include <openbsc/ipaccess.h>
 | 
				
			||||||
 | 
					#include <openbsc/bssap.h>
 | 
				
			||||||
 | 
					#include <openbsc/paging.h>
 | 
				
			||||||
 | 
					#include <openbsc/signal.h>
 | 
				
			||||||
 | 
					#include <openbsc/chan_alloc.h>
 | 
				
			||||||
 | 
					#include <openbsc/bsc_msc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sccp/sccp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* SCCP helper */
 | 
				
			||||||
 | 
					#define SCCP_IT_TIMER 60
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* MCC and MNC for the Location Area Identifier */
 | 
				
			||||||
 | 
					struct gsm_network *bsc_gsmnet = 0;
 | 
				
			||||||
 | 
					static const char *config_file = "openbsc.cfg";
 | 
				
			||||||
 | 
					static char *msc_address = "127.0.0.1";
 | 
				
			||||||
 | 
					static struct bsc_fd msc_connection;
 | 
				
			||||||
 | 
					static struct in_addr local_addr;
 | 
				
			||||||
 | 
					extern int ipacc_rtp_direct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, int, void *), const char *cfg_file);
 | 
				
			||||||
 | 
					extern int bsc_shutdown_net(struct gsm_network *net);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bss_sccp_connection_data *bss_sccp_create_data()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bss_sccp_connection_data *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data = _talloc_zero(tall_bsc_ctx,
 | 
				
			||||||
 | 
								    sizeof(struct bss_sccp_connection_data),
 | 
				
			||||||
 | 
								    "bsc<->msc");
 | 
				
			||||||
 | 
						if (!data)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						INIT_LLIST_HEAD(&data->sccp_queue);
 | 
				
			||||||
 | 
						INIT_LLIST_HEAD(&data->gsm_queue);
 | 
				
			||||||
 | 
						return data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bss_sccp_free_data(struct bss_sccp_connection_data *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bsc_del_timer(&data->T10);
 | 
				
			||||||
 | 
						bsc_del_timer(&data->sccp_it);
 | 
				
			||||||
 | 
						bsc_free_queued(data->sccp);
 | 
				
			||||||
 | 
						bts_free_queued(data);
 | 
				
			||||||
 | 
						talloc_free(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void sccp_it_fired(void *_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bss_sccp_connection_data *data =
 | 
				
			||||||
 | 
							(struct bss_sccp_connection_data *) _data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sccp_connection_send_it(data->sccp);
 | 
				
			||||||
 | 
						bsc_schedule_timer(&data->sccp_it, SCCP_IT_TIMER, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GSM subscriber drop-ins */
 | 
				
			||||||
 | 
					extern struct llist_head *subscr_bsc_active_subscriber(void);
 | 
				
			||||||
 | 
					struct gsm_subscriber *find_subscriber(u_int8_t type, const char *mi_string)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gsm_subscriber *subscr;
 | 
				
			||||||
 | 
						u_int32_t tmsi = GSM_RESERVED_TMSI;
 | 
				
			||||||
 | 
						if (type == GSM_MI_TYPE_TMSI) {
 | 
				
			||||||
 | 
							tmsi = tmsi_from_string(mi_string);
 | 
				
			||||||
 | 
							if (tmsi == GSM_RESERVED_TMSI) {
 | 
				
			||||||
 | 
								DEBUGP(DMSC, "The TMSI is the reserved one.\n");
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						llist_for_each_entry(subscr, subscr_bsc_active_subscriber(), entry) {
 | 
				
			||||||
 | 
							if (type == GSM_MI_TYPE_TMSI && tmsi == subscr->tmsi) {
 | 
				
			||||||
 | 
								return subscr_get(subscr);
 | 
				
			||||||
 | 
							} else if (type == GSM_MI_TYPE_IMSI && strcmp(mi_string, subscr->imsi) == 0) {
 | 
				
			||||||
 | 
								return subscr_get(subscr);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "No subscriber has been found.\n");
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* SCCP handling */
 | 
				
			||||||
 | 
					void msc_outgoing_sccp_data(struct sccp_connection *conn, struct msgb *msg, unsigned int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bssmap_header *bs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len < 1) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "The header is too short.\n");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (msg->l3h[0]) {
 | 
				
			||||||
 | 
						case BSSAP_MSG_BSS_MANAGEMENT:
 | 
				
			||||||
 | 
							msg->l4h = &msg->l3h[sizeof(*bs)];
 | 
				
			||||||
 | 
							msg->lchan = sccp_get_lchan(conn->data_ctx);
 | 
				
			||||||
 | 
							bssmap_rcvmsg_dt1(conn, msg, len - sizeof(*bs));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case BSSAP_MSG_DTAP:
 | 
				
			||||||
 | 
							dtap_rcvmsg(sccp_get_lchan(conn->data_ctx), msg, len);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							DEBUGPC(DMSC, "Unimplemented msg type: %d\n", msg->l3h[0]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "Freeing sccp conn: %p state: %d\n", conn, conn->connection_state);
 | 
				
			||||||
 | 
							if (sccp_get_lchan(conn->data_ctx) != NULL) {
 | 
				
			||||||
 | 
								struct gsm_lchan *lchan = sccp_get_lchan(conn->data_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								DEBUGP(DMSC, "ERROR: The lchan is still associated\n.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								lchan->msc_data = NULL;
 | 
				
			||||||
 | 
								put_lchan(lchan);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bss_sccp_free_data((struct bss_sccp_connection_data *)conn->data_ctx);
 | 
				
			||||||
 | 
							sccp_connection_free(conn);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						} else if (conn->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED) {
 | 
				
			||||||
 | 
							struct bss_sccp_connection_data *con_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "Connection established: %p\n", conn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* start the inactivity test timer */
 | 
				
			||||||
 | 
							con_data = (struct bss_sccp_connection_data *) conn->data_ctx;
 | 
				
			||||||
 | 
							con_data->sccp_it.cb = sccp_it_fired;
 | 
				
			||||||
 | 
							con_data->sccp_it.data = con_data;
 | 
				
			||||||
 | 
							bsc_schedule_timer(&con_data->sccp_it, SCCP_IT_TIMER, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bsc_send_queued(conn);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * General COMPLETE LAYER3 INFORMATION handling for
 | 
				
			||||||
 | 
					 * PAGING RESPONSE, LOCATION UPDATING REQUEST, CM REESTABLISHMENT REQUEST,
 | 
				
			||||||
 | 
					 * CM SERVICE REQUEST, IMSI DETACH, IMMEDIATE SETUP.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * IMMEDIATE SETUP is coming from GROUP CC that is not yet
 | 
				
			||||||
 | 
					 * supported...
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int open_sccp_connection(struct msgb *layer3)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bss_sccp_connection_data *con_data;
 | 
				
			||||||
 | 
						struct sccp_connection *sccp_connection;
 | 
				
			||||||
 | 
						struct msgb *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "Opening new layer3 connection\n");
 | 
				
			||||||
 | 
						sccp_connection = sccp_connection_socket();
 | 
				
			||||||
 | 
						if (!sccp_connection) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "Failed to allocate memory.\n");
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data = bssmap_create_layer3(layer3);
 | 
				
			||||||
 | 
						if (!data) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "Failed to allocate complete layer3.\n");
 | 
				
			||||||
 | 
							sccp_connection_free(sccp_connection);
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						con_data = bss_sccp_create_data();
 | 
				
			||||||
 | 
						if (!con_data) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "Failed to allocate bss<->msc data.\n");
 | 
				
			||||||
 | 
							sccp_connection_free(sccp_connection);
 | 
				
			||||||
 | 
							msgb_free(data);
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* initialize the bridge */
 | 
				
			||||||
 | 
						con_data->lchan = layer3->lchan;
 | 
				
			||||||
 | 
						con_data->sccp = sccp_connection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sccp_connection->state_cb = msc_outgoing_sccp_state;
 | 
				
			||||||
 | 
						sccp_connection->data_cb = msc_outgoing_sccp_data;
 | 
				
			||||||
 | 
						sccp_connection->data_ctx = con_data;
 | 
				
			||||||
 | 
						layer3->lchan->msc_data = con_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* FIXME: Use transaction for this */
 | 
				
			||||||
 | 
						use_lchan(layer3->lchan);
 | 
				
			||||||
 | 
						sccp_connection_connect(sccp_connection, &sccp_ssn_bssap, data);
 | 
				
			||||||
 | 
						msgb_free(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* figure out if this is the inial layer3 message */
 | 
				
			||||||
 | 
					static int send_dtap_or_open_connection(struct msgb *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (msg->lchan->msc_data) {
 | 
				
			||||||
 | 
							struct msgb *dtap = dtap_create_msg(msg, 0);
 | 
				
			||||||
 | 
							if (!dtap) {
 | 
				
			||||||
 | 
								DEBUGP(DMSC, "Creating a DTAP message failed.\n");
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bsc_queue_connection_write(lchan_get_sccp(msg->lchan), dtap);
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return open_sccp_connection(msg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Receive a PAGING RESPONSE message from the MS */
 | 
				
			||||||
 | 
					static int handle_paging_response(struct msgb *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gsm_subscriber *subscr;
 | 
				
			||||||
 | 
						char mi_string[GSM48_MI_SIZE];
 | 
				
			||||||
 | 
						u_int8_t mi_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gsm48_paging_extract_mi(msg, mi_string, &mi_type);
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n",
 | 
				
			||||||
 | 
							mi_type, mi_string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						subscr = find_subscriber(mi_type, mi_string);
 | 
				
			||||||
 | 
						if (!subscr)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* force the paging to stop at every bts */
 | 
				
			||||||
 | 
						subscr->lac = GSM_LAC_RESERVED_ALL_BTS;
 | 
				
			||||||
 | 
						if (gsm48_handle_paging_resp(msg, subscr) != 0) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "Paging failed.\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* open a new transaction and SCCP connection */
 | 
				
			||||||
 | 
						return send_dtap_or_open_connection(msg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Receive a CIPHER MODE COMPLETE from the MS */
 | 
				
			||||||
 | 
					static int handle_cipher_m_complete(struct msgb *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct msgb *resp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "CIPHER MODE COMPLETE from MS, forwarding to MSC\n");
 | 
				
			||||||
 | 
						resp = bssmap_create_cipher_complete(msg);
 | 
				
			||||||
 | 
						if (!resp) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "Creating MSC response failed.\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* handled this message */
 | 
				
			||||||
 | 
						bts_unblock_queue(msg->lchan->msc_data);
 | 
				
			||||||
 | 
						bsc_queue_connection_write(lchan_get_sccp(msg->lchan), resp);
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Receive a ASSIGNMENT COMPLETE */
 | 
				
			||||||
 | 
					static int handle_ass_compl(struct msgb *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gsm_lchan *old_chan;
 | 
				
			||||||
 | 
						struct gsm48_hdr *gh = msgb_l3(msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "ASSIGNMENT COMPLETE from MS, forwarding to MSC\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!msg->lchan->msc_data) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "No MSC data\n");
 | 
				
			||||||
 | 
							put_lchan(msg->lchan);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
 | 
				
			||||||
 | 
							LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
 | 
				
			||||||
 | 
							put_lchan(msg->lchan);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (msgb_l3len(msg) - sizeof(*gh) != 1) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "assignment failure invalid: %d\n",
 | 
				
			||||||
 | 
								msgb_l3len(msg) - sizeof(*gh));
 | 
				
			||||||
 | 
							put_lchan(msg->lchan);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* swap the channels and release the old */
 | 
				
			||||||
 | 
						old_chan = msg->lchan->msc_data->lchan;
 | 
				
			||||||
 | 
						msg->lchan->msc_data->lchan = msg->lchan;
 | 
				
			||||||
 | 
						msg->lchan->msc_data->secondary_lchan = NULL;
 | 
				
			||||||
 | 
						old_chan->msc_data = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* give up the old channel to not do a SACCH deactivate */
 | 
				
			||||||
 | 
						subscr_put(old_chan->subscr);
 | 
				
			||||||
 | 
						old_chan->subscr = NULL;
 | 
				
			||||||
 | 
						put_lchan(old_chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* activate audio on it... */
 | 
				
			||||||
 | 
						if (is_ipaccess_bts(msg->lchan->ts->trx->bts) && msg->lchan->tch_mode != GSM48_CMODE_SIGN)
 | 
				
			||||||
 | 
							rsl_ipacc_crcx(msg->lchan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gsm0808_send_assignment_compl(msg->lchan, gh->data[0]);
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Receive a ASSIGNMENT FAILURE. If the message is failed
 | 
				
			||||||
 | 
					 * to be parsed the T10 timer will send the failure.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int handle_ass_fail(struct msgb *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gsm48_hdr *gh = msgb_l3(msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "ASSIGNMENT FAILURE from MS, forwarding to MSC\n");
 | 
				
			||||||
 | 
						if (!msg->lchan->msc_data) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "No MSC data\n");
 | 
				
			||||||
 | 
							put_lchan(msg->lchan);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
 | 
				
			||||||
 | 
							LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
 | 
				
			||||||
 | 
							put_lchan(msg->lchan);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (msgb_l3len(msg) - sizeof(*gh) != 1) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "assignment failure invalid: %d\n",
 | 
				
			||||||
 | 
								msgb_l3len(msg) - sizeof(*gh));
 | 
				
			||||||
 | 
							put_lchan(msg->lchan);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gsm0808_send_assignment_failure(msg->lchan,
 | 
				
			||||||
 | 
							GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, &gh->data[0]);
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Receive a GSM04.08 MODIFY ACK. Actually we have to check
 | 
				
			||||||
 | 
					 * the content to see if this was a success or not.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int handle_modify_ack(struct msgb *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* modify RSL */
 | 
				
			||||||
 | 
						rc = gsm48_rx_rr_modif_ack(msg);
 | 
				
			||||||
 | 
						if (rc < 0)
 | 
				
			||||||
 | 
							gsm0808_send_assignment_failure(msg->lchan,
 | 
				
			||||||
 | 
								GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							gsm0808_send_assignment_compl(msg->lchan, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Receive a GSM 04.08 Radio Resource (RR) message */
 | 
				
			||||||
 | 
					static int gsm0408_rcv_rr(struct msgb *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gsm48_hdr *gh = msgb_l3(msg);
 | 
				
			||||||
 | 
						int rc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (gh->msg_type) {
 | 
				
			||||||
 | 
						case GSM48_MT_RR_PAG_RESP:
 | 
				
			||||||
 | 
							rc = handle_paging_response(msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case GSM48_MT_RR_MEAS_REP:
 | 
				
			||||||
 | 
							/* ignore measurement for now */
 | 
				
			||||||
 | 
							rc = -1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case GSM48_MT_RR_CIPH_M_COMPL:
 | 
				
			||||||
 | 
							rc = handle_cipher_m_complete(msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case GSM48_MT_RR_ASS_COMPL:
 | 
				
			||||||
 | 
							rc = handle_ass_compl(msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case GSM48_MT_RR_ASS_FAIL:
 | 
				
			||||||
 | 
							rc = handle_ass_fail(msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
 | 
				
			||||||
 | 
							rc = handle_modify_ack(msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Receive a GSM 04.08 Mobility Management (MM) message */
 | 
				
			||||||
 | 
					static int gsm0408_rcv_mm(struct msgb *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gsm48_hdr *gh = msgb_l3(msg);
 | 
				
			||||||
 | 
						int rc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (gh->msg_type & 0xbf) {
 | 
				
			||||||
 | 
						case GSM48_MT_MM_LOC_UPD_REQUEST:
 | 
				
			||||||
 | 
						case GSM48_MT_MM_CM_REEST_REQ:
 | 
				
			||||||
 | 
						case GSM48_MT_MM_CM_SERV_REQ:
 | 
				
			||||||
 | 
						case GSM48_MT_MM_IMSI_DETACH_IND:
 | 
				
			||||||
 | 
							rc = send_dtap_or_open_connection(msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gsm48_hdr *gh = msgb_l3(msg);
 | 
				
			||||||
 | 
						u_int8_t pdisc = gh->proto_discr & 0x0f;
 | 
				
			||||||
 | 
						int rc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (pdisc) {
 | 
				
			||||||
 | 
						case GSM48_PDISC_RR:
 | 
				
			||||||
 | 
							rc = gsm0408_rcv_rr(msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case GSM48_PDISC_MM:
 | 
				
			||||||
 | 
							rc = gsm0408_rcv_mm(msg);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * if we have a sccp connection and didn't handle the message
 | 
				
			||||||
 | 
						 * forward it to the MSC using DTAP
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (rc == 0 && msg->lchan->msc_data && lchan_get_sccp(msg->lchan)) {
 | 
				
			||||||
 | 
							struct msgb *dtap = dtap_create_msg(msg, link_id);
 | 
				
			||||||
 | 
							if (!dtap) {
 | 
				
			||||||
 | 
								DEBUGP(DMSC, "Creating a DTAP message failed.\n");
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bsc_queue_connection_write(lchan_get_sccp(msg->lchan), dtap);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* handle ipaccess signals */
 | 
				
			||||||
 | 
					static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
 | 
				
			||||||
 | 
									 void *handler_data, void *signal_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gsm_lchan *lchan = signal_data;
 | 
				
			||||||
 | 
						struct gsm_bts_trx_ts *ts;
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (subsys != SS_ABISIP)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ts = lchan->ts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (signal) {
 | 
				
			||||||
 | 
						case S_ABISIP_CRCX_ACK:
 | 
				
			||||||
 | 
							/* we can ask it to connect now */
 | 
				
			||||||
 | 
							if (lchan->msc_data) {
 | 
				
			||||||
 | 
								DEBUGP(DMSC, "Connecting BTS to port: %d conn: %d\n",
 | 
				
			||||||
 | 
									lchan->msc_data->rtp_port, lchan->abis_ip.conn_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								int rtp_payload = ts->trx->bts->network->rtp_payload;
 | 
				
			||||||
 | 
								if (rtp_payload == 0)
 | 
				
			||||||
 | 
									rtp_payload = lchan->abis_ip.rtp_payload2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								rc = rsl_ipacc_mdcx(lchan, ntohl(local_addr.s_addr),
 | 
				
			||||||
 | 
										    lchan->msc_data->rtp_port,
 | 
				
			||||||
 | 
										    rtp_payload);
 | 
				
			||||||
 | 
								if (rc < 0) {
 | 
				
			||||||
 | 
									DEBUGP(DMSC, "Failed to send connect: %d\n", rc);
 | 
				
			||||||
 | 
									return rc;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case S_ABISIP_DLCX_IND:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_usage()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						printf("Usage: bsc_hack\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SCCP handling
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int msc_sccp_write_ipa(struct msgb *msg, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "Sending SCCP to MSC: %u\n", msgb_l2len(msg));
 | 
				
			||||||
 | 
						ipaccess_prepend_header(msg, IPAC_PROTO_SCCP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGP(DMI, "MSC TX %s\n", hexdump(msg->l2h, msgb_l2len(msg)));
 | 
				
			||||||
 | 
						ret = write(msc_connection.fd, msg->data, msg->len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret <= 0) {
 | 
				
			||||||
 | 
							perror("MSC: Failed to send SCCP");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int msc_sccp_accept(struct sccp_connection *connection, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "Rejecting incoming SCCP connection.\n");
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int msc_sccp_read(struct msgb *msgb, unsigned int length, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bssmap_header *bs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "Incoming SCCP message ftom MSC: %s\n", hexdump(msgb->l3h, length));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (length < sizeof(*bs)) {
 | 
				
			||||||
 | 
							DEBUGP(DMSC, "The header is too short.\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bs = (struct bssmap_header *) msgb->l3h;
 | 
				
			||||||
 | 
						if (bs->length < length - sizeof(*bs))
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (bs->type) {
 | 
				
			||||||
 | 
						case BSSAP_MSG_BSS_MANAGEMENT:
 | 
				
			||||||
 | 
							msgb->l4h = &msgb->l3h[sizeof(*bs)];
 | 
				
			||||||
 | 
							bssmap_rcvmsg_udt(bsc_gsmnet, msgb, length - sizeof(*bs));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							DEBUGPC(DMSC, "Unimplemented msg type: %d\n", bs->type);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * network initialisation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void initialize_if_needed(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!bsc_gsmnet) {
 | 
				
			||||||
 | 
							int rc;
 | 
				
			||||||
 | 
							struct msgb *msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fprintf(stderr, "Bootstraping the network. Sending GSM08.08 reset.\n");
 | 
				
			||||||
 | 
							rc = bsc_bootstrap_network(NULL, config_file);
 | 
				
			||||||
 | 
							if (rc < 0) {
 | 
				
			||||||
 | 
								fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
 | 
				
			||||||
 | 
								exit(1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* send a gsm 08.08 reset message from here */
 | 
				
			||||||
 | 
							msg = bssmap_create_reset();
 | 
				
			||||||
 | 
							if (!msg) {
 | 
				
			||||||
 | 
								DEBUGP(DMSC, "Failed to create the reset message.\n");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sccp_write(msg, &sccp_ssn_bssap, &sccp_ssn_bssap, 0);
 | 
				
			||||||
 | 
							msgb_free(msg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * callback with IP access data
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int ipaccess_a_fd_cb(struct bsc_fd *bfd, unsigned int what)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int error;
 | 
				
			||||||
 | 
						struct msgb *msg = ipaccess_read_msg(bfd, &error);
 | 
				
			||||||
 | 
						struct ipaccess_head *hh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!msg) {
 | 
				
			||||||
 | 
							if (error == 0) {
 | 
				
			||||||
 | 
								fprintf(stderr, "The connection to the MSC was lost, exiting\n");
 | 
				
			||||||
 | 
								exit(-2);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fprintf(stderr, "Failed to parse ip access message: %d\n", error);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUGP(DMSC, "From MSC: %s proto: %d\n", hexdump(msg->data, msg->len), msg->l2h[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* handle base message handling */
 | 
				
			||||||
 | 
						hh = (struct ipaccess_head *) msg->data;
 | 
				
			||||||
 | 
						ipaccess_rcvmsg_base(msg, bfd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* initialize the networking. This includes sending a GSM08.08 message */
 | 
				
			||||||
 | 
						if (hh->proto == IPAC_PROTO_IPACCESS && msg->l2h[0] == IPAC_MSGT_ID_ACK)
 | 
				
			||||||
 | 
							initialize_if_needed();
 | 
				
			||||||
 | 
						else if (hh->proto == IPAC_PROTO_SCCP)
 | 
				
			||||||
 | 
							sccp_system_incoming(msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msgb_free(msg);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_help()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						printf("  Some useful help...\n");
 | 
				
			||||||
 | 
						printf("  -h --help this text\n");
 | 
				
			||||||
 | 
						printf("  -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
 | 
				
			||||||
 | 
						printf("  -s --disable-color\n");
 | 
				
			||||||
 | 
						printf("  -c --config-file filename The config file to use.\n");
 | 
				
			||||||
 | 
						printf("  -m --msc=IP. The address of the MSC.\n");
 | 
				
			||||||
 | 
						printf("  -l --local=IP. The local address of the MGCP.\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_options(int argc, char** argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while (1) {
 | 
				
			||||||
 | 
							int option_index = 0, c;
 | 
				
			||||||
 | 
							static struct option long_options[] = {
 | 
				
			||||||
 | 
								{"help", 0, 0, 'h'},
 | 
				
			||||||
 | 
								{"debug", 1, 0, 'd'},
 | 
				
			||||||
 | 
								{"config-file", 1, 0, 'c'},
 | 
				
			||||||
 | 
								{"disable-color", 0, 0, 's'},
 | 
				
			||||||
 | 
								{"timestamp", 0, 0, 'T'},
 | 
				
			||||||
 | 
								{"rtp-proxy", 0, 0, 'P'},
 | 
				
			||||||
 | 
								{"msc", 1, 0, 'm'},
 | 
				
			||||||
 | 
								{"local", 1, 0, 'l'},
 | 
				
			||||||
 | 
								{0, 0, 0, 0}
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							c = getopt_long(argc, argv, "hd:sTPc:m:l:",
 | 
				
			||||||
 | 
									long_options, &option_index);
 | 
				
			||||||
 | 
							if (c == -1)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (c) {
 | 
				
			||||||
 | 
							case 'h':
 | 
				
			||||||
 | 
								print_usage();
 | 
				
			||||||
 | 
								print_help();
 | 
				
			||||||
 | 
								exit(0);
 | 
				
			||||||
 | 
							case 's':
 | 
				
			||||||
 | 
								debug_use_color(0);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'd':
 | 
				
			||||||
 | 
								debug_parse_category_mask(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'c':
 | 
				
			||||||
 | 
								config_file = strdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'T':
 | 
				
			||||||
 | 
								debug_timestamp(1);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'P':
 | 
				
			||||||
 | 
								ipacc_rtp_direct = 0;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'm':
 | 
				
			||||||
 | 
								msc_address = strdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'l':
 | 
				
			||||||
 | 
								inet_aton(optarg, &local_addr);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								/* ignore */
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void signal_handler(int signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						fprintf(stdout, "signal %u received\n", signal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (signal) {
 | 
				
			||||||
 | 
						case SIGINT:
 | 
				
			||||||
 | 
							bsc_shutdown_net(bsc_gsmnet);
 | 
				
			||||||
 | 
							sleep(3);
 | 
				
			||||||
 | 
							exit(0);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGABRT:
 | 
				
			||||||
 | 
							/* in case of abort, we want to obtain a talloc report
 | 
				
			||||||
 | 
							 * and then return to the caller, who will abort the process */
 | 
				
			||||||
 | 
						case SIGUSR1:
 | 
				
			||||||
 | 
							talloc_report_full(tall_bsc_ctx, stderr);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_mode()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const u_int8_t assignment_req[] = { 0x01, 0x0b, 0x03, 0x01, 0x0b, 0x25, 0x01, 0x00, 0x01 };
 | 
				
			||||||
 | 
						struct gsm_lchan lchan;
 | 
				
			||||||
 | 
						struct sccp_connection conn;
 | 
				
			||||||
 | 
						struct bss_sccp_connection_data data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct gsm_bts_trx_ts trx_ts;
 | 
				
			||||||
 | 
						struct gsm_bts_trx trx;
 | 
				
			||||||
 | 
						struct gsm_bts bts;
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* initialize */
 | 
				
			||||||
 | 
						fprintf(stderr, "Bootstraping the network. Sending GSM08.08 reset.\n");
 | 
				
			||||||
 | 
						rc = bsc_bootstrap_network(NULL, config_file);
 | 
				
			||||||
 | 
						if (rc < 0) {
 | 
				
			||||||
 | 
							fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
 | 
				
			||||||
 | 
							exit(1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bts.network = bsc_gsmnet;
 | 
				
			||||||
 | 
						trx.bts = &bts;
 | 
				
			||||||
 | 
						trx_ts.trx = &trx;
 | 
				
			||||||
 | 
						lchan.ts = &trx_ts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* create fake data connection */
 | 
				
			||||||
 | 
						data.lchan = &lchan;
 | 
				
			||||||
 | 
						data.sccp = &conn;
 | 
				
			||||||
 | 
						lchan.msc_data = &data;
 | 
				
			||||||
 | 
						conn.data_ctx = &data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct msgb *msg = msgb_alloc(400, "test-msg");
 | 
				
			||||||
 | 
						msg->lchan = &lchan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msg->l4h = msgb_put(msg, ARRAY_SIZE(assignment_req));
 | 
				
			||||||
 | 
						memcpy(msg->l4h, assignment_req, ARRAY_SIZE(assignment_req));
 | 
				
			||||||
 | 
						bssmap_rcvmsg_dt1(&conn, msg, ARRAY_SIZE(assignment_req));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* parse options */
 | 
				
			||||||
 | 
						handle_options(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* seed the PRNG */
 | 
				
			||||||
 | 
						srand(time(NULL));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* initialize sccp */
 | 
				
			||||||
 | 
						sccp_system_init(msc_sccp_write_ipa, NULL);
 | 
				
			||||||
 | 
						sccp_connection_set_incoming(&sccp_ssn_bssap, msc_sccp_accept, NULL);
 | 
				
			||||||
 | 
						sccp_set_read(&sccp_ssn_bssap, msc_sccp_read, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* initialize ipaccess handling */
 | 
				
			||||||
 | 
						register_signal_handler(SS_ABISIP, handle_abisip_signal, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msc_connection.cb = ipaccess_a_fd_cb;
 | 
				
			||||||
 | 
						rc = connect_to_msc(&msc_connection, msc_address, 5000);
 | 
				
			||||||
 | 
						if (rc < 0) {
 | 
				
			||||||
 | 
							fprintf(stderr, "Opening the MSC connection failed.\n");
 | 
				
			||||||
 | 
							exit(1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						signal(SIGINT, &signal_handler);
 | 
				
			||||||
 | 
						signal(SIGABRT, &signal_handler);
 | 
				
			||||||
 | 
						signal(SIGUSR1, &signal_handler);
 | 
				
			||||||
 | 
						signal(SIGPIPE, SIG_IGN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (1) {
 | 
				
			||||||
 | 
							bsc_select_main(0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -24,14 +24,13 @@
 | 
				
			|||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <openbsc/debug.h>
 | 
					#include <openbsc/debug.h>
 | 
				
			||||||
#include <osmocore/talloc.h>
 | 
					#include <openbsc/talloc.h>
 | 
				
			||||||
#include <osmocore/timer.h>
 | 
					#include <openbsc/timer.h>
 | 
				
			||||||
#include <osmocore/linuxlist.h>
 | 
					#include <openbsc/linuxlist.h>
 | 
				
			||||||
#include <openbsc/bsc_rll.h>
 | 
					#include <openbsc/bsc_rll.h>
 | 
				
			||||||
#include <openbsc/gsm_data.h>
 | 
					#include <openbsc/gsm_data.h>
 | 
				
			||||||
#include <openbsc/chan_alloc.h>
 | 
					#include <openbsc/chan_alloc.h>
 | 
				
			||||||
#include <openbsc/abis_rsl.h>
 | 
					#include <openbsc/abis_rsl.h>
 | 
				
			||||||
#include <openbsc/signal.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct bsc_rll_req {
 | 
					struct bsc_rll_req {
 | 
				
			||||||
	struct llist_head list;
 | 
						struct llist_head list;
 | 
				
			||||||
@@ -53,6 +52,7 @@ static LLIST_HEAD(bsc_rll_reqs);
 | 
				
			|||||||
static void complete_rllr(struct bsc_rll_req *rllr, enum bsc_rllr_ind type)
 | 
					static void complete_rllr(struct bsc_rll_req *rllr, enum bsc_rllr_ind type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	llist_del(&rllr->list);
 | 
						llist_del(&rllr->list);
 | 
				
			||||||
 | 
						put_lchan(rllr->lchan);
 | 
				
			||||||
	rllr->cb(rllr->lchan, rllr->link_id, rllr->data, type);
 | 
						rllr->cb(rllr->lchan, rllr->link_id, rllr->data, type);
 | 
				
			||||||
	talloc_free(rllr);
 | 
						talloc_free(rllr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -80,9 +80,11 @@ int rll_establish(struct gsm_lchan *lchan, u_int8_t sapi,
 | 
				
			|||||||
	/* If we are a TCH and not in signalling mode, we need to
 | 
						/* If we are a TCH and not in signalling mode, we need to
 | 
				
			||||||
	 * indicate that the new RLL connection is to be made on the SACCH */
 | 
						 * indicate that the new RLL connection is to be made on the SACCH */
 | 
				
			||||||
	if ((lchan->type == GSM_LCHAN_TCH_F ||
 | 
						if ((lchan->type == GSM_LCHAN_TCH_F ||
 | 
				
			||||||
	     lchan->type == GSM_LCHAN_TCH_H) && sapi != 0)
 | 
						     lchan->type == GSM_LCHAN_TCH_H) &&
 | 
				
			||||||
 | 
						    lchan->rsl_cmode != RSL_CMOD_SPD_SIGN)
 | 
				
			||||||
		link_id |= 0x40;
 | 
							link_id |= 0x40;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						use_lchan(lchan);
 | 
				
			||||||
	rllr->lchan = lchan;
 | 
						rllr->lchan = lchan;
 | 
				
			||||||
	rllr->link_id = link_id;
 | 
						rllr->link_id = link_id;
 | 
				
			||||||
	rllr->cb = cb;
 | 
						rllr->cb = cb;
 | 
				
			||||||
@@ -114,29 +116,3 @@ void rll_indication(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t type)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
static int rll_lchan_signal(unsigned int subsys, unsigned int signal,
 | 
					 | 
				
			||||||
			    void *handler_data, void *signal_data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct challoc_signal_data *challoc;
 | 
					 | 
				
			||||||
	struct bsc_rll_req *rllr, *rllr2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (subsys != SS_CHALLOC || signal != S_CHALLOC_FREED)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	challoc = (struct challoc_signal_data *) signal_data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	llist_for_each_entry_safe(rllr, rllr2, &bsc_rll_reqs, list) {
 | 
					 | 
				
			||||||
		if (rllr->lchan == challoc->lchan) {
 | 
					 | 
				
			||||||
			bsc_del_timer(&rllr->timer);
 | 
					 | 
				
			||||||
			complete_rllr(rllr, BSC_RLLR_IND_ERR_IND);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static __attribute__((constructor)) void on_dso_load_rll(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	register_signal_handler(SS_CHALLOC, rll_lchan_signal, NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user