mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-04 05:53:26 +00:00 
			
		
		
		
	Compare commits
	
		
			93 Commits
		
	
	
		
			1.0.1
			...
			on-waves/0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					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 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
debian/*.log
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
[gerrit]
 | 
			
		||||
host=gerrit.osmocom.org
 | 
			
		||||
project=openbsc
 | 
			
		||||
							
								
								
									
										12
									
								
								.mailmap
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								.mailmap
									
									
									
									
									
								
							@@ -1,12 +0,0 @@
 | 
			
		||||
Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
Harald Welte <laforge@gnumonks.org> <laflocal@hanuman.gnumonks.org>
 | 
			
		||||
Harald Welte <laforge@gnumonks.org> <laflocal@goeller.de.gnumonks.org>
 | 
			
		||||
Holger Hans Peter Freyther <holger@moiji-mobile.com> <zecke@selfish.org>
 | 
			
		||||
Holger Hans Peter Freyther <holger@moiji-mobile.com> <ich@tamarin.(none)>
 | 
			
		||||
Holger Hans Peter Freyther <holgre@moiji-mobile.com> <holger@freyther.de>
 | 
			
		||||
Andreas Eversberg <jolly@eversberg.eu>
 | 
			
		||||
Andreas Eversberg <jolly@eversberg.eu> <Andreas.Eversberg@versatel.de>
 | 
			
		||||
Andreas Eversberg <jolly@eversberg.eu> <root@nuedel.(none)>
 | 
			
		||||
Pablo Neira Ayuso <pablo@soleta.eu> <pablo@gnumonks.org>
 | 
			
		||||
Max Suraev <msuraev@sysmocom.de>
 | 
			
		||||
Tom Tsou <tom.tsou@ettus.com> <tom@tsou.cc>
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
set -ex
 | 
			
		||||
 | 
			
		||||
base="$PWD"
 | 
			
		||||
deps="$base/deps"
 | 
			
		||||
inst="$deps/install"
 | 
			
		||||
export deps inst
 | 
			
		||||
 | 
			
		||||
mkdir "$deps" || true
 | 
			
		||||
rm -rf "$inst"
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmocore "" ac_cv_path_DOXYGEN=false
 | 
			
		||||
 | 
			
		||||
"$deps"/libosmocore/contrib/verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]")
 | 
			
		||||
 | 
			
		||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
 | 
			
		||||
export LD_LIBRARY_PATH="$inst/lib"
 | 
			
		||||
 | 
			
		||||
if [ "x$IU" = "x--enable-iu" ]; then
 | 
			
		||||
	sccp_branch="old_sua"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmo-abis
 | 
			
		||||
osmo-build-dep.sh libosmo-netif
 | 
			
		||||
osmo-build-dep.sh libosmo-sccp $sccp_branch
 | 
			
		||||
PARALLEL_MAKE="" osmo-build-dep.sh libsmpp34
 | 
			
		||||
osmo-build-dep.sh openggsn
 | 
			
		||||
 | 
			
		||||
if [ "x$IU" = "x--enable-iu" ]; then
 | 
			
		||||
	osmo-build-dep.sh libasn1c
 | 
			
		||||
	#osmo-build-dep.sh asn1c aper-prefix # only needed for make regen in osmo-iuh
 | 
			
		||||
	osmo-build-dep.sh osmo-iuh
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
set +x
 | 
			
		||||
echo
 | 
			
		||||
echo
 | 
			
		||||
echo
 | 
			
		||||
echo " =============================== openbsc ==============================="
 | 
			
		||||
echo
 | 
			
		||||
set -x
 | 
			
		||||
 | 
			
		||||
cd "$base"
 | 
			
		||||
cd openbsc
 | 
			
		||||
autoreconf --install --force
 | 
			
		||||
./configure --enable-osmo-bsc --enable-nat $SMPP $MGCP $IU --enable-vty-tests --enable-external-tests
 | 
			
		||||
$MAKE $PARALLEL_MAKE
 | 
			
		||||
LD_LIBRARY_PATH="$inst/lib" $MAKE check \
 | 
			
		||||
  || cat-testlogs.sh
 | 
			
		||||
LD_LIBRARY_PATH="$inst/lib" $MAKE distcheck \
 | 
			
		||||
  || cat-testlogs.sh
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/autoreconf
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/autoreconf
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
openbsc
 | 
			
		||||
							
								
								
									
										75
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@@ -1,75 +0,0 @@
 | 
			
		||||
openbsc (0.15.1) UNRELEASED; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Move forward toward a new release.
 | 
			
		||||
  * Prevent SGSN starting with 'auth-policy remote' when no 'gsup remote-*' are configured.
 | 
			
		||||
    Note: such configs are broken without extra workarounds anyway.
 | 
			
		||||
 | 
			
		||||
 -- Holger Hans Peter Freyther <holger@moiji-mobile.com>  Tue, 24 May 2016 23:14:31 +0200
 | 
			
		||||
 | 
			
		||||
openbsc (0.14.0) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New upstream tag and additional patches.
 | 
			
		||||
 | 
			
		||||
 -- Holger Hans Peter Freyther <holger@freyther.de>  Sat, 14 Mar 2015 20:33:25 +0100
 | 
			
		||||
 | 
			
		||||
openbsc (0.12.0+git26-7) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * 64bit fix for the MGCP rewriting
 | 
			
		||||
 | 
			
		||||
 -- Holger Hans Peter Freyther <holger@freyther.de>  Wed, 07 Nov 2012 11:39:34 +0100
 | 
			
		||||
 | 
			
		||||
openbsc (0.12.0+git26-6) precise; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Added init script for osmocom-sgsn. 
 | 
			
		||||
 | 
			
		||||
 -- Eric Butler <eric@codebutler.com>  Fri, 24 Aug 2012 21:04:32 -0700
 | 
			
		||||
 | 
			
		||||
openbsc (0.12.0+git26-5) precise; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Don't enable MNCC sock by default.
 | 
			
		||||
  * Automatically create important directories.
 | 
			
		||||
  * Fix init script 'stop' command.
 | 
			
		||||
 | 
			
		||||
 -- Eric Butler <eric@codebutler.com>  Fri, 24 Aug 2012 20:56:33 -0700
 | 
			
		||||
 | 
			
		||||
openbsc (0.12.0+git26-4) precise; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Specify HLR path and enable RTP proxy.
 | 
			
		||||
 | 
			
		||||
 -- Eric Butler <eric@codebutler.com>  Mon, 20 Aug 2012 00:21:07 -0700
 | 
			
		||||
 | 
			
		||||
openbsc (0.12.0+git26-3) precise; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fix init script.
 | 
			
		||||
 | 
			
		||||
 -- Eric Butler <eric@codebutler.com>  Sun, 19 Aug 2012 16:05:44 -0700
 | 
			
		||||
 | 
			
		||||
openbsc (0.12.0+git26-2) precise; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fix libdbi package dependency.
 | 
			
		||||
 | 
			
		||||
 -- Eric Butler <eric@codebutler.com>  Wed, 15 Aug 2012 00:35:37 -0700
 | 
			
		||||
 | 
			
		||||
openbsc (0.12.0+git26-1) precise; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fix version issue.
 | 
			
		||||
 | 
			
		||||
 -- Eric Butler <eric@codebutler.com>  Tue, 14 Aug 2012 21:00:51 -0700
 | 
			
		||||
 | 
			
		||||
openbsc (0.12.0+git26) precise; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Updated ubuntu package.
 | 
			
		||||
 | 
			
		||||
 -- Eric Butler <eric@codebutler.com>  Tue, 14 Aug 2012 17:36:51 -0700
 | 
			
		||||
 | 
			
		||||
openbsc (0.9.13.115.eb113-1) natty; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New upstream release
 | 
			
		||||
 | 
			
		||||
 -- Harald Welte <laforge@gnumonks.org>  Wed, 11 May 2011 18:41:24 +0000
 | 
			
		||||
 | 
			
		||||
openbsc (0.9.4-1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Initial release
 | 
			
		||||
 | 
			
		||||
 -- Harald Welte <laforge@gnumonks.org>  Tue, 24 Aug 2010 13:34:24 +0200
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
9
 | 
			
		||||
							
								
								
									
										181
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										181
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@@ -1,181 +0,0 @@
 | 
			
		||||
Source: openbsc
 | 
			
		||||
Maintainer: Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
Section: net
 | 
			
		||||
Priority: optional
 | 
			
		||||
Build-Depends: debhelper (>= 9),
 | 
			
		||||
               autotools-dev,
 | 
			
		||||
               autoconf-archive,
 | 
			
		||||
               pkg-config,
 | 
			
		||||
               libgtp-dev,
 | 
			
		||||
               libosmocore-dev,
 | 
			
		||||
               libosmo-sccp-dev,
 | 
			
		||||
               libdbi0-dev,
 | 
			
		||||
               dh-autoreconf,
 | 
			
		||||
               libosmo-abis-dev,
 | 
			
		||||
               libosmo-netif-dev,
 | 
			
		||||
               libdbd-sqlite3,
 | 
			
		||||
               libpcap-dev,
 | 
			
		||||
               libssl-dev,
 | 
			
		||||
               libc-ares-dev,
 | 
			
		||||
               libsmpp34-dev
 | 
			
		||||
Standards-Version: 3.9.8
 | 
			
		||||
Vcs-Git: git://bs11-abis.gnumonks.org/openbsc.git
 | 
			
		||||
Vcs-Browser: http://openbsc.osmocom.org/trac/browser
 | 
			
		||||
Homepage: https://projects.osmocom.org/projects/openbsc
 | 
			
		||||
 | 
			
		||||
Package: osmocom-bsc
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends}
 | 
			
		||||
Description: GSM Base Station Controller
 | 
			
		||||
 This is the BSC-only version of OpenBSC. It requires a Mobile Switching Center
 | 
			
		||||
 (MSC) to operate.
 | 
			
		||||
 .
 | 
			
		||||
 You might rather prefer to use osmocom-nitb which is considered a
 | 
			
		||||
 "GSM Network-in-a-Box" and does not depend on a MSC.
 | 
			
		||||
 | 
			
		||||
Package: osmocom-nitb
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends},
 | 
			
		||||
         libdbd-sqlite3
 | 
			
		||||
Description: GSM Network-in-a-Box, implements BSC, MSC, SMSC, HLR, VLR
 | 
			
		||||
 This is the Network-in-a-Box version of OpenBSC. It has all the GSM network
 | 
			
		||||
 components bundled together. When using osmocom-nitb, there is no need for a
 | 
			
		||||
 Mobile Switching Center (MSC) which is needed when using osmocom-bsc.
 | 
			
		||||
 | 
			
		||||
Package: osmocom-ipaccess-utils
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends}
 | 
			
		||||
Description: Command line utilities for ip.access nanoBTS
 | 
			
		||||
 This package contains utilities that are specific for nanoBTS when being used
 | 
			
		||||
 together with OpenBSC. It contains mainly three tools: ipaccess-find,
 | 
			
		||||
 ipaccess-config and ipaccess-proxy.
 | 
			
		||||
 | 
			
		||||
Package: osmocom-bs11-utils
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends}
 | 
			
		||||
Description: Command line utilities for Siemens BS-11 BTS
 | 
			
		||||
 There is a tool in this package for configuring the Siemens BS-11 BTS.
 | 
			
		||||
 Additionally, it contains one tool for making use of an ISDN-card and the
 | 
			
		||||
 public telephone network as frequency standard for the E1 line.
 | 
			
		||||
 | 
			
		||||
Package: osmocom-sgsn
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends}
 | 
			
		||||
Suggests: osmocom-bsc
 | 
			
		||||
Description: Osmocom Serving GPRS Support Node
 | 
			
		||||
 This is an implementation of the GPRS Serving GPRS Support Node (SGSN). As
 | 
			
		||||
 such it implements the GPRS Mobility Management (GMM) and SM (Session
 | 
			
		||||
 Management).
 | 
			
		||||
 .
 | 
			
		||||
 The SGSN connects via the Gb-interface to the BSS (like the osmo-pcu or an
 | 
			
		||||
 ip.access nanoBTS), and it connects via the GTP protocol to a Gateway GPRS
 | 
			
		||||
 Support Node (GGSN) like openggsn.
 | 
			
		||||
 | 
			
		||||
Package: osmocom-gbproxy
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends}
 | 
			
		||||
Recommends: osmocom-sgsn
 | 
			
		||||
Description: Osmocom GPRS Gb Interface Proxy
 | 
			
		||||
 The purpose of the Gb proxy is to aggregate the Gb links of multiple
 | 
			
		||||
 BSS's and present them in one Gb link to the SGSN.
 | 
			
		||||
 .
 | 
			
		||||
 This package is part of OpenBSC and closely related to osmocom-sgsn.
 | 
			
		||||
 | 
			
		||||
Package: osmocom-bsc-nat
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends},
 | 
			
		||||
         ${misc:Depends}
 | 
			
		||||
Recommends: osmocom-bsc
 | 
			
		||||
Description: Osmocom Base Station Controller Network Address Translation
 | 
			
		||||
 This NAT is useful for masquerading multiple BSCs behind one. It listens
 | 
			
		||||
 for incoming BSCs on port 5000 and connects to a specified Mobile Switching
 | 
			
		||||
 Center (MSC).
 | 
			
		||||
 .
 | 
			
		||||
 This package is part of OpenBSC and closely related to osmocom-bsc.
 | 
			
		||||
 | 
			
		||||
Package: openbsc-dev
 | 
			
		||||
Architecture: all
 | 
			
		||||
Depends: ${misc:Depends}
 | 
			
		||||
Description: Header file needed by tools tightly integrated
 | 
			
		||||
 Some other programs depend on gsm_data_shared.h and gsm_data_shared.c
 | 
			
		||||
 from OpenBSC. This package installs these files to your file system so
 | 
			
		||||
 that the other packages can build-depend on this package.
 | 
			
		||||
 .
 | 
			
		||||
 The directory structure is copied after the structure in the repository
 | 
			
		||||
 and the header and .c file are installed into /usr/src/osmocom/openbsc/.
 | 
			
		||||
 | 
			
		||||
Package: osmo-gtphub
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends}, ${misc:Depends}
 | 
			
		||||
Description: Osmocom GTP Hub
 | 
			
		||||
 Proxy for comms between multiple SGSNs and GGSNs.
 | 
			
		||||
 | 
			
		||||
Package: osmocom-bsc-dbg
 | 
			
		||||
Architecture: any
 | 
			
		||||
Section: debug
 | 
			
		||||
Priority: extra
 | 
			
		||||
Depends: osmocom-bsc (= ${binary:Version}), ${misc:Depends}
 | 
			
		||||
Description: Debug symbols for the OpenBSC BSC
 | 
			
		||||
 Make debugging possible
 | 
			
		||||
 | 
			
		||||
Package: osmocom-nitb-dbg
 | 
			
		||||
Architecture: any
 | 
			
		||||
Section: debug
 | 
			
		||||
Priority: extra
 | 
			
		||||
Depends: osmocom-nitb (= ${binary:Version}), ${misc:Depends}
 | 
			
		||||
Description: Debug symbols for the OpenBSC NITB
 | 
			
		||||
 Make debugging possible
 | 
			
		||||
 | 
			
		||||
Package: osmocom-ipaccess-utils-dbg
 | 
			
		||||
Architecture: any
 | 
			
		||||
Section: debug
 | 
			
		||||
Priority: extra
 | 
			
		||||
Depends: osmocom-ipaccess-utils (= ${binary:Version}), ${misc:Depends}
 | 
			
		||||
Description: Debug symbols for the OpenBSC ip.access utils
 | 
			
		||||
 Make debugging possible
 | 
			
		||||
 | 
			
		||||
Package: osmocom-bs11-utils-dbg
 | 
			
		||||
Architecture: any
 | 
			
		||||
Section: debug
 | 
			
		||||
Priority: extra
 | 
			
		||||
Depends: osmocom-bs11-utils (= ${binary:Version}), ${misc:Depends}
 | 
			
		||||
Description: Debug symbols for the OpenBSC BS11 utils
 | 
			
		||||
 Make debugging possible
 | 
			
		||||
 | 
			
		||||
Package: osmocom-sgsn-dbg
 | 
			
		||||
Architecture: any
 | 
			
		||||
Section: debug
 | 
			
		||||
Priority: extra
 | 
			
		||||
Depends: osmocom-sgsn (= ${binary:Version}), ${misc:Depends}
 | 
			
		||||
Description: Debug symbols for the OpenBSC Serving GPRS Support Node
 | 
			
		||||
 Make debugging possible
 | 
			
		||||
 | 
			
		||||
Package: osmocom-gbproxy-dbg
 | 
			
		||||
Architecture: any
 | 
			
		||||
Section: debug
 | 
			
		||||
Priority: extra
 | 
			
		||||
Depends: osmocom-gbproxy (= ${binary:Version}), ${misc:Depends}
 | 
			
		||||
Description: Debug symbols for the OpenBSC GPRS GBProxy
 | 
			
		||||
 Make debugging possible
 | 
			
		||||
 | 
			
		||||
Package: osmocom-bsc-nat-dbg
 | 
			
		||||
Architecture: any
 | 
			
		||||
Section: debug
 | 
			
		||||
Priority: extra
 | 
			
		||||
Depends: osmocom-bsc-nat (= ${binary:Version}), ${misc:Depends}
 | 
			
		||||
Description: Debug symbols for the OpenBSC Network Address Translation
 | 
			
		||||
 Make debugging possible
 | 
			
		||||
 | 
			
		||||
Package: osmo-gtphub-dbg
 | 
			
		||||
Architecture: any
 | 
			
		||||
Section: debug
 | 
			
		||||
Priority: extra
 | 
			
		||||
Depends: osmo-gtphub (= ${binary:Version}), ${misc:Depends}
 | 
			
		||||
Description: Debug symbols for Osmocom GTP Hub
 | 
			
		||||
 Make debugging possible
 | 
			
		||||
							
								
								
									
										137
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										137
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							@@ -1,137 +0,0 @@
 | 
			
		||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 | 
			
		||||
Upstream-Name: OpenBSC
 | 
			
		||||
Source: http://openbsc.osmocom.org/
 | 
			
		||||
 | 
			
		||||
Files: *
 | 
			
		||||
Copyright: 2008-2015        Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
           2008-2015        Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
           2009-2015        On-Waves
 | 
			
		||||
           2008             Jan Luebbe <jluebbe@debian.org>
 | 
			
		||||
           2008,2010-2011   Daniel Willmann <daniel@totalueberwachung.de>
 | 
			
		||||
           2009,2011,2013   Andreas Eversberg <Andreas.Eversberg@versatel.de>
 | 
			
		||||
           2009,2011        Dieter Spaar <spaar@mirider.augusta.de>
 | 
			
		||||
           2009             Mike Haben <michael.haben@btinternet.com>
 | 
			
		||||
           2010             Sylvain Munaut <246tnt@gmail.com>
 | 
			
		||||
           2012-2013        Pablo Neira Ayuso <pablo@gnumonks.org>
 | 
			
		||||
           2013-2015        Sysmocom s.f.m.c. GmbH  (Jacob Erlbeck)
 | 
			
		||||
           2014             Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
 | 
			
		||||
License: AGPL-3+
 | 
			
		||||
Comment: Contributions by Stefan Schmidt <stefan@datenfreihafen.org> as well
 | 
			
		||||
 | 
			
		||||
Files: wireshark/0001-abis_oml.patch
 | 
			
		||||
       wireshark/0002-ericsson_rbs2409.patch
 | 
			
		||||
       wireshark/0003-lucent-hnb.patch
 | 
			
		||||
       wireshark/0005-rsl-hsl.patch
 | 
			
		||||
Copyright: 1998         Gerald Combs <gerald@wireshark.org>
 | 
			
		||||
           2007,2011    Anders Broman <anders.broman@ericsson.com>
 | 
			
		||||
           2009         Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
           2009-2011    Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
License: GPL-2+
 | 
			
		||||
 | 
			
		||||
Files: openbsc/include/mISDNif.h
 | 
			
		||||
Copyright: 2008         Karsten Keil <kkeil@novell.com>
 | 
			
		||||
License: LGPL-2.1
 | 
			
		||||
 | 
			
		||||
Files: openbsc/src/libmgcp/g711common.h
 | 
			
		||||
Copyright: 2009         Abramo Bagnara <abramo@alsa-project.org>
 | 
			
		||||
License: GPL-2+
 | 
			
		||||
 | 
			
		||||
Files: openbsc/git-version-gen
 | 
			
		||||
Copyright: 2007-2010    Free Software Foundation
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: openbsc/osmoappdesc.py
 | 
			
		||||
       openbsc/tests/smpp_test_runner.py
 | 
			
		||||
       openbsc/tests/ctrl_test_runner.py
 | 
			
		||||
       openbsc/tests/vty_test_runner.py
 | 
			
		||||
Copyright: 2013         Katerina Barone-Adesi <kat.obsc@gmail.com>
 | 
			
		||||
           2013         Jacob Erlbeck <jerlbeck@sysmocom.de>
 | 
			
		||||
           2013-2014    Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: openbsc/src/libbsc/bsc_ctrl_lookup.c
 | 
			
		||||
Copyright: 2010-2011    Daniel Willmann <daniel@totalueberwachung.de>
 | 
			
		||||
           2010-2011    On-Waves
 | 
			
		||||
License: GPL-2+
 | 
			
		||||
 | 
			
		||||
Files: openbsc/src/libmsc/mncc_sock.c
 | 
			
		||||
       openbsc/src/libmsc/mncc_builtin.c
 | 
			
		||||
Copyright: 2008-2010    Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
           2009         Andreas Eversberg <Andreas.Eversberg@versatel.de>
 | 
			
		||||
           2012         Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
License: GPL-2+
 | 
			
		||||
 | 
			
		||||
Files: debian/*
 | 
			
		||||
Copyright: 2012-2015    Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
           2016         Ruben Undheim <ruben.undheim@gmail.com>
 | 
			
		||||
License: GPL-2+
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
License: AGPL-3+
 | 
			
		||||
 This package is free software; you can redistribute it and/or modify
 | 
			
		||||
 it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
 the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 (at your option) any later version.
 | 
			
		||||
 .
 | 
			
		||||
 This program is distributed in the hope that it will be useful,
 | 
			
		||||
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 GNU General Public License for more details.
 | 
			
		||||
 .
 | 
			
		||||
 You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
License: GPL-2+
 | 
			
		||||
 This package 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 .
 | 
			
		||||
 On Debian systems, the complete text of the GNU General Public
 | 
			
		||||
 License version 2 can be found in "/usr/share/common-licenses/GPL-2".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 This package 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/>.
 | 
			
		||||
 .
 | 
			
		||||
 On Debian systems, the complete text of the GNU General Public
 | 
			
		||||
 License version 3 can be found in "/usr/share/common-licenses/GPL-3".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
License: LGPL-2.1
 | 
			
		||||
 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; version
 | 
			
		||||
 2.1 of the License.
 | 
			
		||||
 .
 | 
			
		||||
 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/>.
 | 
			
		||||
 .
 | 
			
		||||
 On Debian systems, the complete text of the GNU Lesser General
 | 
			
		||||
 Public License version 2.1 can be found in
 | 
			
		||||
 "/usr/share/common-licenses/LGPL-2.1".
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/docs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/docs
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
openbsc/README
 | 
			
		||||
							
								
								
									
										4
									
								
								debian/openbsc-dev.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								debian/openbsc-dev.install
									
									
									
									
										vendored
									
									
								
							@@ -1,4 +0,0 @@
 | 
			
		||||
openbsc/include/openbsc/gsm_data_shared.h usr/src/osmocom/openbsc/openbsc/include/openbsc/
 | 
			
		||||
openbsc/include/openbsc/common_cs.h usr/src/osmocom/openbsc/openbsc/include/openbsc/
 | 
			
		||||
openbsc/src/libcommon/gsm_data_shared.c usr/src/osmocom/openbsc/openbsc/src/libcommon/
 | 
			
		||||
usr/lib/*/pkgconfig/openbsc.pc
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/osmo-gtphub.default
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/osmo-gtphub.default
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +0,0 @@
 | 
			
		||||
CONFIG_FILE="/etc/osmocom/osmo-gtphub.cfg"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/osmo-gtphub.examples
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/osmo-gtphub.examples
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
openbsc/doc/examples/osmo-gtphub
 | 
			
		||||
							
								
								
									
										150
									
								
								debian/osmo-gtphub.init
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										150
									
								
								debian/osmo-gtphub.init
									
									
									
									
										vendored
									
									
								
							@@ -1,150 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
### BEGIN INIT INFO
 | 
			
		||||
# Provides:          osmo-gtphub
 | 
			
		||||
# Required-Start:    $network $local_fs
 | 
			
		||||
# Required-Stop:
 | 
			
		||||
# Default-Start:     2 3 4 5
 | 
			
		||||
# Default-Stop:      0 1 6
 | 
			
		||||
# Short-Description: Osmocom GTP hub
 | 
			
		||||
# Description:       Osmocom GTP hub
 | 
			
		||||
### END INIT INFO
 | 
			
		||||
 | 
			
		||||
# Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
 | 
			
		||||
 | 
			
		||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
 | 
			
		||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
 | 
			
		||||
NAME=osmo-gtphub                         # Introduce the short server's name here
 | 
			
		||||
DESC="Osmocom GTP hub"                   # Introduce a short description here
 | 
			
		||||
DAEMON=/usr/bin/osmo-gtphub              # Introduce the server's location here
 | 
			
		||||
SCRIPTNAME=/etc/init.d/osmo-gtphub
 | 
			
		||||
 | 
			
		||||
# Exit if the package is not installed
 | 
			
		||||
[ -x $DAEMON ] || exit 0
 | 
			
		||||
 | 
			
		||||
# Read configuration variable file if it is present
 | 
			
		||||
[ -r /etc/default/osmo-gtphub ] && . /etc/default/osmo-gtphub
 | 
			
		||||
 | 
			
		||||
# Load the VERBOSE setting and other rcS variables
 | 
			
		||||
. /lib/init/vars.sh
 | 
			
		||||
 | 
			
		||||
# Define LSB log_* functions.
 | 
			
		||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
 | 
			
		||||
. /lib/lsb/init-functions
 | 
			
		||||
 | 
			
		||||
DAEMON_ARGS="$DAEMON_ARGS -D -c $CONFIG_FILE"
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that starts the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_start()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been started
 | 
			
		||||
	#   1 if daemon was already running
 | 
			
		||||
	#   2 if daemon could not be started
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
 | 
			
		||||
		|| return 1
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON -- \
 | 
			
		||||
		$DAEMON_ARGS \
 | 
			
		||||
		|| return 2
 | 
			
		||||
	# Add code here, if necessary, that waits for the process to be ready
 | 
			
		||||
	# to handle requests from services started subsequently which depend
 | 
			
		||||
	# on this one.  As a last resort, sleep for some time.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that stops the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_stop()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been stopped
 | 
			
		||||
	#   1 if daemon was already stopped
 | 
			
		||||
	#   2 if daemon could not be stopped
 | 
			
		||||
	#   other if a failure occurred
 | 
			
		||||
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
 | 
			
		||||
	RETVAL="$?"
 | 
			
		||||
	[ "$RETVAL" = 2 ] && return 2
 | 
			
		||||
	# Wait for children to finish too if this is a daemon that forks
 | 
			
		||||
	# and if the daemon is only ever run from this initscript.
 | 
			
		||||
	# If the above conditions are not satisfied then add some other code
 | 
			
		||||
	# that waits for the process to drop all resources that could be
 | 
			
		||||
	# needed by services started subsequently.  A last resort is to
 | 
			
		||||
	# sleep for some time.
 | 
			
		||||
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
 | 
			
		||||
	[ "$?" = 2 ] && return 2
 | 
			
		||||
	return "$RETVAL"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that sends a SIGHUP to the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_reload() {
 | 
			
		||||
	#
 | 
			
		||||
	# If the daemon can reload its configuration without
 | 
			
		||||
	# restarting (for example, when it is sent a SIGHUP),
 | 
			
		||||
	# then implement that here.
 | 
			
		||||
	#
 | 
			
		||||
	start-stop-daemon --stop --signal 1 --quiet $PIDFILE --name $NAME
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
  start)
 | 
			
		||||
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
 | 
			
		||||
    do_start
 | 
			
		||||
    case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
  ;;
 | 
			
		||||
  stop)
 | 
			
		||||
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  status)
 | 
			
		||||
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
 | 
			
		||||
       ;;
 | 
			
		||||
  #reload|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If do_reload() is not implemented then leave this commented out
 | 
			
		||||
	# and leave 'force-reload' as an alias for 'restart'.
 | 
			
		||||
	#
 | 
			
		||||
	#log_daemon_msg "Reloading $DESC" "$NAME"
 | 
			
		||||
	#do_reload
 | 
			
		||||
	#log_end_msg $?
 | 
			
		||||
	#;;
 | 
			
		||||
  restart|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If the "reload" option is implemented then remove the
 | 
			
		||||
	# 'force-reload' alias
 | 
			
		||||
	#
 | 
			
		||||
	log_daemon_msg "Restarting $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
	  0|1)
 | 
			
		||||
		do_start
 | 
			
		||||
		case "$?" in
 | 
			
		||||
			0) log_end_msg 0 ;;
 | 
			
		||||
			1) log_end_msg 1 ;; # Old process is still running
 | 
			
		||||
			*) log_end_msg 1 ;; # Failed to start
 | 
			
		||||
		esac
 | 
			
		||||
		;;
 | 
			
		||||
	  *)
 | 
			
		||||
		# Failed to stop
 | 
			
		||||
		log_end_msg 1
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  *)
 | 
			
		||||
	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
 | 
			
		||||
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
 | 
			
		||||
	exit 3
 | 
			
		||||
	;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
:
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/osmo-gtphub.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/osmo-gtphub.install
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
/usr/bin/osmo-gtphub
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/osmocom-bs11-utils.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/osmocom-bs11-utils.install
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +0,0 @@
 | 
			
		||||
/usr/bin/bs11_config
 | 
			
		||||
/usr/bin/isdnsync
 | 
			
		||||
							
								
								
									
										153
									
								
								debian/osmocom-bsc-nat.init
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										153
									
								
								debian/osmocom-bsc-nat.init
									
									
									
									
										vendored
									
									
								
							@@ -1,153 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
### BEGIN INIT INFO
 | 
			
		||||
# Provides:          osmocom-bsc-nat
 | 
			
		||||
# Required-Start:    $network $local_fs
 | 
			
		||||
# Required-Stop:
 | 
			
		||||
# Default-Start:     2 3 4 5
 | 
			
		||||
# Default-Stop:      0 1 6
 | 
			
		||||
# Short-Description: Osmocom GSM network-in-a-box
 | 
			
		||||
# Description:       A minimal implementation of the GSM Base Station Controller,
 | 
			
		||||
#                    Mobile Switching Center, Home Location regster and all other
 | 
			
		||||
#                    components to run a self-contained GSM network.
 | 
			
		||||
### END INIT INFO
 | 
			
		||||
 | 
			
		||||
# Author: Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
 | 
			
		||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
 | 
			
		||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
 | 
			
		||||
NAME=osmo-bsc_nat                      # Introduce the short server's name here
 | 
			
		||||
DESC="Osmocom GSM BSC Multiplexer (NAT)" # Introduce a short description here
 | 
			
		||||
DAEMON=/usr/bin/osmo-bsc_nat           # Introduce the server's location here
 | 
			
		||||
SCRIPTNAME=/etc/init.d/osmocom-bsc-nat
 | 
			
		||||
CONFIG_FILE=/etc/osmocom/osmocom-bsc-nat.cfg
 | 
			
		||||
 | 
			
		||||
# Exit if the package is not installed
 | 
			
		||||
[ -x $DAEMON ] || exit 0
 | 
			
		||||
 | 
			
		||||
# Read configuration variable file if it is present
 | 
			
		||||
[ -r /etc/default/osmocom-bsc-nat ] && . /etc/default/osmocom-bsc-nat
 | 
			
		||||
 | 
			
		||||
# Load the VERBOSE setting and other rcS variables
 | 
			
		||||
. /lib/init/vars.sh
 | 
			
		||||
 | 
			
		||||
# Define LSB log_* functions.
 | 
			
		||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
 | 
			
		||||
. /lib/lsb/init-functions
 | 
			
		||||
 | 
			
		||||
DAEMON_ARGS="-D -c $CONFIG_FILE"
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that starts the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_start()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been started
 | 
			
		||||
	#   1 if daemon was already running
 | 
			
		||||
	#   2 if daemon could not be started
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
 | 
			
		||||
		|| return 1
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON -- \
 | 
			
		||||
		$DAEMON_ARGS \
 | 
			
		||||
		|| return 2
 | 
			
		||||
	# Add code here, if necessary, that waits for the process to be ready
 | 
			
		||||
	# to handle requests from services started subsequently which depend
 | 
			
		||||
	# on this one.  As a last resort, sleep for some time.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that stops the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_stop()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been stopped
 | 
			
		||||
	#   1 if daemon was already stopped
 | 
			
		||||
	#   2 if daemon could not be stopped
 | 
			
		||||
	#   other if a failure occurred
 | 
			
		||||
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
 | 
			
		||||
	RETVAL="$?"
 | 
			
		||||
	[ "$RETVAL" = 2 ] && return 2
 | 
			
		||||
	# Wait for children to finish too if this is a daemon that forks
 | 
			
		||||
	# and if the daemon is only ever run from this initscript.
 | 
			
		||||
	# If the above conditions are not satisfied then add some other code
 | 
			
		||||
	# that waits for the process to drop all resources that could be
 | 
			
		||||
	# needed by services started subsequently.  A last resort is to
 | 
			
		||||
	# sleep for some time.
 | 
			
		||||
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
 | 
			
		||||
	[ "$?" = 2 ] && return 2
 | 
			
		||||
	return "$RETVAL"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that sends a SIGHUP to the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_reload() {
 | 
			
		||||
	#
 | 
			
		||||
	# If the daemon can reload its configuration without
 | 
			
		||||
	# restarting (for example, when it is sent a SIGHUP),
 | 
			
		||||
	# then implement that here.
 | 
			
		||||
	#
 | 
			
		||||
	start-stop-daemon --stop --signal 1 --quiet $PIDFILE --name $NAME
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
  start)
 | 
			
		||||
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
 | 
			
		||||
    do_start
 | 
			
		||||
    case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
  ;;
 | 
			
		||||
  stop)
 | 
			
		||||
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  status)
 | 
			
		||||
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
 | 
			
		||||
       ;;
 | 
			
		||||
  #reload|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If do_reload() is not implemented then leave this commented out
 | 
			
		||||
	# and leave 'force-reload' as an alias for 'restart'.
 | 
			
		||||
	#
 | 
			
		||||
	#log_daemon_msg "Reloading $DESC" "$NAME"
 | 
			
		||||
	#do_reload
 | 
			
		||||
	#log_end_msg $?
 | 
			
		||||
	#;;
 | 
			
		||||
  restart|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If the "reload" option is implemented then remove the
 | 
			
		||||
	# 'force-reload' alias
 | 
			
		||||
	#
 | 
			
		||||
	log_daemon_msg "Restarting $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
	  0|1)
 | 
			
		||||
		do_start
 | 
			
		||||
		case "$?" in
 | 
			
		||||
			0) log_end_msg 0 ;;
 | 
			
		||||
			1) log_end_msg 1 ;; # Old process is still running
 | 
			
		||||
			*) log_end_msg 1 ;; # Failed to start
 | 
			
		||||
		esac
 | 
			
		||||
		;;
 | 
			
		||||
	  *)
 | 
			
		||||
	  	# Failed to stop
 | 
			
		||||
		log_end_msg 1
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  *)
 | 
			
		||||
	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
 | 
			
		||||
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
 | 
			
		||||
	exit 3
 | 
			
		||||
	;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
:
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/osmocom-bsc-nat.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/osmocom-bsc-nat.install
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
/usr/bin/osmo-bsc_nat
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/osmocom-bsc.examples
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/osmocom-bsc.examples
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
openbsc/doc/examples/osmo-bsc_mgcp
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/osmocom-bsc.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/osmocom-bsc.install
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +0,0 @@
 | 
			
		||||
/usr/bin/osmo-bsc_mgcp
 | 
			
		||||
/usr/bin/osmo-bsc
 | 
			
		||||
							
								
								
									
										151
									
								
								debian/osmocom-gbproxy.init
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										151
									
								
								debian/osmocom-gbproxy.init
									
									
									
									
										vendored
									
									
								
							@@ -1,151 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
### BEGIN INIT INFO
 | 
			
		||||
# Provides:          osmo-gbproxy
 | 
			
		||||
# Required-Start:    $network $local_fs
 | 
			
		||||
# Required-Stop:
 | 
			
		||||
# Default-Start:     2 3 4 5
 | 
			
		||||
# Default-Stop:      0 1 6
 | 
			
		||||
# Short-Description: Osmocom GBproxy
 | 
			
		||||
# Description:       A tool to proxy the GPRS Gb interface.
 | 
			
		||||
### END INIT INFO
 | 
			
		||||
 | 
			
		||||
# Author: Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
 | 
			
		||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
 | 
			
		||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
 | 
			
		||||
NAME=osmo-gbproxy                      # Introduce the short server's name here
 | 
			
		||||
DESC="Osmocom GBProxy" # Introduce a short description here
 | 
			
		||||
DAEMON=/usr/bin/osmo-gbproxy           # Introduce the server's location here
 | 
			
		||||
SCRIPTNAME=/etc/init.d/osmocom-gbproxy
 | 
			
		||||
CONFIG_FILE=/etc/osmocom/osmocom-gbproxy.cfg
 | 
			
		||||
 | 
			
		||||
# Exit if the package is not installed
 | 
			
		||||
[ -x $DAEMON ] || exit 0
 | 
			
		||||
 | 
			
		||||
# Read configuration variable file if it is present
 | 
			
		||||
[ -r /etc/default/osmocom-gbproxy ] && . /etc/default/osmocom-gbproxy
 | 
			
		||||
 | 
			
		||||
# Load the VERBOSE setting and other rcS variables
 | 
			
		||||
. /lib/init/vars.sh
 | 
			
		||||
 | 
			
		||||
# Define LSB log_* functions.
 | 
			
		||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
 | 
			
		||||
. /lib/lsb/init-functions
 | 
			
		||||
 | 
			
		||||
DAEMON_ARGS="-D -c $CONFIG_FILE"
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that starts the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_start()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been started
 | 
			
		||||
	#   1 if daemon was already running
 | 
			
		||||
	#   2 if daemon could not be started
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
 | 
			
		||||
		|| return 1
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON -- \
 | 
			
		||||
		$DAEMON_ARGS \
 | 
			
		||||
		|| return 2
 | 
			
		||||
	# Add code here, if necessary, that waits for the process to be ready
 | 
			
		||||
	# to handle requests from services started subsequently which depend
 | 
			
		||||
	# on this one.  As a last resort, sleep for some time.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that stops the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_stop()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been stopped
 | 
			
		||||
	#   1 if daemon was already stopped
 | 
			
		||||
	#   2 if daemon could not be stopped
 | 
			
		||||
	#   other if a failure occurred
 | 
			
		||||
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
 | 
			
		||||
	RETVAL="$?"
 | 
			
		||||
	[ "$RETVAL" = 2 ] && return 2
 | 
			
		||||
	# Wait for children to finish too if this is a daemon that forks
 | 
			
		||||
	# and if the daemon is only ever run from this initscript.
 | 
			
		||||
	# If the above conditions are not satisfied then add some other code
 | 
			
		||||
	# that waits for the process to drop all resources that could be
 | 
			
		||||
	# needed by services started subsequently.  A last resort is to
 | 
			
		||||
	# sleep for some time.
 | 
			
		||||
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
 | 
			
		||||
	[ "$?" = 2 ] && return 2
 | 
			
		||||
	return "$RETVAL"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that sends a SIGHUP to the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_reload() {
 | 
			
		||||
	#
 | 
			
		||||
	# If the daemon can reload its configuration without
 | 
			
		||||
	# restarting (for example, when it is sent a SIGHUP),
 | 
			
		||||
	# then implement that here.
 | 
			
		||||
	#
 | 
			
		||||
	start-stop-daemon --stop --signal 1 --quiet $PIDFILE --name $NAME
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
  start)
 | 
			
		||||
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
 | 
			
		||||
    do_start
 | 
			
		||||
    case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
  ;;
 | 
			
		||||
  stop)
 | 
			
		||||
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  status)
 | 
			
		||||
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
 | 
			
		||||
       ;;
 | 
			
		||||
  #reload|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If do_reload() is not implemented then leave this commented out
 | 
			
		||||
	# and leave 'force-reload' as an alias for 'restart'.
 | 
			
		||||
	#
 | 
			
		||||
	#log_daemon_msg "Reloading $DESC" "$NAME"
 | 
			
		||||
	#do_reload
 | 
			
		||||
	#log_end_msg $?
 | 
			
		||||
	#;;
 | 
			
		||||
  restart|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If the "reload" option is implemented then remove the
 | 
			
		||||
	# 'force-reload' alias
 | 
			
		||||
	#
 | 
			
		||||
	log_daemon_msg "Restarting $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
	  0|1)
 | 
			
		||||
		do_start
 | 
			
		||||
		case "$?" in
 | 
			
		||||
			0) log_end_msg 0 ;;
 | 
			
		||||
			1) log_end_msg 1 ;; # Old process is still running
 | 
			
		||||
			*) log_end_msg 1 ;; # Failed to start
 | 
			
		||||
		esac
 | 
			
		||||
		;;
 | 
			
		||||
	  *)
 | 
			
		||||
	  	# Failed to stop
 | 
			
		||||
		log_end_msg 1
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  *)
 | 
			
		||||
	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
 | 
			
		||||
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
 | 
			
		||||
	exit 3
 | 
			
		||||
	;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
:
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/osmocom-gbproxy.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/osmocom-gbproxy.install
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
/usr/bin/osmo-gbproxy
 | 
			
		||||
							
								
								
									
										3
									
								
								debian/osmocom-ipaccess-utils.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								debian/osmocom-ipaccess-utils.install
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +0,0 @@
 | 
			
		||||
/usr/bin/ipaccess-config
 | 
			
		||||
/usr/bin/abisip-find
 | 
			
		||||
/usr/bin/ipaccess-proxy
 | 
			
		||||
							
								
								
									
										8
									
								
								debian/osmocom-nitb.default
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								debian/osmocom-nitb.default
									
									
									
									
										vendored
									
									
								
							@@ -1,8 +0,0 @@
 | 
			
		||||
CONFIG_FILE="/etc/osmocom/osmo-nitb.cfg"
 | 
			
		||||
HLR_FILE="/var/lib/osmocom/hlr.sqlite3"
 | 
			
		||||
 | 
			
		||||
DAEMON_ARGS="-P"
 | 
			
		||||
 | 
			
		||||
# Uncomment if using LCR+Asterisk
 | 
			
		||||
# DAEMON_ARGS="-m -P"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								debian/osmocom-nitb.dirs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								debian/osmocom-nitb.dirs
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +0,0 @@
 | 
			
		||||
/etc/osmocom
 | 
			
		||||
/var/log/osmocom
 | 
			
		||||
/var/lib/osmocom
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/osmocom-nitb.examples
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/osmocom-nitb.examples
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
openbsc/doc/examples/osmo-nitb
 | 
			
		||||
							
								
								
									
										152
									
								
								debian/osmocom-nitb.init
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										152
									
								
								debian/osmocom-nitb.init
									
									
									
									
										vendored
									
									
								
							@@ -1,152 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
### BEGIN INIT INFO
 | 
			
		||||
# Provides:          osmo-nitb
 | 
			
		||||
# Required-Start:    $network $local_fs
 | 
			
		||||
# Required-Stop:
 | 
			
		||||
# Default-Start:     2 3 4 5
 | 
			
		||||
# Default-Stop:      0 1 6
 | 
			
		||||
# Short-Description: Osmocom GSM network-in-a-box
 | 
			
		||||
# Description:       A minimal implementation of the GSM Base Station Controller,
 | 
			
		||||
#                    Mobile Switching Center, Home Location regster and all other
 | 
			
		||||
#                    components to run a self-contained GSM network.
 | 
			
		||||
### END INIT INFO
 | 
			
		||||
 | 
			
		||||
# Author: Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
 | 
			
		||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
 | 
			
		||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
 | 
			
		||||
NAME=osmo-nitb                      # Introduce the short server's name here
 | 
			
		||||
DESC="Osmocom GSM Network-in-a-Box" # Introduce a short description here
 | 
			
		||||
DAEMON=/usr/bin/osmo-nitb           # Introduce the server's location here
 | 
			
		||||
SCRIPTNAME=/etc/init.d/osmocom-nitb
 | 
			
		||||
 | 
			
		||||
# Exit if the package is not installed
 | 
			
		||||
[ -x $DAEMON ] || exit 0
 | 
			
		||||
 | 
			
		||||
# Read configuration variable file if it is present
 | 
			
		||||
[ -r /etc/default/osmocom-nitb ] && . /etc/default/osmocom-nitb
 | 
			
		||||
 | 
			
		||||
# Load the VERBOSE setting and other rcS variables
 | 
			
		||||
. /lib/init/vars.sh
 | 
			
		||||
 | 
			
		||||
# Define LSB log_* functions.
 | 
			
		||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
 | 
			
		||||
. /lib/lsb/init-functions
 | 
			
		||||
 | 
			
		||||
DAEMON_ARGS="$DAEMON_ARGS -D -c $CONFIG_FILE -l $HLR_FILE"
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that starts the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_start()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been started
 | 
			
		||||
	#   1 if daemon was already running
 | 
			
		||||
	#   2 if daemon could not be started
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
 | 
			
		||||
		|| return 1
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON -- \
 | 
			
		||||
		$DAEMON_ARGS \
 | 
			
		||||
		|| return 2
 | 
			
		||||
	# Add code here, if necessary, that waits for the process to be ready
 | 
			
		||||
	# to handle requests from services started subsequently which depend
 | 
			
		||||
	# on this one.  As a last resort, sleep for some time.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that stops the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_stop()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been stopped
 | 
			
		||||
	#   1 if daemon was already stopped
 | 
			
		||||
	#   2 if daemon could not be stopped
 | 
			
		||||
	#   other if a failure occurred
 | 
			
		||||
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
 | 
			
		||||
	RETVAL="$?"
 | 
			
		||||
	[ "$RETVAL" = 2 ] && return 2
 | 
			
		||||
	# Wait for children to finish too if this is a daemon that forks
 | 
			
		||||
	# and if the daemon is only ever run from this initscript.
 | 
			
		||||
	# If the above conditions are not satisfied then add some other code
 | 
			
		||||
	# that waits for the process to drop all resources that could be
 | 
			
		||||
	# needed by services started subsequently.  A last resort is to
 | 
			
		||||
	# sleep for some time.
 | 
			
		||||
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
 | 
			
		||||
	[ "$?" = 2 ] && return 2
 | 
			
		||||
	return "$RETVAL"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that sends a SIGHUP to the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_reload() {
 | 
			
		||||
	#
 | 
			
		||||
	# If the daemon can reload its configuration without
 | 
			
		||||
	# restarting (for example, when it is sent a SIGHUP),
 | 
			
		||||
	# then implement that here.
 | 
			
		||||
	#
 | 
			
		||||
	start-stop-daemon --stop --signal 1 --quiet $PIDFILE --name $NAME
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
  start)
 | 
			
		||||
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
 | 
			
		||||
    do_start
 | 
			
		||||
    case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
  ;;
 | 
			
		||||
  stop)
 | 
			
		||||
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  status)
 | 
			
		||||
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
 | 
			
		||||
       ;;
 | 
			
		||||
  #reload|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If do_reload() is not implemented then leave this commented out
 | 
			
		||||
	# and leave 'force-reload' as an alias for 'restart'.
 | 
			
		||||
	#
 | 
			
		||||
	#log_daemon_msg "Reloading $DESC" "$NAME"
 | 
			
		||||
	#do_reload
 | 
			
		||||
	#log_end_msg $?
 | 
			
		||||
	#;;
 | 
			
		||||
  restart|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If the "reload" option is implemented then remove the
 | 
			
		||||
	# 'force-reload' alias
 | 
			
		||||
	#
 | 
			
		||||
	log_daemon_msg "Restarting $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
	  0|1)
 | 
			
		||||
		do_start
 | 
			
		||||
		case "$?" in
 | 
			
		||||
			0) log_end_msg 0 ;;
 | 
			
		||||
			1) log_end_msg 1 ;; # Old process is still running
 | 
			
		||||
			*) log_end_msg 1 ;; # Failed to start
 | 
			
		||||
		esac
 | 
			
		||||
		;;
 | 
			
		||||
	  *)
 | 
			
		||||
	  	# Failed to stop
 | 
			
		||||
		log_end_msg 1
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  *)
 | 
			
		||||
	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
 | 
			
		||||
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
 | 
			
		||||
	exit 3
 | 
			
		||||
	;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
:
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/osmocom-nitb.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/osmocom-nitb.install
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +0,0 @@
 | 
			
		||||
/usr/bin/osmo-nitb
 | 
			
		||||
openbsc/contrib/*.py usr/bin/
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/osmocom-sgsn.default
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/osmocom-sgsn.default
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +0,0 @@
 | 
			
		||||
CONFIG_FILE="/etc/osmocom/osmo-sgsn.cfg"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/osmocom-sgsn.examples
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/osmocom-sgsn.examples
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
openbsc/doc/examples/osmo-sgsn
 | 
			
		||||
							
								
								
									
										150
									
								
								debian/osmocom-sgsn.init
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										150
									
								
								debian/osmocom-sgsn.init
									
									
									
									
										vendored
									
									
								
							@@ -1,150 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
### BEGIN INIT INFO
 | 
			
		||||
# Provides:          osmo-sgsn
 | 
			
		||||
# Required-Start:    $network $local_fs
 | 
			
		||||
# Required-Stop:
 | 
			
		||||
# Default-Start:     2 3 4 5
 | 
			
		||||
# Default-Stop:      0 1 6
 | 
			
		||||
# Short-Description: Osmocom Serving GPRS Support Node
 | 
			
		||||
# Description:       Osmocom Serving GPRS Support Node
 | 
			
		||||
### END INIT INFO
 | 
			
		||||
 | 
			
		||||
# Author: Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
 | 
			
		||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
 | 
			
		||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
 | 
			
		||||
NAME=osmo-sgsn                           # Introduce the short server's name here
 | 
			
		||||
DESC="Osmocom Serving GPRS Support Node" # Introduce a short description here
 | 
			
		||||
DAEMON=/usr/bin/osmo-sgsn                # Introduce the server's location here
 | 
			
		||||
SCRIPTNAME=/etc/init.d/osmocom-sgsn
 | 
			
		||||
 | 
			
		||||
# Exit if the package is not installed
 | 
			
		||||
[ -x $DAEMON ] || exit 0
 | 
			
		||||
 | 
			
		||||
# Read configuration variable file if it is present
 | 
			
		||||
[ -r /etc/default/osmocom-sgsn ] && . /etc/default/osmocom-sgsn
 | 
			
		||||
 | 
			
		||||
# Load the VERBOSE setting and other rcS variables
 | 
			
		||||
. /lib/init/vars.sh
 | 
			
		||||
 | 
			
		||||
# Define LSB log_* functions.
 | 
			
		||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
 | 
			
		||||
. /lib/lsb/init-functions
 | 
			
		||||
 | 
			
		||||
DAEMON_ARGS="$DAEMON_ARGS -D -c $CONFIG_FILE"
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that starts the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_start()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been started
 | 
			
		||||
	#   1 if daemon was already running
 | 
			
		||||
	#   2 if daemon could not be started
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
 | 
			
		||||
		|| return 1
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON -- \
 | 
			
		||||
		$DAEMON_ARGS \
 | 
			
		||||
		|| return 2
 | 
			
		||||
	# Add code here, if necessary, that waits for the process to be ready
 | 
			
		||||
	# to handle requests from services started subsequently which depend
 | 
			
		||||
	# on this one.  As a last resort, sleep for some time.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that stops the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_stop()
 | 
			
		||||
{
 | 
			
		||||
	# Return
 | 
			
		||||
	#   0 if daemon has been stopped
 | 
			
		||||
	#   1 if daemon was already stopped
 | 
			
		||||
	#   2 if daemon could not be stopped
 | 
			
		||||
	#   other if a failure occurred
 | 
			
		||||
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
 | 
			
		||||
	RETVAL="$?"
 | 
			
		||||
	[ "$RETVAL" = 2 ] && return 2
 | 
			
		||||
	# Wait for children to finish too if this is a daemon that forks
 | 
			
		||||
	# and if the daemon is only ever run from this initscript.
 | 
			
		||||
	# If the above conditions are not satisfied then add some other code
 | 
			
		||||
	# that waits for the process to drop all resources that could be
 | 
			
		||||
	# needed by services started subsequently.  A last resort is to
 | 
			
		||||
	# sleep for some time.
 | 
			
		||||
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
 | 
			
		||||
	[ "$?" = 2 ] && return 2
 | 
			
		||||
	return "$RETVAL"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Function that sends a SIGHUP to the daemon/service
 | 
			
		||||
#
 | 
			
		||||
do_reload() {
 | 
			
		||||
	#
 | 
			
		||||
	# If the daemon can reload its configuration without
 | 
			
		||||
	# restarting (for example, when it is sent a SIGHUP),
 | 
			
		||||
	# then implement that here.
 | 
			
		||||
	#
 | 
			
		||||
	start-stop-daemon --stop --signal 1 --quiet $PIDFILE --name $NAME
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
  start)
 | 
			
		||||
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
 | 
			
		||||
    do_start
 | 
			
		||||
    case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
  ;;
 | 
			
		||||
  stop)
 | 
			
		||||
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
 | 
			
		||||
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  status)
 | 
			
		||||
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
 | 
			
		||||
       ;;
 | 
			
		||||
  #reload|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If do_reload() is not implemented then leave this commented out
 | 
			
		||||
	# and leave 'force-reload' as an alias for 'restart'.
 | 
			
		||||
	#
 | 
			
		||||
	#log_daemon_msg "Reloading $DESC" "$NAME"
 | 
			
		||||
	#do_reload
 | 
			
		||||
	#log_end_msg $?
 | 
			
		||||
	#;;
 | 
			
		||||
  restart|force-reload)
 | 
			
		||||
	#
 | 
			
		||||
	# If the "reload" option is implemented then remove the
 | 
			
		||||
	# 'force-reload' alias
 | 
			
		||||
	#
 | 
			
		||||
	log_daemon_msg "Restarting $DESC" "$NAME"
 | 
			
		||||
	do_stop
 | 
			
		||||
	case "$?" in
 | 
			
		||||
	  0|1)
 | 
			
		||||
		do_start
 | 
			
		||||
		case "$?" in
 | 
			
		||||
			0) log_end_msg 0 ;;
 | 
			
		||||
			1) log_end_msg 1 ;; # Old process is still running
 | 
			
		||||
			*) log_end_msg 1 ;; # Failed to start
 | 
			
		||||
		esac
 | 
			
		||||
		;;
 | 
			
		||||
	  *)
 | 
			
		||||
	  	# Failed to stop
 | 
			
		||||
		log_end_msg 1
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
  *)
 | 
			
		||||
	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
 | 
			
		||||
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
 | 
			
		||||
	exit 3
 | 
			
		||||
	;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
:
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/osmocom-sgsn.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/osmocom-sgsn.install
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
/usr/bin/osmo-sgsn
 | 
			
		||||
							
								
								
									
										32
									
								
								debian/rules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								debian/rules
									
									
									
									
										vendored
									
									
								
							@@ -1,32 +0,0 @@
 | 
			
		||||
#!/usr/bin/make -f
 | 
			
		||||
 | 
			
		||||
# Uncomment this to turn on verbose mode.
 | 
			
		||||
#export DH_VERBOSE=1
 | 
			
		||||
 | 
			
		||||
DEBIAN  := $(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2)
 | 
			
		||||
DEBVERS := $(shell echo '$(DEBIAN)' | cut -d- -f1)
 | 
			
		||||
VERSION := $(shell echo '$(DEBVERS)' | sed -e 's/[+-].*//' -e 's/~//g')
 | 
			
		||||
 | 
			
		||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
 | 
			
		||||
 | 
			
		||||
%:
 | 
			
		||||
	dh $@ --sourcedirectory=openbsc --with autoreconf
 | 
			
		||||
 | 
			
		||||
# This is needed for debian stable (squeeze)
 | 
			
		||||
override_dh_autoreconf:
 | 
			
		||||
	cd openbsc && autoreconf --install --force
 | 
			
		||||
 | 
			
		||||
override_dh_strip:
 | 
			
		||||
	dh_strip -posmocom-bsc --dbg-package=osmocom-bsc-dbg
 | 
			
		||||
	dh_strip -posmocom-nitb --dbg-package=osmocom-nitb-dbg
 | 
			
		||||
	dh_strip -posmocom-ipaccess-utils --dbg-package=osmocom-ipaccess-utils-dbg
 | 
			
		||||
	dh_strip -posmocom-bs11-utils --dbg-package=osmocom-bs11-utils-dbg
 | 
			
		||||
	dh_strip -posmocom-sgsn --dbg-package=osmocom-sgsn-dbg
 | 
			
		||||
	dh_strip -posmocom-gbproxy --dbg-package=osmocom-gbproxy-dbg
 | 
			
		||||
	dh_strip -posmocom-bsc-nat --dbg-package=osmocom-bsc-nat-dbg
 | 
			
		||||
	dh_strip -posmo-gtphub --dbg-package=osmo-gtphub-dbg
 | 
			
		||||
 | 
			
		||||
override_dh_auto_configure:
 | 
			
		||||
	echo $(VERSION) > openbsc/.tarball-version
 | 
			
		||||
	dh_auto_configure --sourcedirectory=openbsc -- --enable-nat --enable-osmo-bsc --enable-smpp
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
3.0 (native)
 | 
			
		||||
							
								
								
									
										144
									
								
								linux-kernel/linux-2.6.27.4-misdn-abis.diff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								linux-kernel/linux-2.6.27.4-misdn-abis.diff
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
			
		||||
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c linux-2.6.27.4/drivers/isdn/mISDN/layer2.c
 | 
			
		||||
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c	2008-10-26 00:05:07.000000000 +0200
 | 
			
		||||
+++ linux-2.6.27.4/drivers/isdn/mISDN/layer2.c	2008-12-23 16:16:29.000000000 +0100
 | 
			
		||||
@@ -94,8 +94,10 @@
 | 
			
		||||
 	struct layer2 *l2 = fi->userdata;
 | 
			
		||||
 	va_list va;
 | 
			
		||||
 
 | 
			
		||||
+#if 0
 | 
			
		||||
 	if (!(*debug & DEBUG_L2_FSM))
 | 
			
		||||
 		return;
 | 
			
		||||
+#endif
 | 
			
		||||
 	va_start(va, fmt);
 | 
			
		||||
 	printk(KERN_DEBUG "l2 (tei %d): ", l2->tei);
 | 
			
		||||
 	vprintk(fmt, va);
 | 
			
		||||
@@ -882,6 +884,8 @@
 | 
			
		||||
 	l2->va = 0;
 | 
			
		||||
 	l2->vr = 0;
 | 
			
		||||
 	l2->sow = 0;
 | 
			
		||||
+	l2->sapi = skb->data[0] >> 2;
 | 
			
		||||
+	set_channel_address(&l2->ch, l2->sapi, l2->tei);
 | 
			
		||||
 	clear_exception(l2);
 | 
			
		||||
 	send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
 | 
			
		||||
 	mISDN_FsmChangeState(fi, ST_L2_7);
 | 
			
		||||
@@ -898,6 +902,7 @@
 | 
			
		||||
 	struct layer2 *l2 = fi->userdata;
 | 
			
		||||
 	struct sk_buff *skb = arg;
 | 
			
		||||
 
 | 
			
		||||
+	printk(KERN_DEBUG "l2_send_UA()\n");
 | 
			
		||||
 	send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -931,6 +936,8 @@
 | 
			
		||||
 	l2->va = 0;
 | 
			
		||||
 	l2->vr = 0;
 | 
			
		||||
 	l2->sow = 0;
 | 
			
		||||
+	l2->sapi = skb->data[0] >> 2;
 | 
			
		||||
+	set_channel_address(&l2->ch, l2->sapi, l2->tei);
 | 
			
		||||
 	mISDN_FsmChangeState(fi, ST_L2_7);
 | 
			
		||||
 	stop_t200(l2, 3);
 | 
			
		||||
 	mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
 | 
			
		||||
@@ -982,6 +989,8 @@
 | 
			
		||||
 	} else if (l2->vs != l2->va) {
 | 
			
		||||
 		skb_queue_purge(&l2->i_queue);
 | 
			
		||||
 		pr = DL_ESTABLISH_IND;
 | 
			
		||||
+		//l2->sapi = skb->data[0] >> 2;
 | 
			
		||||
+		//set_channel_address(&l2->ch, l2->sapi, l2->tei);
 | 
			
		||||
 	}
 | 
			
		||||
 	stop_t200(l2, 5);
 | 
			
		||||
 	l2->vr = 0;
 | 
			
		||||
@@ -1841,11 +1850,14 @@
 | 
			
		||||
 	u_int	l;
 | 
			
		||||
 	int	c = 0;
 | 
			
		||||
 
 | 
			
		||||
+	printk(KERN_DEBUG "ph_data_indication 0x%x 0x%x 0x%x\n", datap[0], datap[1], datap[2]);
 | 
			
		||||
+
 | 
			
		||||
 	l = l2addrsize(l2);
 | 
			
		||||
 	if (skb->len <= l) {
 | 
			
		||||
 		mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
 | 
			
		||||
 		return ret;
 | 
			
		||||
 	}
 | 
			
		||||
+#if 0
 | 
			
		||||
 	if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
 | 
			
		||||
 		psapi = *datap++;
 | 
			
		||||
 		ptei = *datap++;
 | 
			
		||||
@@ -1875,6 +1887,7 @@
 | 
			
		||||
 			return 0;
 | 
			
		||||
 		}
 | 
			
		||||
 	} else
 | 
			
		||||
+#endif
 | 
			
		||||
 		datap += l;
 | 
			
		||||
 	if (!(*datap & 1)) {	/* I-Frame */
 | 
			
		||||
 		c = iframe_error(l2, skb);
 | 
			
		||||
@@ -1890,6 +1903,7 @@
 | 
			
		||||
 			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
 | 
			
		||||
 	} else if (IsSABME(datap, l2)) {
 | 
			
		||||
 		c = unnum_error(l2, skb, CMD);
 | 
			
		||||
+		printk(KERN_DEBUG "IsSABME() returned true, unnum_error=%d\n", c);
 | 
			
		||||
 		if (!c)
 | 
			
		||||
 			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
 | 
			
		||||
 	} else if (IsUA(datap)) {
 | 
			
		||||
@@ -2087,7 +2101,7 @@
 | 
			
		||||
 		test_and_set_bit(FLG_LAPD, &l2->flag);
 | 
			
		||||
 		test_and_set_bit(FLG_LAPD_NET, &l2->flag);
 | 
			
		||||
 		test_and_set_bit(FLG_MOD128, &l2->flag);
 | 
			
		||||
-		l2->sapi = 0;
 | 
			
		||||
+		l2->sapi = 62;
 | 
			
		||||
 		l2->maxlen = MAX_DFRAME_LEN;
 | 
			
		||||
 		if (test_bit(OPTION_L2_PMX, &options))
 | 
			
		||||
 			l2->window = 7;
 | 
			
		||||
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c linux-2.6.27.4/drivers/isdn/mISDN/tei.c
 | 
			
		||||
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c	2008-10-26 00:05:07.000000000 +0200
 | 
			
		||||
+++ linux-2.6.27.4/drivers/isdn/mISDN/tei.c	2008-12-23 16:32:59.000000000 +0100
 | 
			
		||||
@@ -830,18 +830,29 @@
 | 
			
		||||
 	int		tei, ri;
 | 
			
		||||
 	struct layer2	*l2;
 | 
			
		||||
 
 | 
			
		||||
+	printk(KERN_DEBUG "new tei request: tei=%d\n", dp[3] >> 1);
 | 
			
		||||
+
 | 
			
		||||
 	ri = dp[0] << 8;
 | 
			
		||||
 	ri += dp[1];
 | 
			
		||||
-	if (!mgr->up)
 | 
			
		||||
-		goto denied;
 | 
			
		||||
-	tei = get_free_tei(mgr);
 | 
			
		||||
-	if (tei < 0) {
 | 
			
		||||
-		printk(KERN_WARNING "%s:No free tei\n", __func__);
 | 
			
		||||
+	if (!mgr->up) {
 | 
			
		||||
+		printk(KERN_DEBUG "mgr->up == NULL\n");
 | 
			
		||||
 		goto denied;
 | 
			
		||||
 	}
 | 
			
		||||
+	if (dp[3] != 0xff) {
 | 
			
		||||
+		/* This is a TEI request according to 3GPP TS 08.56 6.1.11.2 */
 | 
			
		||||
+		tei = dp[3] >> 1;
 | 
			
		||||
+	} else {
 | 
			
		||||
+		tei = get_free_tei(mgr);
 | 
			
		||||
+		if (tei < 0) {
 | 
			
		||||
+			printk(KERN_WARNING "%s:No free tei\n", __func__);
 | 
			
		||||
+			goto denied;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
 	l2 = create_new_tei(mgr, tei);
 | 
			
		||||
-	if (!l2)
 | 
			
		||||
+	if (!l2) {
 | 
			
		||||
+		printk(KERN_DEBUG "create_new_tei == NULL\n");
 | 
			
		||||
 		goto denied;
 | 
			
		||||
+	}
 | 
			
		||||
 	else
 | 
			
		||||
 		mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp);
 | 
			
		||||
 	return;
 | 
			
		||||
@@ -1159,12 +1170,14 @@
 | 
			
		||||
 		return -ENOTCONN;
 | 
			
		||||
 	if (skb->len != 3)
 | 
			
		||||
 		return -ENOTCONN;
 | 
			
		||||
+#if 0
 | 
			
		||||
 	if (skb->data[0] != 0)
 | 
			
		||||
 		/* only SAPI 0 command */
 | 
			
		||||
 		return -ENOTCONN;
 | 
			
		||||
+#endif
 | 
			
		||||
 	if (!(skb->data[1] & 1)) /* invalid EA1 */
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
-	tei = skb->data[1] >> 0;
 | 
			
		||||
+	tei = skb->data[1] >> 1;
 | 
			
		||||
 	if (tei > 63) /* not a fixed tei */
 | 
			
		||||
 		return -ENOTCONN;
 | 
			
		||||
 	if ((skb->data[2] & ~0x10) != SABME)
 | 
			
		||||
							
								
								
									
										486
									
								
								linux-kernel/linux-2.6.30-hfcmulti-multibts.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										486
									
								
								linux-kernel/linux-2.6.30-hfcmulti-multibts.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,486 @@
 | 
			
		||||
This experimental patch splits one E1 card into three virtual cards,
 | 
			
		||||
 | 
			
		||||
TS 1,2,3,4,5 is card 0
 | 
			
		||||
TS 6,7,8,9,10 is card 1
 | 
			
		||||
TS 11,12,13,14 is card 2
 | 
			
		||||
 | 
			
		||||
This allows you to run one L2 TEI handler on each of the virtual cards,
 | 
			
		||||
which is required if you want to run multiple BTS on a single E1 link.
 | 
			
		||||
 | 
			
		||||
Thanks to Andreas Eversberg for this patch.
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
 | 
			
		||||
index 0c77386..02dd4a1 100644
 | 
			
		||||
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
 | 
			
		||||
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
 | 
			
		||||
@@ -209,14 +209,17 @@ struct hfc_multi {
 | 
			
		||||
 	u_long		ledstate; /* save last state of leds */
 | 
			
		||||
 	int		opticalsupport; /* has the e1 board */
 | 
			
		||||
 					/* an optical Interface */
 | 
			
		||||
-	int		dslot;	/* channel # of d-channel (E1) default 16 */
 | 
			
		||||
+
 | 
			
		||||
+	u_int		bmask[32]; /* bitmask of bchannels for port */
 | 
			
		||||
+	u_char		dnum[32]; /* array of used dchannel numbers for port */
 | 
			
		||||
+	u_char		created[32]; /* what port is created */
 | 
			
		||||
+	u_int		activity[32]; 	/* if there is any action on this */
 | 
			
		||||
+					/* port (will be cleared after */
 | 
			
		||||
+					/* showing led-states) */
 | 
			
		||||
 
 | 
			
		||||
 	u_long		wdcount; 	/* every 500 ms we need to */
 | 
			
		||||
 					/* send the watchdog a signal */
 | 
			
		||||
 	u_char		wdbyte; /* watchdog toggle byte */
 | 
			
		||||
-	u_int		activity[8]; 	/* if there is any action on this */
 | 
			
		||||
-					/* port (will be cleared after */
 | 
			
		||||
-					/* showing led-states) */
 | 
			
		||||
 	int		e1_state; /* keep track of last state */
 | 
			
		||||
 	int		e1_getclock; /* if sync is retrieved from interface */
 | 
			
		||||
 	int		syncronized; /* keep track of existing sync interface */
 | 
			
		||||
@@ -233,7 +236,6 @@ struct hfc_multi {
 | 
			
		||||
 	 * the bch->channel is equvalent to the hfc-channel
 | 
			
		||||
 	 */
 | 
			
		||||
 	struct hfc_chan	chan[32];
 | 
			
		||||
-	u_char		created[8]; /* what port is created */
 | 
			
		||||
 	signed char	slot_owner[256]; /* owner channel of slot */
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
 | 
			
		||||
index e1dab30..4fe2d27 100644
 | 
			
		||||
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
 | 
			
		||||
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
 | 
			
		||||
@@ -1619,8 +1619,8 @@ hfcmulti_leds(struct hfc_multi *hc)
 | 
			
		||||
 		 * left red:       frame sync, but no L1
 | 
			
		||||
 		 * right green:    L2 active
 | 
			
		||||
 		 */
 | 
			
		||||
-		if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */
 | 
			
		||||
-			if (hc->chan[hc->dslot].dch->dev.D.protocol
 | 
			
		||||
+		if (hc->chan[hc->dnum[0]].sync != 2) { /* no frame sync */
 | 
			
		||||
+			if (hc->chan[hc->dnum[0]].dch->dev.D.protocol
 | 
			
		||||
 				!= ISDN_P_NT_E1) {
 | 
			
		||||
 				led[0] = 1;
 | 
			
		||||
 				led[1] = 1;
 | 
			
		||||
@@ -2428,55 +2428,56 @@ handle_timer_irq(struct hfc_multi *hc)
 | 
			
		||||
 			}
 | 
			
		||||
 		}
 | 
			
		||||
 	if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
 | 
			
		||||
-		dch = hc->chan[hc->dslot].dch;
 | 
			
		||||
-		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
 | 
			
		||||
+#warning todo: put interface parameters to hc
 | 
			
		||||
+		dch = hc->chan[hc->dnum[0]].dch;
 | 
			
		||||
+		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
 | 
			
		||||
 			/* LOS */
 | 
			
		||||
 			temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
 | 
			
		||||
-			if (!temp && hc->chan[hc->dslot].los)
 | 
			
		||||
+			if (!temp && hc->chan[hc->dnum[0]].los)
 | 
			
		||||
 				signal_state_up(dch, L1_SIGNAL_LOS_ON,
 | 
			
		||||
 				    "LOS detected");
 | 
			
		||||
-			if (temp && !hc->chan[hc->dslot].los)
 | 
			
		||||
+			if (temp && !hc->chan[hc->dnum[0]].los)
 | 
			
		||||
 				signal_state_up(dch, L1_SIGNAL_LOS_OFF,
 | 
			
		||||
 				    "LOS gone");
 | 
			
		||||
-			hc->chan[hc->dslot].los = temp;
 | 
			
		||||
+			hc->chan[hc->dnum[0]].los = temp;
 | 
			
		||||
 		}
 | 
			
		||||
-		if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {
 | 
			
		||||
+		if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
 | 
			
		||||
 			/* AIS */
 | 
			
		||||
 			temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
 | 
			
		||||
-			if (!temp && hc->chan[hc->dslot].ais)
 | 
			
		||||
+			if (!temp && hc->chan[hc->dnum[0]].ais)
 | 
			
		||||
 				signal_state_up(dch, L1_SIGNAL_AIS_ON,
 | 
			
		||||
 				    "AIS detected");
 | 
			
		||||
-			if (temp && !hc->chan[hc->dslot].ais)
 | 
			
		||||
+			if (temp && !hc->chan[hc->dnum[0]].ais)
 | 
			
		||||
 				signal_state_up(dch, L1_SIGNAL_AIS_OFF,
 | 
			
		||||
 				    "AIS gone");
 | 
			
		||||
-			hc->chan[hc->dslot].ais = temp;
 | 
			
		||||
+			hc->chan[hc->dnum[0]].ais = temp;
 | 
			
		||||
 		}
 | 
			
		||||
-		if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {
 | 
			
		||||
+		if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
 | 
			
		||||
 			/* SLIP */
 | 
			
		||||
 			temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
 | 
			
		||||
-			if (!temp && hc->chan[hc->dslot].slip_rx)
 | 
			
		||||
+			if (!temp && hc->chan[hc->dnum[0]].slip_rx)
 | 
			
		||||
 				signal_state_up(dch, L1_SIGNAL_SLIP_RX,
 | 
			
		||||
 				    " bit SLIP detected RX");
 | 
			
		||||
-			hc->chan[hc->dslot].slip_rx = temp;
 | 
			
		||||
+			hc->chan[hc->dnum[0]].slip_rx = temp;
 | 
			
		||||
 			temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
 | 
			
		||||
-			if (!temp && hc->chan[hc->dslot].slip_tx)
 | 
			
		||||
+			if (!temp && hc->chan[hc->dnum[0]].slip_tx)
 | 
			
		||||
 				signal_state_up(dch, L1_SIGNAL_SLIP_TX,
 | 
			
		||||
 				    " bit SLIP detected TX");
 | 
			
		||||
-			hc->chan[hc->dslot].slip_tx = temp;
 | 
			
		||||
+			hc->chan[hc->dnum[0]].slip_tx = temp;
 | 
			
		||||
 		}
 | 
			
		||||
-		if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {
 | 
			
		||||
+		if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
 | 
			
		||||
 			/* RDI */
 | 
			
		||||
 			temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
 | 
			
		||||
-			if (!temp && hc->chan[hc->dslot].rdi)
 | 
			
		||||
+			if (!temp && hc->chan[hc->dnum[0]].rdi)
 | 
			
		||||
 				signal_state_up(dch, L1_SIGNAL_RDI_ON,
 | 
			
		||||
 				    "RDI detected");
 | 
			
		||||
-			if (temp && !hc->chan[hc->dslot].rdi)
 | 
			
		||||
+			if (temp && !hc->chan[hc->dnum[0]].rdi)
 | 
			
		||||
 				signal_state_up(dch, L1_SIGNAL_RDI_OFF,
 | 
			
		||||
 				    "RDI gone");
 | 
			
		||||
-			hc->chan[hc->dslot].rdi = temp;
 | 
			
		||||
+			hc->chan[hc->dnum[0]].rdi = temp;
 | 
			
		||||
 		}
 | 
			
		||||
 		temp = HFC_inb_nodebug(hc, R_JATT_DIR);
 | 
			
		||||
-		switch (hc->chan[hc->dslot].sync) {
 | 
			
		||||
+		switch (hc->chan[hc->dnum[0]].sync) {
 | 
			
		||||
 		case 0:
 | 
			
		||||
 			if ((temp & 0x60) == 0x60) {
 | 
			
		||||
 				if (debug & DEBUG_HFCMULTI_SYNC)
 | 
			
		||||
@@ -2485,10 +2486,10 @@ handle_timer_irq(struct hfc_multi *hc)
 | 
			
		||||
 					    "in clock sync\n",
 | 
			
		||||
 					    __func__, hc->id);
 | 
			
		||||
 				HFC_outb(hc, R_RX_OFF,
 | 
			
		||||
-				    hc->chan[hc->dslot].jitter | V_RX_INIT);
 | 
			
		||||
+				    hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
 | 
			
		||||
 				HFC_outb(hc, R_TX_OFF,
 | 
			
		||||
-				    hc->chan[hc->dslot].jitter | V_RX_INIT);
 | 
			
		||||
-				hc->chan[hc->dslot].sync = 1;
 | 
			
		||||
+				    hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
 | 
			
		||||
+				hc->chan[hc->dnum[0]].sync = 1;
 | 
			
		||||
 				goto check_framesync;
 | 
			
		||||
 			}
 | 
			
		||||
 			break;
 | 
			
		||||
@@ -2499,7 +2500,7 @@ handle_timer_irq(struct hfc_multi *hc)
 | 
			
		||||
 					    "%s: (id=%d) E1 "
 | 
			
		||||
 					    "lost clock sync\n",
 | 
			
		||||
 					    __func__, hc->id);
 | 
			
		||||
-				hc->chan[hc->dslot].sync = 0;
 | 
			
		||||
+				hc->chan[hc->dnum[0]].sync = 0;
 | 
			
		||||
 				break;
 | 
			
		||||
 			}
 | 
			
		||||
 check_framesync:
 | 
			
		||||
@@ -2510,7 +2511,7 @@ check_framesync:
 | 
			
		||||
 					    "%s: (id=%d) E1 "
 | 
			
		||||
 					    "now in frame sync\n",
 | 
			
		||||
 					    __func__, hc->id);
 | 
			
		||||
-				hc->chan[hc->dslot].sync = 2;
 | 
			
		||||
+				hc->chan[hc->dnum[0]].sync = 2;
 | 
			
		||||
 			}
 | 
			
		||||
 			break;
 | 
			
		||||
 		case 2:
 | 
			
		||||
@@ -2520,7 +2521,7 @@ check_framesync:
 | 
			
		||||
 					    "%s: (id=%d) E1 lost "
 | 
			
		||||
 					    "clock & frame sync\n",
 | 
			
		||||
 					    __func__, hc->id);
 | 
			
		||||
-				hc->chan[hc->dslot].sync = 0;
 | 
			
		||||
+				hc->chan[hc->dnum[0]].sync = 0;
 | 
			
		||||
 				break;
 | 
			
		||||
 			}
 | 
			
		||||
 			temp = HFC_inb_nodebug(hc, R_SYNC_STA);
 | 
			
		||||
@@ -2530,7 +2531,7 @@ check_framesync:
 | 
			
		||||
 					    "%s: (id=%d) E1 "
 | 
			
		||||
 					    "lost frame sync\n",
 | 
			
		||||
 					    __func__, hc->id);
 | 
			
		||||
-				hc->chan[hc->dslot].sync = 1;
 | 
			
		||||
+				hc->chan[hc->dnum[0]].sync = 1;
 | 
			
		||||
 			}
 | 
			
		||||
 			break;
 | 
			
		||||
 		}
 | 
			
		||||
@@ -2746,7 +2747,8 @@ hfcmulti_interrupt(int intno, void *dev_id)
 | 
			
		||||
 		if (r_irq_misc & V_STA_IRQ) {
 | 
			
		||||
 			if (hc->ctype == HFC_TYPE_E1) {
 | 
			
		||||
 				/* state machine */
 | 
			
		||||
-				dch = hc->chan[hc->dslot].dch;
 | 
			
		||||
+#warning todo
 | 
			
		||||
+				dch = hc->chan[hc->dnum[0]].dch;
 | 
			
		||||
 				e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
 | 
			
		||||
 				if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
 | 
			
		||||
 				 && hc->e1_getclock) {
 | 
			
		||||
@@ -2768,7 +2770,15 @@ hfcmulti_interrupt(int intno, void *dev_id)
 | 
			
		||||
 				}
 | 
			
		||||
 				dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
 | 
			
		||||
 					& 0x7;
 | 
			
		||||
+#warning todo hack!!! broadcast state change!!!
 | 
			
		||||
+				dch = hc->chan[hc->dnum[0]].dch;
 | 
			
		||||
 				schedule_event(dch, FLG_PHCHANGE);
 | 
			
		||||
+				dch = hc->chan[hc->dnum[1]].dch;
 | 
			
		||||
+				dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
 | 
			
		||||
+					& 0x7;
 | 
			
		||||
+				schedule_event(dch, FLG_PHCHANGE);
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
 				if (debug & DEBUG_HFCMULTI_STATE)
 | 
			
		||||
 					printk(KERN_DEBUG
 | 
			
		||||
 					    "%s: E1 (id=%d) newstate %x\n",
 | 
			
		||||
@@ -3851,31 +3861,35 @@ hfcmulti_initmode(struct dchannel *dch)
 | 
			
		||||
 	if (debug & DEBUG_HFCMULTI_INIT)
 | 
			
		||||
 		printk(KERN_DEBUG "%s: entered\n", __func__);
 | 
			
		||||
 
 | 
			
		||||
+	i = dch->slot;
 | 
			
		||||
+	pt = hc->chan[i].port;
 | 
			
		||||
 	if (hc->ctype == HFC_TYPE_E1) {
 | 
			
		||||
-		hc->chan[hc->dslot].slot_tx = -1;
 | 
			
		||||
-		hc->chan[hc->dslot].slot_rx = -1;
 | 
			
		||||
-		hc->chan[hc->dslot].conf = -1;
 | 
			
		||||
-		if (hc->dslot) {
 | 
			
		||||
-			mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,
 | 
			
		||||
+		/* E1 */
 | 
			
		||||
+#warning todo: don''t do it if dnum == 0
 | 
			
		||||
+		hc->chan[hc->dnum[pt]].slot_tx = -1;
 | 
			
		||||
+		hc->chan[hc->dnum[pt]].slot_rx = -1;
 | 
			
		||||
+		hc->chan[hc->dnum[pt]].conf = -1;
 | 
			
		||||
+		if (hc->dnum[pt]) {
 | 
			
		||||
+			mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
 | 
			
		||||
 				-1, 0, -1, 0);
 | 
			
		||||
 			dch->timer.function = (void *) hfcmulti_dbusy_timer;
 | 
			
		||||
 			dch->timer.data = (long) dch;
 | 
			
		||||
 			init_timer(&dch->timer);
 | 
			
		||||
 		}
 | 
			
		||||
 		for (i = 1; i <= 31; i++) {
 | 
			
		||||
-			if (i == hc->dslot)
 | 
			
		||||
+			if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
 | 
			
		||||
 				continue;
 | 
			
		||||
 			hc->chan[i].slot_tx = -1;
 | 
			
		||||
 			hc->chan[i].slot_rx = -1;
 | 
			
		||||
 			hc->chan[i].conf = -1;
 | 
			
		||||
 			mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
 | 
			
		||||
 		}
 | 
			
		||||
-		/* E1 */
 | 
			
		||||
-		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
 | 
			
		||||
+#warning todo (global)
 | 
			
		||||
+		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[pt]].cfg)) {
 | 
			
		||||
 			HFC_outb(hc, R_LOS0, 255); /* 2 ms */
 | 
			
		||||
 			HFC_outb(hc, R_LOS1, 255); /* 512 ms */
 | 
			
		||||
 		}
 | 
			
		||||
-		if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) {
 | 
			
		||||
+		if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[pt]].cfg)) {
 | 
			
		||||
 			HFC_outb(hc, R_RX0, 0);
 | 
			
		||||
 			hc->hw.r_tx0 = 0 | V_OUT_EN;
 | 
			
		||||
 		} else {
 | 
			
		||||
@@ -3888,12 +3902,12 @@ hfcmulti_initmode(struct dchannel *dch)
 | 
			
		||||
 		HFC_outb(hc, R_TX_FR0, 0x00);
 | 
			
		||||
 		HFC_outb(hc, R_TX_FR1, 0xf8);
 | 
			
		||||
 
 | 
			
		||||
-		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
 | 
			
		||||
+		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
 | 
			
		||||
 			HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
 | 
			
		||||
 
 | 
			
		||||
 		HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
 | 
			
		||||
 
 | 
			
		||||
-		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
 | 
			
		||||
+		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
 | 
			
		||||
 			HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
 | 
			
		||||
 
 | 
			
		||||
 		if (dch->dev.D.protocol == ISDN_P_NT_E1) {
 | 
			
		||||
@@ -3957,7 +3971,7 @@ hfcmulti_initmode(struct dchannel *dch)
 | 
			
		||||
 			plxsd_checksync(hc, 0);
 | 
			
		||||
 		}
 | 
			
		||||
 	} else {
 | 
			
		||||
-		i = dch->slot;
 | 
			
		||||
+		/* ST */
 | 
			
		||||
 		hc->chan[i].slot_tx = -1;
 | 
			
		||||
 		hc->chan[i].slot_rx = -1;
 | 
			
		||||
 		hc->chan[i].conf = -1;
 | 
			
		||||
@@ -3973,8 +3987,6 @@ hfcmulti_initmode(struct dchannel *dch)
 | 
			
		||||
 		hc->chan[i - 1].slot_rx = -1;
 | 
			
		||||
 		hc->chan[i - 1].conf = -1;
 | 
			
		||||
 		mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
 | 
			
		||||
-		/* ST */
 | 
			
		||||
-		pt = hc->chan[i].port;
 | 
			
		||||
 		/* select interface */
 | 
			
		||||
 		HFC_outb(hc, R_ST_SEL, pt);
 | 
			
		||||
 		/* undocumented: delay after R_ST_SEL */
 | 
			
		||||
@@ -4557,6 +4569,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
 | 
			
		||||
 		}
 | 
			
		||||
 		/* free channels */
 | 
			
		||||
 		for (i = 0; i <= 31; i++) {
 | 
			
		||||
+			if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
 | 
			
		||||
+				continue;
 | 
			
		||||
 			if (hc->chan[i].bch) {
 | 
			
		||||
 				if (debug & DEBUG_HFCMULTI_INIT)
 | 
			
		||||
 					printk(KERN_DEBUG
 | 
			
		||||
@@ -4680,12 +4694,13 @@ release_card(struct hfc_multi *hc)
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int
 | 
			
		||||
-init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
+init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
 | 
			
		||||
 {
 | 
			
		||||
 	struct dchannel	*dch;
 | 
			
		||||
 	struct bchannel	*bch;
 | 
			
		||||
 	int		ch, ret = 0;
 | 
			
		||||
 	char		name[MISDN_MAX_IDLEN];
 | 
			
		||||
+	int		bcount = 0;
 | 
			
		||||
 
 | 
			
		||||
 	dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
 | 
			
		||||
 	if (!dch)
 | 
			
		||||
@@ -4698,13 +4713,12 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
 	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
 | 
			
		||||
 	dch->dev.D.send = handle_dmsg;
 | 
			
		||||
 	dch->dev.D.ctrl = hfcm_dctrl;
 | 
			
		||||
-	dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
 | 
			
		||||
-	dch->slot = hc->dslot;
 | 
			
		||||
-	hc->chan[hc->dslot].dch = dch;
 | 
			
		||||
-	hc->chan[hc->dslot].port = 0;
 | 
			
		||||
-	hc->chan[hc->dslot].nt_timer = -1;
 | 
			
		||||
+	dch->slot = hc->dnum[pt];
 | 
			
		||||
+	hc->chan[hc->dnum[pt]].dch = dch;
 | 
			
		||||
+	hc->chan[hc->dnum[pt]].port = pt;
 | 
			
		||||
+	hc->chan[hc->dnum[pt]].nt_timer = -1;
 | 
			
		||||
 	for (ch = 1; ch <= 31; ch++) {
 | 
			
		||||
-		if (ch == hc->dslot) /* skip dchannel */
 | 
			
		||||
+		if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
 | 
			
		||||
 			continue;
 | 
			
		||||
 		bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
 | 
			
		||||
 		if (!bch) {
 | 
			
		||||
@@ -4733,7 +4747,10 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
 		hc->chan[ch].bch = bch;
 | 
			
		||||
 		hc->chan[ch].port = 0;
 | 
			
		||||
 		set_channelmap(bch->nr, dch->dev.channelmap);
 | 
			
		||||
+		bcount++;
 | 
			
		||||
 	}
 | 
			
		||||
+	dch->dev.nrbchan = bcount;
 | 
			
		||||
+#warning todo: must be set globally, and must be a seperate function
 | 
			
		||||
 	/* set optical line type */
 | 
			
		||||
 	if (port[Port_cnt] & 0x001) {
 | 
			
		||||
 		if (!m->opticalsupport)  {
 | 
			
		||||
@@ -4749,7 +4766,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
 				    __func__,
 | 
			
		||||
 				    HFC_cnt + 1, 1);
 | 
			
		||||
 			test_and_set_bit(HFC_CFG_OPTICAL,
 | 
			
		||||
-			    &hc->chan[hc->dslot].cfg);
 | 
			
		||||
+			    &hc->chan[hc->dnum[pt]].cfg);
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 	/* set LOS report */
 | 
			
		||||
@@ -4759,7 +4776,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
 			    "LOS report: card(%d) port(%d)\n",
 | 
			
		||||
 			    __func__, HFC_cnt + 1, 1);
 | 
			
		||||
 		test_and_set_bit(HFC_CFG_REPORT_LOS,
 | 
			
		||||
-		    &hc->chan[hc->dslot].cfg);
 | 
			
		||||
+		    &hc->chan[hc->dnum[pt]].cfg);
 | 
			
		||||
 	}
 | 
			
		||||
 	/* set AIS report */
 | 
			
		||||
 	if (port[Port_cnt] & 0x008) {
 | 
			
		||||
@@ -4768,7 +4785,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
 			    "AIS report: card(%d) port(%d)\n",
 | 
			
		||||
 			    __func__, HFC_cnt + 1, 1);
 | 
			
		||||
 		test_and_set_bit(HFC_CFG_REPORT_AIS,
 | 
			
		||||
-		    &hc->chan[hc->dslot].cfg);
 | 
			
		||||
+		    &hc->chan[hc->dnum[pt]].cfg);
 | 
			
		||||
 	}
 | 
			
		||||
 	/* set SLIP report */
 | 
			
		||||
 	if (port[Port_cnt] & 0x010) {
 | 
			
		||||
@@ -4778,7 +4795,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
 			    "card(%d) port(%d)\n",
 | 
			
		||||
 			    __func__, HFC_cnt + 1, 1);
 | 
			
		||||
 		test_and_set_bit(HFC_CFG_REPORT_SLIP,
 | 
			
		||||
-		    &hc->chan[hc->dslot].cfg);
 | 
			
		||||
+		    &hc->chan[hc->dnum[pt]].cfg);
 | 
			
		||||
 	}
 | 
			
		||||
 	/* set RDI report */
 | 
			
		||||
 	if (port[Port_cnt] & 0x020) {
 | 
			
		||||
@@ -4788,7 +4805,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
 			    "card(%d) port(%d)\n",
 | 
			
		||||
 			    __func__, HFC_cnt + 1, 1);
 | 
			
		||||
 		test_and_set_bit(HFC_CFG_REPORT_RDI,
 | 
			
		||||
-		    &hc->chan[hc->dslot].cfg);
 | 
			
		||||
+		    &hc->chan[hc->dnum[pt]].cfg);
 | 
			
		||||
 	}
 | 
			
		||||
 	/* set CRC-4 Mode */
 | 
			
		||||
 	if (!(port[Port_cnt] & 0x100)) {
 | 
			
		||||
@@ -4797,7 +4814,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
 				" card(%d) port(%d)\n",
 | 
			
		||||
 				__func__, HFC_cnt + 1, 1);
 | 
			
		||||
 		test_and_set_bit(HFC_CFG_CRC4,
 | 
			
		||||
-		    &hc->chan[hc->dslot].cfg);
 | 
			
		||||
+		    &hc->chan[hc->dnum[pt]].cfg);
 | 
			
		||||
 	} else {
 | 
			
		||||
 		if (debug & DEBUG_HFCMULTI_INIT)
 | 
			
		||||
 			printk(KERN_DEBUG "%s: PORT turn off CRC4"
 | 
			
		||||
@@ -4829,20 +4846,23 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 | 
			
		||||
 	}
 | 
			
		||||
 	/* set elastic jitter buffer */
 | 
			
		||||
 	if (port[Port_cnt] & 0x3000) {
 | 
			
		||||
-		hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;
 | 
			
		||||
+		hc->chan[hc->dnum[pt]].jitter = (port[Port_cnt]>>12) & 0x3;
 | 
			
		||||
 		if (debug & DEBUG_HFCMULTI_INIT)
 | 
			
		||||
 			printk(KERN_DEBUG
 | 
			
		||||
 			    "%s: PORT set elastic "
 | 
			
		||||
 			    "buffer to %d: card(%d) port(%d)\n",
 | 
			
		||||
-			    __func__, hc->chan[hc->dslot].jitter,
 | 
			
		||||
+			    __func__, hc->chan[hc->dnum[pt]].jitter,
 | 
			
		||||
 			    HFC_cnt + 1, 1);
 | 
			
		||||
 	} else
 | 
			
		||||
-		hc->chan[hc->dslot].jitter = 2; /* default */
 | 
			
		||||
-	snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
 | 
			
		||||
+		hc->chan[hc->dnum[pt]].jitter = 2; /* default */
 | 
			
		||||
+	if (hc->ports > 1)
 | 
			
		||||
+		snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d", HFC_cnt + 1, pt+1);
 | 
			
		||||
+	else
 | 
			
		||||
+		snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
 | 
			
		||||
 	ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		goto free_chan;
 | 
			
		||||
-	hc->created[0] = 1;
 | 
			
		||||
+	hc->created[pt] = 1;
 | 
			
		||||
 	return ret;
 | 
			
		||||
 free_chan:
 | 
			
		||||
 	release_port(hc, dch);
 | 
			
		||||
@@ -5009,18 +5029,30 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 | 
			
		||||
 	hc->id = HFC_cnt;
 | 
			
		||||
 	hc->pcm = pcm[HFC_cnt];
 | 
			
		||||
 	hc->io_mode = iomode[HFC_cnt];
 | 
			
		||||
+#warning todo: rework module parameters for customizing e1 fragments.... yea, let''s call it: fragments
 | 
			
		||||
 	if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {
 | 
			
		||||
-		hc->dslot = 0;
 | 
			
		||||
+		hc->dnum[0] = 0;
 | 
			
		||||
 		printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
 | 
			
		||||
 			"31 B-channels\n");
 | 
			
		||||
 	}
 | 
			
		||||
 	if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32
 | 
			
		||||
 	    && hc->ctype == HFC_TYPE_E1) {
 | 
			
		||||
-		hc->dslot = dslot[HFC_cnt];
 | 
			
		||||
+		hc->dnum[0] = dslot[HFC_cnt];
 | 
			
		||||
 		printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
 | 
			
		||||
 			"time slot %d\n", dslot[HFC_cnt]);
 | 
			
		||||
 	} else
 | 
			
		||||
-		hc->dslot = 16;
 | 
			
		||||
+		hc->dnum[0] = 16;
 | 
			
		||||
+
 | 
			
		||||
+#warning todo HACK!!! just a small map of two "fragments"
 | 
			
		||||
+	if (hc->ctype == HFC_TYPE_E1) {
 | 
			
		||||
+		hc->dnum[0] = 1;
 | 
			
		||||
+		hc->bmask[0] = 0x0000003c;
 | 
			
		||||
+		hc->dnum[1] = 6;
 | 
			
		||||
+		hc->bmask[1] = 0x00000780;
 | 
			
		||||
+		hc->dnum[2] = 11;
 | 
			
		||||
+		hc->bmask[2] = 0x00007800;
 | 
			
		||||
+		hc->ports = 3;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	/* set chip specific features */
 | 
			
		||||
 	hc->masterclk = -1;
 | 
			
		||||
@@ -5103,7 +5135,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 | 
			
		||||
 			goto free_card;
 | 
			
		||||
 		}
 | 
			
		||||
 		if (hc->ctype == HFC_TYPE_E1)
 | 
			
		||||
-			ret_err = init_e1_port(hc, m);
 | 
			
		||||
+			ret_err = init_e1_port(hc, m, pt);
 | 
			
		||||
 		else
 | 
			
		||||
 			ret_err = init_multi_port(hc, pt);
 | 
			
		||||
 		if (debug & DEBUG_HFCMULTI_INIT)
 | 
			
		||||
@@ -5115,10 +5147,14 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 | 
			
		||||
 		if (ret_err) {
 | 
			
		||||
 			while (pt) { /* release already registered ports */
 | 
			
		||||
 				pt--;
 | 
			
		||||
-				release_port(hc, hc->chan[(pt << 2) + 2].dch);
 | 
			
		||||
+				if (hc->ctype == HFC_TYPE_E1)
 | 
			
		||||
+					release_port(hc, hc->chan[hc->dnum[pt]].dch);
 | 
			
		||||
+				else
 | 
			
		||||
+					release_port(hc, hc->chan[(pt << 2) + 2].dch);
 | 
			
		||||
 			}
 | 
			
		||||
 			goto free_card;
 | 
			
		||||
 		}
 | 
			
		||||
+#warning todo: count it right, add additional "fragment" counter...
 | 
			
		||||
 		Port_cnt++;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										76
									
								
								openbsc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								openbsc/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,103 +1,39 @@
 | 
			
		||||
*.o
 | 
			
		||||
*.lo
 | 
			
		||||
*.a
 | 
			
		||||
.deps
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
bscconfig.h
 | 
			
		||||
bscconfig.h.in
 | 
			
		||||
openbsc.pc
 | 
			
		||||
src/osmo-nitb/osmo-nitb
 | 
			
		||||
src/osmo-bsc_mgcp/osmo-bsc_mgcp
 | 
			
		||||
src/osmo-bsc/osmo-bsc
 | 
			
		||||
src/utils/meas_vis
 | 
			
		||||
src/utils/meas_json
 | 
			
		||||
src/utils/osmo-meas-pcap2db
 | 
			
		||||
src/utils/osmo-meas-udp2db
 | 
			
		||||
src/utils/smpp_mirror
 | 
			
		||||
bsc_hack
 | 
			
		||||
bsc_msc_ip
 | 
			
		||||
*.*~
 | 
			
		||||
*.sw?
 | 
			
		||||
.libs
 | 
			
		||||
*.pyc
 | 
			
		||||
*.gcda
 | 
			
		||||
*.gcno
 | 
			
		||||
 | 
			
		||||
#configure
 | 
			
		||||
aclocal.m4
 | 
			
		||||
autom4te.cache/
 | 
			
		||||
config.log
 | 
			
		||||
config.status
 | 
			
		||||
config.guess
 | 
			
		||||
config.sub
 | 
			
		||||
configure
 | 
			
		||||
compile
 | 
			
		||||
depcomp
 | 
			
		||||
install-sh
 | 
			
		||||
missing
 | 
			
		||||
stamp-h1
 | 
			
		||||
libtool
 | 
			
		||||
ltmain.sh
 | 
			
		||||
 | 
			
		||||
# git-version-gen magic
 | 
			
		||||
.tarball-version
 | 
			
		||||
.version
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# apps and app data
 | 
			
		||||
hlr.sqlite3
 | 
			
		||||
src/utils/bs11_config
 | 
			
		||||
src/ipaccess/ipaccess-config
 | 
			
		||||
src/ipaccess/abisip-find
 | 
			
		||||
src/ipaccess/ipaccess-firmware
 | 
			
		||||
src/ipaccess/ipaccess-proxy
 | 
			
		||||
src/utils/isdnsync
 | 
			
		||||
src/nat/bsc_nat
 | 
			
		||||
src/gprs/osmo-sgsn
 | 
			
		||||
src/gprs/osmo-gbproxy
 | 
			
		||||
src/gprs/osmo-gtphub
 | 
			
		||||
src/osmo-bsc_nat/osmo-bsc_nat
 | 
			
		||||
src/libcommon/gsup_test_client
 | 
			
		||||
bs11_config
 | 
			
		||||
ipaccess-config
 | 
			
		||||
ipaccess-find
 | 
			
		||||
isdnsync
 | 
			
		||||
 | 
			
		||||
#tests
 | 
			
		||||
tests/testsuite.dir
 | 
			
		||||
tests/bsc-nat/bsc_nat_test
 | 
			
		||||
tests/bsc-nat-trie/bsc_nat_trie_test
 | 
			
		||||
tests/channel/channel_test
 | 
			
		||||
tests/db/db_test
 | 
			
		||||
tests/debug/debug_test
 | 
			
		||||
tests/gsm0408/gsm0408_test
 | 
			
		||||
tests/mgcp/mgcp_test
 | 
			
		||||
tests/sccp/sccp_test
 | 
			
		||||
tests/sms/sms_test
 | 
			
		||||
tests/timer/timer_test
 | 
			
		||||
tests/gprs/gprs_test
 | 
			
		||||
tests/gbproxy/gbproxy_test
 | 
			
		||||
tests/abis/abis_test
 | 
			
		||||
tests/si/si_test
 | 
			
		||||
tests/smpp/smpp_test
 | 
			
		||||
tests/bsc/bsc_test
 | 
			
		||||
tests/trau/trau_test
 | 
			
		||||
tests/mgcp/mgcp_transcoding_test
 | 
			
		||||
tests/sgsn/sgsn_test
 | 
			
		||||
tests/subscr/subscr_test
 | 
			
		||||
tests/subscr/bsc_subscr_test
 | 
			
		||||
tests/oap/oap_test
 | 
			
		||||
tests/gtphub/gtphub_test
 | 
			
		||||
tests/mm_auth/mm_auth_test
 | 
			
		||||
tests/xid/xid_test
 | 
			
		||||
tests/sndcp_xid/sndcp_xid_test
 | 
			
		||||
tests/slhc/slhc_test
 | 
			
		||||
tests/v42bis/v42bis_test
 | 
			
		||||
tests/nanobts_omlattr/nanobts_omlattr_test
 | 
			
		||||
tests/oap/oap_client_test
 | 
			
		||||
 | 
			
		||||
tests/atconfig
 | 
			
		||||
tests/atlocal
 | 
			
		||||
tests/package.m4
 | 
			
		||||
tests/testsuite
 | 
			
		||||
tests/testsuite.log
 | 
			
		||||
 | 
			
		||||
gsn_restart
 | 
			
		||||
src/openbsc.cfg*
 | 
			
		||||
writtenconfig/
 | 
			
		||||
gtphub_restart_count
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,3 @@ Holger Freyther <zecke@selfish.org>
 | 
			
		||||
Jan Luebbe <jluebbe@debian.org>
 | 
			
		||||
Stefan Schmidt <stefan@datenfreihafen.org>
 | 
			
		||||
Daniel Willmann <daniel@totalueberwachung.de>
 | 
			
		||||
Andreas Eversberg <Andreas.Eversberg@versatel.de>
 | 
			
		||||
Sylvain Munaut <246tnt@gmail.com>
 | 
			
		||||
Jacob Erlbeck <jerlbeck@sysmocom.de>
 | 
			
		||||
Neels Hofmeyr <nhofmeyr@sysmocom.de>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										884
									
								
								openbsc/COPYING
									
									
									
									
									
								
							
							
						
						
									
										884
									
								
								openbsc/COPYING
									
									
									
									
									
								
							@@ -1,620 +1,281 @@
 | 
			
		||||
                    GNU AFFERO GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 3, 19 November 2007
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
		       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 | 
			
		||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 | 
			
		||||
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
			    Preamble
 | 
			
		||||
 | 
			
		||||
  The GNU Affero General Public License is a free, copyleft license for
 | 
			
		||||
software and other kinds of works, specifically designed to ensure
 | 
			
		||||
cooperation with the community in the case of network server software.
 | 
			
		||||
 | 
			
		||||
  The licenses for most software and other practical works are designed
 | 
			
		||||
to take away your freedom to share and change the works.  By contrast,
 | 
			
		||||
our General Public Licenses are intended to guarantee your freedom to
 | 
			
		||||
share and change all versions of a program--to make sure it remains free
 | 
			
		||||
software for all its users.
 | 
			
		||||
  The licenses for most software are designed to take away your
 | 
			
		||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
			
		||||
License is intended to guarantee your freedom to share and change free
 | 
			
		||||
software--to make sure the software is free for all its users.  This
 | 
			
		||||
General Public License applies to most of the Free Software
 | 
			
		||||
Foundation's software and to any other program whose authors commit to
 | 
			
		||||
using it.  (Some other Free Software Foundation software is covered by
 | 
			
		||||
the GNU Lesser General Public License instead.)  You can apply it to
 | 
			
		||||
your programs, too.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
price.  Our General Public Licenses are designed to make sure that you
 | 
			
		||||
have the freedom to distribute copies of free software (and charge for
 | 
			
		||||
them if you wish), that you receive source code or can get it if you
 | 
			
		||||
want it, that you can change the software or use pieces of it in new
 | 
			
		||||
free programs, and that you know you can do these things.
 | 
			
		||||
this service if you wish), that you receive source code or can get it
 | 
			
		||||
if you want it, that you can change the software or use pieces of it
 | 
			
		||||
in new free programs; and that you know you can do these things.
 | 
			
		||||
 | 
			
		||||
  Developers that use our General Public Licenses protect your rights
 | 
			
		||||
with two steps: (1) assert copyright on the software, and (2) offer
 | 
			
		||||
you this License which gives you legal permission to copy, distribute
 | 
			
		||||
and/or modify the software.
 | 
			
		||||
  To protect your rights, we need to make restrictions that forbid
 | 
			
		||||
anyone to deny you these rights or to ask you to surrender the rights.
 | 
			
		||||
These restrictions translate to certain responsibilities for you if you
 | 
			
		||||
distribute copies of the software, or if you modify it.
 | 
			
		||||
 | 
			
		||||
  A secondary benefit of defending all users' freedom is that
 | 
			
		||||
improvements made in alternate versions of the program, if they
 | 
			
		||||
receive widespread use, become available for other developers to
 | 
			
		||||
incorporate.  Many developers of free software are heartened and
 | 
			
		||||
encouraged by the resulting cooperation.  However, in the case of
 | 
			
		||||
software used on network servers, this result may fail to come about.
 | 
			
		||||
The GNU General Public License permits making a modified version and
 | 
			
		||||
letting the public access it on a server without ever releasing its
 | 
			
		||||
source code to the public.
 | 
			
		||||
  For example, if you distribute copies of such a program, whether
 | 
			
		||||
gratis or for a fee, you must give the recipients all the rights that
 | 
			
		||||
you have.  You must make sure that they, too, receive or can get the
 | 
			
		||||
source code.  And you must show them these terms so they know their
 | 
			
		||||
rights.
 | 
			
		||||
 | 
			
		||||
  The GNU Affero General Public License is designed specifically to
 | 
			
		||||
ensure that, in such cases, the modified source code becomes available
 | 
			
		||||
to the community.  It requires the operator of a network server to
 | 
			
		||||
provide the source code of the modified version running there to the
 | 
			
		||||
users of that server.  Therefore, public use of a modified version, on
 | 
			
		||||
a publicly accessible server, gives the public access to the source
 | 
			
		||||
code of the modified version.
 | 
			
		||||
  We protect your rights with two steps: (1) copyright the software, and
 | 
			
		||||
(2) offer you this license which gives you legal permission to copy,
 | 
			
		||||
distribute and/or modify the software.
 | 
			
		||||
 | 
			
		||||
  An older license, called the Affero General Public License and
 | 
			
		||||
published by Affero, was designed to accomplish similar goals.  This is
 | 
			
		||||
a different license, not a version of the Affero GPL, but Affero has
 | 
			
		||||
released a new version of the Affero GPL which permits relicensing under
 | 
			
		||||
this license.
 | 
			
		||||
  Also, for each author's protection and ours, we want to make certain
 | 
			
		||||
that everyone understands that there is no warranty for this free
 | 
			
		||||
software.  If the software is modified by someone else and passed on, we
 | 
			
		||||
want its recipients to know that what they have is not the original, so
 | 
			
		||||
that any problems introduced by others will not reflect on the original
 | 
			
		||||
authors' reputations.
 | 
			
		||||
 | 
			
		||||
  Finally, any free program is threatened constantly by software
 | 
			
		||||
patents.  We wish to avoid the danger that redistributors of a free
 | 
			
		||||
program will individually obtain patent licenses, in effect making the
 | 
			
		||||
program proprietary.  To prevent this, we have made it clear that any
 | 
			
		||||
patent must be licensed for everyone's free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.
 | 
			
		||||
 | 
			
		||||
                       TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
  0. Definitions.
 | 
			
		||||
 | 
			
		||||
  "This License" refers to version 3 of the GNU Affero General Public License.
 | 
			
		||||
 | 
			
		||||
  "Copyright" also means copyright-like laws that apply to other kinds of
 | 
			
		||||
works, such as semiconductor masks.
 | 
			
		||||
 | 
			
		||||
  "The Program" refers to any copyrightable work licensed under this
 | 
			
		||||
License.  Each licensee is addressed as "you".  "Licensees" and
 | 
			
		||||
"recipients" may be individuals or organizations.
 | 
			
		||||
 | 
			
		||||
  To "modify" a work means to copy from or adapt all or part of the work
 | 
			
		||||
in a fashion requiring copyright permission, other than the making of an
 | 
			
		||||
exact copy.  The resulting work is called a "modified version" of the
 | 
			
		||||
earlier work or a work "based on" the earlier work.
 | 
			
		||||
 | 
			
		||||
  A "covered work" means either the unmodified Program or a work based
 | 
			
		||||
on the Program.
 | 
			
		||||
 | 
			
		||||
  To "propagate" a work means to do anything with it that, without
 | 
			
		||||
permission, would make you directly or secondarily liable for
 | 
			
		||||
infringement under applicable copyright law, except executing it on a
 | 
			
		||||
computer or modifying a private copy.  Propagation includes copying,
 | 
			
		||||
distribution (with or without modification), making available to the
 | 
			
		||||
public, and in some countries other activities as well.
 | 
			
		||||
 | 
			
		||||
  To "convey" a work means any kind of propagation that enables other
 | 
			
		||||
parties to make or receive copies.  Mere interaction with a user through
 | 
			
		||||
a computer network, with no transfer of a copy, is not conveying.
 | 
			
		||||
 | 
			
		||||
  An interactive user interface displays "Appropriate Legal Notices"
 | 
			
		||||
to the extent that it includes a convenient and prominently visible
 | 
			
		||||
feature that (1) displays an appropriate copyright notice, and (2)
 | 
			
		||||
tells the user that there is no warranty for the work (except to the
 | 
			
		||||
extent that warranties are provided), that licensees may convey the
 | 
			
		||||
work under this License, and how to view a copy of this License.  If
 | 
			
		||||
the interface presents a list of user commands or options, such as a
 | 
			
		||||
menu, a prominent item in the list meets this criterion.
 | 
			
		||||
 | 
			
		||||
  1. Source Code.
 | 
			
		||||
 | 
			
		||||
  The "source code" for a work means the preferred form of the work
 | 
			
		||||
for making modifications to it.  "Object code" means any non-source
 | 
			
		||||
form of a work.
 | 
			
		||||
 | 
			
		||||
  A "Standard Interface" means an interface that either is an official
 | 
			
		||||
standard defined by a recognized standards body, or, in the case of
 | 
			
		||||
interfaces specified for a particular programming language, one that
 | 
			
		||||
is widely used among developers working in that language.
 | 
			
		||||
 | 
			
		||||
  The "System Libraries" of an executable work include anything, other
 | 
			
		||||
than the work as a whole, that (a) is included in the normal form of
 | 
			
		||||
packaging a Major Component, but which is not part of that Major
 | 
			
		||||
Component, and (b) serves only to enable use of the work with that
 | 
			
		||||
Major Component, or to implement a Standard Interface for which an
 | 
			
		||||
implementation is available to the public in source code form.  A
 | 
			
		||||
"Major Component", in this context, means a major essential component
 | 
			
		||||
(kernel, window system, and so on) of the specific operating system
 | 
			
		||||
(if any) on which the executable work runs, or a compiler used to
 | 
			
		||||
produce the work, or an object code interpreter used to run it.
 | 
			
		||||
 | 
			
		||||
  The "Corresponding Source" for a work in object code form means all
 | 
			
		||||
the source code needed to generate, install, and (for an executable
 | 
			
		||||
work) run the object code and to modify the work, including scripts to
 | 
			
		||||
control those activities.  However, it does not include the work's
 | 
			
		||||
System Libraries, or general-purpose tools or generally available free
 | 
			
		||||
programs which are used unmodified in performing those activities but
 | 
			
		||||
which are not part of the work.  For example, Corresponding Source
 | 
			
		||||
includes interface definition files associated with source files for
 | 
			
		||||
the work, and the source code for shared libraries and dynamically
 | 
			
		||||
linked subprograms that the work is specifically designed to require,
 | 
			
		||||
such as by intimate data communication or control flow between those
 | 
			
		||||
subprograms and other parts of the work.
 | 
			
		||||
 | 
			
		||||
  The Corresponding Source need not include anything that users
 | 
			
		||||
can regenerate automatically from other parts of the Corresponding
 | 
			
		||||
Source.
 | 
			
		||||
 | 
			
		||||
  The Corresponding Source for a work in source code form is that
 | 
			
		||||
same work.
 | 
			
		||||
 | 
			
		||||
  2. Basic Permissions.
 | 
			
		||||
 | 
			
		||||
  All rights granted under this License are granted for the term of
 | 
			
		||||
copyright on the Program, and are irrevocable provided the stated
 | 
			
		||||
conditions are met.  This License explicitly affirms your unlimited
 | 
			
		||||
permission to run the unmodified Program.  The output from running a
 | 
			
		||||
covered work is covered by this License only if the output, given its
 | 
			
		||||
content, constitutes a covered work.  This License acknowledges your
 | 
			
		||||
rights of fair use or other equivalent, as provided by copyright law.
 | 
			
		||||
 | 
			
		||||
  You may make, run and propagate covered works that you do not
 | 
			
		||||
convey, without conditions so long as your license otherwise remains
 | 
			
		||||
in force.  You may convey covered works to others for the sole purpose
 | 
			
		||||
of having them make modifications exclusively for you, or provide you
 | 
			
		||||
with facilities for running those works, provided that you comply with
 | 
			
		||||
the terms of this License in conveying all material for which you do
 | 
			
		||||
not control copyright.  Those thus making or running the covered works
 | 
			
		||||
for you must do so exclusively on your behalf, under your direction
 | 
			
		||||
and control, on terms that prohibit them from making any copies of
 | 
			
		||||
your copyrighted material outside their relationship with you.
 | 
			
		||||
 | 
			
		||||
  Conveying under any other circumstances is permitted solely under
 | 
			
		||||
the conditions stated below.  Sublicensing is not allowed; section 10
 | 
			
		||||
makes it unnecessary.
 | 
			
		||||
 | 
			
		||||
  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
 | 
			
		||||
 | 
			
		||||
  No covered work shall be deemed part of an effective technological
 | 
			
		||||
measure under any applicable law fulfilling obligations under article
 | 
			
		||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
 | 
			
		||||
similar laws prohibiting or restricting circumvention of such
 | 
			
		||||
measures.
 | 
			
		||||
 | 
			
		||||
  When you convey a covered work, you waive any legal power to forbid
 | 
			
		||||
circumvention of technological measures to the extent such circumvention
 | 
			
		||||
is effected by exercising rights under this License with respect to
 | 
			
		||||
the covered work, and you disclaim any intention to limit operation or
 | 
			
		||||
modification of the work as a means of enforcing, against the work's
 | 
			
		||||
users, your or third parties' legal rights to forbid circumvention of
 | 
			
		||||
technological measures.
 | 
			
		||||
 | 
			
		||||
  4. Conveying Verbatim Copies.
 | 
			
		||||
 | 
			
		||||
  You may convey verbatim copies of the Program's source code as you
 | 
			
		||||
receive it, in any medium, provided that you conspicuously and
 | 
			
		||||
appropriately publish on each copy an appropriate copyright notice;
 | 
			
		||||
keep intact all notices stating that this License and any
 | 
			
		||||
non-permissive terms added in accord with section 7 apply to the code;
 | 
			
		||||
keep intact all notices of the absence of any warranty; and give all
 | 
			
		||||
recipients a copy of this License along with the Program.
 | 
			
		||||
 | 
			
		||||
  You may charge any price or no price for each copy that you convey,
 | 
			
		||||
and you may offer support or warranty protection for a fee.
 | 
			
		||||
 | 
			
		||||
  5. Conveying Modified Source Versions.
 | 
			
		||||
 | 
			
		||||
  You may convey a work based on the Program, or the modifications to
 | 
			
		||||
produce it from the Program, in the form of source code under the
 | 
			
		||||
terms of section 4, provided that you also meet all of these conditions:
 | 
			
		||||
 | 
			
		||||
    a) The work must carry prominent notices stating that you modified
 | 
			
		||||
    it, and giving a relevant date.
 | 
			
		||||
 | 
			
		||||
    b) The work must carry prominent notices stating that it is
 | 
			
		||||
    released under this License and any conditions added under section
 | 
			
		||||
    7.  This requirement modifies the requirement in section 4 to
 | 
			
		||||
    "keep intact all notices".
 | 
			
		||||
 | 
			
		||||
    c) You must license the entire work, as a whole, under this
 | 
			
		||||
    License to anyone who comes into possession of a copy.  This
 | 
			
		||||
    License will therefore apply, along with any applicable section 7
 | 
			
		||||
    additional terms, to the whole of the work, and all its parts,
 | 
			
		||||
    regardless of how they are packaged.  This License gives no
 | 
			
		||||
    permission to license the work in any other way, but it does not
 | 
			
		||||
    invalidate such permission if you have separately received it.
 | 
			
		||||
 | 
			
		||||
    d) If the work has interactive user interfaces, each must display
 | 
			
		||||
    Appropriate Legal Notices; however, if the Program has interactive
 | 
			
		||||
    interfaces that do not display Appropriate Legal Notices, your
 | 
			
		||||
    work need not make them do so.
 | 
			
		||||
 | 
			
		||||
  A compilation of a covered work with other separate and independent
 | 
			
		||||
works, which are not by their nature extensions of the covered work,
 | 
			
		||||
and which are not combined with it such as to form a larger program,
 | 
			
		||||
in or on a volume of a storage or distribution medium, is called an
 | 
			
		||||
"aggregate" if the compilation and its resulting copyright are not
 | 
			
		||||
used to limit the access or legal rights of the compilation's users
 | 
			
		||||
beyond what the individual works permit.  Inclusion of a covered work
 | 
			
		||||
in an aggregate does not cause this License to apply to the other
 | 
			
		||||
parts of the aggregate.
 | 
			
		||||
 | 
			
		||||
  6. Conveying Non-Source Forms.
 | 
			
		||||
 | 
			
		||||
  You may convey a covered work in object code form under the terms
 | 
			
		||||
of sections 4 and 5, provided that you also convey the
 | 
			
		||||
machine-readable Corresponding Source under the terms of this License,
 | 
			
		||||
in one of these ways:
 | 
			
		||||
 | 
			
		||||
    a) Convey the object code in, or embodied in, a physical product
 | 
			
		||||
    (including a physical distribution medium), accompanied by the
 | 
			
		||||
    Corresponding Source fixed on a durable physical medium
 | 
			
		||||
    customarily used for software interchange.
 | 
			
		||||
 | 
			
		||||
    b) Convey the object code in, or embodied in, a physical product
 | 
			
		||||
    (including a physical distribution medium), accompanied by a
 | 
			
		||||
    written offer, valid for at least three years and valid for as
 | 
			
		||||
    long as you offer spare parts or customer support for that product
 | 
			
		||||
    model, to give anyone who possesses the object code either (1) a
 | 
			
		||||
    copy of the Corresponding Source for all the software in the
 | 
			
		||||
    product that is covered by this License, on a durable physical
 | 
			
		||||
    medium customarily used for software interchange, for a price no
 | 
			
		||||
    more than your reasonable cost of physically performing this
 | 
			
		||||
    conveying of source, or (2) access to copy the
 | 
			
		||||
    Corresponding Source from a network server at no charge.
 | 
			
		||||
 | 
			
		||||
    c) Convey individual copies of the object code with a copy of the
 | 
			
		||||
    written offer to provide the Corresponding Source.  This
 | 
			
		||||
    alternative is allowed only occasionally and noncommercially, and
 | 
			
		||||
    only if you received the object code with such an offer, in accord
 | 
			
		||||
    with subsection 6b.
 | 
			
		||||
 | 
			
		||||
    d) Convey the object code by offering access from a designated
 | 
			
		||||
    place (gratis or for a charge), and offer equivalent access to the
 | 
			
		||||
    Corresponding Source in the same way through the same place at no
 | 
			
		||||
    further charge.  You need not require recipients to copy the
 | 
			
		||||
    Corresponding Source along with the object code.  If the place to
 | 
			
		||||
    copy the object code is a network server, the Corresponding Source
 | 
			
		||||
    may be on a different server (operated by you or a third party)
 | 
			
		||||
    that supports equivalent copying facilities, provided you maintain
 | 
			
		||||
    clear directions next to the object code saying where to find the
 | 
			
		||||
    Corresponding Source.  Regardless of what server hosts the
 | 
			
		||||
    Corresponding Source, you remain obligated to ensure that it is
 | 
			
		||||
    available for as long as needed to satisfy these requirements.
 | 
			
		||||
 | 
			
		||||
    e) Convey the object code using peer-to-peer transmission, provided
 | 
			
		||||
    you inform other peers where the object code and Corresponding
 | 
			
		||||
    Source of the work are being offered to the general public at no
 | 
			
		||||
    charge under subsection 6d.
 | 
			
		||||
 | 
			
		||||
  A separable portion of the object code, whose source code is excluded
 | 
			
		||||
from the Corresponding Source as a System Library, need not be
 | 
			
		||||
included in conveying the object code work.
 | 
			
		||||
 | 
			
		||||
  A "User Product" is either (1) a "consumer product", which means any
 | 
			
		||||
tangible personal property which is normally used for personal, family,
 | 
			
		||||
or household purposes, or (2) anything designed or sold for incorporation
 | 
			
		||||
into a dwelling.  In determining whether a product is a consumer product,
 | 
			
		||||
doubtful cases shall be resolved in favor of coverage.  For a particular
 | 
			
		||||
product received by a particular user, "normally used" refers to a
 | 
			
		||||
typical or common use of that class of product, regardless of the status
 | 
			
		||||
of the particular user or of the way in which the particular user
 | 
			
		||||
actually uses, or expects or is expected to use, the product.  A product
 | 
			
		||||
is a consumer product regardless of whether the product has substantial
 | 
			
		||||
commercial, industrial or non-consumer uses, unless such uses represent
 | 
			
		||||
the only significant mode of use of the product.
 | 
			
		||||
 | 
			
		||||
  "Installation Information" for a User Product means any methods,
 | 
			
		||||
procedures, authorization keys, or other information required to install
 | 
			
		||||
and execute modified versions of a covered work in that User Product from
 | 
			
		||||
a modified version of its Corresponding Source.  The information must
 | 
			
		||||
suffice to ensure that the continued functioning of the modified object
 | 
			
		||||
code is in no case prevented or interfered with solely because
 | 
			
		||||
modification has been made.
 | 
			
		||||
 | 
			
		||||
  If you convey an object code work under this section in, or with, or
 | 
			
		||||
specifically for use in, a User Product, and the conveying occurs as
 | 
			
		||||
part of a transaction in which the right of possession and use of the
 | 
			
		||||
User Product is transferred to the recipient in perpetuity or for a
 | 
			
		||||
fixed term (regardless of how the transaction is characterized), the
 | 
			
		||||
Corresponding Source conveyed under this section must be accompanied
 | 
			
		||||
by the Installation Information.  But this requirement does not apply
 | 
			
		||||
if neither you nor any third party retains the ability to install
 | 
			
		||||
modified object code on the User Product (for example, the work has
 | 
			
		||||
been installed in ROM).
 | 
			
		||||
 | 
			
		||||
  The requirement to provide Installation Information does not include a
 | 
			
		||||
requirement to continue to provide support service, warranty, or updates
 | 
			
		||||
for a work that has been modified or installed by the recipient, or for
 | 
			
		||||
the User Product in which it has been modified or installed.  Access to a
 | 
			
		||||
network may be denied when the modification itself materially and
 | 
			
		||||
adversely affects the operation of the network or violates the rules and
 | 
			
		||||
protocols for communication across the network.
 | 
			
		||||
 | 
			
		||||
  Corresponding Source conveyed, and Installation Information provided,
 | 
			
		||||
in accord with this section must be in a format that is publicly
 | 
			
		||||
documented (and with an implementation available to the public in
 | 
			
		||||
source code form), and must require no special password or key for
 | 
			
		||||
unpacking, reading or copying.
 | 
			
		||||
 | 
			
		||||
  7. Additional Terms.
 | 
			
		||||
 | 
			
		||||
  "Additional permissions" are terms that supplement the terms of this
 | 
			
		||||
License by making exceptions from one or more of its conditions.
 | 
			
		||||
Additional permissions that are applicable to the entire Program shall
 | 
			
		||||
be treated as though they were included in this License, to the extent
 | 
			
		||||
that they are valid under applicable law.  If additional permissions
 | 
			
		||||
apply only to part of the Program, that part may be used separately
 | 
			
		||||
under those permissions, but the entire Program remains governed by
 | 
			
		||||
this License without regard to the additional permissions.
 | 
			
		||||
 | 
			
		||||
  When you convey a copy of a covered work, you may at your option
 | 
			
		||||
remove any additional permissions from that copy, or from any part of
 | 
			
		||||
it.  (Additional permissions may be written to require their own
 | 
			
		||||
removal in certain cases when you modify the work.)  You may place
 | 
			
		||||
additional permissions on material, added by you to a covered work,
 | 
			
		||||
for which you have or can give appropriate copyright permission.
 | 
			
		||||
 | 
			
		||||
  Notwithstanding any other provision of this License, for material you
 | 
			
		||||
add to a covered work, you may (if authorized by the copyright holders of
 | 
			
		||||
that material) supplement the terms of this License with terms:
 | 
			
		||||
 | 
			
		||||
    a) Disclaiming warranty or limiting liability differently from the
 | 
			
		||||
    terms of sections 15 and 16 of this License; or
 | 
			
		||||
 | 
			
		||||
    b) Requiring preservation of specified reasonable legal notices or
 | 
			
		||||
    author attributions in that material or in the Appropriate Legal
 | 
			
		||||
    Notices displayed by works containing it; or
 | 
			
		||||
 | 
			
		||||
    c) Prohibiting misrepresentation of the origin of that material, or
 | 
			
		||||
    requiring that modified versions of such material be marked in
 | 
			
		||||
    reasonable ways as different from the original version; or
 | 
			
		||||
 | 
			
		||||
    d) Limiting the use for publicity purposes of names of licensors or
 | 
			
		||||
    authors of the material; or
 | 
			
		||||
 | 
			
		||||
    e) Declining to grant rights under trademark law for use of some
 | 
			
		||||
    trade names, trademarks, or service marks; or
 | 
			
		||||
 | 
			
		||||
    f) Requiring indemnification of licensors and authors of that
 | 
			
		||||
    material by anyone who conveys the material (or modified versions of
 | 
			
		||||
    it) with contractual assumptions of liability to the recipient, for
 | 
			
		||||
    any liability that these contractual assumptions directly impose on
 | 
			
		||||
    those licensors and authors.
 | 
			
		||||
 | 
			
		||||
  All other non-permissive additional terms are considered "further
 | 
			
		||||
restrictions" within the meaning of section 10.  If the Program as you
 | 
			
		||||
received it, or any part of it, contains a notice stating that it is
 | 
			
		||||
governed by this License along with a term that is a further
 | 
			
		||||
restriction, you may remove that term.  If a license document contains
 | 
			
		||||
a further restriction but permits relicensing or conveying under this
 | 
			
		||||
License, you may add to a covered work material governed by the terms
 | 
			
		||||
of that license document, provided that the further restriction does
 | 
			
		||||
not survive such relicensing or conveying.
 | 
			
		||||
 | 
			
		||||
  If you add terms to a covered work in accord with this section, you
 | 
			
		||||
must place, in the relevant source files, a statement of the
 | 
			
		||||
additional terms that apply to those files, or a notice indicating
 | 
			
		||||
where to find the applicable terms.
 | 
			
		||||
 | 
			
		||||
  Additional terms, permissive or non-permissive, may be stated in the
 | 
			
		||||
form of a separately written license, or stated as exceptions;
 | 
			
		||||
the above requirements apply either way.
 | 
			
		||||
 | 
			
		||||
  8. Termination.
 | 
			
		||||
 | 
			
		||||
  You may not propagate or modify a covered work except as expressly
 | 
			
		||||
provided under this License.  Any attempt otherwise to propagate or
 | 
			
		||||
modify it is void, and will automatically terminate your rights under
 | 
			
		||||
this License (including any patent licenses granted under the third
 | 
			
		||||
paragraph of section 11).
 | 
			
		||||
 | 
			
		||||
  However, if you cease all violation of this License, then your
 | 
			
		||||
license from a particular copyright holder is reinstated (a)
 | 
			
		||||
provisionally, unless and until the copyright holder explicitly and
 | 
			
		||||
finally terminates your license, and (b) permanently, if the copyright
 | 
			
		||||
holder fails to notify you of the violation by some reasonable means
 | 
			
		||||
prior to 60 days after the cessation.
 | 
			
		||||
 | 
			
		||||
  Moreover, your license from a particular copyright holder is
 | 
			
		||||
reinstated permanently if the copyright holder notifies you of the
 | 
			
		||||
violation by some reasonable means, this is the first time you have
 | 
			
		||||
received notice of violation of this License (for any work) from that
 | 
			
		||||
copyright holder, and you cure the violation prior to 30 days after
 | 
			
		||||
your receipt of the notice.
 | 
			
		||||
 | 
			
		||||
  Termination of your rights under this section does not terminate the
 | 
			
		||||
licenses of parties who have received copies or rights from you under
 | 
			
		||||
this License.  If your rights have been terminated and not permanently
 | 
			
		||||
reinstated, you do not qualify to receive new licenses for the same
 | 
			
		||||
material under section 10.
 | 
			
		||||
 | 
			
		||||
  9. Acceptance Not Required for Having Copies.
 | 
			
		||||
 | 
			
		||||
  You are not required to accept this License in order to receive or
 | 
			
		||||
run a copy of the Program.  Ancillary propagation of a covered work
 | 
			
		||||
occurring solely as a consequence of using peer-to-peer transmission
 | 
			
		||||
to receive a copy likewise does not require acceptance.  However,
 | 
			
		||||
nothing other than this License grants you permission to propagate or
 | 
			
		||||
modify any covered work.  These actions infringe copyright if you do
 | 
			
		||||
not accept this License.  Therefore, by modifying or propagating a
 | 
			
		||||
covered work, you indicate your acceptance of this License to do so.
 | 
			
		||||
 | 
			
		||||
  10. Automatic Licensing of Downstream Recipients.
 | 
			
		||||
 | 
			
		||||
  Each time you convey a covered work, the recipient automatically
 | 
			
		||||
receives a license from the original licensors, to run, modify and
 | 
			
		||||
propagate that work, subject to this License.  You are not responsible
 | 
			
		||||
for enforcing compliance by third parties with this License.
 | 
			
		||||
 | 
			
		||||
  An "entity transaction" is a transaction transferring control of an
 | 
			
		||||
organization, or substantially all assets of one, or subdividing an
 | 
			
		||||
organization, or merging organizations.  If propagation of a covered
 | 
			
		||||
work results from an entity transaction, each party to that
 | 
			
		||||
transaction who receives a copy of the work also receives whatever
 | 
			
		||||
licenses to the work the party's predecessor in interest had or could
 | 
			
		||||
give under the previous paragraph, plus a right to possession of the
 | 
			
		||||
Corresponding Source of the work from the predecessor in interest, if
 | 
			
		||||
the predecessor has it or can get it with reasonable efforts.
 | 
			
		||||
 | 
			
		||||
  You may not impose any further restrictions on the exercise of the
 | 
			
		||||
rights granted or affirmed under this License.  For example, you may
 | 
			
		||||
not impose a license fee, royalty, or other charge for exercise of
 | 
			
		||||
rights granted under this License, and you may not initiate litigation
 | 
			
		||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
 | 
			
		||||
any patent claim is infringed by making, using, selling, offering for
 | 
			
		||||
sale, or importing the Program or any portion of it.
 | 
			
		||||
 | 
			
		||||
  11. Patents.
 | 
			
		||||
 | 
			
		||||
  A "contributor" is a copyright holder who authorizes use under this
 | 
			
		||||
License of the Program or a work on which the Program is based.  The
 | 
			
		||||
work thus licensed is called the contributor's "contributor version".
 | 
			
		||||
 | 
			
		||||
  A contributor's "essential patent claims" are all patent claims
 | 
			
		||||
owned or controlled by the contributor, whether already acquired or
 | 
			
		||||
hereafter acquired, that would be infringed by some manner, permitted
 | 
			
		||||
by this License, of making, using, or selling its contributor version,
 | 
			
		||||
but do not include claims that would be infringed only as a
 | 
			
		||||
consequence of further modification of the contributor version.  For
 | 
			
		||||
purposes of this definition, "control" includes the right to grant
 | 
			
		||||
patent sublicenses in a manner consistent with the requirements of
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. This License applies to any program or other work which contains
 | 
			
		||||
a notice placed by the copyright holder saying it may be distributed
 | 
			
		||||
under the terms of this General Public License.  The "Program", below,
 | 
			
		||||
refers to any such program or work, and a "work based on the Program"
 | 
			
		||||
means either the Program or any derivative work under copyright law:
 | 
			
		||||
that is to say, a work containing the Program or a portion of it,
 | 
			
		||||
either verbatim or with modifications and/or translated into another
 | 
			
		||||
language.  (Hereinafter, translation is included without limitation in
 | 
			
		||||
the term "modification".)  Each licensee is addressed as "you".
 | 
			
		||||
 | 
			
		||||
Activities other than copying, distribution and modification are not
 | 
			
		||||
covered by this License; they are outside its scope.  The act of
 | 
			
		||||
running the Program is not restricted, and the output from the Program
 | 
			
		||||
is covered only if its contents constitute a work based on the
 | 
			
		||||
Program (independent of having been made by running the Program).
 | 
			
		||||
Whether that is true depends on what the Program does.
 | 
			
		||||
 | 
			
		||||
  1. You may copy and distribute verbatim copies of the Program's
 | 
			
		||||
source code as you receive it, in any medium, provided that you
 | 
			
		||||
conspicuously and appropriately publish on each copy an appropriate
 | 
			
		||||
copyright notice and disclaimer of warranty; keep intact all the
 | 
			
		||||
notices that refer to this License and to the absence of any warranty;
 | 
			
		||||
and give any other recipients of the Program a copy of this License
 | 
			
		||||
along with the Program.
 | 
			
		||||
 | 
			
		||||
You may charge a fee for the physical act of transferring a copy, and
 | 
			
		||||
you may at your option offer warranty protection in exchange for a fee.
 | 
			
		||||
 | 
			
		||||
  2. You may modify your copy or copies of the Program or any portion
 | 
			
		||||
of it, thus forming a work based on the Program, and copy and
 | 
			
		||||
distribute such modifications or work under the terms of Section 1
 | 
			
		||||
above, provided that you also meet all of these conditions:
 | 
			
		||||
 | 
			
		||||
    a) You must cause the modified files to carry prominent notices
 | 
			
		||||
    stating that you changed the files and the date of any change.
 | 
			
		||||
 | 
			
		||||
    b) You must cause any work that you distribute or publish, that in
 | 
			
		||||
    whole or in part contains or is derived from the Program or any
 | 
			
		||||
    part thereof, to be licensed as a whole at no charge to all third
 | 
			
		||||
    parties under the terms of this License.
 | 
			
		||||
 | 
			
		||||
    c) If the modified program normally reads commands interactively
 | 
			
		||||
    when run, you must cause it, when started running for such
 | 
			
		||||
    interactive use in the most ordinary way, to print or display an
 | 
			
		||||
    announcement including an appropriate copyright notice and a
 | 
			
		||||
    notice that there is no warranty (or else, saying that you provide
 | 
			
		||||
    a warranty) and that users may redistribute the program under
 | 
			
		||||
    these conditions, and telling the user how to view a copy of this
 | 
			
		||||
    License.  (Exception: if the Program itself is interactive but
 | 
			
		||||
    does not normally print such an announcement, your work based on
 | 
			
		||||
    the Program is not required to print an announcement.)
 | 
			
		||||
 | 
			
		||||
These requirements apply to the modified work as a whole.  If
 | 
			
		||||
identifiable sections of that work are not derived from the Program,
 | 
			
		||||
and can be reasonably considered independent and separate works in
 | 
			
		||||
themselves, then this License, and its terms, do not apply to those
 | 
			
		||||
sections when you distribute them as separate works.  But when you
 | 
			
		||||
distribute the same sections as part of a whole which is a work based
 | 
			
		||||
on the Program, the distribution of the whole must be on the terms of
 | 
			
		||||
this License, whose permissions for other licensees extend to the
 | 
			
		||||
entire whole, and thus to each and every part regardless of who wrote it.
 | 
			
		||||
 | 
			
		||||
Thus, it is not the intent of this section to claim rights or contest
 | 
			
		||||
your rights to work written entirely by you; rather, the intent is to
 | 
			
		||||
exercise the right to control the distribution of derivative or
 | 
			
		||||
collective works based on the Program.
 | 
			
		||||
 | 
			
		||||
In addition, mere aggregation of another work not based on the Program
 | 
			
		||||
with the Program (or with a work based on the Program) on a volume of
 | 
			
		||||
a storage or distribution medium does not bring the other work under
 | 
			
		||||
the scope of this License.
 | 
			
		||||
 | 
			
		||||
  3. You may copy and distribute the Program (or a work based on it,
 | 
			
		||||
under Section 2) in object code or executable form under the terms of
 | 
			
		||||
Sections 1 and 2 above provided that you also do one of the following:
 | 
			
		||||
 | 
			
		||||
    a) Accompany it with the complete corresponding machine-readable
 | 
			
		||||
    source code, which must be distributed under the terms of Sections
 | 
			
		||||
    1 and 2 above on a medium customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    b) Accompany it with a written offer, valid for at least three
 | 
			
		||||
    years, to give any third party, for a charge no more than your
 | 
			
		||||
    cost of physically performing source distribution, a complete
 | 
			
		||||
    machine-readable copy of the corresponding source code, to be
 | 
			
		||||
    distributed under the terms of Sections 1 and 2 above on a medium
 | 
			
		||||
    customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    c) Accompany it with the information you received as to the offer
 | 
			
		||||
    to distribute corresponding source code.  (This alternative is
 | 
			
		||||
    allowed only for noncommercial distribution and only if you
 | 
			
		||||
    received the program in object code or executable form with such
 | 
			
		||||
    an offer, in accord with Subsection b above.)
 | 
			
		||||
 | 
			
		||||
The source code for a work means the preferred form of the work for
 | 
			
		||||
making modifications to it.  For an executable work, complete source
 | 
			
		||||
code means all the source code for all modules it contains, plus any
 | 
			
		||||
associated interface definition files, plus the scripts used to
 | 
			
		||||
control compilation and installation of the executable.  However, as a
 | 
			
		||||
special exception, the source code distributed need not include
 | 
			
		||||
anything that is normally distributed (in either source or binary
 | 
			
		||||
form) with the major components (compiler, kernel, and so on) of the
 | 
			
		||||
operating system on which the executable runs, unless that component
 | 
			
		||||
itself accompanies the executable.
 | 
			
		||||
 | 
			
		||||
If distribution of executable or object code is made by offering
 | 
			
		||||
access to copy from a designated place, then offering equivalent
 | 
			
		||||
access to copy the source code from the same place counts as
 | 
			
		||||
distribution of the source code, even though third parties are not
 | 
			
		||||
compelled to copy the source along with the object code.
 | 
			
		||||
 | 
			
		||||
  4. You may not copy, modify, sublicense, or distribute the Program
 | 
			
		||||
except as expressly provided under this License.  Any attempt
 | 
			
		||||
otherwise to copy, modify, sublicense or distribute the Program is
 | 
			
		||||
void, and will automatically terminate your rights under this License.
 | 
			
		||||
However, parties who have received copies, or rights, from you under
 | 
			
		||||
this License will not have their licenses terminated so long as such
 | 
			
		||||
parties remain in full compliance.
 | 
			
		||||
 | 
			
		||||
  5. You are not required to accept this License, since you have not
 | 
			
		||||
signed it.  However, nothing else grants you permission to modify or
 | 
			
		||||
distribute the Program or its derivative works.  These actions are
 | 
			
		||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
			
		||||
modifying or distributing the Program (or any work based on the
 | 
			
		||||
Program), you indicate your acceptance of this License to do so, and
 | 
			
		||||
all its terms and conditions for copying, distributing or modifying
 | 
			
		||||
the Program or works based on it.
 | 
			
		||||
 | 
			
		||||
  6. Each time you redistribute the Program (or any work based on the
 | 
			
		||||
Program), the recipient automatically receives a license from the
 | 
			
		||||
original licensor to copy, distribute or modify the Program subject to
 | 
			
		||||
these terms and conditions.  You may not impose any further
 | 
			
		||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
			
		||||
You are not responsible for enforcing compliance by third parties to
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
  Each contributor grants you a non-exclusive, worldwide, royalty-free
 | 
			
		||||
patent license under the contributor's essential patent claims, to
 | 
			
		||||
make, use, sell, offer for sale, import and otherwise run, modify and
 | 
			
		||||
propagate the contents of its contributor version.
 | 
			
		||||
 | 
			
		||||
  In the following three paragraphs, a "patent license" is any express
 | 
			
		||||
agreement or commitment, however denominated, not to enforce a patent
 | 
			
		||||
(such as an express permission to practice a patent or covenant not to
 | 
			
		||||
sue for patent infringement).  To "grant" such a patent license to a
 | 
			
		||||
party means to make such an agreement or commitment not to enforce a
 | 
			
		||||
patent against the party.
 | 
			
		||||
 | 
			
		||||
  If you convey a covered work, knowingly relying on a patent license,
 | 
			
		||||
and the Corresponding Source of the work is not available for anyone
 | 
			
		||||
to copy, free of charge and under the terms of this License, through a
 | 
			
		||||
publicly available network server or other readily accessible means,
 | 
			
		||||
then you must either (1) cause the Corresponding Source to be so
 | 
			
		||||
available, or (2) arrange to deprive yourself of the benefit of the
 | 
			
		||||
patent license for this particular work, or (3) arrange, in a manner
 | 
			
		||||
consistent with the requirements of this License, to extend the patent
 | 
			
		||||
license to downstream recipients.  "Knowingly relying" means you have
 | 
			
		||||
actual knowledge that, but for the patent license, your conveying the
 | 
			
		||||
covered work in a country, or your recipient's use of the covered work
 | 
			
		||||
in a country, would infringe one or more identifiable patents in that
 | 
			
		||||
country that you have reason to believe are valid.
 | 
			
		||||
 | 
			
		||||
  If, pursuant to or in connection with a single transaction or
 | 
			
		||||
arrangement, you convey, or propagate by procuring conveyance of, a
 | 
			
		||||
covered work, and grant a patent license to some of the parties
 | 
			
		||||
receiving the covered work authorizing them to use, propagate, modify
 | 
			
		||||
or convey a specific copy of the covered work, then the patent license
 | 
			
		||||
you grant is automatically extended to all recipients of the covered
 | 
			
		||||
work and works based on it.
 | 
			
		||||
 | 
			
		||||
  A patent license is "discriminatory" if it does not include within
 | 
			
		||||
the scope of its coverage, prohibits the exercise of, or is
 | 
			
		||||
conditioned on the non-exercise of one or more of the rights that are
 | 
			
		||||
specifically granted under this License.  You may not convey a covered
 | 
			
		||||
work if you are a party to an arrangement with a third party that is
 | 
			
		||||
in the business of distributing software, under which you make payment
 | 
			
		||||
to the third party based on the extent of your activity of conveying
 | 
			
		||||
the work, and under which the third party grants, to any of the
 | 
			
		||||
parties who would receive the covered work from you, a discriminatory
 | 
			
		||||
patent license (a) in connection with copies of the covered work
 | 
			
		||||
conveyed by you (or copies made from those copies), or (b) primarily
 | 
			
		||||
for and in connection with specific products or compilations that
 | 
			
		||||
contain the covered work, unless you entered into that arrangement,
 | 
			
		||||
or that patent license was granted, prior to 28 March 2007.
 | 
			
		||||
 | 
			
		||||
  Nothing in this License shall be construed as excluding or limiting
 | 
			
		||||
any implied license or other defenses to infringement that may
 | 
			
		||||
otherwise be available to you under applicable patent law.
 | 
			
		||||
 | 
			
		||||
  12. No Surrender of Others' Freedom.
 | 
			
		||||
 | 
			
		||||
  If conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
  7. If, as a consequence of a court judgment or allegation of patent
 | 
			
		||||
infringement or for any other reason (not limited to patent issues),
 | 
			
		||||
conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
otherwise) that contradict the conditions of this License, they do not
 | 
			
		||||
excuse you from the conditions of this License.  If you cannot convey a
 | 
			
		||||
covered work so as to satisfy simultaneously your obligations under this
 | 
			
		||||
License and any other pertinent obligations, then as a consequence you may
 | 
			
		||||
not convey it at all.  For example, if you agree to terms that obligate you
 | 
			
		||||
to collect a royalty for further conveying from those to whom you convey
 | 
			
		||||
the Program, the only way you could satisfy both those terms and this
 | 
			
		||||
License would be to refrain entirely from conveying the Program.
 | 
			
		||||
excuse you from the conditions of this License.  If you cannot
 | 
			
		||||
distribute so as to satisfy simultaneously your obligations under this
 | 
			
		||||
License and any other pertinent obligations, then as a consequence you
 | 
			
		||||
may not distribute the Program at all.  For example, if a patent
 | 
			
		||||
license would not permit royalty-free redistribution of the Program by
 | 
			
		||||
all those who receive copies directly or indirectly through you, then
 | 
			
		||||
the only way you could satisfy both it and this License would be to
 | 
			
		||||
refrain entirely from distribution of the Program.
 | 
			
		||||
 | 
			
		||||
  13. Remote Network Interaction; Use with the GNU General Public License.
 | 
			
		||||
If any portion of this section is held invalid or unenforceable under
 | 
			
		||||
any particular circumstance, the balance of the section is intended to
 | 
			
		||||
apply and the section as a whole is intended to apply in other
 | 
			
		||||
circumstances.
 | 
			
		||||
 | 
			
		||||
  Notwithstanding any other provision of this License, if you modify the
 | 
			
		||||
Program, your modified version must prominently offer all users
 | 
			
		||||
interacting with it remotely through a computer network (if your version
 | 
			
		||||
supports such interaction) an opportunity to receive the Corresponding
 | 
			
		||||
Source of your version by providing access to the Corresponding Source
 | 
			
		||||
from a network server at no charge, through some standard or customary
 | 
			
		||||
means of facilitating copying of software.  This Corresponding Source
 | 
			
		||||
shall include the Corresponding Source for any work covered by version 3
 | 
			
		||||
of the GNU General Public License that is incorporated pursuant to the
 | 
			
		||||
following paragraph.
 | 
			
		||||
It is not the purpose of this section to induce you to infringe any
 | 
			
		||||
patents or other property right claims or to contest validity of any
 | 
			
		||||
such claims; this section has the sole purpose of protecting the
 | 
			
		||||
integrity of the free software distribution system, which is
 | 
			
		||||
implemented by public license practices.  Many people have made
 | 
			
		||||
generous contributions to the wide range of software distributed
 | 
			
		||||
through that system in reliance on consistent application of that
 | 
			
		||||
system; it is up to the author/donor to decide if he or she is willing
 | 
			
		||||
to distribute software through any other system and a licensee cannot
 | 
			
		||||
impose that choice.
 | 
			
		||||
 | 
			
		||||
  Notwithstanding any other provision of this License, you have
 | 
			
		||||
permission to link or combine any covered work with a work licensed
 | 
			
		||||
under version 3 of the GNU General Public License into a single
 | 
			
		||||
combined work, and to convey the resulting work.  The terms of this
 | 
			
		||||
License will continue to apply to the part which is the covered work,
 | 
			
		||||
but the work with which it is combined will remain governed by version
 | 
			
		||||
3 of the GNU General Public License.
 | 
			
		||||
This section is intended to make thoroughly clear what is believed to
 | 
			
		||||
be a consequence of the rest of this License.
 | 
			
		||||
 | 
			
		||||
  14. Revised Versions of this License.
 | 
			
		||||
  8. If the distribution and/or use of the Program is restricted in
 | 
			
		||||
certain countries either by patents or by copyrighted interfaces, the
 | 
			
		||||
original copyright holder who places the Program under this License
 | 
			
		||||
may add an explicit geographical distribution limitation excluding
 | 
			
		||||
those countries, so that distribution is permitted only in or among
 | 
			
		||||
countries not thus excluded.  In such case, this License incorporates
 | 
			
		||||
the limitation as if written in the body of this License.
 | 
			
		||||
 | 
			
		||||
  The Free Software Foundation may publish revised and/or new versions of
 | 
			
		||||
the GNU Affero General Public License from time to time.  Such new versions
 | 
			
		||||
will be similar in spirit to the present version, but may differ in detail to
 | 
			
		||||
  9. The Free Software Foundation may publish revised and/or new versions
 | 
			
		||||
of the General Public License from time to time.  Such new versions will
 | 
			
		||||
be similar in spirit to the present version, but may differ in detail to
 | 
			
		||||
address new problems or concerns.
 | 
			
		||||
 | 
			
		||||
  Each version is given a distinguishing version number.  If the
 | 
			
		||||
Program specifies that a certain numbered version of the GNU Affero General
 | 
			
		||||
Public License "or any later version" applies to it, you have the
 | 
			
		||||
option of following the terms and conditions either of that numbered
 | 
			
		||||
version or of any later version published by the Free Software
 | 
			
		||||
Foundation.  If the Program does not specify a version number of the
 | 
			
		||||
GNU Affero General Public License, you may choose any version ever published
 | 
			
		||||
by the Free Software Foundation.
 | 
			
		||||
Each version is given a distinguishing version number.  If the Program
 | 
			
		||||
specifies a version number of this License which applies to it and "any
 | 
			
		||||
later version", you have the option of following the terms and conditions
 | 
			
		||||
either of that version or of any later version published by the Free
 | 
			
		||||
Software Foundation.  If the Program does not specify a version number of
 | 
			
		||||
this License, you may choose any version ever published by the Free Software
 | 
			
		||||
Foundation.
 | 
			
		||||
 | 
			
		||||
  If the Program specifies that a proxy can decide which future
 | 
			
		||||
versions of the GNU Affero General Public License can be used, that proxy's
 | 
			
		||||
public statement of acceptance of a version permanently authorizes you
 | 
			
		||||
to choose that version for the Program.
 | 
			
		||||
  10. If you wish to incorporate parts of the Program into other free
 | 
			
		||||
programs whose distribution conditions are different, write to the author
 | 
			
		||||
to ask for permission.  For software which is copyrighted by the Free
 | 
			
		||||
Software Foundation, write to the Free Software Foundation; we sometimes
 | 
			
		||||
make exceptions for this.  Our decision will be guided by the two goals
 | 
			
		||||
of preserving the free status of all derivatives of our free software and
 | 
			
		||||
of promoting the sharing and reuse of software generally.
 | 
			
		||||
 | 
			
		||||
  Later license versions may give you additional or different
 | 
			
		||||
permissions.  However, no additional obligations are imposed on any
 | 
			
		||||
author or copyright holder as a result of your choosing to follow a
 | 
			
		||||
later version.
 | 
			
		||||
			    NO WARRANTY
 | 
			
		||||
 | 
			
		||||
  15. Disclaimer of Warranty.
 | 
			
		||||
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
			
		||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
			
		||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 | 
			
		||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 | 
			
		||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
 | 
			
		||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
 | 
			
		||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 | 
			
		||||
REPAIR OR CORRECTION.
 | 
			
		||||
 | 
			
		||||
  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
 | 
			
		||||
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
 | 
			
		||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
 | 
			
		||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | 
			
		||||
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
 | 
			
		||||
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
 | 
			
		||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 | 
			
		||||
 | 
			
		||||
  16. Limitation of Liability.
 | 
			
		||||
 | 
			
		||||
  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
			
		||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
 | 
			
		||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
 | 
			
		||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
 | 
			
		||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
 | 
			
		||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
 | 
			
		||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
 | 
			
		||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
SUCH DAMAGES.
 | 
			
		||||
 | 
			
		||||
  17. Interpretation of Sections 15 and 16.
 | 
			
		||||
 | 
			
		||||
  If the disclaimer of warranty and limitation of liability provided
 | 
			
		||||
above cannot be given local legal effect according to their terms,
 | 
			
		||||
reviewing courts shall apply local law that most closely approximates
 | 
			
		||||
an absolute waiver of all civil liability in connection with the
 | 
			
		||||
Program, unless a warranty or assumption of liability accompanies a
 | 
			
		||||
copy of the Program in return for a fee.
 | 
			
		||||
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
			
		||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 | 
			
		||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 | 
			
		||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 | 
			
		||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 | 
			
		||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 | 
			
		||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
			
		||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
			
		||||
POSSIBILITY OF SUCH DAMAGES.
 | 
			
		||||
 | 
			
		||||
		     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
@@ -626,36 +287,53 @@ free software which everyone can redistribute and change under these terms.
 | 
			
		||||
 | 
			
		||||
  To do so, attach the following notices to the program.  It is safest
 | 
			
		||||
to attach them to the start of each source file to most effectively
 | 
			
		||||
state the exclusion of warranty; and each file should have at least
 | 
			
		||||
convey the exclusion of warranty; and each file should have at least
 | 
			
		||||
the "copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
 | 
			
		||||
    <one line to give the program's name and a brief idea of what it does.>
 | 
			
		||||
    Copyright (C) <year>  <name of author>
 | 
			
		||||
 | 
			
		||||
    This program is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    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 Affero General Public License for more details.
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
  If your software can interact with users remotely through a computer
 | 
			
		||||
network, you should also make sure that it provides a way for users to
 | 
			
		||||
get its source.  For example, if your program is a web application, its
 | 
			
		||||
interface could display a "Source" link that leads users to an archive
 | 
			
		||||
of the code.  There are many ways you could offer source, and different
 | 
			
		||||
solutions will be better for different programs; see section 13 for the
 | 
			
		||||
specific requirements.
 | 
			
		||||
If the program is interactive, make it output a short notice like this
 | 
			
		||||
when it starts in an interactive mode:
 | 
			
		||||
 | 
			
		||||
  You should also get your employer (if you work as a programmer) or school,
 | 
			
		||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
 | 
			
		||||
For more information on this, and how to apply and follow the GNU AGPL, see
 | 
			
		||||
<http://www.gnu.org/licenses/>.
 | 
			
		||||
    Gnomovision version 69, Copyright (C) year name of author
 | 
			
		||||
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
			
		||||
    This is free software, and you are welcome to redistribute it
 | 
			
		||||
    under certain conditions; type `show c' for details.
 | 
			
		||||
 | 
			
		||||
The hypothetical commands `show w' and `show c' should show the appropriate
 | 
			
		||||
parts of the General Public License.  Of course, the commands you use may
 | 
			
		||||
be called something other than `show w' and `show c'; they could even be
 | 
			
		||||
mouse-clicks or menu items--whatever suits your program.
 | 
			
		||||
 | 
			
		||||
You should also get your employer (if you work as a programmer) or your
 | 
			
		||||
school, if any, to sign a "copyright disclaimer" for the program, if
 | 
			
		||||
necessary.  Here is a sample; alter the names:
 | 
			
		||||
 | 
			
		||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 | 
			
		||||
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
 | 
			
		||||
 | 
			
		||||
  <signature of Ty Coon>, 1 April 1989
 | 
			
		||||
  Ty Coon, President of Vice
 | 
			
		||||
 | 
			
		||||
This General Public License does not permit incorporating your program into
 | 
			
		||||
proprietary programs.  If your program is a subroutine library, you may
 | 
			
		||||
consider it more useful to permit linking proprietary applications with the
 | 
			
		||||
library.  If this is what you want to do, use the GNU Lesser General
 | 
			
		||||
Public License instead of this License.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +1,10 @@
 | 
			
		||||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
 | 
			
		||||
 | 
			
		||||
## FIXME: automake >= 1.13 or autoconf >= 2.70 provide better suited AC_CONFIG_MACRO_DIRS for configure.ac
 | 
			
		||||
## remove line below when OE toolchain is updated to version which include those
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4
 | 
			
		||||
AM_CPPFLAGS = \
 | 
			
		||||
	$(all_includes) \
 | 
			
		||||
	-I$(top_srcdir)/include \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
SUBDIRS = \
 | 
			
		||||
	doc \
 | 
			
		||||
	include \
 | 
			
		||||
	src \
 | 
			
		||||
	tests \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
 | 
			
		||||
SUBDIRS = include src tests
 | 
			
		||||
 | 
			
		||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
			
		||||
pkgconfig_DATA = openbsc.pc
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES = $(top_srcdir)/.version
 | 
			
		||||
EXTRA_DIST = git-version-gen osmoappdesc.py .version
 | 
			
		||||
$(top_srcdir)/.version:
 | 
			
		||||
	echo $(VERSION) > $@-t && mv $@-t $@
 | 
			
		||||
dist-hook:
 | 
			
		||||
	echo $(VERSION) > $(distdir)/.tarball-version
 | 
			
		||||
#dist-hook:
 | 
			
		||||
#	rm -rf `find $(distdir) -name .svn`
 | 
			
		||||
 
 | 
			
		||||
@@ -1,39 +1,18 @@
 | 
			
		||||
About OpenBSC
 | 
			
		||||
=============
 | 
			
		||||
 | 
			
		||||
OpenBSC started as a minimalistic all-in-one implementation of the GSM Network,
 | 
			
		||||
with particular emphasis on the functionality typically provided by the BSC,
 | 
			
		||||
MSC, HLR, VLR and SMSC.  Today it is a growing suite of libraries and programs,
 | 
			
		||||
implementing protocol stacks and functional elements, including
 | 
			
		||||
OpenBSC is a minimalistic implementation of the GSM Network, with particular
 | 
			
		||||
emphasis on the functionality typically provided by the BSC, MSC, HLR, VLR.
 | 
			
		||||
 | 
			
		||||
 * OsmoBSC - a pure GSM BSC, speaking Abis/IP to the BTS and A/IP to the MSC
 | 
			
		||||
 * OsmoBSC-MGCP - MGCP helper to the OsmoBSC software
 | 
			
		||||
 * OsmoNITB - a BSC+MSC+VLR+HLR+SMSC "Network in the box".
 | 
			
		||||
 * OsmoMSC - a voice CN with A/IP and IuCS/IP towards the BSC and/or HNB-GW
 | 
			
		||||
 * OsmoSGSN - a GPRS SGSN with Gb/IP and IuPS/IP towards the PCU and/or HNB-GW
 | 
			
		||||
 * Osmo-GbProxy - a Proxy to aggregate many Gb links as one Gb link to the SGSN
 | 
			
		||||
 * OsmoBSCNAT - a gateway aggregating many A links as one A link to the MSC
 | 
			
		||||
 * OsmoGTPHUB - a hub aggregating many GTP links (between SGSN and GGSN)
 | 
			
		||||
 * ipaccess-utils - some tools to discover + configure ip.access nanoBTS
 | 
			
		||||
 * bs11_config - a tool to configure the Siemens BS-11 microBTS
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
Various interfaces towards the BTS are supported, among which are:
 | 
			
		||||
So far, it has only been tested with the Siemens microBTS BS-11.  Test reports
 | 
			
		||||
with other BTS are appreciated!
 | 
			
		||||
 | 
			
		||||
 * Classic A-bis over E1 using a mISDN based E1 interface. In other
 | 
			
		||||
   words, you can connect existing GSM Base Transceiver Station (BTS)
 | 
			
		||||
   through E1 to OpenBSC.  So far, we have made it work with the Siemens BS-11,
 | 
			
		||||
   various Ericsson RBS2xxx BTS models and the Nokia MetroSite.
 | 
			
		||||
 | 
			
		||||
 * A-bis over IP as used by the ip.access nanoBTS product family as well as
 | 
			
		||||
   the Open Source OsmoBTS software (by the same authors as OpenBSC).  OsmoBTS
 | 
			
		||||
   in turn supports various transceiver hardware, including the sysmoBTS
 | 
			
		||||
   product family, as well as SDR transceivers supported by OsmoTRX, such as
 | 
			
		||||
   the UmTRX or USRP boardss.
 | 
			
		||||
 | 
			
		||||
 * IuCS and IuPS over IP towards an HNB-GW (see osmo-iuh) for UMTS (3G)
 | 
			
		||||
   voice and data links.
 | 
			
		||||
 | 
			
		||||
Find OpenBSC online at
 | 
			
		||||
http://openbsc.osmocom.org/
 | 
			
		||||
This project is still in its early days, and there are lots of areas where it
 | 
			
		||||
doesn't behave as per GSM spec.
 | 
			
		||||
 | 
			
		||||
December 29, 2008
 | 
			
		||||
	Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
To run the configuration parsing and output (VTY) test suite, first install
 | 
			
		||||
 | 
			
		||||
  git://git.osmocom.org/python/osmo-python-tests
 | 
			
		||||
 | 
			
		||||
and pass the following configure options here:
 | 
			
		||||
 | 
			
		||||
  ./configure --enable-vty-tests --enable-external-tests
 | 
			
		||||
 | 
			
		||||
The VTY tests are then included in the standard check target:
 | 
			
		||||
 | 
			
		||||
  make check
 | 
			
		||||
@@ -1,266 +0,0 @@
 | 
			
		||||
dnl Process this file with autoconf to produce a configure script
 | 
			
		||||
AC_INIT([openbsc],
 | 
			
		||||
	m4_esyscmd([./git-version-gen .tarball-version]),
 | 
			
		||||
	[openbsc@lists.osmocom.org])
 | 
			
		||||
 | 
			
		||||
dnl *This* is the root dir, even if an install-sh exists in ../ or ../../
 | 
			
		||||
AC_CONFIG_AUX_DIR([.])
 | 
			
		||||
 | 
			
		||||
AM_INIT_AUTOMAKE([dist-bzip2])
 | 
			
		||||
AC_CONFIG_TESTDIR(tests)
 | 
			
		||||
 | 
			
		||||
dnl kernel style compile messages
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
			
		||||
 | 
			
		||||
dnl checks for programs
 | 
			
		||||
AC_PROG_MAKE_SET
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
LT_INIT
 | 
			
		||||
 | 
			
		||||
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
 | 
			
		||||
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
 | 
			
		||||
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
 | 
			
		||||
        AC_MSG_WARN([You need to install pkg-config])
 | 
			
		||||
fi
 | 
			
		||||
PKG_PROG_PKG_CONFIG([0.20])
 | 
			
		||||
 | 
			
		||||
dnl check for AX_CHECK_COMPILE_FLAG
 | 
			
		||||
m4_ifdef([AX_CHECK_COMPILE_FLAG], [], [
 | 
			
		||||
	AC_MSG_ERROR([Please install autoconf-archive; re-run 'autoreconf -fi' for it to take effect.])
 | 
			
		||||
	])
 | 
			
		||||
 | 
			
		||||
dnl checks for libraries
 | 
			
		||||
AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""])
 | 
			
		||||
AC_SUBST(LIBRARY_DL)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.9.5)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.9.5)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.2.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 0.6.4)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.1)
 | 
			
		||||
PKG_CHECK_MODULES(LIBCRYPTO, libcrypto >= 0.9.5)
 | 
			
		||||
 | 
			
		||||
# Enabke/disable the NAT?
 | 
			
		||||
AC_ARG_ENABLE([nat], [AS_HELP_STRING([--enable-nat], [Build the BSC NAT. Requires SCCP])],
 | 
			
		||||
    [osmo_ac_build_nat="$enableval"],[osmo_ac_build_nat="no"])
 | 
			
		||||
if test "$osmo_ac_build_nat" = "yes" ; then
 | 
			
		||||
        PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.2)
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL(BUILD_NAT, test "x$osmo_ac_build_nat" = "xyes")
 | 
			
		||||
AC_SUBST(osmo_ac_build_nat)
 | 
			
		||||
 | 
			
		||||
# Enable/disable the BSC?
 | 
			
		||||
AC_ARG_ENABLE([osmo-bsc], [AS_HELP_STRING([--enable-osmo-bsc], [Build the Osmo BSC])],
 | 
			
		||||
    [osmo_ac_build_bsc="$enableval"],[osmo_ac_build_bsc="no"])
 | 
			
		||||
if test "$osmo_ac_build_bsc" = "yes" ; then
 | 
			
		||||
    PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.6)
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
 | 
			
		||||
AC_SUBST(osmo_ac_build_bsc)
 | 
			
		||||
 | 
			
		||||
# Enable/disable smpp support in the nitb?
 | 
			
		||||
AC_ARG_ENABLE([smpp], [AS_HELP_STRING([--enable-smpp], [Build the SMPP interface])],
 | 
			
		||||
    [osmo_ac_build_smpp="$enableval"],[osmo_ac_build_smpp="no"])
 | 
			
		||||
if test "$osmo_ac_build_smpp" = "yes" ; then
 | 
			
		||||
    PKG_CHECK_MODULES(LIBSMPP34, libsmpp34 >= 1.10)
 | 
			
		||||
    AC_DEFINE(BUILD_SMPP, 1, [Define if we want to build SMPP])
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL(BUILD_SMPP, test "x$osmo_ac_build_smpp" = "xyes")
 | 
			
		||||
AC_SUBST(osmo_ac_build_smpp)
 | 
			
		||||
 | 
			
		||||
# Enable/disable transcoding within osmo-bsc_mgcp?
 | 
			
		||||
AC_ARG_ENABLE([mgcp-transcoding], [AS_HELP_STRING([--enable-mgcp-transcoding], [Build the MGCP gateway with internal transcoding enabled.])],
 | 
			
		||||
    [osmo_ac_mgcp_transcoding="$enableval"],[osmo_ac_mgcp_transcoding="no"])
 | 
			
		||||
AC_ARG_WITH([g729], [AS_HELP_STRING([--with-g729], [Enable G.729 encoding/decoding.])], [osmo_ac_with_g729="$withval"],[osmo_ac_with_g729="no"])
 | 
			
		||||
 | 
			
		||||
if test "$osmo_ac_mgcp_transcoding" = "yes" ; then
 | 
			
		||||
    AC_SEARCH_LIBS([gsm_create], [gsm], [LIBRARY_GSM="$LIBS";LIBS=""], [AC_MSG_ERROR([--enable-mgcp-transcoding: cannot find usable libgsm])])
 | 
			
		||||
    AC_SUBST(LIBRARY_GSM)
 | 
			
		||||
    if test "$osmo_ac_with_g729" = "yes" ; then
 | 
			
		||||
	PKG_CHECK_MODULES(LIBBCG729, libbcg729 >= 0.1, [AC_DEFINE([HAVE_BCG729], [1], [Use bgc729 decoder/encoder])])
 | 
			
		||||
    fi
 | 
			
		||||
    AC_DEFINE(BUILD_MGCP_TRANSCODING, 1, [Define if we want to build the MGCP gateway with transcoding support])
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL(BUILD_MGCP_TRANSCODING, test "x$osmo_ac_mgcp_transcoding" = "xyes")
 | 
			
		||||
AC_SUBST(osmo_ac_mgcp_transcoding)
 | 
			
		||||
 | 
			
		||||
# Enable/disable 3G aka IuPS + IuCS support?
 | 
			
		||||
AC_ARG_ENABLE([iu], [AS_HELP_STRING([--enable-iu], [Build 3G support, aka IuPS and IuCS interfaces])],
 | 
			
		||||
    [osmo_ac_iu="$enableval"],[osmo_ac_iu="no"])
 | 
			
		||||
if test "x$osmo_ac_iu" = "xyes" ; then
 | 
			
		||||
    PKG_CHECK_MODULES(LIBASN1C, libasn1c) # TODO version?
 | 
			
		||||
    PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap) # TODO version?
 | 
			
		||||
    PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran) # TODO version?
 | 
			
		||||
    AC_DEFINE(BUILD_IU, 1, [Define if we want to build IuPS and IuCS interfaces support])
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL(BUILD_IU, test "x$osmo_ac_iu" = "xyes")
 | 
			
		||||
AC_SUBST(osmo_ac_iu)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
found_libgtp=yes
 | 
			
		||||
PKG_CHECK_MODULES(LIBGTP, libgtp >= 0.92, , found_libgtp=no)
 | 
			
		||||
AM_CONDITIONAL(HAVE_LIBGTP, test "$found_libgtp" = yes)
 | 
			
		||||
AC_SUBST(found_libgtp)
 | 
			
		||||
 | 
			
		||||
found_libcares=yes
 | 
			
		||||
PKG_CHECK_MODULES([LIBCARES], [libcares], [], [found_libcares=no])
 | 
			
		||||
AM_CONDITIONAL(HAVE_LIBCARES, test "$found_libcares" = yes)
 | 
			
		||||
AC_SUBST(found_libcares)
 | 
			
		||||
 | 
			
		||||
found_libgtp_and_libcares=no
 | 
			
		||||
if test "$found_libgtp" = "yes" -a "$found_libcares" = "yes"; then
 | 
			
		||||
    found_libgtp_and_libcares=yes
 | 
			
		||||
fi
 | 
			
		||||
AC_SUBST(found_libgtp_and_libcares)
 | 
			
		||||
 | 
			
		||||
dnl checks for header files
 | 
			
		||||
AC_HEADER_STDC
 | 
			
		||||
AC_CHECK_HEADERS(dbi/dbd.h,,AC_MSG_ERROR(DBI library is not installed))
 | 
			
		||||
 | 
			
		||||
found_pcap=yes
 | 
			
		||||
AC_CHECK_HEADERS(pcap/pcap.h,,found_pcap=no)
 | 
			
		||||
AM_CONDITIONAL(HAVE_PCAP, test "$found_pcap" = yes)
 | 
			
		||||
 | 
			
		||||
found_cdk=yes
 | 
			
		||||
AC_CHECK_HEADERS(cdk/cdk.h,,found_cdk=no)
 | 
			
		||||
AM_CONDITIONAL(HAVE_LIBCDK, test "$found_cdk" = yes)
 | 
			
		||||
 | 
			
		||||
found_sqlite3=yes
 | 
			
		||||
PKG_CHECK_MODULES(SQLITE3, sqlite3, ,found_sqlite3=no)
 | 
			
		||||
AM_CONDITIONAL(HAVE_SQLITE3, test "$found_sqlite3" = yes)
 | 
			
		||||
AC_SUBST(found_sqlite3)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dnl Checks for typedefs, structures and compiler characteristics
 | 
			
		||||
 | 
			
		||||
# The following test is taken from WebKit's webkit.m4
 | 
			
		||||
saved_CFLAGS="$CFLAGS"
 | 
			
		||||
CFLAGS="$CFLAGS -fvisibility=hidden "
 | 
			
		||||
AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
 | 
			
		||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])],
 | 
			
		||||
      [ AC_MSG_RESULT([yes])
 | 
			
		||||
        SYMBOL_VISIBILITY="-fvisibility=hidden"],
 | 
			
		||||
        AC_MSG_RESULT([no]))
 | 
			
		||||
CFLAGS="$saved_CFLAGS"
 | 
			
		||||
AC_SUBST(SYMBOL_VISIBILITY)
 | 
			
		||||
 | 
			
		||||
AX_CHECK_COMPILE_FLAG([-Werror=implicit], [CFLAGS="$CFLAGS -Werror=implicit"])
 | 
			
		||||
AX_CHECK_COMPILE_FLAG([-Werror=maybe-uninitialized], [CFLAGS="$CFLAGS -Werror=maybe-uninitialized"])
 | 
			
		||||
AX_CHECK_COMPILE_FLAG([-Werror=memset-transposed-args], [CFLAGS="$CFLAGS -Werror=memset-transposed-args"])
 | 
			
		||||
AX_CHECK_COMPILE_FLAG([-Werror=null-dereference], [CFLAGS="$CFLAGS -Werror=null-dereference"])
 | 
			
		||||
AX_CHECK_COMPILE_FLAG([-Werror=sizeof-array-argument], [CFLAGS="$CFLAGS -Werror=sizeof-array-argument"])
 | 
			
		||||
AX_CHECK_COMPILE_FLAG([-Werror=sizeof-pointer-memaccess], [CFLAGS="$CFLAGS -Werror=sizeof-pointer-memaccess"])
 | 
			
		||||
 | 
			
		||||
# Coverage build taken from WebKit's configure.in
 | 
			
		||||
AC_MSG_CHECKING([whether to enable code coverage support])
 | 
			
		||||
AC_ARG_ENABLE(coverage,
 | 
			
		||||
              AC_HELP_STRING([--enable-coverage],
 | 
			
		||||
                             [enable code coverage support [default=no]]),
 | 
			
		||||
              [],[enable_coverage="no"])
 | 
			
		||||
AC_MSG_RESULT([$enable_coverage])
 | 
			
		||||
if test "$enable_coverage" = "yes"; then
 | 
			
		||||
   COVERAGE_CFLAGS="-ftest-coverage -fprofile-arcs"
 | 
			
		||||
   COVERAGE_LDFLAGS="-ftest-coverage -fprofile-arcs"
 | 
			
		||||
   AC_SUBST([COVERAGE_CFLAGS])
 | 
			
		||||
   AC_SUBST([COVERAGE_LDFLAGS])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([CHECK_TM_INCLUDES_TM_GMTOFF], [
 | 
			
		||||
  AC_CACHE_CHECK(
 | 
			
		||||
    [whether struct tm has tm_gmtoff member],
 | 
			
		||||
    osmo_cv_tm_includes_tm_gmtoff,
 | 
			
		||||
    [AC_LINK_IFELSE([
 | 
			
		||||
      AC_LANG_PROGRAM([
 | 
			
		||||
        #include <time.h>
 | 
			
		||||
      ], [
 | 
			
		||||
        time_t t = time(NULL);
 | 
			
		||||
        struct tm* lt = localtime(&t);
 | 
			
		||||
        int off = lt->tm_gmtoff;
 | 
			
		||||
      ])
 | 
			
		||||
    ],
 | 
			
		||||
    osmo_cv_tm_includes_tm_gmtoff=yes,
 | 
			
		||||
    osmo_cv_tm_includes_tm_gmtoff=no
 | 
			
		||||
    )]
 | 
			
		||||
  )
 | 
			
		||||
  if test "x$osmo_cv_tm_includes_tm_gmtoff" = xyes; then
 | 
			
		||||
    AC_DEFINE(HAVE_TM_GMTOFF_IN_TM, 1,
 | 
			
		||||
              [Define if struct tm has tm_gmtoff member.])
 | 
			
		||||
  fi
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
CHECK_TM_INCLUDES_TM_GMTOFF
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE([vty_tests],
 | 
			
		||||
		AC_HELP_STRING([--enable-vty-tests],
 | 
			
		||||
				[Include the VTY/CTRL tests in make check (deprecated)
 | 
			
		||||
				[default=no]]),
 | 
			
		||||
		[enable_ext_tests="$enableval"],[enable_ext_tests="no"])
 | 
			
		||||
AC_ARG_ENABLE([external_tests],
 | 
			
		||||
		AC_HELP_STRING([--enable-external-tests],
 | 
			
		||||
				[Include the VTY/CTRL tests in make check [default=no]]),
 | 
			
		||||
		[enable_ext_tests="$enableval"],[enable_ext_tests="no"])
 | 
			
		||||
if test "x$enable_ext_tests" = "xyes" ; then
 | 
			
		||||
	AM_PATH_PYTHON
 | 
			
		||||
	AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
 | 
			
		||||
	 if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
 | 
			
		||||
		AC_MSG_ERROR([Please install osmocom-python to run the VTY/CTRL tests.])
 | 
			
		||||
	fi
 | 
			
		||||
fi
 | 
			
		||||
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
 | 
			
		||||
AC_MSG_RESULT([$enable_ext_tests])
 | 
			
		||||
AM_CONDITIONAL(ENABLE_EXT_TESTS, test "x$enable_ext_tests" = "xyes")
 | 
			
		||||
 | 
			
		||||
dnl Generate the output
 | 
			
		||||
AM_CONFIG_HEADER(bscconfig.h)
 | 
			
		||||
 | 
			
		||||
AC_OUTPUT(
 | 
			
		||||
    openbsc.pc
 | 
			
		||||
    include/openbsc/Makefile
 | 
			
		||||
    include/Makefile
 | 
			
		||||
    src/Makefile
 | 
			
		||||
    src/libtrau/Makefile
 | 
			
		||||
    src/libbsc/Makefile
 | 
			
		||||
    src/libmsc/Makefile
 | 
			
		||||
    src/libmgcp/Makefile
 | 
			
		||||
    src/libcommon/Makefile
 | 
			
		||||
    src/libfilter/Makefile
 | 
			
		||||
    src/libiu/Makefile
 | 
			
		||||
    src/libcommon-cs/Makefile
 | 
			
		||||
    src/osmo-nitb/Makefile
 | 
			
		||||
    src/osmo-bsc/Makefile
 | 
			
		||||
    src/osmo-bsc_nat/Makefile
 | 
			
		||||
    src/osmo-bsc_mgcp/Makefile
 | 
			
		||||
    src/ipaccess/Makefile
 | 
			
		||||
    src/utils/Makefile
 | 
			
		||||
    src/gprs/Makefile
 | 
			
		||||
    tests/Makefile
 | 
			
		||||
    tests/atlocal
 | 
			
		||||
    tests/gsm0408/Makefile
 | 
			
		||||
    tests/db/Makefile
 | 
			
		||||
    tests/channel/Makefile
 | 
			
		||||
    tests/bsc/Makefile
 | 
			
		||||
    tests/bsc-nat/Makefile
 | 
			
		||||
    tests/bsc-nat-trie/Makefile
 | 
			
		||||
    tests/mgcp/Makefile
 | 
			
		||||
    tests/gprs/Makefile
 | 
			
		||||
    tests/gbproxy/Makefile
 | 
			
		||||
    tests/abis/Makefile
 | 
			
		||||
    tests/smpp/Makefile
 | 
			
		||||
    tests/trau/Makefile
 | 
			
		||||
    tests/sgsn/Makefile
 | 
			
		||||
    tests/subscr/Makefile
 | 
			
		||||
    tests/oap/Makefile
 | 
			
		||||
    tests/gtphub/Makefile
 | 
			
		||||
    tests/mm_auth/Makefile
 | 
			
		||||
    tests/xid/Makefile
 | 
			
		||||
    tests/sndcp_xid/Makefile
 | 
			
		||||
    tests/slhc/Makefile
 | 
			
		||||
    tests/v42bis/Makefile
 | 
			
		||||
    tests/nanobts_omlattr/Makefile
 | 
			
		||||
    doc/Makefile
 | 
			
		||||
    doc/examples/Makefile
 | 
			
		||||
    Makefile)
 | 
			
		||||
							
								
								
									
										54
									
								
								openbsc/configure.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								openbsc/configure.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
dnl Process this file with autoconf to produce a configure script
 | 
			
		||||
AC_INIT
 | 
			
		||||
 | 
			
		||||
AM_INIT_AUTOMAKE(openbsc, 0.3.1onwaves)
 | 
			
		||||
 | 
			
		||||
dnl kernel style compile messages
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
			
		||||
 | 
			
		||||
dnl checks for programs
 | 
			
		||||
AC_PROG_MAKE_SET
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
AC_PROG_RANLIB
 | 
			
		||||
 | 
			
		||||
dnl checks for libraries
 | 
			
		||||
AC_SEARCH_LIBS(crypt, crypt,
 | 
			
		||||
    [LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
 | 
			
		||||
 | 
			
		||||
dnl checks for header files
 | 
			
		||||
AC_HEADER_STDC
 | 
			
		||||
 | 
			
		||||
dnl Checks for typedefs, structures and compiler characteristics
 | 
			
		||||
 | 
			
		||||
# The following test is taken from WebKit's webkit.m4
 | 
			
		||||
saved_CFLAGS="$CFLAGS"
 | 
			
		||||
CFLAGS="$CFLAGS -fvisibility=hidden "
 | 
			
		||||
AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
 | 
			
		||||
AC_COMPILE_IFELSE([char foo;],
 | 
			
		||||
      [ AC_MSG_RESULT([yes])
 | 
			
		||||
        SYMBOL_VISIBILITY="-fvisibility=hidden"],
 | 
			
		||||
        AC_MSG_RESULT([no]))
 | 
			
		||||
CFLAGS="$saved_CFLAGS"
 | 
			
		||||
AC_SUBST(SYMBOL_VISIBILITY)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dnl Generate the output
 | 
			
		||||
AM_CONFIG_HEADER(bscconfig.h)
 | 
			
		||||
 | 
			
		||||
AC_OUTPUT(
 | 
			
		||||
    openbsc.pc
 | 
			
		||||
    include/openbsc/Makefile
 | 
			
		||||
    include/vty/Makefile
 | 
			
		||||
    include/sccp/Makefile
 | 
			
		||||
    include/Makefile
 | 
			
		||||
    src/Makefile
 | 
			
		||||
    tests/Makefile
 | 
			
		||||
    tests/debug/Makefile
 | 
			
		||||
    tests/timer/Makefile
 | 
			
		||||
    tests/sms/Makefile
 | 
			
		||||
    tests/gsm0408/Makefile
 | 
			
		||||
    tests/db/Makefile
 | 
			
		||||
    tests/channel/Makefile
 | 
			
		||||
    tests/sccp/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,170 +0,0 @@
 | 
			
		||||
-- Split trace based on SCCP Source
 | 
			
		||||
-- There are still bugs to find... bugs bugs bugs... hmm
 | 
			
		||||
do
 | 
			
		||||
        local function init_listener()
 | 
			
		||||
                print("CREATED LISTENER")
 | 
			
		||||
		local tap = Listener.new("ip", "sccp && (ip.src == 172.16.1.81 || ip.dst == 172.16.1.81)")
 | 
			
		||||
		local sccp_type_field = Field.new("sccp.message_type")
 | 
			
		||||
		local sccp_src_field = Field.new("sccp.slr")
 | 
			
		||||
		local sccp_dst_field = Field.new("sccp.dlr")
 | 
			
		||||
		local msg_type_field = Field.new("gsm_a.dtap_msg_mm_type")
 | 
			
		||||
		local lu_rej_field = Field.new("gsm_a.dtap.rej_cause")
 | 
			
		||||
		local ip_src_field = Field.new("ip.src")
 | 
			
		||||
		local ip_dst_field = Field.new("ip.dst")
 | 
			
		||||
 | 
			
		||||
		--
 | 
			
		||||
		local bssmap_msgtype_field = Field.new("gsm_a.bssmap_msgtype")
 | 
			
		||||
		-- assignment failure 0x03
 | 
			
		||||
		-- 
 | 
			
		||||
 | 
			
		||||
		--
 | 
			
		||||
		local dtap_cause_field = Field.new("gsm_a_dtap.cause")
 | 
			
		||||
		local dtap_cc_field = Field.new("gsm_a.dtap_msg_cc_type")
 | 
			
		||||
 | 
			
		||||
		local connections = {}
 | 
			
		||||
 | 
			
		||||
		function check_failure(con)
 | 
			
		||||
			check_lu_reject(con)
 | 
			
		||||
			check_disconnect(con)
 | 
			
		||||
			check_failures(con)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		-- cipher mode reject
 | 
			
		||||
		function check_failures(con)
 | 
			
		||||
			local msgtype = bssmap_msgtype_field()
 | 
			
		||||
			if not msgtype then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			msgtype = tonumber(msgtype)
 | 
			
		||||
			if msgtype == 89 then
 | 
			
		||||
				print("Cipher mode reject")
 | 
			
		||||
				con[4] = true
 | 
			
		||||
			elseif msgtype == 0x03 then
 | 
			
		||||
				print("Assignment failure")
 | 
			
		||||
				con[4] = true
 | 
			
		||||
			elseif msgtype == 0x22 then
 | 
			
		||||
				print("Clear Request... RF failure?")
 | 
			
		||||
				con[4] = true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		-- check if a DISCONNECT is normal
 | 
			
		||||
		function check_disconnect(con)
 | 
			
		||||
			local msg_type = dtap_cc_field()
 | 
			
		||||
			if not msg_type then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			if tonumber(msg_type) ~= 0x25 then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			local cause = dtap_cause_field()
 | 
			
		||||
			if not cause then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			cause = tonumber(cause)
 | 
			
		||||
			if cause ~= 0x10 then
 | 
			
		||||
				print("DISCONNECT != Normal")
 | 
			
		||||
				con[4] = true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		-- check if we have a LU Reject
 | 
			
		||||
		function check_lu_reject(con)
 | 
			
		||||
			local msg_type =  msg_type_field()
 | 
			
		||||
			if not msg_type then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			msg_type = tonumber(tostring(msg_type))
 | 
			
		||||
			if msg_type == 0x04 then
 | 
			
		||||
				print("LU REJECT with " .. tostring(lu_rej_field()))
 | 
			
		||||
				con[4] = true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
                function tap.packet(pinfo,tvb,ip)
 | 
			
		||||
			local ip_src = tostring(ip_src_field())
 | 
			
		||||
			local ip_dst = tostring(ip_dst_field())
 | 
			
		||||
			local sccp_type = tonumber(tostring(sccp_type_field()))
 | 
			
		||||
			local sccp_src = sccp_src_field()
 | 
			
		||||
			local sccp_dst = sccp_dst_field()
 | 
			
		||||
 | 
			
		||||
			local con
 | 
			
		||||
 | 
			
		||||
			if sccp_type == 0x01 then
 | 
			
		||||
			elseif sccp_type == 0x2 then
 | 
			
		||||
				local src = string.format("%s-%s", ip_src, tostring(sccp_src))
 | 
			
		||||
				local dst = string.format("%s-%s", ip_dst, tostring(sccp_dst))
 | 
			
		||||
				local datestring = os.date("%Y%m%d%H%M%S")
 | 
			
		||||
				local pcap_name = string.format("alink_trace_%s-%s_%s.pcap", src, dst, datestring)
 | 
			
		||||
				local dumper = Dumper.new_for_current(pcap_name)
 | 
			
		||||
 | 
			
		||||
				local con = { ip_src, tostring(sccp_src), tostring(sccp_dst), false, dumper, pcap_name }
 | 
			
		||||
 | 
			
		||||
				dumper:dump_current()
 | 
			
		||||
				connections[src] = con
 | 
			
		||||
				connections[dst] = con
 | 
			
		||||
			elseif sccp_type == 0x4 then
 | 
			
		||||
				-- close a connection... remove it from the list
 | 
			
		||||
				local src = string.format("%s-%s", ip_src, tostring(sccp_src))
 | 
			
		||||
				local dst = string.format("%s-%s", ip_dst, tostring(sccp_dst))
 | 
			
		||||
 | 
			
		||||
				local con = connections[src]
 | 
			
		||||
				if not con then
 | 
			
		||||
					return
 | 
			
		||||
				end
 | 
			
		||||
 | 
			
		||||
				con[5]:dump_current()
 | 
			
		||||
				con[5]:flush()
 | 
			
		||||
 | 
			
		||||
				-- this causes a crash on unpacted wireshark
 | 
			
		||||
				con[5]:close()
 | 
			
		||||
 | 
			
		||||
				-- the connection had a failure
 | 
			
		||||
				if con[4] == true then
 | 
			
		||||
					local datestring = os.date("%Y%m%d%H%M%S")
 | 
			
		||||
					local new_name = string.format("alink_failure_%s_%s-%s.pcap", datestring, con[2], con[3])
 | 
			
		||||
					os.rename(con[6], new_name)
 | 
			
		||||
				else
 | 
			
		||||
					os.remove(con[6])
 | 
			
		||||
				end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
				-- clear the old connection
 | 
			
		||||
				connections[src] = nil
 | 
			
		||||
				connections[dst] = nil
 | 
			
		||||
 | 
			
		||||
			elseif sccp_type == 0x5 then
 | 
			
		||||
				-- not handled yet... we should verify stuff here...
 | 
			
		||||
				local dst = string.format("%s-%s", ip_dst, tostring(sccp_dst))
 | 
			
		||||
				local con = connections[dst]
 | 
			
		||||
				if not con then
 | 
			
		||||
					return
 | 
			
		||||
				end
 | 
			
		||||
				con[5]:dump_current()
 | 
			
		||||
			elseif sccp_type == 0x6 then
 | 
			
		||||
				local dst = string.format("%s-%s", ip_dst, tostring(sccp_dst))
 | 
			
		||||
				local con = connections[dst]
 | 
			
		||||
				if not con then
 | 
			
		||||
					print("DON'T KNOW THIS CONNECTION for " .. ip_dst)
 | 
			
		||||
					return
 | 
			
		||||
				end
 | 
			
		||||
				con[5]:dump_current()
 | 
			
		||||
				check_failure(con)
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
                end
 | 
			
		||||
                function tap.draw()
 | 
			
		||||
                        print("DRAW")
 | 
			
		||||
                end
 | 
			
		||||
                function tap.reset()
 | 
			
		||||
                        print("RESET")
 | 
			
		||||
                end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        init_listener()
 | 
			
		||||
end
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
Some crazy scripts call testing... and MSC link failure simulation
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
ABORT BUSY
 | 
			
		||||
ABORT 'NO CARRIER'
 | 
			
		||||
ABORT 'OK'
 | 
			
		||||
 | 
			
		||||
'' AT
 | 
			
		||||
SAY "Dialing a number\n"
 | 
			
		||||
'OK' ATD05660066;
 | 
			
		||||
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# Evil dial script..
 | 
			
		||||
 | 
			
		||||
while true;
 | 
			
		||||
do
 | 
			
		||||
	chat -v -f all_dial < /dev/ttyACM0 > /dev/ttyACM0
 | 
			
		||||
	sleep 5s
 | 
			
		||||
	chat -v -f hangup < /dev/ttyACM0 > /dev/ttyACM0
 | 
			
		||||
	sleep 2s
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
sleep 3
 | 
			
		||||
echo "enable"
 | 
			
		||||
sleep 1
 | 
			
		||||
echo "drop bts connection 0 oml"
 | 
			
		||||
sleep 1
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
while true;
 | 
			
		||||
do
 | 
			
		||||
	echo "Going to drop the OML connection"
 | 
			
		||||
	./drop-oml.sh | telnet 127.0.0.1 4242
 | 
			
		||||
	sleep 58m
 | 
			
		||||
done
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
TIMEOUT 10
 | 
			
		||||
'' ^Z
 | 
			
		||||
SAY "Waiting for hangup confirm\n"
 | 
			
		||||
'' ATH;
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
while true;
 | 
			
		||||
do
 | 
			
		||||
	echo "Kill the osmo-bsc"
 | 
			
		||||
	/usr/bin/kill -s SIGUSR2 `pidof osmo-bsc`
 | 
			
		||||
	sleep 58s
 | 
			
		||||
done
 | 
			
		||||
@@ -1,120 +0,0 @@
 | 
			
		||||
#!/usr/bin/python
 | 
			
		||||
# -*- mode: python-mode; py-indent-tabs-mode: nil -*-
 | 
			
		||||
"""
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from optparse import OptionParser
 | 
			
		||||
from ipa import Ctrl
 | 
			
		||||
import socket
 | 
			
		||||
 | 
			
		||||
verbose = False
 | 
			
		||||
 | 
			
		||||
def connect(host, port):
 | 
			
		||||
        if verbose:
 | 
			
		||||
                print "Connecting to host %s:%i" % (host, port)
 | 
			
		||||
 | 
			
		||||
        sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 | 
			
		||||
        sck.setblocking(1)
 | 
			
		||||
        sck.connect((host, port))
 | 
			
		||||
        return sck
 | 
			
		||||
 | 
			
		||||
def do_set_get(sck, var, value = None):
 | 
			
		||||
        (r, c) = Ctrl().cmd(var, value)
 | 
			
		||||
        sck.send(c)
 | 
			
		||||
        answer = Ctrl().rem_header(sck.recv(4096))
 | 
			
		||||
        return (answer,) + Ctrl().verify(answer, r, var, value)
 | 
			
		||||
 | 
			
		||||
def set_var(sck, var, val):
 | 
			
		||||
        (a, _, _) = do_set_get(sck, var, val)
 | 
			
		||||
        return a
 | 
			
		||||
 | 
			
		||||
def get_var(sck, var):
 | 
			
		||||
        (_, _, v) = do_set_get(sck, var)
 | 
			
		||||
        return v
 | 
			
		||||
 | 
			
		||||
def _leftovers(sck, fl):
 | 
			
		||||
        """
 | 
			
		||||
        Read outstanding data if any according to flags
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
                data = sck.recv(1024, fl)
 | 
			
		||||
        except socket.error as (s_errno, strerror):
 | 
			
		||||
                return False
 | 
			
		||||
        if len(data) != 0:
 | 
			
		||||
                tail = data
 | 
			
		||||
                while True:
 | 
			
		||||
                        (head, tail) = Ctrl().split_combined(tail)
 | 
			
		||||
                        print "Got message:", Ctrl().rem_header(head)
 | 
			
		||||
                        if len(tail) == 0:
 | 
			
		||||
                                break
 | 
			
		||||
                return True
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
        parser = OptionParser("Usage: %prog [options] var [value]")
 | 
			
		||||
        parser.add_option("-d", "--host", dest="host",
 | 
			
		||||
                          help="connect to HOST", metavar="HOST")
 | 
			
		||||
        parser.add_option("-p", "--port", dest="port", type="int",
 | 
			
		||||
                          help="use PORT", metavar="PORT", default=4249)
 | 
			
		||||
        parser.add_option("-g", "--get", action="store_true",
 | 
			
		||||
                          dest="cmd_get", help="perform GET operation")
 | 
			
		||||
        parser.add_option("-s", "--set", action="store_true",
 | 
			
		||||
                          dest="cmd_set", help="perform SET operation")
 | 
			
		||||
        parser.add_option("-v", "--verbose", action="store_true",
 | 
			
		||||
                          dest="verbose", help="be verbose", default=False)
 | 
			
		||||
        parser.add_option("-m", "--monitor", action="store_true",
 | 
			
		||||
                          dest="monitor", help="monitor the connection for traps", default=False)
 | 
			
		||||
 | 
			
		||||
        (options, args) = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
        verbose = options.verbose
 | 
			
		||||
 | 
			
		||||
        if options.cmd_set and options.cmd_get:
 | 
			
		||||
                parser.error("Get and set options are mutually exclusive!")
 | 
			
		||||
 | 
			
		||||
        if not (options.cmd_get or options.cmd_set or options.monitor):
 | 
			
		||||
                parser.error("One of -m, -g, or -s must be set")
 | 
			
		||||
 | 
			
		||||
        if not (options.host):
 | 
			
		||||
                parser.error("Destination host and port required!")
 | 
			
		||||
 | 
			
		||||
        sock = connect(options.host, options.port)
 | 
			
		||||
 | 
			
		||||
        if options.cmd_set:
 | 
			
		||||
                if len(args) < 2:
 | 
			
		||||
                        parser.error("Set requires var and value arguments")
 | 
			
		||||
                _leftovers(sock, socket.MSG_DONTWAIT)
 | 
			
		||||
                print "Got message:", set_var(sock, args[0], ' '.join(args[1:]))
 | 
			
		||||
 | 
			
		||||
        if options.cmd_get:
 | 
			
		||||
                if len(args) != 1:
 | 
			
		||||
                        parser.error("Get requires the var argument")
 | 
			
		||||
                _leftovers(sock, socket.MSG_DONTWAIT)
 | 
			
		||||
                (a, _, _) = do_set_get(sock, args[0])
 | 
			
		||||
                print "Got message:", a
 | 
			
		||||
 | 
			
		||||
        if options.monitor:
 | 
			
		||||
                while True:
 | 
			
		||||
                        if not _leftovers(sock, 0):
 | 
			
		||||
                                print "Connection is gone."
 | 
			
		||||
                                break
 | 
			
		||||
        sock.close()
 | 
			
		||||
@@ -1,147 +0,0 @@
 | 
			
		||||
#!/usr/bin/python2
 | 
			
		||||
 | 
			
		||||
mod_license = '''
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
import sys, argparse, random, logging, tornado.ioloop, tornado.web, tornado.tcpclient, tornado.httpclient, eventsource, bsc_control
 | 
			
		||||
from eventsource import listener, request
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
N. B: this is not an example of building proper REST API or building secure web application.
 | 
			
		||||
It's only purpose is to illustrate conversion of Osmocom's Control Interface to web-friendly API.
 | 
			
		||||
Exposing this to Internet while connected to production network might lead to all sorts of mischief and mayhem
 | 
			
		||||
from NSA' TAO breaking into your network to zombie apocalypse. Do NOT do that.
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
token = None
 | 
			
		||||
stream = None
 | 
			
		||||
url = None
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
Returns json according to following schema - see http://json-schema.org/documentation.html for details:
 | 
			
		||||
{
 | 
			
		||||
        "title": "Ctrl Schema",
 | 
			
		||||
        "type": "object",
 | 
			
		||||
        "properties": {
 | 
			
		||||
                "variable": {
 | 
			
		||||
                        "type": "string"
 | 
			
		||||
                },
 | 
			
		||||
                "varlue": {
 | 
			
		||||
                        "type": "string"
 | 
			
		||||
                }
 | 
			
		||||
        },
 | 
			
		||||
        "required": ["interface", "variable", "value"]
 | 
			
		||||
}
 | 
			
		||||
Example validation from command-line:
 | 
			
		||||
json validate --schema-file=schema.json --document-file=data.json
 | 
			
		||||
The interface is represented as string because it might look different for IPv4 vs v6.
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
def read_header(data):
 | 
			
		||||
	t_length = bsc_control.ipa_ctrl_header(data)
 | 
			
		||||
	if (t_length):
 | 
			
		||||
		stream.read_bytes(t_length - 1, callback = read_trap)
 | 
			
		||||
	else:
 | 
			
		||||
		print >> sys.stderr, "protocol error: length missing in %s!" % data
 | 
			
		||||
 | 
			
		||||
@tornado.gen.coroutine
 | 
			
		||||
def read_trap(data):
 | 
			
		||||
	(t, z, v, p) = data.split()
 | 
			
		||||
	if (t != 'TRAP' or int(z) != 0):
 | 
			
		||||
		print >> sys.stderr, "protocol error: TRAP != %s or 0! = %d" % (t, int(z))
 | 
			
		||||
	else:
 | 
			
		||||
		yield tornado.httpclient.AsyncHTTPClient().fetch(tornado.httpclient.HTTPRequest(url = "%s/%s/%s" % (url, "ping", token),
 | 
			
		||||
												method = 'POST',
 | 
			
		||||
												headers = {'Content-Type': 'application/json'},
 | 
			
		||||
												body = tornado.escape.json_encode({ 'variable' : v, 'value' : p })))
 | 
			
		||||
		stream.read_bytes(4, callback = read_header)
 | 
			
		||||
 | 
			
		||||
@tornado.gen.coroutine
 | 
			
		||||
def trap_setup(host, port, target_host, target_port, tk):
 | 
			
		||||
	global stream
 | 
			
		||||
	global url
 | 
			
		||||
	global token
 | 
			
		||||
	token = tk
 | 
			
		||||
	url = "http://%s:%s/sse" % (host, port)
 | 
			
		||||
	stream = yield tornado.tcpclient.TCPClient().connect(target_host, target_port)
 | 
			
		||||
	stream.read_bytes(4, callback = read_header)
 | 
			
		||||
 | 
			
		||||
def get_v(s, v):
 | 
			
		||||
	return { 'variable' : v, 'value' : bsc_control.get_var(s, tornado.escape.native_str(v)) }
 | 
			
		||||
 | 
			
		||||
class CtrlHandler(tornado.web.RequestHandler):
 | 
			
		||||
	def initialize(self):
 | 
			
		||||
		self.skt = bsc_control.connect(self.settings['ctrl_host'], self.settings['ctrl_port'])
 | 
			
		||||
 | 
			
		||||
	def get(self, v):
 | 
			
		||||
		self.write(get_v(self.skt, v))
 | 
			
		||||
 | 
			
		||||
	def post(self):
 | 
			
		||||
		self.write(get_v(self.skt, self.get_argument("variable")))
 | 
			
		||||
 | 
			
		||||
class SetCtrl(CtrlHandler):
 | 
			
		||||
	def get(self, var, val):
 | 
			
		||||
		bsc_control.set_var(self.skt, tornado.escape.native_str(var), tornado.escape.native_str(val))
 | 
			
		||||
		super(SetCtrl, self).get(tornado.escape.native_str(var))
 | 
			
		||||
 | 
			
		||||
	def post(self):
 | 
			
		||||
		bsc_control.set_var(self.skt, tornado.escape.native_str(self.get_argument("variable")), tornado.escape.native_str(self.get_argument("value")))
 | 
			
		||||
		super(SetCtrl, self).post()
 | 
			
		||||
 | 
			
		||||
class Slash(tornado.web.RequestHandler):
 | 
			
		||||
	def get(self):
 | 
			
		||||
		self.write('<html><head><title>%s</title></head><body>Using Tornado framework v%s'
 | 
			
		||||
				'<form action="/get" method="POST">'
 | 
			
		||||
					'<input type="text" name="variable">'
 | 
			
		||||
					'<input type="submit" value="GET">'
 | 
			
		||||
				'</form>'
 | 
			
		||||
				'<form action="/set" method="POST">'
 | 
			
		||||
					'<input type="text" name="variable">'
 | 
			
		||||
					'<input type="text" name="value">'
 | 
			
		||||
					'<input type="submit" value="SET">'
 | 
			
		||||
				'</form>'
 | 
			
		||||
				'</body></html>' % ("Osmocom Control Interface Proxy", tornado.version))
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
	p = argparse.ArgumentParser(description='Osmocom Control Interface proxy.')
 | 
			
		||||
	p.add_argument('-c', '--control-port', type = int, default = 4252, help = "Target Control Interface port")
 | 
			
		||||
	p.add_argument('-a', '--control-host', default = 'localhost', help = "Target Control Interface adress")
 | 
			
		||||
	p.add_argument('-b', '--host', default = 'localhost', help = "Adress to bind proxy's web interface")
 | 
			
		||||
	p.add_argument('-p', '--port', type = int, default = 6969, help = "Port to bind proxy's web interface")
 | 
			
		||||
	p.add_argument('-d', '--debug', action='store_true', help = "Activate debugging (default off)")
 | 
			
		||||
	p.add_argument('-t', '--token', default = 'osmocom', help = "Token to be used by SSE client in URL e. g. http://127.0.0.1:8888/poll/osmocom where 'osmocom' is default token value")
 | 
			
		||||
	p.add_argument('-k', '--keepalive', type = int, default = 5000, help = "Timeout betwwen keepalive messages, in milliseconds, defaults to 5000")
 | 
			
		||||
	args = p.parse_args()
 | 
			
		||||
	random.seed()
 | 
			
		||||
	tornado.netutil.Resolver.configure('tornado.netutil.ThreadedResolver') # Use non-blocking resolver
 | 
			
		||||
	logging.basicConfig()
 | 
			
		||||
	application = tornado.web.Application([
 | 
			
		||||
		(r"/", Slash),
 | 
			
		||||
		(r"/get", CtrlHandler),
 | 
			
		||||
		(r"/get/(.*)", CtrlHandler),
 | 
			
		||||
		(r"/set", SetCtrl),
 | 
			
		||||
		(r"/set/(.*)/(.*)", SetCtrl),
 | 
			
		||||
		(r"/sse/(.*)/(.*)", listener.EventSourceHandler, dict(event_class = listener.JSONIdEvent, keepalive = args.keepalive)),
 | 
			
		||||
	], debug = args.debug, ctrl_host = args.control_host, ctrl_port = args.control_port)
 | 
			
		||||
	application.listen(address = args.host, port = args.port)
 | 
			
		||||
	trap_setup(args.host, args.port, application.settings['ctrl_host'], application.settings['ctrl_port'], args.token)
 | 
			
		||||
	tornado.ioloop.IOLoop.instance().start()
 | 
			
		||||
@@ -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,80 +0,0 @@
 | 
			
		||||
-- I count the buffer space needed for LLC PDUs in the worse case and print it
 | 
			
		||||
 | 
			
		||||
do
 | 
			
		||||
	local function init_listener()
 | 
			
		||||
		-- handle the port as NS over IP
 | 
			
		||||
		local udp_port_table = DissectorTable.get("udp.port")
 | 
			
		||||
		local gprs_ns_dis = Dissector.get("gprs_ns")
 | 
			
		||||
		udp_port_table:add(23000,gprs_ns_dis)
 | 
			
		||||
 | 
			
		||||
		-- bssgp filters
 | 
			
		||||
		local bssgp_pdu_get = Field.new("bssgp.pdu_type")
 | 
			
		||||
		local bssgp_delay_get = Field.new("bssgp.delay_val")
 | 
			
		||||
		local llcgprs_get = Field.new("llcgprs")
 | 
			
		||||
		local pdus = nil
 | 
			
		||||
 | 
			
		||||
		print("START...")
 | 
			
		||||
 | 
			
		||||
		local tap = Listener.new("ip", "udp.port == 23000 && bssgp.pdu_type == 0")
 | 
			
		||||
		function tap.packet(pinfo,tvb,ip)
 | 
			
		||||
			local pdu = bssgp_pdu_get()
 | 
			
		||||
			local len = llcgprs_get().len
 | 
			
		||||
			local delay = bssgp_delay_get()
 | 
			
		||||
 | 
			
		||||
			-- only handle bssgp, but we also want the IP frame
 | 
			
		||||
			if not pdu then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			if tonumber(tostring(delay)) == 65535 then
 | 
			
		||||
				pdus = { next = pdus,
 | 
			
		||||
					 len = len,
 | 
			
		||||
					 expires = -1 }
 | 
			
		||||
			else
 | 
			
		||||
				local off = tonumber(tostring(delay)) / 100.0
 | 
			
		||||
				pdus = { next = pdus,
 | 
			
		||||
					 len = len,
 | 
			
		||||
					 expires = pinfo.rel_ts + off }
 | 
			
		||||
			end
 | 
			
		||||
			local now_time = tonumber(tostring(pinfo.rel_ts))
 | 
			
		||||
			local now_size = 0
 | 
			
		||||
			local l = pdus
 | 
			
		||||
			local prev = nil
 | 
			
		||||
			local count = 0
 | 
			
		||||
			while l do
 | 
			
		||||
				if now_time < l.expires or l.expires == -1 then
 | 
			
		||||
					now_size = now_size + l.len
 | 
			
		||||
					prev = l
 | 
			
		||||
					l = l.next
 | 
			
		||||
					count = count + 1
 | 
			
		||||
				else
 | 
			
		||||
					-- delete things
 | 
			
		||||
					if prev == nil then
 | 
			
		||||
						pdus = nil
 | 
			
		||||
						l = nil
 | 
			
		||||
					else
 | 
			
		||||
						prev.next = l.next
 | 
			
		||||
						l = l.next
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
--			print("TOTAL: " .. now_time .. " PDU_SIZE: " .. now_size)
 | 
			
		||||
			print(now_time .. " " .. now_size / 1024.0 .. " " .. count)
 | 
			
		||||
--			print("NOW: " .. tostring(pinfo.rel_ts) .. " Delay: " .. tostring(delay) .. " Length: " .. tostring(len))
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		function tap.draw()
 | 
			
		||||
			-- well... this will not be called...
 | 
			
		||||
--			for ip,bssgp_histo in pairs(dumpers) do
 | 
			
		||||
--				print("IP " .. ip)
 | 
			
		||||
--			end
 | 
			
		||||
			print("END")
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		function tap.reset()
 | 
			
		||||
			-- well... this will not be called...
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	init_listener()
 | 
			
		||||
end
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
-- Remove old data from the database
 | 
			
		||||
DELETE FROM Subscriber
 | 
			
		||||
	WHERE id != 1 AND datetime('now', '-10 days') > updated AND authorized != 1;
 | 
			
		||||
DELETE FROM Equipment
 | 
			
		||||
	WHERE datetime('now', '-10 days') > updated;
 | 
			
		||||
DELETE FROM EquipmentWatch
 | 
			
		||||
	WHERE datetime('now', '-10 days') > updated;
 | 
			
		||||
DELETE FROM SMS
 | 
			
		||||
	WHERE datetime('now', '-10 days') > created;
 | 
			
		||||
DELETE FROM VLR
 | 
			
		||||
	WHERE datetime('now', '-10 days') > updated;
 | 
			
		||||
DELETE FROM ApduBlobs
 | 
			
		||||
	WHERE datetime('now', '-10 days') > created;
 | 
			
		||||
DELETE FROM Counters
 | 
			
		||||
	WHERE datetime('now', '-10 days') > timestamp;
 | 
			
		||||
DELETE FROM RateCounters
 | 
			
		||||
	WHERE datetime('now', '-10 days') > timestamp;
 | 
			
		||||
VACUUM;
 | 
			
		||||
@@ -1,278 +0,0 @@
 | 
			
		||||
#!/usr/bin/python3
 | 
			
		||||
# -*- mode: python-mode; py-indent-tabs-mode: nil -*-
 | 
			
		||||
"""
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import struct, random, sys
 | 
			
		||||
 | 
			
		||||
class IPA(object):
 | 
			
		||||
    """
 | 
			
		||||
    Stateless IPA protocol multiplexer: add/remove/parse (extended) header
 | 
			
		||||
    """
 | 
			
		||||
    version = "0.0.5"
 | 
			
		||||
    TCP_PORT_OML = 3002
 | 
			
		||||
    TCP_PORT_RSL = 3003
 | 
			
		||||
    # OpenBSC extensions: OSMO, MGCP_OLD
 | 
			
		||||
    PROTO = dict(RSL=0x00, CCM=0xFE, SCCP=0xFD, OML=0xFF, OSMO=0xEE, MGCP_OLD=0xFC)
 | 
			
		||||
    # ...OML Router Control, GSUP GPRS extension, Osmocom Authn Protocol
 | 
			
		||||
    EXT = dict(CTRL=0, MGCP=1, LAC=2, SMSC=3, ORC=4, GSUP=5, OAP=6)
 | 
			
		||||
    # OpenBSC extension: SCCP_OLD
 | 
			
		||||
    MSGT = dict(PING=0x00, PONG=0x01, ID_GET=0x04, ID_RESP=0x05, ID_ACK=0x06, SCCP_OLD=0xFF)
 | 
			
		||||
    _IDTAG = dict(SERNR=0, UNITNAME=1, LOCATION=2, TYPE=3, EQUIPVERS=4, SWVERSION=5, IPADDR=6, MACADDR=7, UNIT=8)
 | 
			
		||||
    CTRL_GET = 'GET'
 | 
			
		||||
    CTRL_SET = 'SET'
 | 
			
		||||
    CTRL_REP = 'REPLY'
 | 
			
		||||
    CTRL_ERR = 'ERR'
 | 
			
		||||
    CTRL_TRAP = 'TRAP'
 | 
			
		||||
 | 
			
		||||
    def _l(self, d, p):
 | 
			
		||||
        """
 | 
			
		||||
        Reverse dictionary lookup: return key for a given value
 | 
			
		||||
        """
 | 
			
		||||
        if p is None:
 | 
			
		||||
            return 'UNKNOWN'
 | 
			
		||||
        return list(d.keys())[list(d.values()).index(p)]
 | 
			
		||||
 | 
			
		||||
    def _tag(self, t, v):
 | 
			
		||||
        """
 | 
			
		||||
        Create TAG as TLV data
 | 
			
		||||
        """
 | 
			
		||||
        return struct.pack(">HB", len(v) + 1, t) + v
 | 
			
		||||
 | 
			
		||||
    def proto(self, p):
 | 
			
		||||
        """
 | 
			
		||||
        Lookup protocol name
 | 
			
		||||
        """
 | 
			
		||||
        return self._l(self.PROTO, p)
 | 
			
		||||
 | 
			
		||||
    def ext(self, p):
 | 
			
		||||
        """
 | 
			
		||||
        Lookup protocol extension name
 | 
			
		||||
        """
 | 
			
		||||
        return self._l(self.EXT, p)
 | 
			
		||||
 | 
			
		||||
    def msgt(self, p):
 | 
			
		||||
        """
 | 
			
		||||
        Lookup message type name
 | 
			
		||||
        """
 | 
			
		||||
        return self._l(self.MSGT, p)
 | 
			
		||||
 | 
			
		||||
    def idtag(self, p):
 | 
			
		||||
        """
 | 
			
		||||
        Lookup ID tag name
 | 
			
		||||
        """
 | 
			
		||||
        return self._l(self._IDTAG, p)
 | 
			
		||||
 | 
			
		||||
    def ext_name(self, proto, exten):
 | 
			
		||||
        """
 | 
			
		||||
        Return proper extension byte name depending on the protocol used
 | 
			
		||||
        """
 | 
			
		||||
        if self.PROTO['CCM'] == proto:
 | 
			
		||||
            return self.msgt(exten)
 | 
			
		||||
        if self.PROTO['OSMO'] == proto:
 | 
			
		||||
            return self.ext(exten)
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def add_header(self, data, proto, ext=None):
 | 
			
		||||
        """
 | 
			
		||||
        Add IPA header (with extension if necessary), data must be represented as bytes
 | 
			
		||||
        """
 | 
			
		||||
        if ext is None:
 | 
			
		||||
            return struct.pack(">HB", len(data) + 1, proto) + data
 | 
			
		||||
        return struct.pack(">HBB", len(data) + 1, proto, ext) + data
 | 
			
		||||
 | 
			
		||||
    def del_header(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Strip IPA protocol header correctly removing extension if present
 | 
			
		||||
        Returns data length, IPA protocol, extension (or None if not defined for a give protocol) and the data without header
 | 
			
		||||
        """
 | 
			
		||||
        if not len(data):
 | 
			
		||||
            return None, None, None, None
 | 
			
		||||
        (dlen, proto) = struct.unpack('>HB', data[:3])
 | 
			
		||||
        if self.PROTO['OSMO'] == proto or self.PROTO['CCM'] == proto: # there's extension which we have to unpack
 | 
			
		||||
            return struct.unpack('>HBB', data[:4]) + (data[4:], ) # length, protocol, extension, data
 | 
			
		||||
        return dlen, proto, None, data[3:] # length, protocol, _, data
 | 
			
		||||
 | 
			
		||||
    def split_combined(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Split the data which contains multiple concatenated IPA messages into tuple (first, rest) where rest contains remaining messages, first is the single IPA message
 | 
			
		||||
        """
 | 
			
		||||
        (length, _, _, _) = self.del_header(data)
 | 
			
		||||
        return data[:(length + 3)], data[(length + 3):]
 | 
			
		||||
 | 
			
		||||
    def tag_serial(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make TAG for serial number
 | 
			
		||||
        """
 | 
			
		||||
        return self._tag(self._IDTAG['SERNR'], data)
 | 
			
		||||
 | 
			
		||||
    def tag_name(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make TAG for unit name
 | 
			
		||||
        """
 | 
			
		||||
        return self._tag(self._IDTAG['UNITNAME'], data)
 | 
			
		||||
 | 
			
		||||
    def tag_loc(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make TAG for location
 | 
			
		||||
        """
 | 
			
		||||
        return self._tag(self._IDTAG['LOCATION'], data)
 | 
			
		||||
 | 
			
		||||
    def tag_type(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make TAG for unit type
 | 
			
		||||
        """
 | 
			
		||||
        return self._tag(self._IDTAG['TYPE'], data)
 | 
			
		||||
 | 
			
		||||
    def tag_equip(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make TAG for equipment version
 | 
			
		||||
        """
 | 
			
		||||
        return self._tag(self._IDTAG['EQUIPVERS'], data)
 | 
			
		||||
 | 
			
		||||
    def tag_sw(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make TAG for software version
 | 
			
		||||
        """
 | 
			
		||||
        return self._tag(self._IDTAG['SWVERSION'], data)
 | 
			
		||||
 | 
			
		||||
    def tag_ip(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make TAG for IP address
 | 
			
		||||
        """
 | 
			
		||||
        return self._tag(self._IDTAG['IPADDR'], data)
 | 
			
		||||
 | 
			
		||||
    def tag_mac(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make TAG for MAC address
 | 
			
		||||
        """
 | 
			
		||||
        return self._tag(self._IDTAG['MACADDR'], data)
 | 
			
		||||
 | 
			
		||||
    def tag_unit(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make TAG for unit ID
 | 
			
		||||
        """
 | 
			
		||||
        return self._tag(self._IDTAG['UNIT'], data)
 | 
			
		||||
 | 
			
		||||
    def identity(self, unit=b'', mac=b'', location=b'', utype=b'', equip=b'', sw=b'', name=b'', serial=b''):
 | 
			
		||||
        """
 | 
			
		||||
        Make IPA IDENTITY tag list, by default returns empty concatenated bytes of tag list
 | 
			
		||||
        """
 | 
			
		||||
        return self.tag_unit(unit) + self.tag_mac(mac) + self.tag_loc(location) + self.tag_type(utype) + self.tag_equip(equip) + self.tag_sw(sw) + self.tag_name(name) + self.tag_serial(serial)
 | 
			
		||||
 | 
			
		||||
    def ping(self):
 | 
			
		||||
        """
 | 
			
		||||
        Make PING message
 | 
			
		||||
        """
 | 
			
		||||
        return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PING'])
 | 
			
		||||
 | 
			
		||||
    def pong(self):
 | 
			
		||||
        """
 | 
			
		||||
        Make PONG message
 | 
			
		||||
        """
 | 
			
		||||
        return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PONG'])
 | 
			
		||||
 | 
			
		||||
    def id_ack(self):
 | 
			
		||||
        """
 | 
			
		||||
        Make ID_ACK CCM message
 | 
			
		||||
        """
 | 
			
		||||
        return self.add_header(b'', self.PROTO['CCM'], self.MSGT['ID_ACK'])
 | 
			
		||||
 | 
			
		||||
    def id_get(self):
 | 
			
		||||
        """
 | 
			
		||||
        Make ID_GET CCM message
 | 
			
		||||
        """
 | 
			
		||||
        return self.add_header(self.identity(), self.PROTO['CCM'], self.MSGT['ID_GET'])
 | 
			
		||||
 | 
			
		||||
    def id_resp(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Make ID_RESP CCM message
 | 
			
		||||
        """
 | 
			
		||||
        return self.add_header(data, self.PROTO['CCM'], self.MSGT['ID_RESP'])
 | 
			
		||||
 | 
			
		||||
class Ctrl(IPA):
 | 
			
		||||
    """
 | 
			
		||||
    Osmocom CTRL protocol implemented on top of IPA multiplexer
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        random.seed()
 | 
			
		||||
 | 
			
		||||
    def add_header(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Add CTRL header
 | 
			
		||||
        """
 | 
			
		||||
        return super(Ctrl, self).add_header(data.encode('utf-8'), IPA.PROTO['OSMO'], IPA.EXT['CTRL'])
 | 
			
		||||
 | 
			
		||||
    def rem_header(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Remove CTRL header, check for appropriate protocol and extension
 | 
			
		||||
        """
 | 
			
		||||
        (_, proto, ext, d) = super(Ctrl, self).del_header(data)
 | 
			
		||||
        if self.PROTO['OSMO'] != proto or self.EXT['CTRL'] != ext:
 | 
			
		||||
            return None
 | 
			
		||||
        return d
 | 
			
		||||
 | 
			
		||||
    def parse(self, data, op=None):
 | 
			
		||||
        """
 | 
			
		||||
        Parse Ctrl string returning (var, value) pair
 | 
			
		||||
        var could be None in case of ERROR message
 | 
			
		||||
        value could be None in case of GET message
 | 
			
		||||
        """
 | 
			
		||||
        (s, i, v) = data.split(' ', 2)
 | 
			
		||||
        if s == self.CTRL_ERR:
 | 
			
		||||
            return None, v
 | 
			
		||||
        if s == self.CTRL_GET:
 | 
			
		||||
            return v, None
 | 
			
		||||
        (s, i, var, val) = data.split(' ', 3)
 | 
			
		||||
        if s == self.CTRL_TRAP and i != '0':
 | 
			
		||||
            return None, '%s with non-zero id %s' % (s, i)
 | 
			
		||||
        if op is not None and i != op:
 | 
			
		||||
            if s == self.CTRL_GET + '_' + self.CTRL_REP or s == self.CTRL_SET + '_' + self.CTRL_REP:
 | 
			
		||||
                return None, '%s with unexpected id %s' % (s, i)
 | 
			
		||||
        return var, val
 | 
			
		||||
 | 
			
		||||
    def trap(self, var, val):
 | 
			
		||||
        """
 | 
			
		||||
        Make TRAP message with given (vak, val) pair
 | 
			
		||||
        """
 | 
			
		||||
        return self.add_header("%s 0 %s %s" % (self.CTRL_TRAP, var, val))
 | 
			
		||||
 | 
			
		||||
    def cmd(self, var, val=None):
 | 
			
		||||
        """
 | 
			
		||||
        Make SET/GET command message: returns (r, m) tuple where r is random operation id and m is assembled message
 | 
			
		||||
        """
 | 
			
		||||
        r = random.randint(1, sys.maxsize)
 | 
			
		||||
        if val is not None:
 | 
			
		||||
            return r, self.add_header("%s %s %s %s" % (self.CTRL_SET, r, var, val))
 | 
			
		||||
        return r, self.add_header("%s %s %s" % (self.CTRL_GET, r, var))
 | 
			
		||||
 | 
			
		||||
    def verify(self, reply, r, var, val=None):
 | 
			
		||||
        """
 | 
			
		||||
        Verify reply to SET/GET command: returns (b, v) tuple where v is True/False verification result and v is the variable value
 | 
			
		||||
        """
 | 
			
		||||
        (k, v) = self.parse(reply)
 | 
			
		||||
        if k != var or (val is not None and v != val):
 | 
			
		||||
            return False, v
 | 
			
		||||
        return True, v
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    print("IPA multiplexer v%s loaded." % IPA.version)
 | 
			
		||||
@@ -10,7 +10,7 @@ rsip_resp = """200 321321332\r\n"""
 | 
			
		||||
audit_packet = """AUEP %d 13@mgw MGCP 1.0\r\n"""
 | 
			
		||||
crcx_packet = """CRCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n"""
 | 
			
		||||
dlcx_packet = """DLCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\n"""
 | 
			
		||||
mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 6666 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
 | 
			
		||||
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):
 | 
			
		||||
    """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.bind(("127.0.0.1", MGCP_CALLAGENT_PORT))
 | 
			
		||||
server_socket.setblocking(1)
 | 
			
		||||
server_socket.setblocking(0)
 | 
			
		||||
 | 
			
		||||
last_ci = 1
 | 
			
		||||
def send_and_receive(packet):
 | 
			
		||||
    global last_ci
 | 
			
		||||
 | 
			
		||||
def send_receive(packet):
 | 
			
		||||
    server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT))
 | 
			
		||||
    try:
 | 
			
		||||
        data, addr = server_socket.recvfrom(4096)
 | 
			
		||||
 | 
			
		||||
        # attempt to store the CI of the response
 | 
			
		||||
        list = data.split("\n")
 | 
			
		||||
        for item in list:
 | 
			
		||||
           if item.startswith("I: "):
 | 
			
		||||
               last_ci = int(item[3:])
 | 
			
		||||
 | 
			
		||||
        print hexdump(data), addr
 | 
			
		||||
    except socket.error, e:
 | 
			
		||||
        print e
 | 
			
		||||
    except socket.error:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
def generate_tid():
 | 
			
		||||
@@ -51,10 +42,13 @@ def generate_tid():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
i = 1
 | 
			
		||||
while True:
 | 
			
		||||
    send_and_receive(audit_packet % generate_tid())
 | 
			
		||||
    send_and_receive(crcx_packet % generate_tid() )
 | 
			
		||||
    send_and_receive(mdcx_packet % (generate_tid(), last_ci))
 | 
			
		||||
    send_and_receive(dlcx_packet % (generate_tid(), last_ci))
 | 
			
		||||
    send_receive(rsip_resp)
 | 
			
		||||
    send_receive(audit_packet)
 | 
			
		||||
    send_receive(crcx_packet % generate_tid() )
 | 
			
		||||
    send_receive(mdcx_packet % (generate_tid(), i))
 | 
			
		||||
    send_receive(dlcx_packet % (generate_tid(), i))
 | 
			
		||||
    i = i + 1
 | 
			
		||||
 | 
			
		||||
    time.sleep(3)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
/* make test_regexp */
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <regex.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	regex_t reg;
 | 
			
		||||
	regmatch_t matches[2];
 | 
			
		||||
 | 
			
		||||
	if (argc != 4) {
 | 
			
		||||
		printf("Invoke with: test_regexp REGEXP REPLACE NR\n");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (regcomp(®, argv[1], REG_EXTENDED) != 0) {
 | 
			
		||||
		fprintf(stderr, "Regexp '%s' is not valid.\n", argv[1]);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (regexec(®, argv[3], 2, matches, 0) == 0 && matches[1].rm_eo != -1)
 | 
			
		||||
		printf("New Number: %s%s\n", argv[2], &argv[3][matches[1].rm_so]);
 | 
			
		||||
	else
 | 
			
		||||
		printf("No match.\n");
 | 
			
		||||
 | 
			
		||||
	regfree(®);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,65 +0,0 @@
 | 
			
		||||
#!/usr/bin/env python2.7
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
AGPLv3+ 2016 Copyright Holger Hans Peter Freyther
 | 
			
		||||
 | 
			
		||||
Example of how to connect to the USSD side-channel and how to respond
 | 
			
		||||
with a fixed message.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import socket
 | 
			
		||||
import struct
 | 
			
		||||
 | 
			
		||||
ussdSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 | 
			
		||||
ussdSocket.connect(('127.0.0.1', 5001))
 | 
			
		||||
 | 
			
		||||
def send_dt1(dstref, data):
 | 
			
		||||
    dlen = struct.pack('B', len(data)).encode('hex')
 | 
			
		||||
    hex = '06' + dstref.encode('hex') + '00' + '01' + dlen + data.encode('hex')
 | 
			
		||||
    pdata = hex.decode('hex')
 | 
			
		||||
    out = struct.pack('>HB', len(pdata), 0xfd) + pdata
 | 
			
		||||
    ussdSocket.send(out)
 | 
			
		||||
 | 
			
		||||
def send_rel(srcref, dstref):
 | 
			
		||||
    hex = '04' + dstref.encode('hex') + srcref.encode('hex') + '000100'
 | 
			
		||||
    pdata = hex.decode('hex')
 | 
			
		||||
    out = struct.pack('>HB', len(pdata), 0xfd) + pdata
 | 
			
		||||
    ussdSocket.send(out)
 | 
			
		||||
 | 
			
		||||
def recv_one():
 | 
			
		||||
    plen = ussdSocket.recv(3)
 | 
			
		||||
    (plen,ptype) = struct.unpack(">HB", plen)
 | 
			
		||||
    data = ussdSocket.recv(plen)
 | 
			
		||||
 | 
			
		||||
    return ptype, data
 | 
			
		||||
 | 
			
		||||
# Assume this is the ID request
 | 
			
		||||
data = ussdSocket.recv(4)
 | 
			
		||||
ussdSocket.send("\x00\x08\xfe\x05\x00" + "\x05\x01" + "ussd")
 | 
			
		||||
#                      ^len                ^len of tag ... and ignore
 | 
			
		||||
 | 
			
		||||
# Expect a fake message. see struct ipac_msgt_sccp_state
 | 
			
		||||
ptype, data = recv_one()
 | 
			
		||||
print("%d %s" % (ptype, data.encode('hex')))
 | 
			
		||||
(srcref, dstref, transid, invokeid) = struct.unpack("<3s3sBB", data[1:9])
 | 
			
		||||
print("New transID %d invoke %d" % (transid, invokeid))
 | 
			
		||||
 | 
			
		||||
# Expect a the invocation.. todo.. extract invoke id
 | 
			
		||||
ptype, data = recv_one()
 | 
			
		||||
print("%d %s" % (ptype, data.encode('hex')))
 | 
			
		||||
 | 
			
		||||
# Reply with BSSAP + GSM 04.08 + MAP portion
 | 
			
		||||
#                                    00 == invoke id     0f == DCS
 | 
			
		||||
res = "01002a9b2a0802e1901c22a220020100301b02013b301604010f041155e7d2f9bc3a41412894991c06a9c9a713"
 | 
			
		||||
send_dt1(dstref, res.decode('hex'))
 | 
			
		||||
 | 
			
		||||
clear = "000420040109"
 | 
			
		||||
send_dt1(dstref, clear.decode('hex'))
 | 
			
		||||
 | 
			
		||||
# should be the clear complete
 | 
			
		||||
send_rel(srcref, dstref)
 | 
			
		||||
 | 
			
		||||
# Give it some time to handle connection shutdown properly
 | 
			
		||||
print("Gracefully sleeping")
 | 
			
		||||
import time
 | 
			
		||||
time.sleep(3)
 | 
			
		||||
@@ -1,420 +0,0 @@
 | 
			
		||||
#!/usr/bin/env escript
 | 
			
		||||
%% -*- erlang -*-
 | 
			
		||||
%%! -smp disable
 | 
			
		||||
-module(gen_rtp_header).
 | 
			
		||||
 | 
			
		||||
% -mode(compile).
 | 
			
		||||
 | 
			
		||||
-define(VERSION, "0.1").
 | 
			
		||||
 | 
			
		||||
-export([main/1]).
 | 
			
		||||
 | 
			
		||||
-record(rtp_packet,
 | 
			
		||||
        {
 | 
			
		||||
          version = 2,
 | 
			
		||||
          padding = 0,
 | 
			
		||||
          marker = 0,
 | 
			
		||||
          payload_type = 0,
 | 
			
		||||
          seqno = 0,
 | 
			
		||||
          timestamp = 0,
 | 
			
		||||
          ssrc = 0,
 | 
			
		||||
          csrcs = [],
 | 
			
		||||
          extension = <<>>,
 | 
			
		||||
          payload = <<>>,
 | 
			
		||||
	  realtime
 | 
			
		||||
        }).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
main(Args) ->
 | 
			
		||||
    DefaultOpts = [{format, state},
 | 
			
		||||
                   {ssrc, 16#11223344},
 | 
			
		||||
                   {rate, 8000},
 | 
			
		||||
                   {pt, 98}],
 | 
			
		||||
    {PosArgs, Opts} = getopts_checked(Args, DefaultOpts),
 | 
			
		||||
    log(debug, fun (Dev) ->
 | 
			
		||||
            io:format(Dev, "Initial options:~n", []),
 | 
			
		||||
	    dump_opts(Dev, Opts),
 | 
			
		||||
	    io:format(Dev, "~s: ~p~n", ["Args", PosArgs])
 | 
			
		||||
        end, [], Opts),
 | 
			
		||||
    main(PosArgs, Opts).
 | 
			
		||||
 | 
			
		||||
main([First | RemArgs], Opts) ->
 | 
			
		||||
    try
 | 
			
		||||
        F = list_to_integer(First),
 | 
			
		||||
	Format = proplists:get_value(format, Opts, state),
 | 
			
		||||
	PayloadData = proplists:get_value(payload, Opts, undef),
 | 
			
		||||
	InFile = proplists:get_value(file, Opts, undef),
 | 
			
		||||
 | 
			
		||||
        Payload = case {PayloadData, InFile} of
 | 
			
		||||
	    {undef, undef} ->
 | 
			
		||||
		% use default value
 | 
			
		||||
		#rtp_packet{}#rtp_packet.payload;
 | 
			
		||||
	    {P, undef} -> P;
 | 
			
		||||
	    {_, File} ->
 | 
			
		||||
		log(info, "Loading file '~s'~n", [File], Opts),
 | 
			
		||||
		{ok, InDev} = file:open(File, [read]),
 | 
			
		||||
		DS = [ Pl#rtp_packet.payload || {_T, Pl} <- read_packets(InDev, Opts)],
 | 
			
		||||
		file:close(InDev),
 | 
			
		||||
		log(debug, "File '~s' closed, ~w packets read.~n", [File, length(DS)], Opts),
 | 
			
		||||
		DS
 | 
			
		||||
	end,
 | 
			
		||||
        Dev = standard_io,
 | 
			
		||||
	write_packet_pre(Dev, Format),
 | 
			
		||||
        do_groups(Dev, Payload, F, RemArgs, Opts),
 | 
			
		||||
	write_packet_post(Dev, Format),
 | 
			
		||||
	0
 | 
			
		||||
    catch
 | 
			
		||||
        _:_ ->
 | 
			
		||||
            log(debug, "~p~n", [hd(erlang:get_stacktrace())], Opts),
 | 
			
		||||
            usage(),
 | 
			
		||||
            halt(1)
 | 
			
		||||
    end
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
main(_, _Opts) ->
 | 
			
		||||
    usage(),
 | 
			
		||||
    halt(1).
 | 
			
		||||
 | 
			
		||||
%%% group (count + offset) handling %%%
 | 
			
		||||
 | 
			
		||||
do_groups(_Dev, _Pl, _F, [], _Opts) ->
 | 
			
		||||
    ok;
 | 
			
		||||
 | 
			
		||||
do_groups(Dev, Pl, F, [L], Opts) ->
 | 
			
		||||
    do_groups(Dev, Pl, F, [L, 0], Opts);
 | 
			
		||||
 | 
			
		||||
do_groups(Dev, Pl, First, [L, O | Args], Opts) ->
 | 
			
		||||
    Ssrc = proplists:get_value(ssrc, Opts, #rtp_packet.ssrc),
 | 
			
		||||
    PT   = proplists:get_value(pt, Opts, #rtp_packet.payload_type),
 | 
			
		||||
    Len  = list_to_num(L),
 | 
			
		||||
    Offs = list_to_num(O),
 | 
			
		||||
    log(info, "Starting group: Ssrc=~.16B, PT=~B, First=~B, Len=~B, Offs=~B~n",
 | 
			
		||||
        [Ssrc, PT, First, Len, Offs], Opts),
 | 
			
		||||
    Pkg = #rtp_packet{ssrc = Ssrc, payload_type = PT},
 | 
			
		||||
    Pl2 = write_packets(Dev, Pl, Pkg, First, Len, Offs, Opts),
 | 
			
		||||
    {Args2, Opts2} = getopts_checked(Args, Opts),
 | 
			
		||||
    log(debug, fun (Io) ->
 | 
			
		||||
            io:format(Io, "Changed options:~n", []),
 | 
			
		||||
	    dump_opts(Io, Opts2 -- Opts)
 | 
			
		||||
        end, [], Opts),
 | 
			
		||||
    do_groups(Dev, Pl2, First+Len, Args2, Opts2).
 | 
			
		||||
 | 
			
		||||
%%% error handling helpers %%%
 | 
			
		||||
 | 
			
		||||
getopts_checked(Args, Opts) ->
 | 
			
		||||
    try
 | 
			
		||||
        getopts(Args, Opts)
 | 
			
		||||
    catch
 | 
			
		||||
        C:R ->
 | 
			
		||||
            log(error, "~s~n",
 | 
			
		||||
                [explain_error(C, R, erlang:get_stacktrace(), Opts)], Opts),
 | 
			
		||||
            usage(),
 | 
			
		||||
            halt(1)
 | 
			
		||||
    end.
 | 
			
		||||
 | 
			
		||||
explain_error(error, badarg, [{erlang,list_to_integer,[S,B]} | _ ], _Opts) ->
 | 
			
		||||
    io_lib:format("Invalid number '~s' (base ~B)", [S, B]);
 | 
			
		||||
explain_error(error, badarg, [{erlang,list_to_integer,[S]} | _ ], _Opts) ->
 | 
			
		||||
    io_lib:format("Invalid decimal number '~s'", [S]);
 | 
			
		||||
explain_error(C, R, [Hd | _ ], _Opts) ->
 | 
			
		||||
    io_lib:format("~p, ~p:~p", [Hd, C, R]);
 | 
			
		||||
explain_error(_, _, [], _Opts) ->
 | 
			
		||||
    "".
 | 
			
		||||
 | 
			
		||||
%%% usage and options %%%
 | 
			
		||||
 | 
			
		||||
myname() ->
 | 
			
		||||
    filename:basename(escript:script_name()).
 | 
			
		||||
 | 
			
		||||
usage(Text) ->
 | 
			
		||||
    io:format(standard_error, "~s: ~s~n", [myname(), Text]),
 | 
			
		||||
    usage().
 | 
			
		||||
 | 
			
		||||
usage() ->
 | 
			
		||||
    io:format(standard_error,
 | 
			
		||||
              "Usage: ~s [Options] Start Count1 Offs1 [[Options] Count2 Offs2 ...]~n",
 | 
			
		||||
              [myname()]).
 | 
			
		||||
 | 
			
		||||
show_version() ->
 | 
			
		||||
    io:format(standard_io,
 | 
			
		||||
              "~s ~s~n", [myname(), ?VERSION]).
 | 
			
		||||
 | 
			
		||||
show_help() ->
 | 
			
		||||
    io:format(standard_io,
 | 
			
		||||
              "Usage: ~s [Options] Start Count1 Offs1 [[Options] Count2 Offs2 ...]~n~n" ++
 | 
			
		||||
              "Options:~n" ++
 | 
			
		||||
	      "  -h, --help             this text~n" ++
 | 
			
		||||
	      "      --version          show version info~n" ++
 | 
			
		||||
	      "  -i, --file=FILE        reads payload from file (state format by default)~n" ++
 | 
			
		||||
	      "  -f, --frame-size=N     read payload as binary frames of size N instead~n" ++
 | 
			
		||||
	      "  -p, --payload=HEX      set constant payload~n" ++
 | 
			
		||||
	      "      --verbose=N        set verbosity~n" ++
 | 
			
		||||
	      "  -v                     increase verbosity~n" ++
 | 
			
		||||
	      "      --format=state     use state format for output (default)~n" ++
 | 
			
		||||
	      "  -C, --format=c         use simple C lines for output~n" ++
 | 
			
		||||
	      "      --format=carray    use a C array for output~n" ++
 | 
			
		||||
	      "  -s, --ssrc=SSRC        set the SSRC~n" ++
 | 
			
		||||
	      "  -t, --type=N           set the payload type~n" ++
 | 
			
		||||
	      "  -r, --rate=N           set the RTP rate [8000]~n" ++
 | 
			
		||||
	      "  -D, --duration=N       set the packet duration in RTP time units [160]~n" ++
 | 
			
		||||
	      "  -d, --delay=FLOAT      add offset to playout timestamp~n" ++
 | 
			
		||||
	      "~n" ++
 | 
			
		||||
	      "Arguments:~n" ++
 | 
			
		||||
	      "  Start              initial packet (sequence) number~n" ++
 | 
			
		||||
	      "  Count              number of packets~n" ++
 | 
			
		||||
	      "  Offs               timestamp offset (in RTP units)~n" ++
 | 
			
		||||
	      "", [myname()]).
 | 
			
		||||
 | 
			
		||||
getopts([ "--file=" ++ File | R], Opts) ->
 | 
			
		||||
        getopts(R, [{file, File} | Opts]);
 | 
			
		||||
getopts([ "-i" ++ T | R], Opts) ->
 | 
			
		||||
        getopts_alias_arg("--file", T, R, Opts);
 | 
			
		||||
getopts([ "--frame-size=" ++ N | R], Opts) ->
 | 
			
		||||
        Size = list_to_integer(N),
 | 
			
		||||
        getopts(R, [{frame_size, Size}, {in_format, bin} | Opts]);
 | 
			
		||||
getopts([ "-f" ++ T | R], Opts) ->
 | 
			
		||||
        getopts_alias_arg("--frame-size", T, R, Opts);
 | 
			
		||||
getopts([ "--duration=" ++ N | R], Opts) ->
 | 
			
		||||
        Duration = list_to_integer(N),
 | 
			
		||||
        getopts(R, [{duration, Duration} | Opts]);
 | 
			
		||||
getopts([ "-D" ++ T | R], Opts) ->
 | 
			
		||||
        getopts_alias_arg("--duration", T, R, Opts);
 | 
			
		||||
getopts([ "--rate=" ++ N | R], Opts) ->
 | 
			
		||||
        Rate = list_to_integer(N),
 | 
			
		||||
        getopts(R, [{rate, Rate} | Opts]);
 | 
			
		||||
getopts([ "-r" ++ T | R], Opts) ->
 | 
			
		||||
        getopts_alias_arg("--rate", T, R, Opts);
 | 
			
		||||
getopts([ "--version" | _], _Opts) ->
 | 
			
		||||
	show_version(),
 | 
			
		||||
        halt(0);
 | 
			
		||||
getopts([ "--help" | _], _Opts) ->
 | 
			
		||||
	show_help(),
 | 
			
		||||
        halt(0);
 | 
			
		||||
getopts([ "-h" ++ T | R], Opts) ->
 | 
			
		||||
        getopts_alias_no_arg("--help", T, R, Opts);
 | 
			
		||||
getopts([ "--verbose=" ++ V | R], Opts) ->
 | 
			
		||||
        Verbose = list_to_integer(V),
 | 
			
		||||
        getopts(R, [{verbose, Verbose} | Opts]);
 | 
			
		||||
getopts([ "-v" ++ T | R], Opts) ->
 | 
			
		||||
        Verbose = proplists:get_value(verbose, Opts, 0),
 | 
			
		||||
        getopts_short_no_arg(T, R, [ {verbose, Verbose+1} | Opts]);
 | 
			
		||||
getopts([ "--format=state" | R], Opts) ->
 | 
			
		||||
        getopts(R, [{format, state} | Opts]);
 | 
			
		||||
getopts([ "--format=c" | R], Opts) ->
 | 
			
		||||
        getopts(R, [{format, c} | Opts]);
 | 
			
		||||
getopts([ "-C" ++ T | R], Opts) ->
 | 
			
		||||
        getopts_alias_no_arg("--format=c", T, R, Opts);
 | 
			
		||||
getopts([ "--format=carray" | R], Opts) ->
 | 
			
		||||
        getopts(R, [{format, carray} | Opts]);
 | 
			
		||||
getopts([ "--payload=" ++ Hex | R], Opts) ->
 | 
			
		||||
        getopts(R, [{payload, hex_to_bin(Hex)} | Opts]);
 | 
			
		||||
getopts([ "--ssrc=" ++ Num | R], Opts) ->
 | 
			
		||||
        getopts(R, [{ssrc, list_to_num(Num)} | Opts]);
 | 
			
		||||
getopts([ "-s" ++ T | R], Opts) ->
 | 
			
		||||
        getopts_alias_arg("--ssrc", T, R, Opts);
 | 
			
		||||
getopts([ "--type=" ++ Num | R], Opts) ->
 | 
			
		||||
        getopts(R, [{pt, list_to_num(Num)} | Opts]);
 | 
			
		||||
getopts([ "-t" ++ T | R], Opts) ->
 | 
			
		||||
        getopts_alias_arg("--type", T, R, Opts);
 | 
			
		||||
getopts([ "--delay=" ++ Num | R], Opts) ->
 | 
			
		||||
        getopts(R, [{delay, list_to_float(Num)} | Opts]);
 | 
			
		||||
getopts([ "-d" ++ T | R], Opts) ->
 | 
			
		||||
        getopts_alias_arg("--delay", T, R, Opts);
 | 
			
		||||
 | 
			
		||||
% parsing helpers
 | 
			
		||||
getopts([ "--" | R], Opts) ->
 | 
			
		||||
        {R, normalize_opts(Opts)};
 | 
			
		||||
getopts([ O = "--" ++ _ | _], _Opts) ->
 | 
			
		||||
        usage("Invalid option: " ++ O),
 | 
			
		||||
        halt(1);
 | 
			
		||||
getopts([ [ $-, C | _] | _], _Opts) when C < $0; C > $9 ->
 | 
			
		||||
        usage("Invalid option: -" ++ [C]),
 | 
			
		||||
        halt(1);
 | 
			
		||||
 | 
			
		||||
getopts(R, Opts) ->
 | 
			
		||||
        {R, normalize_opts(Opts)}.
 | 
			
		||||
 | 
			
		||||
getopts_short_no_arg([], R, Opts) -> getopts(R, Opts);
 | 
			
		||||
getopts_short_no_arg(T, R, Opts)  -> getopts([ "-" ++ T | R], Opts).
 | 
			
		||||
 | 
			
		||||
getopts_alias_no_arg(A, [], R, Opts) -> getopts([A | R], Opts);
 | 
			
		||||
getopts_alias_no_arg(A, T, R, Opts)  -> getopts([A, "-" ++ T | R], Opts).
 | 
			
		||||
 | 
			
		||||
getopts_alias_arg(A, [], [T | R], Opts) -> getopts([A ++ "=" ++ T | R], Opts);
 | 
			
		||||
getopts_alias_arg(A, T, R, Opts)        -> getopts([A ++ "=" ++ T | R], Opts).
 | 
			
		||||
 | 
			
		||||
normalize_opts(Opts) ->
 | 
			
		||||
       [ proplists:lookup(E, Opts) || E <- proplists:get_keys(Opts) ].
 | 
			
		||||
 | 
			
		||||
%%% conversions %%%
 | 
			
		||||
 | 
			
		||||
bin_to_hex(Bin) -> [hd(integer_to_list(N,16)) || <<N:4>> <= Bin].
 | 
			
		||||
hex_to_bin(Hex) -> << <<(list_to_integer([Nib],16)):4>> || Nib <- Hex>>.
 | 
			
		||||
 | 
			
		||||
list_to_num("-" ++ Str) -> -list_to_num(Str);
 | 
			
		||||
list_to_num("0x" ++ Str) -> list_to_integer(Str, 16);
 | 
			
		||||
list_to_num("0b" ++ Str) -> list_to_integer(Str, 2);
 | 
			
		||||
list_to_num(Str = [ $0 | _ ])  -> list_to_integer(Str, 8);
 | 
			
		||||
list_to_num(Str)         -> list_to_integer(Str, 10).
 | 
			
		||||
 | 
			
		||||
%%% dumping data %%%
 | 
			
		||||
 | 
			
		||||
dump_opts(Dev, Opts) ->
 | 
			
		||||
        dump_opts2(Dev, Opts, proplists:get_keys(Opts)).
 | 
			
		||||
 | 
			
		||||
dump_opts2(Dev, Opts, [OptName | R]) ->
 | 
			
		||||
        io:format(Dev, "  ~-10s: ~p~n",
 | 
			
		||||
                  [OptName, proplists:get_value(OptName, Opts)]),
 | 
			
		||||
        dump_opts2(Dev, Opts, R);
 | 
			
		||||
dump_opts2(_Dev, _Opts, []) -> ok.
 | 
			
		||||
 | 
			
		||||
%%% logging %%%
 | 
			
		||||
 | 
			
		||||
log(L, Fmt, Args, Opts) when is_list(Opts) ->
 | 
			
		||||
    log(L, Fmt, Args, proplists:get_value(verbose, Opts, 0), Opts).
 | 
			
		||||
 | 
			
		||||
log(debug,  Fmt, Args, V, Opts) when V > 2 -> log2("DEBUG", Fmt, Args, Opts);
 | 
			
		||||
log(info,   Fmt, Args, V, Opts) when V > 1 -> log2("INFO", Fmt, Args, Opts);
 | 
			
		||||
log(notice, Fmt, Args, V, Opts) when V > 0 -> log2("NOTICE", Fmt, Args, Opts);
 | 
			
		||||
log(warn,   Fmt, Args, _V, Opts)           -> log2("WARNING", Fmt, Args, Opts);
 | 
			
		||||
log(error,  Fmt, Args, _V, Opts)           -> log2("ERROR", Fmt, Args, Opts);
 | 
			
		||||
 | 
			
		||||
log(Lvl,  Fmt, Args, V, Opts) when V >= Lvl -> log2("", Fmt, Args, Opts);
 | 
			
		||||
 | 
			
		||||
log(_, _, _, _i, _) -> ok.
 | 
			
		||||
 | 
			
		||||
log2(Type, Fmt, Args, _Opts) when is_list(Fmt) ->
 | 
			
		||||
    io:format(standard_error, "~s: " ++ Fmt, [Type | Args]);
 | 
			
		||||
log2("", Fmt, Args, _Opts) when is_list(Fmt) ->
 | 
			
		||||
    io:format(standard_error, Fmt, Args);
 | 
			
		||||
log2(_Type, Fun, _Args, _Opts) when is_function(Fun, 1) ->
 | 
			
		||||
    Fun(standard_error).
 | 
			
		||||
 | 
			
		||||
%%% RTP packets %%%
 | 
			
		||||
 | 
			
		||||
make_rtp_packet(P = #rtp_packet{version = 2}) ->
 | 
			
		||||
    << (P#rtp_packet.version):2,
 | 
			
		||||
       0:1, % P
 | 
			
		||||
       0:1, % X
 | 
			
		||||
       0:4, % CC
 | 
			
		||||
       (P#rtp_packet.marker):1,
 | 
			
		||||
       (P#rtp_packet.payload_type):7,
 | 
			
		||||
       (P#rtp_packet.seqno):16,
 | 
			
		||||
       (P#rtp_packet.timestamp):32,
 | 
			
		||||
       (P#rtp_packet.ssrc):32,
 | 
			
		||||
       (P#rtp_packet.payload)/bytes
 | 
			
		||||
    >>.
 | 
			
		||||
 | 
			
		||||
parse_rtp_packet(
 | 
			
		||||
    << 2:2, % Version 2
 | 
			
		||||
       0:1, % P (not supported yet)
 | 
			
		||||
       0:1, % X (not supported yet)
 | 
			
		||||
       0:4, % CC (not supported yet)
 | 
			
		||||
       M:1,
 | 
			
		||||
       PT:7,
 | 
			
		||||
       SeqNo: 16,
 | 
			
		||||
       TS:32,
 | 
			
		||||
       Ssrc:32,
 | 
			
		||||
       Payload/bytes >>) ->
 | 
			
		||||
    #rtp_packet{
 | 
			
		||||
        version = 0,
 | 
			
		||||
	marker = M,
 | 
			
		||||
	payload_type = PT,
 | 
			
		||||
	seqno = SeqNo,
 | 
			
		||||
	timestamp = TS,
 | 
			
		||||
	ssrc = Ssrc,
 | 
			
		||||
	payload = Payload}.
 | 
			
		||||
 | 
			
		||||
%%% payload generation %%%
 | 
			
		||||
 | 
			
		||||
next_payload(F) when is_function(F) ->
 | 
			
		||||
    {F(), F};
 | 
			
		||||
next_payload({F, D}) when is_function(F) ->
 | 
			
		||||
    {P, D2} = F(D),
 | 
			
		||||
    {P, {F, D2}};
 | 
			
		||||
next_payload([P | R]) ->
 | 
			
		||||
    {P, R};
 | 
			
		||||
next_payload([]) ->
 | 
			
		||||
    undef;
 | 
			
		||||
next_payload(Bin = <<_/bytes>>) ->
 | 
			
		||||
    {Bin, Bin}.
 | 
			
		||||
 | 
			
		||||
%%% real writing work %%%
 | 
			
		||||
 | 
			
		||||
write_packets(_Dev, DS, _P, _F, 0, _O, _Opts) ->
 | 
			
		||||
    DS;
 | 
			
		||||
write_packets(Dev, DataSource, P = #rtp_packet{}, F, L, O, Opts) ->
 | 
			
		||||
    Format = proplists:get_value(format, Opts, state),
 | 
			
		||||
    Ptime = proplists:get_value(duration, Opts, 160),
 | 
			
		||||
    Delay = proplists:get_value(delay, Opts, 0),
 | 
			
		||||
    Rate = proplists:get_value(rate, Opts, 8000),
 | 
			
		||||
    case next_payload(DataSource) of
 | 
			
		||||
        {Payload, DataSource2} ->
 | 
			
		||||
            write_packet(Dev, Ptime * F / Rate + Delay,
 | 
			
		||||
                         P#rtp_packet{seqno = F, timestamp = F*Ptime+O,
 | 
			
		||||
			              payload = Payload},
 | 
			
		||||
                         Format),
 | 
			
		||||
            write_packets(Dev, DataSource2, P, F+1, L-1, O, Opts);
 | 
			
		||||
	Other -> Other
 | 
			
		||||
    end.
 | 
			
		||||
 | 
			
		||||
write_packet(Dev, Time, P = #rtp_packet{}, Format) ->
 | 
			
		||||
    Bin = make_rtp_packet(P),
 | 
			
		||||
 | 
			
		||||
    write_packet_line(Dev, Time, P, Bin, Format).
 | 
			
		||||
 | 
			
		||||
write_packet_pre(Dev, carray) ->
 | 
			
		||||
    io:format(Dev,
 | 
			
		||||
              "struct {float t; int len; char *data;} packets[] = {~n", []);
 | 
			
		||||
 | 
			
		||||
write_packet_pre(_Dev, _) -> ok.
 | 
			
		||||
 | 
			
		||||
write_packet_post(Dev, carray) ->
 | 
			
		||||
    io:format(Dev, "};~n", []);
 | 
			
		||||
 | 
			
		||||
write_packet_post(_Dev, _) -> ok.
 | 
			
		||||
 | 
			
		||||
write_packet_line(Dev, Time, _P, Bin, state) ->
 | 
			
		||||
    io:format(Dev, "~f ~s~n", [Time, bin_to_hex(Bin)]);
 | 
			
		||||
 | 
			
		||||
write_packet_line(Dev, Time, #rtp_packet{seqno = N, timestamp = TS}, Bin, c) ->
 | 
			
		||||
    ByteList = [ [ $0, $x | integer_to_list(Byte, 16) ] || <<Byte:8>> <= Bin ],
 | 
			
		||||
    ByteStr = string:join(ByteList, ", "),
 | 
			
		||||
    io:format(Dev, "/* time=~f, SeqNo=~B, TS=~B */ {~s}~n", [Time, N, TS, ByteStr]);
 | 
			
		||||
 | 
			
		||||
write_packet_line(Dev, Time, #rtp_packet{seqno = N, timestamp = TS}, Bin, carray) ->
 | 
			
		||||
    io:format(Dev, "  /* RTP: SeqNo=~B, TS=~B */~n", [N, TS]),
 | 
			
		||||
    io:format(Dev, "  {~f, ~B, \"", [Time, size(Bin)]),
 | 
			
		||||
    [ io:format(Dev, "\\x~2.16.0B", [Byte]) || <<Byte:8>> <= Bin ],
 | 
			
		||||
    io:format(Dev, "\"},~n", []).
 | 
			
		||||
 | 
			
		||||
%%% real reading work %%%
 | 
			
		||||
 | 
			
		||||
read_packets(Dev, Opts) ->
 | 
			
		||||
    Format = proplists:get_value(in_format, Opts, state),
 | 
			
		||||
 | 
			
		||||
    read_packets(Dev, Opts, Format).
 | 
			
		||||
 | 
			
		||||
read_packets(Dev, Opts, Format) ->
 | 
			
		||||
    case read_packet(Dev, Opts, Format) of
 | 
			
		||||
        eof -> [];
 | 
			
		||||
        Tuple -> [Tuple | read_packets(Dev, Opts, Format)]
 | 
			
		||||
    end.
 | 
			
		||||
 | 
			
		||||
read_packet(Dev, Opts, bin) ->
 | 
			
		||||
    Size = proplists:get_value(frame_size, Opts),
 | 
			
		||||
    case file:read(Dev, Size) of
 | 
			
		||||
        {ok, Data} -> {0, #rtp_packet{payload = iolist_to_binary(Data)}};
 | 
			
		||||
	eof -> eof
 | 
			
		||||
    end;
 | 
			
		||||
read_packet(Dev, _Opts, Format) ->
 | 
			
		||||
    case read_packet_line(Dev, Format) of
 | 
			
		||||
        {Time, Bin} -> {Time, parse_rtp_packet(Bin)};
 | 
			
		||||
	eof -> eof
 | 
			
		||||
    end.
 | 
			
		||||
 | 
			
		||||
read_packet_line(Dev, state) ->
 | 
			
		||||
    case io:fread(Dev, "", "~f ~s") of
 | 
			
		||||
        {ok, [Time, Hex]} -> {Time, hex_to_bin(Hex)};
 | 
			
		||||
	eof -> eof
 | 
			
		||||
    end.
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
"
 | 
			
		||||
Simple UDP replay from the state files
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
PackageLoader fileInPackage: #Sockets.
 | 
			
		||||
FileStream fileIn: 'rtp_replay_shared.st'.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Eval [
 | 
			
		||||
    | replay file host dport |
 | 
			
		||||
 | 
			
		||||
    file := Smalltalk arguments at: 1 ifAbsent: [ 'rtpstream.state' ].
 | 
			
		||||
    host := Smalltalk arguments at: 2 ifAbsent: [ '127.0.0.1' ].
 | 
			
		||||
    dport := (Smalltalk arguments at: 3 ifAbsent: [ '4000' ]) asInteger.
 | 
			
		||||
    sport := (Smalltalk arguments at: 4 ifAbsent: [ '0' ]) asInteger.
 | 
			
		||||
 | 
			
		||||
    replay := RTPReplay on: file fromPort: sport.
 | 
			
		||||
 | 
			
		||||
    Transcript nextPutAll: 'Going to stream now'; nl.
 | 
			
		||||
    replay streamAudio: host port: dport.
 | 
			
		||||
]
 | 
			
		||||
@@ -1,118 +0,0 @@
 | 
			
		||||
"
 | 
			
		||||
Simple UDP replay from the state files
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
PackageLoader fileInPackage: #Sockets.
 | 
			
		||||
 | 
			
		||||
Object subclass: SDPUtils [
 | 
			
		||||
    "Look into using PetitParser."
 | 
			
		||||
    SDPUtils class >> findPort: aSDP [
 | 
			
		||||
        aSDP linesDo: [:line |
 | 
			
		||||
            (line startsWith: 'm=audio ') ifTrue: [
 | 
			
		||||
                | stream |
 | 
			
		||||
                stream := line readStream
 | 
			
		||||
                            skip: 'm=audio ' size;
 | 
			
		||||
                            yourself.
 | 
			
		||||
                ^ Number readFrom: stream.
 | 
			
		||||
            ]
 | 
			
		||||
        ].
 | 
			
		||||
 | 
			
		||||
        ^ self error: 'Not found'.
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    SDPUtils class >> findHost: aSDP [
 | 
			
		||||
        aSDP linesDo: [:line |
 | 
			
		||||
            (line startsWith: 'c=IN IP4 ') ifTrue: [
 | 
			
		||||
                | stream |
 | 
			
		||||
                ^ stream := line readStream
 | 
			
		||||
                            skip: 'c=IN IP4 ' size;
 | 
			
		||||
                            upToEnd.
 | 
			
		||||
            ]
 | 
			
		||||
        ].
 | 
			
		||||
 | 
			
		||||
        ^ self error: 'Not found'.
 | 
			
		||||
    ]
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
Object subclass: RTPReplay [
 | 
			
		||||
    | filename socket |
 | 
			
		||||
    RTPReplay class >> on: aFile [
 | 
			
		||||
        ^ self new
 | 
			
		||||
            initialize;
 | 
			
		||||
            file: aFile; yourself
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    RTPReplay class >> on: aFile fromPort: aPort [
 | 
			
		||||
        ^ self new
 | 
			
		||||
            initialize: aPort;
 | 
			
		||||
            file: aFile; yourself
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    initialize [
 | 
			
		||||
        self initialize: 0.
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    initialize: aPort [
 | 
			
		||||
        socket := Sockets.DatagramSocket local: '0.0.0.0' port: aPort.
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    file: aFile [ 
 | 
			
		||||
        filename := aFile
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    localPort [
 | 
			
		||||
        ^ socket port
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    streamAudio: aHost port: aPort [
 | 
			
		||||
        | file last_time last_image udp_send dest |
 | 
			
		||||
 | 
			
		||||
        last_time := nil.
 | 
			
		||||
        last_image := nil.
 | 
			
		||||
        file := FileStream open: filename mode: #read.
 | 
			
		||||
 | 
			
		||||
        "Send the payload"
 | 
			
		||||
        dest := Sockets.SocketAddress byName: aHost.
 | 
			
		||||
        udp_send := [:payload | | datagram |
 | 
			
		||||
            datagram := Sockets.Datagram data: payload contents address: dest port: aPort.
 | 
			
		||||
            socket nextPut: datagram
 | 
			
		||||
        ].
 | 
			
		||||
 | 
			
		||||
        [file atEnd] whileFalse: [
 | 
			
		||||
            | lineStream time data now_image |
 | 
			
		||||
            lineStream := file nextLine readStream.
 | 
			
		||||
 | 
			
		||||
            "Read the time, skip the blank, parse the data"
 | 
			
		||||
            time := Number readFrom: lineStream.
 | 
			
		||||
            lineStream skip: 1.
 | 
			
		||||
 | 
			
		||||
            data := WriteStream on: (ByteArray new: 30).
 | 
			
		||||
            [lineStream atEnd] whileFalse: [
 | 
			
		||||
                | hex |
 | 
			
		||||
                hex := lineStream next: 2.
 | 
			
		||||
                data nextPut: (Number readFrom: hex readStream radix: 16).
 | 
			
		||||
            ].
 | 
			
		||||
 | 
			
		||||
            last_time isNil
 | 
			
		||||
                ifTrue: [
 | 
			
		||||
                    "First time, send it right now"
 | 
			
		||||
                    last_time := time.
 | 
			
		||||
                    last_image := Time millisecondClockValue.
 | 
			
		||||
                    udp_send value: data.
 | 
			
		||||
                ]
 | 
			
		||||
                ifFalse: [
 | 
			
		||||
                    | wait_image new_image_time |
 | 
			
		||||
 | 
			
		||||
                    "How long to wait?"
 | 
			
		||||
                    wait_image := last_image + ((time - last_time) * 1000).
 | 
			
		||||
                    [ wait_image > Time millisecondClockValue ]
 | 
			
		||||
                        whileTrue: [Processor yield].
 | 
			
		||||
 | 
			
		||||
                    udp_send value: data.
 | 
			
		||||
                    last_time := time.
 | 
			
		||||
                    last_image := wait_image.
 | 
			
		||||
                ]
 | 
			
		||||
        ]
 | 
			
		||||
    ]
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@@ -1,87 +0,0 @@
 | 
			
		||||
"""
 | 
			
		||||
Create a SIP connection and then stream...
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
PackageLoader
 | 
			
		||||
    fileInPackage: #OsmoSIP.
 | 
			
		||||
 | 
			
		||||
"Load for the replay code"
 | 
			
		||||
FileStream fileIn: 'rtp_replay_shared.st'.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Osmo.SIPCall subclass: StreamCall [
 | 
			
		||||
    | sem stream |
 | 
			
		||||
 | 
			
		||||
    createCall: aSDP [
 | 
			
		||||
        | sdp |
 | 
			
		||||
        stream := RTPReplay on: 'rtp_ssrc6976010.240.240.1_to_10.240.240.50.state'.
 | 
			
		||||
        sdp := aSDP % {stream localPort}.
 | 
			
		||||
        ^ super createCall: sdp.
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    sem: aSemaphore [
 | 
			
		||||
          sem := aSemaphore
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    sessionNew [
 | 
			
		||||
        | host port |
 | 
			
		||||
        Transcript nextPutAll: 'The call has started'; nl.
 | 
			
		||||
        Transcript nextPutAll: sdp_result; nl.
 | 
			
		||||
 | 
			
		||||
        host := SDPUtils findHost: sdp_result.
 | 
			
		||||
        port := SDPUtils findPort: sdp_result.
 | 
			
		||||
 | 
			
		||||
        [
 | 
			
		||||
            stream streamAudio: host port: port.
 | 
			
		||||
            Transcript nextPutAll: 'Streaming has finished.'; nl.
 | 
			
		||||
        ] fork.
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    sessionFailed [
 | 
			
		||||
        sem signal
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    sessionEnd [
 | 
			
		||||
        sem signal
 | 
			
		||||
    ]
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
Eval [
 | 
			
		||||
    | transport agent call sem sdp_fr sdp_amr |
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    sdp_fr := (WriteStream on: String new)
 | 
			
		||||
        nextPutAll: 'v=0'; cr; nl;
 | 
			
		||||
        nextPutAll: 'o=twinkle 1739517580 1043400482 IN IP4 127.0.0.1'; cr; nl;
 | 
			
		||||
        nextPutAll: 's=-'; cr; nl;
 | 
			
		||||
        nextPutAll: 'c=IN IP4 127.0.0.1'; cr; nl;
 | 
			
		||||
        nextPutAll: 't=0 0'; cr; nl;
 | 
			
		||||
        nextPutAll: 'm=audio %1 RTP/AVP 0 101'; cr; nl;
 | 
			
		||||
        nextPutAll: 'a=rtpmap:0 PCMU/8000'; cr; nl;
 | 
			
		||||
        nextPutAll: 'a=rtpmap:101 telephone-event/8000'; cr; nl;
 | 
			
		||||
        nextPutAll: 'a=fmtp:101 0-15'; cr; nl;
 | 
			
		||||
        nextPutAll: 'a=ptime:20'; cr; nl;
 | 
			
		||||
        contents.
 | 
			
		||||
 | 
			
		||||
    sem := Semaphore new.
 | 
			
		||||
    transport := Osmo.SIPUdpTransport
 | 
			
		||||
          startOn: '0.0.0.0' port: 5066.
 | 
			
		||||
    agent := Osmo.SIPUserAgent createOn: transport.
 | 
			
		||||
    transport start.
 | 
			
		||||
 | 
			
		||||
    call := (StreamCall
 | 
			
		||||
              fromUser: 'sip:1000@sip.zecke.osmocom.org'
 | 
			
		||||
              host: '127.0.0.1'
 | 
			
		||||
              port: 5060
 | 
			
		||||
              to: 'sip:123456@127.0.0.1'
 | 
			
		||||
              on: agent)
 | 
			
		||||
              sem: sem; yourself.
 | 
			
		||||
 | 
			
		||||
    call createCall: sdp_fr.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    "Wait for the stream to have ended"
 | 
			
		||||
    sem wait.
 | 
			
		||||
 | 
			
		||||
    (Delay forSeconds: 4) wait.
 | 
			
		||||
]
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
print("Ni hao")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
do
 | 
			
		||||
	local tap = Listener.new("ip", "rtp")
 | 
			
		||||
	local rtp_ssrc = Field.new("rtp.ssrc")
 | 
			
		||||
	local frame_time = Field.new("frame.time_relative")
 | 
			
		||||
	local rtp = Field.new("rtp")
 | 
			
		||||
 | 
			
		||||
	function tap.packet(pinfo, tvb, ip)
 | 
			
		||||
		local ip_src, ip_dst = tostring(ip.ip_src), tostring(ip.ip_dst)
 | 
			
		||||
		local rtp_data = rtp()
 | 
			
		||||
		local filename = "rtp_ssrc" .. rtp_ssrc() "_src_" .. ip_src .. "_to_" .. ip_dst .. ".state"
 | 
			
		||||
		local f = io.open(filename, "a")
 | 
			
		||||
 | 
			
		||||
		f:write(tostring(frame_time()) .. " ")
 | 
			
		||||
		f:write(tostring(rtp_data.value))
 | 
			
		||||
		f:write("\n")
 | 
			
		||||
		f:close()
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	function tap.draw()
 | 
			
		||||
		print("DRAW")
 | 
			
		||||
	end
 | 
			
		||||
	function tap.reset()
 | 
			
		||||
		print("RESET")
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										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)
 | 
			
		||||
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
"I create output for some simple SQL statements for the HLR db"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Eval [
 | 
			
		||||
 | 
			
		||||
"Create tables if they don't exist"
 | 
			
		||||
Transcript show: 'CREATE TABLE SMS (
 | 
			
		||||
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
			
		||||
                    created TIMESTAMP NOT NULL,
 | 
			
		||||
                    sent TIMESTAMP,
 | 
			
		||||
                    sender_id INTEGER NOT NULL,
 | 
			
		||||
                    receiver_id INTEGER NOT NULL,
 | 
			
		||||
                    deliver_attempts INTEGER NOT NULL DEFAULT 0,
 | 
			
		||||
                    valid_until TIMESTAMP,
 | 
			
		||||
                    reply_path_req INTEGER NOT NULL,
 | 
			
		||||
                    status_rep_req INTEGER NOT NULL,
 | 
			
		||||
                    protocol_id INTEGER NOT NULL,
 | 
			
		||||
                    data_coding_scheme INTEGER NOT NULL,
 | 
			
		||||
                    ud_hdr_ind INTEGER NOT NULL,
 | 
			
		||||
                    dest_addr TEXT,
 | 
			
		||||
                    user_data BLOB,
 | 
			
		||||
                    header BLOB,
 | 
			
		||||
                    text TEXT);'; nl;
 | 
			
		||||
	     show: 'CREATE TABLE Subscriber (
 | 
			
		||||
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
			
		||||
                    created TIMESTAMP NOT NULL,
 | 
			
		||||
                    updated TIMESTAMP NOT NULL,
 | 
			
		||||
                    imsi NUMERIC UNIQUE NOT NULL,
 | 
			
		||||
                    name TEXT,
 | 
			
		||||
                    extension TEXT UNIQUE,
 | 
			
		||||
                    authorized INTEGER NOT NULL DEFAULT 0,
 | 
			
		||||
                    tmsi TEXT UNIQUE,
 | 
			
		||||
                    lac INTEGER NOT NULL DEFAULT 0);'; nl.
 | 
			
		||||
 | 
			
		||||
"Create some dummy subscribers"
 | 
			
		||||
num_sub := 1000.
 | 
			
		||||
num_sms := 30.
 | 
			
		||||
lac := 1.
 | 
			
		||||
 | 
			
		||||
Transcript show: 'BEGIN;'; nl.
 | 
			
		||||
 | 
			
		||||
1 to: num_sub do: [:each |
 | 
			
		||||
   Transcript show: 'INSERT INTO Subscriber
 | 
			
		||||
                        (imsi, created, updated, authorized, lac, extension)
 | 
			
		||||
                        VALUES
 | 
			
		||||
                        (%1, datetime(''now''), datetime(''now''), 1, %2, %3);' %
 | 
			
		||||
                        {(274090000000000 + each). lac. each}; nl.
 | 
			
		||||
].
 | 
			
		||||
 | 
			
		||||
1 to: num_sms do: [:sms |
 | 
			
		||||
    1 to: num_sub do: [:sub |
 | 
			
		||||
        Transcript show: 'INSERT INTO SMS
 | 
			
		||||
                            (created, sender_id, receiver_id, valid_until,
 | 
			
		||||
                             reply_path_req, status_rep_req, protocol_id,
 | 
			
		||||
                             data_coding_scheme, ud_hdr_ind, dest_addr,
 | 
			
		||||
                             text) VALUES
 | 
			
		||||
                            (datetime(''now''), 1, %1, ''2222-2-2'',
 | 
			
		||||
                             0, 0, 0,
 | 
			
		||||
                             0, 0, ''123456'',
 | 
			
		||||
                             ''abc'');' % {sub}; nl.
 | 
			
		||||
    ]
 | 
			
		||||
].
 | 
			
		||||
 | 
			
		||||
Transcript show: 'COMMIT;'; nl.
 | 
			
		||||
 | 
			
		||||
]
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
"Query for one SMS"
 | 
			
		||||
 | 
			
		||||
Eval [
 | 
			
		||||
1 to: 100 do: [:each |
 | 
			
		||||
    Transcript show: 'SELECT SMS.* FROM SMS
 | 
			
		||||
                        JOIN Subscriber ON SMS.receiver_id = Subscriber.id
 | 
			
		||||
                            WHERE SMS.id >= 1 AND SMS.sent IS NULL AND Subscriber.lac > 0
 | 
			
		||||
                            ORDER BY SMS.id LIMIT 1;'; nl.
 | 
			
		||||
].
 | 
			
		||||
]
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
probe process("/usr/lib/libsqlite3.so.0.8.6").function("sqlite3_get_table")
 | 
			
		||||
{
 | 
			
		||||
  a = user_string($zSql);
 | 
			
		||||
  printf("sqlite3_get_table called '%s'\n", a);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,188 +0,0 @@
 | 
			
		||||
#!/usr/bin/python3
 | 
			
		||||
# -*- mode: python-mode; py-indent-tabs-mode: nil -*-
 | 
			
		||||
"""
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__version__ = "v0.7" # bump this on every non-trivial change
 | 
			
		||||
 | 
			
		||||
from twisted.internet import defer, reactor
 | 
			
		||||
from twisted_ipa import CTRL, IPAFactory, __version__ as twisted_ipa_version
 | 
			
		||||
from ipa import Ctrl
 | 
			
		||||
from treq import post, collect
 | 
			
		||||
from suds.client import Client
 | 
			
		||||
from functools import partial
 | 
			
		||||
from distutils.version import StrictVersion as V # FIXME: use NormalizedVersion from PEP-386 when available
 | 
			
		||||
import argparse, datetime, signal, sys, os, logging, logging.handlers
 | 
			
		||||
 | 
			
		||||
# we don't support older versions of TwistedIPA module
 | 
			
		||||
assert V(twisted_ipa_version) > V('0.4')
 | 
			
		||||
 | 
			
		||||
# keys from OpenBSC openbsc/src/libbsc/bsc_rf_ctrl.c, values SOAP-specific
 | 
			
		||||
oper = { 'inoperational' : 0, 'operational' : 1 }
 | 
			
		||||
admin = { 'locked' : 0, 'unlocked' : 1 }
 | 
			
		||||
policy = { 'off' : 0, 'on' : 1, 'grace' : 2, 'unknown' : 3 }
 | 
			
		||||
 | 
			
		||||
# keys from OpenBSC openbsc/src/libbsc/bsc_vty.c
 | 
			
		||||
fix = { 'invalid' : 0, 'fix2d' : 1, 'fix3d' : 1 } # SOAP server treats it as boolean but expects int
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def handle_reply(p, f, log, r):
 | 
			
		||||
    """
 | 
			
		||||
    Reply handler: takes function p to process raw SOAP server reply r, function f to run for each command and verbosity flag v
 | 
			
		||||
    """
 | 
			
		||||
    repl = p(r) # result is expected to have both commands[] array and error string (could be None)
 | 
			
		||||
    bsc_id = repl.commands[0].split()[0].split('.')[3] # we expect 1st command to have net.0.bsc.666.bts.2.trx.1 location prefix format
 | 
			
		||||
    log.info("Received SOAP response for BSC %s with %d commands, error status: %s" % (bsc_id, len(repl.commands), repl.error))
 | 
			
		||||
    log.debug("BSC %s commands: %s" % (bsc_id, repl.commands))
 | 
			
		||||
    for t in repl.commands: # Process OpenBscCommands format from .wsdl
 | 
			
		||||
        (_, m) = Ctrl().cmd(*t.split())
 | 
			
		||||
        f(m)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Trap(CTRL):
 | 
			
		||||
    """
 | 
			
		||||
    TRAP handler (agnostic to factory's client object)
 | 
			
		||||
    """
 | 
			
		||||
    def ctrl_TRAP(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        Parse CTRL TRAP and dispatch to appropriate handler after normalization
 | 
			
		||||
        """
 | 
			
		||||
        (l, r) = v.split()
 | 
			
		||||
        loc = l.split('.')
 | 
			
		||||
        t_type = loc[-1]
 | 
			
		||||
        p = partial(lambda a, i: a[i] if len(a) > i else None, loc) # parse helper
 | 
			
		||||
        method = getattr(self, 'handle_' + t_type.replace('-', ''), lambda: "Unhandled %s trap" % t_type)
 | 
			
		||||
        method(p(1), p(3), p(5), p(7), r) # we expect net.0.bsc.666.bts.2.trx.1 format for trap prefix
 | 
			
		||||
 | 
			
		||||
    def ctrl_SET_REPLY(self, data, _, v):
 | 
			
		||||
        """
 | 
			
		||||
        Debug log for replies to our commands
 | 
			
		||||
        """
 | 
			
		||||
        self.factory.log.debug('SET REPLY %s' % v)
 | 
			
		||||
 | 
			
		||||
    def ctrl_ERROR(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        We want to know if smth went wrong
 | 
			
		||||
        """
 | 
			
		||||
        self.factory.log.debug('CTRL ERROR [%s] %s' % (op_id, v))
 | 
			
		||||
 | 
			
		||||
    def connectionMade(self):
 | 
			
		||||
        """
 | 
			
		||||
        Logging wrapper, calling super() is necessary not to break reconnection logic
 | 
			
		||||
        """
 | 
			
		||||
        self.factory.log.info("Connected to CTRL@%s:%d" % (self.factory.host, self.factory.port))
 | 
			
		||||
        super(CTRL, self).connectionMade()
 | 
			
		||||
 | 
			
		||||
    @defer.inlineCallbacks
 | 
			
		||||
    def handle_locationstate(self, net, bsc, bts, trx, data):
 | 
			
		||||
        """
 | 
			
		||||
        Handle location-state TRAP: parse trap content, build SOAP context and use treq's routines to post it while setting up async handlers
 | 
			
		||||
        """
 | 
			
		||||
        (ts, fx, lat, lon, height, opr, adm, pol, mcc, mnc) = data.split(',')
 | 
			
		||||
        tstamp = datetime.datetime.fromtimestamp(float(ts)).isoformat()
 | 
			
		||||
        self.factory.log.debug('location-state@%s.%s.%s.%s (%s) [%s/%s] => %s' % (net, bsc, bts, trx, tstamp, mcc, mnc, data))
 | 
			
		||||
        ctx = self.factory.client.registerSiteLocation(bsc, float(lon), float(lat), fix.get(fx, 0), tstamp, oper.get(opr, 2), admin.get(adm, 2), policy.get(pol, 3))
 | 
			
		||||
        d = post(self.factory.location, ctx.envelope)
 | 
			
		||||
        d.addCallback(collect, partial(handle_reply, ctx.process_reply, self.transport.write, self.factory.log)) # treq's collect helper is handy to get all reply content at once using closure on ctx
 | 
			
		||||
        d.addErrback(lambda e, bsc: self.factory.log.critical("HTTP POST error %s while trying to register BSC %s" % (e, bsc)), bsc) # handle HTTP errors
 | 
			
		||||
        # Ensure that we run only limited number of requests in parallel:
 | 
			
		||||
        yield self.factory.semaphore.acquire()
 | 
			
		||||
        yield d # we end up here only if semaphore is available which means it's ok to fire the request without exceeding the limit
 | 
			
		||||
        self.factory.semaphore.release()
 | 
			
		||||
 | 
			
		||||
    def handle_notificationrejectionv1(self, net, bsc, bts, trx, data):
 | 
			
		||||
        """
 | 
			
		||||
        Handle notification-rejection-v1 TRAP: just an example to show how more message types can be handled
 | 
			
		||||
        """
 | 
			
		||||
        self.factory.log.debug('notification-rejection-v1@bsc-id %s => %s' % (bsc, data))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TrapFactory(IPAFactory):
 | 
			
		||||
    """
 | 
			
		||||
    Store SOAP client object so TRAP handler can use it for requests
 | 
			
		||||
    """
 | 
			
		||||
    location = None
 | 
			
		||||
    log = None
 | 
			
		||||
    semaphore = None
 | 
			
		||||
    client = None
 | 
			
		||||
    host = None
 | 
			
		||||
    port = None
 | 
			
		||||
    def __init__(self, host, port, proto, semaphore, log, wsdl=None, location=None):
 | 
			
		||||
        self.host = host # for logging only,
 | 
			
		||||
        self.port = port # seems to be no way to get it from ReconnectingClientFactory
 | 
			
		||||
        self.log = log
 | 
			
		||||
        self.semaphore = semaphore
 | 
			
		||||
        soap = Client(wsdl, location=location, nosend=True) # make async SOAP client
 | 
			
		||||
        self.location = location.encode() if location else soap.wsdl.services[0].ports[0].location # necessary for dispatching HTTP POST via treq
 | 
			
		||||
        self.client = soap.service
 | 
			
		||||
        level = self.log.getEffectiveLevel()
 | 
			
		||||
        self.log.setLevel(logging.WARNING) # we do not need excessive debug from lower levels
 | 
			
		||||
        super(TrapFactory, self).__init__(proto, self.log)
 | 
			
		||||
        self.log.setLevel(level)
 | 
			
		||||
        self.log.debug("Using IPA %s, SUDS client: %s" % (Ctrl.version, soap))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def reloader(path, script, log, dbg1, dbg2, signum, _):
 | 
			
		||||
    """
 | 
			
		||||
    Signal handler: we have to use execl() because twisted's reactor is not restartable due to some bug in twisted implementation
 | 
			
		||||
    """
 | 
			
		||||
    log.info("Received Signal %d - restarting..." % signum)
 | 
			
		||||
    if signum == signal.SIGUSR1 and dbg1 not in sys.argv and dbg2 not in sys.argv:
 | 
			
		||||
        sys.argv.append(dbg1) # enforce debug
 | 
			
		||||
    if signum == signal.SIGUSR2 and (dbg1 in sys.argv or dbg2 in sys.argv): # disable debug
 | 
			
		||||
        if dbg1 in sys.argv:
 | 
			
		||||
            sys.argv.remove(dbg1)
 | 
			
		||||
        if dbg2 in sys.argv:
 | 
			
		||||
            sys.argv.remove(dbg2)
 | 
			
		||||
    os.execl(path, script, *sys.argv[1:])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    p = argparse.ArgumentParser(description='Proxy between given SOAP service and Osmocom CTRL protocol.')
 | 
			
		||||
    p.add_argument('-v', '--version', action='version', version=("%(prog)s " + __version__))
 | 
			
		||||
    p.add_argument('-p', '--port', type=int, default=4250, help="Port to use for CTRL interface, defaults to 4250")
 | 
			
		||||
    p.add_argument('-c', '--ctrl', default='localhost', help="Adress to use for CTRL interface, defaults to localhost")
 | 
			
		||||
    p.add_argument('-w', '--wsdl', required=True, help="WSDL URL for SOAP")
 | 
			
		||||
    p.add_argument('-n', '--num', type=int, default=5, help="Max number of concurrent HTTP requests to SOAP server")
 | 
			
		||||
    p.add_argument('-d', '--debug', action='store_true', help="Enable debug log")
 | 
			
		||||
    p.add_argument('-o', '--output', action='store_true', help="Log to STDOUT in addition to SYSLOG")
 | 
			
		||||
    p.add_argument('-l', '--location', help="Override location found in WSDL file (don't use unless you know what you're doing)")
 | 
			
		||||
    args = p.parse_args()
 | 
			
		||||
 | 
			
		||||
    log = logging.getLogger('CTRL2SOAP')
 | 
			
		||||
    if args.debug:
 | 
			
		||||
        log.setLevel(logging.DEBUG)
 | 
			
		||||
    else:
 | 
			
		||||
        log.setLevel(logging.INFO)
 | 
			
		||||
    log.addHandler(logging.handlers.SysLogHandler('/dev/log'))
 | 
			
		||||
    if args.output:
 | 
			
		||||
        log.addHandler(logging.StreamHandler(sys.stdout))
 | 
			
		||||
 | 
			
		||||
    reboot = partial(reloader, os.path.abspath(__file__), os.path.basename(__file__), log, '-d', '--debug') # keep in sync with add_argument() call above
 | 
			
		||||
    signal.signal(signal.SIGHUP, reboot)
 | 
			
		||||
    signal.signal(signal.SIGQUIT, reboot)
 | 
			
		||||
    signal.signal(signal.SIGUSR1, reboot) # restart and enabled debug output
 | 
			
		||||
    signal.signal(signal.SIGUSR2, reboot) # restart and disable debug output
 | 
			
		||||
 | 
			
		||||
    log.info("SOAP proxy %s starting with PID %d ..." % (__version__, os.getpid()))
 | 
			
		||||
    reactor.connectTCP(args.ctrl, args.port, TrapFactory(args.ctrl, args.port, Trap, defer.DeferredSemaphore(args.num), log, args.wsdl, args.location))
 | 
			
		||||
    reactor.run()
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=OpenBSC MGCP
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
Restart=always
 | 
			
		||||
ExecStart=/usr/bin/osmo-bsc_mgcp -s -c /etc/osmocom/osmo-bsc-mgcp.cfg
 | 
			
		||||
RestartSec=2
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=OpenBSC BSC
 | 
			
		||||
Wants=osmo-bsc-mgcp.service
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
Restart=always
 | 
			
		||||
ExecStart=/usr/bin/osmo-bsc -c /etc/osmocom/osmo-bsc.cfg -s
 | 
			
		||||
RestartSec=2
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Osmocom Gb proxy
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
ExecStart=/usr/bin/osmo-gbproxy -c /etc/osmocom/osmo-gbproxy.cfg
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=2
 | 
			
		||||
RestartPreventExitStatus=1
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=OpenBSC Network In the Box (NITB)
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
Restart=always
 | 
			
		||||
ExecStart=/usr/bin/osmo-nitb -s -C -c /etc/osmocom/osmo-nitb.cfg -l /var/lib/osmocom/hlr.sqlite3
 | 
			
		||||
RestartSec=2
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=OpenBSC SGSN
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
Restart=always
 | 
			
		||||
ExecStart=/usr/bin/osmo-sgsn -c /etc/osmocom/osmo-sgsn.cfg
 | 
			
		||||
RestartSec=2
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
 | 
			
		||||
OBJS = testconv_main.o
 | 
			
		||||
 | 
			
		||||
CC = gcc
 | 
			
		||||
CFLAGS = -O0 -ggdb -Wall
 | 
			
		||||
LDFLAGS =
 | 
			
		||||
CPPFLAGS = -I../.. -I../../include $(shell pkg-config --cflags libosmocore) $(shell pkg-config --cflags libbcg729)
 | 
			
		||||
LIBS =  ../../src/libmgcp/libmgcp.a ../../src/libcommon/libcommon.a $(shell pkg-config --libs libosmocore) $(shell pkg-config --libs libbcg729) -lgsm -lrt
 | 
			
		||||
 | 
			
		||||
testconv: $(OBJS)
 | 
			
		||||
	$(CC)  -o $@ $^ $(LDFLAGS) $(LIBS)
 | 
			
		||||
 | 
			
		||||
testconv_main.o: testconv_main.c
 | 
			
		||||
 | 
			
		||||
$(OBJS):
 | 
			
		||||
	$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
 | 
			
		||||
@@ -1,133 +0,0 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <err.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocom/core/talloc.h>
 | 
			
		||||
#include <osmocom/core/application.h>
 | 
			
		||||
 | 
			
		||||
#include <openbsc/debug.h>
 | 
			
		||||
#include <openbsc/gsm_data.h>
 | 
			
		||||
#include <openbsc/mgcp.h>
 | 
			
		||||
#include <openbsc/mgcp_internal.h>
 | 
			
		||||
 | 
			
		||||
#include "bscconfig.h"
 | 
			
		||||
#ifndef BUILD_MGCP_TRANSCODING
 | 
			
		||||
#error "Requires MGCP transcoding enabled (see --enable-mgcp-transcoding)"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "openbsc/mgcp_transcode.h"
 | 
			
		||||
 | 
			
		||||
static int audio_name_to_type(const char *name)
 | 
			
		||||
{
 | 
			
		||||
	if (!strcasecmp(name, "gsm"))
 | 
			
		||||
		return 3;
 | 
			
		||||
#ifdef HAVE_BCG729
 | 
			
		||||
	else if (!strcasecmp(name, "g729"))
 | 
			
		||||
		return 18;
 | 
			
		||||
#endif
 | 
			
		||||
	else if (!strcasecmp(name, "pcma"))
 | 
			
		||||
		return 8;
 | 
			
		||||
	else if (!strcasecmp(name, "l16"))
 | 
			
		||||
		return 11;
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int mgcp_get_trans_frame_size(void *state_, int nsamples, int dst);
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	char buf[4096] = {0x80, 0};
 | 
			
		||||
	int cc, rc;
 | 
			
		||||
	struct mgcp_rtp_end *dst_end;
 | 
			
		||||
	struct mgcp_rtp_end *src_end;
 | 
			
		||||
	struct mgcp_trunk_config tcfg = {{0}};
 | 
			
		||||
	struct mgcp_endpoint endp = {0};
 | 
			
		||||
	struct mgcp_process_rtp_state *state;
 | 
			
		||||
	int in_size;
 | 
			
		||||
	int in_samples = 160;
 | 
			
		||||
	int out_samples = 0;
 | 
			
		||||
	uint32_t ts = 0;
 | 
			
		||||
	uint16_t seq = 0;
 | 
			
		||||
 | 
			
		||||
	osmo_init_logging(&log_info);
 | 
			
		||||
 | 
			
		||||
	tcfg.endpoints = &endp;
 | 
			
		||||
	tcfg.number_endpoints = 1;
 | 
			
		||||
	endp.tcfg = &tcfg;
 | 
			
		||||
	mgcp_initialize_endp(&endp);
 | 
			
		||||
 | 
			
		||||
	dst_end = &endp.bts_end;
 | 
			
		||||
	src_end = &endp.net_end;
 | 
			
		||||
 | 
			
		||||
	if (argc <= 2)
 | 
			
		||||
		errx(1, "Usage: {gsm|g729|pcma|l16} {gsm|g729|pcma|l16} [SPP]");
 | 
			
		||||
 | 
			
		||||
	if ((src_end->codec.payload_type = audio_name_to_type(argv[1])) == -1)
 | 
			
		||||
		errx(1, "invalid input format '%s'", argv[1]);
 | 
			
		||||
	if ((dst_end->codec.payload_type = audio_name_to_type(argv[2])) == -1)
 | 
			
		||||
		errx(1, "invalid output format '%s'", argv[2]);
 | 
			
		||||
	if (argc > 3)
 | 
			
		||||
		out_samples = atoi(argv[3]);
 | 
			
		||||
 | 
			
		||||
	if (out_samples) {
 | 
			
		||||
		dst_end->codec.frame_duration_den = dst_end->codec.rate;
 | 
			
		||||
		dst_end->codec.frame_duration_num = out_samples;
 | 
			
		||||
		dst_end->frames_per_packet = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rc = mgcp_transcoding_setup(&endp, dst_end, src_end);
 | 
			
		||||
	if (rc < 0)
 | 
			
		||||
		errx(1, "setup failed: %s", strerror(-rc));
 | 
			
		||||
 | 
			
		||||
	state = dst_end->rtp_process_data;
 | 
			
		||||
	OSMO_ASSERT(state != NULL);
 | 
			
		||||
 | 
			
		||||
	in_size = mgcp_transcoding_get_frame_size(state, in_samples, 0);
 | 
			
		||||
	OSMO_ASSERT(sizeof(buf) >= in_size + 12);
 | 
			
		||||
 | 
			
		||||
	buf[1] = src_end->codec.payload_type;
 | 
			
		||||
	*(uint16_t*)(buf+2) = htons(1);
 | 
			
		||||
	*(uint32_t*)(buf+4) = htonl(0);
 | 
			
		||||
	*(uint32_t*)(buf+8) = htonl(0xaabbccdd);
 | 
			
		||||
 | 
			
		||||
	while ((cc = read(0, buf + 12, in_size))) {
 | 
			
		||||
		int cont;
 | 
			
		||||
		int len;
 | 
			
		||||
 | 
			
		||||
		if (cc != in_size)
 | 
			
		||||
			err(1, "read");
 | 
			
		||||
 | 
			
		||||
		*(uint16_t*)(buf+2) = htonl(seq);
 | 
			
		||||
		*(uint32_t*)(buf+4) = htonl(ts);
 | 
			
		||||
 | 
			
		||||
		seq += 1;
 | 
			
		||||
		ts += in_samples;
 | 
			
		||||
 | 
			
		||||
		cc += 12; /* include RTP header */
 | 
			
		||||
 | 
			
		||||
		len = cc;
 | 
			
		||||
 | 
			
		||||
		do {
 | 
			
		||||
			cont = mgcp_transcoding_process_rtp(&endp, dst_end,
 | 
			
		||||
							    buf, &len, sizeof(buf));
 | 
			
		||||
			if (cont == -EAGAIN) {
 | 
			
		||||
				fprintf(stderr, "Got EAGAIN\n");
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cont < 0)
 | 
			
		||||
				errx(1, "processing failed: %s", strerror(-cont));
 | 
			
		||||
 | 
			
		||||
			len -= 12; /* ignore RTP header */
 | 
			
		||||
 | 
			
		||||
			if (write(1, buf + 12, len) != len)
 | 
			
		||||
				err(1, "write");
 | 
			
		||||
 | 
			
		||||
			len = cont;
 | 
			
		||||
		} while (len > 0);
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,384 +0,0 @@
 | 
			
		||||
#!/usr/bin/python3
 | 
			
		||||
# -*- mode: python-mode; py-indent-tabs-mode: nil -*-
 | 
			
		||||
"""
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__version__ = "0.6" # bump this on every non-trivial change
 | 
			
		||||
 | 
			
		||||
from ipa import Ctrl, IPA
 | 
			
		||||
from twisted.internet.protocol import ReconnectingClientFactory
 | 
			
		||||
from twisted.internet import reactor
 | 
			
		||||
from twisted.protocols import basic
 | 
			
		||||
import argparse, logging
 | 
			
		||||
 | 
			
		||||
class IPACommon(basic.Int16StringReceiver):
 | 
			
		||||
    """
 | 
			
		||||
    Generic IPA protocol handler: include some routines for simpler subprotocols.
 | 
			
		||||
    It's not intended as full implementation of all subprotocols, rather common ground and example code.
 | 
			
		||||
    """
 | 
			
		||||
    def dbg(self, line):
 | 
			
		||||
        """
 | 
			
		||||
        Debug print helper
 | 
			
		||||
        """
 | 
			
		||||
        self.factory.log.debug(line)
 | 
			
		||||
 | 
			
		||||
    def osmo_CTRL(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        OSMO CTRL protocol
 | 
			
		||||
        Placeholder, see corresponding derived class
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def osmo_MGCP(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        OSMO MGCP extension
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('OSMO MGCP received %s' % data)
 | 
			
		||||
 | 
			
		||||
    def osmo_LAC(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        OSMO LAC extension
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('OSMO LAC received %s' % data)
 | 
			
		||||
 | 
			
		||||
    def osmo_SMSC(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        OSMO SMSC extension
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('OSMO SMSC received %s' % data)
 | 
			
		||||
 | 
			
		||||
    def osmo_ORC(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        OSMO ORC extension
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('OSMO ORC received %s' % data)
 | 
			
		||||
 | 
			
		||||
    def osmo_GSUP(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        OSMO GSUP extension
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('OSMO GSUP received %s' % data)
 | 
			
		||||
 | 
			
		||||
    def osmo_OAP(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        OSMO OAP extension
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('OSMO OAP received %s' % data)
 | 
			
		||||
 | 
			
		||||
    def osmo_UNKNOWN(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        OSMO defaul extension handler
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('OSMO unknown extension received %s' % data)
 | 
			
		||||
 | 
			
		||||
    def handle_RSL(self, data, proto, extension):
 | 
			
		||||
        """
 | 
			
		||||
        RSL protocol handler
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('IPA RSL received message with extension %s' % extension)
 | 
			
		||||
 | 
			
		||||
    def handle_CCM(self, data, proto, msgt):
 | 
			
		||||
        """
 | 
			
		||||
        CCM (IPA Connection Management)
 | 
			
		||||
        Placeholder, see corresponding derived class
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def handle_SCCP(self, data, proto, extension):
 | 
			
		||||
        """
 | 
			
		||||
        SCCP protocol handler
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('IPA SCCP received message with extension %s' % extension)
 | 
			
		||||
 | 
			
		||||
    def handle_OML(self, data, proto, extension):
 | 
			
		||||
        """
 | 
			
		||||
        OML protocol handler
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('IPA OML received message with extension %s' % extension)
 | 
			
		||||
 | 
			
		||||
    def handle_OSMO(self, data, proto, extension):
 | 
			
		||||
        """
 | 
			
		||||
        Dispatcher point for OSMO subprotocols based on extension name, lambda default should never happen
 | 
			
		||||
        """
 | 
			
		||||
        method = getattr(self, 'osmo_' + IPA().ext(extension), lambda: "extension dispatch failure")
 | 
			
		||||
        method(data)
 | 
			
		||||
 | 
			
		||||
    def handle_MGCP(self, data, proto, extension):
 | 
			
		||||
        """
 | 
			
		||||
        MGCP protocol handler
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('IPA MGCP received message with attribute %s' % extension)
 | 
			
		||||
 | 
			
		||||
    def handle_UNKNOWN(self, data, proto, extension):
 | 
			
		||||
        """
 | 
			
		||||
        Default protocol handler
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('IPA received message for %s (%s) protocol with attribute %s' % (IPA().proto(proto), proto, extension))
 | 
			
		||||
 | 
			
		||||
    def process_chunk(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Generic message dispatcher for IPA (sub)protocols based on protocol name, lambda default should never happen
 | 
			
		||||
        """
 | 
			
		||||
        (_, proto, extension, content) = IPA().del_header(data)
 | 
			
		||||
        if content is not None:
 | 
			
		||||
            self.dbg('IPA received %s::%s [%d/%d] %s' % (IPA().proto(proto), IPA().ext_name(proto, extension), len(data), len(content), content))
 | 
			
		||||
            method = getattr(self, 'handle_' + IPA().proto(proto), lambda: "protocol dispatch failure")
 | 
			
		||||
            method(content, proto, extension)
 | 
			
		||||
 | 
			
		||||
    def dataReceived(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Override for dataReceived from Int16StringReceiver because of inherently incompatible interpretation of length
 | 
			
		||||
        If default handler is used than we would always get off-by-1 error (Int16StringReceiver use equivalent of l + 2)
 | 
			
		||||
        """
 | 
			
		||||
        if len(data):
 | 
			
		||||
            (head, tail) = IPA().split_combined(data)
 | 
			
		||||
            self.process_chunk(head)
 | 
			
		||||
            self.dataReceived(tail)
 | 
			
		||||
 | 
			
		||||
    def connectionMade(self):
 | 
			
		||||
        """
 | 
			
		||||
        We have to resetDelay() here to drop internal state to default values to make reconnection logic work
 | 
			
		||||
        Make sure to call this via super() if overriding to keep reconnection logic intact
 | 
			
		||||
        """
 | 
			
		||||
        addr = self.transport.getPeer()
 | 
			
		||||
        self.dbg('IPA connected to %s:%d peer' % (addr.host, addr.port))
 | 
			
		||||
        self.factory.resetDelay()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CCM(IPACommon):
 | 
			
		||||
    """
 | 
			
		||||
    Implementation of CCM protocol for IPA multiplex
 | 
			
		||||
    """
 | 
			
		||||
    def ack(self):
 | 
			
		||||
        self.transport.write(IPA().id_ack())
 | 
			
		||||
 | 
			
		||||
    def ping(self):
 | 
			
		||||
        self.transport.write(IPA().ping())
 | 
			
		||||
 | 
			
		||||
    def pong(self):
 | 
			
		||||
        self.transport.write(IPA().pong())
 | 
			
		||||
 | 
			
		||||
    def handle_CCM(self, data, proto, msgt):
 | 
			
		||||
        """
 | 
			
		||||
        CCM (IPA Connection Management)
 | 
			
		||||
        Only basic logic necessary for tests is implemented (ping-pong, id ack etc)
 | 
			
		||||
        """
 | 
			
		||||
        if msgt == IPA.MSGT['ID_GET']:
 | 
			
		||||
            self.transport.getHandle().sendall(IPA().id_resp(self.factory.ccm_id))
 | 
			
		||||
            # if we call
 | 
			
		||||
            # self.transport.write(IPA().id_resp(self.factory.test_id))
 | 
			
		||||
            # instead, than we would have to also call
 | 
			
		||||
            # reactor.callLater(1, self.ack)
 | 
			
		||||
            # instead of self.ack()
 | 
			
		||||
            # otherwise the writes will be glued together - hence the necessity for ugly hack with 1s timeout
 | 
			
		||||
            # Note: this still might work depending on the IPA implementation details on the other side
 | 
			
		||||
            self.ack()
 | 
			
		||||
            # schedule PING in 4s
 | 
			
		||||
            reactor.callLater(4, self.ping)
 | 
			
		||||
        if msgt == IPA.MSGT['PING']:
 | 
			
		||||
            self.pong()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CTRL(IPACommon):
 | 
			
		||||
    """
 | 
			
		||||
    Implementation of Osmocom control protocol for IPA multiplex
 | 
			
		||||
    """
 | 
			
		||||
    def ctrl_SET(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        Handle CTRL SET command
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('CTRL SET [%s] %s' % (op_id, v))
 | 
			
		||||
 | 
			
		||||
    def ctrl_SET_REPLY(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        Handle CTRL SET reply
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('CTRL SET REPLY [%s] %s' % (op_id, v))
 | 
			
		||||
 | 
			
		||||
    def ctrl_GET(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        Handle CTRL GET command
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('CTRL GET [%s] %s' % (op_id, v))
 | 
			
		||||
 | 
			
		||||
    def ctrl_GET_REPLY(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        Handle CTRL GET reply
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('CTRL GET REPLY [%s] %s' % (op_id, v))
 | 
			
		||||
 | 
			
		||||
    def ctrl_TRAP(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        Handle CTRL TRAP command
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('CTRL TRAP [%s] %s' % (op_id, v))
 | 
			
		||||
 | 
			
		||||
    def ctrl_ERROR(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        Handle CTRL ERROR reply
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('CTRL ERROR [%s] %s' % (op_id, v))
 | 
			
		||||
 | 
			
		||||
    def osmo_CTRL(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        OSMO CTRL message dispatcher, lambda default should never happen
 | 
			
		||||
        For basic tests only, appropriate handling routines should be replaced: see CtrlServer for example
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('OSMO CTRL received %s::%s' % Ctrl().parse(data.decode('utf-8')))
 | 
			
		||||
        (cmd, op_id, v) = data.decode('utf-8').split(' ', 2)
 | 
			
		||||
        method = getattr(self, 'ctrl_' + cmd, lambda: "CTRL unknown command")
 | 
			
		||||
        method(data, op_id, v)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IPAServer(CCM):
 | 
			
		||||
    """
 | 
			
		||||
    Test implementation of IPA server
 | 
			
		||||
    Demonstrate CCM opearation by overriding necessary bits from CCM
 | 
			
		||||
    """
 | 
			
		||||
    def connectionMade(self):
 | 
			
		||||
        """
 | 
			
		||||
        Keep reconnection logic working by calling routine from CCM
 | 
			
		||||
        Initiate CCM upon connection
 | 
			
		||||
        """
 | 
			
		||||
        addr = self.transport.getPeer()
 | 
			
		||||
        self.factory.log.info('IPA server: connection from %s:%d client' % (addr.host, addr.port))
 | 
			
		||||
        super(IPAServer, self).connectionMade()
 | 
			
		||||
        self.transport.write(IPA().id_get())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CtrlServer(CTRL):
 | 
			
		||||
    """
 | 
			
		||||
    Test implementation of CTRL server
 | 
			
		||||
    Demonstarte CTRL handling by overriding simpler routines from CTRL
 | 
			
		||||
    """
 | 
			
		||||
    def connectionMade(self):
 | 
			
		||||
        """
 | 
			
		||||
        Keep reconnection logic working by calling routine from CTRL
 | 
			
		||||
        Send TRAP upon connection
 | 
			
		||||
        Note: we can't use sendString() because of it's incompatibility with IPA interpretation of length prefix
 | 
			
		||||
        """
 | 
			
		||||
        addr = self.transport.getPeer()
 | 
			
		||||
        self.factory.log.info('CTRL server: connection from %s:%d client' % (addr.host, addr.port))
 | 
			
		||||
        super(CtrlServer, self).connectionMade()
 | 
			
		||||
        self.transport.write(Ctrl().trap('LOL', 'what'))
 | 
			
		||||
        self.transport.write(Ctrl().trap('rulez', 'XXX'))
 | 
			
		||||
 | 
			
		||||
    def reply(self, r):
 | 
			
		||||
        self.transport.write(Ctrl().add_header(r))
 | 
			
		||||
 | 
			
		||||
    def ctrl_SET(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        CTRL SET command: always succeed
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('SET [%s] %s' % (op_id, v))
 | 
			
		||||
        self.reply('SET_REPLY %s %s' % (op_id, v))
 | 
			
		||||
 | 
			
		||||
    def ctrl_GET(self, data, op_id, v):
 | 
			
		||||
        """
 | 
			
		||||
        CTRL GET command: always fail
 | 
			
		||||
        """
 | 
			
		||||
        self.dbg('GET [%s] %s' % (op_id, v))
 | 
			
		||||
        self.reply('ERROR %s No variable found' % op_id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IPAFactory(ReconnectingClientFactory):
 | 
			
		||||
    """
 | 
			
		||||
    Generic IPA Client Factory which can be used to store state for various subprotocols and manage connections
 | 
			
		||||
    Note: so far we do not really need separate Factory for acting as a server due to protocol simplicity
 | 
			
		||||
    """
 | 
			
		||||
    protocol = IPACommon
 | 
			
		||||
    log = None
 | 
			
		||||
    ccm_id = IPA().identity(unit=b'1515/0/1', mac=b'b0:0b:fa:ce:de:ad:be:ef', utype=b'sysmoBTS', name=b'StingRay', location=b'hell', sw=IPA.version.encode('utf-8'))
 | 
			
		||||
 | 
			
		||||
    def __init__(self, proto=None, log=None, ccm_id=None):
 | 
			
		||||
        if proto:
 | 
			
		||||
            self.protocol = proto
 | 
			
		||||
        if ccm_id:
 | 
			
		||||
            self.ccm_id = ccm_id
 | 
			
		||||
        if log:
 | 
			
		||||
            self.log = log
 | 
			
		||||
        else:
 | 
			
		||||
            self.log = logging.getLogger('IPAFactory')
 | 
			
		||||
            self.log.setLevel(logging.CRITICAL)
 | 
			
		||||
            self.log.addHandler(logging.NullHandler)
 | 
			
		||||
 | 
			
		||||
    def clientConnectionFailed(self, connector, reason):
 | 
			
		||||
        """
 | 
			
		||||
        Only necessary for as debugging aid - if we can somehow set parent's class noisy attribute then we can omit this method
 | 
			
		||||
        """
 | 
			
		||||
        self.log.warning('IPAFactory connection failed: %s' % reason.getErrorMessage())
 | 
			
		||||
        ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
 | 
			
		||||
 | 
			
		||||
    def clientConnectionLost(self, connector, reason):
 | 
			
		||||
        """
 | 
			
		||||
        Only necessary for as debugging aid - if we can somehow set parent's class noisy attribute then we can omit this method
 | 
			
		||||
        """
 | 
			
		||||
        self.log.warning('IPAFactory connection lost: %s' % reason.getErrorMessage())
 | 
			
		||||
        ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    p = argparse.ArgumentParser("Twisted IPA (module v%s) app" % IPA.version)
 | 
			
		||||
    p.add_argument('-v', '--version', action='version', version="%(prog)s v" + __version__)
 | 
			
		||||
    p.add_argument('-p', '--port', type=int, default=4250, help="Port to use for CTRL interface")
 | 
			
		||||
    p.add_argument('-d', '--host', default='localhost', help="Adress to use for CTRL interface")
 | 
			
		||||
    cs = p.add_mutually_exclusive_group()
 | 
			
		||||
    cs.add_argument("-c", "--client", action='store_true', help="asume client role")
 | 
			
		||||
    cs.add_argument("-s", "--server", action='store_true', help="asume server role")
 | 
			
		||||
    ic = p.add_mutually_exclusive_group()
 | 
			
		||||
    ic.add_argument("--ipa", action='store_true', help="use IPA protocol")
 | 
			
		||||
    ic.add_argument("--ctrl", action='store_true', help="use CTRL protocol")
 | 
			
		||||
    args = p.parse_args()
 | 
			
		||||
    test = False
 | 
			
		||||
 | 
			
		||||
    log = logging.getLogger('TwistedIPA')
 | 
			
		||||
    log.setLevel(logging.DEBUG)
 | 
			
		||||
    log.addHandler(logging.StreamHandler(sys.stdout))
 | 
			
		||||
 | 
			
		||||
    if args.ctrl:
 | 
			
		||||
        if args.client:
 | 
			
		||||
            # Start osmo-bsc to receive TRAP messages when osmo-bts-* connects to it
 | 
			
		||||
            print('CTRL client, connecting to %s:%d' % (args.host, args.port))
 | 
			
		||||
            reactor.connectTCP(args.host, args.port, IPAFactory(CTRL, log))
 | 
			
		||||
            test = True
 | 
			
		||||
        if args.server:
 | 
			
		||||
            # Use bsc_control.py to issue set/get commands
 | 
			
		||||
            print('CTRL server, listening on port %d' % args.port)
 | 
			
		||||
            reactor.listenTCP(args.port, IPAFactory(CtrlServer, log))
 | 
			
		||||
            test = True
 | 
			
		||||
    if args.ipa:
 | 
			
		||||
        if args.client:
 | 
			
		||||
            # Start osmo-nitb which would initiate A-bis/IP session
 | 
			
		||||
            print('IPA client, connecting to %s ports %d and %d' % (args.host, IPA.TCP_PORT_OML, IPA.TCP_PORT_RSL))
 | 
			
		||||
            reactor.connectTCP(args.host, IPA.TCP_PORT_OML, IPAFactory(CCM, log))
 | 
			
		||||
            reactor.connectTCP(args.host, IPA.TCP_PORT_RSL, IPAFactory(CCM, log))
 | 
			
		||||
            test = True
 | 
			
		||||
        if args.server:
 | 
			
		||||
            # Start osmo-bts-* which would attempt to connect to us
 | 
			
		||||
            print('IPA server, listening on ports %d and %d' % (IPA.TCP_PORT_OML, IPA.TCP_PORT_RSL))
 | 
			
		||||
            reactor.listenTCP(IPA.TCP_PORT_RSL, IPAFactory(IPAServer, log))
 | 
			
		||||
            reactor.listenTCP(IPA.TCP_PORT_OML, IPAFactory(IPAServer, log))
 | 
			
		||||
            test = True
 | 
			
		||||
    if test:
 | 
			
		||||
        reactor.run()
 | 
			
		||||
    else:
 | 
			
		||||
        print("Please specify which protocol in which role you'd like to test.")
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
SUBDIRS = \
 | 
			
		||||
	examples \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
@@ -31,65 +31,44 @@ GSM 04.08 3.4.13: RR connection release procedure
 | 
			
		||||
 | 
			
		||||
== Implementation in OpenBSC ==
 | 
			
		||||
 | 
			
		||||
There are two possible reasons a gsm_subscriber_connection
 | 
			
		||||
will be released. One is a network failure, the other is
 | 
			
		||||
the completion of an operation/transaction.
 | 
			
		||||
 | 
			
		||||
=== Failure ===
 | 
			
		||||
The BSC API will call the gsm_04_08.c:gsm0408_clear_request callback
 | 
			
		||||
and the MSC part will release all transactions, operations and such
 | 
			
		||||
and the channels will be released as error case.
 | 
			
		||||
 | 
			
		||||
=== Success ===
 | 
			
		||||
Every time an 'operation' or 'transaction' is finished msc_release_connection
 | 
			
		||||
will be called and it will determine if the gsm_subscriber_connection can
 | 
			
		||||
be released.
 | 
			
		||||
 | 
			
		||||
In case it can be released bsc_api.c:gsm0808_clear will be called
 | 
			
		||||
which will release all lchan's associated with the connection. For the
 | 
			
		||||
primary channel a SACH Deactivate will be send with the release
 | 
			
		||||
reason NORMAL RELEASE.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bsc_api.c:gsm0808_clear
 | 
			
		||||
	* Release a channel used for handover
 | 
			
		||||
	* Release the primary lchan with normal release, SACH deactivate
 | 
			
		||||
 | 
			
		||||
chan_alloc.c:lchan_release(chan, sacch_deactivate, reason)
 | 
			
		||||
	* Start the release procedure. It is working in steps with callbacks
 | 
			
		||||
	  coming from the abis_rsl.c code.
 | 
			
		||||
	* Release all SAPI's > 0 as local end (The BTS should send a
 | 
			
		||||
	  REL_CONF a message)
 | 
			
		||||
	* Send SACH Deactivate on SAPI=0 if required.
 | 
			
		||||
	* Start T3109 (stop it when the main signalling link is disconnected)
 | 
			
		||||
	  or when the channel released. On timeout start the error handling.
 | 
			
		||||
	* abis_rsl.c schedules the RSL_MT_RF_CHAN_REL once all SAPI's are
 | 
			
		||||
	  released and after T3111 has timed out or there is an error.
 | 
			
		||||
chan_alloc.c:lchan_auto_release()
 | 
			
		||||
	* checks if use count still > 0 (abort)
 | 
			
		||||
	* calls gsm48_send_rr_release()
 | 
			
		||||
		* which calls rsl_deact_sacch()
 | 
			
		||||
	* calls rsl_release_request()
 | 
			
		||||
		* which sends RLL Link Release request
 | 
			
		||||
	
 | 
			
		||||
RX of RELease INDication:
 | 
			
		||||
        * Calls internal rsl_handle_release which might release the RF.
 | 
			
		||||
	* call rsl_rf_chan_release() (send RF_CHAN_REL)
 | 
			
		||||
 | 
			
		||||
RX of RELease CONFirmation:
 | 
			
		||||
        * Calls internal rsl_handle_release which might release the RF.
 | 
			
		||||
RX of RELease CONFimem:
 | 
			
		||||
	* call rsl_rf_chan_release() (send RF_CHAN_REL)
 | 
			
		||||
 | 
			
		||||
* RX of RF_CHAN_REL_ACK
 | 
			
		||||
	* call lchan_free()
 | 
			
		||||
		* subscr_put()
 | 
			
		||||
		* delete release_timer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
=== Integration with SMS ===
 | 
			
		||||
 | 
			
		||||
* RX of CP_ERROR or unimplemented MT
 | 
			
		||||
	* trigger trans_free() which will msc_release_connection()
 | 
			
		||||
	* trigger trans_free() which will lchan_auto_release()
 | 
			
		||||
 | 
			
		||||
* CP TC1* expired while waiting for CP-ACK
 | 
			
		||||
	* trigger trans_free() which will msc_release_connection()
 | 
			
		||||
	* trigger trans_free() which will lchan_auto_release()
 | 
			
		||||
 | 
			
		||||
* RX of RP_ERROR
 | 
			
		||||
	* trigger trans_free() which will msc_release_connection()
 | 
			
		||||
	* trigger trans_free() which will lchan_auto_release()
 | 
			
		||||
	
 | 
			
		||||
* TX of CP-ACK in MT DELIVER
 | 
			
		||||
	* trigger trans_free() which will msc_release_connection()
 | 
			
		||||
	* trigger trans_free() which will lchan_auto_release()
 | 
			
		||||
 | 
			
		||||
* RX of CP-ACK in MO SUBMIT
 | 
			
		||||
	* trigger trans_free() which will msc_release_connection()
 | 
			
		||||
	* trigger trans_free() which will lchan_auto_release()
 | 
			
		||||
	
 | 
			
		||||
* RX of RP-ACK in MT DELIVER (and no more messages)
 | 
			
		||||
	* trigger rsl_release_request() for SAPI3
 | 
			
		||||
 | 
			
		||||
* RX of RP-SMMA in MT DELIVER (and no more messages)
 | 
			
		||||
	* trigger rsl_release_request() for SAPI3
 | 
			
		||||
 
 | 
			
		||||
@@ -52,10 +52,10 @@ int abis_link_event(int event, void *data);
 | 
			
		||||
	signal some event (such as layer 1 connect/disconnect) from the
 | 
			
		||||
	input core to the stack.
 | 
			
		||||
 | 
			
		||||
int subch_demux_in(mx, const uint8_t *data, int len);
 | 
			
		||||
int subch_demux_in(mx, const u_int8_t *data, int len);
 | 
			
		||||
	receive 'len' bytes from a given E1 timeslot (TRAU frames)
 | 
			
		||||
 | 
			
		||||
int subchan_mux_out(mx, uint8_t *data, int len);
 | 
			
		||||
int subchan_mux_out(mx, u_int8_t *data, int len);
 | 
			
		||||
	obtain 'len' bytes of output data to be sent on E1 timeslot
 | 
			
		||||
 | 
			
		||||
Intrface by Input Core for Input Plugins
 | 
			
		||||
@@ -112,8 +112,8 @@ struct e1inp_sign_link {
 | 
			
		||||
	struct llist_head tx_list;
 | 
			
		||||
 | 
			
		||||
	/* SAPI and TEI on the E1 TS */
 | 
			
		||||
	uint8_t sapi;
 | 
			
		||||
	uint8_t tei;
 | 
			
		||||
	u_int8_t sapi;
 | 
			
		||||
	u_int8_t tei;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum e1inp_ts_type {
 | 
			
		||||
@@ -140,7 +140,7 @@ struct e1inp_ts {
 | 
			
		||||
	union {
 | 
			
		||||
		struct {
 | 
			
		||||
			/* mISDN driver has one fd for each ts */
 | 
			
		||||
			struct osmo_fd;
 | 
			
		||||
			struct bsc_fd;
 | 
			
		||||
		} misdn;
 | 
			
		||||
	} driver;
 | 
			
		||||
};
 | 
			
		||||
@@ -160,7 +160,7 @@ int e1inp_update_ts(struct e1inp_ts *ts);
 | 
			
		||||
 | 
			
		||||
/* Receive a packet from the E1 driver */
 | 
			
		||||
int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
 | 
			
		||||
		uint8_t tei, uint8_t sapi);
 | 
			
		||||
		u_int8_t tei, u_int8_t sapi);
 | 
			
		||||
 | 
			
		||||
/* Send a packet, callback function in the driver */
 | 
			
		||||
int e1driver_tx_ts(struct e1inp_ts *ts, struct msgb *msg)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,'
 | 
			
		||||
 | 
			
		||||
dist-hook:
 | 
			
		||||
	for f in $$($(CFG_FILES)); do \
 | 
			
		||||
		j="$(distdir)/$$f" && \
 | 
			
		||||
		mkdir -p "$$(dirname $$j)" && \
 | 
			
		||||
		$(INSTALL_DATA) $(srcdir)/$$f $$j; \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
install-data-hook:
 | 
			
		||||
	for f in $$($(CFG_FILES)); do \
 | 
			
		||||
		j="$(DESTDIR)$(docdir)/examples/$$f" && \
 | 
			
		||||
		mkdir -p "$$(dirname $$j)" && \
 | 
			
		||||
		$(INSTALL_DATA) $(srcdir)/$$f $$j; \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
uninstall-hook:
 | 
			
		||||
	@$(PRE_UNINSTALL)
 | 
			
		||||
	for f in $$($(CFG_FILES)); do \
 | 
			
		||||
		j="$(DESTDIR)$(docdir)/examples/$$f" && \
 | 
			
		||||
		$(RM) $$j; \
 | 
			
		||||
	done
 | 
			
		||||
@@ -1,106 +0,0 @@
 | 
			
		||||
!
 | 
			
		||||
! OsmoBSC (0.9.14+gitr1+3d331c0062bb0c9694dbd4d1eab7adc58138c3ae) configuration saved from vty
 | 
			
		||||
!!
 | 
			
		||||
password foo
 | 
			
		||||
!
 | 
			
		||||
!
 | 
			
		||||
line vty
 | 
			
		||||
 no login
 | 
			
		||||
!
 | 
			
		||||
e1_input
 | 
			
		||||
 e1_line 0 driver ipa
 | 
			
		||||
network
 | 
			
		||||
 network country code 1
 | 
			
		||||
 mobile network code 1
 | 
			
		||||
 short name OsmoBSC
 | 
			
		||||
 long name OsmoBSC
 | 
			
		||||
 auth policy closed
 | 
			
		||||
 location updating reject cause 13
 | 
			
		||||
 encryption a5 0
 | 
			
		||||
 neci 1
 | 
			
		||||
 paging any use tch 0
 | 
			
		||||
 rrlp mode none
 | 
			
		||||
 mm info 1
 | 
			
		||||
 handover 0
 | 
			
		||||
 handover window rxlev averaging 10
 | 
			
		||||
 handover window rxqual averaging 1
 | 
			
		||||
 handover window rxlev neighbor averaging 10
 | 
			
		||||
 handover power budget interval 6
 | 
			
		||||
 handover power budget hysteresis 3
 | 
			
		||||
 handover maximum distance 9999
 | 
			
		||||
 timer t3101 10
 | 
			
		||||
 timer t3103 0
 | 
			
		||||
 timer t3105 0
 | 
			
		||||
 timer t3107 0
 | 
			
		||||
 timer t3109 0
 | 
			
		||||
 timer t3111 0
 | 
			
		||||
 timer t3113 60
 | 
			
		||||
 timer t3115 0
 | 
			
		||||
 timer t3117 0
 | 
			
		||||
 timer t3119 0
 | 
			
		||||
 timer t3122 0
 | 
			
		||||
 timer t3141 0
 | 
			
		||||
 subscriber-keep-in-ram 0
 | 
			
		||||
 bts 0
 | 
			
		||||
  type nanobts
 | 
			
		||||
  band DCS1800
 | 
			
		||||
  cell_identity 0
 | 
			
		||||
  location_area_code 1
 | 
			
		||||
  training_sequence_code 7
 | 
			
		||||
  base_station_id_code 63
 | 
			
		||||
  ms max power 15
 | 
			
		||||
  cell reselection hysteresis 4
 | 
			
		||||
  rxlev access min 0
 | 
			
		||||
  channel allocator ascending
 | 
			
		||||
  rach tx integer 9
 | 
			
		||||
  rach max transmission 7
 | 
			
		||||
  dtx uplink force
 | 
			
		||||
  dtx downlink
 | 
			
		||||
  ip.access unit_id 0 0
 | 
			
		||||
  oml ip.access stream_id 255 line 0
 | 
			
		||||
  neighbor-list mode manual-si5
 | 
			
		||||
  neighbor-list add arfcn 100
 | 
			
		||||
  neighbor-list add arfcn 200
 | 
			
		||||
  si5 neighbor-list add arfcn 10
 | 
			
		||||
  si5 neighbor-list add arfcn 20
 | 
			
		||||
  gprs mode none
 | 
			
		||||
  trx 0
 | 
			
		||||
   rf_locked 0
 | 
			
		||||
   arfcn 871
 | 
			
		||||
   nominal power 23
 | 
			
		||||
   max_power_red 20
 | 
			
		||||
   rsl e1 tei 0
 | 
			
		||||
   timeslot 0
 | 
			
		||||
    phys_chan_config CCCH+SDCCH4
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
   timeslot 1
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
   timeslot 2
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
   timeslot 3
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
   timeslot 4
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
   timeslot 5
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
   timeslot 6
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
   timeslot 7
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
msc
 | 
			
		||||
 ip.access rtp-base 4000
 | 
			
		||||
 timeout-ping 20
 | 
			
		||||
 timeout-pong 5
 | 
			
		||||
 dest 192.168.100.11 6666 0
 | 
			
		||||
 access-list-name msc-list
 | 
			
		||||
 no access-list-name
 | 
			
		||||
bsc
 | 
			
		||||
 no access-list-name
 | 
			
		||||
 access-list-name bsc-list
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
678012512671923:6:6:
 | 
			
		||||
@@ -1,13 +0,0 @@
 | 
			
		||||
nat
 | 
			
		||||
 bsc 0
 | 
			
		||||
  token lol
 | 
			
		||||
  location_area_code 1234
 | 
			
		||||
  description bsc
 | 
			
		||||
  max-endpoints 32
 | 
			
		||||
  paging forbidden 0
 | 
			
		||||
 bsc 1
 | 
			
		||||
  token wat
 | 
			
		||||
  location_area_code 5678
 | 
			
		||||
  description bsc
 | 
			
		||||
  max-endpoints 32
 | 
			
		||||
  paging forbidden 0
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
!
 | 
			
		||||
! OsmoBSCNAT (0.12.0.266-2daa9) configuration saved from vty
 | 
			
		||||
!!
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
  logging filter all 1
 | 
			
		||||
  logging color 1
 | 
			
		||||
  logging timestamp 0
 | 
			
		||||
  logging level all debug
 | 
			
		||||
  logging level rll notice
 | 
			
		||||
  logging level cc notice
 | 
			
		||||
  logging level mm notice
 | 
			
		||||
  logging level rr notice
 | 
			
		||||
  logging level rsl notice
 | 
			
		||||
  logging level nm info
 | 
			
		||||
  logging level mncc notice
 | 
			
		||||
  logging level pag notice
 | 
			
		||||
  logging level meas notice
 | 
			
		||||
  logging level sccp notice
 | 
			
		||||
  logging level msc notice
 | 
			
		||||
  logging level mgcp notice
 | 
			
		||||
  logging level ho notice
 | 
			
		||||
  logging level db notice
 | 
			
		||||
  logging level ref notice
 | 
			
		||||
  logging level gprs debug
 | 
			
		||||
  logging level ns info
 | 
			
		||||
  logging level bssgp debug
 | 
			
		||||
  logging level llc debug
 | 
			
		||||
  logging level sndcp debug
 | 
			
		||||
  logging level nat notice
 | 
			
		||||
  logging level ctrl notice
 | 
			
		||||
  logging level smpp debug
 | 
			
		||||
  logging level lglobal notice
 | 
			
		||||
  logging level llapd notice
 | 
			
		||||
  logging level linp notice
 | 
			
		||||
  logging level lmux notice
 | 
			
		||||
  logging level lmi notice
 | 
			
		||||
  logging level lmib notice
 | 
			
		||||
  logging level lsms notice
 | 
			
		||||
!
 | 
			
		||||
line vty
 | 
			
		||||
 no login
 | 
			
		||||
!
 | 
			
		||||
mgcp
 | 
			
		||||
  bind ip 0.0.0.0
 | 
			
		||||
  bind port 2427
 | 
			
		||||
  rtp bts-base 4000
 | 
			
		||||
  rtp net-base 16000
 | 
			
		||||
  rtp ip-dscp 0
 | 
			
		||||
  no rtcp-omit
 | 
			
		||||
  sdp audio-payload number 126
 | 
			
		||||
  sdp audio-payload name AMR/8000
 | 
			
		||||
  loop 0
 | 
			
		||||
  number endpoints 1
 | 
			
		||||
  call-agent ip 127.0.0.1
 | 
			
		||||
  rtp transcoder-base 0
 | 
			
		||||
  transcoder-remote-base 4000
 | 
			
		||||
nat
 | 
			
		||||
 msc ip 127.0.0.1
 | 
			
		||||
 msc port 5000
 | 
			
		||||
 timeout auth 2
 | 
			
		||||
 timeout ping 20
 | 
			
		||||
 timeout pong 5
 | 
			
		||||
 ip-dscp 0
 | 
			
		||||
 bscs-config-file bscs.config
 | 
			
		||||
 access-list bla imsi-allow ^11$
 | 
			
		||||
@@ -1,44 +0,0 @@
 | 
			
		||||
!
 | 
			
		||||
! OsmoGbProxy (UNKNOWN) configuration saved from vty
 | 
			
		||||
!!
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
  logging filter all 1
 | 
			
		||||
  logging color 1
 | 
			
		||||
  logging timestamp 0
 | 
			
		||||
  logging level all debug
 | 
			
		||||
  logging level gprs debug
 | 
			
		||||
  logging level ns info
 | 
			
		||||
  logging level bssgp debug
 | 
			
		||||
  logging level lglobal notice
 | 
			
		||||
  logging level llapd notice
 | 
			
		||||
  logging level linp notice
 | 
			
		||||
  logging level lmux notice
 | 
			
		||||
  logging level lmi notice
 | 
			
		||||
  logging level lmib notice
 | 
			
		||||
  logging level lsms notice
 | 
			
		||||
!
 | 
			
		||||
line vty
 | 
			
		||||
 no login
 | 
			
		||||
!
 | 
			
		||||
ns
 | 
			
		||||
 nse 666 nsvci 666
 | 
			
		||||
 nse 666 remote-role sgsn
 | 
			
		||||
! nse 666 encapsulation framerelay-gre
 | 
			
		||||
! nse 666 remote-ip 172.16.1.70
 | 
			
		||||
! nse 666 fr-dlci 666
 | 
			
		||||
 timer tns-block 3
 | 
			
		||||
 timer tns-block-retries 3
 | 
			
		||||
 timer tns-reset 3
 | 
			
		||||
 timer tns-reset-retries 3
 | 
			
		||||
 timer tns-test 30
 | 
			
		||||
 timer tns-alive 3
 | 
			
		||||
 timer tns-alive-retries 10
 | 
			
		||||
 encapsulation udp local-port 23000
 | 
			
		||||
! encapsulation framerelay-gre enabled 1
 | 
			
		||||
gbproxy
 | 
			
		||||
 sgsn nsei 666
 | 
			
		||||
 core-mobile-country-code 666
 | 
			
		||||
 core-mobile-network-code 6
 | 
			
		||||
 core-access-point-name none match-imsi ^666066|^66607
 | 
			
		||||
 tlli-list max-length 200
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
!
 | 
			
		||||
! Osmocom Gb Proxy (0.9.0.404-6463) configuration saved from vty
 | 
			
		||||
!!
 | 
			
		||||
!
 | 
			
		||||
line vty
 | 
			
		||||
 no login
 | 
			
		||||
!
 | 
			
		||||
gbproxy
 | 
			
		||||
 sgsn nsei 101
 | 
			
		||||
ns
 | 
			
		||||
 nse 101 nsvci 101
 | 
			
		||||
 nse 101 remote-role sgsn
 | 
			
		||||
 nse 101 encapsulation udp
 | 
			
		||||
 nse 101 remote-ip 192.168.100.239
 | 
			
		||||
 nse 101 remote-port 7777
 | 
			
		||||
 timer tns-block 3
 | 
			
		||||
 timer tns-block-retries 3
 | 
			
		||||
 timer tns-reset 3
 | 
			
		||||
 timer tns-reset-retries 3
 | 
			
		||||
 timer tns-test 30
 | 
			
		||||
 timer tns-alive 3
 | 
			
		||||
 timer tns-alive-retries 10
 | 
			
		||||
 encapsulation framerelay-gre enabled 0
 | 
			
		||||
 encapsulation framerelay-gre local-ip 0.0.0.0
 | 
			
		||||
 encapsulation udp local-port 23000
 | 
			
		||||
@@ -1,90 +0,0 @@
 | 
			
		||||
Here is a simple setup to test GTPHub operations. The IP addresses picked will
 | 
			
		||||
work well only on a system that creates local addresses (127.0.0.123) on the
 | 
			
		||||
fly (like linux) -- you may pick of course different IP addresses.
 | 
			
		||||
 | 
			
		||||
Overview of the example setup:
 | 
			
		||||
 | 
			
		||||
    sgsnemu               gtphub             ggsn
 | 
			
		||||
    127.0.0.1 <--> 127.0.0.3  127.0.0.4 <--> 127.0.0.2
 | 
			
		||||
 | 
			
		||||
Prerequisites: openggsn.
 | 
			
		||||
 | 
			
		||||
Have a local directory where you store config files and from which you launch
 | 
			
		||||
the GSNs and the hub (they will store restart counter files in that dir).
 | 
			
		||||
In it, have these config files:
 | 
			
		||||
 | 
			
		||||
ggsn.conf:
 | 
			
		||||
 | 
			
		||||
    # GGSN local address
 | 
			
		||||
    listen 127.0.0.2
 | 
			
		||||
 | 
			
		||||
    # End User Addresses are picked from this range
 | 
			
		||||
    net 10.23.42.0/24
 | 
			
		||||
 | 
			
		||||
    pcodns1 8.8.8.8
 | 
			
		||||
 | 
			
		||||
    logfile /tmp/foo
 | 
			
		||||
 | 
			
		||||
gtphub.conf:
 | 
			
		||||
 | 
			
		||||
    gtphub
 | 
			
		||||
     bind-to-sgsns 127.0.0.3
 | 
			
		||||
     bind-to-ggsns 127.0.0.4
 | 
			
		||||
     ggsn-proxy 127.0.0.2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(
 | 
			
		||||
You may omit the ggsn-proxy if GRX ares is working, or if you add the GRX
 | 
			
		||||
address and GGSN IP address to /etc/hosts something like:
 | 
			
		||||
 | 
			
		||||
    127.0.0.2 internet.mnc070.mcc901.gprs
 | 
			
		||||
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Once the config files are in place, start the programs, in separate terminals.
 | 
			
		||||
GGSN and SGSN need to be started with root priviliges to be able to create tun
 | 
			
		||||
interfaces. GTPHub may run as unprivileged user.
 | 
			
		||||
 | 
			
		||||
The LD_LIBRARY_PATH below may be needed if OpenGGSN installed to /usr/local.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
1. GGSN:
 | 
			
		||||
 | 
			
		||||
    sudo -s
 | 
			
		||||
    cd <your-test-dir>
 | 
			
		||||
    LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/ggsn -f -c ./ggsn.conf
 | 
			
		||||
 | 
			
		||||
2. GTPHub:
 | 
			
		||||
 | 
			
		||||
    cd <your-test-dir>
 | 
			
		||||
    path/to/openbsc/openbsc/src/gprs/osmo-gtphub -c gtphub.conf #-e 1 #for DEBUG level
 | 
			
		||||
 | 
			
		||||
3. SGSN tests:
 | 
			
		||||
 | 
			
		||||
    sudo -s
 | 
			
		||||
    cd <your-test-dir>
 | 
			
		||||
    /usr/local/bin/sgsnemu --createif -l 127.0.0.1 -r 127.0.0.3 --imsi 420001214365100 --contexts=3
 | 
			
		||||
 | 
			
		||||
Add more SGSNs using different IMSIs and local ports (if the same IMSI is used,
 | 
			
		||||
the GGSN will reuse TEIs and tunnels will be discarded automatically):
 | 
			
		||||
 | 
			
		||||
    /usr/local/bin/sgsnemu --createif -l 127.0.0.11 -r 127.0.0.3 --imsi 420001214365300 --contexts=3
 | 
			
		||||
 | 
			
		||||
This shows the basic setup of GTPHub. Testing internet traffic via sgsnemu
 | 
			
		||||
still needs some effort to announce a mobile subscriber or the like (I have
 | 
			
		||||
used a real BTS, osmo-sgsn and a testing SIM in a web phone, instead).
 | 
			
		||||
 | 
			
		||||
The core capability of GTPHub is to manage more than two GSNs, e.g. an SGSN
 | 
			
		||||
contacting various GGSNs over the single GTPHub link. You would configure the
 | 
			
		||||
SGSN to use one fixed GGSN (sending to gtphub) and gtphub will resolve the
 | 
			
		||||
GGSNs once it has received the messages. So the SGSN may be behind NAT (add
 | 
			
		||||
"sgsn-use-sender" to gtphub.conf) and communicate to various GGSNs over a
 | 
			
		||||
single link to gtphub.
 | 
			
		||||
 | 
			
		||||
I hope this helps to get you going.
 | 
			
		||||
Any suggestions/patches are welcome!
 | 
			
		||||
 | 
			
		||||
~Neels
 | 
			
		||||
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
!
 | 
			
		||||
! Osmocom gtphub configuration
 | 
			
		||||
!
 | 
			
		||||
! This file is used for VTY tests, referenced by openbsc/osmoappdesc.py
 | 
			
		||||
! For the test, try to use most config commands.
 | 
			
		||||
!
 | 
			
		||||
 | 
			
		||||
line vty
 | 
			
		||||
 no login
 | 
			
		||||
 | 
			
		||||
gtphub
 | 
			
		||||
 ! Local addresses to listen on and send from, both on one interface.
 | 
			
		||||
 ! The side towards SGSN uses nonstandard ports.
 | 
			
		||||
 bind-to-sgsns ctrl 127.0.0.1 12123 user 127.0.0.1 12153
 | 
			
		||||
 ! The GGSN side with standard ports.
 | 
			
		||||
 bind-to-ggsns 127.0.0.1
 | 
			
		||||
 | 
			
		||||
 ! Proxy: unconditionally direct all traffic to...
 | 
			
		||||
 sgsn-proxy 127.0.0.4
 | 
			
		||||
 | 
			
		||||
 ! Proxy with nonstandard ports or separate IPs:
 | 
			
		||||
 ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152
 | 
			
		||||
 | 
			
		||||
 ! Add a name server for GGSN resolution
 | 
			
		||||
 grx-dns-add 192.168.0.1
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
!
 | 
			
		||||
! Osmocom gtphub configuration
 | 
			
		||||
!
 | 
			
		||||
 | 
			
		||||
line vty
 | 
			
		||||
 no login
 | 
			
		||||
 | 
			
		||||
gtphub
 | 
			
		||||
 ! Local addresses to listen on and send from, each on standard ports
 | 
			
		||||
 ! 2123 and 2152. Setting these addresses is mandatory.
 | 
			
		||||
 bind-to-sgsns 127.0.0.1
 | 
			
		||||
 bind-to-ggsns 127.0.0.2
 | 
			
		||||
 | 
			
		||||
 ! Local nonstandard ports or separate IPs:
 | 
			
		||||
 !bind-to-sgsns ctrl 127.0.0.1 2342 user 127.0.0.1 4223
 | 
			
		||||
 | 
			
		||||
 ! Proxy: unconditionally direct all traffic to...
 | 
			
		||||
 !ggsn-proxy 127.0.0.3
 | 
			
		||||
 !sgsn-proxy 127.0.0.4
 | 
			
		||||
 | 
			
		||||
 ! Proxy with nonstandard ports or separate IPs:
 | 
			
		||||
 !ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152
 | 
			
		||||
 | 
			
		||||
 ! Add a name server for GGSN resolution
 | 
			
		||||
 !grx-dns-add 192.168.0.1
 | 
			
		||||
@@ -1,164 +0,0 @@
 | 
			
		||||
!
 | 
			
		||||
! OpenBSC (0.9.0.845-57c4) configuration saved from vty
 | 
			
		||||
!!
 | 
			
		||||
password foo
 | 
			
		||||
!
 | 
			
		||||
line vty
 | 
			
		||||
 no login
 | 
			
		||||
!
 | 
			
		||||
e1_input
 | 
			
		||||
 e1_line 0 driver misdn
 | 
			
		||||
network
 | 
			
		||||
 network country code 1
 | 
			
		||||
 mobile network code 1
 | 
			
		||||
 short name OpenBSC
 | 
			
		||||
 long name OpenBSC
 | 
			
		||||
 auth policy closed
 | 
			
		||||
 location updating reject cause 13
 | 
			
		||||
 encryption a5 0
 | 
			
		||||
 neci 1
 | 
			
		||||
 rrlp mode none
 | 
			
		||||
 mm info 0
 | 
			
		||||
 handover 0
 | 
			
		||||
 handover window rxlev averaging 10
 | 
			
		||||
 handover window rxqual averaging 1
 | 
			
		||||
 handover window rxlev neighbor averaging 10
 | 
			
		||||
 handover power budget interval 6
 | 
			
		||||
 handover power budget hysteresis 3
 | 
			
		||||
 handover maximum distance 9999
 | 
			
		||||
 timer t3101 10
 | 
			
		||||
 timer t3103 0
 | 
			
		||||
 timer t3105 0
 | 
			
		||||
 timer t3107 0
 | 
			
		||||
 timer t3109 4
 | 
			
		||||
 timer t3111 0
 | 
			
		||||
 timer t3113 60
 | 
			
		||||
 timer t3115 0
 | 
			
		||||
 timer t3117 0
 | 
			
		||||
 timer t3119 0
 | 
			
		||||
 timer t3141 0
 | 
			
		||||
 bts 0
 | 
			
		||||
  type bs11
 | 
			
		||||
  band GSM900
 | 
			
		||||
  cell_identity 0
 | 
			
		||||
  location_area_code 1
 | 
			
		||||
  training_sequence_code 7
 | 
			
		||||
  base_station_id_code 63
 | 
			
		||||
  ms max power 15
 | 
			
		||||
  cell reselection hysteresis 4
 | 
			
		||||
  rxlev access min 0
 | 
			
		||||
  channel allocator descending
 | 
			
		||||
  rach tx integer 9
 | 
			
		||||
  rach max transmission 7
 | 
			
		||||
  oml e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
  oml e1 tei 25
 | 
			
		||||
  gprs mode none
 | 
			
		||||
  trx 0
 | 
			
		||||
   rf_locked 0
 | 
			
		||||
   arfcn 121
 | 
			
		||||
   nominal power 24
 | 
			
		||||
   max_power_red 12
 | 
			
		||||
   rsl e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
   rsl e1 tei 1
 | 
			
		||||
   timeslot 0
 | 
			
		||||
    phys_chan_config CCCH
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
    e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
   timeslot 1
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
    e1 line 0 timeslot 2 sub-slot 1
 | 
			
		||||
   timeslot 2
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
    e1 line 0 timeslot 2 sub-slot 2
 | 
			
		||||
   timeslot 3
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
    e1 line 0 timeslot 2 sub-slot 3
 | 
			
		||||
   timeslot 4
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 0
 | 
			
		||||
   timeslot 5
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 1
 | 
			
		||||
   timeslot 6
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 2
 | 
			
		||||
   timeslot 7
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 0
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 3
 | 
			
		||||
  trx 1
 | 
			
		||||
   rf_locked 0
 | 
			
		||||
   arfcn 119
 | 
			
		||||
   nominal power 24
 | 
			
		||||
   max_power_red 12
 | 
			
		||||
   rsl e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
   rsl e1 tei 2
 | 
			
		||||
   timeslot 0
 | 
			
		||||
    phys_chan_config SDCCH8
 | 
			
		||||
    hopping enabled 1
 | 
			
		||||
    hopping sequence-number 0
 | 
			
		||||
    hopping maio 0
 | 
			
		||||
    hopping arfcn add 117
 | 
			
		||||
    hopping arfcn add 119
 | 
			
		||||
   timeslot 1
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 1
 | 
			
		||||
    hopping sequence-number 0
 | 
			
		||||
    hopping maio 0
 | 
			
		||||
    hopping arfcn add 117
 | 
			
		||||
    hopping arfcn add 119
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 1
 | 
			
		||||
   timeslot 2
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 1
 | 
			
		||||
    hopping sequence-number 0
 | 
			
		||||
    hopping maio 0
 | 
			
		||||
    hopping arfcn add 117
 | 
			
		||||
    hopping arfcn add 119
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 2
 | 
			
		||||
   timeslot 3
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 1
 | 
			
		||||
    hopping sequence-number 0
 | 
			
		||||
    hopping maio 0
 | 
			
		||||
    hopping arfcn add 117
 | 
			
		||||
    hopping arfcn add 119
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 3
 | 
			
		||||
   timeslot 4
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 1
 | 
			
		||||
    hopping sequence-number 0
 | 
			
		||||
    hopping maio 0
 | 
			
		||||
    hopping arfcn add 117
 | 
			
		||||
    hopping arfcn add 119
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 0
 | 
			
		||||
   timeslot 5
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 1
 | 
			
		||||
    hopping sequence-number 0
 | 
			
		||||
    hopping maio 0
 | 
			
		||||
    hopping arfcn add 117
 | 
			
		||||
    hopping arfcn add 119
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 1
 | 
			
		||||
   timeslot 6
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 1
 | 
			
		||||
    hopping sequence-number 0
 | 
			
		||||
    hopping maio 0
 | 
			
		||||
    hopping arfcn add 117
 | 
			
		||||
    hopping arfcn add 119
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 2
 | 
			
		||||
   timeslot 7
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    hopping enabled 1
 | 
			
		||||
    hopping sequence-number 0
 | 
			
		||||
    hopping maio 0
 | 
			
		||||
    hopping arfcn add 117
 | 
			
		||||
    hopping arfcn add 119
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 3
 | 
			
		||||
@@ -1,84 +0,0 @@
 | 
			
		||||
!
 | 
			
		||||
! OpenBSC configuration saved from vty
 | 
			
		||||
!   !
 | 
			
		||||
password foo
 | 
			
		||||
!
 | 
			
		||||
line vty
 | 
			
		||||
 no login
 | 
			
		||||
!
 | 
			
		||||
e1_input
 | 
			
		||||
 e1_line 0 driver misdn
 | 
			
		||||
network
 | 
			
		||||
 network country code 1
 | 
			
		||||
 mobile network code 1
 | 
			
		||||
 short name OpenBSC
 | 
			
		||||
 long name OpenBSC
 | 
			
		||||
 timer t3101 10
 | 
			
		||||
 timer t3113 60
 | 
			
		||||
 bts 0
 | 
			
		||||
  type bs11
 | 
			
		||||
  band GSM900
 | 
			
		||||
  cell_identity 1
 | 
			
		||||
  location_area_code 1
 | 
			
		||||
  training_sequence_code 7
 | 
			
		||||
  base_station_id_code 63
 | 
			
		||||
  oml e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
  oml e1 tei 25
 | 
			
		||||
  trx 0
 | 
			
		||||
   arfcn 121
 | 
			
		||||
   max_power_red 0
 | 
			
		||||
   rsl e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
   rsl e1 tei 1
 | 
			
		||||
   timeslot 0
 | 
			
		||||
    phys_chan_config CCCH+SDCCH4
 | 
			
		||||
    e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
   timeslot 1
 | 
			
		||||
    phys_chan_config SDCCH8
 | 
			
		||||
    e1 line 0 timeslot 2 sub-slot 1
 | 
			
		||||
   timeslot 2
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 2 sub-slot 2
 | 
			
		||||
   timeslot 3
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 2 sub-slot 3
 | 
			
		||||
   timeslot 4
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 0
 | 
			
		||||
   timeslot 5
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 1
 | 
			
		||||
   timeslot 6
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 2
 | 
			
		||||
   timeslot 7
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 3
 | 
			
		||||
  trx 1
 | 
			
		||||
   arfcn 123
 | 
			
		||||
   max_power_red 0
 | 
			
		||||
   rsl e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
   rsl e1 tei 2
 | 
			
		||||
   timeslot 0
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 0
 | 
			
		||||
   timeslot 1
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 1
 | 
			
		||||
   timeslot 2
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 2
 | 
			
		||||
   timeslot 3
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 3
 | 
			
		||||
   timeslot 4
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 0
 | 
			
		||||
   timeslot 5
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 1
 | 
			
		||||
   timeslot 6
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 2
 | 
			
		||||
   timeslot 7
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 3
 | 
			
		||||
@@ -1,148 +0,0 @@
 | 
			
		||||
!
 | 
			
		||||
! OpenBSC configuration saved from vty
 | 
			
		||||
!   !
 | 
			
		||||
password foo
 | 
			
		||||
!
 | 
			
		||||
line vty
 | 
			
		||||
 no login
 | 
			
		||||
!
 | 
			
		||||
network
 | 
			
		||||
 network country code 1
 | 
			
		||||
 mobile network code 1
 | 
			
		||||
 short name OpenBSC
 | 
			
		||||
 long name OpenBSC
 | 
			
		||||
 timer t3101 10
 | 
			
		||||
 timer t3113 60
 | 
			
		||||
 bts 0
 | 
			
		||||
  type bs11
 | 
			
		||||
  band GSM900
 | 
			
		||||
  cell_identity 1
 | 
			
		||||
  location_area_code 1
 | 
			
		||||
  training_sequence_code 7
 | 
			
		||||
  base_station_id_code 63
 | 
			
		||||
  oml e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
  oml e1 tei 25
 | 
			
		||||
  trx 0
 | 
			
		||||
   arfcn 121
 | 
			
		||||
   max_power_red 0
 | 
			
		||||
   rsl e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
   rsl e1 tei 1
 | 
			
		||||
   timeslot 0
 | 
			
		||||
    phys_chan_config CCCH+SDCCH4
 | 
			
		||||
    e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
   timeslot 1
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 2 sub-slot 1
 | 
			
		||||
   timeslot 2
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 2 sub-slot 2
 | 
			
		||||
   timeslot 3
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 2 sub-slot 3
 | 
			
		||||
   timeslot 4
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 0
 | 
			
		||||
   timeslot 5
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 1
 | 
			
		||||
   timeslot 6
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 2
 | 
			
		||||
   timeslot 7
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 3 sub-slot 3
 | 
			
		||||
  trx 1
 | 
			
		||||
   arfcn 123
 | 
			
		||||
   max_power_red 0
 | 
			
		||||
   rsl e1 line 0 timeslot 1 sub-slot full
 | 
			
		||||
   rsl e1 tei 2
 | 
			
		||||
   timeslot 0
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 0
 | 
			
		||||
   timeslot 1
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 1
 | 
			
		||||
   timeslot 2
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 2
 | 
			
		||||
   timeslot 3
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 4 sub-slot 3
 | 
			
		||||
   timeslot 4
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 0
 | 
			
		||||
   timeslot 5
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 1
 | 
			
		||||
   timeslot 6
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 2
 | 
			
		||||
   timeslot 7
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 0 timeslot 5 sub-slot 3
 | 
			
		||||
 bts 1
 | 
			
		||||
  type bs11
 | 
			
		||||
  band GSM900
 | 
			
		||||
  location_area_code 2
 | 
			
		||||
  training_sequence_code 7
 | 
			
		||||
  base_station_id_code 63
 | 
			
		||||
  oml e1 line 1 timeslot 6 sub-slot full
 | 
			
		||||
  oml e1 tei 25
 | 
			
		||||
  trx 0
 | 
			
		||||
   arfcn 122
 | 
			
		||||
   max_power_red 0
 | 
			
		||||
   rsl e1 line 1 timeslot 6 sub-slot full
 | 
			
		||||
   rsl e1 tei 1
 | 
			
		||||
   timeslot 0
 | 
			
		||||
    phys_chan_config CCCH+SDCCH4
 | 
			
		||||
    e1 line 1 timeslot 7 sub-slot 0
 | 
			
		||||
   timeslot 1
 | 
			
		||||
    phys_chan_config SDCCH8
 | 
			
		||||
    e1 line 1 timeslot 7 sub-slot 1
 | 
			
		||||
   timeslot 2
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 7 sub-slot 2
 | 
			
		||||
   timeslot 3
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 7 sub-slot 3
 | 
			
		||||
   timeslot 4
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 8 sub-slot 0
 | 
			
		||||
   timeslot 5
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 8 sub-slot 1
 | 
			
		||||
   timeslot 6
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 8 sub-slot 2
 | 
			
		||||
   timeslot 7
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 8 sub-slot 3
 | 
			
		||||
  trx 1
 | 
			
		||||
   arfcn 124
 | 
			
		||||
   max_power_red 0
 | 
			
		||||
   rsl e1 line 1 timeslot 6 sub-slot full
 | 
			
		||||
   rsl e1 tei 2
 | 
			
		||||
   timeslot 0
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 9 sub-slot 0
 | 
			
		||||
   timeslot 1
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 9 sub-slot 1
 | 
			
		||||
   timeslot 2
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 9 sub-slot 2
 | 
			
		||||
   timeslot 3
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 9 sub-slot 3
 | 
			
		||||
   timeslot 4
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 10 sub-slot 0
 | 
			
		||||
   timeslot 5
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 10 sub-slot 1
 | 
			
		||||
   timeslot 6
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 10 sub-slot 2
 | 
			
		||||
   timeslot 7
 | 
			
		||||
    phys_chan_config TCH/F
 | 
			
		||||
    e1 line 1 timeslot 10 sub-slot 3
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user