mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-10-31 12:03:50 +00:00 
			
		
		
		
	Compare commits
	
		
			317 Commits
		
	
	
		
			1.0.1
			...
			on-waves/0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8deab8cdee | ||
|  | a54f9e81c8 | ||
|  | ed4390747f | ||
|  | 242d098d32 | ||
|  | f795164f04 | ||
|  | b6c6d43daa | ||
|  | 82df124c8e | ||
|  | 189587f428 | ||
|  | 45ab581f37 | ||
|  | f48776ea6a | ||
|  | 7fc17cff64 | ||
|  | a5a7075fe5 | ||
|  | 2b4e366083 | ||
|  | bf1eb64b02 | ||
|  | f0fbae94ea | ||
|  | 8fe4df503c | ||
|  | 8da7103070 | ||
|  | f73f6fad8c | ||
|  | 25cb84be12 | ||
|  | d9ae25c1bf | ||
|  | 5c011366c9 | ||
|  | 79e2d4230d | ||
|  | 8ecd029b12 | ||
|  | 3c0508e94a | ||
|  | f535aad612 | ||
|  | d0ac8866f1 | ||
|  | 73f9a65f12 | ||
|  | b2c55c49a8 | ||
|  | 8dc241959c | ||
|  | f99709430a | ||
|  | b9bc45b1b0 | ||
|  | 65d10c1320 | ||
|  | 414ba77f75 | ||
|  | 59f2470650 | ||
|  | 339dfdb624 | ||
|  | 9e2e2e04d1 | ||
|  | 2ab6db0153 | ||
|  | 6cb97bdebe | ||
|  | 8c3694a282 | ||
|  | 191d23a889 | ||
|  | a5963097ac | ||
|  | 221fb37518 | ||
|  | 4ec8a390cc | ||
|  | cf3f1c8b3d | ||
|  | 984f3b8047 | ||
|  | ec1f15d513 | ||
|  | b76cd5ed7e | ||
|  | 1592550d98 | ||
|  | 5cdf42b1a4 | ||
|  | 3a6b1a41fb | ||
|  | 1b5b3bbfdb | ||
|  | 3a67035411 | ||
|  | cb1937a4c5 | ||
|  | 3cfd5d6a02 | ||
|  | 6cc4dbfd46 | ||
|  | 9960d59fff | ||
|  | 161bd6d253 | ||
|  | add3472e9f | ||
|  | 33b0bee457 | ||
|  | 6949db1bd8 | ||
|  | 8ae0080e21 | ||
|  | 546c296c4a | ||
|  | 86f42eb6a5 | ||
|  | 494c086dca | ||
|  | 6b18c8f3b6 | ||
|  | 87f6d26c2e | ||
|  | fab2ff34c4 | ||
|  | 06d353e02e | ||
|  | dfe47549c6 | ||
|  | c70e8c2103 | ||
|  | b462a03c35 | ||
|  | 6e0ec5b6fa | ||
|  | 6768387f16 | ||
|  | 5ef1234dd3 | ||
|  | 581e58d166 | ||
|  | e308bb466a | ||
|  | e4be5394ef | ||
|  | 81e1edd3e6 | ||
|  | cfd1c28604 | ||
|  | 3ba8963a1d | ||
|  | 238d156481 | ||
|  | 516c4f073a | ||
|  | fa22aa6bbd | ||
|  | 4072ceed32 | ||
|  | cf6bf63a0d | ||
|  | 88b614110f | ||
|  | d9b825a5f5 | ||
|  | b91e5f1da4 | ||
|  | 07bb509434 | ||
|  | 08db6ca509 | ||
|  | 6446ded81c | ||
|  | 7b8f6064d6 | ||
|  | c6a1fe773d | ||
|  | 729d468fdf | ||
|  | b37ce4c5a4 | ||
|  | 5cd62c0ba5 | ||
|  | 1e1acafafd | ||
|  | fb83b7a86d | ||
|  | ef0b641f63 | ||
|  | 27e0bfd3c7 | ||
|  | bbfff6ec39 | ||
|  | dc0914df09 | ||
|  | 0db691dcf6 | ||
|  | bb45b73b20 | ||
|  | 5f5c1b6bcb | ||
|  | e51cf4f946 | ||
|  | 749ba7f5ad | ||
|  | 860c8955c3 | ||
|  | c33701c4e5 | ||
|  | 44d92b4728 | ||
|  | 8aaec620da | ||
|  | a5a4014d67 | ||
|  | 9d519189ae | ||
|  | f0fc618782 | ||
|  | c57575bea8 | ||
|  | 8cdfe9fc37 | ||
|  | 0959f8cbe6 | ||
|  | f21028985e | ||
|  | 483b768ab2 | ||
|  | 82cb311c4f | ||
|  | 2980442e33 | ||
|  | fa7afb31e9 | ||
|  | 7513b3a1c2 | ||
|  | 135d99b36e | ||
|  | 5aaf7c164c | ||
|  | 790db1e01b | ||
|  | 81a8975662 | ||
|  | fd876b7488 | ||
|  | 2ffe7aa340 | ||
|  | 538ea6d5c6 | ||
|  | e14ec0dab4 | ||
|  | 8252b9b947 | ||
|  | 9fb88021dd | ||
|  | b031d6ecae | ||
|  | fcfdde5390 | ||
|  | 571ba8e4da | ||
|  | bed6234e26 | ||
|  | 9d24578812 | ||
|  | a087c4e75d | ||
|  | 6b64b26d8b | ||
|  | 22252a98e3 | ||
|  | 957bc93244 | ||
|  | 18bbe2e8a0 | ||
|  | 1b17913cbc | ||
|  | ce2a36840d | ||
|  | 0e09feccb0 | ||
|  | 40a1de699a | ||
|  | d906a366c8 | ||
|  | d44d4c8c8b | ||
|  | af0e1d7a85 | ||
|  | d21b4d7f98 | ||
|  | 3bdaa69fb2 | ||
|  | 5c0132882a | ||
|  | ed443e949e | ||
|  | 1df69f3c64 | ||
|  | d7cafafeee | ||
|  | e09348d366 | ||
|  | 5f1b7c14f5 | ||
|  | 5b3e9198f0 | ||
|  | f0b21dfd25 | ||
|  | e165d1aaa4 | ||
|  | 649496eb57 | ||
|  | 135a45c833 | ||
|  | 1a3d9dbabf | ||
|  | a91d15df7e | ||
|  | 3368e2a3d1 | ||
|  | 929d788e21 | ||
|  | 6958065f85 | ||
|  | 097c82b2bc | ||
|  | abaeb3f55f | ||
|  | f42e29c79c | ||
|  | 3177580cc1 | ||
|  | cbe77e1657 | ||
|  | 3cedc4738f | ||
|  | 0834fd9b85 | ||
|  | 7b65c986eb | ||
|  | 17d751531e | ||
|  | facb5cdfc2 | ||
|  | aebea482f5 | ||
|  | 12f20d369c | ||
|  | 2008d3f54c | ||
|  | a26ebe40f5 | ||
|  | a52f1cacb3 | ||
|  | f5e71415a2 | ||
|  | 82a8d6e393 | ||
|  | 1226c93937 | ||
|  | b9c520f9b3 | ||
|  | 8a7ca57d3e | ||
|  | 29f9f9fc79 | ||
|  | d512e454b3 | ||
|  | 22481bf76d | ||
|  | b973955295 | ||
|  | 9d51a36528 | ||
|  | ba3bbe55c1 | ||
|  | 0619478073 | ||
|  | f8f184edab | ||
|  | d838951302 | ||
|  | f8e1b45a78 | ||
|  | dd2c9fdbcf | ||
|  | 9991421cfb | ||
|  | e30f0e1c75 | ||
|  | 18598ff66d | ||
|  | 8882c9e3a8 | ||
|  | fdc64f6806 | ||
|  | 16b331d14f | ||
|  | ab46372e2a | ||
|  | be807e4250 | ||
|  | 71ddbf5c4f | ||
|  | 63bb29fac0 | ||
|  | 04b4f915a7 | ||
|  | 4d95ab2231 | ||
|  | 17944f7285 | ||
|  | d2964b6cd1 | ||
|  | 1ce5d7c8b7 | ||
|  | 846457b10a | ||
|  | e7b9771c4d | ||
|  | d709900efa | ||
|  | 55b4f5cc2e | ||
|  | 1ac5ac75a9 | ||
|  | 5cf38ed1ab | ||
|  | 35d1531089 | ||
|  | 47e3777caa | ||
|  | 710f3c615c | ||
|  | 3111560e8a | ||
|  | 7396afbba4 | ||
|  | 52a72e217e | ||
|  | 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) | ||||
							
								
								
									
										25
									
								
								libosmocore/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								libosmocore/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| Makefile | ||||
| Makefile.in | ||||
| .deps | ||||
| .libs | ||||
| *.o | ||||
| *.lo | ||||
| *.la | ||||
| *.pc | ||||
| aclocal.m4 | ||||
| autom4te.cache | ||||
| config.h* | ||||
| config.sub | ||||
| config.log | ||||
| config.status | ||||
| config.guess | ||||
| configure | ||||
| depcomp | ||||
| missing | ||||
| ltmain.sh | ||||
| install-sh | ||||
| stamp-h1 | ||||
| libtool | ||||
|  | ||||
| .tarball-version | ||||
| .version | ||||
							
								
								
									
										339
									
								
								libosmocore/COPYING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								libosmocore/COPYING
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,339 @@ | ||||
| 		    GNU GENERAL PUBLIC LICENSE | ||||
| 		       Version 2, June 1991 | ||||
|  | ||||
|  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 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 | ||||
| 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. | ||||
|  | ||||
|   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. | ||||
|  | ||||
|   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. | ||||
|  | ||||
|   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. | ||||
|  | ||||
|   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. | ||||
|  | ||||
| 		    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. | ||||
|  | ||||
|   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 | ||||
| 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. | ||||
|  | ||||
| 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. | ||||
|  | ||||
| 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. | ||||
|  | ||||
| This section is intended to make thoroughly clear what is believed to | ||||
| be a consequence of the rest 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. | ||||
|  | ||||
|   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 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. | ||||
|  | ||||
|   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. | ||||
|  | ||||
| 			    NO 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. | ||||
|  | ||||
|   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 | ||||
|  | ||||
| 	    How to Apply These Terms to Your New Programs | ||||
|  | ||||
|   If you develop a new program, and you want it to be of the greatest | ||||
| possible use to the public, the best way to achieve this is to make it | ||||
| 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 | ||||
| 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 General Public License as published by | ||||
|     the Free Software Foundation; either version 2 of the License, or | ||||
|     (at your option) any later version. | ||||
|  | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
|  | ||||
|     You should have received a copy of the GNU General Public License along | ||||
|     with this program; if not, write to the Free Software Foundation, Inc., | ||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  | ||||
| Also add information on how to contact you by electronic and paper mail. | ||||
|  | ||||
| If the program is interactive, make it output a short notice like this | ||||
| when it starts in an interactive mode: | ||||
|  | ||||
|     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. | ||||
							
								
								
									
										14
									
								
								libosmocore/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								libosmocore/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 | ||||
| ACLOCAL_AMFLAGS = -I m4 | ||||
|  | ||||
| INCLUDES = $(all_includes) -I$(top_srcdir)/include | ||||
| SUBDIRS = include src tests | ||||
|  | ||||
| pkgconfigdir = $(libdir)/pkgconfig | ||||
| pkgconfig_DATA = libosmocore.pc | ||||
|  | ||||
| BUILT_SOURCES = $(top_srcdir)/.version | ||||
| $(top_srcdir)/.version: | ||||
| 	echo $(VERSION) > $@-t && mv $@-t $@ | ||||
| dist-hook: | ||||
| 	echo $(VERSION) > $(distdir)/.tarball-version | ||||
							
								
								
									
										56
									
								
								libosmocore/configure.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								libosmocore/configure.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| AC_INIT([libosmocore], | ||||
| 	m4_esyscmd([./git-version-gen .tarball-version]), | ||||
| 	[openbsc-devel@lists.openbsc.org]) | ||||
|  | ||||
| AM_INIT_AUTOMAKE([dist-bzip2]) | ||||
|  | ||||
| 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 | ||||
| AC_PROG_LIBTOOL | ||||
|  | ||||
| AC_CONFIG_MACRO_DIR([m4]) | ||||
|  | ||||
| dnl checks for header files | ||||
| AC_HEADER_STDC | ||||
| AC_CHECK_HEADERS(execinfo.h sys/select.h) | ||||
|  | ||||
| # 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(config.h) | ||||
|  | ||||
| AC_ARG_ENABLE(talloc, | ||||
| 	[  --disable-talloc Disable building talloc memory allocator ], | ||||
| 	[enable_talloc=0], [enable_talloc=1]) | ||||
| AM_CONDITIONAL(ENABLE_TALLOC, test "x$enable_talloc" = "x1") | ||||
|  | ||||
| AC_ARG_ENABLE(tests, | ||||
| 	[  --disable-tests Disable building test programs ], | ||||
| 	[enable_tests=0], [enable_tests=1]) | ||||
| AM_CONDITIONAL(ENABLE_TESTS, test "x$enable_tests" = "x1") | ||||
|  | ||||
| AC_OUTPUT( | ||||
| 	libosmocore.pc | ||||
| 	include/osmocore/Makefile | ||||
| 	include/osmocore/protocol/Makefile | ||||
| 	include/Makefile | ||||
| 	src/Makefile | ||||
| 	tests/Makefile | ||||
| 	tests/timer/Makefile | ||||
| 	tests/sms/Makefile | ||||
| 	Makefile) | ||||
							
								
								
									
										151
									
								
								libosmocore/git-version-gen
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										151
									
								
								libosmocore/git-version-gen
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,151 @@ | ||||
| #!/bin/sh | ||||
| # Print a version string. | ||||
| scriptversion=2010-01-28.01 | ||||
|  | ||||
| # Copyright (C) 2007-2010 Free Software Foundation, Inc. | ||||
| # | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation; either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| # This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/. | ||||
| # It may be run two ways: | ||||
| # - from a git repository in which the "git describe" command below | ||||
| #   produces useful output (thus requiring at least one signed tag) | ||||
| # - from a non-git-repo directory containing a .tarball-version file, which | ||||
| #   presumes this script is invoked like "./git-version-gen .tarball-version". | ||||
|  | ||||
| # In order to use intra-version strings in your project, you will need two | ||||
| # separate generated version string files: | ||||
| # | ||||
| # .tarball-version - present only in a distribution tarball, and not in | ||||
| #   a checked-out repository.  Created with contents that were learned at | ||||
| #   the last time autoconf was run, and used by git-version-gen.  Must not | ||||
| #   be present in either $(srcdir) or $(builddir) for git-version-gen to | ||||
| #   give accurate answers during normal development with a checked out tree, | ||||
| #   but must be present in a tarball when there is no version control system. | ||||
| #   Therefore, it cannot be used in any dependencies.  GNUmakefile has | ||||
| #   hooks to force a reconfigure at distribution time to get the value | ||||
| #   correct, without penalizing normal development with extra reconfigures. | ||||
| # | ||||
| # .version - present in a checked-out repository and in a distribution | ||||
| #   tarball.  Usable in dependencies, particularly for files that don't | ||||
| #   want to depend on config.h but do want to track version changes. | ||||
| #   Delete this file prior to any autoconf run where you want to rebuild | ||||
| #   files to pick up a version string change; and leave it stale to | ||||
| #   minimize rebuild time after unrelated changes to configure sources. | ||||
| # | ||||
| # It is probably wise to add these two files to .gitignore, so that you | ||||
| # don't accidentally commit either generated file. | ||||
| # | ||||
| # Use the following line in your configure.ac, so that $(VERSION) will | ||||
| # automatically be up-to-date each time configure is run (and note that | ||||
| # since configure.ac no longer includes a version string, Makefile rules | ||||
| # should not depend on configure.ac for version updates). | ||||
| # | ||||
| # AC_INIT([GNU project], | ||||
| #         m4_esyscmd([build-aux/git-version-gen .tarball-version]), | ||||
| #         [bug-project@example]) | ||||
| # | ||||
| # Then use the following lines in your Makefile.am, so that .version | ||||
| # will be present for dependencies, and so that .tarball-version will | ||||
| # exist in distribution tarballs. | ||||
| # | ||||
| # BUILT_SOURCES = $(top_srcdir)/.version | ||||
| # $(top_srcdir)/.version: | ||||
| #	echo $(VERSION) > $@-t && mv $@-t $@ | ||||
| # dist-hook: | ||||
| #	echo $(VERSION) > $(distdir)/.tarball-version | ||||
|  | ||||
| case $# in | ||||
|     1) ;; | ||||
|     *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;; | ||||
| esac | ||||
|  | ||||
| tarball_version_file=$1 | ||||
| nl=' | ||||
| ' | ||||
|  | ||||
| # First see if there is a tarball-only version file. | ||||
| # then try "git describe", then default. | ||||
| if test -f $tarball_version_file | ||||
| then | ||||
|     v=`cat $tarball_version_file` || exit 1 | ||||
|     case $v in | ||||
| 	*$nl*) v= ;; # reject multi-line output | ||||
| 	[0-9]*) ;; | ||||
| 	*) v= ;; | ||||
|     esac | ||||
|     test -z "$v" \ | ||||
| 	&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2 | ||||
| fi | ||||
|  | ||||
| if test -n "$v" | ||||
| then | ||||
|     : # use $v | ||||
| elif | ||||
|        v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \ | ||||
| 	  || git describe --abbrev=4 HEAD 2>/dev/null` \ | ||||
|     && case $v in | ||||
| 	 [0-9]*) ;; | ||||
| 	 v[0-9]*) ;; | ||||
| 	 *) (exit 1) ;; | ||||
|        esac | ||||
| then | ||||
|     # Is this a new git that lists number of commits since the last | ||||
|     # tag or the previous older version that did not? | ||||
|     #   Newer: v6.10-77-g0f8faeb | ||||
|     #   Older: v6.10-g0f8faeb | ||||
|     case $v in | ||||
| 	*-*-*) : git describe is okay three part flavor ;; | ||||
| 	*-*) | ||||
| 	    : git describe is older two part flavor | ||||
| 	    # Recreate the number of commits and rewrite such that the | ||||
| 	    # result is the same as if we were using the newer version | ||||
| 	    # of git describe. | ||||
| 	    vtag=`echo "$v" | sed 's/-.*//'` | ||||
| 	    numcommits=`git rev-list "$vtag"..HEAD | wc -l` | ||||
| 	    v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`; | ||||
| 	    ;; | ||||
|     esac | ||||
|  | ||||
|     # Change the first '-' to a '.', so version-comparing tools work properly. | ||||
|     # Remove the "g" in git describe's output string, to save a byte. | ||||
|     v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`; | ||||
| else | ||||
|     v=UNKNOWN | ||||
| fi | ||||
|  | ||||
| v=`echo "$v" |sed 's/^v//'` | ||||
|  | ||||
| # Don't declare a version "dirty" merely because a time stamp has changed. | ||||
| git status > /dev/null 2>&1 | ||||
|  | ||||
| dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty= | ||||
| case "$dirty" in | ||||
|     '') ;; | ||||
|     *) # Append the suffix only if there isn't one already. | ||||
| 	case $v in | ||||
| 	  *-dirty) ;; | ||||
| 	  *) v="$v-dirty" ;; | ||||
| 	esac ;; | ||||
| esac | ||||
|  | ||||
| # Omit the trailing newline, so that m4_esyscmd can use the result directly. | ||||
| echo "$v" | tr -d '\012' | ||||
|  | ||||
| # Local variables: | ||||
| # eval: (add-hook 'write-file-hooks 'time-stamp) | ||||
| # time-stamp-start: "scriptversion=" | ||||
| # time-stamp-format: "%:y-%02m-%02d.%02H" | ||||
| # time-stamp-end: "$" | ||||
| # End: | ||||
							
								
								
									
										1
									
								
								libosmocore/include/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								libosmocore/include/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| SUBDIRS = osmocore | ||||
							
								
								
									
										12
									
								
								libosmocore/include/osmocore/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								libosmocore/include/osmocore/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| osmocore_HEADERS = signal.h linuxlist.h timer.h select.h msgb.h \ | ||||
| 		   tlv.h bitvec.h comp128.h statistics.h gsm_utils.h utils.h \ | ||||
| 		   gsmtap.h write_queue.h rsl.h gsm48.h rxlev_stat.h mncc.h \ | ||||
| 		   gsm48_ie.h logging.h | ||||
|  | ||||
| if ENABLE_TALLOC | ||||
| osmocore_HEADERS += talloc.h | ||||
| endif | ||||
|  | ||||
| osmocoredir = $(includedir)/osmocore | ||||
|  | ||||
| SUBDIRS = protocol | ||||
							
								
								
									
										65
									
								
								libosmocore/include/osmocore/bitvec.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								libosmocore/include/osmocore/bitvec.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| #ifndef _BITVEC_H | ||||
| #define _BITVEC_H | ||||
|  | ||||
| /* bit vector utility routines */ | ||||
|  | ||||
| /* (C) 2009 by Harald Welte <laforge@gnumonks.org> | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /* In GSM mac blocks, every bit can be 0 or 1, or L or H.  L/H are | ||||
|  * defined relative to the 0x2b padding pattern */ | ||||
| enum bit_value { | ||||
| 	ZERO	= 0, | ||||
| 	ONE	= 1, | ||||
| 	L	= 2, | ||||
| 	H	= 3, | ||||
| }; | ||||
|  | ||||
| struct bitvec { | ||||
| 	unsigned int cur_bit;	/* curser to the next unused bit */ | ||||
| 	unsigned int data_len;	/* length of data array in bytes */ | ||||
| 	uint8_t *data;		/* pointer to data array */ | ||||
| }; | ||||
|  | ||||
| /* check if the bit is 0 or 1 for a given position inside a bitvec */ | ||||
| enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr); | ||||
|  | ||||
| /* get the Nth set bit inside the bit vector */ | ||||
| unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n); | ||||
|  | ||||
| /* Set a bit at given position */ | ||||
| int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum, | ||||
| 			enum bit_value bit); | ||||
|  | ||||
| /* Set the next bit in the vector */ | ||||
| int bitvec_set_bit(struct bitvec *bv, enum bit_value bit); | ||||
|  | ||||
| /* Set multiple bits at the current position */ | ||||
| int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count); | ||||
|  | ||||
| /* Add an unsigned integer (of length count bits) to current position */ | ||||
| int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count); | ||||
|  | ||||
|  | ||||
| /* Pad the bit vector up to a certain bit position */ | ||||
| int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit); | ||||
|  | ||||
| #endif /* _BITVEC_H */ | ||||
							
								
								
									
										22
									
								
								libosmocore/include/osmocore/comp128.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								libosmocore/include/osmocore/comp128.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| /* | ||||
|  * COMP128 header | ||||
|  * | ||||
|  * See comp128.c for details | ||||
|  */ | ||||
|  | ||||
| #ifndef __COMP128_H__ | ||||
| #define __COMP128_H__ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| /* | ||||
|  * Performs the COMP128 algorithm (used as A3/A8) | ||||
|  * ki    : uint8_t [16] | ||||
|  * srand : uint8_t [16] | ||||
|  * sres  : uint8_t [4] | ||||
|  * kc    : uint8_t [8] | ||||
|  */ | ||||
| void comp128(uint8_t *ki, uint8_t *srand, uint8_t *sres, uint8_t *kc); | ||||
|  | ||||
| #endif /* __COMP128_H__ */ | ||||
|  | ||||
							
								
								
									
										17
									
								
								libosmocore/include/osmocore/gsm48.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								libosmocore/include/osmocore/gsm48.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #ifndef _OSMOCORE_GSM48_H | ||||
|  | ||||
| #include <osmocore/tlv.h> | ||||
| #include <osmocore/protocol/gsm_04_08.h> | ||||
| #include <osmocore/gsm48_ie.h> | ||||
|  | ||||
| extern const struct tlv_definition gsm48_att_tlvdef; | ||||
| const char *gsm48_cc_state_name(uint8_t state); | ||||
| const char *gsm48_cc_msg_name(uint8_t msgtype); | ||||
| const char *rr_cause_name(uint8_t cause); | ||||
|  | ||||
| void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc, | ||||
| 			uint16_t mnc, uint16_t lac); | ||||
| int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi); | ||||
| int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										107
									
								
								libosmocore/include/osmocore/gsm48_ie.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								libosmocore/include/osmocore/gsm48_ie.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| #ifndef _OSMOCORE_GSM48_IE_H | ||||
| #define _OSMOCORE_GSM48_IE_H | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| #include <osmocore/msgb.h> | ||||
| #include <osmocore/tlv.h> | ||||
| #include <osmocore/mncc.h> | ||||
| #include <osmocore/protocol/gsm_04_08.h> | ||||
|  | ||||
| /* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */ | ||||
| int gsm48_decode_bcd_number(char *output, int output_len, | ||||
| 			    const uint8_t *bcd_lv, int h_len); | ||||
|  | ||||
| /* convert a ASCII phone number to 'called/calling/connect party BCD number' */ | ||||
| int gsm48_encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len, | ||||
| 			    int h_len, const char *input); | ||||
| /* decode 'bearer capability' */ | ||||
| int gsm48_decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap, | ||||
| 			     const uint8_t *lv); | ||||
| /* encode 'bearer capability' */ | ||||
| int gsm48_encode_bearer_cap(struct msgb *msg, int lv_only, | ||||
| 			     const struct gsm_mncc_bearer_cap *bcap); | ||||
| /* decode 'call control cap' */ | ||||
| int gsm48_decode_cccap(struct gsm_mncc_cccap *ccap, const uint8_t *lv); | ||||
| /* encode 'call control cap' */ | ||||
| int gsm48_encode_cccap(struct msgb *msg, | ||||
| 			const struct gsm_mncc_cccap *ccap); | ||||
| /* decode 'called party BCD number' */ | ||||
| int gsm48_decode_called(struct gsm_mncc_number *called, | ||||
| 			 const uint8_t *lv); | ||||
| /* encode 'called party BCD number' */ | ||||
| int gsm48_encode_called(struct msgb *msg, | ||||
| 			 const struct gsm_mncc_number *called); | ||||
| /* decode callerid of various IEs */ | ||||
| int gsm48_decode_callerid(struct gsm_mncc_number *callerid, | ||||
| 			 const uint8_t *lv); | ||||
| /* encode callerid of various IEs */ | ||||
| int gsm48_encode_callerid(struct msgb *msg, int ie, int max_len, | ||||
| 			   const struct gsm_mncc_number *callerid); | ||||
| /* decode 'cause' */ | ||||
| int gsm48_decode_cause(struct gsm_mncc_cause *cause, | ||||
| 			const uint8_t *lv); | ||||
| /* encode 'cause' */ | ||||
| int gsm48_encode_cause(struct msgb *msg, int lv_only, | ||||
| 			const struct gsm_mncc_cause *cause); | ||||
| /* decode 'calling number' */ | ||||
| int gsm48_decode_calling(struct gsm_mncc_number *calling, | ||||
| 			 const uint8_t *lv); | ||||
| /* encode 'calling number' */ | ||||
| int gsm48_encode_calling(struct msgb *msg,  | ||||
| 			  const struct gsm_mncc_number *calling); | ||||
| /* decode 'connected number' */ | ||||
| int gsm48_decode_connected(struct gsm_mncc_number *connected, | ||||
| 			 const uint8_t *lv); | ||||
| /* encode 'connected number' */ | ||||
| int gsm48_encode_connected(struct msgb *msg, | ||||
| 			    const struct gsm_mncc_number *connected); | ||||
| /* decode 'redirecting number' */ | ||||
| int gsm48_decode_redirecting(struct gsm_mncc_number *redirecting, | ||||
| 			 const uint8_t *lv); | ||||
| /* encode 'redirecting number' */ | ||||
| int gsm48_encode_redirecting(struct msgb *msg, | ||||
| 			      const struct gsm_mncc_number *redirecting); | ||||
| /* decode 'facility' */ | ||||
| int gsm48_decode_facility(struct gsm_mncc_facility *facility, | ||||
| 			   const uint8_t *lv); | ||||
| /* encode 'facility' */ | ||||
| int gsm48_encode_facility(struct msgb *msg, int lv_only, | ||||
| 			   const struct gsm_mncc_facility *facility); | ||||
| /* decode 'notify' */ | ||||
| int gsm48_decode_notify(int *notify, const uint8_t *v); | ||||
| /* encode 'notify' */ | ||||
| int gsm48_encode_notify(struct msgb *msg, int notify); | ||||
| /* decode 'signal' */ | ||||
| int gsm48_decode_signal(int *signal, const uint8_t *v); | ||||
| /* encode 'signal' */ | ||||
| int gsm48_encode_signal(struct msgb *msg, int signal); | ||||
| /* decode 'keypad' */ | ||||
| int gsm48_decode_keypad(int *keypad, const uint8_t *lv); | ||||
| /* encode 'keypad' */ | ||||
| int gsm48_encode_keypad(struct msgb *msg, int keypad); | ||||
| /* decode 'progress' */ | ||||
| int gsm48_decode_progress(struct gsm_mncc_progress *progress, | ||||
| 			   const uint8_t *lv); | ||||
| /* encode 'progress' */ | ||||
| int gsm48_encode_progress(struct msgb *msg, int lv_only, | ||||
| 			   const struct gsm_mncc_progress *p); | ||||
| /* decode 'user-user' */ | ||||
| int gsm48_decode_useruser(struct gsm_mncc_useruser *uu, | ||||
| 			   const uint8_t *lv); | ||||
| /* encode 'useruser' */ | ||||
| int gsm48_encode_useruser(struct msgb *msg, int lv_only, | ||||
| 			   const struct gsm_mncc_useruser *uu); | ||||
| /* decode 'ss version' */ | ||||
| int gsm48_decode_ssversion(struct gsm_mncc_ssversion *ssv, | ||||
| 			    const uint8_t *lv); | ||||
| /* encode 'ss version' */ | ||||
| int gsm48_encode_ssversion(struct msgb *msg, | ||||
| 			   const struct gsm_mncc_ssversion *ssv); | ||||
| /* decode 'more data' does not require a function, because it has no value */ | ||||
| /* encode 'more data' */ | ||||
| int gsm48_encode_more(struct msgb *msg); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										84
									
								
								libosmocore/include/osmocore/gsm_utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								libosmocore/include/osmocore/gsm_utils.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /* GSM utility functions, e.g. coding and decoding */ | ||||
| /* | ||||
|  * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de> | ||||
|  * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> | ||||
|  * (C) 2009-2010 by Harald Welte <laforge@gnumonks.org> | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef GSM_UTILS_H | ||||
| #define GSM_UTILS_H | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| struct gsm_time { | ||||
| 	uint32_t	fn;	/* FN count */ | ||||
| 	uint16_t	t1;	/* FN div (26*51) */ | ||||
| 	uint8_t		t2;	/* FN modulo 26 */ | ||||
| 	uint8_t		t3;	/* FN modulo 51 */ | ||||
| 	uint8_t		tc; | ||||
| }; | ||||
|  | ||||
| enum gsm_band { | ||||
| 	GSM_BAND_850	= 1, | ||||
| 	GSM_BAND_900	= 2, | ||||
| 	GSM_BAND_1800	= 4, | ||||
| 	GSM_BAND_1900	= 8, | ||||
| 	GSM_BAND_450	= 0x10, | ||||
| 	GSM_BAND_480	= 0x20, | ||||
| 	GSM_BAND_750	= 0x40, | ||||
| 	GSM_BAND_810	= 0x80, | ||||
| }; | ||||
|  | ||||
| const char *gsm_band_name(enum gsm_band band); | ||||
| enum gsm_band gsm_band_parse(const char *mhz); | ||||
|  | ||||
| int gsm_7bit_decode(char *decoded, const uint8_t *user_data, uint8_t length); | ||||
| int gsm_7bit_encode(uint8_t *result, const char *data); | ||||
|  | ||||
| int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm); | ||||
| int ms_pwr_dbm(enum gsm_band band, uint8_t lvl); | ||||
|  | ||||
| /* According to TS 08.05 Chapter 8.1.4 */ | ||||
| int rxlev2dbm(uint8_t rxlev); | ||||
| uint8_t dbm2rxlev(int dbm); | ||||
|  | ||||
| /* According to GSM 04.08 Chapter 10.5.2.29 */ | ||||
| static inline int rach_max_trans_val2raw(int val) { return (val >> 1) & 3; } | ||||
| static inline int rach_max_trans_raw2val(int raw) { | ||||
| 	const int tbl[4] = { 1, 2, 4, 7 }; | ||||
| 	return tbl[raw & 3]; | ||||
| } | ||||
|  | ||||
| #define	ARFCN_PCS	0x8000 | ||||
| #define	ARFCN_UPLINK	0x4000 | ||||
|  | ||||
| enum gsm_band gsm_arfcn2band(uint16_t arfcn); | ||||
|  | ||||
| /* Convert an ARFCN to the frequency in MHz * 10 */ | ||||
| uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink); | ||||
|  | ||||
| /* Convert from frame number to GSM time */ | ||||
| void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn); | ||||
|  | ||||
| /* Convert from GSM time to frame number */ | ||||
| uint32_t gsm_gsmtime2fn(struct gsm_time *time); | ||||
|  | ||||
| void generate_backtrace(); | ||||
| #endif | ||||
							
								
								
									
										72
									
								
								libosmocore/include/osmocore/gsmtap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								libosmocore/include/osmocore/gsmtap.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| #ifndef _GSMTAP_H | ||||
| #define _GSMTAP_H | ||||
|  | ||||
| /* gsmtap header, pseudo-header in front of the actua GSM payload */ | ||||
|  | ||||
| /* GSMTAP is a generic header format for GSM protocol captures, | ||||
|  * it uses the IANA-assigned UDP port number 4729 and carries | ||||
|  * payload in various formats of GSM interfaces such as Um MAC | ||||
|  * blocks or Um bursts. | ||||
|  * | ||||
|  * Example programs generating GSMTAP data are airprobe | ||||
|  * (http://airprobe.org/) or OsmocomBB (http://bb.osmocom.org/) | ||||
|  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #define GSMTAP_VERSION		0x02 | ||||
|  | ||||
| #define GSMTAP_TYPE_UM		0x01 | ||||
| #define GSMTAP_TYPE_ABIS	0x02 | ||||
| #define GSMTAP_TYPE_UM_BURST	0x03	/* raw burst bits */ | ||||
|  | ||||
| #define GSMTAP_BURST_UNKNOWN		0x00 | ||||
| #define GSMTAP_BURST_FCCH		0x01 | ||||
| #define GSMTAP_BURST_PARTIAL_SCH	0x02 | ||||
| #define GSMTAP_BURST_SCH		0x03 | ||||
| #define GSMTAP_BURST_CTS_SCH		0x04 | ||||
| #define GSMTAP_BURST_COMPACT_SCH	0x05 | ||||
| #define GSMTAP_BURST_NORMAL		0x06 | ||||
| #define GSMTAP_BURST_DUMMY		0x07 | ||||
| #define GSMTAP_BURST_ACCESS		0x08 | ||||
| #define GSMTAP_BURST_NONE		0x09 | ||||
|  | ||||
| #define GSMTAP_CHANNEL_UNKNOWN	0x00 | ||||
| #define GSMTAP_CHANNEL_BCCH	0x01 | ||||
| #define GSMTAP_CHANNEL_CCCH	0x02 | ||||
| #define GSMTAP_CHANNEL_RACH	0x03 | ||||
| #define GSMTAP_CHANNEL_AGCH	0x04 | ||||
| #define GSMTAP_CHANNEL_PCH	0x05 | ||||
| #define GSMTAP_CHANNEL_SDCCH	0x06 | ||||
| #define GSMTAP_CHANNEL_SDCCH4	0x07 | ||||
| #define GSMTAP_CHANNEL_SDCCH8	0x08 | ||||
| #define GSMTAP_CHANNEL_TCH_F	0x09 | ||||
| #define GSMTAP_CHANNEL_TCH_H	0x0a | ||||
| #define GSMTAP_CHANNEL_ACCH	0x80 | ||||
|  | ||||
| #define GSMTAP_ARFCN_F_PCS	0x8000 | ||||
| #define GSMTAP_ARFCN_F_UPLINK	0x4000 | ||||
| #define GSMTAP_ARFCN_MASK	0x3fff | ||||
|  | ||||
| #define GSMTAP_UDP_PORT			4729 | ||||
|  | ||||
| struct gsmtap_hdr { | ||||
| 	uint8_t version;	/* version, set to 0x01 currently */ | ||||
| 	uint8_t hdr_len;	/* length in number of 32bit words */ | ||||
| 	uint8_t type;		/* see GSMTAP_TYPE_* */ | ||||
| 	uint8_t timeslot;	/* timeslot (0..7 on Um) */ | ||||
|  | ||||
| 	uint16_t arfcn;		/* ARFCN (frequency) */ | ||||
| 	int8_t signal_dbm;	/* signal level in dBm */ | ||||
| 	int8_t snr_db;		/* signal/noise ratio in dB */ | ||||
|  | ||||
| 	uint32_t frame_number;	/* GSM Frame Number (FN) */ | ||||
|  | ||||
| 	uint8_t sub_type;	/* Type of burst/channel, see above */ | ||||
| 	uint8_t antenna_nr;	/* Antenna Number */ | ||||
| 	uint8_t sub_slot;	/* sub-slot within timeslot */ | ||||
| 	uint8_t res;		/* reserved for future use (RFU) */ | ||||
|  | ||||
| } __attribute__((packed)); | ||||
|  | ||||
| #endif /* _GSMTAP_H */ | ||||
							
								
								
									
										360
									
								
								libosmocore/include/osmocore/linuxlist.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								libosmocore/include/osmocore/linuxlist.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,360 @@ | ||||
| #ifndef _LINUX_LLIST_H | ||||
| #define _LINUX_LLIST_H | ||||
|  | ||||
| #include <stddef.h> | ||||
|  | ||||
| #ifndef inline | ||||
| #define inline __inline__ | ||||
| #endif | ||||
|  | ||||
| static inline void prefetch(const void *x) {;} | ||||
|  | ||||
| /** | ||||
|  * container_of - cast a member of a structure out to the containing structure | ||||
|  * | ||||
|  * @ptr:	the pointer to the member. | ||||
|  * @type:	the type of the container struct this is embedded in. | ||||
|  * @member:	the name of the member within the struct. | ||||
|  * | ||||
|  */ | ||||
| #define container_of(ptr, type, member) ({			\ | ||||
|         const typeof( ((type *)0)->member ) *__mptr = (typeof( ((type *)0)->member ) *)(ptr);	\ | ||||
|         (type *)( (char *)__mptr - offsetof(type, member) );}) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * These are non-NULL pointers that will result in page faults | ||||
|  * under normal circumstances, used to verify that nobody uses | ||||
|  * non-initialized llist entries. | ||||
|  */ | ||||
| #define LLIST_POISON1  ((void *) 0x00100100) | ||||
| #define LLIST_POISON2  ((void *) 0x00200200) | ||||
|  | ||||
| /* | ||||
|  * Simple doubly linked llist implementation. | ||||
|  * | ||||
|  * Some of the internal functions ("__xxx") are useful when | ||||
|  * manipulating whole llists rather than single entries, as | ||||
|  * sometimes we already know the next/prev entries and we can | ||||
|  * generate better code by using them directly rather than | ||||
|  * using the generic single-entry routines. | ||||
|  */ | ||||
|  | ||||
| struct llist_head { | ||||
| 	struct llist_head *next, *prev; | ||||
| }; | ||||
|  | ||||
| #define LLIST_HEAD_INIT(name) { &(name), &(name) } | ||||
|  | ||||
| #define LLIST_HEAD(name) \ | ||||
| 	struct llist_head name = LLIST_HEAD_INIT(name) | ||||
|  | ||||
| #define INIT_LLIST_HEAD(ptr) do { \ | ||||
| 	(ptr)->next = (ptr); (ptr)->prev = (ptr); \ | ||||
| } while (0) | ||||
|  | ||||
| /* | ||||
|  * Insert a new entry between two known consecutive entries.  | ||||
|  * | ||||
|  * This is only for internal llist manipulation where we know | ||||
|  * the prev/next entries already! | ||||
|  */ | ||||
| static inline void __llist_add(struct llist_head *_new, | ||||
| 			      struct llist_head *prev, | ||||
| 			      struct llist_head *next) | ||||
| { | ||||
| 	next->prev = _new; | ||||
| 	_new->next = next; | ||||
| 	_new->prev = prev; | ||||
| 	prev->next = _new; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_add - add a new entry | ||||
|  * @new: new entry to be added | ||||
|  * @head: llist head to add it after | ||||
|  * | ||||
|  * Insert a new entry after the specified head. | ||||
|  * This is good for implementing stacks. | ||||
|  */ | ||||
| static inline void llist_add(struct llist_head *_new, struct llist_head *head) | ||||
| { | ||||
| 	__llist_add(_new, head, head->next); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_add_tail - add a new entry | ||||
|  * @new: new entry to be added | ||||
|  * @head: llist head to add it before | ||||
|  * | ||||
|  * Insert a new entry before the specified head. | ||||
|  * This is useful for implementing queues. | ||||
|  */ | ||||
| static inline void llist_add_tail(struct llist_head *_new, struct llist_head *head) | ||||
| { | ||||
| 	__llist_add(_new, head->prev, head); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Delete a llist entry by making the prev/next entries | ||||
|  * point to each other. | ||||
|  * | ||||
|  * This is only for internal llist manipulation where we know | ||||
|  * the prev/next entries already! | ||||
|  */ | ||||
| static inline void __llist_del(struct llist_head * prev, struct llist_head * next) | ||||
| { | ||||
| 	next->prev = prev; | ||||
| 	prev->next = next; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_del - deletes entry from llist. | ||||
|  * @entry: the element to delete from the llist. | ||||
|  * Note: llist_empty on entry does not return true after this, the entry is | ||||
|  * in an undefined state. | ||||
|  */ | ||||
| static inline void llist_del(struct llist_head *entry) | ||||
| { | ||||
| 	__llist_del(entry->prev, entry->next); | ||||
| 	entry->next = (struct llist_head *)LLIST_POISON1; | ||||
| 	entry->prev = (struct llist_head *)LLIST_POISON2; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_del_init - deletes entry from llist and reinitialize it. | ||||
|  * @entry: the element to delete from the llist. | ||||
|  */ | ||||
| static inline void llist_del_init(struct llist_head *entry) | ||||
| { | ||||
| 	__llist_del(entry->prev, entry->next); | ||||
| 	INIT_LLIST_HEAD(entry);  | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_move - delete from one llist and add as another's head | ||||
|  * @llist: the entry to move | ||||
|  * @head: the head that will precede our entry | ||||
|  */ | ||||
| static inline void llist_move(struct llist_head *llist, struct llist_head *head) | ||||
| { | ||||
|         __llist_del(llist->prev, llist->next); | ||||
|         llist_add(llist, head); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_move_tail - delete from one llist and add as another's tail | ||||
|  * @llist: the entry to move | ||||
|  * @head: the head that will follow our entry | ||||
|  */ | ||||
| static inline void llist_move_tail(struct llist_head *llist, | ||||
| 				  struct llist_head *head) | ||||
| { | ||||
|         __llist_del(llist->prev, llist->next); | ||||
|         llist_add_tail(llist, head); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_empty - tests whether a llist is empty | ||||
|  * @head: the llist to test. | ||||
|  */ | ||||
| static inline int llist_empty(const struct llist_head *head) | ||||
| { | ||||
| 	return head->next == head; | ||||
| } | ||||
|  | ||||
| static inline void __llist_splice(struct llist_head *llist, | ||||
| 				 struct llist_head *head) | ||||
| { | ||||
| 	struct llist_head *first = llist->next; | ||||
| 	struct llist_head *last = llist->prev; | ||||
| 	struct llist_head *at = head->next; | ||||
|  | ||||
| 	first->prev = head; | ||||
| 	head->next = first; | ||||
|  | ||||
| 	last->next = at; | ||||
| 	at->prev = last; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_splice - join two llists | ||||
|  * @llist: the new llist to add. | ||||
|  * @head: the place to add it in the first llist. | ||||
|  */ | ||||
| static inline void llist_splice(struct llist_head *llist, struct llist_head *head) | ||||
| { | ||||
| 	if (!llist_empty(llist)) | ||||
| 		__llist_splice(llist, head); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_splice_init - join two llists and reinitialise the emptied llist. | ||||
|  * @llist: the new llist to add. | ||||
|  * @head: the place to add it in the first llist. | ||||
|  * | ||||
|  * The llist at @llist is reinitialised | ||||
|  */ | ||||
| static inline void llist_splice_init(struct llist_head *llist, | ||||
| 				    struct llist_head *head) | ||||
| { | ||||
| 	if (!llist_empty(llist)) { | ||||
| 		__llist_splice(llist, head); | ||||
| 		INIT_LLIST_HEAD(llist); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * llist_entry - get the struct for this entry | ||||
|  * @ptr:	the &struct llist_head pointer. | ||||
|  * @type:	the type of the struct this is embedded in. | ||||
|  * @member:	the name of the llist_struct within the struct. | ||||
|  */ | ||||
| #define llist_entry(ptr, type, member) \ | ||||
| 	container_of(ptr, type, member) | ||||
|  | ||||
| /** | ||||
|  * llist_for_each	-	iterate over a llist | ||||
|  * @pos:	the &struct llist_head to use as a loop counter. | ||||
|  * @head:	the head for your llist. | ||||
|  */ | ||||
| #define llist_for_each(pos, head) \ | ||||
| 	for (pos = (head)->next, prefetch(pos->next); pos != (head); \ | ||||
|         	pos = pos->next, prefetch(pos->next)) | ||||
|  | ||||
| /** | ||||
|  * __llist_for_each	-	iterate over a llist | ||||
|  * @pos:	the &struct llist_head to use as a loop counter. | ||||
|  * @head:	the head for your llist. | ||||
|  * | ||||
|  * This variant differs from llist_for_each() in that it's the | ||||
|  * simplest possible llist iteration code, no prefetching is done. | ||||
|  * Use this for code that knows the llist to be very short (empty | ||||
|  * or 1 entry) most of the time. | ||||
|  */ | ||||
| #define __llist_for_each(pos, head) \ | ||||
| 	for (pos = (head)->next; pos != (head); pos = pos->next) | ||||
|  | ||||
| /** | ||||
|  * llist_for_each_prev	-	iterate over a llist backwards | ||||
|  * @pos:	the &struct llist_head to use as a loop counter. | ||||
|  * @head:	the head for your llist. | ||||
|  */ | ||||
| #define llist_for_each_prev(pos, head) \ | ||||
| 	for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \ | ||||
|         	pos = pos->prev, prefetch(pos->prev)) | ||||
|         	 | ||||
| /** | ||||
|  * llist_for_each_safe	-	iterate over a llist safe against removal of llist entry | ||||
|  * @pos:	the &struct llist_head to use as a loop counter. | ||||
|  * @n:		another &struct llist_head to use as temporary storage | ||||
|  * @head:	the head for your llist. | ||||
|  */ | ||||
| #define llist_for_each_safe(pos, n, head) \ | ||||
| 	for (pos = (head)->next, n = pos->next; pos != (head); \ | ||||
| 		pos = n, n = pos->next) | ||||
|  | ||||
| /** | ||||
|  * llist_for_each_entry	-	iterate over llist of given type | ||||
|  * @pos:	the type * to use as a loop counter. | ||||
|  * @head:	the head for your llist. | ||||
|  * @member:	the name of the llist_struct within the struct. | ||||
|  */ | ||||
| #define llist_for_each_entry(pos, head, member)				\ | ||||
| 	for (pos = llist_entry((head)->next, typeof(*pos), member),	\ | ||||
| 		     prefetch(pos->member.next);			\ | ||||
| 	     &pos->member != (head); 					\ | ||||
| 	     pos = llist_entry(pos->member.next, typeof(*pos), member),	\ | ||||
| 		     prefetch(pos->member.next)) | ||||
|  | ||||
| /** | ||||
|  * llist_for_each_entry_reverse - iterate backwards over llist of given type. | ||||
|  * @pos:	the type * to use as a loop counter. | ||||
|  * @head:	the head for your llist. | ||||
|  * @member:	the name of the llist_struct within the struct. | ||||
|  */ | ||||
| #define llist_for_each_entry_reverse(pos, head, member)			\ | ||||
| 	for (pos = llist_entry((head)->prev, typeof(*pos), member),	\ | ||||
| 		     prefetch(pos->member.prev);			\ | ||||
| 	     &pos->member != (head); 					\ | ||||
| 	     pos = llist_entry(pos->member.prev, typeof(*pos), member),	\ | ||||
| 		     prefetch(pos->member.prev)) | ||||
|  | ||||
| /** | ||||
|  * llist_for_each_entry_continue -	iterate over llist of given type | ||||
|  *			continuing after existing point | ||||
|  * @pos:	the type * to use as a loop counter. | ||||
|  * @head:	the head for your llist. | ||||
|  * @member:	the name of the llist_struct within the struct. | ||||
|  */ | ||||
| #define llist_for_each_entry_continue(pos, head, member) 		\ | ||||
| 	for (pos = llist_entry(pos->member.next, typeof(*pos), member),	\ | ||||
| 		     prefetch(pos->member.next);			\ | ||||
| 	     &pos->member != (head);					\ | ||||
| 	     pos = llist_entry(pos->member.next, typeof(*pos), member),	\ | ||||
| 		     prefetch(pos->member.next)) | ||||
|  | ||||
| /** | ||||
|  * llist_for_each_entry_safe - iterate over llist of given type safe against removal of llist entry | ||||
|  * @pos:	the type * to use as a loop counter. | ||||
|  * @n:		another type * to use as temporary storage | ||||
|  * @head:	the head for your llist. | ||||
|  * @member:	the name of the llist_struct within the struct. | ||||
|  */ | ||||
| #define llist_for_each_entry_safe(pos, n, head, member)			\ | ||||
| 	for (pos = llist_entry((head)->next, typeof(*pos), member),	\ | ||||
| 		n = llist_entry(pos->member.next, typeof(*pos), member);	\ | ||||
| 	     &pos->member != (head); 					\ | ||||
| 	     pos = n, n = llist_entry(n->member.next, typeof(*n), member)) | ||||
|  | ||||
| /** | ||||
|  * llist_for_each_rcu	-	iterate over an rcu-protected llist | ||||
|  * @pos:	the &struct llist_head to use as a loop counter. | ||||
|  * @head:	the head for your llist. | ||||
|  */ | ||||
| #define llist_for_each_rcu(pos, head) \ | ||||
| 	for (pos = (head)->next, prefetch(pos->next); pos != (head); \ | ||||
|         	pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next)) | ||||
|         	 | ||||
| #define __llist_for_each_rcu(pos, head) \ | ||||
| 	for (pos = (head)->next; pos != (head); \ | ||||
|         	pos = pos->next, ({ smp_read_barrier_depends(); 0;})) | ||||
|         	 | ||||
| /** | ||||
|  * llist_for_each_safe_rcu	-	iterate over an rcu-protected llist safe | ||||
|  *					against removal of llist entry | ||||
|  * @pos:	the &struct llist_head to use as a loop counter. | ||||
|  * @n:		another &struct llist_head to use as temporary storage | ||||
|  * @head:	the head for your llist. | ||||
|  */ | ||||
| #define llist_for_each_safe_rcu(pos, n, head) \ | ||||
| 	for (pos = (head)->next, n = pos->next; pos != (head); \ | ||||
| 		pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next) | ||||
|  | ||||
| /** | ||||
|  * llist_for_each_entry_rcu	-	iterate over rcu llist of given type | ||||
|  * @pos:	the type * to use as a loop counter. | ||||
|  * @head:	the head for your llist. | ||||
|  * @member:	the name of the llist_struct within the struct. | ||||
|  */ | ||||
| #define llist_for_each_entry_rcu(pos, head, member)			\ | ||||
| 	for (pos = llist_entry((head)->next, typeof(*pos), member),	\ | ||||
| 		     prefetch(pos->member.next);			\ | ||||
| 	     &pos->member != (head); 					\ | ||||
| 	     pos = llist_entry(pos->member.next, typeof(*pos), member),	\ | ||||
| 		     ({ smp_read_barrier_depends(); 0;}),		\ | ||||
| 		     prefetch(pos->member.next)) | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * llist_for_each_continue_rcu	-	iterate over an rcu-protected llist  | ||||
|  *			continuing after existing point. | ||||
|  * @pos:	the &struct llist_head to use as a loop counter. | ||||
|  * @head:	the head for your llist. | ||||
|  */ | ||||
| #define llist_for_each_continue_rcu(pos, head) \ | ||||
| 	for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \ | ||||
|         	(pos) = (pos)->next, ({ smp_read_barrier_depends(); 0;}), prefetch((pos)->next)) | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										130
									
								
								libosmocore/include/osmocore/logging.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								libosmocore/include/osmocore/logging.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,130 @@ | ||||
| #ifndef _OSMOCORE_LOGGING_H | ||||
| #define _OSMOCORE_LOGGING_H | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <osmocore/linuxlist.h> | ||||
|  | ||||
| #define LOG_MAX_CATEGORY	32 | ||||
| #define LOG_MAX_CTX		8 | ||||
| #define LOG_MAX_FILTERS	8 | ||||
|  | ||||
| #define DEBUG | ||||
|  | ||||
| #ifdef DEBUG | ||||
| #define DEBUGP(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 0, fmt, ## args) | ||||
| #define DEBUGPC(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 1, fmt, ## args) | ||||
| #else | ||||
| #define DEBUGP(xss, fmt, args...) | ||||
| #define DEBUGPC(ss, fmt, args...) | ||||
| #endif | ||||
|  | ||||
| #define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1]; | ||||
|  | ||||
| char *hexdump(const unsigned char *buf, int len); | ||||
| void logp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6))); | ||||
|  | ||||
| /* new logging interface */ | ||||
| #define LOGP(ss, level, fmt, args...) \ | ||||
| 	logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args) | ||||
| #define LOGPC(ss, level, fmt, args...) \ | ||||
| 	logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args) | ||||
|  | ||||
| /* different levels */ | ||||
| #define LOGL_DEBUG	1	/* debugging information */ | ||||
| #define LOGL_INFO	3 | ||||
| #define LOGL_NOTICE	5	/* abnormal/unexpected condition */ | ||||
| #define LOGL_ERROR	7	/* error condition, requires user action */ | ||||
| #define LOGL_FATAL	8	/* fatal, program aborted */ | ||||
|  | ||||
| #define LOG_FILTER_ALL	0x0001 | ||||
|  | ||||
| struct log_category { | ||||
| 	uint8_t loglevel; | ||||
| 	uint8_t enabled; | ||||
| }; | ||||
|  | ||||
| struct log_info_cat { | ||||
| 	const char *name; | ||||
| 	const char *color; | ||||
| 	const char *description; | ||||
| 	uint8_t loglevel; | ||||
| 	uint8_t enabled; | ||||
| }; | ||||
|  | ||||
| /* log context information, passed to filter */ | ||||
| struct log_context { | ||||
| 	void *ctx[LOG_MAX_CTX+1]; | ||||
| }; | ||||
|  | ||||
| struct log_target; | ||||
|  | ||||
| typedef int log_filter(const struct log_context *ctx, | ||||
| 		       struct log_target *target); | ||||
|  | ||||
| struct log_info { | ||||
| 	/* filter callback function */ | ||||
| 	log_filter *filter_fn; | ||||
|  | ||||
| 	/* per-category information */ | ||||
| 	const struct log_info_cat *cat; | ||||
| 	unsigned int num_cat; | ||||
| }; | ||||
|  | ||||
| struct log_target { | ||||
|         struct llist_head entry; | ||||
|  | ||||
| 	int filter_map; | ||||
| 	void *filter_data[LOG_MAX_FILTERS+1]; | ||||
|  | ||||
| 	struct log_category categories[LOG_MAX_CATEGORY+1]; | ||||
| 	uint8_t loglevel; | ||||
| 	int use_color:1; | ||||
| 	int print_timestamp:1; | ||||
|  | ||||
| 	union { | ||||
| 		struct { | ||||
| 			FILE *out; | ||||
| 		} tgt_stdout; | ||||
|  | ||||
| 		struct { | ||||
| 			int priority; | ||||
| 		} tgt_syslog; | ||||
|  | ||||
| 		struct { | ||||
| 			void *vty; | ||||
| 		} tgt_vty; | ||||
| 	}; | ||||
|  | ||||
|         void (*output) (struct log_target *target, const char *string); | ||||
| }; | ||||
|  | ||||
| /* use the above macros */ | ||||
| void logp2(unsigned int subsys, unsigned int level, char *file, | ||||
| 	   int line, int cont, const char *format, ...) | ||||
| 				__attribute__ ((format (printf, 6, 7))); | ||||
| void log_init(const struct log_info *cat); | ||||
|  | ||||
| /* context management */ | ||||
| void log_reset_context(void); | ||||
| int log_set_context(uint8_t ctx, void *value); | ||||
|  | ||||
| /* filter on the targets */ | ||||
| void log_set_all_filter(struct log_target *target, int); | ||||
|  | ||||
| void log_set_use_color(struct log_target *target, int); | ||||
| void log_set_print_timestamp(struct log_target *target, int); | ||||
| void log_set_log_level(struct log_target *target, int log_level); | ||||
| void log_parse_category_mask(struct log_target *target, const char* mask); | ||||
| int log_parse_level(const char *lvl); | ||||
| int log_parse_category(const char *category); | ||||
| void log_set_category_filter(struct log_target *target, int category, | ||||
| 			       int enable, int level); | ||||
|  | ||||
| /* management of the targets */ | ||||
| struct log_target *log_target_create(void); | ||||
| struct log_target *log_target_create_stderr(void); | ||||
| void log_add_target(struct log_target *target); | ||||
| void log_del_target(struct log_target *target); | ||||
|  | ||||
| #endif /* _OSMOCORE_LOGGING_H */ | ||||
							
								
								
									
										71
									
								
								libosmocore/include/osmocore/mncc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								libosmocore/include/osmocore/mncc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| #ifndef _OSMOCORE_MNCC_H | ||||
| #define _OSMOCORE_MNCC_H | ||||
|  | ||||
| #define GSM_MAX_FACILITY       128 | ||||
| #define GSM_MAX_SSVERSION      128 | ||||
| #define GSM_MAX_USERUSER       128 | ||||
|  | ||||
| /* Expanded fields from GSM TS 04.08, Table 10.5.102 */ | ||||
| struct gsm_mncc_bearer_cap { | ||||
| 	int		transfer;	/* Information Transfer Capability */ | ||||
| 	int 		mode;		/* Transfer Mode */ | ||||
| 	int		coding;		/* Coding Standard */ | ||||
| 	int		radio;		/* Radio Channel Requirement */ | ||||
| 	int		speech_ctm;	/* CTM text telephony indication */ | ||||
| 	int		speech_ver[8];	/* Speech version indication */ | ||||
| }; | ||||
|  | ||||
| struct gsm_mncc_number { | ||||
| 	int 		type; | ||||
| 	int 		plan; | ||||
| 	int		present; | ||||
| 	int		screen; | ||||
| 	char		number[33]; | ||||
| }; | ||||
|  | ||||
| struct gsm_mncc_cause { | ||||
| 	int		location; | ||||
| 	int		coding; | ||||
| 	int		rec; | ||||
| 	int		rec_val; | ||||
| 	int		value; | ||||
| 	int		diag_len; | ||||
| 	char		diag[32]; | ||||
| }; | ||||
|  | ||||
| struct gsm_mncc_useruser { | ||||
| 	int		proto; | ||||
| 	char		info[GSM_MAX_USERUSER + 1]; /* + termination char */ | ||||
| }; | ||||
|  | ||||
| struct gsm_mncc_progress { | ||||
| 	int		coding; | ||||
| 	int		location; | ||||
| 	int 		descr; | ||||
| }; | ||||
|  | ||||
| struct gsm_mncc_facility { | ||||
| 	int		len; | ||||
| 	char		info[GSM_MAX_FACILITY]; | ||||
| }; | ||||
|  | ||||
| struct gsm_mncc_ssversion { | ||||
| 	int		len; | ||||
| 	char		info[GSM_MAX_SSVERSION]; | ||||
| }; | ||||
|  | ||||
| struct gsm_mncc_cccap { | ||||
| 	int		dtmf; | ||||
| 	int		pcp; | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	GSM_MNCC_BCAP_SPEECH	= 0, | ||||
| 	GSM_MNCC_BCAP_UNR_DIG	= 1, | ||||
| 	GSM_MNCC_BCAP_AUDIO	= 2, | ||||
| 	GSM_MNCC_BCAP_FAX_G3	= 3, | ||||
| 	GSM_MNCC_BCAP_OTHER_ITC = 5, | ||||
| 	GSM_MNCC_BCAP_RESERVED	= 7, | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										175
									
								
								libosmocore/include/osmocore/msgb.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								libosmocore/include/osmocore/msgb.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,175 @@ | ||||
| #ifndef _MSGB_H | ||||
| #define _MSGB_H | ||||
|  | ||||
| /* (C) 2008 by Harald Welte <laforge@gnumonks.org> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include "linuxlist.h" | ||||
|  | ||||
| struct bts_link; | ||||
|  | ||||
| struct msgb { | ||||
| 	struct llist_head list; | ||||
|  | ||||
| 	/* ptr to the physical E1 link to the BTS(s) */ | ||||
| 	struct gsm_bts_link *bts_link; | ||||
|  | ||||
| 	/* Part of which TRX logical channel we were received / transmitted */ | ||||
| 	struct gsm_bts_trx *trx; | ||||
| 	struct gsm_lchan *lchan; | ||||
|  | ||||
| 	/* the Layer1 header (if any) */ | ||||
| 	unsigned char *l1h; | ||||
| 	/* the A-bis layer 2 header: OML, RSL(RLL), NS */ | ||||
| 	unsigned char *l2h; | ||||
| 	/* the layer 3 header. For OML: FOM; RSL: 04.08; GPRS: BSSGP */ | ||||
| 	unsigned char *l3h; | ||||
|  | ||||
| 	/* the layer 4 header */ | ||||
| 	union { | ||||
| 		unsigned char *smsh; | ||||
| 		unsigned char *llch; | ||||
| 		unsigned char *l4h; | ||||
| 	}; | ||||
|  | ||||
| 	/* the layer 5 header, GPRS: GMM header */ | ||||
| 	unsigned char *gmmh; | ||||
| 	uint32_t tlli; | ||||
|  | ||||
| 	uint16_t data_len; | ||||
| 	uint16_t len; | ||||
|  | ||||
| 	unsigned char *head; | ||||
| 	unsigned char *tail; | ||||
| 	unsigned char *data; | ||||
| 	unsigned char _data[0]; | ||||
| }; | ||||
|  | ||||
| extern struct msgb *msgb_alloc(uint16_t size, const char *name); | ||||
| extern void msgb_free(struct msgb *m); | ||||
| extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg); | ||||
| extern struct msgb *msgb_dequeue(struct llist_head *queue); | ||||
| extern void msgb_reset(struct msgb *m); | ||||
|  | ||||
| #define msgb_l1(m)	((void *)(m->l1h)) | ||||
| #define msgb_l2(m)	((void *)(m->l2h)) | ||||
| #define msgb_l3(m)	((void *)(m->l3h)) | ||||
| #define msgb_sms(m)	((void *)(m->smsh)) | ||||
|  | ||||
| static inline unsigned int msgb_l1len(const struct msgb *msgb) | ||||
| { | ||||
| 	return msgb->tail - (uint8_t *)msgb_l1(msgb); | ||||
| } | ||||
|  | ||||
| static inline unsigned int msgb_l2len(const struct msgb *msgb) | ||||
| { | ||||
| 	return msgb->tail - (uint8_t *)msgb_l2(msgb); | ||||
| } | ||||
|  | ||||
| static inline unsigned int msgb_l3len(const struct msgb *msgb) | ||||
| { | ||||
| 	return msgb->tail - (uint8_t *)msgb_l3(msgb); | ||||
| } | ||||
|  | ||||
| static inline unsigned int msgb_headlen(const struct msgb *msgb) | ||||
| { | ||||
| 	return msgb->len - msgb->data_len; | ||||
| } | ||||
| static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len) | ||||
| { | ||||
| 	unsigned char *tmp = msgb->tail; | ||||
| 	msgb->tail += len; | ||||
| 	msgb->len += len; | ||||
| 	return tmp; | ||||
| } | ||||
| static inline void msgb_put_u8(struct msgb *msgb, uint8_t word) | ||||
| { | ||||
| 	uint8_t *space = msgb_put(msgb, 1); | ||||
| 	space[0] = word & 0xFF; | ||||
| } | ||||
| static inline void msgb_put_u16(struct msgb *msgb, uint16_t word) | ||||
| { | ||||
| 	uint8_t *space = msgb_put(msgb, 2); | ||||
| 	space[0] = word >> 8 & 0xFF; | ||||
| 	space[1] = word & 0xFF; | ||||
| } | ||||
| static inline void msgb_put_u32(struct msgb *msgb, uint32_t word) | ||||
| { | ||||
| 	uint8_t *space = msgb_put(msgb, 4); | ||||
| 	space[0] = word >> 24 & 0xFF; | ||||
| 	space[1] = word >> 16 & 0xFF; | ||||
| 	space[2] = word >> 8 & 0xFF; | ||||
| 	space[3] = word & 0xFF; | ||||
| } | ||||
| static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len) | ||||
| { | ||||
| 	unsigned char *tmp = msgb->data; | ||||
| 	msgb->data += len; | ||||
| 	msgb->len -= len; | ||||
| 	return tmp; | ||||
| } | ||||
| static inline uint8_t msgb_get_u8(struct msgb *msgb) | ||||
| { | ||||
| 	uint8_t *space = msgb_get(msgb, 1); | ||||
| 	return space[0]; | ||||
| } | ||||
| static inline uint16_t msgb_get_u16(struct msgb *msgb) | ||||
| { | ||||
| 	uint8_t *space = msgb_get(msgb, 2); | ||||
| 	return space[0] << 8 | space[1]; | ||||
| } | ||||
| static inline uint32_t msgb_get_u32(struct msgb *msgb) | ||||
| { | ||||
| 	uint8_t *space = msgb_get(msgb, 4); | ||||
| 	return space[0] << 24 | space[1] << 16 | space[2] << 8 | space[3]; | ||||
| } | ||||
| static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len) | ||||
| { | ||||
| 	msgb->data -= len; | ||||
| 	msgb->len += len; | ||||
| 	return msgb->data; | ||||
| } | ||||
| static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len) | ||||
| { | ||||
| 	msgb->len -= len; | ||||
| 	return msgb->data += len; | ||||
| } | ||||
| static inline int msgb_tailroom(const struct msgb *msgb) | ||||
| { | ||||
| 	return (msgb->head + msgb->data_len) - msgb->tail; | ||||
| } | ||||
|  | ||||
| /* increase the headroom of an empty msgb, reducing the tailroom */ | ||||
| static inline void msgb_reserve(struct msgb *msg, int len) | ||||
| { | ||||
| 	msg->data += len; | ||||
| 	msg->tail += len; | ||||
| } | ||||
|  | ||||
| static inline struct msgb *msgb_alloc_headroom(int size, int headroom, | ||||
| 						const char *name) | ||||
| { | ||||
| 	struct msgb *msg = msgb_alloc(size, name); | ||||
| 	if (msg) | ||||
| 		msgb_reserve(msg, headroom); | ||||
| 	return msg; | ||||
| } | ||||
|  | ||||
| #endif /* _MSGB_H */ | ||||
							
								
								
									
										3
									
								
								libosmocore/include/osmocore/protocol/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								libosmocore/include/osmocore/protocol/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| osmocore_proto_HEADERS = gsm_04_08.h gsm_04_11.h gsm_04_80.h gsm_08_58.h gsm_12_21.h | ||||
|  | ||||
| osmocore_protodir = $(includedir)/osmocore/protocol | ||||
							
								
								
									
										743
									
								
								libosmocore/include/osmocore/protocol/gsm_04_08.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										743
									
								
								libosmocore/include/osmocore/protocol/gsm_04_08.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,743 @@ | ||||
| #ifndef PROTO_GSM_04_08_H | ||||
| #define PROTO_GSM_04_08_H | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| /* GSM TS 04.08  definitions */ | ||||
| struct gsm_lchan; | ||||
|  | ||||
| struct gsm48_classmark1 { | ||||
| 	uint8_t spare:1, | ||||
| 		 rev_level:2, | ||||
| 		 es_ind:1, | ||||
| 		 a5_1:1, | ||||
| 		 pwr_lev:3; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Chapter 10.5.2.5 */ | ||||
| struct gsm48_chan_desc { | ||||
| 	uint8_t chan_nr; | ||||
| 	union { | ||||
| 		struct { | ||||
| 			uint8_t maio_high:4, | ||||
| 				 h:1, | ||||
| 				 tsc:3; | ||||
| 			uint8_t hsn:6, | ||||
| 				 maio_low:2; | ||||
| 		} h1; | ||||
| 		struct { | ||||
| 			uint8_t arfcn_high:2, | ||||
| 				 spare:2, | ||||
| 				 h:1, | ||||
| 				 tsc:3; | ||||
| 			uint8_t arfcn_low; | ||||
| 		} h0; | ||||
| 	}; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Chapter 10.5.2.21aa */ | ||||
| struct gsm48_multi_rate_conf { | ||||
| 	uint8_t smod : 2, | ||||
| 		 spare: 1, | ||||
| 		 icmi : 1, | ||||
| 		 nscb : 1, | ||||
| 		 ver : 3; | ||||
| 	uint8_t m4_75 : 1, | ||||
| 		 m5_15 : 1, | ||||
| 		 m5_90 : 1, | ||||
| 		 m6_70 : 1, | ||||
| 		 m7_40 : 1, | ||||
| 		 m7_95 : 1, | ||||
| 		 m10_2 : 1, | ||||
| 		 m12_2 : 1; | ||||
| } __attribute__((packed)); | ||||
|  | ||||
| /* Chapter 10.5.2.30 */ | ||||
| struct gsm48_req_ref { | ||||
| 	uint8_t ra; | ||||
| 	uint8_t t3_high:3, | ||||
| 		 t1_:5; | ||||
| 	uint8_t t2:5, | ||||
| 		 t3_low:3; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* | ||||
|  * Chapter 9.1.5/9.1.6 | ||||
|  * | ||||
|  * For 9.1.6 the chan_desc has the meaning of 10.5.2.5a | ||||
|  */ | ||||
| struct gsm48_chan_mode_modify { | ||||
| 	struct gsm48_chan_desc chan_desc; | ||||
| 	uint8_t mode; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| enum gsm48_chan_mode { | ||||
| 	GSM48_CMODE_SIGN	= 0x00, | ||||
| 	GSM48_CMODE_SPEECH_V1	= 0x01, | ||||
| 	GSM48_CMODE_SPEECH_EFR	= 0x21, | ||||
| 	GSM48_CMODE_SPEECH_AMR	= 0x41, | ||||
| 	GSM48_CMODE_DATA_14k5	= 0x0f, | ||||
| 	GSM48_CMODE_DATA_12k0	= 0x03, | ||||
| 	GSM48_CMODE_DATA_6k0	= 0x0b, | ||||
| 	GSM48_CMODE_DATA_3k6	= 0x23, | ||||
| }; | ||||
|  | ||||
| /* Chapter 9.1.2 */ | ||||
| struct gsm48_ass_cmd { | ||||
| 	/* Semantic is from 10.5.2.5a */ | ||||
| 	struct gsm48_chan_desc chan_desc; | ||||
| 	uint8_t power_command; | ||||
| 	uint8_t data[0]; | ||||
| } __attribute__((packed)); | ||||
|  | ||||
| /* Chapter 10.5.2.2 */ | ||||
| struct gsm48_cell_desc { | ||||
| 	uint8_t bcc:3, | ||||
| 		 ncc:3, | ||||
| 		 arfcn_hi:2; | ||||
| 	uint8_t arfcn_lo; | ||||
| } __attribute__((packed)); | ||||
|  | ||||
| /* Chapter 9.1.15 */ | ||||
| struct gsm48_ho_cmd { | ||||
| 	struct gsm48_cell_desc cell_desc; | ||||
| 	struct gsm48_chan_desc chan_desc; | ||||
| 	uint8_t ho_ref; | ||||
| 	uint8_t power_command; | ||||
| 	uint8_t data[0]; | ||||
| } __attribute__((packed)); | ||||
|  | ||||
| /* Chapter 9.1.18 */ | ||||
| struct gsm48_imm_ass { | ||||
| 	uint8_t l2_plen; | ||||
| 	uint8_t proto_discr; | ||||
| 	uint8_t msg_type; | ||||
| 	uint8_t page_mode; | ||||
| 	struct gsm48_chan_desc chan_desc; | ||||
| 	struct gsm48_req_ref req_ref; | ||||
| 	uint8_t timing_advance; | ||||
| 	uint8_t mob_alloc_len; | ||||
| 	uint8_t mob_alloc[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Chapter 10.5.1.3 */ | ||||
| struct gsm48_loc_area_id { | ||||
| 	uint8_t digits[3];	/* BCD! */ | ||||
| 	uint16_t lac; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.2.2 */ | ||||
| struct gsm48_auth_req { | ||||
| 	uint8_t key_seq:4, | ||||
| 	         spare:4; | ||||
| 	uint8_t rand[16]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.2.15 */ | ||||
| struct gsm48_loc_upd_req { | ||||
| 	uint8_t type:4, | ||||
| 		 key_seq:4; | ||||
| 	struct gsm48_loc_area_id lai; | ||||
| 	struct gsm48_classmark1 classmark1; | ||||
| 	uint8_t mi_len; | ||||
| 	uint8_t mi[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 10.1 */ | ||||
| struct gsm48_hdr { | ||||
| 	uint8_t proto_discr; | ||||
| 	uint8_t msg_type; | ||||
| 	uint8_t data[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.1.3x System information Type header */ | ||||
| struct gsm48_system_information_type_header { | ||||
| 	uint8_t l2_plen; | ||||
| 	uint8_t rr_protocol_discriminator :4, | ||||
| 		skip_indicator:4;  | ||||
| 	uint8_t system_information; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| struct gsm48_rach_control { | ||||
| 	uint8_t re :1, | ||||
| 		 cell_bar :1, | ||||
| 		 tx_integer :4, | ||||
| 		 max_trans :2; | ||||
| 	uint8_t t2; | ||||
| 	uint8_t t3; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 10.5.2.4 Cell Selection Parameters */ | ||||
| struct gsm48_cell_sel_par { | ||||
| 	uint8_t ms_txpwr_max_ccch:5,	/* GSM 05.08 MS-TXPWR-MAX-CCCH */ | ||||
| 		 cell_resel_hyst:3;	/* GSM 05.08 CELL-RESELECT-HYSTERESIS */ | ||||
| 	uint8_t rxlev_acc_min:6,	/* GSM 05.08 RXLEV-ACCESS-MIN */ | ||||
| 		 neci:1, | ||||
| 		 acs:1; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 10.5.2.11 Control Channel Description , Figure 10.5.33 */ | ||||
| struct gsm48_control_channel_descr { | ||||
| 	uint8_t ccch_conf :3, | ||||
| 		bs_ag_blks_res :3, | ||||
| 		att :1, | ||||
| 		spare1 :1; | ||||
| 	uint8_t bs_pa_mfrms : 3, | ||||
| 		spare2 :5; | ||||
| 	uint8_t t3212; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| struct gsm48_cell_options { | ||||
| 	uint8_t radio_link_timeout:4, | ||||
| 		 dtx:2, | ||||
| 		 pwrc:1, | ||||
| 		 spare:1; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.2.9 CM service request */ | ||||
| struct gsm48_service_request { | ||||
| 	uint8_t cm_service_type : 4, | ||||
| 		 cipher_key_seq  : 4; | ||||
| 	/* length + 3 bytes */ | ||||
| 	uint32_t classmark; | ||||
| 	uint8_t mi_len; | ||||
| 	uint8_t mi[0]; | ||||
| 	/* optional priority level */ | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.1.31 System information Type 1 */ | ||||
| struct gsm48_system_information_type_1 { | ||||
| 	struct gsm48_system_information_type_header header; | ||||
| 	uint8_t cell_channel_description[16]; | ||||
| 	struct gsm48_rach_control rach_control; | ||||
| 	uint8_t rest_octets[0]; /* NCH position on the CCCH */ | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.1.32 System information Type 2 */ | ||||
| struct gsm48_system_information_type_2 { | ||||
| 	struct gsm48_system_information_type_header header; | ||||
| 	uint8_t bcch_frequency_list[16]; | ||||
| 	uint8_t ncc_permitted; | ||||
| 	struct gsm48_rach_control rach_control; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.1.35 System information Type 3 */ | ||||
| struct gsm48_system_information_type_3 { | ||||
| 	struct gsm48_system_information_type_header header; | ||||
| 	uint16_t cell_identity; | ||||
| 	struct gsm48_loc_area_id lai; | ||||
| 	struct gsm48_control_channel_descr control_channel_desc; | ||||
| 	struct gsm48_cell_options cell_options; | ||||
| 	struct gsm48_cell_sel_par cell_sel_par; | ||||
| 	struct gsm48_rach_control rach_control; | ||||
| 	uint8_t rest_octets[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.1.36 System information Type 4 */ | ||||
| struct gsm48_system_information_type_4 { | ||||
| 	struct gsm48_system_information_type_header header; | ||||
| 	struct gsm48_loc_area_id lai; | ||||
| 	struct gsm48_cell_sel_par cell_sel_par; | ||||
| 	struct gsm48_rach_control rach_control; | ||||
| 	/*	optional CBCH conditional CBCH... followed by | ||||
| 		mandantory SI 4 Reset Octets | ||||
| 	 */ | ||||
| 	uint8_t data[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.1.37 System information Type 5 */ | ||||
| struct gsm48_system_information_type_5 { | ||||
| 	uint8_t rr_protocol_discriminator :4, | ||||
| 		skip_indicator:4;  | ||||
| 	uint8_t system_information; | ||||
| 	uint8_t bcch_frequency_list[16]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.1.40 System information Type 6 */ | ||||
| struct gsm48_system_information_type_6 { | ||||
| 	uint8_t rr_protocol_discriminator :4, | ||||
| 		skip_indicator:4;  | ||||
| 	uint8_t system_information; | ||||
| 	uint16_t cell_identity; | ||||
| 	struct gsm48_loc_area_id lai; | ||||
| 	struct gsm48_cell_options cell_options; | ||||
| 	uint8_t ncc_permitted; | ||||
| 	uint8_t rest_octets[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.1.43a System Information type 13 */ | ||||
| struct gsm48_system_information_type_13 { | ||||
| 	struct gsm48_system_information_type_header header; | ||||
| 	uint8_t rest_octets[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 9.2.12 IMSI Detach Indication */ | ||||
| struct gsm48_imsi_detach_ind { | ||||
| 	struct gsm48_classmark1 classmark1; | ||||
| 	uint8_t mi_len; | ||||
| 	uint8_t mi[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Section 10.2 + GSM 04.07 12.2.3.1.1 */ | ||||
| #define GSM48_PDISC_GROUP_CC	0x00 | ||||
| #define GSM48_PDISC_BCAST_CC	0x01 | ||||
| #define GSM48_PDISC_PDSS1	0x02 | ||||
| #define GSM48_PDISC_CC		0x03 | ||||
| #define GSM48_PDISC_PDSS2	0x04 | ||||
| #define GSM48_PDISC_MM		0x05 | ||||
| #define GSM48_PDISC_RR		0x06 | ||||
| #define GSM48_PDISC_MM_GPRS	0x08 | ||||
| #define GSM48_PDISC_SMS		0x09 | ||||
| #define GSM48_PDISC_SM_GPRS	0x0a | ||||
| #define GSM48_PDISC_NC_SS	0x0b | ||||
| #define GSM48_PDISC_LOC		0x0c | ||||
| #define GSM48_PDISC_MASK	0x0f | ||||
| #define GSM48_PDISC_USSD	0x11 | ||||
|  | ||||
| /* Section 10.4 */ | ||||
| #define GSM48_MT_RR_INIT_REQ		0x3c | ||||
| #define GSM48_MT_RR_ADD_ASS		0x3b | ||||
| #define GSM48_MT_RR_IMM_ASS		0x3f | ||||
| #define GSM48_MT_RR_IMM_ASS_EXT		0x39 | ||||
| #define GSM48_MT_RR_IMM_ASS_REJ		0x3a | ||||
|  | ||||
| #define GSM48_MT_RR_CIPH_M_CMD		0x35 | ||||
| #define GSM48_MT_RR_CIPH_M_COMPL	0x32 | ||||
|  | ||||
| #define GSM48_MT_RR_CFG_CHG_CMD		0x30 | ||||
| #define GSM48_MT_RR_CFG_CHG_ACK		0x31 | ||||
| #define GSM48_MT_RR_CFG_CHG_REJ		0x33 | ||||
|  | ||||
| #define GSM48_MT_RR_ASS_CMD		0x2e | ||||
| #define GSM48_MT_RR_ASS_COMPL		0x29 | ||||
| #define GSM48_MT_RR_ASS_FAIL		0x2f | ||||
| #define GSM48_MT_RR_HANDO_CMD		0x2b | ||||
| #define GSM48_MT_RR_HANDO_COMPL		0x2c | ||||
| #define GSM48_MT_RR_HANDO_FAIL		0x28 | ||||
| #define GSM48_MT_RR_HANDO_INFO		0x2d | ||||
|  | ||||
| #define GSM48_MT_RR_CELL_CHG_ORDER	0x08 | ||||
| #define GSM48_MT_RR_PDCH_ASS_CMD	0x23 | ||||
|  | ||||
| #define GSM48_MT_RR_CHAN_REL		0x0d | ||||
| #define GSM48_MT_RR_PART_REL		0x0a | ||||
| #define GSM48_MT_RR_PART_REL_COMP	0x0f | ||||
|  | ||||
| #define GSM48_MT_RR_PAG_REQ_1		0x21 | ||||
| #define GSM48_MT_RR_PAG_REQ_2		0x22 | ||||
| #define GSM48_MT_RR_PAG_REQ_3		0x24 | ||||
| #define GSM48_MT_RR_PAG_RESP		0x27 | ||||
| #define GSM48_MT_RR_NOTIF_NCH		0x20 | ||||
| #define GSM48_MT_RR_NOTIF_FACCH		0x25 | ||||
| #define GSM48_MT_RR_NOTIF_RESP		0x26 | ||||
|  | ||||
| #define GSM48_MT_RR_SYSINFO_8		0x18 | ||||
| #define GSM48_MT_RR_SYSINFO_1		0x19 | ||||
| #define GSM48_MT_RR_SYSINFO_2		0x1a | ||||
| #define GSM48_MT_RR_SYSINFO_3		0x1b | ||||
| #define GSM48_MT_RR_SYSINFO_4		0x1c | ||||
| #define GSM48_MT_RR_SYSINFO_5		0x1d | ||||
| #define GSM48_MT_RR_SYSINFO_6		0x1e | ||||
| #define GSM48_MT_RR_SYSINFO_7		0x1f | ||||
|  | ||||
| #define GSM48_MT_RR_SYSINFO_2bis	0x02 | ||||
| #define GSM48_MT_RR_SYSINFO_2ter	0x03 | ||||
| #define GSM48_MT_RR_SYSINFO_5bis	0x05 | ||||
| #define GSM48_MT_RR_SYSINFO_5ter	0x06 | ||||
| #define GSM48_MT_RR_SYSINFO_9		0x04 | ||||
| #define GSM48_MT_RR_SYSINFO_13		0x00 | ||||
|  | ||||
| #define GSM48_MT_RR_SYSINFO_16		0x3d | ||||
| #define GSM48_MT_RR_SYSINFO_17		0x3e | ||||
|  | ||||
| #define GSM48_MT_RR_CHAN_MODE_MODIF	0x10 | ||||
| #define GSM48_MT_RR_STATUS		0x12 | ||||
| #define GSM48_MT_RR_CHAN_MODE_MODIF_ACK	0x17 | ||||
| #define GSM48_MT_RR_FREQ_REDEF		0x14 | ||||
| #define GSM48_MT_RR_MEAS_REP		0x15 | ||||
| #define GSM48_MT_RR_CLSM_CHG		0x16 | ||||
| #define GSM48_MT_RR_CLSM_ENQ		0x13 | ||||
| #define GSM48_MT_RR_EXT_MEAS_REP	0x36 | ||||
| #define GSM48_MT_RR_EXT_MEAS_REP_ORD	0x37 | ||||
| #define GSM48_MT_RR_GPRS_SUSP_REQ	0x34 | ||||
|  | ||||
| #define GSM48_MT_RR_VGCS_UPL_GRANT	0x08 | ||||
| #define GSM48_MT_RR_UPLINK_RELEASE	0x0e | ||||
| #define GSM48_MT_RR_UPLINK_FREE		0x0c | ||||
| #define GSM48_MT_RR_UPLINK_BUSY		0x2a | ||||
| #define GSM48_MT_RR_TALKER_IND		0x11 | ||||
|  | ||||
| #define GSM48_MT_RR_APP_INFO		0x38 | ||||
|  | ||||
| /* Table 10.2/3GPP TS 04.08 */ | ||||
| #define GSM48_MT_MM_IMSI_DETACH_IND	0x01 | ||||
| #define GSM48_MT_MM_LOC_UPD_ACCEPT	0x02 | ||||
| #define GSM48_MT_MM_LOC_UPD_REJECT	0x04 | ||||
| #define GSM48_MT_MM_LOC_UPD_REQUEST	0x08 | ||||
|  | ||||
| #define GSM48_MT_MM_AUTH_REJ		0x11 | ||||
| #define GSM48_MT_MM_AUTH_REQ		0x12 | ||||
| #define GSM48_MT_MM_AUTH_RESP		0x14 | ||||
| #define GSM48_MT_MM_ID_REQ		0x18 | ||||
| #define GSM48_MT_MM_ID_RESP		0x19 | ||||
| #define GSM48_MT_MM_TMSI_REALL_CMD	0x1a | ||||
| #define GSM48_MT_MM_TMSI_REALL_COMPL	0x1b | ||||
|  | ||||
| #define GSM48_MT_MM_CM_SERV_ACC		0x21 | ||||
| #define GSM48_MT_MM_CM_SERV_REJ		0x22 | ||||
| #define GSM48_MT_MM_CM_SERV_ABORT	0x23 | ||||
| #define GSM48_MT_MM_CM_SERV_REQ		0x24 | ||||
| #define GSM48_MT_MM_CM_SERV_PROMPT	0x25 | ||||
| #define GSM48_MT_MM_CM_REEST_REQ	0x28 | ||||
| #define GSM48_MT_MM_ABORT		0x29 | ||||
|  | ||||
| #define GSM48_MT_MM_NULL		0x30 | ||||
| #define GSM48_MT_MM_STATUS		0x31 | ||||
| #define GSM48_MT_MM_INFO		0x32 | ||||
|  | ||||
| /* Table 10.3/3GPP TS 04.08 */ | ||||
| #define GSM48_MT_CC_ALERTING		0x01 | ||||
| #define GSM48_MT_CC_CALL_CONF		0x08 | ||||
| #define GSM48_MT_CC_CALL_PROC		0x02 | ||||
| #define GSM48_MT_CC_CONNECT		0x07 | ||||
| #define GSM48_MT_CC_CONNECT_ACK		0x0f | ||||
| #define GSM48_MT_CC_EMERG_SETUP		0x0e | ||||
| #define GSM48_MT_CC_PROGRESS		0x03 | ||||
| #define GSM48_MT_CC_ESTAB		0x04 | ||||
| #define GSM48_MT_CC_ESTAB_CONF		0x06 | ||||
| #define GSM48_MT_CC_RECALL		0x0b | ||||
| #define GSM48_MT_CC_START_CC		0x09 | ||||
| #define GSM48_MT_CC_SETUP		0x05 | ||||
|  | ||||
| #define GSM48_MT_CC_MODIFY		0x17 | ||||
| #define GSM48_MT_CC_MODIFY_COMPL	0x1f | ||||
| #define GSM48_MT_CC_MODIFY_REJECT	0x13 | ||||
| #define GSM48_MT_CC_USER_INFO		0x10 | ||||
| #define GSM48_MT_CC_HOLD		0x18 | ||||
| #define GSM48_MT_CC_HOLD_ACK		0x19 | ||||
| #define GSM48_MT_CC_HOLD_REJ		0x1a | ||||
| #define GSM48_MT_CC_RETR		0x1c | ||||
| #define GSM48_MT_CC_RETR_ACK		0x1d | ||||
| #define GSM48_MT_CC_RETR_REJ		0x1e | ||||
|  | ||||
| #define GSM48_MT_CC_DISCONNECT		0x25 | ||||
| #define GSM48_MT_CC_RELEASE		0x2d | ||||
| #define GSM48_MT_CC_RELEASE_COMPL	0x2a | ||||
|  | ||||
| #define GSM48_MT_CC_CONG_CTRL		0x39 | ||||
| #define GSM48_MT_CC_NOTIFY		0x3e | ||||
| #define GSM48_MT_CC_STATUS		0x3d | ||||
| #define GSM48_MT_CC_STATUS_ENQ		0x34 | ||||
| #define GSM48_MT_CC_START_DTMF		0x35 | ||||
| #define GSM48_MT_CC_STOP_DTMF		0x31 | ||||
| #define GSM48_MT_CC_STOP_DTMF_ACK	0x32 | ||||
| #define GSM48_MT_CC_START_DTMF_ACK	0x36 | ||||
| #define GSM48_MT_CC_START_DTMF_REJ	0x37 | ||||
| #define GSM48_MT_CC_FACILITY		0x3a | ||||
|  | ||||
| /* FIXME: Table 10.4 / 10.4a (GPRS) */ | ||||
|  | ||||
| /* Section 10.5.2.26, Table 10.5.64 */ | ||||
| #define GSM48_PM_MASK		0x03 | ||||
| #define GSM48_PM_NORMAL		0x00 | ||||
| #define GSM48_PM_EXTENDED	0x01 | ||||
| #define GSM48_PM_REORG		0x02 | ||||
| #define GSM48_PM_SAME		0x03 | ||||
|  | ||||
| /* Chapter 10.5.3.5 / Table 10.5.93 */ | ||||
| #define GSM48_LUPD_NORMAL	0x0 | ||||
| #define GSM48_LUPD_PERIODIC	0x1 | ||||
| #define GSM48_LUPD_IMSI_ATT	0x2 | ||||
| #define GSM48_LUPD_RESERVED	0x3 | ||||
|  | ||||
| /* Table 10.5.4 */ | ||||
| #define GSM_MI_TYPE_MASK	0x07 | ||||
| #define GSM_MI_TYPE_NONE	0x00 | ||||
| #define GSM_MI_TYPE_IMSI	0x01 | ||||
| #define GSM_MI_TYPE_IMEI	0x02 | ||||
| #define GSM_MI_TYPE_IMEISV	0x03 | ||||
| #define GSM_MI_TYPE_TMSI	0x04 | ||||
| #define GSM_MI_ODD		0x08 | ||||
|  | ||||
| #define GSM48_IE_MUL_RATE_CFG	0x03	/* 10.5.2.21aa */ | ||||
| #define GSM48_IE_MOBILE_ID	0x17 | ||||
| #define GSM48_IE_NAME_LONG	0x43	/* 10.5.3.5a */ | ||||
| #define GSM48_IE_NAME_SHORT	0x45	/* 10.5.3.5a */ | ||||
| #define GSM48_IE_UTC		0x46	/* 10.5.3.8 */ | ||||
| #define GSM48_IE_NET_TIME_TZ	0x47	/* 10.5.3.9 */ | ||||
| #define GSM48_IE_LSA_IDENT	0x48	/* 10.5.3.11 */ | ||||
|  | ||||
| #define GSM48_IE_BEARER_CAP	0x04	/* 10.5.4.5 */ | ||||
| #define GSM48_IE_CAUSE		0x08	/* 10.5.4.11 */ | ||||
| #define GSM48_IE_CC_CAP		0x15	/* 10.5.4.5a */ | ||||
| #define GSM48_IE_ALERT		0x19	/* 10.5.4.26 */ | ||||
| #define GSM48_IE_FACILITY	0x1c	/* 10.5.4.15 */ | ||||
| #define GSM48_IE_PROGR_IND	0x1e	/* 10.5.4.21 */ | ||||
| #define GSM48_IE_AUX_STATUS	0x24	/* 10.5.4.4 */ | ||||
| #define GSM48_IE_NOTIFY		0x27	/* 10.5.4.20 */ | ||||
| #define GSM48_IE_KPD_FACILITY	0x2c	/* 10.5.4.17 */ | ||||
| #define GSM48_IE_SIGNAL		0x34	/* 10.5.4.23 */ | ||||
| #define GSM48_IE_CONN_BCD	0x4c	/* 10.5.4.13 */ | ||||
| #define GSM48_IE_CONN_SUB	0x4d	/* 10.5.4.14 */ | ||||
| #define GSM48_IE_CALLING_BCD	0x5c	/* 10.5.4.9 */ | ||||
| #define GSM48_IE_CALLING_SUB	0x5d	/* 10.5.4.10 */ | ||||
| #define GSM48_IE_CALLED_BCD	0x5e	/* 10.5.4.7 */ | ||||
| #define GSM48_IE_CALLED_SUB	0x6d	/* 10.5.4.8 */ | ||||
| #define GSM48_IE_REDIR_BCD	0x74	/* 10.5.4.21a */ | ||||
| #define GSM48_IE_REDIR_SUB	0x75	/* 10.5.4.21b */ | ||||
| #define GSM48_IE_LOWL_COMPAT	0x7c	/* 10.5.4.18 */ | ||||
| #define GSM48_IE_HIGHL_COMPAT	0x7d	/* 10.5.4.16 */ | ||||
| #define GSM48_IE_USER_USER	0x7e	/* 10.5.4.25 */ | ||||
| #define GSM48_IE_SS_VERS	0x7f	/* 10.5.4.24 */ | ||||
| #define GSM48_IE_MORE_DATA	0xa0	/* 10.5.4.19 */ | ||||
| #define GSM48_IE_CLIR_SUPP	0xa1	/* 10.5.4.11a */ | ||||
| #define GSM48_IE_CLIR_INVOC	0xa2	/* 10.5.4.11b */ | ||||
| #define GSM48_IE_REV_C_SETUP	0xa3	/* 10.5.4.22a */ | ||||
| #define GSM48_IE_REPEAT_CIR	0xd1	/* 10.5.4.22 */ | ||||
| #define GSM48_IE_REPEAT_SEQ	0xd3	/* 10.5.4.22 */ | ||||
|  | ||||
| /* Section 10.5.4.11 / Table 10.5.122 */ | ||||
| #define GSM48_CAUSE_CS_GSM	0x60 | ||||
|  | ||||
| /* Section 9.1.2 / Table 9.3 */ | ||||
| #define GSM48_IE_FRQLIST_AFTER	0x05 | ||||
| #define GSM48_IE_CELL_CH_DESC	0x62 | ||||
| #define GSM48_IE_MSLOT_DESC	0x10 | ||||
| #define GSM48_IE_CHANMODE_1	0x63 | ||||
| #define GSM48_IE_CHANMODE_2	0x11 | ||||
| #define GSM48_IE_CHANMODE_3	0x13 | ||||
| #define GSM48_IE_CHANMODE_4	0x14 | ||||
| #define GSM48_IE_CHANMODE_5	0x15 | ||||
| #define GSM48_IE_CHANMODE_6	0x16 | ||||
| #define GSM48_IE_CHANMODE_7	0x17 | ||||
| #define GSM48_IE_CHANMODE_8	0x18 | ||||
| #define GSM48_IE_CHANDESC_2	0x64 | ||||
| /* FIXME */ | ||||
|  | ||||
| /* Section 10.5.4.23 / Table 10.5.130 */ | ||||
| enum gsm48_signal_val { | ||||
| 	GSM48_SIGNAL_DIALTONE	= 0x00, | ||||
| 	GSM48_SIGNAL_RINGBACK	= 0x01, | ||||
| 	GSM48_SIGNAL_INTERCEPT	= 0x02, | ||||
| 	GSM48_SIGNAL_NET_CONG	= 0x03, | ||||
| 	GSM48_SIGNAL_BUSY	= 0x04, | ||||
| 	GSM48_SIGNAL_CONFIRM	= 0x05, | ||||
| 	GSM48_SIGNAL_ANSWER	= 0x06, | ||||
| 	GSM48_SIGNAL_CALL_WAIT	= 0x07, | ||||
| 	GSM48_SIGNAL_OFF_HOOK	= 0x08, | ||||
| 	GSM48_SIGNAL_OFF	= 0x3f, | ||||
| 	GSM48_SIGNAL_ALERT_OFF	= 0x4f, | ||||
| }; | ||||
|  | ||||
| enum gsm48_cause_loc { | ||||
| 	GSM48_CAUSE_LOC_USER		= 0x00, | ||||
| 	GSM48_CAUSE_LOC_PRN_S_LU	= 0x01, | ||||
| 	GSM48_CAUSE_LOC_PUN_S_LU	= 0x02, | ||||
| 	GSM48_CAUSE_LOC_TRANS_NET	= 0x03, | ||||
| 	GSM48_CAUSE_LOC_PUN_S_RU	= 0x04, | ||||
| 	GSM48_CAUSE_LOC_PRN_S_RU	= 0x05, | ||||
| 	/* not defined */ | ||||
| 	GSM48_CAUSE_LOC_INN_NET		= 0x07, | ||||
| 	GSM48_CAUSE_LOC_NET_BEYOND	= 0x0a, | ||||
| }; | ||||
|  | ||||
| /* Section 10.5.2.31 RR Cause / Table 10.5.70 */ | ||||
| enum gsm48_rr_cause { | ||||
| 	GSM48_RR_CAUSE_NORMAL		= 0x00, | ||||
| 	GSM48_RR_CAUSE_ABNORMAL_UNSPEC	= 0x01, | ||||
| 	GSM48_RR_CAUSE_ABNORMAL_UNACCT	= 0x02, | ||||
| 	GSM48_RR_CAUSE_ABNORMAL_TIMER	= 0x03, | ||||
| 	GSM48_RR_CAUSE_ABNORMAL_NOACT	= 0x04, | ||||
| 	GSM48_RR_CAUSE_PREMPTIVE_REL	= 0x05, | ||||
| 	GSM48_RR_CAUSE_HNDOVER_IMP	= 0x06, | ||||
| 	GSM48_RR_CAUSE_CHAN_MODE_UNACCT	= 0x07, | ||||
| 	GSM48_RR_CAUSE_FREQ_NOT_IMPL	= 0x08, | ||||
| 	GSM48_RR_CAUSE_CALL_CLEARED	= 0x41, | ||||
| 	GSM48_RR_CAUSE_SEMANT_INCORR	= 0x5f, | ||||
| 	GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60, | ||||
| 	GSM48_RR_CAUSE_MSG_TYPE_N	= 0x61, | ||||
| 	GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62, | ||||
| 	GSM48_RR_CAUSE_COND_IE_ERROR	= 0x64, | ||||
| 	GSM48_RR_CAUSE_NO_CELL_ALLOC_A	= 0x65, | ||||
| 	GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f, | ||||
| }; | ||||
|  | ||||
| /* Section 10.5.4.11 CC Cause / Table 10.5.123 */ | ||||
| enum gsm48_cc_cause { | ||||
| 	GSM48_CC_CAUSE_UNASSIGNED_NR	= 1, | ||||
| 	GSM48_CC_CAUSE_NO_ROUTE		= 3, | ||||
| 	GSM48_CC_CAUSE_CHAN_UNACCEPT	= 6, | ||||
| 	GSM48_CC_CAUSE_OP_DET_BARRING	= 8, | ||||
| 	GSM48_CC_CAUSE_NORM_CALL_CLEAR	= 16, | ||||
| 	GSM48_CC_CAUSE_USER_BUSY	= 17, | ||||
| 	GSM48_CC_CAUSE_USER_NOTRESPOND	= 18, | ||||
| 	GSM48_CC_CAUSE_USER_ALERTING_NA	= 19, | ||||
| 	GSM48_CC_CAUSE_CALL_REJECTED	= 21, | ||||
| 	GSM48_CC_CAUSE_NUMBER_CHANGED	= 22, | ||||
| 	GSM48_CC_CAUSE_PRE_EMPTION	= 25, | ||||
| 	GSM48_CC_CAUSE_NONSE_USER_CLR	= 26, | ||||
| 	GSM48_CC_CAUSE_DEST_OOO		= 27, | ||||
| 	GSM48_CC_CAUSE_INV_NR_FORMAT	= 28, | ||||
| 	GSM48_CC_CAUSE_FACILITY_REJ	= 29, | ||||
| 	GSM48_CC_CAUSE_RESP_STATUS_INQ	= 30, | ||||
| 	GSM48_CC_CAUSE_NORMAL_UNSPEC	= 31, | ||||
| 	GSM48_CC_CAUSE_NO_CIRCUIT_CHAN	= 34, | ||||
| 	GSM48_CC_CAUSE_NETWORK_OOO	= 38, | ||||
| 	GSM48_CC_CAUSE_TEMP_FAILURE	= 41, | ||||
| 	GSM48_CC_CAUSE_SWITCH_CONG	= 42, | ||||
| 	GSM48_CC_CAUSE_ACC_INF_DISCARD	= 43, | ||||
| 	GSM48_CC_CAUSE_REQ_CHAN_UNAVAIL	= 44, | ||||
| 	GSM48_CC_CAUSE_RESOURCE_UNAVAIL	= 47, | ||||
| 	GSM48_CC_CAUSE_QOS_UNAVAIL	= 49, | ||||
| 	GSM48_CC_CAUSE_REQ_FAC_NOT_SUBSC= 50, | ||||
| 	GSM48_CC_CAUSE_INC_BARRED_CUG	= 55, | ||||
| 	GSM48_CC_CAUSE_BEARER_CAP_UNAUTH= 57, | ||||
| 	GSM48_CC_CAUSE_BEARER_CA_UNAVAIL= 58, | ||||
| 	GSM48_CC_CAUSE_SERV_OPT_UNAVAIL	= 63, | ||||
| 	GSM48_CC_CAUSE_BEARERSERV_UNIMPL= 65, | ||||
| 	GSM48_CC_CAUSE_ACM_GE_ACM_MAX	= 68, | ||||
| 	GSM48_CC_CAUSE_REQ_FAC_NOTIMPL	= 69, | ||||
| 	GSM48_CC_CAUSE_RESTR_BCAP_AVAIL	= 70, | ||||
| 	GSM48_CC_CAUSE_SERV_OPT_UNIMPL	= 79, | ||||
| 	GSM48_CC_CAUSE_INVAL_TRANS_ID	= 81, | ||||
| 	GSM48_CC_CAUSE_USER_NOT_IN_CUG	= 87, | ||||
| 	GSM48_CC_CAUSE_INCOMPAT_DEST	= 88, | ||||
| 	GSM48_CC_CAUSE_INVAL_TRANS_NET	= 91, | ||||
| 	GSM48_CC_CAUSE_SEMANTIC_INCORR	= 95, | ||||
| 	GSM48_CC_CAUSE_INVAL_MAND_INF	= 96, | ||||
| 	GSM48_CC_CAUSE_MSGTYPE_NOTEXIST	= 97, | ||||
| 	GSM48_CC_CAUSE_MSGTYPE_INCOMPAT	= 98, | ||||
| 	GSM48_CC_CAUSE_IE_NOTEXIST	= 99, | ||||
| 	GSM48_CC_CAUSE_COND_IE_ERR	= 100, | ||||
| 	GSM48_CC_CAUSE_MSG_INCOMP_STATE	= 101, | ||||
| 	GSM48_CC_CAUSE_RECOVERY_TIMER	= 102, | ||||
| 	GSM48_CC_CAUSE_PROTO_ERR	= 111, | ||||
| 	GSM48_CC_CAUSE_INTERWORKING	= 127, | ||||
| }; | ||||
|  | ||||
| /* Annex G, GSM specific cause values for mobility management */ | ||||
| enum gsm48_reject_value { | ||||
| 	GSM48_REJECT_IMSI_UNKNOWN_IN_HLR	= 2, | ||||
| 	GSM48_REJECT_ILLEGAL_MS			= 3, | ||||
| 	GSM48_REJECT_IMSI_UNKNOWN_IN_VLR	= 4, | ||||
| 	GSM48_REJECT_IMEI_NOT_ACCEPTED		= 5, | ||||
| 	GSM48_REJECT_ILLEGAL_ME			= 6, | ||||
| 	GSM48_REJECT_PLMN_NOT_ALLOWED		= 11, | ||||
| 	GSM48_REJECT_LOC_NOT_ALLOWED		= 12, | ||||
| 	GSM48_REJECT_ROAMING_NOT_ALLOWED	= 13, | ||||
| 	GSM48_REJECT_NETWORK_FAILURE		= 17, | ||||
| 	GSM48_REJECT_CONGESTION			= 22, | ||||
| 	GSM48_REJECT_SRV_OPT_NOT_SUPPORTED	= 32, | ||||
| 	GSM48_REJECT_RQD_SRV_OPT_NOT_SUPPORTED	= 33, | ||||
| 	GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER	= 34, | ||||
| 	GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED	= 38, | ||||
| 	GSM48_REJECT_INCORRECT_MESSAGE		= 95, | ||||
| 	GSM48_REJECT_INVALID_MANDANTORY_INF	= 96, | ||||
| 	GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED	= 97, | ||||
| 	GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE	= 98, | ||||
| 	GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED	= 99, | ||||
| 	GSM48_REJECT_CONDTIONAL_IE_ERROR	= 100, | ||||
| 	GSM48_REJECT_MSG_NOT_COMPATIBLE		= 101, | ||||
| 	GSM48_REJECT_PROTOCOL_ERROR		= 111, | ||||
|  | ||||
| 	/* according to G.6 Additional cause codes for GMM */ | ||||
| 	GSM48_REJECT_GPRS_NOT_ALLOWED		= 7, | ||||
| 	GSM48_REJECT_SERVICES_NOT_ALLOWED	= 8, | ||||
| 	GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE = 9, | ||||
| 	GSM48_REJECT_IMPLICITLY_DETACHED	= 10, | ||||
| 	GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN	= 14, | ||||
| 	GSM48_REJECT_MSC_TMP_NOT_REACHABLE	= 16, | ||||
| }; | ||||
|  | ||||
| enum chreq_type { | ||||
| 	CHREQ_T_EMERG_CALL, | ||||
| 	CHREQ_T_CALL_REEST_TCH_F, | ||||
| 	CHREQ_T_CALL_REEST_TCH_H, | ||||
| 	CHREQ_T_CALL_REEST_TCH_H_DBL, | ||||
| 	CHREQ_T_SDCCH, | ||||
| 	CHREQ_T_TCH_F, | ||||
| 	CHREQ_T_VOICE_CALL_TCH_H, | ||||
| 	CHREQ_T_DATA_CALL_TCH_H, | ||||
| 	CHREQ_T_LOCATION_UPD, | ||||
| 	CHREQ_T_PAG_R_ANY_NECI0, | ||||
| 	CHREQ_T_PAG_R_ANY_NECI1, | ||||
| 	CHREQ_T_PAG_R_TCH_F, | ||||
| 	CHREQ_T_PAG_R_TCH_FH, | ||||
| 	CHREQ_T_LMU, | ||||
| 	CHREQ_T_RESERVED_SDCCH, | ||||
| 	CHREQ_T_RESERVED_IGNORE, | ||||
| }; | ||||
|  | ||||
| /* Chapter 11.3 */ | ||||
| #define GSM48_T301	180, 0 | ||||
| #define GSM48_T303	30, 0 | ||||
| #define GSM48_T305	30, 0 | ||||
| #define GSM48_T306	30, 0 | ||||
| #define GSM48_T308	10, 0 | ||||
| #define GSM48_T310	180, 0 | ||||
| #define GSM48_T313	30, 0 | ||||
| #define GSM48_T323	30, 0 | ||||
| #define GSM48_T331	30, 0 | ||||
| #define GSM48_T333	30, 0 | ||||
| #define GSM48_T334	25, 0 /* min 15 */ | ||||
| #define GSM48_T338	30, 0 | ||||
|  | ||||
| /* Chapter 5.1.2.2 */ | ||||
| #define	GSM_CSTATE_NULL			0 | ||||
| #define	GSM_CSTATE_INITIATED		1 | ||||
| #define	GSM_CSTATE_MO_CALL_PROC		3 | ||||
| #define	GSM_CSTATE_CALL_DELIVERED	4 | ||||
| #define	GSM_CSTATE_CALL_PRESENT		6 | ||||
| #define	GSM_CSTATE_CALL_RECEIVED	7 | ||||
| #define	GSM_CSTATE_CONNECT_REQUEST	8 | ||||
| #define	GSM_CSTATE_MO_TERM_CALL_CONF	9 | ||||
| #define	GSM_CSTATE_ACTIVE		10 | ||||
| #define	GSM_CSTATE_DISCONNECT_REQ	12 | ||||
| #define	GSM_CSTATE_DISCONNECT_IND	12 | ||||
| #define	GSM_CSTATE_RELEASE_REQ		19 | ||||
| #define	GSM_CSTATE_MO_ORIG_MODIFY	26 | ||||
| #define	GSM_CSTATE_MO_TERM_MODIFY	27 | ||||
| #define	GSM_CSTATE_CONNECT_IND		28 | ||||
|  | ||||
| #define SBIT(a) (1 << a) | ||||
| #define ALL_STATES 0xffffffff | ||||
|  | ||||
| /* Table 10.5.3/3GPP TS 04.08: Location Area Identification information element */ | ||||
| #define GSM_LAC_RESERVED_DETACHED       0x0 | ||||
| #define GSM_LAC_RESERVED_ALL_BTS        0xfffe | ||||
|  | ||||
| /* GSM 04.08 Bearer Capability: Information Transfer Capability */ | ||||
| enum gsm48_bcap_itcap { | ||||
| 	GSM48_BCAP_ITCAP_SPEECH		= 0, | ||||
| 	GSM48_BCAP_ITCAP_UNR_DIG_INF	= 1, | ||||
| 	GSM48_BCAP_ITCAP_3k1_AUDIO	= 2, | ||||
| 	GSM48_BCAP_ITCAP_FAX_G3		= 3, | ||||
| 	GSM48_BCAP_ITCAP_OTHER		= 5, | ||||
| 	GSM48_BCAP_ITCAP_RESERVED	= 7, | ||||
| }; | ||||
|  | ||||
| /* GSM 04.08 Bearer Capability: Transfer Mode */ | ||||
| enum gsm48_bcap_tmod { | ||||
| 	GSM48_BCAP_TMOD_CIRCUIT		= 0, | ||||
| 	GSM48_BCAP_TMOD_PACKET		= 1, | ||||
| }; | ||||
|  | ||||
| /* GSM 04.08 Bearer Capability: Coding Standard */ | ||||
| enum gsm48_bcap_coding { | ||||
| 	GSM48_BCAP_CODING_GSM_STD	= 0, | ||||
| }; | ||||
|  | ||||
| /* GSM 04.08 Bearer Capability: Radio Channel Requirements */ | ||||
| enum gsm48_bcap_rrq { | ||||
| 	GSM48_BCAP_RRQ_FR_ONLY	= 1, | ||||
| 	GSM48_BCAP_RRQ_DUAL_HR	= 2, | ||||
| 	GSM48_BCAP_RRQ_DUAL_FR	= 3, | ||||
| }; | ||||
|  | ||||
|  | ||||
| #define GSM48_TMSI_LEN	5 | ||||
| #define GSM48_MID_TMSI_LEN	(GSM48_TMSI_LEN + 2) | ||||
| #define GSM48_MI_SIZE 32 | ||||
|  | ||||
|  | ||||
| #endif /* PROTO_GSM_04_08_H */ | ||||
							
								
								
									
										188
									
								
								libosmocore/include/osmocore/protocol/gsm_04_11.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								libosmocore/include/osmocore/protocol/gsm_04_11.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | ||||
| #ifndef PROTO_GSM_04_11_H | ||||
| #define PROTO_GSM_04_11_H | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| /* GSM TS 04.11  definitions */ | ||||
|  | ||||
| /* Chapter 5.2.3: SMC-CS states at the network side */ | ||||
| enum gsm411_cp_state { | ||||
| 	GSM411_CPS_IDLE 		= 0, | ||||
| 	GSM411_CPS_MM_CONN_PENDING	= 1,	/* only MT ! */ | ||||
| 	GSM411_CPS_WAIT_CP_ACK		= 2, | ||||
| 	GSM411_CPS_MM_ESTABLISHED	= 3, | ||||
| }; | ||||
|  | ||||
| /* Chapter 6.2.2: SMR states at the network side */ | ||||
| enum gsm411_rp_state { | ||||
| 	GSM411_RPS_IDLE			= 0, | ||||
| 	GSM411_RPS_WAIT_FOR_RP_ACK	= 1, | ||||
| 	GSM411_RPS_WAIT_TO_TX_RP_ACK	= 3, | ||||
| }; | ||||
|  | ||||
| /* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */ | ||||
| #define GSM411_PDISC_SMS	0x09 | ||||
|  | ||||
| /* Chapter 8.1.3 */ | ||||
| #define GSM411_MT_CP_DATA	0x01 | ||||
| #define GSM411_MT_CP_ACK	0x04 | ||||
| #define GSM411_MT_CP_ERROR	0x10 | ||||
|  | ||||
| enum gsm411_cp_ie { | ||||
| 	GSM411_CP_IE_USER_DATA		= 0x01,	/* 8.1.4.1 */ | ||||
| 	GSM411_CP_IE_CAUSE		= 0x02,	/* 8.1.4.2. */ | ||||
| }; | ||||
|  | ||||
| /* Section 8.1.4.2 / Table 8.2 */ | ||||
| enum gsm411_cp_cause { | ||||
| 	GSM411_CP_CAUSE_NET_FAIL	= 17, | ||||
| 	GSM411_CP_CAUSE_CONGESTION	= 22, | ||||
| 	GSM411_CP_CAUSE_INV_TRANS_ID	= 81, | ||||
| 	GSM411_CP_CAUSE_SEMANT_INC_MSG	= 95, | ||||
| 	GSM411_CP_CAUSE_INV_MAND_INF	= 96, | ||||
| 	GSM411_CP_CAUSE_MSGTYPE_NOTEXIST= 97, | ||||
| 	GSM411_CP_CAUSE_MSG_INCOMP_STATE= 98, | ||||
| 	GSM411_CP_CAUSE_IE_NOTEXIST	= 99, | ||||
| 	GSM411_CP_CAUSE_PROTOCOL_ERR	= 111, | ||||
| }; | ||||
|  | ||||
| /* Chapter 8.2.2 */ | ||||
| #define GSM411_MT_RP_DATA_MO	0x00 | ||||
| #define GSM411_MT_RP_DATA_MT	0x01 | ||||
| #define GSM411_MT_RP_ACK_MO	0x02 | ||||
| #define GSM411_MT_RP_ACK_MT	0x03 | ||||
| #define GSM411_MT_RP_ERROR_MO	0x04 | ||||
| #define GSM411_MT_RP_ERROR_MT	0x05 | ||||
| #define GSM411_MT_RP_SMMA_MO	0x06 | ||||
|  | ||||
| enum gsm411_rp_ie { | ||||
| 	GSM411_IE_RP_USER_DATA		= 0x41,	/* 8.2.5.3 */ | ||||
| 	GSM411_IE_RP_CAUSE		= 0x42,	/* 8.2.5.4 */ | ||||
| }; | ||||
|  | ||||
| /* Chapter 8.2.5.4 Table 8.4 */ | ||||
| enum gsm411_rp_cause { | ||||
| 	/* valid only for MO */ | ||||
| 	GSM411_RP_CAUSE_MO_NUM_UNASSIGNED	= 1, | ||||
| 	GSM411_RP_CAUSE_MO_OP_DET_BARR		= 8, | ||||
| 	GSM411_RP_CAUSE_MO_CALL_BARRED		= 10, | ||||
| 	GSM411_RP_CAUSE_MO_SMS_REJECTED		= 21, | ||||
| 	GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER	= 27, | ||||
| 	GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR	= 28, | ||||
| 	GSM411_RP_CAUSE_MO_FACILITY_REJ		= 29, | ||||
| 	GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR	= 30, | ||||
| 	GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER	= 38, | ||||
| 	GSM411_RP_CAUSE_MO_TEMP_FAIL		= 41, | ||||
| 	GSM411_RP_CAUSE_MO_CONGESTION		= 42, | ||||
| 	GSM411_RP_CAUSE_MO_RES_UNAVAIL		= 47, | ||||
| 	GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR	= 50, | ||||
| 	GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL	= 69, | ||||
| 	GSM411_RP_CAUSE_MO_INTERWORKING		= 127, | ||||
| 	/* valid only for MT */ | ||||
| 	GSM411_RP_CAUSE_MT_MEM_EXCEEDED		= 22, | ||||
| 	/* valid for both directions */ | ||||
| 	GSM411_RP_CAUSE_INV_TRANS_REF		= 81, | ||||
| 	GSM411_RP_CAUSE_SEMANT_INC_MSG		= 95, | ||||
| 	GSM411_RP_CAUSE_INV_MAND_INF		= 96, | ||||
| 	GSM411_RP_CAUSE_MSGTYPE_NOTEXIST	= 97, | ||||
| 	GSM411_RP_CAUSE_MSG_INCOMP_STATE	= 98, | ||||
| 	GSM411_RP_CAUSE_IE_NOTEXIST		= 99, | ||||
| 	GSM411_RP_CAUSE_PROTOCOL_ERR		= 111, | ||||
| }; | ||||
|  | ||||
| /* Chapter 10: Timers */ | ||||
| #define GSM411_TMR_TR1M		40, 0	/* 35 < x < 45 seconds */ | ||||
| #define GSM411_TMR_TRAM		30, 0	/* 25 < x < 35 seconds */ | ||||
| #define GSM411_TMR_TR2M		15, 0	/* 12 < x < 20 seconds */ | ||||
|  | ||||
| #define GSM411_TMR_TC1A		30, 0 | ||||
|  | ||||
| /* Chapter 8.2.1 */ | ||||
| struct gsm411_rp_hdr { | ||||
| 	uint8_t len; | ||||
| 	uint8_t msg_type; | ||||
| 	uint8_t msg_ref; | ||||
| 	uint8_t data[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* our own enum, not related to on-air protocol */ | ||||
| enum sms_alphabet { | ||||
| 	DCS_NONE, | ||||
| 	DCS_7BIT_DEFAULT, | ||||
| 	DCS_UCS2, | ||||
| 	DCS_8BIT_DATA, | ||||
| }; | ||||
|  | ||||
| /* GSM 03.40 / Chapter 9.2.3.1: TP-Message-Type-Indicator */ | ||||
| #define GSM340_SMS_DELIVER_SC2MS	0x00 | ||||
| #define GSM340_SMS_DELIVER_REP_MS2SC	0x00 | ||||
| #define GSM340_SMS_STATUS_REP_SC2MS	0x02 | ||||
| #define GSM340_SMS_COMMAND_MS2SC	0x02 | ||||
| #define GSM340_SMS_SUBMIT_MS2SC		0x01 | ||||
| #define GSM340_SMS_SUBMIT_REP_SC2MS	0x01 | ||||
| #define GSM340_SMS_RESSERVED		0x03 | ||||
|  | ||||
| /* GSM 03.40 / Chapter 9.2.3.2: TP-More-Messages-to-Send */ | ||||
| #define GSM340_TP_MMS_MORE		0 | ||||
| #define GSM340_TP_MMS_NO_MORE		1 | ||||
|  | ||||
| /* GSM 03.40 / Chapter 9.2.3.3: TP-Validity-Period-Format */ | ||||
| #define GSM340_TP_VPF_NONE		0 | ||||
| #define GSM340_TP_VPF_RELATIVE		2 | ||||
| #define GSM340_TP_VPF_ENHANCED		1 | ||||
| #define GSM340_TP_VPF_ABSOLUTE		3 | ||||
|  | ||||
| /* GSM 03.40 / Chapter 9.2.3.4: TP-Status-Report-Indication */ | ||||
| #define GSM340_TP_SRI_NONE		0 | ||||
| #define GSM340_TP_SRI_PRESENT		1 | ||||
|  | ||||
| /* GSM 03.40 / Chapter 9.2.3.5: TP-Status-Report-Request */ | ||||
| #define GSM340_TP_SRR_NONE		0 | ||||
| #define GSM340_TP_SRR_REQUESTED		1 | ||||
|  | ||||
| /* GSM 03.40 / Chapter 9.2.3.9: TP-Protocol-Identifier */ | ||||
| /* telematic interworking (001 or 111 in bits 7-5) */ | ||||
| #define GSM340_TP_PID_IMPLICIT		0x00 | ||||
| #define GSM340_TP_PID_TELEX		0x01 | ||||
| #define GSM340_TP_PID_FAX_G3		0x02 | ||||
| #define GSM340_TP_PID_FAX_G4		0x03 | ||||
| #define GSM340_TP_PID_VOICE		0x04 | ||||
| #define GSM430_TP_PID_ERMES		0x05 | ||||
| #define GSM430_TP_PID_NATIONAL_PAGING	0x06 | ||||
| #define GSM430_TP_PID_VIDEOTEX		0x07 | ||||
| #define GSM430_TP_PID_TELETEX_UNSPEC	0x08 | ||||
| #define GSM430_TP_PID_TELETEX_PSPDN	0x09 | ||||
| #define GSM430_TP_PID_TELETEX_CSPDN	0x0a | ||||
| #define GSM430_TP_PID_TELETEX_PSTN	0x0b | ||||
| #define GSM430_TP_PID_TELETEX_ISDN	0x0c | ||||
| #define GSM430_TP_PID_TELETEX_UCI	0x0d | ||||
| #define GSM430_TP_PID_MSG_HANDLING	0x10 | ||||
| #define GSM430_TP_PID_MSG_X400		0x11 | ||||
| #define GSM430_TP_PID_EMAIL		0x12 | ||||
| #define GSM430_TP_PID_GSM_MS		0x1f | ||||
| /* if bit 7 = 0 and bit 6 = 1 */ | ||||
| #define GSM430_TP_PID_SMS_TYPE_0	0 | ||||
| #define GSM430_TP_PID_SMS_TYPE_1	1 | ||||
| #define GSM430_TP_PID_SMS_TYPE_2	2 | ||||
| #define GSM430_TP_PID_SMS_TYPE_3	3 | ||||
| #define GSM430_TP_PID_SMS_TYPE_4	4 | ||||
| #define GSM430_TP_PID_SMS_TYPE_5	5 | ||||
| #define GSM430_TP_PID_SMS_TYPE_6	6 | ||||
| #define GSM430_TP_PID_SMS_TYPE_7	7 | ||||
| #define GSM430_TP_PID_RETURN_CALL_MSG	0x1f | ||||
| #define GSM430_TP_PID_ME_DATA_DNLOAD	0x3d | ||||
| #define GSM430_TP_PID_ME_DE_PERSONAL	0x3e | ||||
| #define GSM430_TP_PID_ME_SIM_DNLOAD	0x3f | ||||
|  | ||||
| /* GSM 03.38 Chapter 4: SMS Data Coding Scheme */ | ||||
| #define GSM338_DCS_00_ | ||||
|  | ||||
| #define GSM338_DCS_1110_7BIT		(0 << 2) | ||||
| #define GSM338_DCS_1111_7BIT		(0 << 2) | ||||
| #define GSM338_DCS_1111_8BIT_DATA	(1 << 2) | ||||
| #define GSM338_DCS_1111_CLASS0		0 | ||||
| #define GSM338_DCS_1111_CLASS1_ME	1 | ||||
| #define GSM338_DCS_1111_CLASS2_SIM	2 | ||||
| #define GSM338_DCS_1111_CLASS3_TE	3	/* See TS 07.05 */ | ||||
|  | ||||
| #endif /* PROTO_GSM_04_11_H */ | ||||
							
								
								
									
										126
									
								
								libosmocore/include/osmocore/protocol/gsm_04_80.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								libosmocore/include/osmocore/protocol/gsm_04_80.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| #ifndef PROTO_GSM_04_80_H | ||||
| #define PROTO_GSM_04_80_H | ||||
|  | ||||
| /* GSM TS 04.80  definitions (Supplementary Services Specification, Formats and Coding) */ | ||||
|  | ||||
| /* Section 3.4 */ | ||||
| #define GSM0480_MTYPE_RELEASE_COMPLETE	0x2A | ||||
| #define GSM0480_MTYPE_FACILITY			0x3A | ||||
| #define GSM0480_MTYPE_REGISTER			0x3B | ||||
|  | ||||
| /* Section 3.5 */ | ||||
| #define GSM0480_IE_FACILITY			0x1C | ||||
| #define GSM0480_IE_SS_VERSION			0x7F | ||||
|  | ||||
| /* Section 3.6.2 */ | ||||
| #define GSM0480_CTYPE_INVOKE			0xA1 | ||||
| #define GSM0480_CTYPE_RETURN_RESULT		0xA2 | ||||
| #define GSM0480_CTYPE_RETURN_ERROR		0xA3 | ||||
| #define GSM0480_CTYPE_REJECT			0xA4 | ||||
|  | ||||
| /* Section 3.6.3 */ | ||||
| #define GSM0480_COMPIDTAG_INVOKE_ID		0x02 | ||||
| #define GSM0480_COMPIDTAG_LINKED_ID		0x80 | ||||
|  | ||||
| /* Section 3.6.4 */ | ||||
| #define GSM0480_OPERATION_CODE			0x02 | ||||
|  | ||||
| /* Section 3.6.5 */ | ||||
| #define GSM_0480_SEQUENCE_TAG			0x30 | ||||
| #define GSM_0480_SET_TAG			0x31 | ||||
|  | ||||
| /* Section 3.6.6 */ | ||||
| #define GSM_0480_ERROR_CODE_TAG			0x02 | ||||
|  | ||||
| /* Section 3.6.7 */ | ||||
| /* Table 3.13 */ | ||||
| #define GSM_0480_PROBLEM_CODE_TAG_GENERAL	0x80 | ||||
| #define GSM_0480_PROBLEM_CODE_TAG_INVOKE	0x81 | ||||
| #define GSM_0480_PROBLEM_CODE_TAG_RETURN_RESULT	0x82 | ||||
| #define GSM_0480_PROBLEM_CODE_TAG_RETURN_ERROR	0x83 | ||||
|  | ||||
| /* Table 3.14 */ | ||||
| #define GSM_0480_GEN_PROB_CODE_UNRECOGNISED	0x00 | ||||
| #define GSM_0480_GEN_PROB_CODE_MISTYPED		0x01 | ||||
| #define GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE	0x02 | ||||
|  | ||||
| /* Table 3.15 */ | ||||
| #define GSM_0480_INVOKE_PROB_CODE_DUPLICATE_INVOKE_ID		0x00 | ||||
| #define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION	0x01 | ||||
| #define GSM_0480_INVOKE_PROB_CODE_MISTYPED_PARAMETER		0x02 | ||||
| #define GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION		0x03 | ||||
| #define GSM_0480_INVOKE_PROB_CODE_INITIATING_RELEASE		0x04 | ||||
| #define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_LINKED_ID	0x05 | ||||
| #define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_RESPONSE	0x06 | ||||
| #define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_OPERATION	0x07 | ||||
|  | ||||
| /* Table 3.16 */ | ||||
| #define GSM_0480_RESULT_PROB_CODE_UNRECOGNISED_INVOKE_ID	0x00 | ||||
| #define GSM_0480_RESULT_PROB_CODE_RETURN_RESULT_UNEXPECTED	0x01 | ||||
| #define GSM_0480_RESULT_PROB_CODE_MISTYPED_PARAMETER		0x02 | ||||
|  | ||||
| /* Table 3.17 */ | ||||
| #define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_INVOKE_ID		0x00 | ||||
| #define GSM_0480_ERROR_PROB_CODE_RETURN_ERROR_UNEXPECTED	0x01 | ||||
| #define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_ERROR		0x02 | ||||
| #define GSM_0480_ERROR_PROB_CODE_UNEXPECTED_ERROR		0x03 | ||||
| #define GSM_0480_ERROR_PROB_CODE_MISTYPED_PARAMETER		0x04 | ||||
|  | ||||
| /* Section 4.5 */ | ||||
| #define GSM0480_OP_CODE_REGISTER_SS		0x0A | ||||
| #define GSM0480_OP_CODE_ERASE_SS		0x0B | ||||
| #define GSM0480_OP_CODE_ACTIVATE_SS		0x0C | ||||
| #define GSM0480_OP_CODE_DEACTIVATE_SS		0x0D | ||||
| #define GSM0480_OP_CODE_INTERROGATE_SS		0x0E | ||||
| #define GSM0480_OP_CODE_NOTIFY_SS		0x10 | ||||
| #define GSM0480_OP_CODE_REGISTER_PASSWORD	0x11 | ||||
| #define GSM0480_OP_CODE_GET_PASSWORD		0x12 | ||||
| #define GSM0480_OP_CODE_PROCESS_USS_DATA	0x13 | ||||
| #define GSM0480_OP_CODE_FORWARD_CHECK_SS_IND	0x26 | ||||
| #define GSM0480_OP_CODE_PROCESS_USS_REQ		0x3B | ||||
| #define GSM0480_OP_CODE_USS_REQUEST		0x3C | ||||
| #define GSM0480_OP_CODE_USS_NOTIFY		0x3D | ||||
| #define GSM0480_OP_CODE_FORWARD_CUG_INFO	0x78 | ||||
| #define GSM0480_OP_CODE_SPLIT_MPTY		0x79 | ||||
| #define GSM0480_OP_CODE_RETRIEVE_MPTY		0x7A | ||||
| #define GSM0480_OP_CODE_HOLD_MPTY		0x7B | ||||
| #define GSM0480_OP_CODE_BUILD_MPTY		0x7C | ||||
| #define GSM0480_OP_CODE_FORWARD_CHARGE_ADVICE	0x7D | ||||
|  | ||||
| #define GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER			0x01 | ||||
| #define GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER			0x09 | ||||
| #define GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED		0x0A | ||||
| #define GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED		0x0B | ||||
| #define GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT			0x0C | ||||
| #define GSM0480_ERR_CODE_CALL_BARRED				0x0D | ||||
| #define GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION			0x10 | ||||
| #define GSM0480_ERR_CODE_SS_ERROR_STATUS			0x11 | ||||
| #define GSM0480_ERR_CODE_SS_NOT_AVAILABLE			0x12 | ||||
| #define GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION		0x13 | ||||
| #define GSM0480_ERR_CODE_SS_INCOMPATIBILITY			0x14 | ||||
| #define GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED			0x15 | ||||
| #define GSM0480_ERR_CODE_ABSENT_SUBSCRIBER			0x1B | ||||
| #define GSM0480_ERR_CODE_SYSTEM_FAILURE				0x22 | ||||
| #define GSM0480_ERR_CODE_DATA_MISSING				0x23 | ||||
| #define GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE			0x24 | ||||
| #define GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE		0x25 | ||||
| #define GSM0480_ERR_CODE_NEGATIVE_PW_CHECK			0x26 | ||||
| #define GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION		0x2B | ||||
| #define GSM0480_ERR_CODE_UNKNOWN_ALPHABET			0x47 | ||||
| #define GSM0480_ERR_CODE_USSD_BUSY				0x48 | ||||
| #define GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS			0x7E | ||||
| #define GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE		0x7F | ||||
|  | ||||
| /* ASN.1 type-tags */ | ||||
| #define ASN1_BOOLEAN_TAG		0x01 | ||||
| #define ASN1_INTEGER_TAG		0x02 | ||||
| #define ASN1_BIT_STRING_TAG		0x03 | ||||
| #define ASN1_OCTET_STRING_TAG		0x04 | ||||
| #define ASN1_NULL_TYPE_TAG		0x05 | ||||
| #define ASN1_OBJECT_ID_TAG		0x06 | ||||
| #define ASN1_UTF8_STRING_TAG		0x0C | ||||
| #define ASN1_PRINTABLE_STRING_TAG	0x13 | ||||
| #define ASN1_IA5_STRING_TAG		0x16 | ||||
| #define ASN1_UNICODE_STRING_TAG		0x1E | ||||
|  | ||||
| #endif /* PROTO_GSM_04_80_H */ | ||||
							
								
								
									
										512
									
								
								libosmocore/include/osmocore/protocol/gsm_08_58.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										512
									
								
								libosmocore/include/osmocore/protocol/gsm_08_58.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,512 @@ | ||||
| #ifndef PROTO_GSM_08_58_H | ||||
| #define PROTO_GSM_08_58_H | ||||
|  | ||||
| /* GSM Radio Signalling Link messages on the A-bis interface  | ||||
|  * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */ | ||||
|  | ||||
| /* (C) 2008 by Harald Welte <laforge@gnumonks.org> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| struct abis_rsl_common_hdr { | ||||
| 	uint8_t	msg_discr; | ||||
| 	uint8_t	msg_type; | ||||
| 	uint8_t	data[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Chapter 8.3 */ | ||||
| struct abis_rsl_rll_hdr { | ||||
| 	struct abis_rsl_common_hdr c; | ||||
| 	uint8_t	ie_chan; | ||||
| 	uint8_t	chan_nr; | ||||
| 	uint8_t	ie_link_id; | ||||
| 	uint8_t	link_id; | ||||
| 	uint8_t	data[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Chapter 8.3 and 8.4 */ | ||||
| struct abis_rsl_dchan_hdr { | ||||
| 	struct abis_rsl_common_hdr c; | ||||
| 	uint8_t	ie_chan; | ||||
| 	uint8_t	chan_nr; | ||||
| 	uint8_t	data[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
|  | ||||
| /* Chapter 9.1 */ | ||||
| #define ABIS_RSL_MDISC_RLL		0x02 | ||||
| #define ABIS_RSL_MDISC_DED_CHAN		0x08 | ||||
| #define ABIS_RSL_MDISC_COM_CHAN		0x0c | ||||
| #define ABIS_RSL_MDISC_TRX		0x10 | ||||
| #define ABIS_RSL_MDISC_LOC		0x20 | ||||
| #define ABIS_RSL_MDISC_IPACCESS		0x7e | ||||
| #define ABIS_RSL_MDISC_TRANSP		0x01 | ||||
|  | ||||
| #define ABIS_RSL_MDISC_IS_TRANSP(x)	(x & 0x01) | ||||
|  | ||||
| /* Chapter 9.1 */ | ||||
| enum abis_rsl_msgtype { | ||||
| 	/* Radio Link Layer Management */ | ||||
| 	RSL_MT_DATA_REQ			= 0x01, | ||||
| 	RSL_MT_DATA_IND, | ||||
| 	RSL_MT_ERROR_IND, | ||||
| 	RSL_MT_EST_REQ, | ||||
| 	RSL_MT_EST_CONF, | ||||
| 	RSL_MT_EST_IND, | ||||
| 	RSL_MT_REL_REQ, | ||||
| 	RSL_MT_REL_CONF, | ||||
| 	RSL_MT_REL_IND, | ||||
| 	RSL_MT_UNIT_DATA_REQ, | ||||
| 	RSL_MT_UNIT_DATA_IND,		/* 0x0b */ | ||||
|  | ||||
| 	/* Common Channel Management / TRX Management */ | ||||
| 	RSL_MT_BCCH_INFO			= 0x11, | ||||
| 	RSL_MT_CCCH_LOAD_IND, | ||||
| 	RSL_MT_CHAN_RQD, | ||||
| 	RSL_MT_DELETE_IND, | ||||
| 	RSL_MT_PAGING_CMD, | ||||
| 	RSL_MT_IMMEDIATE_ASSIGN_CMD, | ||||
| 	RSL_MT_SMS_BC_REQ, | ||||
| 	/* empty */ | ||||
| 	RSL_MT_RF_RES_IND			= 0x19, | ||||
| 	RSL_MT_SACCH_FILL, | ||||
| 	RSL_MT_OVERLOAD, | ||||
| 	RSL_MT_ERROR_REPORT, | ||||
| 	RSL_MT_SMS_BC_CMD, | ||||
| 	RSL_MT_CBCH_LOAD_IND, | ||||
| 	RSL_MT_NOT_CMD,			/* 0x1f */ | ||||
|  | ||||
| 	/* Dedicate Channel Management */ | ||||
| 	RSL_MT_CHAN_ACTIV			= 0x21, | ||||
| 	RSL_MT_CHAN_ACTIV_ACK, | ||||
| 	RSL_MT_CHAN_ACTIV_NACK, | ||||
| 	RSL_MT_CONN_FAIL, | ||||
| 	RSL_MT_DEACTIVATE_SACCH, | ||||
| 	RSL_MT_ENCR_CMD, | ||||
| 	RSL_MT_HANDO_DET, | ||||
| 	RSL_MT_MEAS_RES, | ||||
| 	RSL_MT_MODE_MODIFY_REQ, | ||||
| 	RSL_MT_MODE_MODIFY_ACK, | ||||
| 	RSL_MT_MODE_MODIFY_NACK, | ||||
| 	RSL_MT_PHY_CONTEXT_REQ, | ||||
| 	RSL_MT_PHY_CONTEXT_CONF, | ||||
| 	RSL_MT_RF_CHAN_REL, | ||||
| 	RSL_MT_MS_POWER_CONTROL, | ||||
| 	RSL_MT_BS_POWER_CONTROL,		/* 0x30 */ | ||||
| 	RSL_MT_PREPROC_CONFIG, | ||||
| 	RSL_MT_PREPROC_MEAS_RES, | ||||
| 	RSL_MT_RF_CHAN_REL_ACK, | ||||
| 	RSL_MT_SACCH_INFO_MODIFY, | ||||
| 	RSL_MT_TALKER_DET, | ||||
| 	RSL_MT_LISTENER_DET, | ||||
| 	RSL_MT_REMOTE_CODEC_CONF_REP, | ||||
| 	RSL_MT_RTD_REP, | ||||
| 	RSL_MT_PRE_HANDO_NOTIF, | ||||
| 	RSL_MT_MR_CODEC_MOD_REQ, | ||||
| 	RSL_MT_MR_CODEC_MOD_ACK, | ||||
| 	RSL_MT_MR_CODEC_MOD_NACK, | ||||
| 	RSL_MT_MR_CODEC_MOD_PER, | ||||
| 	RSL_MT_TFO_REP, | ||||
| 	RSL_MT_TFO_MOD_REQ,		/* 0x3f */ | ||||
| 	RSL_MT_LOCATION_INFO		= 0x41, | ||||
|  | ||||
| 	/* ip.access specific RSL message types */ | ||||
| 	RSL_MT_IPAC_DIR_RETR_ENQ	= 0x40, | ||||
| 	RSL_MT_IPAC_PDCH_ACT		= 0x48, | ||||
| 	RSL_MT_IPAC_PDCH_ACT_ACK, | ||||
| 	RSL_MT_IPAC_PDCH_ACT_NACK, | ||||
| 	RSL_MT_IPAC_PDCH_DEACT		= 0x4b, | ||||
| 	RSL_MT_IPAC_PDCH_DEACT_ACK, | ||||
| 	RSL_MT_IPAC_PDCH_DEACT_NACK, | ||||
| 	RSL_MT_IPAC_CONNECT_MUX		= 0x50, | ||||
| 	RSL_MT_IPAC_CONNECT_MUX_ACK, | ||||
| 	RSL_MT_IPAC_CONNECT_MUX_NACK, | ||||
| 	RSL_MT_IPAC_BIND_MUX		= 0x53, | ||||
| 	RSL_MT_IPAC_BIND_MUX_ACK, | ||||
| 	RSL_MT_IPAC_BIND_MUX_NACK, | ||||
| 	RSL_MT_IPAC_DISC_MUX		= 0x56, | ||||
| 	RSL_MT_IPAC_DISC_MUX_ACK, | ||||
| 	RSL_MT_IPAC_DISC_MUX_NACK, | ||||
| 	RSL_MT_IPAC_CRCX		= 0x70,		/* Bind to local BTS RTP port */ | ||||
| 	RSL_MT_IPAC_CRCX_ACK, | ||||
| 	RSL_MT_IPAC_CRCX_NACK, | ||||
| 	RSL_MT_IPAC_MDCX		= 0x73, | ||||
| 	RSL_MT_IPAC_MDCX_ACK, | ||||
| 	RSL_MT_IPAC_MDCX_NACK, | ||||
| 	RSL_MT_IPAC_DLCX_IND		= 0x76, | ||||
| 	RSL_MT_IPAC_DLCX		= 0x77, | ||||
| 	RSL_MT_IPAC_DLCX_ACK, | ||||
| 	RSL_MT_IPAC_DLCX_NACK, | ||||
| }; | ||||
|  | ||||
| /* Siemens vendor-specific */ | ||||
| enum abis_rsl_msgtype_siemens { | ||||
| 	RSL_MT_SIEMENS_MRPCI		= 0x41, | ||||
| 	RSL_MT_SIEMENS_INTRAC_HO_COND_IND = 0x42, | ||||
| 	RSL_MT_SIEMENS_INTERC_HO_COND_IND = 0x43, | ||||
| 	RSL_MT_SIEMENS_FORCED_HO_REQ	= 0x44, | ||||
| 	RSL_MT_SIEMENS_PREF_AREA_REQ	= 0x45, | ||||
| 	RSL_MT_SIEMENS_PREF_AREA	= 0x46, | ||||
| 	RSL_MT_SIEMENS_START_TRACE	= 0x47, | ||||
| 	RSL_MT_SIEMENS_START_TRACE_ACK	= 0x48, | ||||
| 	RSL_MT_SIEMENS_STOP_TRACE	= 0x49, | ||||
| 	RSL_MT_SIEMENS_TRMR		= 0x4a, | ||||
| 	RSL_MT_SIEMENS_HO_FAIL_IND	= 0x4b, | ||||
| 	RSL_MT_SIEMENS_STOP_TRACE_ACK	= 0x4c, | ||||
| 	RSL_MT_SIEMENS_UPLF		= 0x4d, | ||||
| 	RSL_MT_SIEMENS_UPLB		= 0x4e, | ||||
| 	RSL_MT_SIEMENS_SET_SYS_INFO_10	= 0x4f, | ||||
| 	RSL_MT_SIEMENS_MODIF_COND_IND	= 0x50, | ||||
| }; | ||||
|  | ||||
| /* Chapter 9.3 */ | ||||
| enum abis_rsl_ie { | ||||
| 	RSL_IE_CHAN_NR			= 0x01, | ||||
| 	RSL_IE_LINK_IDENT, | ||||
| 	RSL_IE_ACT_TYPE, | ||||
| 	RSL_IE_BS_POWER, | ||||
| 	RSL_IE_CHAN_IDENT, | ||||
| 	RSL_IE_CHAN_MODE, | ||||
| 	RSL_IE_ENCR_INFO, | ||||
| 	RSL_IE_FRAME_NUMBER, | ||||
| 	RSL_IE_HANDO_REF, | ||||
| 	RSL_IE_L1_INFO, | ||||
| 	RSL_IE_L3_INFO, | ||||
| 	RSL_IE_MS_IDENTITY, | ||||
| 	RSL_IE_MS_POWER, | ||||
| 	RSL_IE_PAGING_GROUP, | ||||
| 	RSL_IE_PAGING_LOAD, | ||||
| 	RSL_IE_PYHS_CONTEXT		= 0x10, | ||||
| 	RSL_IE_ACCESS_DELAY, | ||||
| 	RSL_IE_RACH_LOAD, | ||||
| 	RSL_IE_REQ_REFERENCE, | ||||
| 	RSL_IE_RELEASE_MODE, | ||||
| 	RSL_IE_RESOURCE_INFO, | ||||
| 	RSL_IE_RLM_CAUSE, | ||||
| 	RSL_IE_STARTNG_TIME, | ||||
| 	RSL_IE_TIMING_ADVANCE, | ||||
| 	RSL_IE_UPLINK_MEAS, | ||||
| 	RSL_IE_CAUSE, | ||||
| 	RSL_IE_MEAS_RES_NR, | ||||
| 	RSL_IE_MSG_ID, | ||||
| 	/* reserved */ | ||||
| 	RSL_IE_SYSINFO_TYPE		= 0x1e, | ||||
| 	RSL_IE_MS_POWER_PARAM, | ||||
| 	RSL_IE_BS_POWER_PARAM, | ||||
| 	RSL_IE_PREPROC_PARAM, | ||||
| 	RSL_IE_PREPROC_MEAS, | ||||
| 	RSL_IE_IMM_ASS_INFO,		/* Phase 1 (3.6.0), later Full below */ | ||||
| 	RSL_IE_SMSCB_INFO		= 0x24, | ||||
| 	RSL_IE_MS_TIMING_OFFSET, | ||||
| 	RSL_IE_ERR_MSG, | ||||
| 	RSL_IE_FULL_BCCH_INFO, | ||||
| 	RSL_IE_CHAN_NEEDED, | ||||
| 	RSL_IE_CB_CMD_TYPE, | ||||
| 	RSL_IE_SMSCB_MSG, | ||||
| 	RSL_IE_FULL_IMM_ASS_INFO, | ||||
| 	RSL_IE_SACCH_INFO, | ||||
| 	RSL_IE_CBCH_LOAD_INFO, | ||||
| 	RSL_IE_SMSCB_CHAN_INDICATOR, | ||||
| 	RSL_IE_GROUP_CALL_REF, | ||||
| 	RSL_IE_CHAN_DESC		= 0x30, | ||||
| 	RSL_IE_NCH_DRX_INFO, | ||||
| 	RSL_IE_CMD_INDICATOR, | ||||
| 	RSL_IE_EMLPP_PRIO, | ||||
| 	RSL_IE_UIC, | ||||
| 	RSL_IE_MAIN_CHAN_REF, | ||||
| 	RSL_IE_MR_CONFIG, | ||||
| 	RSL_IE_MR_CONTROL, | ||||
| 	RSL_IE_SUP_CODEC_TYPES, | ||||
| 	RSL_IE_CODEC_CONFIG, | ||||
| 	RSL_IE_RTD, | ||||
| 	RSL_IE_TFO_STATUS, | ||||
| 	RSL_IE_LLP_APDU, | ||||
| 	/* Siemens vendor-specific */ | ||||
| 	RSL_IE_SIEMENS_MRPCI		= 0x40, | ||||
| 	RSL_IE_SIEMENS_PREF_AREA_TYPE	= 0x43, | ||||
| 	RSL_IE_SIEMENS_ININ_CELL_HO_PAR	= 0x45, | ||||
| 	RSL_IE_SIEMENS_TRACE_REF_NR	= 0x46, | ||||
| 	RSL_IE_SIEMENS_INT_TRACE_IDX	= 0x47, | ||||
| 	RSL_IE_SIEMENS_L2_HDR_INFO	= 0x48, | ||||
| 	RSL_IE_SIEMENS_HIGHEST_RATE	= 0x4e, | ||||
| 	RSL_IE_SIEMENS_SUGGESTED_RATE	= 0x4f, | ||||
|  | ||||
| 	/* ip.access */ | ||||
| 	RSL_IE_IPAC_SRTP_CONFIG	= 0xe0, | ||||
| 	RSL_IE_IPAC_PROXY_UDP	= 0xe1, | ||||
| 	RSL_IE_IPAC_BSCMPL_TOUT	= 0xe2, | ||||
| 	RSL_IE_IPAC_REMOTE_IP	= 0xf0, | ||||
| 	RSL_IE_IPAC_REMOTE_PORT	= 0xf1, | ||||
| 	RSL_IE_IPAC_RTP_PAYLOAD	= 0xf2, | ||||
| 	RSL_IE_IPAC_LOCAL_PORT	= 0xf3, | ||||
| 	RSL_IE_IPAC_SPEECH_MODE	= 0xf4, | ||||
| 	RSL_IE_IPAC_LOCAL_IP	= 0xf5, | ||||
| 	RSL_IE_IPAC_CONN_STAT	= 0xf6, | ||||
| 	RSL_IE_IPAC_HO_C_PARMS	= 0xf7, | ||||
| 	RSL_IE_IPAC_CONN_ID	= 0xf8, | ||||
| 	RSL_IE_IPAC_RTP_CSD_FMT	= 0xf9, | ||||
| 	RSL_IE_IPAC_RTP_JIT_BUF	= 0xfa, | ||||
| 	RSL_IE_IPAC_RTP_COMPR	= 0xfb, | ||||
| 	RSL_IE_IPAC_RTP_PAYLOAD2= 0xfc, | ||||
| 	RSL_IE_IPAC_RTP_MPLEX	= 0xfd, | ||||
| 	RSL_IE_IPAC_RTP_MPLEX_ID= 0xfe, | ||||
| }; | ||||
|  | ||||
| /* Chapter 9.3.1 */ | ||||
| #define RSL_CHAN_NR_MASK	0xf8 | ||||
| #define RSL_CHAN_Bm_ACCHs	0x08 | ||||
| #define RSL_CHAN_Lm_ACCHs	0x10	/* .. 0x18 */ | ||||
| #define RSL_CHAN_SDCCH4_ACCH	0x20	/* .. 0x38 */ | ||||
| #define RSL_CHAN_SDCCH8_ACCH	0x40	/* ...0x78 */ | ||||
| #define RSL_CHAN_BCCH		0x80 | ||||
| #define RSL_CHAN_RACH		0x88 | ||||
| #define RSL_CHAN_PCH_AGCH	0x90 | ||||
|  | ||||
| /* Chapter 9.3.3 */ | ||||
| #define RSL_ACT_TYPE_INITIAL	0x00 | ||||
| #define RSL_ACT_TYPE_REACT	0x80 | ||||
| #define RSL_ACT_INTRA_IMM_ASS	0x00 | ||||
| #define RSL_ACT_INTRA_NORM_ASS	0x01 | ||||
| #define RSL_ACT_INTER_ASYNC	0x02 | ||||
| #define RSL_ACT_INTER_SYNC	0x03 | ||||
| #define RSL_ACT_SECOND_ADD	0x04 | ||||
| #define RSL_ACT_SECOND_MULTI	0x05 | ||||
|  | ||||
| /* Chapter 9.3.6 */ | ||||
| struct rsl_ie_chan_mode { | ||||
| 	uint8_t dtx_dtu; | ||||
| 	uint8_t spd_ind; | ||||
| 	uint8_t chan_rt; | ||||
| 	uint8_t chan_rate; | ||||
| } __attribute__ ((packed)); | ||||
| #define RSL_CMOD_DTXu		0x01	/* uplink */ | ||||
| #define RSL_CMOD_DTXd		0x02	/* downlink */ | ||||
| enum rsl_cmod_spd { | ||||
| 	RSL_CMOD_SPD_SPEECH	= 0x01, | ||||
| 	RSL_CMOD_SPD_DATA	= 0x02, | ||||
| 	RSL_CMOD_SPD_SIGN	= 0x03, | ||||
| }; | ||||
| #define RSL_CMOD_CRT_SDCCH	0x01 | ||||
| #define RSL_CMOD_CRT_TCH_Bm	0x08	/* full-rate */ | ||||
| #define RSL_CMOD_CRT_TCH_Lm	0x09	/* half-rate */ | ||||
| /* FIXME: More CRT types */ | ||||
| /* Speech */ | ||||
| #define RSL_CMOD_SP_GSM1	0x01 | ||||
| #define RSL_CMOD_SP_GSM2	0x11 | ||||
| #define RSL_CMOD_SP_GSM3	0x21 | ||||
| /* Data */ | ||||
| #define RSL_CMOD_SP_NT_14k5	0x58 | ||||
| #define RSL_CMOD_SP_NT_12k0	0x50 | ||||
| #define RSL_CMOD_SP_NT_6k0	0x51 | ||||
|  | ||||
| /* Chapter 9.3.5 */ | ||||
| struct rsl_ie_chan_ident { | ||||
| 	/* GSM 04.08 10.5.2.5 */ | ||||
| 	struct { | ||||
| 		uint8_t iei; | ||||
| 		uint8_t chan_nr;	/* enc_chan_nr */ | ||||
| 		uint8_t oct3; | ||||
| 		uint8_t oct4; | ||||
| 	} chan_desc; | ||||
| #if 0	/* spec says we need this but Abissim doesn't use it */ | ||||
| 	struct { | ||||
| 		uint8_t tag; | ||||
| 		uint8_t len; | ||||
| 	} mobile_alloc; | ||||
| #endif | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Chapter 9.3.22 */ | ||||
| #define RLL_CAUSE_T200_EXPIRED		0x01 | ||||
| #define RLL_CAUSE_REEST_REQ		0x02 | ||||
| #define RLL_CAUSE_UNSOL_UA_RESP		0x03 | ||||
| #define RLL_CAUSE_UNSOL_DM_RESP		0x04 | ||||
| #define RLL_CAUSE_UNSOL_DM_RESP_MF	0x05 | ||||
| #define RLL_CAUSE_UNSOL_SPRV_RESP	0x06 | ||||
| #define RLL_CAUSE_SEQ_ERR		0x07 | ||||
| #define RLL_CAUSE_UFRM_INC_PARAM	0x08 | ||||
| #define RLL_CAUSE_SFRM_INC_PARAM	0x09 | ||||
| #define RLL_CAUSE_IFRM_INC_MBITS	0x0a | ||||
| #define RLL_CAUSE_IFRM_INC_LEN		0x0b | ||||
| #define RLL_CAUSE_FRM_UNIMPL		0x0c | ||||
| #define RLL_CAUSE_SABM_MF		0x0d | ||||
| #define RLL_CAUSE_SABM_INFO_NOTALL	0x0e | ||||
|  | ||||
| /* Chapter 9.3.26 */ | ||||
| #define RSL_ERRCLS_NORMAL		0x00 | ||||
| #define RSL_ERRCLS_RESOURCE_UNAVAIL	0x20 | ||||
| #define RSL_ERRCLS_SERVICE_UNAVAIL	0x30 | ||||
| #define RSL_ERRCLS_SERVICE_UNIMPL	0x40 | ||||
| #define RSL_ERRCLS_INVAL_MSG		0x50 | ||||
| #define RSL_ERRCLS_PROTO_ERROR		0x60 | ||||
| #define RSL_ERRCLS_INTERWORKING		0x70 | ||||
|  | ||||
| /* normal event */ | ||||
| #define RSL_ERR_RADIO_IF_FAIL		0x00 | ||||
| #define RSL_ERR_RADIO_LINK_FAIL		0x01 | ||||
| #define RSL_ERR_HANDOVER_ACC_FAIL	0x02 | ||||
| #define RSL_ERR_TALKER_ACC_FAIL		0x03 | ||||
| #define RSL_ERR_OM_INTERVENTION		0x07 | ||||
| #define RSL_ERR_NORMAL_UNSPEC		0x0f | ||||
| #define RSL_ERR_T_MSRFPCI_EXP		0x18 | ||||
| /* resource unavailable */ | ||||
| #define RSL_ERR_EQUIPMENT_FAIL		0x20 | ||||
| #define RSL_ERR_RR_UNAVAIL		0x21 | ||||
| #define RSL_ERR_TERR_CH_FAIL		0x22 | ||||
| #define RSL_ERR_CCCH_OVERLOAD		0x23 | ||||
| #define RSL_ERR_ACCH_OVERLOAD		0x24 | ||||
| #define RSL_ERR_PROCESSOR_OVERLOAD	0x25 | ||||
| #define RSL_ERR_RES_UNAVAIL		0x2f | ||||
| /* service or option not available */ | ||||
| #define RSL_ERR_TRANSC_UNAVAIL		0x30 | ||||
| #define RSL_ERR_SERV_OPT_UNAVAIL	0x3f | ||||
| /* service or option not implemented */ | ||||
| #define RSL_ERR_ENCR_UNIMPL		0x40 | ||||
| #define RSL_ERR_SERV_OPT_UNIMPL		0x4f | ||||
| /* invalid message */ | ||||
| #define RSL_ERR_RCH_ALR_ACTV_ALLOC	0x50 | ||||
| #define RSL_ERR_INVALID_MESSAGE		0x5f | ||||
| /* protocol error */ | ||||
| #define RSL_ERR_MSG_DISCR		0x60 | ||||
| #define RSL_ERR_MSG_TYPE		0x61 | ||||
| #define RSL_ERR_MSG_SEQ			0x62 | ||||
| #define RSL_ERR_IE_ERROR		0x63 | ||||
| #define RSL_ERR_MAND_IE_ERROR		0x64 | ||||
| #define RSL_ERR_OPT_IE_ERROR		0x65 | ||||
| #define RSL_ERR_IE_NONEXIST		0x66 | ||||
| #define RSL_ERR_IE_LENGTH		0x67 | ||||
| #define RSL_ERR_IE_CONTENT		0x68 | ||||
| #define RSL_ERR_PROTO			0x6f | ||||
| /* interworking */ | ||||
| #define RSL_ERR_INTERWORKING		0x7f | ||||
|  | ||||
| /* Chapter 9.3.30 */ | ||||
| #define RSL_SYSTEM_INFO_8	0x00 | ||||
| #define RSL_SYSTEM_INFO_1	0x01 | ||||
| #define RSL_SYSTEM_INFO_2	0x02 | ||||
| #define RSL_SYSTEM_INFO_3	0x03 | ||||
| #define RSL_SYSTEM_INFO_4	0x04 | ||||
| #define RSL_SYSTEM_INFO_5	0x05 | ||||
| #define RSL_SYSTEM_INFO_6	0x06 | ||||
| #define RSL_SYSTEM_INFO_7	0x07 | ||||
| #define RSL_SYSTEM_INFO_16	0x08 | ||||
| #define RSL_SYSTEM_INFO_17	0x09 | ||||
| #define RSL_SYSTEM_INFO_2bis	0x0a | ||||
| #define RSL_SYSTEM_INFO_2ter	0x0b | ||||
| #define RSL_SYSTEM_INFO_5bis	0x0d | ||||
| #define RSL_SYSTEM_INFO_5ter	0x0e | ||||
| #define RSL_SYSTEM_INFO_10	0x0f | ||||
| #define REL_EXT_MEAS_ORDER	0x47 | ||||
| #define RSL_MEAS_INFO		0x48 | ||||
| #define RSL_SYSTEM_INFO_13	0x28 | ||||
| #define RSL_SYSTEM_INFO_2quater	0x29 | ||||
| #define RSL_SYSTEM_INFO_9	0x2a | ||||
| #define RSL_SYSTEM_INFO_18	0x2b | ||||
| #define RSL_SYSTEM_INFO_19	0x2c | ||||
| #define RSL_SYSTEM_INFO_20	0x2d | ||||
|  | ||||
| /* Chapter 9.3.40 */ | ||||
| #define RSL_CHANNEED_ANY	0x00 | ||||
| #define RSL_CHANNEED_SDCCH	0x01 | ||||
| #define RSL_CHANNEED_TCH_F	0x02 | ||||
| #define RSL_CHANNEED_TCH_ForH	0x03 | ||||
|  | ||||
| /* Chapter 3.3.2.3 Brocast control channel */ | ||||
| /* CCCH-CONF, NC is not combined */ | ||||
| #define RSL_BCCH_CCCH_CONF_1_NC	0x00 | ||||
| #define RSL_BCCH_CCCH_CONF_1_C	0x01 | ||||
| #define RSL_BCCH_CCCH_CONF_2_NC	0x02 | ||||
| #define RSL_BCCH_CCCH_CONF_3_NC	0x04 | ||||
| #define RSL_BCCH_CCCH_CONF_4_NC	0x06 | ||||
|  | ||||
| /* BS-PA-MFRMS */ | ||||
| #define RSL_BS_PA_MFRMS_2	0x00 | ||||
| #define RSL_BS_PA_MFRMS_3	0x01 | ||||
| #define RSL_BS_PA_MFRMS_4	0x02 | ||||
| #define RSL_BS_PA_MFRMS_5	0x03 | ||||
| #define RSL_BS_PA_MFRMS_6	0x04 | ||||
| #define RSL_BS_PA_MFRMS_7	0x05 | ||||
| #define RSL_BS_PA_MFRMS_8	0x06 | ||||
| #define RSL_BS_PA_MFRMS_9	0x07 | ||||
|  | ||||
| /* RSL_IE_IPAC_RTP_PAYLOAD[2] */ | ||||
| enum rsl_ipac_rtp_payload { | ||||
| 	RSL_IPAC_RTP_GSM	= 1, | ||||
| 	RSL_IPAC_RTP_EFR, | ||||
| 	RSL_IPAC_RTP_AMR, | ||||
| 	RSL_IPAC_RTP_CSD, | ||||
| 	RSL_IPAC_RTP_MUX, | ||||
| }; | ||||
|  | ||||
| /* RSL_IE_IPAC_SPEECH_MODE, lower four bits */ | ||||
| enum rsl_ipac_speech_mode_s { | ||||
| 	RSL_IPAC_SPEECH_GSM_FR = 0,	/* GSM FR (Type 1, FS) */ | ||||
| 	RSL_IPAC_SPEECH_GSM_EFR = 1,	/* GSM EFR (Type 2, FS) */ | ||||
| 	RSL_IPAC_SPEECH_GSM_AMR_FR = 2,	/* GSM AMR/FR (Type 3, FS) */ | ||||
| 	RSL_IPAC_SPEECH_GSM_HR = 3,	/* GSM HR (Type 1, HS) */ | ||||
| 	RSL_IPAC_SPEECH_GSM_AMR_HR = 5,	/* GSM AMR/hr (Type 3, HS) */ | ||||
| 	RSL_IPAC_SPEECH_AS_RTP = 0xf,	/* As specified by RTP Payload IE */ | ||||
| }; | ||||
| /* RSL_IE_IPAC_SPEECH_MODE, upper four bits */ | ||||
| enum rsl_ipac_speech_mode_m { | ||||
| 	RSL_IPAC_SPEECH_M_RXTX = 0,	/* Send and Receive */ | ||||
| 	RSL_IPAC_SPEECH_M_RX = 1,	/* Receive only */ | ||||
| 	RSL_IPAC_SPEECH_M_TX = 2,	/* Send only */ | ||||
| }; | ||||
|  | ||||
| /* RSL_IE_IPAC_RTP_CSD_FMT, lower four bits */ | ||||
| enum rsl_ipac_rtp_csd_format_d { | ||||
| 	RSL_IPAC_RTP_CSD_EXT_TRAU = 0, | ||||
| 	RSL_IPAC_RTP_CSD_NON_TRAU = 1, | ||||
| 	RSL_IPAC_RTP_CSD_TRAU_BTS = 2, | ||||
| 	RSL_IPAC_RTP_CSD_IWF_FREE = 3, | ||||
| }; | ||||
| /* RSL_IE_IPAC_RTP_CSD_FMT, upper four bits */ | ||||
| enum rsl_ipac_rtp_csd_format_ir { | ||||
| 	RSL_IPAC_RTP_CSD_IR_8k = 0, | ||||
| 	RSL_IPAC_RTP_CSD_IR_16k = 1, | ||||
| 	RSL_IPAC_RTP_CSD_IR_32k = 2, | ||||
| 	RSL_IPAC_RTP_CSD_IR_64k = 3, | ||||
| }; | ||||
|  | ||||
| /* Siemens vendor-specific RSL extensions */ | ||||
| struct rsl_mrpci { | ||||
| 	uint8_t power_class:3, | ||||
| 		 vgcs_capable:1, | ||||
| 		 vbs_capable:1, | ||||
| 		 gsm_phase:2; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| enum rsl_mrpci_pwrclass { | ||||
| 	RSL_MRPCI_PWRC_1	= 0, | ||||
| 	RSL_MRPCI_PWRC_2	= 1, | ||||
| 	RSL_MRPCI_PWRC_3	= 2, | ||||
| 	RSL_MRPCI_PWRC_4	= 3, | ||||
| 	RSL_MRPCI_PWRC_5	= 4, | ||||
| }; | ||||
| enum rsl_mrpci_phase { | ||||
| 	RSL_MRPCI_PHASE_1	= 0, | ||||
| 	/* reserved */ | ||||
| 	RSL_MRPCI_PHASE_2	= 2, | ||||
| 	RSL_MRPCI_PHASE_2PLUS	= 3, | ||||
| }; | ||||
|  | ||||
|  | ||||
| #endif /* PROTO_GSM_08_58_H */ | ||||
							
								
								
									
										713
									
								
								libosmocore/include/osmocore/protocol/gsm_12_21.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										713
									
								
								libosmocore/include/osmocore/protocol/gsm_12_21.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,713 @@ | ||||
| #ifndef PROTO_GSM_12_21_H | ||||
| #define PROTO_GSM_12_21_H | ||||
|  | ||||
| /* GSM Network Management messages on the A-bis interface  | ||||
|  * 3GPP TS 12.21 version 8.0.0 Release 1999 / ETSI TS 100 623 V8.0.0 */ | ||||
|  | ||||
| /* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <osmocore/tlv.h> | ||||
|  | ||||
| /* generic header in front of every OML message according to TS 08.59 */ | ||||
| struct abis_om_hdr { | ||||
| 	uint8_t	mdisc; | ||||
| 	uint8_t	placement; | ||||
| 	uint8_t	sequence; | ||||
| 	uint8_t	length; | ||||
| 	uint8_t	data[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| #define ABIS_OM_MDISC_FOM		0x80 | ||||
| #define ABIS_OM_MDISC_MMI		0x40 | ||||
| #define ABIS_OM_MDISC_TRAU		0x20 | ||||
| #define ABIS_OM_MDISC_MANUF		0x10 | ||||
| #define ABIS_OM_PLACEMENT_ONLY		0x80 | ||||
| #define ABIS_OM_PLACEMENT_FIRST 	0x40 | ||||
| #define ABIS_OM_PLACEMENT_MIDDLE	0x20 | ||||
| #define ABIS_OM_PLACEMENT_LAST		0x10 | ||||
|  | ||||
| struct abis_om_obj_inst { | ||||
| 	uint8_t	bts_nr; | ||||
| 	uint8_t	trx_nr; | ||||
| 	uint8_t	ts_nr; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| struct abis_om_fom_hdr { | ||||
| 	uint8_t	msg_type; | ||||
| 	uint8_t	obj_class; | ||||
| 	struct abis_om_obj_inst	obj_inst; | ||||
| 	uint8_t	data[0]; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| #define ABIS_OM_FOM_HDR_SIZE	(sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr)) | ||||
|  | ||||
| /* Section 9.1: Message Types */ | ||||
| enum abis_nm_msgtype { | ||||
| 	/* SW Download Management Messages */ | ||||
| 	NM_MT_LOAD_INIT			= 0x01, | ||||
| 	NM_MT_LOAD_INIT_ACK, | ||||
| 	NM_MT_LOAD_INIT_NACK, | ||||
| 	NM_MT_LOAD_SEG, | ||||
| 	NM_MT_LOAD_SEG_ACK, | ||||
| 	NM_MT_LOAD_ABORT, | ||||
| 	NM_MT_LOAD_END, | ||||
| 	NM_MT_LOAD_END_ACK, | ||||
| 	NM_MT_LOAD_END_NACK, | ||||
| 	NM_MT_SW_ACT_REQ,		/* BTS->BSC */ | ||||
| 	NM_MT_SW_ACT_REQ_ACK, | ||||
| 	NM_MT_SW_ACT_REQ_NACK, | ||||
| 	NM_MT_ACTIVATE_SW,		/* BSC->BTS */ | ||||
| 	NM_MT_ACTIVATE_SW_ACK, | ||||
| 	NM_MT_ACTIVATE_SW_NACK, | ||||
| 	NM_MT_SW_ACTIVATED_REP,		/* 0x10 */ | ||||
| 	/* A-bis Interface Management Messages */ | ||||
| 	NM_MT_ESTABLISH_TEI		= 0x21, | ||||
| 	NM_MT_ESTABLISH_TEI_ACK, | ||||
| 	NM_MT_ESTABLISH_TEI_NACK, | ||||
| 	NM_MT_CONN_TERR_SIGN, | ||||
| 	NM_MT_CONN_TERR_SIGN_ACK, | ||||
| 	NM_MT_CONN_TERR_SIGN_NACK, | ||||
| 	NM_MT_DISC_TERR_SIGN, | ||||
| 	NM_MT_DISC_TERR_SIGN_ACK, | ||||
| 	NM_MT_DISC_TERR_SIGN_NACK, | ||||
| 	NM_MT_CONN_TERR_TRAF, | ||||
| 	NM_MT_CONN_TERR_TRAF_ACK, | ||||
| 	NM_MT_CONN_TERR_TRAF_NACK, | ||||
| 	NM_MT_DISC_TERR_TRAF, | ||||
| 	NM_MT_DISC_TERR_TRAF_ACK, | ||||
| 	NM_MT_DISC_TERR_TRAF_NACK, | ||||
| 	/* Transmission Management Messages */ | ||||
| 	NM_MT_CONN_MDROP_LINK		= 0x31, | ||||
| 	NM_MT_CONN_MDROP_LINK_ACK, | ||||
| 	NM_MT_CONN_MDROP_LINK_NACK, | ||||
| 	NM_MT_DISC_MDROP_LINK, | ||||
| 	NM_MT_DISC_MDROP_LINK_ACK, | ||||
| 	NM_MT_DISC_MDROP_LINK_NACK, | ||||
| 	/* Air Interface Management Messages */ | ||||
| 	NM_MT_SET_BTS_ATTR		= 0x41, | ||||
| 	NM_MT_SET_BTS_ATTR_ACK, | ||||
| 	NM_MT_SET_BTS_ATTR_NACK, | ||||
| 	NM_MT_SET_RADIO_ATTR, | ||||
| 	NM_MT_SET_RADIO_ATTR_ACK, | ||||
| 	NM_MT_SET_RADIO_ATTR_NACK, | ||||
| 	NM_MT_SET_CHAN_ATTR, | ||||
| 	NM_MT_SET_CHAN_ATTR_ACK, | ||||
| 	NM_MT_SET_CHAN_ATTR_NACK, | ||||
| 	/* Test Management Messages */ | ||||
| 	NM_MT_PERF_TEST			= 0x51, | ||||
| 	NM_MT_PERF_TEST_ACK, | ||||
| 	NM_MT_PERF_TEST_NACK, | ||||
| 	NM_MT_TEST_REP, | ||||
| 	NM_MT_SEND_TEST_REP, | ||||
| 	NM_MT_SEND_TEST_REP_ACK, | ||||
| 	NM_MT_SEND_TEST_REP_NACK, | ||||
| 	NM_MT_STOP_TEST, | ||||
| 	NM_MT_STOP_TEST_ACK, | ||||
| 	NM_MT_STOP_TEST_NACK, | ||||
| 	/* State Management and Event Report Messages */ | ||||
| 	NM_MT_STATECHG_EVENT_REP	= 0x61, | ||||
| 	NM_MT_FAILURE_EVENT_REP, | ||||
| 	NM_MT_STOP_EVENT_REP, | ||||
| 	NM_MT_STOP_EVENT_REP_ACK, | ||||
| 	NM_MT_STOP_EVENT_REP_NACK, | ||||
| 	NM_MT_REST_EVENT_REP, | ||||
| 	NM_MT_REST_EVENT_REP_ACK, | ||||
| 	NM_MT_REST_EVENT_REP_NACK, | ||||
| 	NM_MT_CHG_ADM_STATE, | ||||
| 	NM_MT_CHG_ADM_STATE_ACK, | ||||
| 	NM_MT_CHG_ADM_STATE_NACK, | ||||
| 	NM_MT_CHG_ADM_STATE_REQ, | ||||
| 	NM_MT_CHG_ADM_STATE_REQ_ACK, | ||||
| 	NM_MT_CHG_ADM_STATE_REQ_NACK, | ||||
| 	NM_MT_REP_OUTST_ALARMS		= 0x93, | ||||
| 	NM_MT_REP_OUTST_ALARMS_ACK, | ||||
| 	NM_MT_REP_OUTST_ALARMS_NACK, | ||||
| 	/* Equipment Management Messages */ | ||||
| 	NM_MT_CHANGEOVER		= 0x71, | ||||
| 	NM_MT_CHANGEOVER_ACK, | ||||
| 	NM_MT_CHANGEOVER_NACK, | ||||
| 	NM_MT_OPSTART, | ||||
| 	NM_MT_OPSTART_ACK, | ||||
| 	NM_MT_OPSTART_NACK, | ||||
| 	NM_MT_REINIT, | ||||
| 	NM_MT_REINIT_ACK, | ||||
| 	NM_MT_REINIT_NACK, | ||||
| 	NM_MT_SET_SITE_OUT,		/* BS11: get alarm ?!? */ | ||||
| 	NM_MT_SET_SITE_OUT_ACK, | ||||
| 	NM_MT_SET_SITE_OUT_NACK, | ||||
| 	NM_MT_CHG_HW_CONF		= 0x90, | ||||
| 	NM_MT_CHG_HW_CONF_ACK, | ||||
| 	NM_MT_CHG_HW_CONF_NACK, | ||||
| 	/* Measurement Management Messages */ | ||||
| 	NM_MT_MEAS_RES_REQ		= 0x8a, | ||||
| 	NM_MT_MEAS_RES_RESP, | ||||
| 	NM_MT_STOP_MEAS, | ||||
| 	NM_MT_START_MEAS, | ||||
| 	/* Other Messages */ | ||||
| 	NM_MT_GET_ATTR			= 0x81, | ||||
| 	NM_MT_GET_ATTR_RESP, | ||||
| 	NM_MT_GET_ATTR_NACK, | ||||
| 	NM_MT_SET_ALARM_THRES, | ||||
| 	NM_MT_SET_ALARM_THRES_ACK, | ||||
| 	NM_MT_SET_ALARM_THRES_NACK, | ||||
| }; | ||||
|  | ||||
| enum abis_nm_msgtype_bs11 { | ||||
| 	NM_MT_BS11_RESET_RESOURCE	= 0x74, | ||||
|  | ||||
| 	NM_MT_BS11_BEGIN_DB_TX		= 0xa3, | ||||
| 	NM_MT_BS11_BEGIN_DB_TX_ACK, | ||||
| 	NM_MT_BS11_BEGIN_DB_TX_NACK, | ||||
| 	NM_MT_BS11_END_DB_TX		= 0xa6, | ||||
| 	NM_MT_BS11_END_DB_TX_ACK, | ||||
| 	NM_MT_BS11_END_DB_TX_NACK, | ||||
| 	NM_MT_BS11_CREATE_OBJ		= 0xa9, | ||||
| 	NM_MT_BS11_CREATE_OBJ_ACK, | ||||
| 	NM_MT_BS11_CREATE_OBJ_NACK, | ||||
| 	NM_MT_BS11_DELETE_OBJ		= 0xac, | ||||
| 	NM_MT_BS11_DELETE_OBJ_ACK, | ||||
| 	NM_MT_BS11_DELETE_OBJ_NACK, | ||||
|  | ||||
| 	NM_MT_BS11_SET_ATTR		= 0xd0, | ||||
| 	NM_MT_BS11_SET_ATTR_ACK, | ||||
| 	NM_MT_BS11_SET_ATTR_NACK, | ||||
| 	NM_MT_BS11_LMT_SESSION		= 0xdc, | ||||
|  | ||||
| 	NM_MT_BS11_GET_STATE		= 0xe3, | ||||
| 	NM_MT_BS11_GET_STATE_ACK, | ||||
| 	NM_MT_BS11_LMT_LOGON		= 0xe5, | ||||
| 	NM_MT_BS11_LMT_LOGON_ACK, | ||||
| 	NM_MT_BS11_RESTART		= 0xe7, | ||||
| 	NM_MT_BS11_RESTART_ACK, | ||||
| 	NM_MT_BS11_DISCONNECT		= 0xe9, | ||||
| 	NM_MT_BS11_DISCONNECT_ACK, | ||||
| 	NM_MT_BS11_LMT_LOGOFF		= 0xec, | ||||
| 	NM_MT_BS11_LMT_LOGOFF_ACK, | ||||
| 	NM_MT_BS11_RECONNECT		= 0xf1, | ||||
| 	NM_MT_BS11_RECONNECT_ACK, | ||||
| }; | ||||
|  | ||||
| enum abis_nm_msgtype_ipacc { | ||||
| 	NM_MT_IPACC_RESTART		= 0x87, | ||||
| 	NM_MT_IPACC_RESTART_ACK, | ||||
| 	NM_MT_IPACC_RESTART_NACK, | ||||
| 	NM_MT_IPACC_RSL_CONNECT		= 0xe0, | ||||
| 	NM_MT_IPACC_RSL_CONNECT_ACK, | ||||
| 	NM_MT_IPACC_RSL_CONNECT_NACK, | ||||
| 	NM_MT_IPACC_RSL_DISCONNECT	= 0xe3, | ||||
| 	NM_MT_IPACC_RSL_DISCONNECT_ACK, | ||||
| 	NM_MT_IPACC_RSL_DISCONNECT_NACK, | ||||
| 	NM_MT_IPACC_CONN_TRAF		= 0xe6, | ||||
| 	NM_MT_IPACC_CONN_TRAF_ACK, | ||||
| 	NM_MT_IPACC_CONN_TRAF_NACK, | ||||
| 	NM_MT_IPACC_DEF_BOOT_SW		= 0xec, | ||||
| 	NM_MT_IPACC_DEF_BOOT_SW_ACK, | ||||
| 	MN_MT_IPACC_DEF_BOOT_SW_NACK, | ||||
| 	NM_MT_IPACC_SET_NVATTR		= 0xef, | ||||
| 	NM_MT_IPACC_SET_NVATTR_ACK, | ||||
| 	NM_MT_IPACC_SET_NVATTR_NACK, | ||||
| 	NM_MT_IPACC_GET_NVATTR		= 0xf2, | ||||
| 	NM_MT_IPACC_GET_NVATTR_ACK, | ||||
| 	NM_MT_IPACC_GET_NVATTR_NACK, | ||||
| 	NM_MT_IPACC_SET_ATTR		= 0xf5, | ||||
| 	NM_MT_IPACC_SET_ATTR_ACK, | ||||
| 	NM_MT_IPACC_SET_ATTR_NACK, | ||||
| }; | ||||
|  | ||||
| enum abis_nm_bs11_cell_alloc { | ||||
| 	NM_BS11_CANR_GSM	= 0x00, | ||||
| 	NM_BS11_CANR_DCS1800	= 0x01, | ||||
| }; | ||||
|  | ||||
| /* Section 9.2: Object Class */ | ||||
| enum abis_nm_obj_class { | ||||
| 	NM_OC_SITE_MANAGER		= 0x00, | ||||
| 	NM_OC_BTS, | ||||
| 	NM_OC_RADIO_CARRIER, | ||||
| 	NM_OC_CHANNEL, | ||||
| 	NM_OC_BASEB_TRANSC, | ||||
| 	/* RFU: 05-FE */ | ||||
|  | ||||
| 	NM_OC_IPAC_E1_TRUNK		= 0x0e, | ||||
| 	NM_OC_IPAC_E1_PORT		= 0x0f, | ||||
| 	NM_OC_IPAC_E1_CHAN		= 0x10, | ||||
| 	NM_OC_IPAC_CLK_MODULE		= 0x22, | ||||
|  | ||||
| 	NM_OC_BS11_ADJC			= 0xa0, | ||||
| 	NM_OC_BS11_HANDOVER		= 0xa1, | ||||
| 	NM_OC_BS11_PWR_CTRL		= 0xa2, | ||||
| 	NM_OC_BS11_BTSE			= 0xa3,		/* LMT? */ | ||||
| 	NM_OC_BS11_RACK			= 0xa4, | ||||
| 	NM_OC_BS11			= 0xa5,		/* 01: ALCO */ | ||||
| 	NM_OC_BS11_TEST			= 0xa6, | ||||
| 	NM_OC_BS11_ENVABTSE		= 0xa8, | ||||
| 	NM_OC_BS11_BPORT		= 0xa9, | ||||
|  | ||||
| 	NM_OC_GPRS_NSE			= 0xf0, | ||||
| 	NM_OC_GPRS_CELL			= 0xf1, | ||||
| 	NM_OC_GPRS_NSVC			= 0xf2, | ||||
|  | ||||
| 	NM_OC_NULL			= 0xff, | ||||
| }; | ||||
|  | ||||
| /* Section 9.4: Attributes */ | ||||
| enum abis_nm_attr { | ||||
| 	NM_ATT_ABIS_CHANNEL	= 0x01, | ||||
| 	NM_ATT_ADD_INFO, | ||||
| 	NM_ATT_ADD_TEXT, | ||||
| 	NM_ATT_ADM_STATE, | ||||
| 	NM_ATT_ARFCN_LIST, | ||||
| 	NM_ATT_AUTON_REPORT, | ||||
| 	NM_ATT_AVAIL_STATUS, | ||||
| 	NM_ATT_BCCH_ARFCN, | ||||
| 	NM_ATT_BSIC, | ||||
| 	NM_ATT_BTS_AIR_TIMER, | ||||
| 	NM_ATT_CCCH_L_I_P, | ||||
| 	NM_ATT_CCCH_L_T, | ||||
| 	NM_ATT_CHAN_COMB, | ||||
| 	NM_ATT_CONN_FAIL_CRIT, | ||||
| 	NM_ATT_DEST, | ||||
| 	/* res */ | ||||
| 	NM_ATT_EVENT_TYPE	= 0x11, /* BS11: file data ?!? */ | ||||
| 	NM_ATT_FILE_ID, | ||||
| 	NM_ATT_FILE_VERSION, | ||||
| 	NM_ATT_GSM_TIME, | ||||
| 	NM_ATT_HSN, | ||||
| 	NM_ATT_HW_CONFIG, | ||||
| 	NM_ATT_HW_DESC, | ||||
| 	NM_ATT_INTAVE_PARAM, | ||||
| 	NM_ATT_INTERF_BOUND, | ||||
| 	NM_ATT_LIST_REQ_ATTR, | ||||
| 	NM_ATT_MAIO, | ||||
| 	NM_ATT_MANUF_STATE, | ||||
| 	NM_ATT_MANUF_THRESH, | ||||
| 	NM_ATT_MANUF_ID, | ||||
| 	NM_ATT_MAX_TA, | ||||
| 	NM_ATT_MDROP_LINK,	/* 0x20 */ | ||||
| 	NM_ATT_MDROP_NEXT, | ||||
| 	NM_ATT_NACK_CAUSES, | ||||
| 	NM_ATT_NY1, | ||||
| 	NM_ATT_OPER_STATE, | ||||
| 	NM_ATT_OVERL_PERIOD, | ||||
| 	NM_ATT_PHYS_CONF, | ||||
| 	NM_ATT_POWER_CLASS, | ||||
| 	NM_ATT_POWER_THRESH, | ||||
| 	NM_ATT_PROB_CAUSE, | ||||
| 	NM_ATT_RACH_B_THRESH, | ||||
| 	NM_ATT_LDAVG_SLOTS, | ||||
| 	NM_ATT_RAD_SUBC, | ||||
| 	NM_ATT_RF_MAXPOWR_R, | ||||
| 	NM_ATT_SITE_INPUTS, | ||||
| 	NM_ATT_SITE_OUTPUTS, | ||||
| 	NM_ATT_SOURCE,		/* 0x30 */ | ||||
| 	NM_ATT_SPEC_PROB, | ||||
| 	NM_ATT_START_TIME, | ||||
| 	NM_ATT_T200, | ||||
| 	NM_ATT_TEI, | ||||
| 	NM_ATT_TEST_DUR, | ||||
| 	NM_ATT_TEST_NO, | ||||
| 	NM_ATT_TEST_REPORT, | ||||
| 	NM_ATT_VSWR_THRESH, | ||||
| 	NM_ATT_WINDOW_SIZE, | ||||
| 	/* Res  */ | ||||
| 	NM_ATT_BS11_RSSI_OFFS	= 0x3d, | ||||
| 	NM_ATT_BS11_TXPWR	= 0x3e, | ||||
| 	NM_ATT_BS11_DIVERSITY	= 0x3f, | ||||
| 	/* Res  */ | ||||
| 	NM_ATT_TSC		= 0x40, | ||||
| 	NM_ATT_SW_CONFIG, | ||||
| 	NM_ATT_SW_DESCR, | ||||
| 	NM_ATT_SEVERITY, | ||||
| 	NM_ATT_GET_ARI, | ||||
| 	NM_ATT_HW_CONF_CHG, | ||||
| 	NM_ATT_OUTST_ALARM, | ||||
| 	NM_ATT_FILE_DATA, | ||||
| 	NM_ATT_MEAS_RES, | ||||
| 	NM_ATT_MEAS_TYPE, | ||||
|  | ||||
| 	NM_ATT_BS11_ESN_FW_CODE_NO	= 0x4c, | ||||
| 	NM_ATT_BS11_ESN_HW_CODE_NO	= 0x4f, | ||||
|  | ||||
| 	NM_ATT_BS11_ESN_PCB_SERIAL	= 0x55, | ||||
| 	NM_ATT_BS11_EXCESSIVE_DISTANCE	= 0x58, | ||||
|  | ||||
| 	NM_ATT_BS11_ALL_TEST_CATG	= 0x60, | ||||
| 	NM_ATT_BS11_BTSLS_HOPPING, | ||||
| 	NM_ATT_BS11_CELL_ALLOC_NR, | ||||
| 	NM_ATT_BS11_CELL_GLOBAL_ID, | ||||
| 	NM_ATT_BS11_ENA_INTERF_CLASS	= 0x66, | ||||
| 	NM_ATT_BS11_ENA_INT_INTEC_HANDO	= 0x67, | ||||
| 	NM_ATT_BS11_ENA_INT_INTRC_HANDO	= 0x68, | ||||
| 	NM_ATT_BS11_ENA_MS_PWR_CTRL	= 0x69, | ||||
| 	NM_ATT_BS11_ENA_PWR_BDGT_HO	= 0x6a, | ||||
| 	NM_ATT_BS11_ENA_PWR_CTRL_RLFW	= 0x6b, | ||||
| 	NM_ATT_BS11_ENA_RXLEV_HO	= 0x6c, | ||||
| 	NM_ATT_BS11_ENA_RXQUAL_HO	= 0x6d, | ||||
| 	NM_ATT_BS11_FACCH_QUAL		= 0x6e, | ||||
|  | ||||
| 	NM_ATT_IPACC_DST_IP		= 0x80, | ||||
| 	NM_ATT_IPACC_DST_IP_PORT	= 0x81, | ||||
| 	NM_ATT_IPACC_SSRC		= 0x82, | ||||
| 	NM_ATT_IPACC_RTP_PAYLD_TYPE	= 0x83, | ||||
| 	NM_ATT_IPACC_BASEB_ID		= 0x84, | ||||
| 	NM_ATT_IPACC_STREAM_ID		= 0x85, | ||||
| 	NM_ATT_IPACC_NV_FLAGS		= 0x86, | ||||
| 	NM_ATT_IPACC_FREQ_CTRL		= 0x87, | ||||
| 	NM_ATT_IPACC_PRIM_OML_CFG	= 0x88, | ||||
| 	NM_ATT_IPACC_SEC_OML_CFG	= 0x89, | ||||
| 	NM_ATT_IPACC_IP_IF_CFG		= 0x8a,		/* IP interface */ | ||||
| 	NM_ATT_IPACC_IP_GW_CFG		= 0x8b,		/* IP gateway */ | ||||
| 	NM_ATT_IPACC_IN_SERV_TIME	= 0x8c, | ||||
| 	NM_ATT_IPACC_TRX_BTS_ASS	= 0x8d, | ||||
| 	NM_ATT_IPACC_LOCATION		= 0x8e,		/* string describing location */ | ||||
| 	NM_ATT_IPACC_PAGING_CFG		= 0x8f, | ||||
| 	NM_ATT_IPACC_FILE_DATA		= 0x90, | ||||
| 	NM_ATT_IPACC_UNIT_ID		= 0x91,		/* Site/BTS/TRX */ | ||||
| 	NM_ATT_IPACC_PARENT_UNIT_ID	= 0x92, | ||||
| 	NM_ATT_IPACC_UNIT_NAME		= 0x93,		/* default: nbts-<mac-as-string> */ | ||||
| 	NM_ATT_IPACC_SNMP_CFG		= 0x94, | ||||
| 	NM_ATT_IPACC_PRIM_OML_CFG_LIST	= 0x95, | ||||
| 	NM_ATT_IPACC_PRIM_OML_FB_TOUT	= 0x96, | ||||
| 	NM_ATT_IPACC_CUR_SW_CFG		= 0x97, | ||||
| 	NM_ATT_IPACC_TIMING_BUS		= 0x98, | ||||
| 	NM_ATT_IPACC_CGI		= 0x99, | ||||
| 	NM_ATT_IPACC_RAC		= 0x9a, | ||||
| 	NM_ATT_IPACC_OBJ_VERSION	= 0x9b, | ||||
| 	NM_ATT_IPACC_GPRS_PAGING_CFG	= 0x9c, | ||||
| 	NM_ATT_IPACC_NSEI		= 0x9d, | ||||
| 	NM_ATT_IPACC_BVCI		= 0x9e, | ||||
| 	NM_ATT_IPACC_NSVCI		= 0x9f, | ||||
| 	NM_ATT_IPACC_NS_CFG		= 0xa0, | ||||
| 	NM_ATT_IPACC_BSSGP_CFG		= 0xa1, | ||||
| 	NM_ATT_IPACC_NS_LINK_CFG	= 0xa2, | ||||
| 	NM_ATT_IPACC_RLC_CFG		= 0xa3,	 | ||||
| 	NM_ATT_IPACC_ALM_THRESH_LIST	= 0xa4, | ||||
| 	NM_ATT_IPACC_MONIT_VAL_LIST	= 0xa5, | ||||
| 	NM_ATT_IPACC_TIB_CONTROL	= 0xa6, | ||||
| 	NM_ATT_IPACC_SUPP_FEATURES	= 0xa7, | ||||
| 	NM_ATT_IPACC_CODING_SCHEMES	= 0xa8, | ||||
| 	NM_ATT_IPACC_RLC_CFG_2		= 0xa9, | ||||
| 	NM_ATT_IPACC_HEARTB_TOUT	= 0xaa, | ||||
| 	NM_ATT_IPACC_UPTIME		= 0xab, | ||||
| 	NM_ATT_IPACC_RLC_CFG_3		= 0xac, | ||||
| 	NM_ATT_IPACC_SSL_CFG		= 0xad, | ||||
| 	NM_ATT_IPACC_SEC_POSSIBLE	= 0xae, | ||||
| 	NM_ATT_IPACC_IML_SSL_STATE	= 0xaf, | ||||
| 	NM_ATT_IPACC_REVOC_DATE		= 0xb0, | ||||
|  | ||||
|  | ||||
| 	NM_ATT_BS11_RF_RES_IND_PER	= 0x8f, | ||||
| 	 | ||||
| 	NM_ATT_BS11_RX_LEV_MIN_CELL	= 0x90, | ||||
| 	NM_ATT_BS11_ABIS_EXT_TIME	= 0x91, | ||||
| 	NM_ATT_BS11_TIMER_HO_REQUEST	= 0x92, | ||||
| 	NM_ATT_BS11_TIMER_NCELL		= 0x93, | ||||
| 	NM_ATT_BS11_TSYNC		= 0x94, | ||||
| 	NM_ATT_BS11_TTRAU		= 0x95, | ||||
| 	NM_ATT_BS11_EMRG_CFG_MEMBER	= 0x9b, | ||||
| 	NM_ATT_BS11_TRX_AREA		= 0x9f, | ||||
|  | ||||
| 	NM_ATT_BS11_BCCH_RECONF		= 0xd7, | ||||
| 	NM_ATT_BS11_BIT_ERR_THESH	= 0xa0, | ||||
| 	NM_ATT_BS11_BOOT_SW_VERS	= 0xa1, | ||||
| 	NM_ATT_BS11_CCLK_ACCURACY	= 0xa3, | ||||
| 	NM_ATT_BS11_CCLK_TYPE		= 0xa4, | ||||
| 	NM_ATT_BS11_INP_IMPEDANCE	= 0xaa, | ||||
| 	NM_ATT_BS11_L1_PROT_TYPE	= 0xab, | ||||
| 	NM_ATT_BS11_LINE_CFG		= 0xac, | ||||
| 	NM_ATT_BS11_LI_PORT_1		= 0xad, | ||||
| 	NM_ATT_BS11_LI_PORT_2		= 0xae, | ||||
|  | ||||
| 	NM_ATT_BS11_L1_REM_ALM_TYPE	= 0xb0, | ||||
| 	NM_ATT_BS11_SW_LOAD_INTENDED	= 0xbb, | ||||
| 	NM_ATT_BS11_SW_LOAD_SAFETY	= 0xbc, | ||||
| 	NM_ATT_BS11_SW_LOAD_STORED	= 0xbd, | ||||
|  | ||||
| 	NM_ATT_BS11_VENDOR_NAME		= 0xc1, | ||||
| 	NM_ATT_BS11_HOPPING_MODE	= 0xc5, | ||||
| 	NM_ATT_BS11_LMT_LOGON_SESSION	= 0xc6, | ||||
| 	NM_ATT_BS11_LMT_LOGIN_TIME	= 0xc7, | ||||
| 	NM_ATT_BS11_LMT_USER_ACC_LEV	= 0xc8, | ||||
| 	NM_ATT_BS11_LMT_USER_NAME	= 0xc9, | ||||
|  | ||||
| 	NM_ATT_BS11_L1_CONTROL_TS	= 0xd8, | ||||
| 	NM_ATT_BS11_RADIO_MEAS_GRAN	= 0xdc,	/* in SACCH multiframes */ | ||||
| 	NM_ATT_BS11_RADIO_MEAS_REP	= 0xdd, | ||||
|  | ||||
| 	NM_ATT_BS11_SH_LAPD_INT_TIMER	= 0xe8, | ||||
|  | ||||
| 	NM_ATT_BS11_BTS_STATE		= 0xf0, | ||||
| 	NM_ATT_BS11_E1_STATE		= 0xf1, | ||||
| 	NM_ATT_BS11_PLL			= 0xf2, | ||||
| 	NM_ATT_BS11_RX_OFFSET		= 0xf3, | ||||
| 	NM_ATT_BS11_ANT_TYPE		= 0xf4, | ||||
| 	NM_ATT_BS11_PLL_MODE		= 0xfc, | ||||
| 	NM_ATT_BS11_PASSWORD		= 0xfd, | ||||
| }; | ||||
| #define NM_ATT_BS11_FILE_DATA	NM_ATT_EVENT_TYPE | ||||
|  | ||||
| /* Section 9.4.4: Administrative State */ | ||||
| enum abis_nm_adm_state { | ||||
| 	NM_STATE_LOCKED		= 0x01, | ||||
| 	NM_STATE_UNLOCKED	= 0x02, | ||||
| 	NM_STATE_SHUTDOWN	= 0x03, | ||||
| 	NM_STATE_NULL		= 0xff, | ||||
| }; | ||||
|  | ||||
| /* Section 9.4.7: Administrative State */ | ||||
| enum abis_nm_avail_state { | ||||
| 	NM_AVSTATE_IN_TEST	= 1, | ||||
| 	NM_AVSTATE_POWER_OFF	= 2, | ||||
| 	NM_AVSTATE_OFF_LINE	= 3, | ||||
| 	NM_AVSTATE_DEPENDENCY	= 5, | ||||
| 	NM_AVSTATE_DEGRADED	= 6, | ||||
| 	NM_AVSTATE_NOT_INSTALLED= 7, | ||||
| 	NM_AVSTATE_OK		= 0xff, | ||||
| }; | ||||
|  | ||||
| enum abis_nm_op_state { | ||||
| 	NM_OPSTATE_DISABLED	= 1, | ||||
| 	NM_OPSTATE_ENABLED	= 2, | ||||
| 	NM_OPSTATE_NULL		= 0xff, | ||||
| }; | ||||
|  | ||||
| /* Section 9.4.13: Channel Combination */ | ||||
| enum abis_nm_chan_comb { | ||||
| 	NM_CHANC_TCHFull	= 0x00,	/* TCH/F + TCH/H + SACCH/TF */ | ||||
| 	NM_CHANC_TCHHalf	= 0x01, /* TCH/H(0,1) + FACCH/H(0,1) + | ||||
| 					   SACCH/TH(0,1) */ | ||||
| 	NM_CHANC_TCHHalf2	= 0x02, /* TCH/H(0) + FACCH/H(0) + SACCH/TH(0) + | ||||
| 					   TCH/H(1) */ | ||||
| 	NM_CHANC_SDCCH		= 0x03,	/* SDCCH/8 + SACCH/8 */ | ||||
| 	NM_CHANC_mainBCCH	= 0x04,	/* FCCH + SCH + BCCH + CCCH */ | ||||
| 	NM_CHANC_BCCHComb	= 0x05,	/* FCCH + SCH + BCCH + CCCH + SDCCH/4 + | ||||
| 					   SACCH/C4 */ | ||||
| 	NM_CHANC_BCCH		= 0x06,	/* BCCH + CCCH */ | ||||
| 	NM_CHANC_BCCH_CBCH	= 0x07,	/* CHANC_BCCHComb + CBCH */ | ||||
| 	NM_CHANC_SDCCH_CBCH	= 0x08,	/* CHANC_SDCCH8 + CBCH */ | ||||
| 	/* ip.access */ | ||||
| 	NM_CHANC_IPAC_bPDCH	= 0x0b,	/* PBCCH + PCCCH + PDTCH/F + PACCH/F + | ||||
| 					   PTCCH/F */ | ||||
| 	NM_CHANC_IPAC_cPDCH	= 0x0c, /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */ | ||||
| 	NM_CHANC_IPAC_PDCH	= 0x0d,	/* PDTCH/F + PACCH/F + PTCCH/F */ | ||||
| 	NM_CHANC_IPAC_TCHFull_PDCH = 0x80, | ||||
| 	NM_CHANC_IPAC_TCHFull_TCHHalf = 0x81, | ||||
| }; | ||||
|  | ||||
| /* Section 9.4.16: Event Type */ | ||||
| enum abis_nm_event_type { | ||||
| 	NM_EVT_COMM_FAIL	= 0x00, | ||||
| 	NM_EVT_QOS_FAIL		= 0x01, | ||||
| 	NM_EVT_PROC_FAIL	= 0x02, | ||||
| 	NM_EVT_EQUIP_FAIL	= 0x03, | ||||
| 	NM_EVT_ENV_FAIL		= 0x04, | ||||
| }; | ||||
|  | ||||
| /* Section: 9.4.63: Perceived Severity */ | ||||
| enum abis_nm_severity { | ||||
| 	NM_SEVER_CEASED		= 0x00, | ||||
| 	NM_SEVER_CRITICAL	= 0x01, | ||||
| 	NM_SEVER_MAJOR		= 0x02, | ||||
| 	NM_SEVER_MINOR		= 0x03, | ||||
| 	NM_SEVER_WARNING	= 0x04, | ||||
| 	NM_SEVER_INDETERMINATE	= 0x05, | ||||
| }; | ||||
|  | ||||
| /* Section 9.4.43: Probable Cause Type */ | ||||
| enum abis_nm_pcause_type { | ||||
| 	NM_PCAUSE_T_X721	= 0x01, | ||||
| 	NM_PCAUSE_T_GSM		= 0x02, | ||||
| 	NM_PCAUSE_T_MANUF	= 0x03, | ||||
| }; | ||||
|  | ||||
| /* Section 9.4.36: NACK Causes */ | ||||
| enum abis_nm_nack_cause { | ||||
| 	/* General Nack Causes */ | ||||
| 	NM_NACK_INCORR_STRUCT		= 0x01, | ||||
| 	NM_NACK_MSGTYPE_INVAL		= 0x02, | ||||
| 	NM_NACK_OBJCLASS_INVAL		= 0x05, | ||||
| 	NM_NACK_OBJCLASS_NOTSUPP	= 0x06, | ||||
| 	NM_NACK_BTSNR_UNKN		= 0x07, | ||||
| 	NM_NACK_TRXNR_UNKN		= 0x08, | ||||
| 	NM_NACK_OBJINST_UNKN		= 0x09, | ||||
| 	NM_NACK_ATTRID_INVAL		= 0x0c, | ||||
| 	NM_NACK_ATTRID_NOTSUPP		= 0x0d, | ||||
| 	NM_NACK_PARAM_RANGE		= 0x0e, | ||||
| 	NM_NACK_ATTRLIST_INCONSISTENT	= 0x0f, | ||||
| 	NM_NACK_SPEC_IMPL_NOTSUPP	= 0x10, | ||||
| 	NM_NACK_CANT_PERFORM		= 0x11, | ||||
| 	/* Specific Nack Causes */ | ||||
| 	NM_NACK_RES_NOTIMPL		= 0x19, | ||||
| 	NM_NACK_RES_NOTAVAIL		= 0x1a, | ||||
| 	NM_NACK_FREQ_NOTAVAIL		= 0x1b, | ||||
| 	NM_NACK_TEST_NOTSUPP		= 0x1c, | ||||
| 	NM_NACK_CAPACITY_RESTR		= 0x1d, | ||||
| 	NM_NACK_PHYSCFG_NOTPERFORM	= 0x1e, | ||||
| 	NM_NACK_TEST_NOTINIT		= 0x1f, | ||||
| 	NM_NACK_PHYSCFG_NOTRESTORE	= 0x20, | ||||
| 	NM_NACK_TEST_NOSUCH		= 0x21, | ||||
| 	NM_NACK_TEST_NOSTOP		= 0x22, | ||||
| 	NM_NACK_MSGINCONSIST_PHYSCFG	= 0x23, | ||||
| 	NM_NACK_FILE_INCOMPLETE		= 0x25, | ||||
| 	NM_NACK_FILE_NOTAVAIL		= 0x26, | ||||
| 	NM_NACK_FILE_NOTACTIVATE	= 0x27, | ||||
| 	NM_NACK_REQ_NOT_GRANT		= 0x28, | ||||
| 	NM_NACK_WAIT			= 0x29, | ||||
| 	NM_NACK_NOTH_REPORT_EXIST	= 0x2a, | ||||
| 	NM_NACK_MEAS_NOTSUPP		= 0x2b, | ||||
| 	NM_NACK_MEAS_NOTSTART		= 0x2c, | ||||
| }; | ||||
|  | ||||
| /* Section 9.4.1 */ | ||||
| struct abis_nm_channel { | ||||
| 	uint8_t	attrib; | ||||
| 	uint8_t	bts_port; | ||||
| 	uint8_t	timeslot; | ||||
| 	uint8_t	subslot; | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
| /* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */ | ||||
| enum abis_bs11_objtype { | ||||
| 	BS11_OBJ_ALCO		= 0x01, | ||||
| 	BS11_OBJ_BBSIG		= 0x02,	/* obj_class: 0,1 */ | ||||
| 	BS11_OBJ_TRX1		= 0x03,	/* only DEACTIVATE TRX1 */ | ||||
| 	BS11_OBJ_CCLK		= 0x04, | ||||
| 	BS11_OBJ_GPSU		= 0x06, | ||||
| 	BS11_OBJ_LI		= 0x07, | ||||
| 	BS11_OBJ_PA		= 0x09,	/* obj_class: 0, 1*/ | ||||
| }; | ||||
|  | ||||
| enum abis_bs11_trx_power { | ||||
| 	BS11_TRX_POWER_GSM_2W	= 0x06, | ||||
| 	BS11_TRX_POWER_GSM_250mW= 0x07, | ||||
| 	BS11_TRX_POWER_GSM_80mW	= 0x08, | ||||
| 	BS11_TRX_POWER_GSM_30mW	= 0x09, | ||||
| 	BS11_TRX_POWER_DCS_3W	= 0x0a, | ||||
| 	BS11_TRX_POWER_DCS_1W6	= 0x0b, | ||||
| 	BS11_TRX_POWER_DCS_500mW= 0x0c, | ||||
| 	BS11_TRX_POWER_DCS_160mW= 0x0d, | ||||
| }; | ||||
|  | ||||
| enum abis_bs11_li_pll_mode { | ||||
| 	BS11_LI_PLL_LOCKED	= 2, | ||||
| 	BS11_LI_PLL_STANDALONE	= 3, | ||||
| }; | ||||
|  | ||||
| enum abis_bs11_line_cfg { | ||||
| 	BS11_LINE_CFG_STAR	= 0x00, | ||||
| 	BS11_LINE_CFG_MULTIDROP	= 0x01, | ||||
| 	BS11_LINE_CFG_LOOP	= 0x02, | ||||
| }; | ||||
|  | ||||
| enum abis_bs11_phase { | ||||
| 	BS11_STATE_SOFTWARE_RQD		= 0x01, | ||||
| 	BS11_STATE_LOAD_SMU_INTENDED	= 0x11, | ||||
| 	BS11_STATE_LOAD_SMU_SAFETY	= 0x21, | ||||
| 	BS11_STATE_LOAD_FAILED		= 0x31, | ||||
| 	BS11_STATE_LOAD_DIAGNOSTIC	= 0x41, | ||||
| 	BS11_STATE_WARM_UP		= 0x51, | ||||
| 	BS11_STATE_WARM_UP_2		= 0x52, | ||||
| 	BS11_STATE_WAIT_MIN_CFG		= 0x62, | ||||
| 	BS11_STATE_MAINTENANCE		= 0x72, | ||||
| 	BS11_STATE_LOAD_MBCCU		= 0x92, | ||||
| 	BS11_STATE_WAIT_MIN_CFG_2	= 0xA2, | ||||
| 	BS11_STATE_NORMAL		= 0x03, | ||||
| 	BS11_STATE_ABIS_LOAD		= 0x13, | ||||
| }; | ||||
|  | ||||
| enum abis_nm_ipacc_test_no { | ||||
| 	NM_IPACC_TESTNO_RLOOP_ANT	= 0x01, | ||||
| 	NM_IPACC_TESTNO_RLOOP_XCVR	= 0x02, | ||||
| 	NM_IPACC_TESTNO_FUNC_OBJ	= 0x03, | ||||
| 	NM_IPACC_TESTNO_CHAN_USAGE	= 0x40, | ||||
| 	NM_IPACC_TESTNO_BCCH_CHAN_USAGE	= 0x41, | ||||
| 	NM_IPACC_TESTNO_FREQ_SYNC	= 0x42, | ||||
| 	NM_IPACC_TESTNO_BCCH_INFO	= 0x43, | ||||
| 	NM_IPACC_TESTNO_TX_BEACON	= 0x44, | ||||
| 	NM_IPACC_TESTNO_SYSINFO_MONITOR	= 0x45, | ||||
| 	NM_IPACC_TESTNO_BCCCH_MONITOR	= 0x46, | ||||
| }; | ||||
|  | ||||
| /* first byte after length inside NM_ATT_TEST_REPORT */ | ||||
| enum abis_nm_ipacc_test_res { | ||||
| 	NM_IPACC_TESTRES_SUCCESS	= 0, | ||||
| 	NM_IPACC_TESTRES_TIMEOUT	= 1, | ||||
| 	NM_IPACC_TESTRES_NO_CHANS	= 2, | ||||
| 	NM_IPACC_TESTRES_PARTIAL	= 3, | ||||
| 	NM_IPACC_TESTRES_STOPPED	= 4, | ||||
| }; | ||||
|  | ||||
| /* internal IE inside NM_ATT_TEST_REPORT */ | ||||
| enum abis_nm_ipacc_testres_ie { | ||||
| 	NM_IPACC_TR_IE_FREQ_ERR_LIST	= 3, | ||||
| 	NM_IPACC_TR_IE_CHAN_USAGE	= 4, | ||||
| 	NM_IPACC_TR_IE_BCCH_INFO	= 6, | ||||
| 	NM_IPACC_TR_IE_RESULT_DETAILS	= 8, | ||||
| 	NM_IPACC_TR_IE_FREQ_ERR		= 18, | ||||
| }; | ||||
|  | ||||
| enum ipac_eie { | ||||
| 	NM_IPAC_EIE_ARFCN_WHITE		= 0x01, | ||||
| 	NM_IPAC_EIE_ARFCH_BLACK		= 0x02, | ||||
| 	NM_IPAC_EIE_FREQ_ERR_LIST	= 0x03, | ||||
| 	NM_IPAC_EIE_CHAN_USE_LIST	= 0x04, | ||||
| 	NM_IPAC_EIE_BCCH_INFO_TYPE	= 0x05, | ||||
| 	NM_IPAC_EIE_BCCH_INFO		= 0x06, | ||||
| 	NM_IPAC_EIE_CONFIG		= 0x07, | ||||
| 	NM_IPAC_EIE_RES_DETAILS		= 0x08, | ||||
| 	NM_IPAC_EIE_RXLEV_THRESH	= 0x09, | ||||
| 	NM_IPAC_EIE_FREQ_SYNC_OPTS	= 0x0a, | ||||
| 	NM_IPAC_EIE_MAC_ADDR		= 0x0b, | ||||
| 	NM_IPAC_EIE_HW_SW_COMPAT_NR	= 0x0c, | ||||
| 	NM_IPAC_EIE_MANUF_SER_NR	= 0x0d, | ||||
| 	NM_IPAC_EIE_OEM_ID		= 0x0e, | ||||
| 	NM_IPAC_EIE_DATE_TIME_MANUF	= 0x0f, | ||||
| 	NM_IPAC_EIE_DATE_TIME_CALIB	= 0x10, | ||||
| 	NM_IPAC_EIE_BEACON_INFO		= 0x11, | ||||
| 	NM_IPAC_EIE_FREQ_ERR		= 0x12, | ||||
| 	/* FIXME */ | ||||
| 	NM_IPAC_EIE_FREQ_BANDS		= 0x1c, | ||||
| 	NM_IPAC_EIE_MAX_TA		= 0x1d, | ||||
| 	NM_IPAC_EIE_CIPH_ALGOS		= 0x1e, | ||||
| 	NM_IPAC_EIE_CHAN_TYPES		= 0x1f, | ||||
| 	NM_IPAC_EIE_CHAN_MODES		= 0x20, | ||||
| 	NM_IPAC_EIE_GPRS_CODING		= 0x21, | ||||
| 	NM_IPAC_EIE_RTP_FEATURES	= 0x22, | ||||
| 	NM_IPAC_EIE_RSL_FEATURES	= 0x23, | ||||
| 	NM_IPAC_EIE_BTS_HW_CLASS	= 0x24, | ||||
| 	NM_IPAC_EIE_BTS_ID		= 0x25, | ||||
| }; | ||||
|  | ||||
| enum ipac_bcch_info_type { | ||||
| 	IPAC_BINF_RXLEV			= (1 << 8), | ||||
| 	IPAC_BINF_RXQUAL		= (1 << 9), | ||||
| 	IPAC_BINF_FREQ_ERR_QUAL		= (1 << 10), | ||||
| 	IPAC_BINF_FRAME_OFFSET		= (1 << 11), | ||||
| 	IPAC_BINF_FRAME_NR_OFFSET	= (1 << 12), | ||||
| 	IPAC_BINF_BSIC			= (1 << 13), | ||||
| 	IPAC_BINF_CGI			= (1 << 14), | ||||
| 	IPAC_BINF_NEIGH_BA_SI2		= (1 << 15), | ||||
| 	IPAC_BINF_NEIGH_BA_SI2bis	= (1 << 0), | ||||
| 	IPAC_BINF_NEIGH_BA_SI2ter	= (1 << 1), | ||||
| 	IPAC_BINF_CELL_ALLOC		= (1 << 2), | ||||
| }; | ||||
|  | ||||
| #endif /* PROTO_GSM_12_21_H */ | ||||
							
								
								
									
										32
									
								
								libosmocore/include/osmocore/rsl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								libosmocore/include/osmocore/rsl.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #ifndef _OSMOCORE_RSL_H | ||||
| #define _OSMOCORE_RSL_H | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <osmocore/utils.h> | ||||
| #include <osmocore/protocol/gsm_08_58.h> | ||||
|  | ||||
| void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type); | ||||
|  | ||||
| extern const struct tlv_definition rsl_att_tlvdef; | ||||
| #define rsl_tlv_parse(dec, buf, len)     \ | ||||
| 			tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0) | ||||
|  | ||||
| /* encode channel number as per Section 9.3.1 */ | ||||
| uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot); | ||||
| /* decode channel number as per Section 9.3.1 */ | ||||
| int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot); | ||||
|  | ||||
| const char *rsl_err_name(uint8_t err); | ||||
| const char *rsl_rlm_cause_name(uint8_t err); | ||||
|  | ||||
| /* Section 3.3.2.3 TS 05.02. I think this looks like a table */ | ||||
| int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf); | ||||
|  | ||||
| /* Push a RSL RLL header with L3_INFO IE */ | ||||
| void rsl_rll_push_l3(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr, | ||||
| 		     uint8_t link_id, int transparent); | ||||
|  | ||||
| /* Allocate msgb and fill with simple RSL RLL header */ | ||||
| struct msgb *rsl_rll_simple(uint8_t msg_type, uint8_t chan_nr, | ||||
| 			    uint8_t link_id, int transparent); | ||||
| #endif /* _OSMOCORE_RSL_H */ | ||||
							
								
								
									
										22
									
								
								libosmocore/include/osmocore/rxlev_stat.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								libosmocore/include/osmocore/rxlev_stat.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| #ifndef _OSMOCORE_RXLEV_STATS_H | ||||
| #define _OSMOCORE_RXLEV_STATS_H | ||||
|  | ||||
| #define NUM_RXLEVS 32 | ||||
| #define NUM_ARFCNS 1024 | ||||
|  | ||||
| struct rxlev_stats { | ||||
| 	/* the maximum number of ARFCN's is 1024, and there are 32 RxLevels, | ||||
| 	 * so in we keep one 1024bit-bitvec for each RxLev */ | ||||
| 	uint8_t rxlev_buckets[NUM_RXLEVS][NUM_ARFCNS/8]; | ||||
| }; | ||||
|  | ||||
| void rxlev_stat_input(struct rxlev_stats *st, uint16_t arfcn, uint8_t rxlev); | ||||
|  | ||||
| /* get the next ARFCN that has the specified Rxlev */ | ||||
| int16_t rxlev_stat_get_next(const struct rxlev_stats *st, uint8_t rxlev, int16_t arfcn); | ||||
|  | ||||
| void rxlev_stat_reset(struct rxlev_stats *st); | ||||
|  | ||||
| void rxlev_stat_dump(const struct rxlev_stats *st); | ||||
|  | ||||
| #endif /* _OSMOCORE_RXLEV_STATS_H */ | ||||
							
								
								
									
										22
									
								
								libosmocore/include/osmocore/select.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								libosmocore/include/osmocore/select.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| #ifndef _BSC_SELECT_H | ||||
| #define _BSC_SELECT_H | ||||
|  | ||||
| #include "linuxlist.h" | ||||
|  | ||||
| #define BSC_FD_READ	0x0001 | ||||
| #define BSC_FD_WRITE	0x0002 | ||||
| #define BSC_FD_EXCEPT	0x0004 | ||||
|  | ||||
| struct bsc_fd { | ||||
| 	struct llist_head list; | ||||
| 	int fd; | ||||
| 	unsigned int when; | ||||
| 	int (*cb)(struct bsc_fd *fd, unsigned int what); | ||||
| 	void *data; | ||||
| 	unsigned int priv_nr; | ||||
| }; | ||||
|  | ||||
| int bsc_register_fd(struct bsc_fd *fd); | ||||
| void bsc_unregister_fd(struct bsc_fd *fd); | ||||
| int bsc_select_main(int polling); | ||||
| #endif /* _BSC_SELECT_H */ | ||||
							
								
								
									
										15
									
								
								libosmocore/include/osmocore/signal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								libosmocore/include/osmocore/signal.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| #ifndef OSMOCORE_SIGNAL_H | ||||
| #define OSMOCORE_SIGNAL_H | ||||
|  | ||||
| typedef int signal_cbfn(unsigned int subsys, unsigned int signal, | ||||
| 			void *handler_data, void *signal_data); | ||||
|  | ||||
|  | ||||
| /* Management */ | ||||
| int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data); | ||||
| void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data); | ||||
|  | ||||
| /* Dispatch */ | ||||
| void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data); | ||||
|  | ||||
| #endif /* OSMOCORE_SIGNAL_H */ | ||||
							
								
								
									
										31
									
								
								libosmocore/include/osmocore/statistics.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								libosmocore/include/osmocore/statistics.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| #ifndef _STATISTICS_H | ||||
| #define _STATISTICS_H | ||||
|  | ||||
| struct counter { | ||||
| 	struct llist_head list; | ||||
| 	const char *name; | ||||
| 	const char *description; | ||||
| 	unsigned long value; | ||||
| }; | ||||
|  | ||||
| static inline void counter_inc(struct counter *ctr) | ||||
| { | ||||
| 	ctr->value++; | ||||
| } | ||||
|  | ||||
| static inline unsigned long counter_get(struct counter *ctr) | ||||
| { | ||||
| 	return ctr->value; | ||||
| } | ||||
|  | ||||
| static inline void counter_reset(struct counter *ctr) | ||||
| { | ||||
| 	ctr->value = 0; | ||||
| } | ||||
|  | ||||
| struct counter *counter_alloc(const char *name); | ||||
| void counter_free(struct counter *ctr); | ||||
|  | ||||
| int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data); | ||||
|  | ||||
| #endif /* _STATISTICS_H */ | ||||
							
								
								
									
										192
									
								
								libosmocore/include/osmocore/talloc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								libosmocore/include/osmocore/talloc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,192 @@ | ||||
| #ifndef _TALLOC_H_ | ||||
| #define _TALLOC_H_ | ||||
| /*  | ||||
|    Unix SMB/CIFS implementation. | ||||
|    Samba temporary memory allocation functions | ||||
|  | ||||
|    Copyright (C) Andrew Tridgell 2004-2005 | ||||
|    Copyright (C) Stefan Metzmacher 2006 | ||||
|     | ||||
|      ** NOTE! The following LGPL license applies to the talloc | ||||
|      ** library. This does NOT imply that all of Samba is released | ||||
|      ** under the LGPL | ||||
|     | ||||
|    This library is free software; you can redistribute it and/or | ||||
|    modify it under the terms of the GNU Lesser General Public | ||||
|    License as published by the Free Software Foundation; either | ||||
|    version 3 of the License, or (at your option) any later version. | ||||
|  | ||||
|    This library is distributed in the hope that it will be useful, | ||||
|    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|    Lesser General Public License for more details. | ||||
|  | ||||
|    You should have received a copy of the GNU Lesser General Public | ||||
|    License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <stdarg.h> | ||||
|  | ||||
| #define HAVE_VA_COPY | ||||
|  | ||||
| /* this is only needed for compatibility with the old talloc */ | ||||
| typedef void TALLOC_CTX; | ||||
|  | ||||
| /* | ||||
|   this uses a little trick to allow __LINE__ to be stringified | ||||
| */ | ||||
| #ifndef __location__ | ||||
| #define __TALLOC_STRING_LINE1__(s)    #s | ||||
| #define __TALLOC_STRING_LINE2__(s)   __TALLOC_STRING_LINE1__(s) | ||||
| #define __TALLOC_STRING_LINE3__  __TALLOC_STRING_LINE2__(__LINE__) | ||||
| #define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__ | ||||
| #endif | ||||
|  | ||||
| #ifndef TALLOC_DEPRECATED | ||||
| #define TALLOC_DEPRECATED 0 | ||||
| #endif | ||||
|  | ||||
| #ifndef PRINTF_ATTRIBUTE | ||||
| #if (__GNUC__ >= 3) | ||||
| /** Use gcc attribute to check printf fns.  a1 is the 1-based index of | ||||
|  * the parameter containing the format, and a2 the index of the first | ||||
|  * argument. Note that some gcc 2.x versions don't handle this | ||||
|  * properly **/ | ||||
| #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) | ||||
| #else | ||||
| #define PRINTF_ATTRIBUTE(a1, a2) | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| /* try to make talloc_set_destructor() and talloc_steal() type safe, | ||||
|    if we have a recent gcc */ | ||||
| #if (__GNUC__ >= 3) | ||||
| #define _TALLOC_TYPEOF(ptr) __typeof__(ptr) | ||||
| #define talloc_set_destructor(ptr, function)				      \ | ||||
| 	do {								      \ | ||||
| 		int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function);	      \ | ||||
| 		_talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \ | ||||
| 	} while(0) | ||||
| /* this extremely strange macro is to avoid some braindamaged warning | ||||
|    stupidity in gcc 4.1.x */ | ||||
| #define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)); __talloc_steal_ret; }) | ||||
| #else | ||||
| #define talloc_set_destructor(ptr, function) \ | ||||
| 	_talloc_set_destructor((ptr), (int (*)(void *))(function)) | ||||
| #define _TALLOC_TYPEOF(ptr) void * | ||||
| #define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)) | ||||
| #endif | ||||
|  | ||||
| #define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr)) | ||||
| #define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr)) | ||||
|  | ||||
| /* useful macros for creating type checked pointers */ | ||||
| #define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) | ||||
| #define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) | ||||
| #define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) | ||||
|  | ||||
| #define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) | ||||
|  | ||||
| #define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) | ||||
| #define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) | ||||
|  | ||||
| #define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) | ||||
| #define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) | ||||
| #define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) | ||||
| #define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) | ||||
| #define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx)) | ||||
|  | ||||
| #define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) | ||||
| #define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) | ||||
|  | ||||
| #define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) | ||||
|  | ||||
| #define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) | ||||
| #define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) | ||||
| #define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__) | ||||
|  | ||||
| #define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) | ||||
|  | ||||
| #if TALLOC_DEPRECATED | ||||
| #define talloc_zero_p(ctx, type) talloc_zero(ctx, type) | ||||
| #define talloc_p(ctx, type) talloc(ctx, type) | ||||
| #define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) | ||||
| #define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) | ||||
| #define talloc_destroy(ctx) talloc_free(ctx) | ||||
| #define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) | ||||
| #endif | ||||
|  | ||||
| #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) | ||||
|  | ||||
| /* The following definitions come from talloc.c  */ | ||||
| void *_talloc(const void *context, size_t size); | ||||
| void *talloc_pool(const void *context, size_t size); | ||||
| void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *)); | ||||
| int talloc_increase_ref_count(const void *ptr); | ||||
| size_t talloc_reference_count(const void *ptr); | ||||
| void *_talloc_reference(const void *context, const void *ptr); | ||||
| int talloc_unlink(const void *context, void *ptr); | ||||
| const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); | ||||
| void talloc_set_name_const(const void *ptr, const char *name); | ||||
| void *talloc_named(const void *context, size_t size,  | ||||
| 		   const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); | ||||
| void *talloc_named_const(const void *context, size_t size, const char *name); | ||||
| const char *talloc_get_name(const void *ptr); | ||||
| void *talloc_check_name(const void *ptr, const char *name); | ||||
| void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); | ||||
| void *talloc_parent(const void *ptr); | ||||
| const char *talloc_parent_name(const void *ptr); | ||||
| void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); | ||||
| int talloc_free(void *ptr); | ||||
| void talloc_free_children(void *ptr); | ||||
| void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); | ||||
| void *_talloc_steal(const void *new_ctx, const void *ptr); | ||||
| void *_talloc_move(const void *new_ctx, const void *pptr); | ||||
| size_t talloc_total_size(const void *ptr); | ||||
| size_t talloc_total_blocks(const void *ptr); | ||||
| void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, | ||||
| 			    void (*callback)(const void *ptr, | ||||
| 			  		     int depth, int max_depth, | ||||
| 					     int is_ref, | ||||
| 					     void *private_data), | ||||
| 			    void *private_data); | ||||
| void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); | ||||
| void talloc_report_full(const void *ptr, FILE *f); | ||||
| void talloc_report(const void *ptr, FILE *f); | ||||
| void talloc_enable_null_tracking(void); | ||||
| void talloc_disable_null_tracking(void); | ||||
| void talloc_enable_leak_report(void); | ||||
| void talloc_enable_leak_report_full(void); | ||||
| void *_talloc_zero(const void *ctx, size_t size, const char *name); | ||||
| void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); | ||||
| void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); | ||||
| void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); | ||||
| void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); | ||||
| void *talloc_realloc_fn(const void *context, void *ptr, size_t size); | ||||
| void *talloc_autofree_context(void); | ||||
| size_t talloc_get_size(const void *ctx); | ||||
| void *talloc_find_parent_byname(const void *ctx, const char *name); | ||||
| void talloc_show_parents(const void *context, FILE *file); | ||||
| int talloc_is_parent(const void *context, const void *ptr); | ||||
|  | ||||
| char *talloc_strdup(const void *t, const char *p); | ||||
| char *talloc_strdup_append(char *s, const char *a); | ||||
| char *talloc_strdup_append_buffer(char *s, const char *a); | ||||
|  | ||||
| char *talloc_strndup(const void *t, const char *p, size_t n); | ||||
| char *talloc_strndup_append(char *s, const char *a, size_t n); | ||||
| char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); | ||||
|  | ||||
| char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); | ||||
| char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); | ||||
| char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); | ||||
|  | ||||
| char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); | ||||
| char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); | ||||
| char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); | ||||
|  | ||||
| void talloc_set_abort_fn(void (*abort_fn)(const char *reason)); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										72
									
								
								libosmocore/include/osmocore/timer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								libosmocore/include/osmocore/timer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| /* | ||||
|  * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef TIMER_H | ||||
| #define TIMER_H | ||||
|  | ||||
| #include <sys/time.h> | ||||
|  | ||||
| #include "linuxlist.h" | ||||
|  | ||||
| /** | ||||
|  * Timer management: | ||||
|  *      - Create a struct timer_list | ||||
|  *      - Fill out timeout and use add_timer or | ||||
|  *        use schedule_timer to schedule a timer in | ||||
|  *        x seconds and microseconds from now... | ||||
|  *      - Use del_timer to remove the timer | ||||
|  * | ||||
|  *  Internally: | ||||
|  *      - We hook into select.c to give a timeval of the | ||||
|  *        nearest timer. On already passed timers we give | ||||
|  *        it a 0 to immediately fire after the select | ||||
|  *      - update_timers will call the callbacks and remove | ||||
|  *        the timers. | ||||
|  * | ||||
|  */ | ||||
| struct timer_list { | ||||
| 	struct llist_head entry; | ||||
| 	struct timeval timeout; | ||||
| 	unsigned int active  : 1; | ||||
| 	unsigned int handled : 1; | ||||
| 	unsigned int in_list : 1; | ||||
|  | ||||
| 	void (*cb)(void*); | ||||
| 	void *data; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * timer management | ||||
|  */ | ||||
| void bsc_add_timer(struct timer_list *timer); | ||||
| void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds); | ||||
| void bsc_del_timer(struct timer_list *timer); | ||||
| int bsc_timer_pending(struct timer_list *timer); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * internal timer list management | ||||
|  */ | ||||
| struct timeval *bsc_nearest_timer(); | ||||
| void bsc_prepare_timers(); | ||||
| int bsc_update_timers(); | ||||
| int bsc_timer_check(void); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										244
									
								
								libosmocore/include/osmocore/tlv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								libosmocore/include/osmocore/tlv.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| #ifndef _TLV_H | ||||
| #define _TLV_H | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include <osmocore/msgb.h> | ||||
|  | ||||
| /* Terminology / wording | ||||
| 		tag	length		value	(in bits) | ||||
|  | ||||
| 	    V	-	-		8 | ||||
| 	   LV	-	8		N * 8 | ||||
| 	  TLV	8	8		N * 8 | ||||
| 	TL16V	8	16		N * 8 | ||||
| 	TLV16	8	8		N * 16 | ||||
| 	 TvLV	8	8/16		N * 8 | ||||
|  | ||||
| */ | ||||
|  | ||||
| #define LV_GROSS_LEN(x)		(x+1) | ||||
| #define TLV_GROSS_LEN(x)	(x+2) | ||||
| #define TLV16_GROSS_LEN(x)	((2*x)+2) | ||||
| #define TL16V_GROSS_LEN(x)	(x+3) | ||||
| #define L16TV_GROSS_LEN(x)	(x+3) | ||||
|  | ||||
| #define TVLV_MAX_ONEBYTE	0x7f | ||||
|  | ||||
| static inline uint16_t TVLV_GROSS_LEN(uint16_t len) | ||||
| { | ||||
| 	if (len <= TVLV_MAX_ONEBYTE) | ||||
| 		return TLV_GROSS_LEN(len); | ||||
| 	else | ||||
| 		return TL16V_GROSS_LEN(len); | ||||
| } | ||||
|  | ||||
| /* TLV generation */ | ||||
|  | ||||
| static inline uint8_t *lv_put(uint8_t *buf, uint8_t len, | ||||
| 				const uint8_t *val) | ||||
| { | ||||
| 	*buf++ = len; | ||||
| 	memcpy(buf, val, len); | ||||
| 	return buf + len; | ||||
| } | ||||
|  | ||||
| static inline uint8_t *tlv_put(uint8_t *buf, uint8_t tag, uint8_t len, | ||||
| 				const uint8_t *val) | ||||
| { | ||||
| 	*buf++ = tag; | ||||
| 	*buf++ = len; | ||||
| 	memcpy(buf, val, len); | ||||
| 	return buf + len; | ||||
| } | ||||
|  | ||||
| static inline uint8_t *tlv16_put(uint8_t *buf, uint8_t tag, uint8_t len, | ||||
| 				const uint16_t *val) | ||||
| { | ||||
| 	*buf++ = tag; | ||||
| 	*buf++ = len; | ||||
| 	memcpy(buf, val, len*2); | ||||
| 	return buf + len*2; | ||||
| } | ||||
|  | ||||
| static inline uint8_t *tl16v_put(uint8_t *buf, uint8_t tag, uint16_t len, | ||||
| 				const uint8_t *val) | ||||
| { | ||||
| 	*buf++ = tag; | ||||
| 	*buf++ = len >> 8; | ||||
| 	*buf++ = len & 0xff; | ||||
| 	memcpy(buf, val, len); | ||||
| 	return buf + len*2; | ||||
| } | ||||
|  | ||||
| static inline uint8_t *tvlv_put(uint8_t *buf, uint8_t tag, uint16_t len, | ||||
| 				 const uint8_t *val) | ||||
| { | ||||
| 	uint8_t *ret; | ||||
|  | ||||
| 	if (len <= TVLV_MAX_ONEBYTE) { | ||||
| 		ret = tlv_put(buf, tag, len, val); | ||||
| 		buf[1] |= 0x80; | ||||
| 	} else | ||||
| 		ret = tl16v_put(buf, tag, len, val); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tlv16_put(struct msgb *msg, uint8_t tag, uint8_t len, const uint16_t *val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len)); | ||||
| 	return tlv16_put(buf, tag, len, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tl16v_put(struct msgb *msg, uint8_t tag, uint16_t len, | ||||
| 					const uint8_t *val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len)); | ||||
| 	return tl16v_put(buf, tag, len, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tvlv_put(struct msgb *msg, uint8_t tag, uint16_t len, | ||||
| 				      const uint8_t *val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len)); | ||||
| 	return tvlv_put(buf, tag, len, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_l16tv_put(struct msgb *msg, uint16_t len, uint8_t tag, | ||||
|                                        const uint8_t *val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_put(msg, L16TV_GROSS_LEN(len)); | ||||
|  | ||||
| 	*buf++ = len >> 8; | ||||
| 	*buf++ = len & 0xff; | ||||
| 	*buf++ = tag; | ||||
| 	memcpy(buf, val, len); | ||||
| 	return buf + len; | ||||
| } | ||||
|  | ||||
| static inline uint8_t *v_put(uint8_t *buf, uint8_t val) | ||||
| { | ||||
| 	*buf++ = val; | ||||
| 	return buf; | ||||
| } | ||||
|  | ||||
| static inline uint8_t *tv_put(uint8_t *buf, uint8_t tag,  | ||||
| 				uint8_t val) | ||||
| { | ||||
| 	*buf++ = tag; | ||||
| 	*buf++ = val; | ||||
| 	return buf; | ||||
| } | ||||
|  | ||||
| /* 'val' is still in host byte order! */ | ||||
| static inline uint8_t *tv16_put(uint8_t *buf, uint8_t tag,  | ||||
| 				 uint16_t val) | ||||
| { | ||||
| 	*buf++ = tag; | ||||
| 	*buf++ = val >> 8; | ||||
| 	*buf++ = val & 0xff; | ||||
| 	return buf; | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_lv_put(struct msgb *msg, uint8_t len, const uint8_t *val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_put(msg, LV_GROSS_LEN(len)); | ||||
| 	return lv_put(buf, len, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tlv_put(struct msgb *msg, uint8_t tag, uint8_t len, const uint8_t *val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len)); | ||||
| 	return tlv_put(buf, tag, len, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tv_put(struct msgb *msg, uint8_t tag, uint8_t val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_put(msg, 2); | ||||
| 	return tv_put(buf, tag, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_v_put(struct msgb *msg, uint8_t val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_put(msg, 1); | ||||
| 	return v_put(buf, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tv16_put(struct msgb *msg, uint8_t tag, uint16_t val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_put(msg, 3); | ||||
| 	return tv16_put(buf, tag, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tlv_push(struct msgb *msg, uint8_t tag, uint8_t len, const uint8_t *val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len)); | ||||
| 	return tlv_put(buf, tag, len, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tv_push(struct msgb *msg, uint8_t tag, uint8_t val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_push(msg, 2); | ||||
| 	return tv_put(buf, tag, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tv16_push(struct msgb *msg, uint8_t tag, uint16_t val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_push(msg, 3); | ||||
| 	return tv16_put(buf, tag, val); | ||||
| } | ||||
|  | ||||
| static inline uint8_t *msgb_tvlv_push(struct msgb *msg, uint8_t tag, uint16_t len, | ||||
| 				      const uint8_t *val) | ||||
| { | ||||
| 	uint8_t *buf = msgb_push(msg, TVLV_GROSS_LEN(len)); | ||||
| 	return tvlv_put(buf, tag, len, val); | ||||
| } | ||||
|  | ||||
| /* TLV parsing */ | ||||
|  | ||||
| struct tlv_p_entry { | ||||
| 	uint16_t len; | ||||
| 	const uint8_t *val; | ||||
| }; | ||||
|  | ||||
| enum tlv_type { | ||||
| 	TLV_TYPE_NONE, | ||||
| 	TLV_TYPE_FIXED, | ||||
| 	TLV_TYPE_T, | ||||
| 	TLV_TYPE_TV, | ||||
| 	TLV_TYPE_TLV, | ||||
| 	TLV_TYPE_TL16V, | ||||
| 	TLV_TYPE_TvLV, | ||||
| }; | ||||
|  | ||||
| struct tlv_def { | ||||
| 	enum tlv_type type; | ||||
| 	uint8_t fixed_len; | ||||
| }; | ||||
|  | ||||
| struct tlv_definition { | ||||
| 	struct tlv_def def[0xff]; | ||||
| }; | ||||
|  | ||||
| struct tlv_parsed { | ||||
| 	struct tlv_p_entry lv[0xff]; | ||||
| }; | ||||
|  | ||||
| extern struct tlv_definition tvlv_att_def; | ||||
|  | ||||
| int tlv_parse_one(uint8_t *o_tag, uint16_t *o_len, const uint8_t **o_val, | ||||
|                   const struct tlv_definition *def, | ||||
|                   const uint8_t *buf, int buf_len); | ||||
| int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def, | ||||
| 	      const uint8_t *buf, int buf_len, uint8_t lv_tag, uint8_t lv_tag2); | ||||
| /* take a master (src) tlvdev and fill up all empty slots in 'dst' */ | ||||
| void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src); | ||||
|  | ||||
| #define TLVP_PRESENT(x, y)	((x)->lv[y].val) | ||||
| #define TLVP_LEN(x, y)		(x)->lv[y].len | ||||
| #define TLVP_VAL(x, y)		(x)->lv[y].val | ||||
|  | ||||
| #endif /* _TLV_H */ | ||||
							
								
								
									
										20
									
								
								libosmocore/include/osmocore/utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								libosmocore/include/osmocore/utils.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| #ifndef OSMOCORE_UTIL_H | ||||
| #define OSMOCORE_UTIL_H | ||||
|  | ||||
| #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| struct value_string { | ||||
| 	unsigned int value; | ||||
| 	const char *str; | ||||
| }; | ||||
|  | ||||
| const char *get_value_string(const struct value_string *vs, uint32_t val); | ||||
| int get_string_value(const struct value_string *vs, const char *str); | ||||
|  | ||||
| char bcd2char(uint8_t bcd); | ||||
| /* only works for numbers in ascci */ | ||||
| uint8_t char2bcd(char c); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										45
									
								
								libosmocore/include/osmocore/write_queue.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								libosmocore/include/osmocore/write_queue.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /* Generic write queue implementation */ | ||||
| /* | ||||
|  * (C) 2010 by Holger Hans Peter Freyther | ||||
|  * (C) 2010 by On-Waves | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
| #ifndef write_queue_h | ||||
| #define write_queue_h | ||||
|  | ||||
| #include "select.h" | ||||
| #include "msgb.h" | ||||
|  | ||||
| struct write_queue { | ||||
| 	struct bsc_fd bfd; | ||||
| 	unsigned int max_length; | ||||
| 	unsigned int current_length; | ||||
|  | ||||
| 	struct llist_head msg_queue; | ||||
|  | ||||
| 	int (*read_cb)(struct bsc_fd *fd); | ||||
| 	int (*write_cb)(struct bsc_fd *fd, struct msgb *msg); | ||||
| }; | ||||
|  | ||||
| void write_queue_init(struct write_queue *queue, int max_length); | ||||
| void write_queue_clear(struct write_queue *queue); | ||||
| int write_queue_enqueue(struct write_queue *queue, struct msgb *data); | ||||
| int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										11
									
								
								libosmocore/libosmocore.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								libosmocore/libosmocore.pc.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| prefix=@prefix@ | ||||
| exec_prefix=@exec_prefix@ | ||||
| libdir=@libdir@ | ||||
| includedir=@includedir@ | ||||
|  | ||||
| Name: Osmocom Core Library | ||||
| Description: C Utility Library | ||||
| Version: @VERSION@ | ||||
| Libs: -L${libdir} -losmocore | ||||
| Cflags: -I${includedir}/ | ||||
|  | ||||
							
								
								
									
										1
									
								
								libosmocore/m4/DUMMY
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								libosmocore/m4/DUMMY
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| Dummply placeholder. | ||||
							
								
								
									
										17
									
								
								libosmocore/src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								libosmocore/src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| # This is _NOT_ the library release version, it's an API version. | ||||
| # Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification | ||||
| LIBVERSION=0:0:0 | ||||
|  | ||||
| INCLUDES = $(all_includes) -I$(top_srcdir)/include | ||||
| AM_CFLAGS = -fPIC -Wall | ||||
|  | ||||
| lib_LTLIBRARIES = libosmocore.la | ||||
|  | ||||
| libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c rxlev_stat.c \ | ||||
| 			 tlv_parser.c bitvec.c comp128.c gsm_utils.c statistics.c \ | ||||
| 			 write_queue.c utils.c rsl.c gsm48.c gsm48_ie.c \ | ||||
| 			 logging.c | ||||
|  | ||||
| if ENABLE_TALLOC | ||||
| libosmocore_la_SOURCES += talloc.c | ||||
| endif | ||||
							
								
								
									
										170
									
								
								libosmocore/src/bitvec.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								libosmocore/src/bitvec.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,170 @@ | ||||
| /* bit vector utility routines */ | ||||
|  | ||||
| /* (C) 2009 by Harald Welte <laforge@gnumonks.org> | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include <osmocore/bitvec.h> | ||||
|  | ||||
| #define BITNUM_FROM_COMP(byte, bit)	((byte*8)+bit) | ||||
|  | ||||
| static inline unsigned int bytenum_from_bitnum(unsigned int bitnum) | ||||
| { | ||||
| 	unsigned int bytenum = bitnum / 8; | ||||
|  | ||||
| 	return bytenum; | ||||
| } | ||||
|  | ||||
| /* convert ZERO/ONE/L/H to a bitmask at given pos in a byte */ | ||||
| static uint8_t bitval2mask(enum bit_value bit, uint8_t bitnum) | ||||
| { | ||||
| 	int bitval; | ||||
|  | ||||
| 	switch (bit) { | ||||
| 	case ZERO: | ||||
| 		bitval = (0 << bitnum); | ||||
| 		break; | ||||
| 	case ONE: | ||||
| 		bitval = (1 << bitnum); | ||||
| 		break; | ||||
| 	case L: | ||||
| 		bitval = ((0x2b ^ (0 << bitnum)) & (1 << bitnum)); | ||||
| 		break; | ||||
| 	case H: | ||||
| 		bitval = ((0x2b ^ (1 << bitnum)) & (1 << bitnum)); | ||||
| 		break; | ||||
| 	default: | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return bitval; | ||||
| } | ||||
|  | ||||
| /* check if the bit is 0 or 1 for a given position inside a bitvec */ | ||||
| enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr) | ||||
| { | ||||
| 	unsigned int bytenum = bytenum_from_bitnum(bitnr); | ||||
| 	unsigned int bitnum = 7 - (bitnr % 8); | ||||
| 	uint8_t bitval; | ||||
|  | ||||
| 	if (bytenum >= bv->data_len) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	bitval = bitval2mask(ONE, bitnum); | ||||
|  | ||||
| 	if (bv->data[bytenum] & bitval) | ||||
| 		return ONE; | ||||
|  | ||||
| 	return ZERO; | ||||
| } | ||||
|  | ||||
| /* get the Nth set bit inside the bit vector */ | ||||
| unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n) | ||||
| { | ||||
| 	unsigned int i, k = 0; | ||||
|  | ||||
| 	for (i = 0; i < bv->data_len*8; i++) { | ||||
| 		if (bitvec_get_bit_pos(bv, i) == ONE) { | ||||
| 			k++; | ||||
| 			if (k == n) | ||||
| 				return i; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* set the bit at a given position inside a bitvec */ | ||||
| int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr, | ||||
| 			enum bit_value bit) | ||||
| { | ||||
| 	unsigned int bytenum = bytenum_from_bitnum(bitnr); | ||||
| 	unsigned int bitnum = 7 - (bitnr % 8); | ||||
| 	uint8_t bitval; | ||||
|  | ||||
| 	if (bytenum >= bv->data_len) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	/* first clear the bit */ | ||||
| 	bitval = bitval2mask(ONE, bitnum); | ||||
| 	bv->data[bytenum] &= ~bitval; | ||||
|  | ||||
| 	/* then set it to desired value */ | ||||
| 	bitval = bitval2mask(bit, bitnum); | ||||
| 	bv->data[bytenum] |= bitval; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* set the next bit inside a bitvec */ | ||||
| int bitvec_set_bit(struct bitvec *bv, enum bit_value bit) | ||||
| { | ||||
| 	int rc; | ||||
|  | ||||
| 	rc = bitvec_set_bit_pos(bv, bv->cur_bit, bit); | ||||
| 	if (!rc) | ||||
| 		bv->cur_bit++; | ||||
|  | ||||
| 	return rc; | ||||
| } | ||||
|  | ||||
| /* set multiple bits (based on array of bitvals) at current pos */ | ||||
| int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count) | ||||
| { | ||||
| 	int i, rc; | ||||
|  | ||||
| 	for (i = 0; i < count; i++) { | ||||
| 		rc = bitvec_set_bit(bv, bits[i]); | ||||
| 		if (rc) | ||||
| 			return rc; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* set multiple bits (based on numeric value) at current pos */ | ||||
| int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits) | ||||
| { | ||||
| 	int i, rc; | ||||
|  | ||||
| 	for (i = 0; i < num_bits; i++) { | ||||
| 		int bit = 0; | ||||
| 		if (ui & (1 << (num_bits - i - 1))) | ||||
| 			bit = 1; | ||||
| 		rc = bitvec_set_bit(bv, bit); | ||||
| 		if (rc) | ||||
| 			return rc; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* pad all remaining bits up to num_bits */ | ||||
| int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit) | ||||
| { | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	for (i = bv->cur_bit; i <= up_to_bit; i++) | ||||
| 		bitvec_set_bit(bv, L); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										230
									
								
								libosmocore/src/comp128.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								libosmocore/src/comp128.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,230 @@ | ||||
| /* | ||||
|  * COMP128 implementation | ||||
|  * | ||||
|  * | ||||
|  * This code is inspired by original code from : | ||||
|  *  Marc Briceno <marc@scard.org>, Ian Goldberg <iang@cs.berkeley.edu>, | ||||
|  *  and David Wagner <daw@cs.berkeley.edu> | ||||
|  * | ||||
|  * But it has been fully rewritten from various PDFs found online describing | ||||
|  * the algorithm because the licence of the code referenced above was unclear. | ||||
|  * A comment snippet from the original code is included below, it describes | ||||
|  * where the doc came from and how the algorithm was reverse engineered. | ||||
|  * | ||||
|  * | ||||
|  * (C) 2009 by Sylvain Munaut <tnt@246tNt.com> | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * --- SNIP --- | ||||
|  * | ||||
|  * This code derived from a leaked document from the GSM standards. | ||||
|  * Some missing pieces were filled in by reverse-engineering a working SIM. | ||||
|  * We have verified that this is the correct COMP128 algorithm. | ||||
|  * | ||||
|  * The first page of the document identifies it as | ||||
|  * 	_Technical Information: GSM System Security Study_. | ||||
|  * 	10-1617-01, 10th June 1988. | ||||
|  * The bottom of the title page is marked | ||||
|  * 	Racal Research Ltd. | ||||
|  * 	Worton Drive, Worton Grange Industrial Estate, | ||||
|  * 	Reading, Berks. RG2 0SB, England. | ||||
|  * 	Telephone: Reading (0734) 868601   Telex: 847152 | ||||
|  * The relevant bits are in Part I, Section 20 (pages 66--67).  Enjoy! | ||||
|  * | ||||
|  * Note: There are three typos in the spec (discovered by | ||||
|  * reverse-engineering). | ||||
|  * First, "z = (2 * x[n] + x[n]) mod 2^(9-j)" should clearly read | ||||
|  * "z = (2 * x[m] + x[n]) mod 2^(9-j)". | ||||
|  * Second, the "k" loop in the "Form bits from bytes" section is severely | ||||
|  * botched: the k index should run only from 0 to 3, and clearly the range | ||||
|  * on "the (8-k)th bit of byte j" is also off (should be 0..7, not 1..8, | ||||
|  * to be consistent with the subsequent section). | ||||
|  * Third, SRES is taken from the first 8 nibbles of x[], not the last 8 as | ||||
|  * claimed in the document.  (And the document doesn't specify how Kc is | ||||
|  * derived, but that was also easily discovered with reverse engineering.) | ||||
|  * All of these typos have been corrected in the following code. | ||||
|  * | ||||
|  * --- /SNIP --- | ||||
|  */ | ||||
|  | ||||
| #include <string.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| /* The compression tables (just copied ...) */ | ||||
| static const uint8_t table_0[512] = { | ||||
|  102, 177, 186, 162,   2, 156, 112,  75,  55,  25,   8,  12, 251, 193, 246, 188, | ||||
|  109, 213, 151,  53,  42,  79, 191, 115, 233, 242, 164, 223, 209, 148, 108, 161, | ||||
|  252,  37, 244,  47,  64, 211,   6, 237, 185, 160, 139, 113,  76, 138,  59,  70, | ||||
|   67,  26,  13, 157,  63, 179, 221,  30, 214,  36, 166,  69, 152, 124, 207, 116, | ||||
|  247, 194,  41,  84,  71,   1,  49,  14,  95,  35, 169,  21,  96,  78, 215, 225, | ||||
|  182, 243,  28,  92, 201, 118,   4,  74, 248, 128,  17,  11, 146, 132, 245,  48, | ||||
|  149,  90, 120,  39,  87, 230, 106, 232, 175,  19, 126, 190, 202, 141, 137, 176, | ||||
|  250,  27, 101,  40, 219, 227,  58,  20,  51, 178,  98, 216, 140,  22,  32, 121, | ||||
|   61, 103, 203,  72,  29, 110,  85, 212, 180, 204, 150, 183,  15,  66, 172, 196, | ||||
|   56, 197, 158,   0, 100,  45, 153,   7, 144, 222, 163, 167,  60, 135, 210, 231, | ||||
|  174, 165,  38, 249, 224,  34, 220, 229, 217, 208, 241,  68, 206, 189, 125, 255, | ||||
|  239,  54, 168,  89, 123, 122,  73, 145, 117, 234, 143,  99, 129, 200, 192,  82, | ||||
|  104, 170, 136, 235,  93,  81, 205, 173, 236,  94, 105,  52,  46, 228, 198,   5, | ||||
|   57, 254,  97, 155, 142, 133, 199, 171, 187,  50,  65, 181, 127, 107, 147, 226, | ||||
|  184, 218, 131,  33,  77,  86,  31,  44,  88,  62, 238,  18,  24,  43, 154,  23, | ||||
|   80, 159, 134, 111,   9, 114,   3,  91,  16, 130,  83,  10, 195, 240, 253, 119, | ||||
|  177, 102, 162, 186, 156,   2,  75, 112,  25,  55,  12,   8, 193, 251, 188, 246, | ||||
|  213, 109,  53, 151,  79,  42, 115, 191, 242, 233, 223, 164, 148, 209, 161, 108, | ||||
|   37, 252,  47, 244, 211,  64, 237,   6, 160, 185, 113, 139, 138,  76,  70,  59, | ||||
|   26,  67, 157,  13, 179,  63,  30, 221,  36, 214,  69, 166, 124, 152, 116, 207, | ||||
|  194, 247,  84,  41,   1,  71,  14,  49,  35,  95,  21, 169,  78,  96, 225, 215, | ||||
|  243, 182,  92,  28, 118, 201,  74,   4, 128, 248,  11,  17, 132, 146,  48, 245, | ||||
|   90, 149,  39, 120, 230,  87, 232, 106,  19, 175, 190, 126, 141, 202, 176, 137, | ||||
|   27, 250,  40, 101, 227, 219,  20,  58, 178,  51, 216,  98,  22, 140, 121,  32, | ||||
|  103,  61,  72, 203, 110,  29, 212,  85, 204, 180, 183, 150,  66,  15, 196, 172, | ||||
|  197,  56,   0, 158,  45, 100,   7, 153, 222, 144, 167, 163, 135,  60, 231, 210, | ||||
|  165, 174, 249,  38,  34, 224, 229, 220, 208, 217,  68, 241, 189, 206, 255, 125, | ||||
|   54, 239,  89, 168, 122, 123, 145,  73, 234, 117,  99, 143, 200, 129,  82, 192, | ||||
|  170, 104, 235, 136,  81,  93, 173, 205,  94, 236,  52, 105, 228,  46,   5, 198, | ||||
|  254,  57, 155,  97, 133, 142, 171, 199,  50, 187, 181,  65, 107, 127, 226, 147, | ||||
|  218, 184,  33, 131,  86,  77,  44,  31,  62,  88,  18, 238,  43,  24,  23, 154, | ||||
|  159,  80, 111, 134, 114,   9,  91,   3, 130,  16,  10,  83, 240, 195, 119, 253, | ||||
| }, table_1[256] = { | ||||
|   19,  11,  80, 114,  43,   1,  69,  94,  39,  18, 127, 117,  97,   3,  85,  43, | ||||
|   27, 124,  70,  83,  47,  71,  63,  10,  47,  89,  79,   4,  14,  59,  11,   5, | ||||
|   35, 107, 103,  68,  21,  86,  36,  91,  85, 126,  32,  50, 109,  94, 120,   6, | ||||
|   53,  79,  28,  45,  99,  95,  41,  34,  88,  68,  93,  55, 110, 125, 105,  20, | ||||
|   90,  80,  76,  96,  23,  60,  89,  64, 121,  56,  14,  74, 101,   8,  19,  78, | ||||
|   76,  66, 104,  46, 111,  50,  32,   3,  39,   0,  58,  25,  92,  22,  18,  51, | ||||
|   57,  65, 119, 116,  22, 109,   7,  86,  59,  93,  62, 110,  78,  99,  77,  67, | ||||
|   12, 113,  87,  98, 102,   5,  88,  33,  38,  56,  23,   8,  75,  45,  13,  75, | ||||
|   95,  63,  28,  49, 123, 120,  20, 112,  44,  30,  15,  98, 106,   2, 103,  29, | ||||
|   82, 107,  42, 124,  24,  30,  41,  16, 108, 100, 117,  40,  73,  40,   7, 114, | ||||
|   82, 115,  36, 112,  12, 102, 100,  84,  92,  48,  72,  97,   9,  54,  55,  74, | ||||
|  113, 123,  17,  26,  53,  58,   4,   9,  69, 122,  21, 118,  42,  60,  27,  73, | ||||
|  118, 125,  34,  15,  65, 115,  84,  64,  62,  81,  70,   1,  24, 111, 121,  83, | ||||
|  104,  81,  49, 127,  48, 105,  31,  10,   6,  91,  87,  37,  16,  54, 116, 126, | ||||
|   31,  38,  13,   0,  72, 106,  77,  61,  26,  67,  46,  29,  96,  37,  61,  52, | ||||
|  101,  17,  44, 108,  71,  52,  66,  57,  33,  51,  25,  90,   2, 119, 122,  35, | ||||
| }, table_2[128] = { | ||||
|  52,  50,  44,   6,  21,  49,  41,  59,  39,  51,  25,  32,  51,  47,  52,  43, | ||||
|  37,   4,  40,  34,  61,  12,  28,   4,  58,  23,   8,  15,  12,  22,   9,  18, | ||||
|  55,  10,  33,  35,  50,   1,  43,   3,  57,  13,  62,  14,   7,  42,  44,  59, | ||||
|  62,  57,  27,   6,   8,  31,  26,  54,  41,  22,  45,  20,  39,   3,  16,  56, | ||||
|  48,   2,  21,  28,  36,  42,  60,  33,  34,  18,   0,  11,  24,  10,  17,  61, | ||||
|  29,  14,  45,  26,  55,  46,  11,  17,  54,  46,   9,  24,  30,  60,  32,   0, | ||||
|  20,  38,   2,  30,  58,  35,   1,  16,  56,  40,  23,  48,  13,  19,  19,  27, | ||||
|  31,  53,  47,  38,  63,  15,  49,   5,  37,  53,  25,  36,  63,  29,   5,   7, | ||||
| }, table_3[64] = { | ||||
|   1,   5,  29,   6,  25,   1,  18,  23,  17,  19,   0,   9,  24,  25,   6,  31, | ||||
|  28,  20,  24,  30,   4,  27,   3,  13,  15,  16,  14,  18,   4,   3,   8,   9, | ||||
|  20,   0,  12,  26,  21,   8,  28,   2,  29,   2,  15,   7,  11,  22,  14,  10, | ||||
|  17,  21,  12,  30,  26,  27,  16,  31,  11,   7,  13,  23,  10,   5,  22,  19, | ||||
| }, table_4[32] = { | ||||
|  15,  12,  10,   4,   1,  14,  11,   7,   5,   0,  14,   7,   1,   2,  13,   8, | ||||
|  10,   3,   4,   9,   6,   0,   3,   2,   5,   6,   8,   9,  11,  13,  15,  12, | ||||
| }; | ||||
|  | ||||
| static const uint8_t *_comp128_table[5] = { table_0, table_1, table_2, table_3, table_4 }; | ||||
|  | ||||
|  | ||||
| static inline void | ||||
| _comp128_compression_round(uint8_t *x, int n, const uint8_t *tbl) | ||||
| { | ||||
| 	int i, j, m, a, b, y, z; | ||||
| 	m = 4 - n; | ||||
| 	for (i=0; i<(1<<n); i++) | ||||
| 		for (j=0; j<(1<<m); j++) { | ||||
| 			a = j + i * (2<<m); | ||||
| 			b = a + (1<<m); | ||||
| 			y = (x[a] + (x[b]<<1)) & ((32<<m)-1); | ||||
| 			z = ((x[a]<<1) + x[b]) & ((32<<m)-1); | ||||
| 			x[a] = tbl[y]; | ||||
| 			x[b] = tbl[z]; | ||||
| 		} | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| _comp128_compression(uint8_t *x) | ||||
| { | ||||
| 	int n; | ||||
| 	for (n=0; n<5; n++) | ||||
| 		_comp128_compression_round(x, n, _comp128_table[n]); | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| _comp128_bitsfrombytes(uint8_t *x, uint8_t *bits) | ||||
| { | ||||
| 	int i; | ||||
| 	memset(bits, 0x00, 128); | ||||
| 	for (i=0; i<128; i++) | ||||
| 		if (x[i>>2] & (1<<(3-(i&3)))) | ||||
| 			bits[i] = 1; | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| _comp128_permutation(uint8_t *x, uint8_t *bits) | ||||
| { | ||||
| 	int i; | ||||
| 	memset(&x[16], 0x00, 16); | ||||
| 	for (i=0; i<128; i++) | ||||
| 		x[(i>>3)+16] |= bits[(i*17) & 127] << (7-(i&7)); | ||||
| } | ||||
|  | ||||
| void | ||||
| comp128(uint8_t *ki, uint8_t *rand, uint8_t *sres, uint8_t *kc) | ||||
| { | ||||
| 	int i; | ||||
| 	uint8_t x[32], bits[128]; | ||||
|  | ||||
| 	/* x[16-31] = RAND */ | ||||
| 	memcpy(&x[16], rand, 16); | ||||
|  | ||||
| 	/* Round 1-7 */ | ||||
| 	for (i=0; i<7; i++) { | ||||
| 		/* x[0-15] = Ki */ | ||||
| 		memcpy(x, ki, 16); | ||||
|  | ||||
| 		/* Compression */ | ||||
| 		_comp128_compression(x); | ||||
|  | ||||
| 		/* FormBitFromBytes */ | ||||
| 		_comp128_bitsfrombytes(x, bits); | ||||
|  | ||||
| 		/* Permutation */ | ||||
| 		_comp128_permutation(x, bits); | ||||
| 	} | ||||
|  | ||||
| 	/* Round 8 (final) */ | ||||
| 		/* x[0-15] = Ki */ | ||||
| 	memcpy(x, ki, 16); | ||||
|  | ||||
| 		/* Compression */ | ||||
| 	_comp128_compression(x); | ||||
|  | ||||
| 	/* Output stage */ | ||||
| 	for (i=0; i<8; i+=2) | ||||
| 		sres[i>>1] = x[i]<<4 | x[i+1]; | ||||
|  | ||||
| 	for (i=0; i<12; i+=2) | ||||
| 		kc[i>>1] = (x[i + 18] << 6) | | ||||
| 		           (x[i + 19] << 2) | | ||||
| 		           (x[i + 20] >> 2); | ||||
|  | ||||
| 	kc[6] = (x[30]<<6) | (x[31]<<2); | ||||
| 	kc[7] = 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										263
									
								
								libosmocore/src/gsm48.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								libosmocore/src/gsm48.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,263 @@ | ||||
| /* GSM Mobile Radio Interface Layer 3 messages | ||||
|  * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */ | ||||
|  | ||||
| /* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org> | ||||
|  * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org> | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include <arpa/inet.h> | ||||
|  | ||||
| #include <osmocore/utils.h> | ||||
| #include <osmocore/tlv.h> | ||||
| #include <osmocore/gsm48.h> | ||||
|  | ||||
| #include <osmocore/protocol/gsm_04_08.h> | ||||
|  | ||||
| const struct tlv_definition gsm48_att_tlvdef = { | ||||
| 	.def = { | ||||
| 		[GSM48_IE_MOBILE_ID]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_NAME_LONG]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_NAME_SHORT]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_UTC]		= { TLV_TYPE_TV }, | ||||
| 		[GSM48_IE_NET_TIME_TZ]	= { TLV_TYPE_FIXED, 7 }, | ||||
| 		[GSM48_IE_LSA_IDENT]	= { TLV_TYPE_TLV }, | ||||
|  | ||||
| 		[GSM48_IE_BEARER_CAP]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_CAUSE]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_CC_CAP]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_ALERT]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_FACILITY]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_PROGR_IND]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_AUX_STATUS]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_NOTIFY]	= { TLV_TYPE_TV }, | ||||
| 		[GSM48_IE_KPD_FACILITY]	= { TLV_TYPE_TV }, | ||||
| 		[GSM48_IE_SIGNAL]	= { TLV_TYPE_TV }, | ||||
| 		[GSM48_IE_CONN_BCD]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_CONN_SUB]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_CALLING_BCD]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_CALLING_SUB]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_CALLED_BCD]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_CALLED_SUB]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_REDIR_BCD]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_REDIR_SUB]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_LOWL_COMPAT]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_HIGHL_COMPAT]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_USER_USER]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_SS_VERS]	= { TLV_TYPE_TLV }, | ||||
| 		[GSM48_IE_MORE_DATA]	= { TLV_TYPE_T }, | ||||
| 		[GSM48_IE_CLIR_SUPP]	= { TLV_TYPE_T }, | ||||
| 		[GSM48_IE_CLIR_INVOC]	= { TLV_TYPE_T }, | ||||
| 		[GSM48_IE_REV_C_SETUP]	= { TLV_TYPE_T }, | ||||
| 		[GSM48_IE_REPEAT_CIR]   = { TLV_TYPE_T }, | ||||
| 		[GSM48_IE_REPEAT_SEQ]   = { TLV_TYPE_T }, | ||||
| 		/* FIXME: more elements */ | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| static const struct value_string rr_cause_names[] = { | ||||
| 	{ GSM48_RR_CAUSE_NORMAL,		"Normal event" }, | ||||
| 	{ GSM48_RR_CAUSE_ABNORMAL_UNSPEC,	"Abnormal release, unspecified" }, | ||||
| 	{ GSM48_RR_CAUSE_ABNORMAL_UNACCT,	"Abnormal release, channel unacceptable" }, | ||||
| 	{ GSM48_RR_CAUSE_ABNORMAL_TIMER,	"Abnormal release, timer expired" }, | ||||
| 	{ GSM48_RR_CAUSE_ABNORMAL_NOACT,	"Abnormal release, no activity on radio path" }, | ||||
| 	{ GSM48_RR_CAUSE_PREMPTIVE_REL,		"Preemptive release" }, | ||||
| 	{ GSM48_RR_CAUSE_HNDOVER_IMP,		"Handover impossible, timing advance out of range" }, | ||||
| 	{ GSM48_RR_CAUSE_CHAN_MODE_UNACCT,	"Channel mode unacceptable" }, | ||||
| 	{ GSM48_RR_CAUSE_FREQ_NOT_IMPL,		"Frequency not implemented" }, | ||||
| 	{ GSM48_RR_CAUSE_CALL_CLEARED,		"Call already cleared" }, | ||||
| 	{ GSM48_RR_CAUSE_SEMANT_INCORR,		"Semantically incorrect message" }, | ||||
| 	{ GSM48_RR_CAUSE_INVALID_MAND_INF,	"Invalid mandatory information" }, | ||||
| 	{ GSM48_RR_CAUSE_MSG_TYPE_N,		"Message type non-existant or not implemented" }, | ||||
| 	{ GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT,	"Message type not compatible with protocol state" }, | ||||
| 	{ GSM48_RR_CAUSE_COND_IE_ERROR,		"Conditional IE error" }, | ||||
| 	{ GSM48_RR_CAUSE_NO_CELL_ALLOC_A,	"No cell allocation available" }, | ||||
| 	{ GSM48_RR_CAUSE_PROT_ERROR_UNSPC,	"Protocol error unspecified" }, | ||||
| 	{ 0,					NULL }, | ||||
| }; | ||||
|  | ||||
| /* FIXME: convert to value_string */ | ||||
| static const char *cc_state_names[32] = { | ||||
| 	"NULL", | ||||
| 	"INITIATED", | ||||
| 	"illegal state 2", | ||||
| 	"MO_CALL_PROC", | ||||
| 	"CALL_DELIVERED", | ||||
| 	"illegal state 5", | ||||
| 	"CALL_PRESENT", | ||||
| 	"CALL_RECEIVED", | ||||
| 	"CONNECT_REQUEST", | ||||
| 	"MO_TERM_CALL_CONF", | ||||
| 	"ACTIVE", | ||||
| 	"DISCONNECT_REQ", | ||||
| 	"DISCONNECT_IND", | ||||
| 	"illegal state 13", | ||||
| 	"illegal state 14", | ||||
| 	"illegal state 15", | ||||
| 	"illegal state 16", | ||||
| 	"illegal state 17", | ||||
| 	"illegal state 18", | ||||
| 	"RELEASE_REQ", | ||||
| 	"illegal state 20", | ||||
| 	"illegal state 21", | ||||
| 	"illegal state 22", | ||||
| 	"illegal state 23", | ||||
| 	"illegal state 24", | ||||
| 	"illegal state 25", | ||||
| 	"MO_ORIG_MODIFY", | ||||
| 	"MO_TERM_MODIFY", | ||||
| 	"CONNECT_IND", | ||||
| 	"illegal state 29", | ||||
| 	"illegal state 30", | ||||
| 	"illegal state 31", | ||||
| }; | ||||
|  | ||||
| const char *gsm48_cc_state_name(uint8_t state) | ||||
| { | ||||
| 	if (state < ARRAY_SIZE(cc_state_names)) | ||||
| 		return cc_state_names[state]; | ||||
|  | ||||
| 	return "invalid"; | ||||
| } | ||||
|  | ||||
| static const struct value_string cc_msg_names[] = { | ||||
| 	{ GSM48_MT_CC_ALERTING,		"ALERTING" }, | ||||
| 	{ GSM48_MT_CC_CALL_PROC,	"CALL_PROC" }, | ||||
| 	{ GSM48_MT_CC_PROGRESS,		"PROGRESS" }, | ||||
| 	{ GSM48_MT_CC_ESTAB,		"ESTAB" }, | ||||
| 	{ GSM48_MT_CC_SETUP,		"SETUP" }, | ||||
| 	{ GSM48_MT_CC_ESTAB_CONF,	"ESTAB_CONF" }, | ||||
| 	{ GSM48_MT_CC_CONNECT,		"CONNECT" }, | ||||
| 	{ GSM48_MT_CC_CALL_CONF,	"CALL_CONF" }, | ||||
| 	{ GSM48_MT_CC_START_CC,		"START_CC" }, | ||||
| 	{ GSM48_MT_CC_RECALL,		"RECALL" }, | ||||
| 	{ GSM48_MT_CC_EMERG_SETUP,	"EMERG_SETUP" }, | ||||
| 	{ GSM48_MT_CC_CONNECT_ACK,	"CONNECT_ACK" }, | ||||
| 	{ GSM48_MT_CC_USER_INFO,	"USER_INFO" }, | ||||
| 	{ GSM48_MT_CC_MODIFY_REJECT,	"MODIFY_REJECT" }, | ||||
| 	{ GSM48_MT_CC_MODIFY,		"MODIFY" }, | ||||
| 	{ GSM48_MT_CC_HOLD,		"HOLD" }, | ||||
| 	{ GSM48_MT_CC_HOLD_ACK,		"HOLD_ACK" }, | ||||
| 	{ GSM48_MT_CC_HOLD_REJ,		"HOLD_REJ" }, | ||||
| 	{ GSM48_MT_CC_RETR,		"RETR" }, | ||||
| 	{ GSM48_MT_CC_RETR_ACK,		"RETR_ACK" }, | ||||
| 	{ GSM48_MT_CC_RETR_REJ,		"RETR_REJ" }, | ||||
| 	{ GSM48_MT_CC_MODIFY_COMPL,	"MODIFY_COMPL" }, | ||||
| 	{ GSM48_MT_CC_DISCONNECT,	"DISCONNECT" }, | ||||
| 	{ GSM48_MT_CC_RELEASE_COMPL,	"RELEASE_COMPL" }, | ||||
| 	{ GSM48_MT_CC_RELEASE,		"RELEASE" }, | ||||
| 	{ GSM48_MT_CC_STOP_DTMF,	"STOP_DTMF" }, | ||||
| 	{ GSM48_MT_CC_STOP_DTMF_ACK,	"STOP_DTMF_ACK" }, | ||||
| 	{ GSM48_MT_CC_STATUS_ENQ,	"STATUS_ENQ" }, | ||||
| 	{ GSM48_MT_CC_START_DTMF,	"START_DTMF" }, | ||||
| 	{ GSM48_MT_CC_START_DTMF_ACK,	"START_DTMF_ACK" }, | ||||
| 	{ GSM48_MT_CC_START_DTMF_REJ,	"START_DTMF_REJ" }, | ||||
| 	{ GSM48_MT_CC_CONG_CTRL,	"CONG_CTRL" }, | ||||
| 	{ GSM48_MT_CC_FACILITY,		"FACILITY" }, | ||||
| 	{ GSM48_MT_CC_STATUS,		"STATUS" }, | ||||
| 	{ GSM48_MT_CC_NOTIFY,		"NOTFIY" }, | ||||
| 	{ 0,				NULL } | ||||
| }; | ||||
|  | ||||
| const char *gsm48_cc_msg_name(uint8_t msgtype) | ||||
| { | ||||
| 	return get_value_string(cc_msg_names, msgtype); | ||||
| } | ||||
|  | ||||
| const char *rr_cause_name(uint8_t cause) | ||||
| { | ||||
| 	return get_value_string(rr_cause_names, cause); | ||||
| } | ||||
|  | ||||
| static void to_bcd(uint8_t *bcd, uint16_t val) | ||||
| { | ||||
| 	bcd[2] = val % 10; | ||||
| 	val = val / 10; | ||||
| 	bcd[1] = val % 10; | ||||
| 	val = val / 10; | ||||
| 	bcd[0] = val % 10; | ||||
| 	val = val / 10; | ||||
| } | ||||
|  | ||||
| void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc, | ||||
| 			uint16_t mnc, uint16_t lac) | ||||
| { | ||||
| 	uint8_t bcd[3]; | ||||
|  | ||||
| 	to_bcd(bcd, mcc); | ||||
| 	lai48->digits[0] = bcd[0] | (bcd[1] << 4); | ||||
| 	lai48->digits[1] = bcd[2]; | ||||
|  | ||||
| 	to_bcd(bcd, mnc); | ||||
| 	/* FIXME: do we need three-digit MNC? See Table 10.5.3 */ | ||||
| #if 0 | ||||
| 	lai48->digits[1] |= bcd[2] << 4; | ||||
| 	lai48->digits[2] = bcd[0] | (bcd[1] << 4); | ||||
| #else | ||||
| 	lai48->digits[1] |= 0xf << 4; | ||||
| 	lai48->digits[2] = bcd[1] | (bcd[2] << 4); | ||||
| #endif | ||||
|  | ||||
| 	lai48->lac = htons(lac); | ||||
| } | ||||
|  | ||||
| int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi) | ||||
| { | ||||
| 	uint32_t *tptr = (uint32_t *) &buf[3]; | ||||
|  | ||||
| 	buf[0] = GSM48_IE_MOBILE_ID; | ||||
| 	buf[1] = GSM48_TMSI_LEN; | ||||
| 	buf[2] = 0xf0 | GSM_MI_TYPE_TMSI; | ||||
| 	*tptr = htonl(tmsi); | ||||
|  | ||||
| 	return 7; | ||||
| } | ||||
|  | ||||
| int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi) | ||||
| { | ||||
| 	unsigned int length = strlen(imsi), i, off = 0; | ||||
| 	uint8_t odd = (length & 0x1) == 1; | ||||
|  | ||||
| 	buf[0] = GSM48_IE_MOBILE_ID; | ||||
| 	buf[2] = char2bcd(imsi[0]) << 4 | GSM_MI_TYPE_IMSI | (odd << 3); | ||||
|  | ||||
| 	/* if the length is even we will fill half of the last octet */ | ||||
| 	if (odd) | ||||
| 		buf[1] = (length + 1) >> 1; | ||||
| 	else | ||||
| 		buf[1] = (length + 2) >> 1; | ||||
|  | ||||
| 	for (i = 1; i < buf[1]; ++i) { | ||||
| 		uint8_t lower, upper; | ||||
|  | ||||
| 		lower = char2bcd(imsi[++off]); | ||||
| 		if (!odd && off + 1 == length) | ||||
| 			upper = 0x0f; | ||||
| 		else | ||||
| 			upper = char2bcd(imsi[++off]) & 0x0f; | ||||
|  | ||||
| 		buf[2 + i] = (upper << 4) | lower; | ||||
| 	} | ||||
|  | ||||
| 	return 2 + buf[1]; | ||||
| } | ||||
							
								
								
									
										659
									
								
								libosmocore/src/gsm48_ie.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										659
									
								
								libosmocore/src/gsm48_ie.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,659 @@ | ||||
| /* GSM Mobile Radio Interface Layer 3 messages | ||||
|  * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */ | ||||
|  | ||||
| /* (C) 2008 by Harald Welte <laforge@gnumonks.org> | ||||
|  * (C) 2008-2010 by Andreas Eversberg | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| #include <osmocore/utils.h> | ||||
| #include <osmocore/msgb.h> | ||||
| #include <osmocore/tlv.h> | ||||
| #include <osmocore/mncc.h> | ||||
| #include <osmocore/protocol/gsm_04_08.h> | ||||
|  | ||||
| static const char bcd_num_digits[] = { | ||||
| 	'0', '1', '2', '3', '4', '5', '6', '7', | ||||
| 	'8', '9', '*', '#', 'a', 'b', 'c', '\0' | ||||
| }; | ||||
|  | ||||
| /* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */ | ||||
| int gsm48_decode_bcd_number(char *output, int output_len, | ||||
| 			    const uint8_t *bcd_lv, int h_len) | ||||
| { | ||||
| 	uint8_t in_len = bcd_lv[0]; | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 1 + h_len; i <= in_len; i++) { | ||||
| 		/* lower nibble */ | ||||
| 		output_len--; | ||||
| 		if (output_len <= 1) | ||||
| 			break; | ||||
| 		*output++ = bcd_num_digits[bcd_lv[i] & 0xf]; | ||||
|  | ||||
| 		/* higher nibble */ | ||||
| 		output_len--; | ||||
| 		if (output_len <= 1) | ||||
| 			break; | ||||
| 		*output++ = bcd_num_digits[bcd_lv[i] >> 4]; | ||||
| 	} | ||||
| 	if (output_len >= 1) | ||||
| 		*output++ = '\0'; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* convert a single ASCII character to call-control BCD */ | ||||
| static int asc_to_bcd(const char asc) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_SIZE(bcd_num_digits); i++) { | ||||
| 		if (bcd_num_digits[i] == asc) | ||||
| 			return i; | ||||
| 	} | ||||
| 	return -EINVAL; | ||||
| } | ||||
|  | ||||
| /* convert a ASCII phone number to 'called/calling/connect party BCD number' */ | ||||
| int gsm48_encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len, | ||||
| 		      int h_len, const char *input) | ||||
| { | ||||
| 	int in_len = strlen(input); | ||||
| 	int i; | ||||
| 	uint8_t *bcd_cur = bcd_lv + 1 + h_len; | ||||
|  | ||||
| 	/* two digits per byte, plus type byte */ | ||||
| 	bcd_lv[0] = in_len/2 + h_len; | ||||
| 	if (in_len % 2) | ||||
| 		bcd_lv[0]++; | ||||
|  | ||||
| 	if (bcd_lv[0] > max_len) | ||||
| 		return -EIO; | ||||
|  | ||||
| 	for (i = 0; i < in_len; i++) { | ||||
| 		int rc = asc_to_bcd(input[i]); | ||||
| 		if (rc < 0) | ||||
| 			return rc; | ||||
| 		if (i % 2 == 0) | ||||
| 			*bcd_cur = rc; | ||||
| 		else | ||||
| 			*bcd_cur++ |= (rc << 4); | ||||
| 	} | ||||
| 	/* append padding nibble in case of odd length */ | ||||
| 	if (i % 2) | ||||
| 		*bcd_cur++ |= 0xf0; | ||||
|  | ||||
| 	/* return how many bytes we used */ | ||||
| 	return (bcd_cur - bcd_lv); | ||||
| } | ||||
|  | ||||
| /* decode 'bearer capability' */ | ||||
| int gsm48_decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap, | ||||
| 			     const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
| 	int i, s; | ||||
|  | ||||
| 	if (in_len < 1) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	bcap->speech_ver[0] = -1; /* end of list, of maximum 7 values */ | ||||
|  | ||||
| 	/* octet 3 */ | ||||
| 	bcap->transfer = lv[1] & 0x07; | ||||
| 	bcap->mode = (lv[1] & 0x08) >> 3; | ||||
| 	bcap->coding = (lv[1] & 0x10) >> 4; | ||||
| 	bcap->radio = (lv[1] & 0x60) >> 5; | ||||
|  | ||||
| 	if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) { | ||||
| 		i = 1; | ||||
| 		s = 0; | ||||
| 		while(!(lv[i] & 0x80)) { | ||||
| 			i++; /* octet 3a etc */ | ||||
| 			if (in_len < i) | ||||
| 				return 0; | ||||
| 			bcap->speech_ver[s++] = lv[i] & 0x0f; | ||||
| 			bcap->speech_ver[s] = -1; /* end of list */ | ||||
| 			if (i == 2) /* octet 3a */ | ||||
| 				bcap->speech_ctm = (lv[i] & 0x20) >> 5; | ||||
| 			if (s == 7) /* maximum speech versions + end of list */ | ||||
| 				return 0; | ||||
| 		} | ||||
| 	} else { | ||||
| 		i = 1; | ||||
| 		while (!(lv[i] & 0x80)) { | ||||
| 			i++; /* octet 3a etc */ | ||||
| 			if (in_len < i) | ||||
| 				return 0; | ||||
| 			/* ignore them */ | ||||
| 		} | ||||
| 		/* FIXME: implement OCTET 4+ parsing */ | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'bearer capability' */ | ||||
| int gsm48_encode_bearer_cap(struct msgb *msg, int lv_only, | ||||
| 			     const struct gsm_mncc_bearer_cap *bcap) | ||||
| { | ||||
| 	uint8_t lv[32 + 1]; | ||||
| 	int i = 1, s; | ||||
|  | ||||
| 	lv[1] = bcap->transfer; | ||||
| 	lv[1] |= bcap->mode << 3; | ||||
| 	lv[1] |= bcap->coding << 4; | ||||
| 	lv[1] |= bcap->radio << 5; | ||||
|  | ||||
| 	if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) { | ||||
| 		for (s = 0; bcap->speech_ver[s] >= 0; s++) { | ||||
| 			i++; /* octet 3a etc */ | ||||
| 			lv[i] = bcap->speech_ver[s]; | ||||
| 			if (i == 2) /* octet 3a */ | ||||
| 				lv[i] |= bcap->speech_ctm << 5; | ||||
| 		} | ||||
| 		lv[i] |= 0x80; /* last IE of octet 3 etc */ | ||||
| 	} else { | ||||
| 		/* FIXME: implement OCTET 4+ encoding */ | ||||
| 	} | ||||
|  | ||||
| 	lv[0] = i; | ||||
| 	if (lv_only) | ||||
| 		msgb_lv_put(msg, lv[0], lv+1); | ||||
| 	else | ||||
| 		msgb_tlv_put(msg, GSM48_IE_BEARER_CAP, lv[0], lv+1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'call control cap' */ | ||||
| int gsm48_decode_cccap(struct gsm_mncc_cccap *ccap, const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
|  | ||||
| 	if (in_len < 1) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	/* octet 3 */ | ||||
| 	ccap->dtmf = lv[1] & 0x01; | ||||
| 	ccap->pcp = (lv[1] & 0x02) >> 1; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'call control cap' */ | ||||
| int gsm48_encode_cccap(struct msgb *msg, | ||||
| 			const struct gsm_mncc_cccap *ccap) | ||||
| { | ||||
| 	uint8_t lv[2]; | ||||
|  | ||||
| 	lv[0] = 1; | ||||
| 	lv[1] = 0; | ||||
| 	if (ccap->dtmf) | ||||
| 		lv [1] |= 0x01; | ||||
| 	if (ccap->pcp) | ||||
| 		lv [1] |= 0x02; | ||||
|  | ||||
| 	msgb_tlv_put(msg, GSM48_IE_CC_CAP, lv[0], lv+1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'called party BCD number' */ | ||||
| int gsm48_decode_called(struct gsm_mncc_number *called, | ||||
| 			 const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
|  | ||||
| 	if (in_len < 1) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	/* octet 3 */ | ||||
| 	called->plan = lv[1] & 0x0f; | ||||
| 	called->type = (lv[1] & 0x70) >> 4; | ||||
|  | ||||
| 	/* octet 4..N */ | ||||
| 	gsm48_decode_bcd_number(called->number, sizeof(called->number), lv, 1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'called party BCD number' */ | ||||
| int gsm48_encode_called(struct msgb *msg, | ||||
| 			 const struct gsm_mncc_number *called) | ||||
| { | ||||
| 	uint8_t lv[18]; | ||||
| 	int ret; | ||||
|  | ||||
| 	/* octet 3 */ | ||||
| 	lv[1] = called->plan; | ||||
| 	lv[1] |= called->type << 4; | ||||
|  | ||||
| 	/* octet 4..N, octet 2 */ | ||||
| 	ret = gsm48_encode_bcd_number(lv, sizeof(lv), 1, called->number); | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
|  | ||||
| 	msgb_tlv_put(msg, GSM48_IE_CALLED_BCD, lv[0], lv+1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode callerid of various IEs */ | ||||
| int gsm48_decode_callerid(struct gsm_mncc_number *callerid, | ||||
| 			 const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
| 	int i = 1; | ||||
|  | ||||
| 	if (in_len < 1) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	/* octet 3 */ | ||||
| 	callerid->plan = lv[1] & 0x0f; | ||||
| 	callerid->type = (lv[1] & 0x70) >> 4; | ||||
|  | ||||
| 	/* octet 3a */ | ||||
| 	if (!(lv[1] & 0x80)) { | ||||
| 		callerid->screen = lv[2] & 0x03; | ||||
| 		callerid->present = (lv[2] & 0x60) >> 5; | ||||
| 		i = 2; | ||||
| 	} | ||||
|  | ||||
| 	/* octet 4..N */ | ||||
| 	gsm48_decode_bcd_number(callerid->number, sizeof(callerid->number), lv, i); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode callerid of various IEs */ | ||||
| int gsm48_encode_callerid(struct msgb *msg, int ie, int max_len, | ||||
| 			   const struct gsm_mncc_number *callerid) | ||||
| { | ||||
| 	uint8_t lv[max_len - 1]; | ||||
| 	int h_len = 1; | ||||
| 	int ret; | ||||
|  | ||||
| 	/* octet 3 */ | ||||
| 	lv[1] = callerid->plan; | ||||
| 	lv[1] |= callerid->type << 4; | ||||
|  | ||||
| 	if (callerid->present || callerid->screen) { | ||||
| 		/* octet 3a */ | ||||
| 		lv[2] = callerid->screen; | ||||
| 		lv[2] |= callerid->present << 5; | ||||
| 		lv[2] |= 0x80; | ||||
| 		h_len++; | ||||
| 	} else | ||||
| 		lv[1] |= 0x80; | ||||
|  | ||||
| 	/* octet 4..N, octet 2 */ | ||||
| 	ret = gsm48_encode_bcd_number(lv, sizeof(lv), h_len, callerid->number); | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
|  | ||||
| 	msgb_tlv_put(msg, ie, lv[0], lv+1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'cause' */ | ||||
| int gsm48_decode_cause(struct gsm_mncc_cause *cause, | ||||
| 			const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
| 	int i; | ||||
|  | ||||
| 	if (in_len < 2) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	cause->diag_len = 0; | ||||
|  | ||||
| 	/* octet 3 */ | ||||
| 	cause->location = lv[1] & 0x0f; | ||||
| 	cause->coding = (lv[1] & 0x60) >> 5; | ||||
|  | ||||
| 	i = 1; | ||||
| 	if (!(lv[i] & 0x80)) { | ||||
| 		i++; /* octet 3a */ | ||||
| 		if (in_len < i+1) | ||||
| 			return 0; | ||||
| 		cause->rec = 1; | ||||
| 		cause->rec_val = lv[i] & 0x7f; | ||||
| 	} | ||||
| 	i++; | ||||
|  | ||||
| 	/* octet 4 */ | ||||
| 	cause->value = lv[i] & 0x7f; | ||||
| 	i++; | ||||
|  | ||||
| 	if (in_len < i) /* no diag */ | ||||
| 		return 0; | ||||
|  | ||||
| 	if (in_len - (i-1) > 32) /* maximum 32 octets */ | ||||
| 		return 0; | ||||
|  | ||||
| 	/* octet 5-N */ | ||||
| 	memcpy(cause->diag, lv + i, in_len - (i-1)); | ||||
| 	cause->diag_len = in_len - (i-1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'cause' */ | ||||
| int gsm48_encode_cause(struct msgb *msg, int lv_only, | ||||
| 			const struct gsm_mncc_cause *cause) | ||||
| { | ||||
| 	uint8_t lv[32+4]; | ||||
| 	int i; | ||||
|  | ||||
| 	if (cause->diag_len > 32) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	/* octet 3 */ | ||||
| 	lv[1] = cause->location; | ||||
| 	lv[1] |= cause->coding << 5; | ||||
|  | ||||
| 	i = 1; | ||||
| 	if (cause->rec) { | ||||
| 		i++; /* octet 3a */ | ||||
| 		lv[i] = cause->rec_val; | ||||
| 	} | ||||
| 	lv[i] |= 0x80; /* end of octet 3 */ | ||||
|  | ||||
| 	/* octet 4 */ | ||||
| 	i++; | ||||
| 	lv[i] = 0x80 | cause->value; | ||||
|  | ||||
| 	/* octet 5-N */ | ||||
| 	if (cause->diag_len) { | ||||
| 		memcpy(lv + i, cause->diag, cause->diag_len); | ||||
| 		i += cause->diag_len; | ||||
| 	} | ||||
|  | ||||
| 	lv[0] = i; | ||||
| 	if (lv_only) | ||||
| 		msgb_lv_put(msg, lv[0], lv+1); | ||||
| 	else | ||||
| 		msgb_tlv_put(msg, GSM48_IE_CAUSE, lv[0], lv+1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'calling number' */ | ||||
| int gsm48_decode_calling(struct gsm_mncc_number *calling, | ||||
| 			 const uint8_t *lv) | ||||
| { | ||||
| 	return gsm48_decode_callerid(calling, lv); | ||||
| } | ||||
|  | ||||
| /* encode 'calling number' */ | ||||
| int gsm48_encode_calling(struct msgb *msg,  | ||||
| 			  const struct gsm_mncc_number *calling) | ||||
| { | ||||
| 	return gsm48_encode_callerid(msg, GSM48_IE_CALLING_BCD, 14, calling); | ||||
| } | ||||
|  | ||||
| /* decode 'connected number' */ | ||||
| int gsm48_decode_connected(struct gsm_mncc_number *connected, | ||||
| 			 const uint8_t *lv) | ||||
| { | ||||
| 	return gsm48_decode_callerid(connected, lv); | ||||
| } | ||||
|  | ||||
| /* encode 'connected number' */ | ||||
| int gsm48_encode_connected(struct msgb *msg, | ||||
| 			    const struct gsm_mncc_number *connected) | ||||
| { | ||||
| 	return gsm48_encode_callerid(msg, GSM48_IE_CONN_BCD, 14, connected); | ||||
| } | ||||
|  | ||||
| /* decode 'redirecting number' */ | ||||
| int gsm48_decode_redirecting(struct gsm_mncc_number *redirecting, | ||||
| 			 const uint8_t *lv) | ||||
| { | ||||
| 	return gsm48_decode_callerid(redirecting, lv); | ||||
| } | ||||
|  | ||||
| /* encode 'redirecting number' */ | ||||
| int gsm48_encode_redirecting(struct msgb *msg, | ||||
| 			      const struct gsm_mncc_number *redirecting) | ||||
| { | ||||
| 	return gsm48_encode_callerid(msg, GSM48_IE_REDIR_BCD, 19, redirecting); | ||||
| } | ||||
|  | ||||
| /* decode 'facility' */ | ||||
| int gsm48_decode_facility(struct gsm_mncc_facility *facility, | ||||
| 			   const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
|  | ||||
| 	if (in_len < 1) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	if (in_len > sizeof(facility->info)) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	memcpy(facility->info, lv+1, in_len); | ||||
| 	facility->len = in_len; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'facility' */ | ||||
| int gsm48_encode_facility(struct msgb *msg, int lv_only, | ||||
| 			   const struct gsm_mncc_facility *facility) | ||||
| { | ||||
| 	uint8_t lv[GSM_MAX_FACILITY + 1]; | ||||
|  | ||||
| 	if (facility->len < 1 || facility->len > GSM_MAX_FACILITY) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	memcpy(lv+1, facility->info, facility->len); | ||||
| 	lv[0] = facility->len; | ||||
| 	if (lv_only) | ||||
| 		msgb_lv_put(msg, lv[0], lv+1); | ||||
| 	else | ||||
| 		msgb_tlv_put(msg, GSM48_IE_FACILITY, lv[0], lv+1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'notify' */ | ||||
| int gsm48_decode_notify(int *notify, const uint8_t *v) | ||||
| { | ||||
| 	*notify = v[0] & 0x7f; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'notify' */ | ||||
| int gsm48_encode_notify(struct msgb *msg, int notify) | ||||
| { | ||||
| 	msgb_v_put(msg, notify | 0x80); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'signal' */ | ||||
| int gsm48_decode_signal(int *signal, const uint8_t *v) | ||||
| { | ||||
| 	*signal = v[0]; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'signal' */ | ||||
| int gsm48_encode_signal(struct msgb *msg, int signal) | ||||
| { | ||||
| 	msgb_tv_put(msg, GSM48_IE_SIGNAL, signal); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'keypad' */ | ||||
| int gsm48_decode_keypad(int *keypad, const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
|  | ||||
| 	if (in_len < 1) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	*keypad = lv[1] & 0x7f; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'keypad' */ | ||||
| int gsm48_encode_keypad(struct msgb *msg, int keypad) | ||||
| { | ||||
| 	msgb_tv_put(msg, GSM48_IE_KPD_FACILITY, keypad); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'progress' */ | ||||
| int gsm48_decode_progress(struct gsm_mncc_progress *progress, | ||||
| 			   const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
|  | ||||
| 	if (in_len < 2) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	progress->coding = (lv[1] & 0x60) >> 5; | ||||
| 	progress->location = lv[1] & 0x0f; | ||||
| 	progress->descr = lv[2] & 0x7f; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'progress' */ | ||||
| int gsm48_encode_progress(struct msgb *msg, int lv_only, | ||||
| 			   const struct gsm_mncc_progress *p) | ||||
| { | ||||
| 	uint8_t lv[3]; | ||||
|  | ||||
| 	lv[0] = 2; | ||||
| 	lv[1] = 0x80 | ((p->coding & 0x3) << 5) | (p->location & 0xf); | ||||
| 	lv[2] = 0x80 | (p->descr & 0x7f); | ||||
| 	if (lv_only) | ||||
| 		msgb_lv_put(msg, lv[0], lv+1); | ||||
| 	else | ||||
| 		msgb_tlv_put(msg, GSM48_IE_PROGR_IND, lv[0], lv+1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'user-user' */ | ||||
| int gsm48_decode_useruser(struct gsm_mncc_useruser *uu, | ||||
| 			   const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
| 	char *info = uu->info; | ||||
| 	int info_len = sizeof(uu->info); | ||||
| 	int i; | ||||
|  | ||||
| 	if (in_len < 1) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	uu->proto = lv[1]; | ||||
|  | ||||
| 	for (i = 2; i <= in_len; i++) { | ||||
| 		info_len--; | ||||
| 		if (info_len <= 1) | ||||
| 			break; | ||||
| 		*info++ = lv[i]; | ||||
| 	} | ||||
| 	if (info_len >= 1) | ||||
| 		*info++ = '\0'; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'useruser' */ | ||||
| int gsm48_encode_useruser(struct msgb *msg, int lv_only, | ||||
| 			   const struct gsm_mncc_useruser *uu) | ||||
| { | ||||
| 	uint8_t lv[GSM_MAX_USERUSER + 2]; | ||||
|  | ||||
| 	if (strlen(uu->info) > GSM_MAX_USERUSER) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	lv[0] = 1 + strlen(uu->info); | ||||
| 	lv[1] = uu->proto; | ||||
| 	memcpy(lv + 2, uu->info, strlen(uu->info)); | ||||
| 	if (lv_only) | ||||
| 		msgb_lv_put(msg, lv[0], lv+1); | ||||
| 	else | ||||
| 		msgb_tlv_put(msg, GSM48_IE_USER_USER, lv[0], lv+1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'ss version' */ | ||||
| int gsm48_decode_ssversion(struct gsm_mncc_ssversion *ssv, | ||||
| 			    const uint8_t *lv) | ||||
| { | ||||
| 	uint8_t in_len = lv[0]; | ||||
|  | ||||
| 	if (in_len < 1 || in_len < sizeof(ssv->info)) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	memcpy(ssv->info, lv + 1, in_len); | ||||
| 	ssv->len = in_len; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* encode 'ss version' */ | ||||
| int gsm48_encode_ssversion(struct msgb *msg, | ||||
| 			   const struct gsm_mncc_ssversion *ssv) | ||||
| { | ||||
| 	uint8_t lv[GSM_MAX_SSVERSION + 1]; | ||||
|  | ||||
| 	if (ssv->len > GSM_MAX_SSVERSION) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	lv[0] = ssv->len; | ||||
| 	memcpy(lv + 1, ssv->info, ssv->len); | ||||
| 	msgb_tlv_put(msg, GSM48_IE_SS_VERS, lv[0], lv+1); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* decode 'more data' does not require a function, because it has no value */ | ||||
|  | ||||
| /* encode 'more data' */ | ||||
| int gsm48_encode_more(struct msgb *msg) | ||||
| { | ||||
| 	uint8_t *ie; | ||||
|  | ||||
| 	ie = msgb_put(msg, 1); | ||||
| 	ie[0] = GSM48_IE_MORE_DATA; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										361
									
								
								libosmocore/src/gsm_utils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										361
									
								
								libosmocore/src/gsm_utils.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,361 @@ | ||||
| /* | ||||
|  * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de> | ||||
|  * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> | ||||
|  * (C) 2009-2010 by Harald Welte <laforge@gnumonks.org> | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| //#include <openbsc/gsm_data.h> | ||||
| #include <osmocore/utils.h> | ||||
| #include <osmocore/gsm_utils.h> | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
| #include <ctype.h> | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| /* GSM 03.38 6.2.1 Charachter packing */ | ||||
| int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t length) | ||||
| { | ||||
| 	int i = 0; | ||||
| 	int l = 0; | ||||
|  | ||||
|         /* FIXME: We need to account for user data headers here */ | ||||
| 	i += l; | ||||
| 	for (; i < length; i ++) | ||||
| 		*(text ++) = | ||||
| 			((user_data[(i * 7 + 7) >> 3] << | ||||
| 			  (7 - ((i * 7 + 7) & 7))) | | ||||
| 			 (user_data[(i * 7) >> 3] >> | ||||
| 			  ((i * 7) & 7))) & 0x7f; | ||||
| 	*text = '\0'; | ||||
|  | ||||
| 	return i - l; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* GSM 03.38 6.2.1 Charachter packing */ | ||||
| int gsm_7bit_encode(uint8_t *result, const char *data) | ||||
| { | ||||
| 	int i,j = 0; | ||||
| 	unsigned char ch1, ch2; | ||||
| 	int shift = 0; | ||||
|  | ||||
| 	for ( i=0; i<strlen(data); i++ ) { | ||||
|  | ||||
| 		ch1 = data[i] & 0x7F; | ||||
| 		ch1 = ch1 >> shift; | ||||
| 		ch2 = data[(i+1)] & 0x7F; | ||||
| 		ch2 = ch2 << (7-shift); | ||||
|  | ||||
| 		ch1 = ch1 | ch2; | ||||
|  | ||||
| 		result[j++] = ch1; | ||||
|  | ||||
| 		shift++; | ||||
|  | ||||
| 		if ((shift == 7) && (i+1<strlen(data))) { | ||||
| 			shift = 0; | ||||
| 			i++; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return i; | ||||
| } | ||||
|  | ||||
| /* determine power control level for given dBm value, as indicated | ||||
|  * by the tables in chapter 4.1.1 of GSM TS 05.05 */ | ||||
| int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm) | ||||
| { | ||||
| 	switch (band) { | ||||
| 	case GSM_BAND_450: | ||||
| 	case GSM_BAND_480: | ||||
| 	case GSM_BAND_750: | ||||
| 	case GSM_BAND_900: | ||||
| 	case GSM_BAND_810: | ||||
| 	case GSM_BAND_850: | ||||
| 		if (dbm >= 39) | ||||
| 			return 0; | ||||
| 		else if (dbm < 5) | ||||
| 			return 19; | ||||
| 		else { | ||||
| 			/* we are guaranteed to have (5 <= dbm < 39) */ | ||||
| 			return 2 + ((39 - dbm) / 2); | ||||
| 		} | ||||
| 		break; | ||||
| 	case GSM_BAND_1800: | ||||
| 		if (dbm >= 36) | ||||
| 			return 29; | ||||
| 		else if (dbm >= 34)	 | ||||
| 			return 30; | ||||
| 		else if (dbm >= 32) | ||||
| 			return 31; | ||||
| 		else if (dbm == 31) | ||||
| 			return 0; | ||||
| 		else { | ||||
| 			/* we are guaranteed to have (0 <= dbm < 31) */ | ||||
| 			return (30 - dbm) / 2; | ||||
| 		} | ||||
| 		break; | ||||
| 	case GSM_BAND_1900: | ||||
| 		if (dbm >= 33) | ||||
| 			return 30; | ||||
| 		else if (dbm >= 32) | ||||
| 			return 31; | ||||
| 		else if (dbm == 31) | ||||
| 			return 0; | ||||
| 		else { | ||||
| 			/* we are guaranteed to have (0 <= dbm < 31) */ | ||||
| 			return (30 - dbm) / 2; | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
| 	return -EINVAL; | ||||
| } | ||||
|  | ||||
| int ms_pwr_dbm(enum gsm_band band, uint8_t lvl) | ||||
| { | ||||
| 	lvl &= 0x1f; | ||||
|  | ||||
| 	switch (band) { | ||||
| 	case GSM_BAND_450: | ||||
| 	case GSM_BAND_480: | ||||
| 	case GSM_BAND_750: | ||||
| 	case GSM_BAND_900: | ||||
| 	case GSM_BAND_810: | ||||
| 	case GSM_BAND_850: | ||||
| 		if (lvl < 2) | ||||
| 			return 39; | ||||
| 		else if (lvl < 20) | ||||
| 			return 39 - ((lvl - 2) * 2) ; | ||||
| 		else | ||||
| 			return 5; | ||||
| 		break; | ||||
| 	case GSM_BAND_1800: | ||||
| 		if (lvl < 16) | ||||
| 			return 30 - (lvl * 2); | ||||
| 		else if (lvl < 29) | ||||
| 			return 0; | ||||
| 		else | ||||
| 			return 36 - ((lvl - 29) * 2); | ||||
| 		break; | ||||
| 	case GSM_BAND_1900: | ||||
| 		if (lvl < 16) | ||||
| 			return 30 - (lvl * 2); | ||||
| 		else if (lvl < 30) | ||||
| 			return -EINVAL; | ||||
| 		else | ||||
| 			return 33 - (lvl - 30); | ||||
| 		break; | ||||
| 	} | ||||
| 	return -EINVAL; | ||||
| } | ||||
|  | ||||
| /* According to TS 08.05 Chapter 8.1.4 */ | ||||
| int rxlev2dbm(uint8_t rxlev) | ||||
| { | ||||
| 	if (rxlev > 63) | ||||
| 		rxlev = 63; | ||||
|  | ||||
| 	return -110 + rxlev; | ||||
| } | ||||
|  | ||||
| /* According to TS 08.05 Chapter 8.1.4 */ | ||||
| uint8_t dbm2rxlev(int dbm) | ||||
| { | ||||
| 	int rxlev = dbm + 110; | ||||
|  | ||||
| 	if (rxlev > 63) | ||||
| 		rxlev = 63; | ||||
| 	else if (rxlev < 0) | ||||
| 		rxlev = 0; | ||||
|  | ||||
| 	return rxlev; | ||||
| } | ||||
|  | ||||
| const char *gsm_band_name(enum gsm_band band) | ||||
| { | ||||
| 	switch (band) { | ||||
| 	case GSM_BAND_450: | ||||
| 		return "GSM450"; | ||||
| 	case GSM_BAND_480: | ||||
| 		return "GSM450"; | ||||
| 	case GSM_BAND_750: | ||||
| 		return "GSM750"; | ||||
| 	case GSM_BAND_810: | ||||
| 		return "GSM810"; | ||||
| 	case GSM_BAND_850: | ||||
| 		return "GSM850"; | ||||
| 	case GSM_BAND_900: | ||||
| 		return "GSM900"; | ||||
| 	case GSM_BAND_1800: | ||||
| 		return "DCS1800"; | ||||
| 	case GSM_BAND_1900: | ||||
| 		return "PCS1900"; | ||||
| 	} | ||||
| 	return "invalid"; | ||||
| } | ||||
|  | ||||
| enum gsm_band gsm_band_parse(const char* mhz) | ||||
| { | ||||
| 	while (*mhz && !isdigit(*mhz)) | ||||
| 		mhz++; | ||||
|  | ||||
| 	if (*mhz == '\0') | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	switch (strtol(mhz, NULL, 10)) { | ||||
| 	case 450: | ||||
| 		return GSM_BAND_450; | ||||
| 	case 480: | ||||
| 		return GSM_BAND_480; | ||||
| 	case 750: | ||||
| 		return GSM_BAND_750; | ||||
| 	case 810: | ||||
| 		return GSM_BAND_810; | ||||
| 	case 850: | ||||
| 		return GSM_BAND_850; | ||||
| 	case 900: | ||||
| 		return GSM_BAND_900; | ||||
| 	case 1800: | ||||
| 		return GSM_BAND_1800; | ||||
| 	case 1900: | ||||
| 		return GSM_BAND_1900; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef HAVE_EXECINFO_H | ||||
| #include <execinfo.h> | ||||
| void generate_backtrace() | ||||
| { | ||||
| 	int i, nptrs; | ||||
| 	void *buffer[100]; | ||||
| 	char **strings; | ||||
|  | ||||
| 	nptrs = backtrace(buffer, ARRAY_SIZE(buffer)); | ||||
| 	printf("backtrace() returned %d addresses\n", nptrs); | ||||
|  | ||||
| 	strings = backtrace_symbols(buffer, nptrs); | ||||
| 	if (!strings) | ||||
| 		return; | ||||
|  | ||||
| 	for (i = 1; i < nptrs; i++) | ||||
| 		printf("%s\n", strings[i]); | ||||
|  | ||||
| 	free(strings); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| enum gsm_band gsm_arfcn2band(uint16_t arfcn) | ||||
| { | ||||
| 	if (arfcn & ARFCN_PCS) | ||||
| 		return GSM_BAND_1900; | ||||
| 	else if (arfcn <= 124) | ||||
| 		return GSM_BAND_900; | ||||
| 	else if (arfcn >= 955 && arfcn <= 1023) | ||||
| 		return GSM_BAND_900; | ||||
| 	else if (arfcn >= 128 && arfcn <= 251) | ||||
| 		return GSM_BAND_850; | ||||
| 	else if (arfcn >= 512 && arfcn <= 885) | ||||
| 		return GSM_BAND_1800; | ||||
| 	else if (arfcn >= 259 && arfcn <= 293) | ||||
| 		return GSM_BAND_450; | ||||
| 	else if (arfcn >= 306 && arfcn <= 340) | ||||
| 		return GSM_BAND_480; | ||||
| 	else if (arfcn >= 350 && arfcn <= 425) | ||||
| 		return GSM_BAND_810; | ||||
| 	else if (arfcn >= 438 && arfcn <= 511) | ||||
| 		return GSM_BAND_750; | ||||
| 	else | ||||
| 		return GSM_BAND_1800; | ||||
| } | ||||
|  | ||||
| /* Convert an ARFCN to the frequency in MHz * 10 */ | ||||
| uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink) | ||||
| { | ||||
| 	uint16_t freq10_ul; | ||||
| 	uint16_t freq10_dl; | ||||
|  | ||||
| 	if (arfcn & ARFCN_PCS) { | ||||
| 		/* DCS 1900 */ | ||||
| 		arfcn &= ~ARFCN_PCS; | ||||
| 		freq10_ul = 18502 + 2 * (arfcn-512); | ||||
| 		freq10_dl = freq10_ul + 800; | ||||
| 	} else if (arfcn <= 124) { | ||||
| 		/* Primary GSM + ARFCN 0 of E-GSM */ | ||||
| 		freq10_ul = 8900 + 2 * arfcn; | ||||
| 		freq10_dl = freq10_ul + 450; | ||||
| 	} else if (arfcn >= 955 && arfcn <= 1023) { | ||||
| 		/* E-GSM and R-GSM */ | ||||
| 		freq10_ul = 8900 + 2 * (arfcn - 1024); | ||||
| 		freq10_dl = freq10_ul + 450; | ||||
| 	} else if (arfcn >= 128 && arfcn <= 251) { | ||||
| 		/* GSM 850 */ | ||||
| 		freq10_ul = 8242 + 2 * (arfcn - 128); | ||||
| 		freq10_dl = freq10_ul + 450; | ||||
| 	} else if (arfcn >= 512 && arfcn <= 885) { | ||||
| 		/* DCS 1800 */ | ||||
| 		freq10_ul = 17102 + 2 * (arfcn - 512); | ||||
| 		freq10_dl = freq10_ul + 950; | ||||
| 	} else if (arfcn >= 259 && arfcn <= 293) { | ||||
| 		/* GSM 450 */ | ||||
| 		freq10_ul = 4506 + 2 * (arfcn - 259); | ||||
| 		freq10_dl = freq10_ul + 100; | ||||
| 	} else if (arfcn >= 306 && arfcn <= 340) { | ||||
| 		/* GSM 480 */ | ||||
| 		freq10_ul = 4790 + 2 * (arfcn - 306); | ||||
| 		freq10_dl = freq10_ul + 100; | ||||
| 	} else if (arfcn >= 350 && arfcn <= 425) { | ||||
| 		/* GSM 810 */ | ||||
| 		freq10_ul = 8060 + 2 * (arfcn - 350); | ||||
| 		freq10_dl = freq10_ul + 450; | ||||
| 	} else if (arfcn >= 438 && arfcn <= 511) { | ||||
| 		/* GSM 750 */ | ||||
| 		freq10_ul = 7472 + 2 * (arfcn - 438); | ||||
| 		freq10_dl = freq10_ul + 300; | ||||
| 	} else | ||||
| 		return 0xffff; | ||||
|  | ||||
| 	if (uplink) | ||||
| 		return freq10_ul; | ||||
| 	else | ||||
| 		return freq10_dl; | ||||
| } | ||||
|  | ||||
| void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn) | ||||
| { | ||||
| 	time->fn = fn; | ||||
| 	time->t1 = time->fn / (26*51); | ||||
| 	time->t2 = time->fn % 26; | ||||
| 	time->t3 = time->fn % 51; | ||||
| 	time->tc = (time->fn / 51) % 8; | ||||
| } | ||||
|  | ||||
| uint32_t gsm_gsmtime2fn(struct gsm_time *time) | ||||
| { | ||||
| 	/* TS 05.02 Chapter 4.3.3 TDMA frame number */ | ||||
| 	return (51 * ((time->t3 - time->t2 + 26) % 26) + time->t3 + (26 * 51 * time->t1)); | ||||
| } | ||||
							
								
								
									
										345
									
								
								libosmocore/src/logging.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										345
									
								
								libosmocore/src/logging.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,345 @@ | ||||
| /* Debugging/Logging support code */ | ||||
|  | ||||
| /* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org> | ||||
|  * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdarg.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <strings.h> | ||||
| #include <time.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| #include <osmocore/talloc.h> | ||||
| #include <osmocore/utils.h> | ||||
| #include <osmocore/logging.h> | ||||
|  | ||||
| static const struct log_info *log_info; | ||||
|  | ||||
| static struct log_context log_context; | ||||
| static void *tall_log_ctx = NULL; | ||||
| static LLIST_HEAD(target_list); | ||||
|  | ||||
| static const struct value_string loglevel_strs[] = { | ||||
| 	{ 0,		"EVERYTHING" }, | ||||
| 	{ LOGL_DEBUG,	"DEBUG" }, | ||||
| 	{ LOGL_INFO,	"INFO" }, | ||||
| 	{ LOGL_NOTICE,	"NOTICE" }, | ||||
| 	{ LOGL_ERROR,	"ERROR" }, | ||||
| 	{ LOGL_FATAL,	"FATAL" }, | ||||
| 	{ 0, NULL }, | ||||
| }; | ||||
|  | ||||
| int log_parse_level(const char *lvl) | ||||
| { | ||||
| 	return get_string_value(loglevel_strs, lvl); | ||||
| } | ||||
|  | ||||
| int log_parse_category(const char *category) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0; i < log_info->num_cat; ++i) { | ||||
| 		if (!strcasecmp(log_info->cat[i].name+1, category)) | ||||
| 			return i; | ||||
| 	} | ||||
|  | ||||
| 	return -EINVAL; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Parse the category mask. | ||||
|  * The format can be this: category1:category2:category3 | ||||
|  * or category1,2:category2,3:... | ||||
|  */ | ||||
| void log_parse_category_mask(struct log_target* target, const char *_mask) | ||||
| { | ||||
| 	int i = 0; | ||||
| 	char *mask = strdup(_mask); | ||||
| 	char *category_token = NULL; | ||||
|  | ||||
| 	/* Disable everything to enable it afterwards */ | ||||
| 	for (i = 0; i < ARRAY_SIZE(target->categories); ++i) | ||||
| 		target->categories[i].enabled = 0; | ||||
|  | ||||
| 	category_token = strtok(mask, ":"); | ||||
| 	do { | ||||
| 		for (i = 0; i < log_info->num_cat; ++i) { | ||||
| 			char* colon = strstr(category_token, ","); | ||||
| 			int length = strlen(category_token); | ||||
|  | ||||
| 			if (colon) | ||||
| 			    length = colon - category_token; | ||||
|  | ||||
| 			if (strncasecmp(log_info->cat[i].name, category_token, | ||||
| 					length) == 0) { | ||||
| 				int level = 0; | ||||
|  | ||||
| 				if (colon) | ||||
| 					level = atoi(colon+1); | ||||
|  | ||||
| 				target->categories[i].enabled = 1; | ||||
| 				target->categories[i].loglevel = level; | ||||
| 			} | ||||
| 		} | ||||
| 	} while ((category_token = strtok(NULL, ":"))); | ||||
|  | ||||
| 	free(mask); | ||||
| } | ||||
|  | ||||
| static const char* color(int subsys) | ||||
| { | ||||
| 	if (subsys < log_info->num_cat) | ||||
| 		return log_info->cat[subsys].color; | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| static void _output(struct log_target *target, unsigned int subsys, | ||||
| 		    char *file, int line, int cont, const char *format, | ||||
| 		    va_list ap) | ||||
| { | ||||
| 	char col[30]; | ||||
| 	char sub[30]; | ||||
| 	char tim[30]; | ||||
| 	char buf[4096]; | ||||
| 	char final[4096]; | ||||
|  | ||||
| 	/* prepare the data */ | ||||
| 	col[0] = '\0'; | ||||
| 	sub[0] = '\0'; | ||||
| 	tim[0] = '\0'; | ||||
| 	buf[0] = '\0'; | ||||
|  | ||||
| 	/* are we using color */ | ||||
| 	if (target->use_color) { | ||||
| 		const char *c = color(subsys); | ||||
| 		if (c) { | ||||
| 			snprintf(col, sizeof(col), "%s", color(subsys)); | ||||
| 			col[sizeof(col)-1] = '\0'; | ||||
| 		} | ||||
| 	} | ||||
| 	vsnprintf(buf, sizeof(buf), format, ap); | ||||
| 	buf[sizeof(buf)-1] = '\0'; | ||||
|  | ||||
| 	if (!cont) { | ||||
| 		if (target->print_timestamp) { | ||||
| 			char *timestr; | ||||
| 			time_t tm; | ||||
| 			tm = time(NULL); | ||||
| 			timestr = ctime(&tm); | ||||
| 			timestr[strlen(timestr)-1] = '\0'; | ||||
| 			snprintf(tim, sizeof(tim), "%s ", timestr); | ||||
| 			tim[sizeof(tim)-1] = '\0'; | ||||
| 		} | ||||
| 		snprintf(sub, sizeof(sub), "<%4.4x> %s:%d ", subsys, file, line); | ||||
| 		sub[sizeof(sub)-1] = '\0'; | ||||
| 	} | ||||
|  | ||||
| 	snprintf(final, sizeof(final), "%s%s%s%s\033[0;m", col, tim, sub, buf); | ||||
| 	final[sizeof(final)-1] = '\0'; | ||||
| 	target->output(target, final); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void _logp(unsigned int subsys, int level, char *file, int line, | ||||
| 		  int cont, const char *format, va_list ap) | ||||
| { | ||||
| 	struct log_target *tar; | ||||
|  | ||||
| 	llist_for_each_entry(tar, &target_list, entry) { | ||||
| 		struct log_category *category; | ||||
| 		int output = 0; | ||||
|  | ||||
| 		category = &tar->categories[subsys]; | ||||
| 		/* subsystem is not supposed to be logged */ | ||||
| 		if (!category->enabled) | ||||
| 			continue; | ||||
|  | ||||
| 		/* Check the global log level */ | ||||
| 		if (tar->loglevel != 0 && level < tar->loglevel) | ||||
| 			continue; | ||||
|  | ||||
| 		/* Check the category log level */ | ||||
| 		if (tar->loglevel == 0 && category->loglevel != 0 && | ||||
| 		    level < category->loglevel) | ||||
| 			continue; | ||||
|  | ||||
| 		/* Apply filters here... if that becomes messy we will | ||||
| 		 * need to put filters in a list and each filter will | ||||
| 		 * say stop, continue, output */ | ||||
| 		if ((tar->filter_map & LOG_FILTER_ALL) != 0) | ||||
| 			output = 1; | ||||
| 		else if (log_info->filter_fn) | ||||
| 			output = log_info->filter_fn(&log_context, | ||||
| 						       tar); | ||||
|  | ||||
| 		if (output) { | ||||
| 			/* FIXME: copying the va_list is an ugly | ||||
| 			 * workaround against a bug hidden somewhere in | ||||
| 			 * _output.  If we do not copy here, the first | ||||
| 			 * call to _output() will corrupt the va_list | ||||
| 			 * contents, and any further _output() calls | ||||
| 			 * with the same va_list will segfault */ | ||||
| 			va_list bp; | ||||
| 			va_copy(bp, ap); | ||||
| 			_output(tar, subsys, file, line, cont, format, bp); | ||||
| 			va_end(bp); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void logp(unsigned int subsys, char *file, int line, int cont, | ||||
| 	  const char *format, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
|  | ||||
| 	va_start(ap, format); | ||||
| 	_logp(subsys, LOGL_DEBUG, file, line, cont, format, ap); | ||||
| 	va_end(ap); | ||||
| } | ||||
|  | ||||
| void logp2(unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
|  | ||||
| 	va_start(ap, format); | ||||
| 	_logp(subsys, level, file, line, cont, format, ap); | ||||
| 	va_end(ap); | ||||
| } | ||||
|  | ||||
| static char hexd_buff[4096]; | ||||
|  | ||||
| char *hexdump(const unsigned char *buf, int len) | ||||
| { | ||||
| 	int i; | ||||
| 	char *cur = hexd_buff; | ||||
|  | ||||
| 	hexd_buff[0] = 0; | ||||
| 	for (i = 0; i < len; i++) { | ||||
| 		int len_remain = sizeof(hexd_buff) - (cur - hexd_buff); | ||||
| 		int rc = snprintf(cur, len_remain, "%02x ", buf[i]); | ||||
| 		if (rc <= 0) | ||||
| 			break; | ||||
| 		cur += rc; | ||||
| 	} | ||||
| 	hexd_buff[sizeof(hexd_buff)-1] = 0; | ||||
| 	return hexd_buff; | ||||
| } | ||||
|  | ||||
| void log_add_target(struct log_target *target) | ||||
| { | ||||
| 	llist_add_tail(&target->entry, &target_list); | ||||
| } | ||||
|  | ||||
| void log_del_target(struct log_target *target) | ||||
| { | ||||
| 	llist_del(&target->entry); | ||||
| } | ||||
|  | ||||
| void log_reset_context(void) | ||||
| { | ||||
| 	memset(&log_context, 0, sizeof(log_context)); | ||||
| } | ||||
|  | ||||
| int log_set_context(uint8_t ctx_nr, void *value) | ||||
| { | ||||
| 	if (ctx_nr > LOG_MAX_CTX) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	log_context.ctx[ctx_nr] = value; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void log_set_all_filter(struct log_target *target, int all) | ||||
| { | ||||
| 	if (all) | ||||
| 		target->filter_map |= LOG_FILTER_ALL; | ||||
| 	else | ||||
| 		target->filter_map &= ~LOG_FILTER_ALL; | ||||
| } | ||||
|  | ||||
| void log_set_use_color(struct log_target *target, int use_color) | ||||
| { | ||||
| 	target->use_color = use_color; | ||||
| } | ||||
|  | ||||
| void log_set_print_timestamp(struct log_target *target, int print_timestamp) | ||||
| { | ||||
| 	target->print_timestamp = print_timestamp; | ||||
| } | ||||
|  | ||||
| void log_set_log_level(struct log_target *target, int log_level) | ||||
| { | ||||
| 	target->loglevel = log_level; | ||||
| } | ||||
|  | ||||
| void log_set_category_filter(struct log_target *target, int category, | ||||
| 			       int enable, int level) | ||||
| { | ||||
| 	if (category >= log_info->num_cat) | ||||
| 		return; | ||||
| 	target->categories[category].enabled = !!enable; | ||||
| 	target->categories[category].loglevel = level; | ||||
| } | ||||
|  | ||||
| static void _stderr_output(struct log_target *target, const char *log) | ||||
| { | ||||
| 	fprintf(target->tgt_stdout.out, "%s", log); | ||||
| 	fflush(target->tgt_stdout.out); | ||||
| } | ||||
|  | ||||
| struct log_target *log_target_create(void) | ||||
| { | ||||
| 	struct log_target *target; | ||||
|  | ||||
| 	target = talloc_zero(tall_log_ctx, struct log_target); | ||||
| 	if (!target) | ||||
| 		return NULL; | ||||
|  | ||||
| 	INIT_LLIST_HEAD(&target->entry); | ||||
| 	memcpy(target->categories, log_info->cat, | ||||
| 		sizeof(struct log_category)*log_info->num_cat); | ||||
| 	target->use_color = 1; | ||||
| 	target->print_timestamp = 0; | ||||
| 	target->loglevel = 0; | ||||
| 	return target; | ||||
| } | ||||
|  | ||||
| struct log_target *log_target_create_stderr(void) | ||||
| { | ||||
| 	struct log_target *target; | ||||
|  | ||||
| 	target = log_target_create(); | ||||
| 	if (!target) | ||||
| 		return NULL; | ||||
|  | ||||
| 	target->tgt_stdout.out = stderr; | ||||
| 	target->output = _stderr_output; | ||||
| 	return target; | ||||
| } | ||||
|  | ||||
| void log_init(const struct log_info *cat) | ||||
| { | ||||
| 	tall_log_ctx = talloc_named_const(NULL, 1, "logging"); | ||||
| 	log_info = cat; | ||||
| } | ||||
							
								
								
									
										89
									
								
								libosmocore/src/msgb.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								libosmocore/src/msgb.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| /* (C) 2008 by Harald Welte <laforge@gnumonks.org> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <unistd.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <sys/types.h> | ||||
|  | ||||
| #include <osmocore/msgb.h> | ||||
| //#include <openbsc/gsm_data.h> | ||||
| #include <osmocore/talloc.h> | ||||
| //#include <openbsc/debug.h> | ||||
|  | ||||
| void *tall_msgb_ctx; | ||||
|  | ||||
| struct msgb *msgb_alloc(uint16_t size, const char *name) | ||||
| { | ||||
| 	struct msgb *msg; | ||||
|  | ||||
| 	msg = _talloc_zero(tall_msgb_ctx, sizeof(*msg) + size, name); | ||||
|  | ||||
| 	if (!msg) { | ||||
| 		//LOGP(DRSL, LOGL_FATAL, "unable to allocate msgb\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	msg->data_len = size; | ||||
| 	msg->len = 0; | ||||
| 	msg->data = msg->_data; | ||||
| 	msg->head = msg->_data; | ||||
| 	msg->tail = msg->_data; | ||||
|  | ||||
| 	return msg; | ||||
| } | ||||
|  | ||||
| void msgb_free(struct msgb *m) | ||||
| { | ||||
| 	talloc_free(m); | ||||
| } | ||||
|  | ||||
| void msgb_enqueue(struct llist_head *queue, struct msgb *msg) | ||||
| { | ||||
| 	llist_add_tail(&msg->list, queue); | ||||
| } | ||||
|  | ||||
| struct msgb *msgb_dequeue(struct llist_head *queue) | ||||
| { | ||||
| 	struct llist_head *lh; | ||||
|  | ||||
| 	if (llist_empty(queue)) | ||||
| 		return NULL; | ||||
|  | ||||
| 	lh = queue->next; | ||||
| 	llist_del(lh); | ||||
| 	 | ||||
| 	return llist_entry(lh, struct msgb, list); | ||||
| } | ||||
|  | ||||
| void msgb_reset(struct msgb *msg) | ||||
| { | ||||
| 	msg->len = 0; | ||||
| 	msg->data = msg->_data; | ||||
| 	msg->head = msg->_data; | ||||
| 	msg->tail = msg->_data; | ||||
|  | ||||
| 	msg->bts_link = NULL; | ||||
| 	msg->trx = NULL; | ||||
| 	msg->lchan = NULL; | ||||
| 	msg->l2h = NULL; | ||||
| 	msg->l3h = NULL; | ||||
| 	msg->smsh = NULL; | ||||
| } | ||||
							
								
								
									
										329
									
								
								libosmocore/src/rsl.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								libosmocore/src/rsl.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,329 @@ | ||||
| /* GSM Radio Signalling Link messages on the A-bis interface  | ||||
|  * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */ | ||||
|  | ||||
| /* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org> | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| #include <osmocore/tlv.h> | ||||
| #include <osmocore/rsl.h> | ||||
|  | ||||
| #define RSL_ALLOC_SIZE		200 | ||||
| #define RSL_ALLOC_HEADROOM	56 | ||||
|  | ||||
| void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type) | ||||
| { | ||||
| 	dh->c.msg_discr = ABIS_RSL_MDISC_RLL; | ||||
| 	dh->c.msg_type = msg_type; | ||||
| 	dh->ie_chan = RSL_IE_CHAN_NR; | ||||
| 	dh->ie_link_id = RSL_IE_LINK_IDENT; | ||||
| } | ||||
|  | ||||
| const struct tlv_definition rsl_att_tlvdef = { | ||||
| 	.def = { | ||||
| 		[RSL_IE_CHAN_NR]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_LINK_IDENT]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_ACT_TYPE]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_BS_POWER]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_CHAN_IDENT]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_CHAN_MODE]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_ENCR_INFO]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_FRAME_NUMBER]		= { TLV_TYPE_FIXED, 2 }, | ||||
| 		[RSL_IE_HANDO_REF]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_L1_INFO]		= { TLV_TYPE_FIXED, 2 }, | ||||
| 		[RSL_IE_L3_INFO]		= { TLV_TYPE_TL16V }, | ||||
| 		[RSL_IE_MS_IDENTITY]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_MS_POWER]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_PAGING_GROUP]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_PAGING_LOAD]		= { TLV_TYPE_FIXED, 2 }, | ||||
| 		[RSL_IE_PYHS_CONTEXT]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_ACCESS_DELAY]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_RACH_LOAD]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_REQ_REFERENCE]		= { TLV_TYPE_FIXED, 3 }, | ||||
| 		[RSL_IE_RELEASE_MODE]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_RESOURCE_INFO]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_RLM_CAUSE]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_STARTNG_TIME]		= { TLV_TYPE_FIXED, 2 }, | ||||
| 		[RSL_IE_TIMING_ADVANCE]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_UPLINK_MEAS]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_CAUSE]			= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_MEAS_RES_NR]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_MSG_ID]			= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_SYSINFO_TYPE]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_MS_POWER_PARAM]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_BS_POWER_PARAM]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_PREPROC_PARAM]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_PREPROC_MEAS]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_IMM_ASS_INFO]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_SMSCB_INFO]		= { TLV_TYPE_FIXED, 23 }, | ||||
| 		[RSL_IE_MS_TIMING_OFFSET]	= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_ERR_MSG]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_FULL_BCCH_INFO]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_CHAN_NEEDED]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_CB_CMD_TYPE]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_SMSCB_MSG]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_FULL_IMM_ASS_INFO]	= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_SACCH_INFO]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_CBCH_LOAD_INFO]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_SMSCB_CHAN_INDICATOR]	= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_GROUP_CALL_REF]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_CHAN_DESC]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_NCH_DRX_INFO]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_CMD_INDICATOR]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_EMLPP_PRIO]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_UIC]			= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_MAIN_CHAN_REF]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_MR_CONFIG]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_MR_CONTROL]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_SUP_CODEC_TYPES]	= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_CODEC_CONFIG]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_RTD]			= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_TFO_STATUS]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_LLP_APDU]		= { TLV_TYPE_TLV }, | ||||
| 		[RSL_IE_SIEMENS_MRPCI]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_IPAC_PROXY_UDP]		= { TLV_TYPE_FIXED, 2 }, | ||||
| 		[RSL_IE_IPAC_BSCMPL_TOUT]	= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_IPAC_REMOTE_IP]		= { TLV_TYPE_FIXED, 4 }, | ||||
| 		[RSL_IE_IPAC_REMOTE_PORT]	= { TLV_TYPE_FIXED, 2 }, | ||||
| 		[RSL_IE_IPAC_RTP_PAYLOAD]	= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_IPAC_LOCAL_PORT]	= { TLV_TYPE_FIXED, 2 }, | ||||
| 		[RSL_IE_IPAC_SPEECH_MODE]	= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_IPAC_LOCAL_IP]		= { TLV_TYPE_FIXED, 4 }, | ||||
| 		[RSL_IE_IPAC_CONN_ID]		= { TLV_TYPE_FIXED, 2 }, | ||||
| 		[RSL_IE_IPAC_RTP_CSD_FMT]	= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_IPAC_RTP_JIT_BUF]	= { TLV_TYPE_FIXED, 2 }, | ||||
| 		[RSL_IE_IPAC_RTP_COMPR]		= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_IPAC_RTP_PAYLOAD2]	= { TLV_TYPE_TV }, | ||||
| 		[RSL_IE_IPAC_RTP_MPLEX]		= { TLV_TYPE_FIXED, 8 }, | ||||
| 		[RSL_IE_IPAC_RTP_MPLEX_ID]	= { TLV_TYPE_TV }, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| /* encode channel number as per Section 9.3.1 */ | ||||
| uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot) | ||||
| { | ||||
| 	uint8_t ret; | ||||
|  | ||||
| 	ret = (timeslot & 0x07) | type; | ||||
|  | ||||
| 	switch (type) { | ||||
| 	case RSL_CHAN_Lm_ACCHs: | ||||
| 		subch &= 0x01; | ||||
| 		break; | ||||
| 	case RSL_CHAN_SDCCH4_ACCH: | ||||
| 		subch &= 0x03; | ||||
| 		break; | ||||
| 	case RSL_CHAN_SDCCH8_ACCH: | ||||
| 		subch &= 0x07; | ||||
| 		break; | ||||
| 	default: | ||||
| 		/* no subchannels allowed */ | ||||
| 		subch = 0x00; | ||||
| 		break; | ||||
| 	} | ||||
| 	ret |= (subch << 3); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot) | ||||
| { | ||||
| 	*timeslot = chan_nr & 0x7; | ||||
|  | ||||
| 	if ((chan_nr & 0xf8) == RSL_CHAN_Bm_ACCHs) { | ||||
| 		*type = RSL_CHAN_Bm_ACCHs; | ||||
| 		*subch = 0; | ||||
| 	} else if ((chan_nr & 0xf0) == RSL_CHAN_Lm_ACCHs) { | ||||
| 		*type = RSL_CHAN_Lm_ACCHs; | ||||
| 		*subch = (chan_nr >> 3) & 0x1; | ||||
| 	} else if ((chan_nr & 0xe0) == RSL_CHAN_SDCCH4_ACCH) { | ||||
| 		*type = RSL_CHAN_SDCCH4_ACCH; | ||||
| 		*subch = (chan_nr >> 3) & 0x3; | ||||
| 	} else if ((chan_nr & 0xc0) == RSL_CHAN_SDCCH8_ACCH) { | ||||
| 		*type = RSL_CHAN_SDCCH8_ACCH; | ||||
| 		*subch = (chan_nr >> 3) & 0x7; | ||||
| 	} else if ((chan_nr & 0xf8) == RSL_CHAN_BCCH) { | ||||
| 		*type = RSL_CHAN_BCCH; | ||||
| 		*subch = 0; | ||||
| 	} else if ((chan_nr & 0xf8) == RSL_CHAN_RACH) { | ||||
| 		*type = RSL_CHAN_RACH; | ||||
| 		*subch = 0; | ||||
| 	} else if ((chan_nr & 0xf8) == RSL_CHAN_PCH_AGCH) { | ||||
| 		*type = RSL_CHAN_PCH_AGCH; | ||||
| 		*subch = 0; | ||||
| 	} else | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct value_string rsl_err_vals[] = { | ||||
| 	{ RSL_ERR_RADIO_IF_FAIL,	"Radio Interface Failure" }, | ||||
| 	{ RSL_ERR_RADIO_LINK_FAIL,	"Radio Link Failure" }, | ||||
| 	{ RSL_ERR_HANDOVER_ACC_FAIL,	"Handover Access Failure" }, | ||||
| 	{ RSL_ERR_TALKER_ACC_FAIL,	"Talker Access Failure" }, | ||||
| 	{ RSL_ERR_OM_INTERVENTION,	"O&M Intervention" }, | ||||
| 	{ RSL_ERR_NORMAL_UNSPEC,	"Normal event, unspecified" }, | ||||
| 	{ RSL_ERR_T_MSRFPCI_EXP,	"Siemens: T_MSRFPCI Expired" }, | ||||
| 	{ RSL_ERR_EQUIPMENT_FAIL,	"Equipment Failure" }, | ||||
| 	{ RSL_ERR_RR_UNAVAIL,		"Radio Resource not available" }, | ||||
| 	{ RSL_ERR_TERR_CH_FAIL,		"Terrestrial Channel Failure" }, | ||||
| 	{ RSL_ERR_CCCH_OVERLOAD,	"CCCH Overload" }, | ||||
| 	{ RSL_ERR_ACCH_OVERLOAD,	"ACCH Overload" }, | ||||
| 	{ RSL_ERR_PROCESSOR_OVERLOAD,	"Processor Overload" }, | ||||
| 	{ RSL_ERR_RES_UNAVAIL,		"Resource not available, unspecified" }, | ||||
| 	{ RSL_ERR_TRANSC_UNAVAIL,	"Transcoding not available" }, | ||||
| 	{ RSL_ERR_SERV_OPT_UNAVAIL,	"Service or Option not available" }, | ||||
| 	{ RSL_ERR_ENCR_UNIMPL,		"Encryption algorithm not implemented" }, | ||||
| 	{ RSL_ERR_SERV_OPT_UNIMPL,	"Service or Option not implemented" }, | ||||
| 	{ RSL_ERR_RCH_ALR_ACTV_ALLOC,	"Radio channel already activated" }, | ||||
| 	{ RSL_ERR_INVALID_MESSAGE,	"Invalid Message, unspecified" }, | ||||
| 	{ RSL_ERR_MSG_DISCR,		"Message Discriminator Error" }, | ||||
| 	{ RSL_ERR_MSG_TYPE,		"Message Type Error" }, | ||||
| 	{ RSL_ERR_MSG_SEQ,		"Message Sequence Error" }, | ||||
| 	{ RSL_ERR_IE_ERROR,		"General IE error" }, | ||||
| 	{ RSL_ERR_MAND_IE_ERROR,	"Mandatory IE error" }, | ||||
| 	{ RSL_ERR_OPT_IE_ERROR,		"Optional IE error" }, | ||||
| 	{ RSL_ERR_IE_NONEXIST,		"IE non-existent" }, | ||||
| 	{ RSL_ERR_IE_LENGTH,		"IE length error" }, | ||||
| 	{ RSL_ERR_IE_CONTENT,		"IE content error" }, | ||||
| 	{ RSL_ERR_PROTO,		"Protocol error, unspecified" }, | ||||
| 	{ RSL_ERR_INTERWORKING,		"Interworking error, unspecified" }, | ||||
| 	{ 0,				NULL } | ||||
| }; | ||||
|  | ||||
| const char *rsl_err_name(uint8_t err) | ||||
| { | ||||
| 	return get_value_string(rsl_err_vals, err); | ||||
| } | ||||
|  | ||||
| static const struct value_string rsl_rlm_cause_strs[] = { | ||||
| 	{ RLL_CAUSE_T200_EXPIRED,	"Timer T200 expired (N200+1) times" }, | ||||
| 	{ RLL_CAUSE_REEST_REQ,		"Re-establishment request" }, | ||||
| 	{ RLL_CAUSE_UNSOL_UA_RESP,	"Unsolicited UA response" }, | ||||
| 	{ RLL_CAUSE_UNSOL_DM_RESP,	"Unsolicited DM response" }, | ||||
| 	{ RLL_CAUSE_UNSOL_DM_RESP_MF,	"Unsolicited DM response, multiple frame" }, | ||||
| 	{ RLL_CAUSE_UNSOL_SPRV_RESP,	"Unsolicited supervisory response" }, | ||||
| 	{ RLL_CAUSE_SEQ_ERR,		"Sequence Error" }, | ||||
| 	{ RLL_CAUSE_UFRM_INC_PARAM,	"U-Frame with incorrect parameters" }, | ||||
| 	{ RLL_CAUSE_SFRM_INC_PARAM,	"S-Frame with incorrect parameters" }, | ||||
| 	{ RLL_CAUSE_IFRM_INC_MBITS,	"I-Frame with incorrect use of M bit" }, | ||||
| 	{ RLL_CAUSE_IFRM_INC_LEN,	"I-Frame with incorrect length" }, | ||||
| 	{ RLL_CAUSE_FRM_UNIMPL,		"Fraeme not implemented" }, | ||||
| 	{ RLL_CAUSE_SABM_MF,		"SABM command, multiple frame established state" }, | ||||
| 	{ RLL_CAUSE_SABM_INFO_NOTALL,	"SABM frame with information not allowed in this state" }, | ||||
| 	{ 0,				NULL }, | ||||
| }; | ||||
|  | ||||
| const char *rsl_rlm_cause_name(uint8_t err) | ||||
| { | ||||
| 	return get_value_string(rsl_rlm_cause_strs, err); | ||||
| } | ||||
|  | ||||
| /* Section 3.3.2.3 TS 05.02. I think this looks like a table */ | ||||
| int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf) | ||||
| { | ||||
| 	switch (ccch_conf) { | ||||
| 	case RSL_BCCH_CCCH_CONF_1_NC: | ||||
| 		return 1; | ||||
| 	case RSL_BCCH_CCCH_CONF_1_C: | ||||
| 		return 1; | ||||
| 	case RSL_BCCH_CCCH_CONF_2_NC: | ||||
| 		return 2; | ||||
| 	case RSL_BCCH_CCCH_CONF_3_NC: | ||||
| 		return 3; | ||||
| 	case RSL_BCCH_CCCH_CONF_4_NC: | ||||
| 		return 4; | ||||
| 	default: | ||||
| 		return -1; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Section 3.3.2.3 TS 05.02 */ | ||||
| int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf) | ||||
| { | ||||
| 	switch (ccch_conf) { | ||||
| 	case RSL_BCCH_CCCH_CONF_1_NC: | ||||
| 		return 0; | ||||
| 	case RSL_BCCH_CCCH_CONF_1_C: | ||||
| 		return 1; | ||||
| 	case RSL_BCCH_CCCH_CONF_2_NC: | ||||
| 		return 0; | ||||
| 	case RSL_BCCH_CCCH_CONF_3_NC: | ||||
| 		return 0; | ||||
| 	case RSL_BCCH_CCCH_CONF_4_NC: | ||||
| 		return 0; | ||||
| 	default: | ||||
| 		return -1; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Push a RSL RLL header with L3_INFO IE */ | ||||
| void rsl_rll_push_l3(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr, | ||||
| 		     uint8_t link_id, int transparent) | ||||
| { | ||||
| 	uint8_t l3_len = msg->tail - (uint8_t *)msgb_l3(msg); | ||||
| 	struct abis_rsl_rll_hdr *rh; | ||||
|  | ||||
| 	/* construct a RSLms RLL message (DATA INDICATION, UNIT DATA | ||||
| 	 * INDICATION) and send it off via RSLms */ | ||||
|  | ||||
| 	/* Push the L3 IE tag and lengh */ | ||||
| 	msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len); | ||||
|  | ||||
| 	/* Then push the RSL header */ | ||||
| 	rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh)); | ||||
| 	rsl_init_rll_hdr(rh, msg_type); | ||||
| 	if (transparent) | ||||
| 		rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP; | ||||
| 	rh->chan_nr = chan_nr; | ||||
| 	rh->link_id = link_id; | ||||
|  | ||||
| 	/* set the l2 header pointer */ | ||||
| 	msg->l2h = (uint8_t *)rh; | ||||
| } | ||||
|  | ||||
| struct msgb *rsl_rll_simple(uint8_t msg_type, uint8_t chan_nr, | ||||
| 			    uint8_t link_id, int transparent) | ||||
| { | ||||
| 	struct abis_rsl_rll_hdr *rh; | ||||
| 	struct msgb *msg; | ||||
|  | ||||
| 	msg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM, | ||||
| 				  RSL_ALLOC_HEADROOM, "rsl_rll_simple"); | ||||
|  | ||||
| 	if (!msg) | ||||
| 		return NULL; | ||||
|  | ||||
| 	/* put the RSL header */ | ||||
| 	rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh)); | ||||
| 	rsl_init_rll_hdr(rh, msg_type); | ||||
| 	if (transparent) | ||||
| 		rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP; | ||||
| 	rh->chan_nr = chan_nr; | ||||
| 	rh->link_id = link_id; | ||||
|  | ||||
| 	/* set the l2 header pointer */ | ||||
| 	msg->l2h = (uint8_t *)rh; | ||||
|  | ||||
| 	return msg; | ||||
| } | ||||
							
								
								
									
										94
									
								
								libosmocore/src/rxlev_stat.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								libosmocore/src/rxlev_stat.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| /* Rx Level statistics */ | ||||
|  | ||||
| /* (C) 2010 by Harald Welte <laforge@gnumonks.org> | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <unistd.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include <osmocore/bitvec.h> | ||||
| #include <osmocore/rxlev_stat.h> | ||||
|  | ||||
| int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val) | ||||
| { | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	for (i = n; i < bv->data_len*8; i++) { | ||||
| 		if (bitvec_get_bit_pos(bv, i) == val) | ||||
| 			return i; | ||||
| 	} | ||||
|  | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| void rxlev_stat_input(struct rxlev_stats *st, uint16_t arfcn, uint8_t rxlev) | ||||
| { | ||||
| 	struct bitvec bv; | ||||
|  | ||||
| 	if (rxlev >= NUM_RXLEVS) | ||||
| 		rxlev = NUM_RXLEVS-1; | ||||
|  | ||||
| 	bv.data_len = NUM_ARFCNS/8; | ||||
| 	bv.data = st->rxlev_buckets[rxlev]; | ||||
|  | ||||
| 	bitvec_set_bit_pos(&bv, arfcn, ONE); | ||||
| } | ||||
|  | ||||
| /* get the next ARFCN that has the specified Rxlev */ | ||||
| int16_t rxlev_stat_get_next(const struct rxlev_stats *st, uint8_t rxlev, int16_t arfcn) | ||||
| { | ||||
| 	struct bitvec bv; | ||||
|  | ||||
| 	if (rxlev >= NUM_RXLEVS) | ||||
| 		rxlev = NUM_RXLEVS-1; | ||||
|  | ||||
| 	bv.data_len = NUM_ARFCNS/8; | ||||
|  | ||||
| 	if (arfcn < 0) | ||||
| 		arfcn = -1; | ||||
|  | ||||
| 	bv.data = st->rxlev_buckets[rxlev]; | ||||
|  | ||||
| 	return bitvec_find_bit_pos(&bv, arfcn+1, ONE); | ||||
| } | ||||
|  | ||||
| void rxlev_stat_reset(struct rxlev_stats *st) | ||||
| { | ||||
| 	memset(st, 0, sizeof(*st)); | ||||
| } | ||||
|  | ||||
| void rxlev_stat_dump(const struct rxlev_stats *st) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = NUM_RXLEVS-1; i >= 0; i--) { | ||||
| 		int16_t arfcn = -1; | ||||
|  | ||||
| 		printf("ARFCN with RxLev %u: ", i); | ||||
| 		while ((arfcn = rxlev_stat_get_next(st, i, arfcn)) >= 0) { | ||||
| 			printf("%u ", arfcn); | ||||
| 		} | ||||
| 		printf("\n"); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										130
									
								
								libosmocore/src/select.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								libosmocore/src/select.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,130 @@ | ||||
| /* select filedescriptor handling, taken from: | ||||
|  * userspace logging daemon for the iptables ULOG target | ||||
|  * of the linux 2.4 netfilter subsystem. | ||||
|  * | ||||
|  * (C) 2000-2009 by Harald Welte <laforge@gnumonks.org> | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU General Public License version 2  | ||||
|  *  as published by the Free Software Foundation | ||||
|  * | ||||
|  *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
|  | ||||
| #include <fcntl.h> | ||||
| #include <osmocore/select.h> | ||||
| #include <osmocore/linuxlist.h> | ||||
| #include <osmocore/timer.h> | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #ifdef HAVE_SYS_SELECT_H | ||||
|  | ||||
| static int maxfd = 0; | ||||
| static LLIST_HEAD(bsc_fds); | ||||
| static int unregistered_count; | ||||
|  | ||||
| int bsc_register_fd(struct bsc_fd *fd) | ||||
| { | ||||
| 	int flags; | ||||
|  | ||||
| 	/* make FD nonblocking */ | ||||
| 	flags = fcntl(fd->fd, F_GETFL); | ||||
| 	if (flags < 0) | ||||
| 		return flags; | ||||
| 	flags |= O_NONBLOCK; | ||||
| 	flags = fcntl(fd->fd, F_SETFL, flags); | ||||
| 	if (flags < 0) | ||||
| 		return flags; | ||||
|  | ||||
| 	/* Register FD */ | ||||
| 	if (fd->fd > maxfd) | ||||
| 		maxfd = fd->fd; | ||||
|  | ||||
| 	llist_add_tail(&fd->list, &bsc_fds); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void bsc_unregister_fd(struct bsc_fd *fd) | ||||
| { | ||||
| 	unregistered_count++; | ||||
| 	llist_del(&fd->list); | ||||
| } | ||||
|  | ||||
| int bsc_select_main(int polling) | ||||
| { | ||||
| 	struct bsc_fd *ufd, *tmp; | ||||
| 	fd_set readset, writeset, exceptset; | ||||
| 	int work = 0, rc; | ||||
| 	struct timeval no_time = {0, 0}; | ||||
|  | ||||
| 	FD_ZERO(&readset); | ||||
| 	FD_ZERO(&writeset); | ||||
| 	FD_ZERO(&exceptset); | ||||
|  | ||||
| 	/* prepare read and write fdsets */ | ||||
| 	llist_for_each_entry(ufd, &bsc_fds, list) { | ||||
| 		if (ufd->when & BSC_FD_READ) | ||||
| 			FD_SET(ufd->fd, &readset); | ||||
|  | ||||
| 		if (ufd->when & BSC_FD_WRITE) | ||||
| 			FD_SET(ufd->fd, &writeset); | ||||
|  | ||||
| 		if (ufd->when & BSC_FD_EXCEPT) | ||||
| 			FD_SET(ufd->fd, &exceptset); | ||||
| 	} | ||||
|  | ||||
| 	bsc_timer_check(); | ||||
|  | ||||
| 	if (!polling) | ||||
| 		bsc_prepare_timers(); | ||||
| 	rc = select(maxfd+1, &readset, &writeset, &exceptset, polling ? &no_time : bsc_nearest_timer()); | ||||
| 	if (rc < 0) | ||||
| 		return 0; | ||||
|  | ||||
| 	/* fire timers */ | ||||
| 	bsc_update_timers(); | ||||
|  | ||||
| 	/* call registered callback functions */ | ||||
| restart: | ||||
| 	unregistered_count = 0; | ||||
| 	llist_for_each_entry_safe(ufd, tmp, &bsc_fds, list) { | ||||
| 		int flags = 0; | ||||
|  | ||||
| 		if (FD_ISSET(ufd->fd, &readset)) { | ||||
| 			flags |= BSC_FD_READ; | ||||
| 			FD_CLR(ufd->fd, &readset); | ||||
| 		} | ||||
|  | ||||
| 		if (FD_ISSET(ufd->fd, &writeset)) { | ||||
| 			flags |= BSC_FD_WRITE; | ||||
| 			FD_CLR(ufd->fd, &writeset); | ||||
| 		} | ||||
|  | ||||
| 		if (FD_ISSET(ufd->fd, &exceptset)) { | ||||
| 			flags |= BSC_FD_EXCEPT; | ||||
| 			FD_CLR(ufd->fd, &exceptset); | ||||
| 		} | ||||
|  | ||||
| 		if (flags) { | ||||
| 			work = 1; | ||||
| 			ufd->cb(ufd, flags); | ||||
| 		} | ||||
| 		/* ugly, ugly hack. If more than one filedescriptors were | ||||
| 		 * unregistered, they might have been consecutive and | ||||
| 		 * llist_for_each_entry_safe() is no longer safe */ | ||||
| 		if (unregistered_count > 1) | ||||
| 			goto restart; | ||||
| 	} | ||||
| 	return work; | ||||
| } | ||||
|  | ||||
| #endif /* _HAVE_SYS_SELECT_H */ | ||||
							
								
								
									
										84
									
								
								libosmocore/src/signal.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								libosmocore/src/signal.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /* Generic signalling/notification infrastructure */ | ||||
| /* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <osmocore/signal.h> | ||||
| #include <osmocore/talloc.h> | ||||
| #include <osmocore/linuxlist.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| void *tall_sigh_ctx; | ||||
| static LLIST_HEAD(signal_handler_list); | ||||
|  | ||||
| struct signal_handler { | ||||
| 	struct llist_head entry; | ||||
| 	unsigned int subsys; | ||||
| 	signal_cbfn *cbfn; | ||||
| 	void *data; | ||||
| }; | ||||
|  | ||||
|  | ||||
| int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data) | ||||
| { | ||||
| 	struct signal_handler *sig_data; | ||||
|  | ||||
| 	sig_data = talloc(tall_sigh_ctx, struct signal_handler); | ||||
| 	if (!sig_data) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	memset(sig_data, 0, sizeof(*sig_data)); | ||||
|  | ||||
| 	sig_data->subsys = subsys; | ||||
| 	sig_data->data = data; | ||||
| 	sig_data->cbfn = cbfn; | ||||
|  | ||||
| 	/* FIXME: check if we already have a handler for this subsys/cbfn/data */ | ||||
|  | ||||
| 	llist_add_tail(&sig_data->entry, &signal_handler_list); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data) | ||||
| { | ||||
| 	struct signal_handler *handler; | ||||
|  | ||||
| 	llist_for_each_entry(handler, &signal_handler_list, entry) { | ||||
| 		if (handler->cbfn == cbfn && handler->data == data  | ||||
| 		    && subsys == handler->subsys) { | ||||
| 			llist_del(&handler->entry); | ||||
| 			talloc_free(handler); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data) | ||||
| { | ||||
| 	struct signal_handler *handler; | ||||
|  | ||||
| 	llist_for_each_entry(handler, &signal_handler_list, entry) { | ||||
| 		if (handler->subsys != subsys) | ||||
| 			continue; | ||||
| 		(*handler->cbfn)(subsys, signal, handler->data, signal_data); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										66
									
								
								libosmocore/src/statistics.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								libosmocore/src/statistics.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| /* utility routines for keeping some statistics */ | ||||
|  | ||||
| /* (C) 2009 by Harald Welte <laforge@gnumonks.org> | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <sys/types.h> | ||||
|  | ||||
| #include <osmocore/linuxlist.h> | ||||
| #include <osmocore/talloc.h> | ||||
| #include <osmocore/statistics.h> | ||||
|  | ||||
| static LLIST_HEAD(counters); | ||||
|  | ||||
| void *tall_ctr_ctx; | ||||
|  | ||||
| struct counter *counter_alloc(const char *name) | ||||
| { | ||||
| 	struct counter *ctr = talloc_zero(tall_ctr_ctx, struct counter); | ||||
|  | ||||
| 	if (!ctr) | ||||
| 		return NULL; | ||||
|  | ||||
| 	ctr->name = name; | ||||
| 	llist_add_tail(&ctr->list, &counters); | ||||
|  | ||||
| 	return ctr; | ||||
| } | ||||
|  | ||||
| void counter_free(struct counter *ctr) | ||||
| { | ||||
| 	llist_del(&ctr->list); | ||||
| 	talloc_free(ctr); | ||||
| } | ||||
|  | ||||
| int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data) | ||||
| { | ||||
| 	struct counter *ctr; | ||||
| 	int rc = 0; | ||||
|  | ||||
| 	llist_for_each_entry(ctr, &counters, list) { | ||||
| 		rc = handle_counter(ctr, data); | ||||
| 		if (rc < 0) | ||||
| 			return rc; | ||||
| 	} | ||||
|  | ||||
| 	return rc; | ||||
| } | ||||
|  | ||||
							
								
								
									
										1805
									
								
								libosmocore/src/talloc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1805
									
								
								libosmocore/src/talloc.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										185
									
								
								libosmocore/src/timer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								libosmocore/src/timer.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,185 @@ | ||||
| /* | ||||
|  * (C) 2008,2009 by Holger Hans Peter Freyther <zecke@selfish.org> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <string.h> | ||||
| #include <osmocore/timer.h> | ||||
|  | ||||
| static LLIST_HEAD(timer_list); | ||||
| static struct timeval s_nearest_time; | ||||
| static struct timeval s_select_time; | ||||
|  | ||||
| #define MICRO_SECONDS  1000000LL | ||||
|  | ||||
| #define TIME_SMALLER(left, right) \ | ||||
|         (left.tv_sec*MICRO_SECONDS+left.tv_usec) <= (right.tv_sec*MICRO_SECONDS+right.tv_usec) | ||||
|  | ||||
| void bsc_add_timer(struct timer_list *timer) | ||||
| { | ||||
| 	struct timer_list *list_timer; | ||||
|  | ||||
| 	/* TODO: Optimize and remember the closest item... */ | ||||
| 	timer->active = 1; | ||||
|  | ||||
| 	/* this might be called from within update_timers */ | ||||
| 	llist_for_each_entry(list_timer, &timer_list, entry) | ||||
| 		if (timer == list_timer) | ||||
| 			return; | ||||
|  | ||||
| 	timer->in_list = 1; | ||||
| 	llist_add(&timer->entry, &timer_list); | ||||
| } | ||||
|  | ||||
| void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds) | ||||
| { | ||||
| 	struct timeval current_time; | ||||
|  | ||||
| 	gettimeofday(¤t_time, NULL); | ||||
| 	unsigned long long currentTime = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec; | ||||
| 	currentTime += seconds * MICRO_SECONDS + microseconds; | ||||
| 	timer->timeout.tv_sec = currentTime / MICRO_SECONDS; | ||||
| 	timer->timeout.tv_usec = currentTime % MICRO_SECONDS; | ||||
| 	bsc_add_timer(timer); | ||||
| } | ||||
|  | ||||
| void bsc_del_timer(struct timer_list *timer) | ||||
| { | ||||
| 	if (timer->in_list) { | ||||
| 		timer->active = 0; | ||||
| 		timer->in_list = 0; | ||||
| 		llist_del(&timer->entry); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int bsc_timer_pending(struct timer_list *timer) | ||||
| { | ||||
| 	return timer->active; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * if we have a nearest time return the delta between the current | ||||
|  * time and the time of the nearest timer. | ||||
|  * If the nearest timer timed out return NULL and then we will | ||||
|  * dispatch everything after the select | ||||
|  */ | ||||
| struct timeval *bsc_nearest_timer() | ||||
| { | ||||
| 	struct timeval current_time; | ||||
|  | ||||
| 	if (s_nearest_time.tv_sec == 0 && s_nearest_time.tv_usec == 0) | ||||
| 		return NULL; | ||||
|  | ||||
| 	if (gettimeofday(¤t_time, NULL) == -1) | ||||
| 		return NULL; | ||||
|  | ||||
| 	unsigned long long nearestTime = s_nearest_time.tv_sec * MICRO_SECONDS + s_nearest_time.tv_usec; | ||||
| 	unsigned long long currentTime = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec; | ||||
|  | ||||
| 	if (nearestTime < currentTime) { | ||||
| 		s_select_time.tv_sec = 0; | ||||
| 		s_select_time.tv_usec = 0; | ||||
| 	} else { | ||||
| 		s_select_time.tv_sec = (nearestTime - currentTime) / MICRO_SECONDS; | ||||
| 		s_select_time.tv_usec = (nearestTime - currentTime) % MICRO_SECONDS; | ||||
| 	} | ||||
|  | ||||
| 	return &s_select_time; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Find the nearest time and update s_nearest_time | ||||
|  */ | ||||
| void bsc_prepare_timers() | ||||
| { | ||||
| 	struct timer_list *timer, *nearest_timer = NULL; | ||||
| 	llist_for_each_entry(timer, &timer_list, entry) { | ||||
| 		if (!nearest_timer || TIME_SMALLER(timer->timeout, nearest_timer->timeout)) { | ||||
| 			nearest_timer = timer; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (nearest_timer) { | ||||
| 		s_nearest_time = nearest_timer->timeout; | ||||
| 	} else { | ||||
| 		memset(&s_nearest_time, 0, sizeof(struct timeval)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * fire all timers... and remove them | ||||
|  */ | ||||
| int bsc_update_timers() | ||||
| { | ||||
| 	struct timeval current_time; | ||||
| 	struct timer_list *timer, *tmp; | ||||
| 	int work = 0; | ||||
|  | ||||
| 	gettimeofday(¤t_time, NULL); | ||||
|  | ||||
| 	/* | ||||
| 	 * The callbacks might mess with our list and in this case | ||||
| 	 * even llist_for_each_entry_safe is not safe to use. To allow | ||||
| 	 * del_timer, add_timer, schedule_timer to be called from within | ||||
| 	 * the callback we jump through some loops. | ||||
| 	 * | ||||
| 	 * First we set the handled flag of each active timer to zero, | ||||
| 	 * then we iterate over the list and execute the callbacks. As the | ||||
| 	 * list might have been changed (specially the next) from within | ||||
| 	 * the callback we have to start over again. Once every callback | ||||
| 	 * is dispatched we will remove the non-active from the list. | ||||
| 	 * | ||||
| 	 * TODO: If this is a performance issue we can poison a global | ||||
| 	 * variable in add_timer and del_timer and only then restart. | ||||
| 	 */ | ||||
| 	llist_for_each_entry(timer, &timer_list, entry) { | ||||
| 		timer->handled = 0; | ||||
| 	} | ||||
|  | ||||
| restart: | ||||
| 	llist_for_each_entry(timer, &timer_list, entry) { | ||||
| 		if (!timer->handled && TIME_SMALLER(timer->timeout, current_time)) { | ||||
| 			timer->handled = 1; | ||||
| 			timer->active = 0; | ||||
| 			(*timer->cb)(timer->data); | ||||
| 			work = 1; | ||||
| 			goto restart; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	llist_for_each_entry_safe(timer, tmp, &timer_list, entry) { | ||||
| 		timer->handled = 0; | ||||
| 		if (!timer->active) { | ||||
| 			bsc_del_timer(timer); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return work; | ||||
| } | ||||
|  | ||||
| int bsc_timer_check(void) | ||||
| { | ||||
| 	struct timer_list *timer; | ||||
| 	int i = 0; | ||||
|  | ||||
| 	llist_for_each_entry(timer, &timer_list, entry) { | ||||
| 		i++; | ||||
| 	} | ||||
| 	return i; | ||||
| } | ||||
							
								
								
									
										171
									
								
								libosmocore/src/tlv_parser.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								libosmocore/src/tlv_parser.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <osmocore/utils.h> | ||||
| #include <osmocore/tlv.h> | ||||
|  | ||||
| struct tlv_definition tvlv_att_def; | ||||
|  | ||||
| int tlv_dump(struct tlv_parsed *dec) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0; i <= 0xff; i++) { | ||||
| 		if (!dec->lv[i].val) | ||||
| 			continue; | ||||
| 		printf("T=%02x L=%d\n", i, dec->lv[i].len); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* o_tag:  output: tag found | ||||
|  * o_len:  output: length of the data | ||||
|  * o_val:  output: pointer to the data | ||||
|  * def:     input: a structure defining the valid TLV tags / configurations | ||||
|  * buf:     input: the input data buffer to be parsed | ||||
|  * buf_len: input: the length of the input data buffer | ||||
|  * | ||||
|  * Also, returns the number of bytes consumed by the TLV entry | ||||
|  */ | ||||
| int tlv_parse_one(uint8_t *o_tag, uint16_t *o_len, const uint8_t **o_val, | ||||
| 		  const struct tlv_definition *def, | ||||
| 		  const uint8_t *buf, int buf_len) | ||||
| { | ||||
| 	uint8_t tag; | ||||
| 	int len; | ||||
|  | ||||
| 	tag = *buf; | ||||
| 	*o_tag = tag; | ||||
|  | ||||
| 	/* FIXME: use tables for knwon IEI */ | ||||
| 	switch (def->def[tag].type) { | ||||
| 	case TLV_TYPE_T: | ||||
| 		/* GSM TS 04.07 11.2.4: Type 1 TV or Type 2 T */ | ||||
| 		*o_val = buf; | ||||
| 		*o_len = 0; | ||||
| 		len = 1; | ||||
| 		break; | ||||
| 	case TLV_TYPE_TV: | ||||
| 		*o_val = buf+1; | ||||
| 		*o_len = 1; | ||||
| 		len = 2; | ||||
| 		break; | ||||
| 	case TLV_TYPE_FIXED: | ||||
| 		*o_val = buf+1; | ||||
| 		*o_len = def->def[tag].fixed_len; | ||||
| 		len = def->def[tag].fixed_len + 1; | ||||
| 		break; | ||||
| 	case TLV_TYPE_TLV: | ||||
| 		/* GSM TS 04.07 11.2.4: Type 4 TLV */ | ||||
| 		if (buf + 1 > buf + buf_len) | ||||
| 			return -1; | ||||
| 		*o_val = buf+2; | ||||
| 		*o_len = *(buf+1); | ||||
| 		len = *o_len + 2; | ||||
| 		if (len > buf_len) | ||||
| 			return -2; | ||||
| 		break; | ||||
| 	case TLV_TYPE_TvLV: | ||||
| 		if (*(buf+1) & 0x80) { | ||||
| 			/* like TLV, but without highest bit of len */ | ||||
| 			if (buf + 1 > buf + buf_len) | ||||
| 				return -1; | ||||
| 			*o_val = buf+2; | ||||
| 			*o_len = *(buf+1) & 0x7f; | ||||
| 			len = *o_len + 2; | ||||
| 			if (len > buf_len) | ||||
| 				return -2; | ||||
| 			break; | ||||
| 		} | ||||
| 		/* like TL16V, fallthrough */ | ||||
| 	case TLV_TYPE_TL16V: | ||||
| 		if (2 > buf_len) | ||||
| 			return -1; | ||||
| 		*o_val = buf+3; | ||||
| 		*o_len = *(buf+1) << 8 | *(buf+2); | ||||
| 		len = *o_len + 3; | ||||
| 		if (len > buf_len) | ||||
| 			return -2; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return -3; | ||||
| 	} | ||||
|  | ||||
| 	return len; | ||||
| } | ||||
|  | ||||
| /* dec:    output: a caller-allocated pointer to a struct tlv_parsed, | ||||
|  * def:     input: a structure defining the valid TLV tags / configurations | ||||
|  * buf:     input: the input data buffer to be parsed | ||||
|  * buf_len: input: the length of the input data buffer | ||||
|  * lv_tag:  input: an initial LV tag at the start of the buffer | ||||
|  * lv_tag2: input: a second initial LV tag following lv_tag  | ||||
|  */ | ||||
| int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def, | ||||
| 	      const uint8_t *buf, int buf_len, uint8_t lv_tag, | ||||
| 	      uint8_t lv_tag2) | ||||
| { | ||||
| 	int ofs = 0, num_parsed = 0; | ||||
| 	uint16_t len; | ||||
|  | ||||
| 	memset(dec, 0, sizeof(*dec)); | ||||
|  | ||||
| 	if (lv_tag) { | ||||
| 		if (ofs > buf_len) | ||||
| 			return -1; | ||||
| 		dec->lv[lv_tag].val = &buf[ofs+1]; | ||||
| 		dec->lv[lv_tag].len = buf[ofs]; | ||||
| 		len = dec->lv[lv_tag].len + 1; | ||||
| 		if (ofs + len > buf_len) | ||||
| 			return -2; | ||||
| 		num_parsed++; | ||||
| 		ofs += len; | ||||
| 	} | ||||
| 	if (lv_tag2) { | ||||
| 		if (ofs > buf_len) | ||||
| 			return -1; | ||||
| 		dec->lv[lv_tag2].val = &buf[ofs+1]; | ||||
| 		dec->lv[lv_tag2].len = buf[ofs]; | ||||
| 		len = dec->lv[lv_tag2].len + 1; | ||||
| 		if (ofs + len > buf_len) | ||||
| 			return -2; | ||||
| 		num_parsed++; | ||||
| 		ofs += len; | ||||
| 	} | ||||
|  | ||||
| 	while (ofs < buf_len) { | ||||
| 		int rv; | ||||
| 		uint8_t tag; | ||||
| 		const uint8_t *val; | ||||
|  | ||||
| 		rv = tlv_parse_one(&tag, &len, &val, def, | ||||
| 		                   &buf[ofs], buf_len-ofs); | ||||
| 		if (rv < 0) | ||||
| 			return rv; | ||||
| 		dec->lv[tag].val = val; | ||||
| 		dec->lv[tag].len = len; | ||||
| 		ofs += rv; | ||||
| 		num_parsed++; | ||||
| 	} | ||||
| 	//tlv_dump(dec); | ||||
| 	return num_parsed; | ||||
| } | ||||
|  | ||||
| /* take a master (src) tlvdev and fill up all empty slots in 'dst' */ | ||||
| void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_SIZE(dst->def); i++) { | ||||
| 		if (src->def[i].type == TLV_TYPE_NONE) | ||||
| 			continue; | ||||
| 		if (dst->def[i].type == TLV_TYPE_NONE) | ||||
| 			dst->def[i] = src->def[i]; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static __attribute__((constructor)) void on_dso_load_tlv(void) | ||||
| { | ||||
| 	int i; | ||||
| 	for (i = 0; i < ARRAY_SIZE(tvlv_att_def.def); i++) | ||||
| 		tvlv_att_def.def[i].type = TLV_TYPE_TvLV; | ||||
| } | ||||
							
								
								
									
										50
									
								
								libosmocore/src/utils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								libosmocore/src/utils.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
|  | ||||
| #include <string.h> | ||||
| #include <stdint.h> | ||||
| #include <errno.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include <osmocore/utils.h> | ||||
|  | ||||
| static char namebuf[255]; | ||||
| const char *get_value_string(const struct value_string *vs, uint32_t val) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0;; i++) { | ||||
| 		if (vs[i].value == 0 && vs[i].str == NULL) | ||||
| 			break; | ||||
| 		if (vs[i].value == val) | ||||
| 			return vs[i].str; | ||||
| 	} | ||||
|  | ||||
| 	snprintf(namebuf, sizeof(namebuf), "unknown 0x%x", val); | ||||
| 	return namebuf; | ||||
| } | ||||
|  | ||||
| int get_string_value(const struct value_string *vs, const char *str) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0;; i++) { | ||||
| 		if (vs[i].value == 0 && vs[i].str == NULL) | ||||
| 			break; | ||||
| 		if (!strcasecmp(vs[i].str, str)) | ||||
| 			return vs[i].value; | ||||
| 	} | ||||
| 	return -EINVAL; | ||||
| } | ||||
|  | ||||
| char bcd2char(uint8_t bcd) | ||||
| { | ||||
| 	if (bcd < 0xa) | ||||
| 		return '0' + bcd; | ||||
| 	else | ||||
| 		return 'A' + (bcd - 0xa); | ||||
| } | ||||
|  | ||||
| /* only works for numbers in ascci */ | ||||
| uint8_t char2bcd(char c) | ||||
| { | ||||
| 	return c - 0x30; | ||||
| } | ||||
							
								
								
									
										85
									
								
								libosmocore/src/write_queue.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								libosmocore/src/write_queue.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| /* Generic write queue implementation */ | ||||
| /* | ||||
|  * (C) 2010 by Holger Hans Peter Freyther | ||||
|  * (C) 2010 by On-Waves | ||||
|  * | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <osmocore/write_queue.h> | ||||
|  | ||||
| int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what) | ||||
| { | ||||
| 	struct write_queue *queue; | ||||
|  | ||||
| 	queue = container_of(fd, struct write_queue, bfd); | ||||
|  | ||||
| 	if (what & BSC_FD_READ) | ||||
| 		queue->read_cb(fd); | ||||
|  | ||||
| 	if (what & BSC_FD_WRITE) { | ||||
| 		struct msgb *msg; | ||||
|  | ||||
| 		fd->when &= ~BSC_FD_WRITE; | ||||
| 		msg = msgb_dequeue(&queue->msg_queue); | ||||
| 		if (!msg) | ||||
| 			return -1; | ||||
|  | ||||
| 		--queue->current_length; | ||||
| 		queue->write_cb(fd, msg); | ||||
| 		msgb_free(msg); | ||||
|  | ||||
| 		if (!llist_empty(&queue->msg_queue)) | ||||
| 			fd->when |= BSC_FD_WRITE; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void write_queue_init(struct write_queue *queue, int max_length) | ||||
| { | ||||
| 	queue->max_length = max_length; | ||||
| 	queue->current_length = 0; | ||||
| 	queue->read_cb = NULL; | ||||
| 	queue->write_cb = NULL; | ||||
| 	queue->bfd.cb = write_queue_bfd_cb; | ||||
| 	INIT_LLIST_HEAD(&queue->msg_queue); | ||||
| } | ||||
|  | ||||
| int write_queue_enqueue(struct write_queue *queue, struct msgb *data) | ||||
| { | ||||
| //	if (queue->current_length + 1 >= queue->max_length) | ||||
| //		LOGP(DMSC, LOGL_ERROR, "The queue is full. Dropping not yet implemented.\n"); | ||||
|  | ||||
| 	++queue->current_length; | ||||
| 	msgb_enqueue(&queue->msg_queue, data); | ||||
| 	queue->bfd.when |= BSC_FD_WRITE; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void write_queue_clear(struct write_queue *queue) | ||||
| { | ||||
| 	while (!llist_empty(&queue->msg_queue)) { | ||||
| 		struct msgb *msg = msgb_dequeue(&queue->msg_queue); | ||||
| 		msgb_free(msg); | ||||
| 	} | ||||
|  | ||||
| 	queue->current_length = 0; | ||||
| 	queue->bfd.when &= ~BSC_FD_WRITE; | ||||
| } | ||||
							
								
								
									
										3
									
								
								libosmocore/tests/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								libosmocore/tests/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| if ENABLE_TESTS | ||||
| SUBDIRS = timer sms | ||||
| endif | ||||
							
								
								
									
										5
									
								
								libosmocore/tests/sms/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								libosmocore/tests/sms/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| INCLUDES = $(all_includes) -I$(top_srcdir)/include | ||||
| noinst_PROGRAMS = sms_test | ||||
|  | ||||
| sms_test_SOURCES = sms_test.c | ||||
| sms_test_LDADD = $(top_builddir)/src/libosmocore.la | ||||
							
								
								
									
										47
									
								
								libosmocore/tests/sms/sms_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								libosmocore/tests/sms/sms_test.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| /* | ||||
|  * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/types.h> | ||||
| #include <osmocore/msgb.h> | ||||
| #include <osmocore/gsm_utils.h> | ||||
|  | ||||
| int main(int argc, char** argv) | ||||
| { | ||||
| 	printf("SMS testing\n"); | ||||
| 	struct msgb *msg; | ||||
| 	uint8_t *sms; | ||||
| 	uint8_t i; | ||||
|  | ||||
|         /* test 7-bit coding/decoding */ | ||||
| 	const char *input = "test text"; | ||||
| 	uint8_t length; | ||||
| 	uint8_t coded[256]; | ||||
| 	char result[256]; | ||||
|  | ||||
| 	length = gsm_7bit_encode(coded, input); | ||||
| 	gsm_7bit_decode(result, coded, length); | ||||
| 	if (strcmp(result, input) != 0) { | ||||
| 		printf("7 Bit coding failed... life sucks\n"); | ||||
| 		printf("Wanted: '%s' got '%s'\n", input, result); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										6
									
								
								libosmocore/tests/timer/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								libosmocore/tests/timer/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| INCLUDES = $(all_includes) -I$(top_srcdir)/include | ||||
| noinst_PROGRAMS = timer_test | ||||
|  | ||||
| timer_test_SOURCES = timer_test.c | ||||
| timer_test_LDADD = $(top_builddir)/src/libosmocore.la | ||||
|  | ||||
							
								
								
									
										77
									
								
								libosmocore/tests/timer/timer_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								libosmocore/tests/timer/timer_test.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| /* | ||||
|  * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org> | ||||
|  * All Rights Reserved | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include <osmocore/timer.h> | ||||
| #include <osmocore/select.h> | ||||
|  | ||||
| #include "../../config.h" | ||||
|  | ||||
| static void timer_fired(void *data); | ||||
|  | ||||
| static struct timer_list timer_one = { | ||||
|     .cb = timer_fired, | ||||
|     .data = (void*)1, | ||||
| }; | ||||
|  | ||||
| static struct timer_list timer_two = { | ||||
|     .cb = timer_fired, | ||||
|     .data = (void*)2, | ||||
| }; | ||||
|  | ||||
| static struct timer_list timer_three = { | ||||
|     .cb = timer_fired, | ||||
|     .data = (void*)3, | ||||
| }; | ||||
|  | ||||
| static void timer_fired(void *_data) | ||||
| { | ||||
|     unsigned long data = (unsigned long) _data; | ||||
|     printf("Fired timer: %lu\n", data); | ||||
|  | ||||
|     if (data == 1) { | ||||
|         bsc_schedule_timer(&timer_one, 3, 0); | ||||
|         bsc_del_timer(&timer_two); | ||||
|     } else if (data == 2) { | ||||
|         printf("Should not be fired... bug in del_timer\n"); | ||||
|     } else if (data == 3) { | ||||
|         printf("Timer fired not registering again\n"); | ||||
|     } else  { | ||||
|         printf("wtf... wrong data\n"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| int main(int argc, char** argv) | ||||
| { | ||||
|     printf("Starting... timer\n"); | ||||
|  | ||||
|     bsc_schedule_timer(&timer_one, 3, 0); | ||||
|     bsc_schedule_timer(&timer_two, 5, 0); | ||||
|     bsc_schedule_timer(&timer_three, 4, 0); | ||||
|  | ||||
| #ifdef HAVE_SYS_SELECT_H | ||||
|     while (1) { | ||||
|         bsc_select_main(0); | ||||
|     } | ||||
| #else | ||||
|     printf("Select not supported on this platform!\n"); | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										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++; | ||||
|  	} | ||||
|   | ||||
							
								
								
									
										73
									
								
								openbsc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										73
									
								
								openbsc/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,4 @@ | ||||
| *.o | ||||
| *.lo | ||||
| *.a | ||||
| .deps | ||||
| Makefile | ||||
| @@ -7,36 +6,22 @@ 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 | ||||
| bsc_mgcp | ||||
| *.*~ | ||||
| *.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 | ||||
| @@ -45,59 +30,19 @@ ltmain.sh | ||||
|  | ||||
| # 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 | ||||
| ipaccess-firmware | ||||
| ipaccess-proxy | ||||
| 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 | ||||
|   | ||||
| @@ -5,5 +5,3 @@ 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,25 +1,12 @@ | ||||
| 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 | ||||
| pkgconfig_DATA = openbsc.pc libsccp.pc | ||||
|  | ||||
| BUILT_SOURCES = $(top_srcdir)/.version | ||||
| EXTRA_DIST = git-version-gen osmoappdesc.py .version | ||||
| $(top_srcdir)/.version: | ||||
| 	echo $(VERSION) > $@-t && mv $@-t $@ | ||||
| dist-hook: | ||||
|   | ||||
| @@ -1,39 +1,30 @@ | ||||
| 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 and SMSC. | ||||
|  | ||||
|  * 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 | ||||
|  | ||||
| Various interfaces towards the BTS are supported, among which are: | ||||
| Its currently supported interfaces towards the BTS are: | ||||
|  | ||||
|  * 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. | ||||
|    through E1 to OpenBSC.  So far, we have only tested the Siemens BS-11 | ||||
|    Test reports with other BTS are much appreciated! | ||||
|  | ||||
|  * A-bis over IP as used by the ip.access nanoBTS product family 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. | ||||
|  * A-bis over IP as used by the ip.access nanoBTS product family | ||||
|  | ||||
|  * 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. | ||||
|  | ||||
| 	Harald Welte <laforge@gnumonks.org> | ||||
|  | ||||
|  | ||||
| libosmocore | ||||
| =========== | ||||
|  | ||||
| Please note that as of March 2010, OpenBSC has a dependency to a library | ||||
| called "libosmocore".  You can obtain that library from | ||||
|  | ||||
| 	git://git.osmocom.org/libosmocore.git | ||||
|  | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user