mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-bts.git
				synced 2025-11-04 06:03:26 +00:00 
			
		
		
		
	Compare commits
	
		
			323 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7db79cc39a | ||
| 
						 | 
					8d11671539 | ||
| 
						 | 
					cb5b10e7b7 | ||
| 
						 | 
					d9b456ce6d | ||
| 
						 | 
					a9f3c01ece | ||
| 
						 | 
					799ad7240b | ||
| 
						 | 
					d4bb8d61e7 | ||
| 
						 | 
					aa743cd97e | ||
| 
						 | 
					65c497a69a | ||
| 
						 | 
					b032208a4a | ||
| 
						 | 
					c963f0b6eb | ||
| 
						 | 
					a7b3a780ae | ||
| 
						 | 
					62b37b32f9 | ||
| 
						 | 
					c211b34955 | ||
| 
						 | 
					88f03f8d1d | ||
| 
						 | 
					c8946a077e | ||
| 
						 | 
					8797837deb | ||
| 
						 | 
					5bd8543a5f | ||
| 
						 | 
					7b712121b8 | ||
| 
						 | 
					f33e3c8378 | ||
| 
						 | 
					ff4b83dc23 | ||
| 
						 | 
					64d9f142ab | ||
| 
						 | 
					4af496d44c | ||
| 
						 | 
					6f9ccafde4 | ||
| 
						 | 
					a928fce659 | ||
| 
						 | 
					0a34af1530 | ||
| 
						 | 
					02951e4af3 | ||
| 
						 | 
					7accf7579d | ||
| 
						 | 
					5bed286c6c | ||
| 
						 | 
					414e1ca8ed | ||
| 
						 | 
					c40e75277f | ||
| 
						 | 
					59686cd276 | ||
| 
						 | 
					82d500ccac | ||
| 
						 | 
					aeb78dcc77 | ||
| 
						 | 
					a880011a5f | ||
| 
						 | 
					89415e7433 | ||
| 
						 | 
					332976672e | ||
| 
						 | 
					9512355ebc | ||
| 
						 | 
					2d9643f2ce | ||
| 
						 | 
					8c060ccc5f | ||
| 
						 | 
					3750c36f40 | ||
| 
						 | 
					2849b1e0f0 | ||
| 
						 | 
					152d8e5b8a | ||
| 
						 | 
					9c6c6b043b | ||
| 
						 | 
					5076fef0ec | ||
| 
						 | 
					e01cf27678 | ||
| 
						 | 
					b7aa08f69b | ||
| 
						 | 
					36e4fb63b8 | ||
| 
						 | 
					076324446d | ||
| 
						 | 
					18e5eb668e | ||
| 
						 | 
					38dbebc48c | ||
| 
						 | 
					65337b739a | ||
| 
						 | 
					3c09964b11 | ||
| 
						 | 
					798b28728b | ||
| 
						 | 
					aec0422c8f | ||
| 
						 | 
					3c133dc386 | ||
| 
						 | 
					3af73977dd | ||
| 
						 | 
					a7263b6474 | ||
| 
						 | 
					82a2a8d9b4 | ||
| 
						 | 
					e94553a547 | ||
| 
						 | 
					088f4ffd57 | ||
| 
						 | 
					950ed8bc4d | ||
| 
						 | 
					59c641d20e | ||
| 
						 | 
					1f755bcfee | ||
| 
						 | 
					7786d9b673 | ||
| 
						 | 
					f60f45e7ab | ||
| 
						 | 
					722767a49d | ||
| 
						 | 
					90f6ebcd3b | ||
| 
						 | 
					17fe7d6841 | ||
| 
						 | 
					1013ca3b8b | ||
| 
						 | 
					647b8d0978 | ||
| 
						 | 
					bc6cc67115 | ||
| 
						 | 
					bc4ca18a31 | ||
| 
						 | 
					4a6a2fdf7e | ||
| 
						 | 
					28b8759465 | ||
| 
						 | 
					25aae40e17 | ||
| 
						 | 
					dc3b78da01 | ||
| 
						 | 
					7c76630024 | ||
| 
						 | 
					bcb9875176 | ||
| 
						 | 
					863d4d933e | ||
| 
						 | 
					791d121bd9 | ||
| 
						 | 
					771e9f2838 | ||
| 
						 | 
					e5d8a469d2 | ||
| 
						 | 
					8fafc1a74c | ||
| 
						 | 
					d88cc624ed | ||
| 
						 | 
					bd777b0276 | ||
| 
						 | 
					3bd97d839e | ||
| 
						 | 
					6ed4a9a1eb | ||
| 
						 | 
					d265ce68b2 | ||
| 
						 | 
					586e897eea | ||
| 
						 | 
					955b7dc637 | ||
| 
						 | 
					695080745c | ||
| 
						 | 
					fe005cb76e | ||
| 
						 | 
					b960c7558a | ||
| 
						 | 
					b8a185cc12 | ||
| 
						 | 
					08f058789f | ||
| 
						 | 
					8bff3b6898 | ||
| 
						 | 
					aaa1f26e52 | ||
| 
						 | 
					40ba43a2e8 | ||
| 
						 | 
					c6211a8bec | ||
| 
						 | 
					aa06f97326 | ||
| 
						 | 
					188f76275a | ||
| 
						 | 
					ddc15996dd | ||
| 
						 | 
					f5c1cd3889 | ||
| 
						 | 
					0978d1df71 | ||
| 
						 | 
					852b2cbadc | ||
| 
						 | 
					c4e836838d | ||
| 
						 | 
					9aaaacc7aa | ||
| 
						 | 
					9d9d9e2f27 | ||
| 
						 | 
					fbd8aa8a77 | ||
| 
						 | 
					e8518ae375 | ||
| 
						 | 
					fd4654e1b8 | ||
| 
						 | 
					e97834f2db | ||
| 
						 | 
					8a1f740dfc | ||
| 
						 | 
					1d53d231da | ||
| 
						 | 
					d2d938c261 | ||
| 
						 | 
					f20e13d160 | ||
| 
						 | 
					55a21dc1c3 | ||
| 
						 | 
					b33502a39b | ||
| 
						 | 
					183c088864 | ||
| 
						 | 
					37e639cb8f | ||
| 
						 | 
					7e5a62e9f3 | ||
| 
						 | 
					9171e37aff | ||
| 
						 | 
					086b46a77f | ||
| 
						 | 
					ff085f63c9 | ||
| 
						 | 
					bbb3a1ed17 | ||
| 
						 | 
					88de4d6789 | ||
| 
						 | 
					66eae187b9 | ||
| 
						 | 
					8ae829cabc | ||
| 
						 | 
					007e72d5bc | ||
| 
						 | 
					ca418643b3 | ||
| 
						 | 
					d1f8f3429c | ||
| 
						 | 
					97d3bd3e62 | ||
| 
						 | 
					467d63e387 | ||
| 
						 | 
					be93b87a64 | ||
| 
						 | 
					ba5d2e4a5f | ||
| 
						 | 
					0a2b0a20b3 | ||
| 
						 | 
					290085787a | ||
| 
						 | 
					6fa1dfce61 | ||
| 
						 | 
					65c8f0de94 | ||
| 
						 | 
					98e5d6f7c6 | ||
| 
						 | 
					29fcae8632 | ||
| 
						 | 
					fa90ff3e67 | ||
| 
						 | 
					15330e2368 | ||
| 
						 | 
					cdbd83affd | ||
| 
						 | 
					2ae45aba3f | ||
| 
						 | 
					6c83527e62 | ||
| 
						 | 
					d04e3e708b | ||
| 
						 | 
					4344f323f2 | ||
| 
						 | 
					17087a08c7 | ||
| 
						 | 
					f2c902c2af | ||
| 
						 | 
					bb596dddc7 | ||
| 
						 | 
					4bbfb904b8 | ||
| 
						 | 
					deef79ffae | ||
| 
						 | 
					95407f3f63 | ||
| 
						 | 
					f3a63758d1 | ||
| 
						 | 
					34077236f2 | ||
| 
						 | 
					d53a084fd6 | ||
| 
						 | 
					2bdb2201f6 | ||
| 
						 | 
					84d220abc1 | ||
| 
						 | 
					34838ee4e9 | ||
| 
						 | 
					44c94fdeae | ||
| 
						 | 
					f0510b6207 | ||
| 
						 | 
					3480a2ab4c | ||
| 
						 | 
					ad15414fd9 | ||
| 
						 | 
					f98a55b713 | ||
| 
						 | 
					1f5fdf8c8d | ||
| 
						 | 
					d78968422f | ||
| 
						 | 
					c860309aea | ||
| 
						 | 
					5c1401d6f3 | ||
| 
						 | 
					477fb3d9a4 | ||
| 
						 | 
					e5c2bc346b | ||
| 
						 | 
					c938a95e25 | ||
| 
						 | 
					4c3b4e2868 | ||
| 
						 | 
					676e9e5804 | ||
| 
						 | 
					f0f91fc66c | ||
| 
						 | 
					805340cb9c | ||
| 
						 | 
					81ebfb34b4 | ||
| 
						 | 
					07c3d86356 | ||
| 
						 | 
					34ab6f1470 | ||
| 
						 | 
					235d2bfbc4 | ||
| 
						 | 
					fd544caae1 | ||
| 
						 | 
					3f9e507d77 | ||
| 
						 | 
					b2c6b68a10 | ||
| 
						 | 
					c9a8eca543 | ||
| 
						 | 
					9b5721b3fb | ||
| 
						 | 
					194d1e8bc2 | ||
| 
						 | 
					282c87ab2d | ||
| 
						 | 
					785e731def | ||
| 
						 | 
					592030eee7 | ||
| 
						 | 
					3302d4adfe | ||
| 
						 | 
					405368b697 | ||
| 
						 | 
					1dd710944f | ||
| 
						 | 
					a84b9a0261 | ||
| 
						 | 
					d9de1a5b28 | ||
| 
						 | 
					a0770250bc | ||
| 
						 | 
					c18f9f256c | ||
| 
						 | 
					44d47b2cdd | ||
| 
						 | 
					4b945ec327 | ||
| 
						 | 
					1160cabefb | ||
| 
						 | 
					208127986e | ||
| 
						 | 
					05b4629166 | ||
| 
						 | 
					9cc85c1a6a | ||
| 
						 | 
					2c511d5755 | ||
| 
						 | 
					0eb90a0a98 | ||
| 
						 | 
					7f03444d8b | ||
| 
						 | 
					81cfbb10cb | ||
| 
						 | 
					e38618f7cc | ||
| 
						 | 
					5755946beb | ||
| 
						 | 
					8b306b6f93 | ||
| 
						 | 
					267c2606ad | ||
| 
						 | 
					04a373cf6a | ||
| 
						 | 
					3f5a343098 | ||
| 
						 | 
					2a60cc3087 | ||
| 
						 | 
					acaf6c563b | ||
| 
						 | 
					dfd6224484 | ||
| 
						 | 
					8b535ee77a | ||
| 
						 | 
					cf8736e916 | ||
| 
						 | 
					204cd4d7e3 | ||
| 
						 | 
					1d7133e936 | ||
| 
						 | 
					a4a9c28f15 | ||
| 
						 | 
					f729ff970a | ||
| 
						 | 
					bbdb10ee48 | ||
| 
						 | 
					ac1eb71d78 | ||
| 
						 | 
					11ec99d419 | ||
| 
						 | 
					fad8986f06 | ||
| 
						 | 
					b96d975f7d | ||
| 
						 | 
					30601ccaf4 | ||
| 
						 | 
					a1927f32f7 | ||
| 
						 | 
					be18d2b275 | ||
| 
						 | 
					cb0c0dfa15 | ||
| 
						 | 
					8a21e7c27a | ||
| 
						 | 
					4c56bed4d7 | ||
| 
						 | 
					31c759165a | ||
| 
						 | 
					38491d813b | ||
| 
						 | 
					1dc9e3f2f8 | ||
| 
						 | 
					b07e19d185 | ||
| 
						 | 
					c3e059ce04 | ||
| 
						 | 
					36ef885a6c | ||
| 
						 | 
					7cd45a7cfe | ||
| 
						 | 
					6be13437b7 | ||
| 
						 | 
					3481dd40b3 | ||
| 
						 | 
					66543fe422 | ||
| 
						 | 
					c3d839be9e | ||
| 
						 | 
					5b75e5dc8d | ||
| 
						 | 
					9c4b472179 | ||
| 
						 | 
					10d5499d03 | ||
| 
						 | 
					d50d239914 | ||
| 
						 | 
					989d99ca00 | ||
| 
						 | 
					633bbf174a | ||
| 
						 | 
					4190537d7d | ||
| 
						 | 
					cea6c230ad | ||
| 
						 | 
					92d1d1582b | ||
| 
						 | 
					f4505f6caf | ||
| 
						 | 
					91a1295a5a | ||
| 
						 | 
					8894fe6f4c | ||
| 
						 | 
					aebd2a21b5 | ||
| 
						 | 
					8c397da917 | ||
| 
						 | 
					c4a17d35ec | ||
| 
						 | 
					c12bc93db8 | ||
| 
						 | 
					7a646f963b | ||
| 
						 | 
					914e55caf3 | ||
| 
						 | 
					0350824203 | ||
| 
						 | 
					4ff6888a81 | ||
| 
						 | 
					5f556af232 | ||
| 
						 | 
					909d943fe8 | ||
| 
						 | 
					1266c068d7 | ||
| 
						 | 
					61e7fdbb3f | ||
| 
						 | 
					50710f4e8e | ||
| 
						 | 
					acf0f0f0bb | ||
| 
						 | 
					f06b959c7d | ||
| 
						 | 
					2551882c1c | ||
| 
						 | 
					96263aa908 | ||
| 
						 | 
					362f2e50c2 | ||
| 
						 | 
					3d2c107922 | ||
| 
						 | 
					9584980ea2 | ||
| 
						 | 
					80c605dd0b | ||
| 
						 | 
					c29ca5eb7d | ||
| 
						 | 
					32682c63f6 | ||
| 
						 | 
					e1e204fae3 | ||
| 
						 | 
					ac23ce2e03 | ||
| 
						 | 
					c17697d337 | ||
| 
						 | 
					bb3ed23e71 | ||
| 
						 | 
					a563640f86 | ||
| 
						 | 
					61b005193c | ||
| 
						 | 
					d47d288630 | ||
| 
						 | 
					e464ef6524 | ||
| 
						 | 
					dbd70bca75 | ||
| 
						 | 
					8fe6479358 | ||
| 
						 | 
					8e04613e4f | ||
| 
						 | 
					e7085d1699 | ||
| 
						 | 
					ef9b27526c | ||
| 
						 | 
					4bdc5a74cc | ||
| 
						 | 
					767f690f05 | ||
| 
						 | 
					48b00783f8 | ||
| 
						 | 
					c88ed31d9e | ||
| 
						 | 
					149de0c113 | ||
| 
						 | 
					ca72961bbd | ||
| 
						 | 
					50de553a1f | ||
| 
						 | 
					c1909e7258 | ||
| 
						 | 
					729037de0a | ||
| 
						 | 
					33956215a7 | ||
| 
						 | 
					f162fa9009 | ||
| 
						 | 
					9b88fd8481 | ||
| 
						 | 
					61933e6a7a | ||
| 
						 | 
					a023df5c7f | ||
| 
						 | 
					a21545e374 | ||
| 
						 | 
					72f991f541 | ||
| 
						 | 
					a981e28128 | ||
| 
						 | 
					c48b4651a1 | ||
| 
						 | 
					fa109255ac | ||
| 
						 | 
					69bca44a84 | ||
| 
						 | 
					54840a203b | ||
| 
						 | 
					66bcdd839c | ||
| 
						 | 
					cc13ea8b66 | ||
| 
						 | 
					bdc438299b | ||
| 
						 | 
					f19f533139 | ||
| 
						 | 
					af9466159e | ||
| 
						 | 
					633c09ee50 | ||
| 
						 | 
					dfe96b786f | ||
| 
						 | 
					d28ce3287f | ||
| 
						 | 
					495cf39cb9 | ||
| 
						 | 
					2f6e105956 | 
							
								
								
									
										1
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
open_collective: osmocom
 | 
			
		||||
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -55,6 +55,7 @@ src/osmo-bts-oc2g/misc/.dirstamp
 | 
			
		||||
tests/atconfig
 | 
			
		||||
tests/package.m4
 | 
			
		||||
tests/amr/amr_test
 | 
			
		||||
tests/csd/csd_test
 | 
			
		||||
tests/agch/agch_test
 | 
			
		||||
tests/paging/paging_test
 | 
			
		||||
tests/cipher/cipher_test
 | 
			
		||||
@@ -93,6 +94,7 @@ debian/tmp/
 | 
			
		||||
doc/manuals/*.html
 | 
			
		||||
doc/manuals/*.svg
 | 
			
		||||
doc/manuals/*.pdf
 | 
			
		||||
doc/manuals/vty/*.pdf
 | 
			
		||||
doc/manuals/*__*.png
 | 
			
		||||
doc/manuals/*.check
 | 
			
		||||
doc/manuals/generated/
 | 
			
		||||
@@ -104,3 +106,7 @@ doc/manuals/common
 | 
			
		||||
doc/manuals/build
 | 
			
		||||
 | 
			
		||||
contrib/osmo-bts.spec
 | 
			
		||||
contrib/ber/rtp_ber
 | 
			
		||||
contrib/ber/rtp_gen_map
 | 
			
		||||
 | 
			
		||||
arm-poky-linux-gnueabi-libtool
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,6 @@ EXTRA_DIST = \
 | 
			
		||||
	.version \
 | 
			
		||||
	README.md \
 | 
			
		||||
	contrib/dump_docs.py \
 | 
			
		||||
	contrib/osmo-bts.spec.in \
 | 
			
		||||
	debian \
 | 
			
		||||
	git-version-gen \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								README.md
									
									
									
									
									
								
							@@ -57,6 +57,13 @@ There also is an
 | 
			
		||||
[Abis reference Manual](https://ftp.osmocom.org/docs/latest/osmobts-abis.pdf)
 | 
			
		||||
describing the OsmoBTS specific A-bis dialect.
 | 
			
		||||
 | 
			
		||||
Forum
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
We welcome any osmo-bts related discussions in the
 | 
			
		||||
[Cellular Network Infrastructure -> 2G RAN (GERAN)](https://discourse.osmocom.org/c/cni/geran)
 | 
			
		||||
section of the osmocom discourse (web based Forum).
 | 
			
		||||
 | 
			
		||||
Mailing List
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
@@ -69,13 +76,20 @@ Please observe the [Osmocom Mailing List
 | 
			
		||||
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
 | 
			
		||||
when posting.
 | 
			
		||||
 | 
			
		||||
Issue Tracker
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
We use the [issue tracker of the osmo-bts project on osmocom.org](https://osmocom.org/projects/osmobts/issues) for
 | 
			
		||||
tracking the state of bug reports and feature requests.  Feel free to submit any issues you may find, or help
 | 
			
		||||
us out by resolving existing issues.
 | 
			
		||||
 | 
			
		||||
Contributing
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
Our coding standards are described at
 | 
			
		||||
https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards
 | 
			
		||||
 | 
			
		||||
We us a gerrit based patch submission/review process for managing
 | 
			
		||||
We use a Gerrit based patch submission/review process for managing
 | 
			
		||||
contributions.  Please see
 | 
			
		||||
https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit for
 | 
			
		||||
more details
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install
 | 
			
		||||
# according to https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
 | 
			
		||||
# In short:
 | 
			
		||||
# according to https://osmocom.org/projects/cellular-infrastructure/wiki/Make_a_new_release
 | 
			
		||||
# In short: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
 | 
			
		||||
# LIBVERSION=c:r:a
 | 
			
		||||
# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a.
 | 
			
		||||
# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0.
 | 
			
		||||
# If any interfaces have been added, removed, or changed since the last update: c + 1:0:a.
 | 
			
		||||
# If any interfaces have been added since the last public release: c:r:a + 1.
 | 
			
		||||
# If any interfaces have been removed or changed since the last public release: c:r:0.
 | 
			
		||||
#library	what	        description / commit summary line
 | 
			
		||||
#library	what			description / commit summary line
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								configure.ac
									
									
									
									
									
								
							@@ -69,15 +69,15 @@ then
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
dnl checks for libraries
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.8.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.8.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.8.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.8.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.8.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.8.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.4.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.4.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.3.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.11.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.11.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.11.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.11.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.11.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.11.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 2.0.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 2.0.0)
 | 
			
		||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.6.0)
 | 
			
		||||
 | 
			
		||||
AC_MSG_CHECKING([whether to enable support for sysmobts calibration tool])
 | 
			
		||||
AC_ARG_ENABLE(sysmobts-calib,
 | 
			
		||||
@@ -445,10 +445,11 @@ AC_OUTPUT(
 | 
			
		||||
    tests/power/Makefile
 | 
			
		||||
    tests/meas/Makefile
 | 
			
		||||
    tests/amr/Makefile
 | 
			
		||||
    tests/csd/Makefile
 | 
			
		||||
    doc/Makefile
 | 
			
		||||
    doc/examples/Makefile
 | 
			
		||||
    doc/manuals/Makefile
 | 
			
		||||
    contrib/Makefile
 | 
			
		||||
    contrib/ber/Makefile
 | 
			
		||||
    contrib/systemd/Makefile
 | 
			
		||||
    contrib/osmo-bts.spec
 | 
			
		||||
    Makefile)
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
SUBDIRS = systemd
 | 
			
		||||
SUBDIRS = systemd ber
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								contrib/ber/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								contrib/ber/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
AM_CPPFLAGS = \
 | 
			
		||||
	$(all_includes) \
 | 
			
		||||
	-I$(top_srcdir)/include \
 | 
			
		||||
	-I$(top_builddir)/include \
 | 
			
		||||
	-I$(builddir) \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
AM_CFLAGS = \
 | 
			
		||||
	-Wall \
 | 
			
		||||
	$(LIBOSMOCORE_CFLAGS) \
 | 
			
		||||
	$(LIBOSMOTRAU_CFLAGS) \
 | 
			
		||||
	$(LIBOSMOCODEC_CFLAGS) \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
LDADD = \
 | 
			
		||||
	$(LIBOSMOCORE_LIBS) \
 | 
			
		||||
	$(LIBOSMOTRAU_LIBS) \
 | 
			
		||||
	$(LIBOSMOCODEC_LIBS) \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
noinst_PROGRAMS = rtp_ber rtp_gen_map
 | 
			
		||||
 | 
			
		||||
rtp_ber_SOURCES = rtp_ber.c codec_bit_class.h
 | 
			
		||||
 | 
			
		||||
rtp_gen_map_SOURCES = rtp_gen_map.c
 | 
			
		||||
 | 
			
		||||
update_codec_bit_class_h: rtp_gen_map
 | 
			
		||||
	$(AM_V_GEN)./$< > $(top_srcdir)/contrib/ber/codec_bit_class.h
 | 
			
		||||
							
								
								
									
										26
									
								
								contrib/ber/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								contrib/ber/README
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
BER testing tool
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
* Check all configs (MSC/BSC/BTS) for proper codec support
 | 
			
		||||
  - FR enabled
 | 
			
		||||
  - EFR enabled
 | 
			
		||||
  - AMR 12.2 enabled (and all other modes disabled !)
 | 
			
		||||
  - Use `amr-payload octet-aligned` in BSC config
 | 
			
		||||
 | 
			
		||||
* Check BTS config
 | 
			
		||||
  - Disable jitter buffer : `bts N / rtp jitter-buffer 0`
 | 
			
		||||
 | 
			
		||||
* Check BSC config
 | 
			
		||||
  - Disable radio timeout : `network / bts n / radio-link-timeout infinite`
 | 
			
		||||
 | 
			
		||||
* Start BER testing tool
 | 
			
		||||
  - `./rtp_ber 4000`
 | 
			
		||||
 | 
			
		||||
* On the MSC CLI, start a silent-call, then request GSM to test loop
 | 
			
		||||
  - `subscriber imsi <XXX> silent-call start tch/f speech-amr`
 | 
			
		||||
  - `subscriber imsi <XXX> ms-test close-loop b`
 | 
			
		||||
 | 
			
		||||
  Don't forget to terminate the loop and terminate the silent call !
 | 
			
		||||
 | 
			
		||||
  - `subscriber imsi <XXX> ms-test open-loop`
 | 
			
		||||
  - `subscriber imsi <XXX> silent-call stop`
 | 
			
		||||
							
								
								
									
										59
									
								
								contrib/ber/codec_bit_class.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								contrib/ber/codec_bit_class.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
static const int gsm_fr_bitclass[] = {
 | 
			
		||||
	-1, -1, -1, -1,  0,  0,  0,  0,  1,  2,  0,  0,  0,  1,  2,  2,
 | 
			
		||||
	 0,  0,  1,  2,  2,  0,  0,  1,  2,  2,  0,  1,  1,  2,  0,  1,
 | 
			
		||||
	 2,  2,  0,  1,  2,  1,  2,  2,  0,  0,  0,  0,  0,  0,  1,  1,
 | 
			
		||||
	 1,  1,  1,  0,  0,  0,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,
 | 
			
		||||
	 1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,
 | 
			
		||||
	 2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,
 | 
			
		||||
	 0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  0,  0,  0,  1,  1,
 | 
			
		||||
	 2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,
 | 
			
		||||
	 1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,
 | 
			
		||||
	 1,  2,  1,  1,  2,  1,  1,  2,  0,  0,  0,  0,  0,  0,  1,  1,
 | 
			
		||||
	 1,  1,  1,  0,  0,  0,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,
 | 
			
		||||
	 1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,
 | 
			
		||||
	 2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,
 | 
			
		||||
	 0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  0,  0,  0,  1,  1,
 | 
			
		||||
	 2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  1,  2,  1,  2,  2,
 | 
			
		||||
	 1,  2,  2,  1,  2,  2,  1,  2,  2,  1,  2,  2,  1,  2,  2,  1,
 | 
			
		||||
	 2,  2,  1,  2,  2,  1,  2,  2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const int gsm_efr_bitclass[] = {
 | 
			
		||||
	 1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,
 | 
			
		||||
	 0,  0,  0,  0,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
 | 
			
		||||
	 2,  2,  2,  2,  2,  2,  0,  1,  1,  1,  1,  0,  0,  0,  0,  0,
 | 
			
		||||
	 1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,
 | 
			
		||||
	 2,  2,  2,  2,  2,  2,  2,  2,  0,  1,  1,  1,  1,  0,  0,  0,
 | 
			
		||||
	 0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,
 | 
			
		||||
	 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  1,  1,  1,
 | 
			
		||||
	 1,  1,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,
 | 
			
		||||
	 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  1,
 | 
			
		||||
	 1,  1,  1,  1,  2,  2,  1,  2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const int gsm_amr_12_2_bitclass[] = {
 | 
			
		||||
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 | 
			
		||||
	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
	 0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 | 
			
		||||
	 1,  1,  1,  1, -1, -1, -1, -1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										483
									
								
								contrib/ber/rtp_ber.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										483
									
								
								contrib/ber/rtp_ber.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,483 @@
 | 
			
		||||
/* RTP based GSM BER testing for osmo-bts, implementing ideas described in
 | 
			
		||||
 * https://osmocom.org/projects/osmobts/wiki/BER_Testing
 | 
			
		||||
 *
 | 
			
		||||
 * In short: The command transmits a PRBS sequence encapsulated in RTP frames, which are sent
 | 
			
		||||
 * to the BTS, which transmits that data in the (unimpaired) downlink.  The mobile station
 | 
			
		||||
 * receives the data and is instructed to loop it back in the (possibly impaired) uplink.
 | 
			
		||||
 * The BTS receives that uplink, puts in in RTP frames which end up being received back by this
 | 
			
		||||
 * very tool.  By correlating the received RTP with the PRBS sequence, this tool can compute
 | 
			
		||||
 * the BER (Bit Error Rate) of the (possibly impaired) uplink.  Doing this with different
 | 
			
		||||
 * RF channel model simulators in the uplink allows to establish BER at different levels and
 | 
			
		||||
 * channel conditions. */
 | 
			
		||||
 | 
			
		||||
/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocom/codec/codec.h>
 | 
			
		||||
#include <osmocom/core/logging.h>
 | 
			
		||||
#include <osmocom/core/prbs.h>
 | 
			
		||||
#include <osmocom/core/timer.h>
 | 
			
		||||
#include <osmocom/core/utils.h>
 | 
			
		||||
#include <osmocom/trau/osmo_ortp.h>
 | 
			
		||||
 | 
			
		||||
#include <codec_bit_class.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct app_state {
 | 
			
		||||
	struct osmo_rtp_socket *rs;
 | 
			
		||||
 | 
			
		||||
	enum {
 | 
			
		||||
		WAIT_CONN = 0,	/* Wait for incoming connection */
 | 
			
		||||
		WAIT_LOOP,	/* Wait for a somewhat valid packet to start measuring */
 | 
			
		||||
		RUNNING,	/* Main state */
 | 
			
		||||
	} state;
 | 
			
		||||
 | 
			
		||||
	int pt;
 | 
			
		||||
 | 
			
		||||
	int     ref_len;
 | 
			
		||||
	uint8_t ref_bytes[GSM_FR_BYTES];	/* FR is the largest possible one */
 | 
			
		||||
	ubit_t  ref_bits[8*GSM_FR_BYTES];
 | 
			
		||||
 | 
			
		||||
	struct osmo_timer_list rtp_timer;
 | 
			
		||||
 | 
			
		||||
	uint16_t rx_last_seq;
 | 
			
		||||
	uint32_t rx_last_ts;
 | 
			
		||||
	uint32_t rx_idx;
 | 
			
		||||
	uint32_t tx_idx;
 | 
			
		||||
 | 
			
		||||
	const int *err_tbl;	/* Classification table */
 | 
			
		||||
	int err_frames;		/* Number of accumulated frames */
 | 
			
		||||
	int err_cnt[3];		/* Bit error counter */
 | 
			
		||||
	int err_tot[3];		/* Total # bits in that class */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define FLOW_REG_TX_MAX_ADVANCE		200
 | 
			
		||||
#define FLOW_REG_TX_MIN_ADVANCE		 50
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const struct log_info log_info;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const uint8_t amr_size_by_ft[] = {
 | 
			
		||||
	[0]	= 12,	/* 4.75 */
 | 
			
		||||
	[1]	= 13,	/* 5.15 */
 | 
			
		||||
	[2]	= 15,	/* 5.9 */
 | 
			
		||||
	[3]	= 17,	/* 6.7 */
 | 
			
		||||
	[4]	= 19,	/* 7.4 */
 | 
			
		||||
	[5]	= 20,	/* 7.95 */
 | 
			
		||||
	[6]	= 26,	/* 10.2 */
 | 
			
		||||
	[7]	= 31,	/* 12.2 */
 | 
			
		||||
	[8]	= 5,	/* SID */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char * const amr_rate_by_ft[] = {
 | 
			
		||||
	[0]	= "4.75",
 | 
			
		||||
	[1]	= "5.15",
 | 
			
		||||
	[2]	= "5.9",
 | 
			
		||||
	[3]	= "6.7",
 | 
			
		||||
	[4]	= "7.4",
 | 
			
		||||
	[5]	= "7.95",
 | 
			
		||||
	[6]	= "10.2",
 | 
			
		||||
	[7]	= "12.2",
 | 
			
		||||
	[8]	= "SID",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
_gsm_fr_gen_ref(struct app_state *as)
 | 
			
		||||
{
 | 
			
		||||
	struct osmo_prbs_state pn9;
 | 
			
		||||
 | 
			
		||||
	/* Length */
 | 
			
		||||
	as->ref_len = GSM_FR_BYTES;
 | 
			
		||||
 | 
			
		||||
	/* Marker */
 | 
			
		||||
	as->ref_bits[0] = 1;
 | 
			
		||||
	as->ref_bits[1] = 1;
 | 
			
		||||
	as->ref_bits[2] = 0;
 | 
			
		||||
	as->ref_bits[3] = 1;
 | 
			
		||||
 | 
			
		||||
	/* PN */
 | 
			
		||||
	osmo_prbs_state_init(&pn9, &osmo_prbs9);
 | 
			
		||||
	pn9.state = 31;
 | 
			
		||||
	osmo_prbs_get_ubits(&as->ref_bits[4], 260, &pn9);
 | 
			
		||||
 | 
			
		||||
	/* Convert to bytes */
 | 
			
		||||
	osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_FR_BYTES, 0);
 | 
			
		||||
 | 
			
		||||
	/* Init error classes */
 | 
			
		||||
	as->err_tot[0] =  50;
 | 
			
		||||
	as->err_tot[1] = 132;
 | 
			
		||||
	as->err_tot[2] =  78;
 | 
			
		||||
	as->err_tbl = gsm_fr_bitclass;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
_gsm_efr_gen_ref(struct app_state *as)
 | 
			
		||||
{
 | 
			
		||||
	struct osmo_prbs_state pn9;
 | 
			
		||||
 | 
			
		||||
	/* Length */
 | 
			
		||||
	as->ref_len = GSM_EFR_BYTES;
 | 
			
		||||
 | 
			
		||||
	/* Marker */
 | 
			
		||||
	as->ref_bits[0] = 1;
 | 
			
		||||
	as->ref_bits[1] = 1;
 | 
			
		||||
	as->ref_bits[2] = 0;
 | 
			
		||||
	as->ref_bits[3] = 0;
 | 
			
		||||
 | 
			
		||||
	/* PN */
 | 
			
		||||
	osmo_prbs_state_init(&pn9, &osmo_prbs9);
 | 
			
		||||
	pn9.state = 31;
 | 
			
		||||
	osmo_prbs_get_ubits(&as->ref_bits[4], 244, &pn9);
 | 
			
		||||
 | 
			
		||||
	/* Convert to bytes */
 | 
			
		||||
	osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_EFR_BYTES, 0);
 | 
			
		||||
 | 
			
		||||
	/* Init error classes */
 | 
			
		||||
	as->err_tot[0] =  50;
 | 
			
		||||
	as->err_tot[1] = 125;
 | 
			
		||||
	as->err_tot[2] =  73;
 | 
			
		||||
	as->err_tbl = gsm_efr_bitclass;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
_gsm_amr_gen_ref(struct app_state *as)
 | 
			
		||||
{
 | 
			
		||||
	struct osmo_prbs_state pn9;
 | 
			
		||||
	uint8_t hdr[2];
 | 
			
		||||
 | 
			
		||||
	/* Length */
 | 
			
		||||
	as->ref_len = 33;
 | 
			
		||||
 | 
			
		||||
	/* Header */
 | 
			
		||||
	hdr[0] = 0x70;
 | 
			
		||||
	hdr[1] = 0x3c;
 | 
			
		||||
	osmo_pbit2ubit_ext(as->ref_bits, 0, hdr, 0, 16, 0);
 | 
			
		||||
 | 
			
		||||
	/* PN */
 | 
			
		||||
	osmo_prbs_state_init(&pn9, &osmo_prbs9);
 | 
			
		||||
	pn9.state = 31;
 | 
			
		||||
	osmo_prbs_get_ubits(&as->ref_bits[16], 244, &pn9);
 | 
			
		||||
 | 
			
		||||
	/* Unused bits */
 | 
			
		||||
	as->ref_bits[260] = 0;
 | 
			
		||||
	as->ref_bits[261] = 0;
 | 
			
		||||
	as->ref_bits[262] = 0;
 | 
			
		||||
	as->ref_bits[263] = 0;
 | 
			
		||||
 | 
			
		||||
	/* Convert to bytes */
 | 
			
		||||
	osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 264, 0);
 | 
			
		||||
 | 
			
		||||
	/* Init error classes */
 | 
			
		||||
	as->err_tot[0] =  81;
 | 
			
		||||
	as->err_tot[1] = 163;
 | 
			
		||||
	as->err_tot[2] =  -1;
 | 
			
		||||
	as->err_tbl = gsm_amr_12_2_bitclass;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
_gsm_gen_ref(struct app_state *as)
 | 
			
		||||
{
 | 
			
		||||
	switch (as->pt) {
 | 
			
		||||
	case RTP_PT_GSM_FULL:
 | 
			
		||||
		_gsm_fr_gen_ref(as);
 | 
			
		||||
		break;
 | 
			
		||||
	case RTP_PT_GSM_EFR:
 | 
			
		||||
		_gsm_efr_gen_ref(as);
 | 
			
		||||
		break;
 | 
			
		||||
	case RTP_PT_AMR:
 | 
			
		||||
		_gsm_amr_gen_ref(as);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		fprintf(stderr, "[!] Unsupported payload type for BER measurement\n");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
_gsm_ber(struct app_state *as, const uint8_t *payload, unsigned int payload_len)
 | 
			
		||||
{
 | 
			
		||||
	ubit_t rx_bits[8*33];
 | 
			
		||||
	int err[3];	/* Class 1a, 1b, 2 */
 | 
			
		||||
	int ones;
 | 
			
		||||
	int i, j;
 | 
			
		||||
 | 
			
		||||
	if (payload) {
 | 
			
		||||
		/* Process real-payload */
 | 
			
		||||
		osmo_pbit2ubit_ext(rx_bits, 0, payload, 0, 8*payload_len, 0);
 | 
			
		||||
 | 
			
		||||
		err[0] = err[1] = err[2] = 0;
 | 
			
		||||
		ones = 0;
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < 8 * payload_len; i++) {
 | 
			
		||||
			j = as->err_tbl[i];
 | 
			
		||||
			if (j >= 0) {
 | 
			
		||||
				err[j] += rx_bits[i] ^ as->ref_bits[i];
 | 
			
		||||
				ones += rx_bits[i];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (ones < 32) { // This frames is probably us underrunning Tx, don't use it
 | 
			
		||||
			fprintf(stderr, "[w] Frame ignored as probably TX underrun %d %d\n", as->tx_idx, as->rx_idx);
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		/* No payload -> Lost frame completely */
 | 
			
		||||
		err[0] = as->err_tot[0] / 2;
 | 
			
		||||
		err[1] = as->err_tot[1] / 2;
 | 
			
		||||
		err[2] = as->err_tot[2] / 2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (as->state == RUNNING) {
 | 
			
		||||
		/* Update records */
 | 
			
		||||
		if (err[0] != 0) {
 | 
			
		||||
			/* Class 1a bits bad -> Frame error */
 | 
			
		||||
			as->err_cnt[0]++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		as->err_cnt[1] += err[1];	/* Class 1b */
 | 
			
		||||
		as->err_cnt[2] += err[2];	/* class 2  */
 | 
			
		||||
 | 
			
		||||
		as->err_frames++;
 | 
			
		||||
 | 
			
		||||
		/* Enough for a read-out ? */
 | 
			
		||||
		if (as->err_frames == 200) {
 | 
			
		||||
			printf("FBER: %4.2f    C1b RBER: %5.3f    C2 RBER: %5.3f\n",
 | 
			
		||||
				100.0f * as->err_cnt[0] / as->err_frames,
 | 
			
		||||
				100.0f * as->err_cnt[1] / (as->err_tot[1] * as->err_frames),
 | 
			
		||||
				100.0f * as->err_cnt[2] / (as->err_tot[2] * as->err_frames)
 | 
			
		||||
			);
 | 
			
		||||
			memset(as->err_cnt, 0, sizeof(as->err_cnt));
 | 
			
		||||
			as->err_frames = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err[0] != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
_rtp_check_payload_type(const uint8_t *payload, unsigned int payload_len)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t ft;
 | 
			
		||||
	int pt = -1;
 | 
			
		||||
 | 
			
		||||
	switch (payload_len) {
 | 
			
		||||
	case GSM_FR_BYTES: /* FR  or AMR 12.2k */
 | 
			
		||||
		/* Check for AMR */
 | 
			
		||||
		ft = (payload[1] >> 3) & 0xf;
 | 
			
		||||
		if (ft == 7)
 | 
			
		||||
			pt = RTP_PT_AMR;
 | 
			
		||||
 | 
			
		||||
		/* Check for FR */
 | 
			
		||||
		else if ((payload[0] & 0xF0) == 0xD0)
 | 
			
		||||
			pt = RTP_PT_GSM_FULL;
 | 
			
		||||
 | 
			
		||||
		/* None of the above */
 | 
			
		||||
		else
 | 
			
		||||
			fprintf(stderr, "[!] FR without 0xD0 signature or AMR with unknwon Frame Type ?!?\n");
 | 
			
		||||
 | 
			
		||||
		break;
 | 
			
		||||
	case GSM_EFR_BYTES: /* EFR */
 | 
			
		||||
		if ((payload[0] & 0xF0) != 0xC0)
 | 
			
		||||
			fprintf(stderr, "[!] EFR without 0xC0 signature ?!?\n");
 | 
			
		||||
		pt = RTP_PT_GSM_EFR;
 | 
			
		||||
		break;
 | 
			
		||||
	case GSM_HR_BYTES: /* HR */
 | 
			
		||||
		pt = RTP_PT_GSM_HALF;
 | 
			
		||||
		break;
 | 
			
		||||
	default: /* AMR */
 | 
			
		||||
		{
 | 
			
		||||
			uint8_t cmr, cmi, sti;
 | 
			
		||||
			cmr = payload[0] >> 4;
 | 
			
		||||
			ft = (payload[1] >> 3) & 0xf;
 | 
			
		||||
 | 
			
		||||
			if (payload_len != amr_size_by_ft[ft]+2)
 | 
			
		||||
				fprintf(stderr, "AMR FT %u(%s) but size %u\n",
 | 
			
		||||
					ft, amr_rate_by_ft[ft], payload_len);
 | 
			
		||||
 | 
			
		||||
			switch (ft) {
 | 
			
		||||
			case 0: case 1: case 2: case 3:
 | 
			
		||||
			case 4: case 5: case 6: case 7:
 | 
			
		||||
				cmi = ft;
 | 
			
		||||
				printf("AMR SPEECH with FT/CMI %u(%s), "
 | 
			
		||||
					"CMR %u\n",
 | 
			
		||||
					cmi, amr_rate_by_ft[cmi],
 | 
			
		||||
					cmr);
 | 
			
		||||
				break;
 | 
			
		||||
			case 8: /* SID */
 | 
			
		||||
				cmi = (payload[2+4] >> 1) & 0x7;
 | 
			
		||||
				sti = payload[2+4] & 0x10;
 | 
			
		||||
				printf("AMR SID %s with CMI %u(%s), CMR %u(%s)\n",
 | 
			
		||||
					sti ? "UPDATE" : "FIRST",
 | 
			
		||||
					cmi, amr_rate_by_ft[cmi],
 | 
			
		||||
					cmr, amr_rate_by_ft[cmr]);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
rtp_timer_cb(void *priv)
 | 
			
		||||
{
 | 
			
		||||
	struct app_state *as = (struct app_state *)priv;
 | 
			
		||||
 | 
			
		||||
	/* Send at least one frame if we're not too far ahead */
 | 
			
		||||
	if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MAX_ADVANCE)) {
 | 
			
		||||
		osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION);
 | 
			
		||||
		as->tx_idx++;
 | 
			
		||||
	} else {
 | 
			
		||||
		fprintf(stderr, "Skipped\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Then maybe a second one to try and catch up to RX */
 | 
			
		||||
	if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MIN_ADVANCE)) {
 | 
			
		||||
		osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION);
 | 
			
		||||
		as->tx_idx++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Re-schedule */
 | 
			
		||||
	osmo_timer_schedule(&as->rtp_timer, 0, 20000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
rtp_seq_num_diff(uint16_t new, uint16_t old)
 | 
			
		||||
{
 | 
			
		||||
	int d = (int)new - (int)old;
 | 
			
		||||
	while (d > 49152)
 | 
			
		||||
		d -= 65536;
 | 
			
		||||
	while (d < -49152)
 | 
			
		||||
		d += 65536;
 | 
			
		||||
	return d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
rtp_rx_cb(struct osmo_rtp_socket *rs,
 | 
			
		||||
	const uint8_t *payload, unsigned int payload_len,
 | 
			
		||||
	uint16_t seq_number, uint32_t timestamp, bool marker)
 | 
			
		||||
{
 | 
			
		||||
	struct app_state *as = (struct app_state *)rs->priv;
 | 
			
		||||
	int pt, rc, d;
 | 
			
		||||
 | 
			
		||||
//	printf("Rx(%u, %d, %d, %d): %s\n", payload_len, seq_number, timestamp, marker, osmo_hexdump(payload, payload_len));
 | 
			
		||||
 | 
			
		||||
	/* Identify payload */
 | 
			
		||||
	pt = _rtp_check_payload_type(payload, payload_len);
 | 
			
		||||
 | 
			
		||||
	/* First packet ? */
 | 
			
		||||
	if (as->state == WAIT_CONN) {
 | 
			
		||||
		/* Setup for this payload type */
 | 
			
		||||
		as->pt = pt;
 | 
			
		||||
		osmo_rtp_socket_set_pt(as->rs, pt);
 | 
			
		||||
		_gsm_gen_ref(as);
 | 
			
		||||
 | 
			
		||||
		/* Timer every 20 ms */
 | 
			
		||||
		osmo_timer_setup(&as->rtp_timer, rtp_timer_cb, as);
 | 
			
		||||
		osmo_timer_add(&as->rtp_timer);
 | 
			
		||||
		osmo_timer_schedule(&as->rtp_timer, 0, 20000);
 | 
			
		||||
 | 
			
		||||
		/* Init our time tracking */
 | 
			
		||||
		as->rx_last_seq = seq_number;
 | 
			
		||||
		as->rx_last_ts  = timestamp;
 | 
			
		||||
 | 
			
		||||
		/* Now we wait for a loop */
 | 
			
		||||
		as->state = WAIT_LOOP;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* RX sequence & timstamp tracking */
 | 
			
		||||
	if (rtp_seq_num_diff(seq_number, as->rx_last_seq) > 1)
 | 
			
		||||
		fprintf(stderr, "[!] RTP sequence number discontinuity (%d -> %d)\n", as->rx_last_seq, seq_number);
 | 
			
		||||
 | 
			
		||||
	d = (timestamp - as->rx_last_ts) / GSM_RTP_DURATION;
 | 
			
		||||
 | 
			
		||||
	as->rx_idx += d;
 | 
			
		||||
	as->rx_last_seq = seq_number;
 | 
			
		||||
	as->rx_last_ts  = timestamp;
 | 
			
		||||
 | 
			
		||||
	/* Account for missing frames in BER tracking */
 | 
			
		||||
	if (d > 1) {
 | 
			
		||||
		fprintf(stderr, "[!] RTP %d missing frames assumed lost @%d\n", d-1, seq_number);
 | 
			
		||||
		while (--d)
 | 
			
		||||
			_gsm_ber(as, NULL, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* BER analysis */
 | 
			
		||||
	rc = _gsm_ber(as, payload, payload_len);
 | 
			
		||||
 | 
			
		||||
	if ((as->state == WAIT_LOOP) && (rc == 0))
 | 
			
		||||
		as->state = RUNNING;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	struct app_state _as, *as = &_as;
 | 
			
		||||
	int rc, port;
 | 
			
		||||
 | 
			
		||||
	/* Args */
 | 
			
		||||
	if (argc < 2)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	port = atoi(argv[1]);
 | 
			
		||||
 | 
			
		||||
	/* App init */
 | 
			
		||||
	memset(as, 0x00, sizeof(struct app_state));
 | 
			
		||||
 | 
			
		||||
	log_init(&log_info, NULL);
 | 
			
		||||
	osmo_rtp_init(NULL);
 | 
			
		||||
 | 
			
		||||
	/* Start auto-connect RTP socket */
 | 
			
		||||
	as->rs = osmo_rtp_socket_create(NULL, 0);
 | 
			
		||||
 | 
			
		||||
	as->rs->priv = as;
 | 
			
		||||
	as->rs->rx_cb = rtp_rx_cb;
 | 
			
		||||
 | 
			
		||||
		/* Jitter buffer gets in the way, we want the raw traffic */
 | 
			
		||||
	osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JIT_ADAP, 0);
 | 
			
		||||
	osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JITBUF, 0);
 | 
			
		||||
 | 
			
		||||
		/* Bind to requested port */
 | 
			
		||||
	fprintf(stderr, "[+] Binding RTP socket on port %u...\n", port);
 | 
			
		||||
	rc = osmo_rtp_socket_bind(as->rs, "0.0.0.0", port);
 | 
			
		||||
	if (rc < 0) {
 | 
			
		||||
		fprintf(stderr, "[!] error binding RTP socket: %d\n", rc);
 | 
			
		||||
		return rc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		/* We 'connect' to the first source we hear from */
 | 
			
		||||
	osmo_rtp_socket_autoconnect(as->rs);
 | 
			
		||||
 | 
			
		||||
	/* Main loop */
 | 
			
		||||
	while (1)
 | 
			
		||||
		osmo_select_main(0);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								contrib/ber/rtp_gen_map.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								contrib/ber/rtp_gen_map.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
/* utility to generate codec_bit_class.h, a file with structures
 | 
			
		||||
 * describing which [protection] class each bit of a given codec frame belongs to */
 | 
			
		||||
 | 
			
		||||
/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocom/codec/codec.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
gen_table_fr(int *tbl)
 | 
			
		||||
{
 | 
			
		||||
	int i, j;
 | 
			
		||||
 | 
			
		||||
	tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 260; i++) {
 | 
			
		||||
		j = 4 + gsm610_bitorder[i];
 | 
			
		||||
		if (i < 50)
 | 
			
		||||
			tbl[j] = 0;	/* Class 1a */
 | 
			
		||||
		else if (i < 182)
 | 
			
		||||
			tbl[j] = 1;	/* Class 1b */
 | 
			
		||||
		else
 | 
			
		||||
			tbl[j] = 2;	/* Class 2 */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return GSM_FR_BYTES * 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
gen_table_efr(int *tbl)
 | 
			
		||||
{
 | 
			
		||||
	int i, j, k;
 | 
			
		||||
 | 
			
		||||
	tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 260; i++) {
 | 
			
		||||
		j = gsm660_bitorder[i];
 | 
			
		||||
 | 
			
		||||
		if (j < 71)
 | 
			
		||||
			k = j;
 | 
			
		||||
		else if (j < 73)
 | 
			
		||||
			k = 71;
 | 
			
		||||
		else if (j < 123)
 | 
			
		||||
			k = j - 2;
 | 
			
		||||
		else if (j < 125)
 | 
			
		||||
			k = 119;
 | 
			
		||||
		else if (j < 178)
 | 
			
		||||
			k = j - 4;
 | 
			
		||||
		else if (j < 180)
 | 
			
		||||
			k = 172;
 | 
			
		||||
		else if (j < 230)
 | 
			
		||||
			k = j - 6;
 | 
			
		||||
		else if (j < 232)
 | 
			
		||||
			k = 222;
 | 
			
		||||
		else if (j < 252)
 | 
			
		||||
			k = j - 8;
 | 
			
		||||
		else
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (i < 50)
 | 
			
		||||
			tbl[k] = 0;	/* Class 1a */
 | 
			
		||||
		else if (i < 182)
 | 
			
		||||
			tbl[k] = 1;	/* Class 1b */
 | 
			
		||||
		else
 | 
			
		||||
			tbl[k] = 2;	/* Class 2 */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return GSM_EFR_BYTES * 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
gen_table_amr_12_2(int *tbl)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 16; i++)
 | 
			
		||||
		tbl[i] = -1;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 244; i++)
 | 
			
		||||
		tbl[i+16] = i < 81 ? 0 : 1;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 4; i++)
 | 
			
		||||
		tbl[i+16+244] = -1;
 | 
			
		||||
 | 
			
		||||
	return 8 * 33;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
print_table(const char  *name, int *tbl, int len)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	printf("static const int %s[] = {\n", name);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < len; i++) {
 | 
			
		||||
		if ((i & 15) == 0)
 | 
			
		||||
			printf("\t");
 | 
			
		||||
 | 
			
		||||
		printf("%2d", tbl[i]);
 | 
			
		||||
 | 
			
		||||
		if (((i & 15) == 15) || (i == len-1))
 | 
			
		||||
			printf(",\n");
 | 
			
		||||
		else
 | 
			
		||||
			printf(", ");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printf("};\n\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	int tbl[33*8];
 | 
			
		||||
	int rv;
 | 
			
		||||
 | 
			
		||||
	rv = gen_table_fr(tbl);
 | 
			
		||||
	print_table("gsm_fr_bitclass", tbl, rv);
 | 
			
		||||
 | 
			
		||||
	rv = gen_table_efr(tbl);
 | 
			
		||||
	print_table("gsm_efr_bitclass", tbl, rv);
 | 
			
		||||
 | 
			
		||||
	rv = gen_table_amr_12_2(tbl);
 | 
			
		||||
	print_table("gsm_amr_12_2_bitclass", tbl, rv);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -8,9 +8,8 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
 | 
			
		||||
export LD_LIBRARY_PATH="$inst/lib"
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
 | 
			
		||||
cd "$deps"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,12 @@
 | 
			
		||||
# shellcheck source=contrib/jenkins_common.sh
 | 
			
		||||
. $(dirname "$0")/jenkins_common.sh
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
 | 
			
		||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
 | 
			
		||||
export LD_LIBRARY_PATH="$inst/lib"
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
 | 
			
		||||
cd "$deps"
 | 
			
		||||
osmo-layer1-headers.sh lc15 "$FIRMWARE_VERSION"
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,12 @@
 | 
			
		||||
# shellcheck source=contrib/jenkins_common.sh
 | 
			
		||||
. $(dirname "$0")/jenkins_common.sh
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
 | 
			
		||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
 | 
			
		||||
export LD_LIBRARY_PATH="$inst/lib"
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
 | 
			
		||||
cd "$deps"
 | 
			
		||||
osmo-layer1-headers.sh oc2g "$FIRMWARE_VERSION"
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,12 @@
 | 
			
		||||
# shellcheck source=contrib/jenkins_common.sh
 | 
			
		||||
. $(dirname "$0")/jenkins_common.sh
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
 | 
			
		||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
 | 
			
		||||
export LD_LIBRARY_PATH="$inst/lib"
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
 | 
			
		||||
cd "$deps"
 | 
			
		||||
osmo-layer1-headers.sh oct "$FIRMWARE_VERSION"
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,8 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
 | 
			
		||||
export LD_LIBRARY_PATH="$inst/lib"
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
 | 
			
		||||
cd "$deps"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,12 @@
 | 
			
		||||
# shellcheck source=contrib/jenkins_common.sh
 | 
			
		||||
. $(dirname "$0")/jenkins_common.sh
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
 | 
			
		||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
 | 
			
		||||
export LD_LIBRARY_PATH="$inst/lib"
 | 
			
		||||
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
 | 
			
		||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
 | 
			
		||||
 | 
			
		||||
cd "$deps"
 | 
			
		||||
osmo-layer1-headers.sh sysmo "$FIRMWARE_VERSION"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,118 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# spec file for package osmo-bts
 | 
			
		||||
#
 | 
			
		||||
# Copyright (c) 2017, Martin Hauke <mardnh@gmx.de>
 | 
			
		||||
#
 | 
			
		||||
# All modifications and additions to the file contributed by third parties
 | 
			
		||||
# remain the property of their copyright owners, unless otherwise agreed
 | 
			
		||||
# upon. The license for this file, and modifications and additions to the
 | 
			
		||||
# file, is the same license as for the pristine package itself (unless the
 | 
			
		||||
# license for the pristine package is not an Open Source License, in which
 | 
			
		||||
# case the license is the MIT License). An "Open Source License" is a
 | 
			
		||||
# license that conforms to the Open Source Definition (Version 1.9)
 | 
			
		||||
# published by the Open Source Initiative.
 | 
			
		||||
 | 
			
		||||
Name:           osmo-bts
 | 
			
		||||
Version:        @VERSION@
 | 
			
		||||
Release:        0
 | 
			
		||||
Summary:        Osmocom BTS-Side code (Abis, scheduling)
 | 
			
		||||
License:        AGPL-3.0-or-later AND GPL-2.0-only
 | 
			
		||||
Group:          Productivity/Telephony/Servers
 | 
			
		||||
URL:            https://osmocom.org/projects/osmobts
 | 
			
		||||
Source:         %{name}-%{version}.tar.xz
 | 
			
		||||
BuildRequires:  autoconf
 | 
			
		||||
BuildRequires:  automake
 | 
			
		||||
BuildRequires:  libtool
 | 
			
		||||
BuildRequires:  pkgconfig >= 0.20
 | 
			
		||||
%if 0%{?suse_version}
 | 
			
		||||
BuildRequires:  systemd-rpm-macros
 | 
			
		||||
%endif
 | 
			
		||||
BuildRequires:  pkgconfig(libosmocodec) >= 1.8.0
 | 
			
		||||
BuildRequires:  pkgconfig(libosmocoding) >= 1.8.0
 | 
			
		||||
BuildRequires:  pkgconfig(libosmocore) >= 1.8.0
 | 
			
		||||
BuildRequires:  pkgconfig(libosmoctrl) >= 1.8.0
 | 
			
		||||
BuildRequires:  pkgconfig(libosmogsm) >= 1.8.0
 | 
			
		||||
BuildRequires:  pkgconfig(libosmovty) >= 1.8.0
 | 
			
		||||
BuildRequires:  pkgconfig(libosmoabis) >= 1.4.0
 | 
			
		||||
BuildRequires:  pkgconfig(libosmotrau) >= 1.4.0
 | 
			
		||||
BuildRequires:  pkgconfig(libosmo-netif) >= 1.3.0
 | 
			
		||||
### FIXME: DependencyHACK to include  osmocom/gprs/protocol/gsm_04_60.h
 | 
			
		||||
BuildRequires:  pkgconfig(libosmogb)
 | 
			
		||||
%{?systemd_requires}
 | 
			
		||||
 | 
			
		||||
%description
 | 
			
		||||
Osmocom BTS-Side code (A-bis, scheduling).
 | 
			
		||||
 | 
			
		||||
%package -n osmo-bts-virtual
 | 
			
		||||
Summary:        Virtual Osmocom GSM BTS (no RF hardware; GSMTAP/UDP)
 | 
			
		||||
License:        GPL-2.0-or-later
 | 
			
		||||
Group:          Productivity/Telephony/Utilities
 | 
			
		||||
 | 
			
		||||
%description -n osmo-bts-virtual
 | 
			
		||||
This version of OsmoBTS doesn't use actual GSM PHY/Hardware/RF, but
 | 
			
		||||
utilizes GSMTAP-over-UDP frames for the Um interface.  This is useful
 | 
			
		||||
in fully virtualized setups e.g. in combination with OsmocomBB virt_phy.
 | 
			
		||||
 | 
			
		||||
%package -n osmo-bts-omldummy
 | 
			
		||||
Summary:        Osmocom CI: Bring up only OML without RSL
 | 
			
		||||
License:        GPL-2.0-or-later
 | 
			
		||||
Group:          Productivity/Telephony/Utilities
 | 
			
		||||
 | 
			
		||||
%description -n osmo-bts-omldummy
 | 
			
		||||
This is used only in integration testing, where in the TTCN-3 testsuite
 | 
			
		||||
we currently have no A-bis OML implementation, but only a RSL one.
 | 
			
		||||
 | 
			
		||||
%prep
 | 
			
		||||
%setup -q
 | 
			
		||||
 | 
			
		||||
%build
 | 
			
		||||
echo "%{version}" >.tarball-version
 | 
			
		||||
autoreconf -fi
 | 
			
		||||
%configure \
 | 
			
		||||
    --docdir="%{_docdir}/%{name}" \
 | 
			
		||||
    --with-systemdsystemunitdir=%{_unitdir} \
 | 
			
		||||
    --enable-trx
 | 
			
		||||
make V=1 %{?_smp_mflags}
 | 
			
		||||
 | 
			
		||||
%install
 | 
			
		||||
%make_install
 | 
			
		||||
 | 
			
		||||
%if 0%{?suse_version}
 | 
			
		||||
%pre    %service_add_pre    osmo-bts-trx.service
 | 
			
		||||
%post   %service_add_post   osmo-bts-trx.service
 | 
			
		||||
%preun  %service_del_preun  osmo-bts-trx.service
 | 
			
		||||
%postun %service_del_postun osmo-bts-trx.service
 | 
			
		||||
%pre    virtual %service_add_pre    osmo-bts-virtual.service
 | 
			
		||||
%post   virtual %service_add_post   osmo-bts-virtual.service
 | 
			
		||||
%preun  virtual %service_del_preun  osmo-bts-virtual.service
 | 
			
		||||
%postun virtual %service_del_postun osmo-bts-virtual.service
 | 
			
		||||
%endif
 | 
			
		||||
 | 
			
		||||
%check
 | 
			
		||||
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
 | 
			
		||||
 | 
			
		||||
%files
 | 
			
		||||
%license COPYING
 | 
			
		||||
%doc README.md
 | 
			
		||||
%dir %{_docdir}/%{name}
 | 
			
		||||
%dir %{_docdir}/%{name}/examples
 | 
			
		||||
%dir %{_docdir}/%{name}/examples/osmo-bts-trx
 | 
			
		||||
%{_docdir}/%{name}/examples/osmo-bts-trx/osmo-bts-trx-calypso.cfg
 | 
			
		||||
%{_docdir}/%{name}/examples/osmo-bts-trx/osmo-bts-trx.cfg
 | 
			
		||||
%dir %{_docdir}/%{name}/examples/osmo-bts-virtual
 | 
			
		||||
%{_docdir}/%{name}/examples/osmo-bts-virtual/osmo-bts-virtual.cfg
 | 
			
		||||
%{_bindir}/osmo-bts-trx
 | 
			
		||||
%dir %{_sysconfdir}/osmocom
 | 
			
		||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-bts-trx.cfg
 | 
			
		||||
%{_unitdir}/osmo-bts-trx.service
 | 
			
		||||
 | 
			
		||||
%files -n osmo-bts-virtual
 | 
			
		||||
%{_bindir}/osmo-bts-virtual
 | 
			
		||||
%dir %{_sysconfdir}/osmocom
 | 
			
		||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-bts-virtual.cfg
 | 
			
		||||
%{_unitdir}/osmo-bts-virtual.service
 | 
			
		||||
 | 
			
		||||
%files -n osmo-bts-omldummy
 | 
			
		||||
%{_bindir}/osmo-bts-omldummy
 | 
			
		||||
 | 
			
		||||
%changelog
 | 
			
		||||
@@ -2,6 +2,8 @@
 | 
			
		||||
Description=osmo-bts manager for LC15 / sysmoBTS 2100
 | 
			
		||||
After=lc15-sysdev-remap.service
 | 
			
		||||
Wants=lc15-sysdev-remap.service
 | 
			
		||||
After=network-online.target
 | 
			
		||||
Wants=network-online.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,8 @@
 | 
			
		||||
Description=osmo-bts manager for OC-2G
 | 
			
		||||
After=oc2g-sysdev-remap.service
 | 
			
		||||
Wants=oc2g-sysdev-remap.service
 | 
			
		||||
After=network-online.target
 | 
			
		||||
Wants=network-online.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=osmo-bts for LC15 / sysmoBTS 2100
 | 
			
		||||
After=network-online.target
 | 
			
		||||
Wants=network-online.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
@@ -9,7 +11,6 @@ WorkingDirectory=%S/osmocom
 | 
			
		||||
RuntimeDirectory=osmo-bts
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=2
 | 
			
		||||
RestartPreventExitStatus=1
 | 
			
		||||
 | 
			
		||||
# CPU scheduling policy:
 | 
			
		||||
CPUSchedulingPolicy=rr
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=osmo-bts for OC-2G
 | 
			
		||||
After=network-online.target
 | 
			
		||||
Wants=network-online.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
@@ -9,7 +11,6 @@ WorkingDirectory=%S/osmocom
 | 
			
		||||
RuntimeDirectory=osmo-bts
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=2
 | 
			
		||||
RestartPreventExitStatus=1
 | 
			
		||||
 | 
			
		||||
# CPU scheduling policy:
 | 
			
		||||
CPUSchedulingPolicy=rr
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=osmo-bts for sysmocom sysmoBTS
 | 
			
		||||
After=network-online.target
 | 
			
		||||
Wants=network-online.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
@@ -11,12 +13,11 @@ StateDirectory=osmocom
 | 
			
		||||
WorkingDirectory=%S/osmocom
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=2
 | 
			
		||||
RestartPreventExitStatus=1
 | 
			
		||||
 | 
			
		||||
# CPU scheduling policy:
 | 
			
		||||
CPUSchedulingPolicy=rr
 | 
			
		||||
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
 | 
			
		||||
CPUSchedulingPriority=11
 | 
			
		||||
CPUSchedulingPriority=20
 | 
			
		||||
# See sched(7) for further details on real-time policies and priorities
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Osmocom osmo-bts for osmo-trx
 | 
			
		||||
After=network-online.target
 | 
			
		||||
Wants=network-online.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
@@ -8,6 +10,9 @@ StateDirectory=osmocom
 | 
			
		||||
WorkingDirectory=%S/osmocom
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=2
 | 
			
		||||
User=osmocom
 | 
			
		||||
Group=osmocom
 | 
			
		||||
AmbientCapabilities=CAP_SYS_NICE
 | 
			
		||||
 | 
			
		||||
# CPU scheduling policy:
 | 
			
		||||
CPUSchedulingPolicy=rr
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Osmocom GSM BTS for virtual Um layer based on GSMTAP/UDP
 | 
			
		||||
After=network-online.target
 | 
			
		||||
Wants=network-online.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
@@ -8,6 +10,9 @@ StateDirectory=osmocom
 | 
			
		||||
WorkingDirectory=%S/osmocom
 | 
			
		||||
Restart=always
 | 
			
		||||
RestartSec=2
 | 
			
		||||
User=osmocom
 | 
			
		||||
Group=osmocom
 | 
			
		||||
AmbientCapabilities=CAP_SYS_NICE
 | 
			
		||||
 | 
			
		||||
# CPU scheduling policy:
 | 
			
		||||
CPUSchedulingPolicy=rr
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=osmo-bts manager for sysmoBTS
 | 
			
		||||
After=network-online.target
 | 
			
		||||
Wants=network-online.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=simple
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										374
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										374
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,377 @@
 | 
			
		||||
osmo-bts (1.9.0) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  [ Mychaela N. Falconia ]
 | 
			
		||||
  * sysmo: generate empty TCH/H payload on FACCH/H Rx
 | 
			
		||||
  * CSD: implement half-rate modes correctly
 | 
			
		||||
  * csd_v110: set E2 bit correctly for TCH/[FH]4.8 NT
 | 
			
		||||
  * CSD RTP: verify alignment of V.110 frames
 | 
			
		||||
  * csd_v110_rtp_decode: preserve E2 & E3 bits for RLP alignment
 | 
			
		||||
  * cosmetic: eliminate else-after-return in gsmtap_csd_rlp_process()
 | 
			
		||||
  * cosmetic: move gsmtap_csd_rlp_process() to csd_rlp.c
 | 
			
		||||
  * CSD NT modes: transmit properly aligned RLP frames on DL
 | 
			
		||||
 | 
			
		||||
  [ Vadim Yanitskiy ]
 | 
			
		||||
  * tests/csd: add NT variants for TCH/F4.8 and TCH/F9.6
 | 
			
		||||
  * l1sap: prevent buffer overflow in l1sap_rtp_rx_cb()
 | 
			
		||||
  * l1sap: move struct osmo_rlp_frame_decoded to the if-scope
 | 
			
		||||
  * rsl: rsl_handle_chan_mod_ie(): set lchan->csd_mode for NT CSD
 | 
			
		||||
  * vty: lchan_dump_full_vty(): print CSD mode
 | 
			
		||||
  * l1sap: make send_ul_rtp_packet_hrdata() NULL-safe
 | 
			
		||||
  * osmo-bts-trx: fix scheduling of DL FACCH/H for TCH/H4.8 and TCH/H2.4
 | 
			
		||||
  * l1sap: l1sap_tch_rts_ind(): fix NULL ptr dereference
 | 
			
		||||
  * csd_v110: use osmo_csd_ra2_* API from libosmotrau
 | 
			
		||||
  * csd_v110: add CSD_V110_NUM_BITS macro
 | 
			
		||||
  * csd_v110: clarify field names in csd_v110_lchan_desc[]
 | 
			
		||||
  * csd_v110: clarify lchan description for TCH/F14.4
 | 
			
		||||
  * csd_v110: handle TCH/F14.4
 | 
			
		||||
 | 
			
		||||
  [ Pau Espin Pedrol ]
 | 
			
		||||
  * jenkins.sh: libosmo-netif no longer depends on libosmo-abis
 | 
			
		||||
  * bts-omldummy: Support configuring logging through cmdline
 | 
			
		||||
  * bts-omldummy: print category names instead of hex values
 | 
			
		||||
  * Fix missing quote char in log line
 | 
			
		||||
  * abis: Log line and ts nr of signal
 | 
			
		||||
  * abis: Fix reusing bts->*_link while it is being destroyed
 | 
			
		||||
  * Drop use of libosmo-abis osmocom/abis/ipaccess.h
 | 
			
		||||
 | 
			
		||||
  [ Philipp Maier ]
 | 
			
		||||
  * pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
 | 
			
		||||
 | 
			
		||||
 -- Oliver Smith <osmith@sysmocom.de>  Wed, 12 Feb 2025 12:56:09 +0100
 | 
			
		||||
 | 
			
		||||
osmo-bts (1.8.0) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  [ Vadim Yanitskiy ]
 | 
			
		||||
  * osmo-bts-{oc2g,lc15}: signal CBCH support to BSC
 | 
			
		||||
  * oml: oml_tx_attr_resp(): pass *mo to handle_attrs_{bts,trx}()
 | 
			
		||||
  * oml: refactor generation of Get Attribute Response
 | 
			
		||||
  * oml: oml_tx_attr_resp(): handle common nm_state attributes
 | 
			
		||||
  * oml: implement handling of NM_ATT_IPACC_SUPP_FEATURES
 | 
			
		||||
  * l1sap: l1sap_tch_ind(): fix segfault on stale TCH.ind
 | 
			
		||||
  * osmo-bts-trx: rx_tchh_fn(): fix copy-pasted comment
 | 
			
		||||
  * meas: also match stderr logging for meas_test
 | 
			
		||||
  * meas: lchan_meas_sub_num_expected(): proper cmode enforcement
 | 
			
		||||
  * meas: lchan_meas_check_compute(): fix -SUB frame substitution
 | 
			
		||||
  * meas: handle VAMOS specific chan modes
 | 
			
		||||
  * meas: fix ts45008_83_is_sub(): DTX is permitted on TCH/F sign
 | 
			
		||||
  * meas: ts45008_83_is_sub(): properly handle CSD modes
 | 
			
		||||
  * meas: lchan_meas_sub_num_expected(): handle CSD modes
 | 
			
		||||
  * osmo-bts-trx: tx_tch[fh]_fn(): use BUFPOS macro everywhere
 | 
			
		||||
  * osmo-bts-trx: tx_tch[fh]_fn(): rework generation of dummy FACCH
 | 
			
		||||
  * osmo-bts-trx: tx_tch[fh]_fn(): fix sending idle CSD frames
 | 
			
		||||
  * osmo-bts-trx: add_sbits(): simplify, improve coding style
 | 
			
		||||
  * osmo-bts-trx: use BPLEN macro instead of magic numbers
 | 
			
		||||
  * osmo-bts-trx: eliminate ul_bursts_prev, use the primary buffer
 | 
			
		||||
  * l1sap: fix logic error in gsmtap_csd_rlp_process()
 | 
			
		||||
  * osmo-bts-trx: add test VTY command to send arbitrary TRXC messages
 | 
			
		||||
  * doc/examples: fix missing config files in release tarballs
 | 
			
		||||
  * osmo-bts-{trx,virtual}: do not advertise TCH/F14.4 NT
 | 
			
		||||
  * tests/osmo-bts.vty: aligh with recent libosmovty changes
 | 
			
		||||
  * README.md: cosmetic: fix a typo
 | 
			
		||||
  * doc/examples: use common 'ipa unit-id' in all files
 | 
			
		||||
  * doc/examples: drop no-op 'gsmtap-sapi' lines
 | 
			
		||||
  * doc/examples: osmo-bts-trx.cfg: set 'oml remote-ip' to '127.0.0.1'
 | 
			
		||||
 | 
			
		||||
  [ Pau Espin Pedrol ]
 | 
			
		||||
  * oml: Store RSL connect related fields in bb_transc
 | 
			
		||||
  * Move trx->rsl_link to trx->bb_transc.rsl.link
 | 
			
		||||
  * nm: delay RSL connect until BBTRANSC object is OPSTARTed
 | 
			
		||||
  * cosmetic: oc2g_mgr: fix trailing whitespace
 | 
			
		||||
  * Drop use of deprectated vty callback is_config_node
 | 
			
		||||
  * Revert "trx_if: Allow calling trx_if_flush/close from within TRXC callback"
 | 
			
		||||
  * trx_if: Allow calling trx_if_flush/close from within TRXC callback (v2)
 | 
			
		||||
 | 
			
		||||
  [ Andreas Eversberg ]
 | 
			
		||||
  * ASCI: Ignore LAPD frames from MS, while the uplink is not active
 | 
			
		||||
  * Do not prefix UI header to System Information Type 10
 | 
			
		||||
  * Increase RR scheduler priority to 20, to avoid dropped bursts
 | 
			
		||||
  * ASCI: Add control of uplink access to osmo-bts-trx
 | 
			
		||||
  * ASCI: Add control of uplink access to osmo-bts-sysmo
 | 
			
		||||
  * ASCI: Enable voice group/broadcast call feature at osmo-bts-trx
 | 
			
		||||
  * ASCI: Control uplink access bursts detection of physical interface
 | 
			
		||||
  * ASCI: Add library requirements for uplink access to TODO-RELEASE
 | 
			
		||||
  * Use uniform log format for default config files
 | 
			
		||||
  * Transmit invalid AMR speech blocks instead of dummy FACCH
 | 
			
		||||
  * LAPDm: Reject (release) establishment on DCCH, SAPI 0 without L3 payload
 | 
			
		||||
  * Handle empty (idle) PDCH blocks gracefully
 | 
			
		||||
  * Use polling based LAPDm with frame numbers
 | 
			
		||||
  * OML: Add Get Attributes for supported MOs for BTS Object Class
 | 
			
		||||
  * OML: Add Get Attributes for supported MOs for Radio Carrier Object Class
 | 
			
		||||
  * OML: Add Get Attributes for supported MOs for Channel Object Class
 | 
			
		||||
  * Fix ASCI access burst detection with osmo-bts-trx
 | 
			
		||||
 | 
			
		||||
  [ Oliver Smith ]
 | 
			
		||||
  * systemd: remove RestartPreventExitStatus=1
 | 
			
		||||
  * contrib: remove rpm spec file
 | 
			
		||||
  * contrib/systemd: run as osmocom user
 | 
			
		||||
 | 
			
		||||
  [ Philipp Maier ]
 | 
			
		||||
  * pcuif_proto: rename PCU_IF_FLAG_SYSMO to PCU_IF_FLAG_DIRECT_PHY
 | 
			
		||||
  * pcuif_proto: clean up last remains of old PCUIF v10
 | 
			
		||||
  * pcuif_proto: signal BTS model via PCUIF
 | 
			
		||||
 | 
			
		||||
  [ Harald Welte ]
 | 
			
		||||
  * Add GSMTAP encapsulation of RLP frames in CSD NT mode
 | 
			
		||||
  * gsmtap-rlp: Add support for skipping generating NULL frames
 | 
			
		||||
  * Fix license headers.
 | 
			
		||||
  * sysmobts_mgr_temp: Migrate to ctrl_cmd_send2()
 | 
			
		||||
  * osmo-bts-virtual: Port over to osmo_io
 | 
			
		||||
  * common: Add RTP related rate counters
 | 
			
		||||
  * Add funding link to github mirror
 | 
			
		||||
  * README.md: Add Forum + Issue Tracker sections
 | 
			
		||||
 | 
			
		||||
  [ Matan Perelman ]
 | 
			
		||||
  * ctrl: Add max ber10k rach
 | 
			
		||||
 | 
			
		||||
  [ Neels Hofmeyr ]
 | 
			
		||||
  * early-IA: use the correct TRX
 | 
			
		||||
 | 
			
		||||
  [ Keith ]
 | 
			
		||||
  * vty info: MS power levels in dBm are not negative
 | 
			
		||||
 | 
			
		||||
  [ Mychaela N. Falconia ]
 | 
			
		||||
  * rsl.adoc: mention currently undocumented IEs
 | 
			
		||||
  * rsl: parse RSL_IE_OSMO_OSMUX_CID correctly
 | 
			
		||||
  * common: add support for TW-TS-001
 | 
			
		||||
 | 
			
		||||
 -- Oliver Smith <osmith@sysmocom.de>  Wed, 24 Jul 2024 16:40:02 +0200
 | 
			
		||||
 | 
			
		||||
osmo-bts (1.7.0) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  [ arehbein ]
 | 
			
		||||
  * common: Fix memleak in get_smscb_block()
 | 
			
		||||
  * doc: Adapt to use of 'telnet_init_default'
 | 
			
		||||
  * common: Remove redundant checks
 | 
			
		||||
  * common: Remove unused function gsm_objclass2nmstate()
 | 
			
		||||
  * gsm_objclass2mo(): Change signature/set NACK cause
 | 
			
		||||
  * gsm_objclass2obj(): Change signature/set NACK cause
 | 
			
		||||
  * PCU interface: Log version when starting listener
 | 
			
		||||
  * common: Have PCU socket connection use osmo_wqueue
 | 
			
		||||
  * common: Make socket queue max. length configurable
 | 
			
		||||
 | 
			
		||||
  [ Max ]
 | 
			
		||||
  * bts-virtual: fix segfault
 | 
			
		||||
  * osmo-bts-trx: log TRXC/TRXD connection address
 | 
			
		||||
  * osmo-bts-trx: use bool for true/false flags
 | 
			
		||||
  * GSMTAP: allow configuring local address
 | 
			
		||||
  * license: fix typos
 | 
			
		||||
 | 
			
		||||
  [ Vadim Yanitskiy ]
 | 
			
		||||
  * paging_add_imm_ass(): remove meaningless from_pcu argument
 | 
			
		||||
  * osmo-bts-{trx,virtual}: clean up bts_model_l1sap_down()
 | 
			
		||||
  * osmo-bts-{trx,virtual}: check lchan against NULL in bts_model_l1sap_down()
 | 
			
		||||
  * osmo-bts-{trx,virtual}: set rc on error in bts_model_l1sap_down()
 | 
			
		||||
  * GSMTAP: print 'gsmtap-local-host' if not NULL
 | 
			
		||||
  * osmo-bts-virtual: indicate BTS_FEAT_[E]GPRS to the BSC
 | 
			
		||||
  * rsl: remove redundant gsm_lchan_name() in rsl_tx_rf_rel_ack()
 | 
			
		||||
  * rsl: reduce logging verbosity on some messages
 | 
			
		||||
  * tests: use -no-install libtool flag to avoid ./lt-* scripts
 | 
			
		||||
  * scheduler: log pchan value in trx_sched_set_pchan()
 | 
			
		||||
  * osmo-bts-virtual: properly handle dynamic TS in vbts_set_ts()
 | 
			
		||||
  * contrib/osmo-bts.spec.in: do not depend on libosmogb
 | 
			
		||||
  * osmo-bts-trx: properly activate [CBCH/]BCCH/CCCH
 | 
			
		||||
  * rsl: rsl_handle_chan_mod_ie(): add missing GSM48_CMODE_* values
 | 
			
		||||
  * osmo-bts-{sysmo,lc15,oc2g}: fix segfault in ph_tch_req()
 | 
			
		||||
  * tests: $(BUILT_SOURCES) is not defined, depend on osmo-bts-virtual
 | 
			
		||||
  * osmo-bts-virtual: properly activate [CBCH/]BCCH/CCCH
 | 
			
		||||
  * flags: add missing entries to bts_impl_flag_desc[]
 | 
			
		||||
  * flags: group BTS_INTERNAL_FLAG_* into an enum
 | 
			
		||||
  * flags: ensure completeness of bts_impl_flag_desc[]
 | 
			
		||||
  * fixup: common: Remove unused function gsm_objclass2nmstate()
 | 
			
		||||
  * oml: gsm_objclass2{mo,obj}(): cosmetic: return immediately
 | 
			
		||||
  * oml: gsm_objclass2{mo,obj}(): set cause for unknown obj_class
 | 
			
		||||
  * oml: reset BCCH carrier power reduction mode (if enabled)
 | 
			
		||||
  * copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH
 | 
			
		||||
  * osmo-bts-trx: alloc/free burst buffers in trx_sched_set_lchan()
 | 
			
		||||
  * osmo-bts-trx: use direct pointer to chan_state->{ul,dl}_bursts
 | 
			
		||||
  * osmo-bts-trx: tch_dl_dequeue(): do not drop CSD frames
 | 
			
		||||
  * osmo-bts-trx: tx_pdtch_fn(): use msgb_l2len()
 | 
			
		||||
  * osmo-bts-trx: fix recent regression in Tx lchan handlers
 | 
			
		||||
  * osmo-bts-trx: remove redundant memset() on receipt of NOPE.ind
 | 
			
		||||
  * l1sap: use gsm0502_fn2ccch_block() from libosmogsm
 | 
			
		||||
  * scheduler: fix wrong union field in _sched_compose_tch_ind()
 | 
			
		||||
  * scheduler: use msgb_hexdump_l2() in _sched_compose_tch_ind()
 | 
			
		||||
  * scheduler: unify argument names/order for _sched_compose_*_ind()
 | 
			
		||||
  * scheduler: constify *data pointer in _sched_compose_*_ind()
 | 
			
		||||
  * scheduler: use size_t for data_len in _sched_compose_*_ind()
 | 
			
		||||
  * fix bts_supports_cm(): properly check feature flags for VGCS/VBS
 | 
			
		||||
  * measurement: suppress unsupported tch_mode warnings for CSD
 | 
			
		||||
  * osmo-bts-trx: pull the AMR header in tch_dl_dequeue()
 | 
			
		||||
  * osmo-bts-trx: implement CSD scheduling support
 | 
			
		||||
  * osmo-bts-trx: implement FACCH/[FH] support for CSD
 | 
			
		||||
  * osmo-bts-trx: implement TCH/F2.4 support for CSD
 | 
			
		||||
  * osmo-bts-trx: visualize rx_tch[fh]_fn() functions
 | 
			
		||||
  * osmo-bts-trx: unify and enrich 'Received bad data' logging
 | 
			
		||||
  * osmo-bts-trx: rx_tchf_fn(): move compute_ber10k() above
 | 
			
		||||
  * osmo-bts-trx: rx_tch[fh]_fn(): combine rc-checking ifs
 | 
			
		||||
  * osmo-bts-trx: change 'Received bad data' back to LOGL_DEBUG
 | 
			
		||||
  * osmo-bts-trx: tx_tch[fh]_fn(): fix NULL pointer dereference
 | 
			
		||||
  * osmo-bts-trx: document/clarify the meaning of BUFMAX=24
 | 
			
		||||
  * l1sap: proper rate adaptation for CSD (RFC4040 'clearmode')
 | 
			
		||||
  * csd_v110_rtp_encode(): properly set E1/E2/E3 bits
 | 
			
		||||
  * osmo-bts-trx: bts_supports_cm_data(): allow non-transparent modes
 | 
			
		||||
  * rsl: rsl_handle_chan_mod_ie(): set lchan->csd_mode
 | 
			
		||||
  * rsl: rsl_handle_chan_mod_ie(): do not use legacy defines
 | 
			
		||||
  * csd_v110: fix comments in csd_v110_rtp_{en,de}code()
 | 
			
		||||
  * csd_v110: properly set E1/E2/E3 for non-transparent data
 | 
			
		||||
  * csd_v110: handle empty/incomplete Uplink frames gracefully
 | 
			
		||||
 | 
			
		||||
  [ Philipp Maier ]
 | 
			
		||||
  * pcu_sock: rename rc to fd
 | 
			
		||||
  * pcu_sock: cosmetic: remove whitespace after type cast
 | 
			
		||||
  * pcu_sock: cosmetic: remove unnecessary line breaks
 | 
			
		||||
  * pcu_sock: do not mess with the osmo fd flags directly
 | 
			
		||||
  * sched_lchan_tchx: use GSM_HR_BYTES_RTP_RFC5993 constant
 | 
			
		||||
  * l1sap: fix wording in comment
 | 
			
		||||
  * pcu_sock: don not continue when running out of TRX space
 | 
			
		||||
  * paging: cosmetic: rename all IMM.ASS references to MAC block
 | 
			
		||||
  * paging: parse PCUIF data indication outside of paging.c
 | 
			
		||||
  * paging: do not confirm PAGING COMMAND messages
 | 
			
		||||
  * pcu_sock: move variable declaration of imsi[4] into related scope
 | 
			
		||||
  * l1sap: cosmetic: rename payload_len to rtp_pl_len
 | 
			
		||||
  * pcu_sock: use PCUIF version 11 (direct TLLI)
 | 
			
		||||
  * paging: also accept zero length IMSI strings 3
 | 
			
		||||
  * pcuif_proto: rename tlli to msg_id
 | 
			
		||||
  * pcu_sock: get rid of fn parameter in pcu_tx_pch_data_cnf
 | 
			
		||||
  * pcuif_proto: remove unnecessary members from gsm_pcu_if_data_cnf_dt
 | 
			
		||||
  * pcuif_proto: get rid of _DT, _dt (Direct TLLI)
 | 
			
		||||
  * bts: make bts_agch_dequeue static
 | 
			
		||||
  * pcuif_proto: use confirm flag in struct gsm_pcu_if_pch
 | 
			
		||||
  * pcu_sock: use PCU_IF_SAPI_AGCH_2 instead PCU_IF_SAPI_AGCH
 | 
			
		||||
  * pcu_sock: print SAPI and msg_id when sending confirmation
 | 
			
		||||
 | 
			
		||||
  [ Pau Espin Pedrol ]
 | 
			
		||||
  * bts-trx: Fix no NM Radio{Carrier,Channel} switching to Enabled if one TRX is rf_locked
 | 
			
		||||
  * pcu_sock: Submit all DATA.ind regardless of link quality
 | 
			
		||||
  * pcu_sock.c: Call osmo_fd_unregister() before closing and changing bfd->fd
 | 
			
		||||
  * Rewrite pcu_sock_write()
 | 
			
		||||
  * lchan: Improve error path logging in gsm_pchan2chan_nr()
 | 
			
		||||
  * cosmetic: gsm_pchan2chan_nr(): Update spec documentation
 | 
			
		||||
  * cosmetic: bts_trx.h: Fix whitespace
 | 
			
		||||
  * Avoid tx RF Resource Ind for disabled TRX
 | 
			
		||||
  * bts-trx: Avoid pushing interf_meas for disabled TRX
 | 
			
		||||
  * contrib/ber: Avoid regenerating codec_bit_class.h every build
 | 
			
		||||
  * bts-trx: Drop unused param to internal function
 | 
			
		||||
  * Clarify configuration of TSC on each timeslot
 | 
			
		||||
  * bts_model_apply_oml(): Drop unneded code
 | 
			
		||||
  * oml.c: Remove dot character at the end of log lines
 | 
			
		||||
  * nm: Apply BTS/TRX/TS OML Attributes through NM FSMs
 | 
			
		||||
  * nm: Drop NM_EV_SETATTR_{ACK/NACK}
 | 
			
		||||
  * oml: Get rid of unused tlv_parsed param in bts_model_apply_oml()
 | 
			
		||||
  * bts_model_apply_oml(): Improve definition of parameter
 | 
			
		||||
  * lc15,oc2g,sysmo: Update GPRS NM object state at the right time
 | 
			
		||||
  * Simplify implementation of bts_model_opstart() in all bts types
 | 
			
		||||
  * nm: Apply OPSTART through NM FSMs
 | 
			
		||||
  * NM: NACK received OML OPSTART if no attributes were set beforehand
 | 
			
		||||
  * Introduce NM FSM for GPRS NSE object
 | 
			
		||||
  * Fix octet 2 of NM GPRS Cell
 | 
			
		||||
  * Introduce NM FSM for GPRS Cell object
 | 
			
		||||
  * Rearrange declaration of struct gsm_bts_gprs_nsvc
 | 
			
		||||
  * Move NSVC structs to be part of NSE
 | 
			
		||||
  * bts: Simplify lifecycle of BTS inside bts_list
 | 
			
		||||
  * Introduce NM FSM for GPRS NSVC object
 | 
			
		||||
  * nm: Dispatch NM_EV_SW_ACT in cascade to BTS SiteMgr children
 | 
			
		||||
  * Merge gsm_network into gsm_bts_sm and place gsm_bts under it
 | 
			
		||||
  * Move GPRS NSE under BTS SiteMgr
 | 
			
		||||
  * Drop NM_EV_BBTRANSC_INSTALLED in favour of generic NM_EV_SW_ACT
 | 
			
		||||
  * nm: Document current state of SW_ACT in TRX related objects
 | 
			
		||||
  * Properly report all states through NM FSM upon OML link up
 | 
			
		||||
  * Update g_bts_sm->num_bts when bts is added/removed from bts list
 | 
			
		||||
  * Move pcu_sock_state to gprs section of bts_sm
 | 
			
		||||
  * pcu_sock: Allocate pcu_sock_state using g_bts_sm talloc context
 | 
			
		||||
  * pcu_sock: Drop bts_sm pointer
 | 
			
		||||
  * oml: Fix potential null ptr access on trx object
 | 
			
		||||
  * bts-sysmo: Fix pinst->version filled too early
 | 
			
		||||
  * bts-sysmo: Delay marking phy_link as connected until L1 reset + got info
 | 
			
		||||
  * vty.c: Use already available tpp pointer
 | 
			
		||||
  * octphy: Fix clearly wrong noop assignment
 | 
			
		||||
  * bbtransc/rcarrier: Fix statechg done twice upon NM_EV_RX_OPSTART
 | 
			
		||||
  * Increase PCUIF wqueue size
 | 
			
		||||
  * bts-trx: Fix CCCH not enabled if BS_AG_BLKS_RES!=1 is provided by BSC
 | 
			
		||||
  * rsl: Improve logic reactivating CCCH upon SI3 BS_AG_BLKS_RES change
 | 
			
		||||
 | 
			
		||||
  [ Oliver Smith ]
 | 
			
		||||
  * gitignore: add vty pdf
 | 
			
		||||
  * doc: rsl: add RSL_IE_IPAC_RTP_CSD_FORMAT
 | 
			
		||||
  * rsl_rx_ipac_XXcx: parse csd_fmt_d/ir
 | 
			
		||||
  * debian: set compat level to 10
 | 
			
		||||
  * systemd: depend on networking-online.target
 | 
			
		||||
  * gitignore: add arm-poky-linux-gnueabi-libtool
 | 
			
		||||
  * osmo-bts-sysmo: trx_mute_on_init_cb: call bts_update_status
 | 
			
		||||
  * osmo-bts-sysmo: activate_rf: no dispatch on fail
 | 
			
		||||
  * osmo-bts-sysmo/l1_if: move mute_rf_compl_cb up
 | 
			
		||||
  * osmo-bts-sysmo: mute PHY until OML is ready
 | 
			
		||||
 | 
			
		||||
  [ Harald Welte ]
 | 
			
		||||
  * DTX: bts-{sysmo,oc2g,lc15}: Print DEBUG messages about ONSET
 | 
			
		||||
  * cosmetic: Replace %i with %d
 | 
			
		||||
  * Introduce LOGPLCFN() for logging lchan-name + frame number
 | 
			
		||||
  * bts-{sysmo,oc2g,lc15}: Fix RTP of AMR SID_FIRST_P1
 | 
			
		||||
  * common/vty: Print AMR MultiRate Configuration in "show lchan"
 | 
			
		||||
  * bts-{sysmo,oc2g,lc15}: Dump logical channel params during MPH-ACTIVATE.req
 | 
			
		||||
  * cosmetic: use __func__ instead of __FUNCTION__
 | 
			
		||||
  * lc15: fix compiler warning about wrong indent
 | 
			
		||||
  * lc15: Remove unused warning
 | 
			
		||||
  * lc15/oc2g: remove unused variables
 | 
			
		||||
  * oc2g: Fix 'unused variable' compiler warning
 | 
			
		||||
  * cosmetic: Remove "FIXME?" from Odd AMR CMI phase
 | 
			
		||||
  * lc15: fix compiler warning about unused variable cell_size
 | 
			
		||||
  * Replace explicit gsm_lchan_name() calls with LOGPLCHAN
 | 
			
		||||
  * logging: Introduce LOGPLCGT()
 | 
			
		||||
  * cosmetic: Change LOGPLCFN argument order
 | 
			
		||||
  * paging: Add support for generating NLN/NLN-Status in P1 Rest Octets
 | 
			
		||||
  * Add ASCI (advanced speech call items) log sub-system
 | 
			
		||||
  * ASCI: NCH / NOTIFICATION support
 | 
			
		||||
  * validate RSL "channel rate and type" against VGCS/VBS flags
 | 
			
		||||
  * Store "Channel rate and type" from RSL Channel Mode IE in BTS
 | 
			
		||||
  * ASCI: VGCS/VBS RACH -> RSL TALKER/LISTENER DETECT
 | 
			
		||||
  * sysmo: Enable VGSCS + VBS feature flags
 | 
			
		||||
  * omldummy: Claim to support VBS + VGCS towards BSC
 | 
			
		||||
 | 
			
		||||
  [ Mychaela N. Falconia ]
 | 
			
		||||
  * trx: detect UL SID in EFR just like in FR
 | 
			
		||||
  * sysmo: fix handling of SID in EFR
 | 
			
		||||
  * common: implement rtp continuous-streaming mode
 | 
			
		||||
  * rtp continuous-streaming: fix BFI in the quality-suppressed case
 | 
			
		||||
  * sysmo: emit empty RTP ticks during FACCH stealing on TCH/F
 | 
			
		||||
  * bts-{lc15,oc2g,sysmo}: support EFR in repeat_last_sid()
 | 
			
		||||
  * RTP input, FR & EFR: preen incoming payloads for SID errors
 | 
			
		||||
  * lc15,oc2g: fix handling of SID in EFR
 | 
			
		||||
  * all models, FR/EFR UL: change SID check to _is_any_sid()
 | 
			
		||||
  * trx: remove model-specific BFI packet formats
 | 
			
		||||
  * refactor: replace rtppayload_is_valid() with preening before enqueue
 | 
			
		||||
  * all models, HR1 codec: accept both TS101318 and RFC5993 formats
 | 
			
		||||
  * trx: fix HR1 codec breakage from format change
 | 
			
		||||
  * trx, HR1 codec: change UL PHY output format to TS 101 318
 | 
			
		||||
  * all models, HR1 codec: select RTP output format via vty option
 | 
			
		||||
  * FR/HR/EFR TCH DL: implement DTX rules
 | 
			
		||||
  * HR1 codec: validate ToC header in RFC5993 RTP input
 | 
			
		||||
  * HR1 codec: act on SID indication in RFC5993 RTP input
 | 
			
		||||
  * trx TCH DL: transmit invalid speech blocks instead of dummy FACCH
 | 
			
		||||
  * ECU in UL path: make it optional per vty config
 | 
			
		||||
  * ECU in UL path: move state alloc/free to l1sap
 | 
			
		||||
  * ECU in UL path: move it from trx model to l1sap
 | 
			
		||||
 | 
			
		||||
  [ Sylvain Munaut ]
 | 
			
		||||
  * contrib: Add BER testing tool
 | 
			
		||||
 | 
			
		||||
  [ Andreas Eversberg ]
 | 
			
		||||
  * Change return value of bts_supports_cm() from int to bool
 | 
			
		||||
  * ASCI: Add function to reactivate channel
 | 
			
		||||
  * ASCI: Retrieve NCH position from System Information 1
 | 
			
		||||
  * ASCI: Add Notification CHannel (NCH) support
 | 
			
		||||
  * ASCI: Add support for rest octets in Paging request type 2 and 3
 | 
			
		||||
  * ASCI: Send only NLN on Paging request type 1 rest octets
 | 
			
		||||
  * ASCI: Add Notification/FACCH support
 | 
			
		||||
  * ASCI: Repeat UPLINK FREE message until uplink becomes busy
 | 
			
		||||
  * Add test cases for rest octets of Paging Requests
 | 
			
		||||
  * ASCI: Enable UPLINK ACCESS on various BTS models
 | 
			
		||||
 | 
			
		||||
  [ Keith ]
 | 
			
		||||
  * Fix incorrect order of params passed to logging macro
 | 
			
		||||
 | 
			
		||||
 -- Pau Espin Pedrol <pespin@sysmocom.de>  Tue, 12 Sep 2023 16:05:30 +0200
 | 
			
		||||
 | 
			
		||||
osmo-bts (1.6.0) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  [ Vadim Yanitskiy ]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/compat
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/compat
									
									
									
									
										vendored
									
									
								
							@@ -1 +1 @@
 | 
			
		||||
9
 | 
			
		||||
10
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@@ -2,17 +2,17 @@ Source: osmo-bts
 | 
			
		||||
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
 | 
			
		||||
Section: net
 | 
			
		||||
Priority: optional
 | 
			
		||||
Build-Depends: debhelper (>= 9),
 | 
			
		||||
Build-Depends: debhelper (>= 10),
 | 
			
		||||
               pkg-config,
 | 
			
		||||
               dh-autoreconf,
 | 
			
		||||
               autotools-dev,
 | 
			
		||||
               pkg-config,
 | 
			
		||||
               libosmocore-dev (>= 1.8.0),
 | 
			
		||||
               libosmo-abis-dev (>= 1.4.0),
 | 
			
		||||
               libosmo-netif-dev (>= 1.3.0),
 | 
			
		||||
               libosmocore-dev (>= 1.11.0),
 | 
			
		||||
               libosmo-abis-dev (>= 2.0.0),
 | 
			
		||||
               libosmo-netif-dev (>= 1.6.0),
 | 
			
		||||
               libgps-dev,
 | 
			
		||||
               txt2man,
 | 
			
		||||
               osmo-gsm-manuals-dev (>= 1.4.0)
 | 
			
		||||
               osmo-gsm-manuals-dev (>= 1.6.0)
 | 
			
		||||
Standards-Version: 3.9.8
 | 
			
		||||
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
 | 
			
		||||
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								debian/osmo-bts-trx.postinst
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								debian/osmo-bts-trx.postinst
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
#!/bin/sh -e
 | 
			
		||||
case "$1" in
 | 
			
		||||
	configure)
 | 
			
		||||
		# Create the osmocom group and user (if it doesn't exist yet)
 | 
			
		||||
		if ! getent group osmocom >/dev/null; then
 | 
			
		||||
			groupadd --system osmocom
 | 
			
		||||
		fi
 | 
			
		||||
		if ! getent passwd osmocom >/dev/null; then
 | 
			
		||||
			useradd \
 | 
			
		||||
				--system \
 | 
			
		||||
				--gid osmocom \
 | 
			
		||||
				--home-dir /var/lib/osmocom \
 | 
			
		||||
				--shell /sbin/nologin \
 | 
			
		||||
				--comment "Open Source Mobile Communications" \
 | 
			
		||||
				osmocom
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# Fix permissions of previous (root-owned) install (OS#4107)
 | 
			
		||||
		if dpkg --compare-versions "$2" le "1.13.0"; then
 | 
			
		||||
			if [ -e /etc/osmocom/osmo-bts-trx.cfg ]; then
 | 
			
		||||
				chown -v osmocom:osmocom /etc/osmocom/osmo-bts-trx.cfg
 | 
			
		||||
				chmod -v 0660 /etc/osmocom/osmo-bts-trx.cfg
 | 
			
		||||
			fi
 | 
			
		||||
 | 
			
		||||
			if [ -d /etc/osmocom ]; then
 | 
			
		||||
				chown -v root:osmocom /etc/osmocom
 | 
			
		||||
				chmod -v 2775 /etc/osmocom
 | 
			
		||||
			fi
 | 
			
		||||
 | 
			
		||||
			mkdir -p /var/lib/osmocom
 | 
			
		||||
			chown -R -v osmocom:osmocom /var/lib/osmocom
 | 
			
		||||
		fi
 | 
			
		||||
		;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
# dh_installdeb(1) will replace this with shell code automatically
 | 
			
		||||
# generated by other debhelper scripts.
 | 
			
		||||
#DEBHELPER#
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								debian/osmo-bts-virtual.postinst
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								debian/osmo-bts-virtual.postinst
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
#!/bin/sh -e
 | 
			
		||||
case "$1" in
 | 
			
		||||
	configure)
 | 
			
		||||
		# Create the osmocom group and user (if it doesn't exist yet)
 | 
			
		||||
		if ! getent group osmocom >/dev/null; then
 | 
			
		||||
			groupadd --system osmocom
 | 
			
		||||
		fi
 | 
			
		||||
		if ! getent passwd osmocom >/dev/null; then
 | 
			
		||||
			useradd \
 | 
			
		||||
				--system \
 | 
			
		||||
				--gid osmocom \
 | 
			
		||||
				--home-dir /var/lib/osmocom \
 | 
			
		||||
				--shell /sbin/nologin \
 | 
			
		||||
				--comment "Open Source Mobile Communications" \
 | 
			
		||||
				osmocom
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# Fix permissions of previous (root-owned) install (OS#4107)
 | 
			
		||||
		if dpkg --compare-versions "$2" le "1.13.0"; then
 | 
			
		||||
			if [ -e /etc/osmocom/osmo-bts-virtual.cfg ]; then
 | 
			
		||||
				chown -v osmocom:osmocom /etc/osmocom/osmo-bts-virtual.cfg
 | 
			
		||||
				chmod -v 0660 /etc/osmocom/osmo-bts-virtual.cfg
 | 
			
		||||
			fi
 | 
			
		||||
 | 
			
		||||
			if [ -d /etc/osmocom ]; then
 | 
			
		||||
				chown -v root:osmocom /etc/osmocom
 | 
			
		||||
				chmod -v 2775 /etc/osmocom
 | 
			
		||||
			fi
 | 
			
		||||
 | 
			
		||||
			mkdir -p /var/lib/osmocom
 | 
			
		||||
			chown -R -v osmocom:osmocom /var/lib/osmocom
 | 
			
		||||
		fi
 | 
			
		||||
		;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
# dh_installdeb(1) will replace this with shell code automatically
 | 
			
		||||
# generated by other debhelper scripts.
 | 
			
		||||
#DEBHELPER#
 | 
			
		||||
 | 
			
		||||
@@ -1,16 +1,29 @@
 | 
			
		||||
OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg
 | 
			
		||||
# all config examples must be listed here unconditionally, so that
 | 
			
		||||
# all of them end up in the release tarball (see OS#6349)
 | 
			
		||||
EXTRA_DIST = \
 | 
			
		||||
	trx/osmo-bts-trx.cfg \
 | 
			
		||||
	trx/osmo-bts-trx-calypso.cfg \
 | 
			
		||||
	octphy/osmo-bts-trx2dsp1.cfg \
 | 
			
		||||
	octphy/osmo-bts-octphy.cfg \
 | 
			
		||||
	oc2g/osmo-bts-oc2g.cfg \
 | 
			
		||||
	oc2g/oc2gbts-mgr.cfg \
 | 
			
		||||
	sysmo/sysmobts-mgr.cfg \
 | 
			
		||||
	sysmo/osmo-bts-sysmo.cfg \
 | 
			
		||||
	litecell15/osmo-bts-lc15.cfg \
 | 
			
		||||
	litecell15/lc15bts-mgr.cfg \
 | 
			
		||||
	virtual/osmo-bts-virtual.cfg \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
doc_virtualdir = $(docdir)/examples/osmo-bts-virtual
 | 
			
		||||
doc_virtual_DATA = \
 | 
			
		||||
        virtual/osmo-bts-virtual.cfg
 | 
			
		||||
EXTRA_DIST = $(doc_virtual_DATA)
 | 
			
		||||
OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg
 | 
			
		||||
 | 
			
		||||
if ENABLE_SYSMOBTS
 | 
			
		||||
doc_sysmodir = $(docdir)/examples/osmo-bts-sysmo
 | 
			
		||||
doc_sysmo_DATA = \
 | 
			
		||||
        sysmo/osmo-bts-sysmo.cfg \
 | 
			
		||||
        sysmo/sysmobts-mgr.cfg
 | 
			
		||||
EXTRA_DIST += $(doc_sysmo_DATA)
 | 
			
		||||
OSMOCONF_FILES += sysmo/osmo-bts-sysmo.cfg sysmo/sysmobts-mgr.cfg
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
@@ -19,7 +32,6 @@ doc_trxdir = $(docdir)/examples/osmo-bts-trx
 | 
			
		||||
doc_trx_DATA = \
 | 
			
		||||
        trx/osmo-bts-trx.cfg \
 | 
			
		||||
        trx/osmo-bts-trx-calypso.cfg
 | 
			
		||||
EXTRA_DIST += $(doc_trx_DATA)
 | 
			
		||||
OSMOCONF_FILES += trx/osmo-bts-trx.cfg
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
@@ -28,7 +40,6 @@ doc_octphydir = $(docdir)/examples/osmo-bts-octphy
 | 
			
		||||
doc_octphy_DATA = \
 | 
			
		||||
        octphy/osmo-bts-trx2dsp1.cfg \
 | 
			
		||||
        octphy/osmo-bts-octphy.cfg
 | 
			
		||||
EXTRA_DIST += $(doc_octphy_DATA)
 | 
			
		||||
OSMOCONF_FILES += octphy/osmo-bts-octphy.cfg
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
@@ -37,7 +48,6 @@ doc_lc15dir = $(docdir)/examples/osmo-bts-lc15
 | 
			
		||||
doc_lc15_DATA = \
 | 
			
		||||
        litecell15/osmo-bts-lc15.cfg \
 | 
			
		||||
        litecell15/lc15bts-mgr.cfg
 | 
			
		||||
EXTRA_DIST += $(doc_lc15_DATA)
 | 
			
		||||
OSMOCONF_FILES += litecell15/osmo-bts-lc15.cfg litecell15/lc15bts-mgr.cfg
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
@@ -46,7 +56,6 @@ doc_oc2gdir = $(docdir)/examples/osmo-bts-oc2g
 | 
			
		||||
doc_oc2g_DATA = \
 | 
			
		||||
        oc2g/osmo-bts-oc2g.cfg \
 | 
			
		||||
        oc2g/oc2gbts-mgr.cfg
 | 
			
		||||
EXTRA_DIST += $(doc_oc2g_DATA)
 | 
			
		||||
OSMOCONF_FILES += oc2g/osmo-bts-oc2g.cfg oc2g/oc2gbts-mgr.cfg
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,12 @@
 | 
			
		||||
!!
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
 logging filter all 1
 | 
			
		||||
 logging color 1
 | 
			
		||||
 logging print category 0
 | 
			
		||||
 logging print category-hex 0
 | 
			
		||||
 logging print category 1
 | 
			
		||||
 logging timestamp 0
 | 
			
		||||
 logging print file basename last
 | 
			
		||||
 logging print level 1
 | 
			
		||||
 logging level temp info
 | 
			
		||||
 logging level fw info
 | 
			
		||||
 logging level find info
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,11 @@
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
 logging color 1
 | 
			
		||||
 logging print category-hex 0
 | 
			
		||||
 logging print category 1
 | 
			
		||||
 logging timestamp 0
 | 
			
		||||
 logging print file basename last
 | 
			
		||||
 logging print level 1
 | 
			
		||||
 logging level rsl info
 | 
			
		||||
 logging level oml info
 | 
			
		||||
 logging level rll notice
 | 
			
		||||
@@ -35,7 +39,7 @@ phy 1
 | 
			
		||||
  trx-calibration-path /mnt/rom/factory/calib
 | 
			
		||||
bts 0
 | 
			
		||||
 band 900
 | 
			
		||||
 ipa unit-id 1500 0
 | 
			
		||||
 ipa unit-id 6969 0
 | 
			
		||||
 oml remote-ip 192.168.234.185
 | 
			
		||||
 trx 0
 | 
			
		||||
  phy 0 instance 0
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,12 @@
 | 
			
		||||
!!
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
  logging filter all 1
 | 
			
		||||
  logging color 1
 | 
			
		||||
  logging print category 0
 | 
			
		||||
  logging print category-hex 0
 | 
			
		||||
  logging print category 1
 | 
			
		||||
  logging timestamp 0
 | 
			
		||||
  logging print file basename last
 | 
			
		||||
  logging print level 1
 | 
			
		||||
  logging level temp info
 | 
			
		||||
  logging level fw info
 | 
			
		||||
  logging level find info
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,11 @@
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
  logging color 1
 | 
			
		||||
  logging print category-hex 0
 | 
			
		||||
  logging print category 1
 | 
			
		||||
  logging timestamp 0
 | 
			
		||||
  logging print file basename last
 | 
			
		||||
  logging print level 1
 | 
			
		||||
  logging level rsl info
 | 
			
		||||
  logging level oml info
 | 
			
		||||
  logging level rll notice
 | 
			
		||||
@@ -32,7 +36,7 @@ phy 0
 | 
			
		||||
  trx-calibration-path /mnt/rom/factory/calib
 | 
			
		||||
bts 0
 | 
			
		||||
 band 900
 | 
			
		||||
 ipa unit-id 1500 0
 | 
			
		||||
 ipa unit-id 6969 0
 | 
			
		||||
 oml remote-ip 10.42.0.1
 | 
			
		||||
 trx 0
 | 
			
		||||
  phy 0 instance 0
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,11 @@
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
 logging color 1
 | 
			
		||||
 logging print category-hex 0
 | 
			
		||||
 logging print category 1
 | 
			
		||||
 logging timestamp 0
 | 
			
		||||
 logging print file basename last
 | 
			
		||||
 logging print level 1
 | 
			
		||||
 logging level rsl info
 | 
			
		||||
 logging level oml info
 | 
			
		||||
 logging level rll notice
 | 
			
		||||
@@ -25,7 +29,7 @@ phy 0
 | 
			
		||||
 instance 0
 | 
			
		||||
bts 0
 | 
			
		||||
 band 1800
 | 
			
		||||
 ipa unit-id 1234 0
 | 
			
		||||
 ipa unit-id 6969 0
 | 
			
		||||
 oml remote-ip 127.0.0.1
 | 
			
		||||
 trx 0
 | 
			
		||||
  phy 0 instance 0
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,11 @@
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
 logging color 1
 | 
			
		||||
 logging print category-hex 0
 | 
			
		||||
 logging print category 1
 | 
			
		||||
 logging timestamp 0
 | 
			
		||||
 logging print file basename last
 | 
			
		||||
 logging print level 1
 | 
			
		||||
 logging level rsl info
 | 
			
		||||
 logging level oml info
 | 
			
		||||
 logging level rll notice
 | 
			
		||||
@@ -26,7 +30,7 @@ phy 0
 | 
			
		||||
 instance 1
 | 
			
		||||
bts 0
 | 
			
		||||
 band 1800
 | 
			
		||||
 ipa unit-id 1234 0
 | 
			
		||||
 ipa unit-id 6969 0
 | 
			
		||||
 oml remote-ip 127.0.0.1
 | 
			
		||||
 trx 0
 | 
			
		||||
  phy 0 instance 0
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,11 @@
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
 logging color 1
 | 
			
		||||
 logging print category-hex 0
 | 
			
		||||
 logging print category 1
 | 
			
		||||
 logging timestamp 0
 | 
			
		||||
 logging print file basename last
 | 
			
		||||
 logging print level 1
 | 
			
		||||
 logging level rsl info
 | 
			
		||||
 logging level oml info
 | 
			
		||||
 logging level rll notice
 | 
			
		||||
@@ -23,7 +27,7 @@ phy 0
 | 
			
		||||
 instance 0
 | 
			
		||||
bts 0
 | 
			
		||||
 band 1800
 | 
			
		||||
 ipa unit-id 666 0
 | 
			
		||||
 ipa unit-id 6969 0
 | 
			
		||||
 oml remote-ip 10.1.2.3
 | 
			
		||||
 trx 0
 | 
			
		||||
  phy 0 instance 0
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,12 @@
 | 
			
		||||
!!
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
 logging filter all 1
 | 
			
		||||
 logging color 1
 | 
			
		||||
 logging print category-hex 0
 | 
			
		||||
 logging print category 1
 | 
			
		||||
 logging timestamp 0
 | 
			
		||||
 logging print file basename last
 | 
			
		||||
 logging print level 1
 | 
			
		||||
 logging level temp info
 | 
			
		||||
 logging level fw info
 | 
			
		||||
 logging level find info
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,11 @@
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
 logging color 1
 | 
			
		||||
 logging print category-hex 0
 | 
			
		||||
 logging print category 1
 | 
			
		||||
 logging timestamp 0
 | 
			
		||||
 logging print file basename last
 | 
			
		||||
 logging print level 1
 | 
			
		||||
 logging level rsl notice
 | 
			
		||||
 logging level oml notice
 | 
			
		||||
 logging level rll notice
 | 
			
		||||
@@ -30,8 +34,6 @@ phy 0
 | 
			
		||||
bts 0
 | 
			
		||||
 oml remote-ip 127.0.0.1
 | 
			
		||||
 ipa unit-id 6969 0
 | 
			
		||||
 gsmtap-sapi pdtch
 | 
			
		||||
 gsmtap-sapi ccch
 | 
			
		||||
 band 900
 | 
			
		||||
 trx 0
 | 
			
		||||
  phy 0 instance 0
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,11 @@
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
 logging color 1
 | 
			
		||||
 logging print category-hex 0
 | 
			
		||||
 logging print category 1
 | 
			
		||||
 logging timestamp 0
 | 
			
		||||
 logging print file basename last
 | 
			
		||||
 logging print level 1
 | 
			
		||||
 logging level rsl notice
 | 
			
		||||
 logging level oml notice
 | 
			
		||||
 logging level rll notice
 | 
			
		||||
@@ -26,8 +30,6 @@ phy 0
 | 
			
		||||
bts 0
 | 
			
		||||
 band 1800
 | 
			
		||||
 ipa unit-id 6969 0
 | 
			
		||||
 oml remote-ip 192.168.122.1
 | 
			
		||||
 gsmtap-sapi ccch
 | 
			
		||||
 gsmtap-sapi pdtch
 | 
			
		||||
 oml remote-ip 127.0.0.1
 | 
			
		||||
 trx 0
 | 
			
		||||
  phy 0 instance 0
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,12 @@
 | 
			
		||||
!!
 | 
			
		||||
!
 | 
			
		||||
log stderr
 | 
			
		||||
 logging filter all 1
 | 
			
		||||
 logging color 0
 | 
			
		||||
 logging color 1
 | 
			
		||||
 logging print category-hex 0
 | 
			
		||||
 logging print category 1
 | 
			
		||||
 logging timestamp 0
 | 
			
		||||
 logging print file basename last
 | 
			
		||||
 logging print level 1
 | 
			
		||||
 logging level rsl info
 | 
			
		||||
 logging level oml info
 | 
			
		||||
 logging level rll notice
 | 
			
		||||
 
 | 
			
		||||
@@ -517,6 +517,7 @@ number*.
 | 
			
		||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
 | 
			
		||||
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
 | 
			
		||||
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
 | 
			
		||||
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
 | 
			
		||||
|===
 | 
			
		||||
 | 
			
		||||
[[rsl_crcx_msg_ack]]
 | 
			
		||||
@@ -577,6 +578,7 @@ properties of a user-plane RTP connection.
 | 
			
		||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
 | 
			
		||||
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
 | 
			
		||||
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
 | 
			
		||||
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
 | 
			
		||||
|===
 | 
			
		||||
 | 
			
		||||
[[rsl_mdcx_msg_ack]]
 | 
			
		||||
@@ -865,6 +867,8 @@ addition to those indicated in 3GPP TS 48.058 Section 9.3:
 | 
			
		||||
| 0x01 | RSL_IE_CHAN_NR | <<RSL_IE_CHAN_NR>>
 | 
			
		||||
| 0x60 | RSL_IE_OSMO_REP_ACCH_CAP | <<RSL_IE_OSMO_REP_ACCH_CAP>>
 | 
			
		||||
| 0x61 | RSL_IE_OSMO_TRAINING_SEQUENCE | <<RSL_IE_OSMO_TRAINING_SEQUENCE>>
 | 
			
		||||
| 0x62 | RSL_IE_OSMO_TEMP_OVP_ACCH_CAP | <<RSL_IE_OSMO_TEMP_OVP_ACCH_CAP>>
 | 
			
		||||
| 0x63 | RSL_IE_OSMO_OSMUX_CID | <<RSL_IE_OSMO_OSMUX_CID>>
 | 
			
		||||
| 0xf0 | RSL_IE_IPAC_REMOTE_IP | <<RSL_IE_IPAC_REMOTE_IP>>
 | 
			
		||||
| 0xf1 | RSL_IE_IPAC_REMOTE_PORT | <<RSL_IE_IPAC_REMOTE_PORT>>
 | 
			
		||||
| 0xf3 | RSL_IE_IPAC_LOCAL_PORT | <<RSL_IE_IPAC_LOCAL_PORT>>
 | 
			
		||||
@@ -872,6 +876,7 @@ addition to those indicated in 3GPP TS 48.058 Section 9.3:
 | 
			
		||||
| 0xf5 | RSL_IE_IPAC_LOCAL_IP | <<RSL_IE_IPAC_LOCAL_IP>>
 | 
			
		||||
| 0xf6 | RSL_IE_IPAC_CONN_STAT | <<RSL_IE_IPAC_CONN_STAT>>
 | 
			
		||||
| 0xf8 | RSL_IE_IPAC_CONN_ID | <<RSL_IE_IPAC_CONN_ID>>
 | 
			
		||||
| 0xf9 | RSL_IE_IPAC_RTP_CSD_FORMAT | <<RSL_IE_IPAC_RTP_CSD_FORMAT>>
 | 
			
		||||
| 0xfc | RSL_IE_IPAC_RTP_PAYLOAD2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>>
 | 
			
		||||
|===
 | 
			
		||||
 | 
			
		||||
@@ -1086,6 +1091,49 @@ for future use.
 | 
			
		||||
| 8..255 | reserved values
 | 
			
		||||
|===
 | 
			
		||||
 | 
			
		||||
[[RSL_IE_OSMO_TEMP_OVP_ACCH_CAP]]
 | 
			
		||||
==== RSL_IE_OSMO_TEMP_OVP_ACCH_CAP
 | 
			
		||||
 | 
			
		||||
FIXME: this IE has been defined, but remains to be documented.
 | 
			
		||||
 | 
			
		||||
[[RSL_IE_OSMO_OSMUX_CID]]
 | 
			
		||||
==== RSL_IE_OSMO_OSMUX_CID
 | 
			
		||||
 | 
			
		||||
FIXME: this IE has been defined, but remains to be documented.
 | 
			
		||||
 | 
			
		||||
[[RSL_IE_IPAC_RTP_CSD_FORMAT]]
 | 
			
		||||
==== RSL_IE_IPAC_RTP_CSD_FORMAT
 | 
			
		||||
 | 
			
		||||
This information element contains the RTP Circuit Switched Data format.
 | 
			
		||||
 | 
			
		||||
.A-bis/IP RTP CSD Format
 | 
			
		||||
[options="header",width="60%",cols="15%,15%,70%"]
 | 
			
		||||
|===
 | 
			
		||||
| Offset | Size | Description
 | 
			
		||||
| 0 | 4 | RTP CSD Format D
 | 
			
		||||
| 4 | 4 | RTP CSD Format IR
 | 
			
		||||
|===
 | 
			
		||||
 | 
			
		||||
.A-bis/IP RTP CSD Format D Values
 | 
			
		||||
[options="header",width="40%",cols="20%,80%"]
 | 
			
		||||
|===
 | 
			
		||||
| Value | Description
 | 
			
		||||
| 0 | External TRAU format
 | 
			
		||||
| 1 | Non-TRAU Packed format
 | 
			
		||||
| 2 | TRAU within the BTS
 | 
			
		||||
| 3 | IWF-Free BTS-BTS Data
 | 
			
		||||
|===
 | 
			
		||||
 | 
			
		||||
.A-bis/IP RTP CSD Format IR Values
 | 
			
		||||
[options="header",width="40%",cols="20%,80%"]
 | 
			
		||||
|===
 | 
			
		||||
| Value | Description
 | 
			
		||||
| 0 | 8 kb/s
 | 
			
		||||
| 1 | 16 kb/s
 | 
			
		||||
| 2 | 32 kb/s
 | 
			
		||||
| 3 | 48 kb/s
 | 
			
		||||
|===
 | 
			
		||||
 | 
			
		||||
=== A-bis RSL Initialization / BTS bring-up
 | 
			
		||||
 | 
			
		||||
Upon receiving the 'IPA RSL CONNECT' OML message by the respective
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,7 @@ order to specify which PHY instance is allocated to this specific TRX.
 | 
			
		||||
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
 | 
			
		||||
| common | bts_controlif_setup() | Initialization of Control Interface
 | 
			
		||||
| bts-specific | bts_model_ctrl_cmds_install() | Install model-specific control interface commands
 | 
			
		||||
| common | telnet_init() | Initialization of telnet interface
 | 
			
		||||
| common | telnet_init_default() | Initialization of telnet interface
 | 
			
		||||
| common | pcu_sock_init() | Initialization of PCU socket
 | 
			
		||||
| common | main() | Installation of signal handlers
 | 
			
		||||
| common | abis_open() | Start of the A-bis connection to BSC
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ The start-up procedure of OsmoBTS can be described as follows:
 | 
			
		||||
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
 | 
			
		||||
| common | bts_controlif_setup() | Initialization of Control Interface
 | 
			
		||||
| bts-specific | bts_model_ctrl_cmds_install()
 | 
			
		||||
| common | telnet_init() | Initialization of telnet interface
 | 
			
		||||
| common | telnet_init_default() | Initialization of telnet interface
 | 
			
		||||
| common | pcu_sock_init() | Initialization of PCU socket
 | 
			
		||||
| common | main() | Installation of signal handlers
 | 
			
		||||
| common | abis_open() | Start of the A-bis connection to BSC
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										98
									
								
								doc/trx_sched_tch.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								doc/trx_sched_tch.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
== rx_tchf_fn(): TCH/FS, TCH/EFS, TCH/AFS, TCH/F2.4, and FACCH/F
 | 
			
		||||
 | 
			
		||||
  00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16  17  18  19  20  21  22  23
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d |  Rx bid={0,1,2,3}, decode
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d | e | f | g | h |  Rx bid={0,1,2,3}, decode
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
                                                                |
 | 
			
		||||
                                                                |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|  frame A
 | 
			
		||||
                                                                |               |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|  frame B
 | 
			
		||||
                                                                @ decoding from here
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== rx_tchf_fn(): TCH/F14.4, TCH/F9.6, TCH/F4.8
 | 
			
		||||
 | 
			
		||||
  00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16  17  18  19  20  21  22  23
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d |  Rx bid={0,1,2,3}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d | e | f | g | h |  Rx bid={0,1,2,3}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d | e | f | g | h | i | j | k | l |  Rx bid={0,1,2,3}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
|   |   |   |   |   |   |   |   | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p |  Rx bid={0,1,2,3}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
|   |   |   |   | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t |  Rx bid={0,1,2,3}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x |  Rx bid={0,1,2,3}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 4
 | 
			
		||||
|
 | 
			
		||||
|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|  frame A
 | 
			
		||||
|               |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|  frame B
 | 
			
		||||
@ decoding from here
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== rx_tchh_fn(): TCH/HS, TCH/AHS
 | 
			
		||||
 | 
			
		||||
  00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16  17  18  19  20  21  22  23
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d | e | f |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
                                                                |
 | 
			
		||||
                                                                |<~~~~~~~~~~~~~>|  frame A
 | 
			
		||||
                                                                |       |<~~~~~~~~~~~~~>|  frame B
 | 
			
		||||
                                                                @ decoding from here
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== rx_tchh_fn(): FACCH/H
 | 
			
		||||
 | 
			
		||||
  00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16  17  18  19  20  21  22  23
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d |   |   |  Rx bid={0,1}
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d | e | f |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
                                                                |
 | 
			
		||||
                                                                |<~~~~~~~~~~~~~~~~~~~~~>|  frame A
 | 
			
		||||
                                                                |               |<~~~~~~~~~~~~~~~~~~~~~>|  frame B
 | 
			
		||||
                                                                @ decoding from here
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== rx_tchh_fn(): TCH/H4.8, TCH/H2.4
 | 
			
		||||
 | 
			
		||||
  00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16  17  18  19  20  21  22  23
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d |   |   |  Rx bid={0,1}
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d | e | f |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d | e | f | g | h |   |   |  Rx bid={0,1}
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   |   |   | a | b | c | d | e | f | g | h | i | j |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   |   |   | a | b | c | d | e | f | g | h | i | j | k | l |   |   |  Rx bid={0,1}
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   |   |   | a | b | c | d | e | f | g | h | i | j | k | l | m | n |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   |   |   | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p |   |   |  Rx bid={0,1}
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   |   |   | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|   |   | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t |   |   |  Rx bid={0,1}
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v |   |   |  Rx bid={0,1}, decode
 | 
			
		||||
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  << 2
 | 
			
		||||
|
 | 
			
		||||
|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|  frame A
 | 
			
		||||
|               |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|  frame B
 | 
			
		||||
@ decoding from here
 | 
			
		||||
@@ -1,9 +1,11 @@
 | 
			
		||||
noinst_HEADERS = \
 | 
			
		||||
	abis.h \
 | 
			
		||||
	abis_osmo.h \
 | 
			
		||||
	asci.h \
 | 
			
		||||
	bts.h \
 | 
			
		||||
	bts_model.h \
 | 
			
		||||
	bts_shutdown_fsm.h \
 | 
			
		||||
	bts_sm.h \
 | 
			
		||||
	bts_trx.h \
 | 
			
		||||
	gsm_data.h \
 | 
			
		||||
	logging.h \
 | 
			
		||||
@@ -11,6 +13,7 @@ noinst_HEADERS = \
 | 
			
		||||
	oml.h \
 | 
			
		||||
	paging.h \
 | 
			
		||||
	rsl.h \
 | 
			
		||||
	rtp_input_preen.h \
 | 
			
		||||
	signal.h \
 | 
			
		||||
	vty.h \
 | 
			
		||||
	amr.h \
 | 
			
		||||
@@ -21,6 +24,8 @@ noinst_HEADERS = \
 | 
			
		||||
	tx_power.h \
 | 
			
		||||
	control_if.h \
 | 
			
		||||
	cbch.h \
 | 
			
		||||
	csd_rlp.h \
 | 
			
		||||
	csd_v110.h \
 | 
			
		||||
	l1sap.h \
 | 
			
		||||
	lchan.h \
 | 
			
		||||
	power_control.h \
 | 
			
		||||
@@ -30,5 +35,6 @@ noinst_HEADERS = \
 | 
			
		||||
	dtx_dl_amr_fsm.h \
 | 
			
		||||
	ta_control.h \
 | 
			
		||||
	nm_common_fsm.h \
 | 
			
		||||
	notification.h \
 | 
			
		||||
	osmux.h \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								include/osmo-bts/asci.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								include/osmo-bts/asci.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/lchan.h>
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	VGCS_TALKER_NONE = 0,
 | 
			
		||||
	VGCS_TALKER_WAIT_FRAME,
 | 
			
		||||
	VGCS_TALKER_ACTIVE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn);
 | 
			
		||||
 | 
			
		||||
void vgcs_lchan_activate(struct gsm_lchan *lchan);
 | 
			
		||||
 | 
			
		||||
void vgcs_lchan_react(struct gsm_lchan *lchan);
 | 
			
		||||
 | 
			
		||||
void vgcs_talker_frame(struct gsm_lchan *lchan);
 | 
			
		||||
 | 
			
		||||
void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access);
 | 
			
		||||
 | 
			
		||||
void vgcs_listener_reset(struct gsm_lchan *lchan);
 | 
			
		||||
 | 
			
		||||
static inline bool vgcs_is_uplink_free(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	return lchan->asci.uplink_free;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void vgcs_uplink_free_get(struct gsm_lchan *lchan, uint8_t *msg)
 | 
			
		||||
{
 | 
			
		||||
	memcpy(msg, lchan->asci.uplink_free_msg, GSM_MACBLOCK_LEN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void vgcs_uplink_free_set(struct gsm_lchan *lchan, uint8_t *msg)
 | 
			
		||||
{
 | 
			
		||||
	memcpy(lchan->asci.uplink_free_msg, msg, GSM_MACBLOCK_LEN);
 | 
			
		||||
	lchan->asci.uplink_free = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void vgcs_uplink_free_reset(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	lchan->asci.uplink_free = false;
 | 
			
		||||
}
 | 
			
		||||
@@ -25,11 +25,21 @@ enum {
 | 
			
		||||
	BTS_CTR_RACH_RCVD,
 | 
			
		||||
	BTS_CTR_RACH_DROP,
 | 
			
		||||
	BTS_CTR_RACH_HO,
 | 
			
		||||
	BTS_CTR_RACH_VGCS,
 | 
			
		||||
	BTS_CTR_RACH_CS,
 | 
			
		||||
	BTS_CTR_RACH_PS,
 | 
			
		||||
	BTS_CTR_AGCH_RCVD,
 | 
			
		||||
	BTS_CTR_AGCH_SENT,
 | 
			
		||||
	BTS_CTR_AGCH_DELETED,
 | 
			
		||||
 | 
			
		||||
	BTS_CTR_RTP_RX_TOTAL,
 | 
			
		||||
	BTS_CTR_RTP_RX_MARKER,
 | 
			
		||||
	BTS_CTR_RTP_RX_DROP_PREEN,
 | 
			
		||||
	BTS_CTR_RTP_RX_DROP_LOOPBACK,
 | 
			
		||||
	BTS_CTR_RTP_RX_DROP_OVERFLOW,
 | 
			
		||||
	BTS_CTR_RTP_RX_DROP_V110_DEC,
 | 
			
		||||
	BTS_CTR_RTP_TX_TOTAL,
 | 
			
		||||
	BTS_CTR_RTP_TX_MARKER,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Used by OML layer for BTS Attribute reporting */
 | 
			
		||||
@@ -53,36 +63,28 @@ enum gsm_bts_type_variant {
 | 
			
		||||
};
 | 
			
		||||
const char *btsvariant2str(enum gsm_bts_type_variant v);
 | 
			
		||||
 | 
			
		||||
/* TODO: add a brief description of this flag */
 | 
			
		||||
#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP		(1 << 0)
 | 
			
		||||
/* When this flag is set then the measurement data is included in
 | 
			
		||||
 * (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
 | 
			
		||||
 * measurement data is passed using a separate MPH INFO MEAS IND.
 | 
			
		||||
 * (See also ticket: OS#2977) */
 | 
			
		||||
#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB		(1 << 1)
 | 
			
		||||
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
 | 
			
		||||
 * (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
 | 
			
		||||
#define BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER	(1 << 2)
 | 
			
		||||
/* Whether the BTS model reports interference measurements to L1SAP. */
 | 
			
		||||
#define BTS_INTERNAL_FLAG_INTERF_MEAS			(1 << 3)
 | 
			
		||||
enum bts_impl_flag {
 | 
			
		||||
	/* TODO: add a brief description of this flag */
 | 
			
		||||
	BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP,
 | 
			
		||||
	/* When this flag is set then the measurement data is included in
 | 
			
		||||
	 * (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
 | 
			
		||||
	 * measurement data is passed using a separate MPH INFO MEAS IND.
 | 
			
		||||
	 * (See also ticket: OS#2977) */
 | 
			
		||||
	BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB,
 | 
			
		||||
	/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
 | 
			
		||||
	 * (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
 | 
			
		||||
	BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER,
 | 
			
		||||
	/* Whether the BTS model reports interference measurements to L1SAP. */
 | 
			
		||||
	BTS_INTERNAL_FLAG_INTERF_MEAS,
 | 
			
		||||
 | 
			
		||||
	_BTS_INTERNAL_FLAG_NUM, /* must be at the end */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* BTS implementation flags (internal use, not exposed via OML) */
 | 
			
		||||
#define bts_internal_flag_get(bts, flag) \
 | 
			
		||||
	((bts->flags & (typeof(bts->flags)) flag) != 0)
 | 
			
		||||
	((bts->flags & (typeof(bts->flags))(1 << flag)) != 0)
 | 
			
		||||
#define bts_internal_flag_set(bts, flag) \
 | 
			
		||||
	bts->flags |= (typeof(bts->flags)) flag
 | 
			
		||||
 | 
			
		||||
struct gsm_bts_gprs_nsvc {
 | 
			
		||||
	struct gsm_bts *bts;
 | 
			
		||||
	/* data read via VTY config file, to configure the BTS
 | 
			
		||||
	 * via OML from BSC */
 | 
			
		||||
	int id;
 | 
			
		||||
	uint16_t nsvci;
 | 
			
		||||
	struct osmo_sockaddr local;	/* on the BTS */
 | 
			
		||||
	struct osmo_sockaddr remote;	/* on the SGSN */
 | 
			
		||||
 | 
			
		||||
	struct gsm_abis_mo mo;
 | 
			
		||||
};
 | 
			
		||||
	bts->flags |= (typeof(bts->flags))(1 << flag)
 | 
			
		||||
 | 
			
		||||
struct gprs_rlc_cfg {
 | 
			
		||||
	uint16_t parameter[_NUM_RLC_PAR];
 | 
			
		||||
@@ -131,9 +133,15 @@ struct bts_power_ctrl_params {
 | 
			
		||||
	} pf;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* BTS Site Manager */
 | 
			
		||||
struct gsm_bts_sm {
 | 
			
		||||
/* GPRS CELL; ip.access specific NM Object */
 | 
			
		||||
struct gsm_gprs_cell {
 | 
			
		||||
	struct gsm_abis_mo mo;
 | 
			
		||||
	uint16_t bvci;
 | 
			
		||||
	uint8_t timer[11];
 | 
			
		||||
	struct gprs_rlc_cfg rlc_cfg;
 | 
			
		||||
	struct {
 | 
			
		||||
		uint32_t gprs_codings;	/* see NM_IPAC_F_GPRS_CODING_* flags */
 | 
			
		||||
	} support;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Struct that holds one OML-Address (Address of the BSC) */
 | 
			
		||||
@@ -142,9 +150,11 @@ struct bsc_oml_host {
 | 
			
		||||
	char *addr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT 100
 | 
			
		||||
 | 
			
		||||
/* One BTS */
 | 
			
		||||
struct gsm_bts {
 | 
			
		||||
	/* list header in net->bts_list */
 | 
			
		||||
	/* list header in g_bts_sm->bts_list */
 | 
			
		||||
	struct llist_head list;
 | 
			
		||||
 | 
			
		||||
	/* number of the BTS in network */
 | 
			
		||||
@@ -158,6 +168,7 @@ struct gsm_bts {
 | 
			
		||||
	/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
 | 
			
		||||
	 * which is used as TSC for the CCCH */
 | 
			
		||||
	uint8_t bsic;
 | 
			
		||||
	bool bsic_configured;
 | 
			
		||||
	/* type of BTS */
 | 
			
		||||
	enum gsm_bts_type_variant variant;
 | 
			
		||||
	enum gsm_band band;
 | 
			
		||||
@@ -193,7 +204,7 @@ struct gsm_bts {
 | 
			
		||||
	/* CCCH is on C0 */
 | 
			
		||||
	struct gsm_bts_trx *c0;
 | 
			
		||||
 | 
			
		||||
	struct gsm_bts_sm site_mgr;
 | 
			
		||||
	struct gsm_bts_sm *site_mgr;
 | 
			
		||||
 | 
			
		||||
	/* bitmask of all SI that are present/valid in si_buf */
 | 
			
		||||
	uint32_t si_valid;
 | 
			
		||||
@@ -223,18 +234,7 @@ struct gsm_bts {
 | 
			
		||||
 | 
			
		||||
	/* Not entirely sure how ip.access specific this is */
 | 
			
		||||
	struct {
 | 
			
		||||
		struct {
 | 
			
		||||
			struct gsm_abis_mo mo;
 | 
			
		||||
			uint16_t nsei;
 | 
			
		||||
			uint8_t timer[7];
 | 
			
		||||
		} nse;
 | 
			
		||||
		struct {
 | 
			
		||||
			struct gsm_abis_mo mo;
 | 
			
		||||
			uint16_t bvci;
 | 
			
		||||
			uint8_t timer[11];
 | 
			
		||||
			struct gprs_rlc_cfg rlc_cfg;
 | 
			
		||||
		} cell;
 | 
			
		||||
		struct gsm_bts_gprs_nsvc nsvc[2];
 | 
			
		||||
		struct gsm_gprs_cell cell;
 | 
			
		||||
		uint8_t rac;
 | 
			
		||||
	} gprs;
 | 
			
		||||
 | 
			
		||||
@@ -250,8 +250,9 @@ struct gsm_bts {
 | 
			
		||||
		int16_t boundary[6];
 | 
			
		||||
		uint8_t intave;
 | 
			
		||||
	} interference;
 | 
			
		||||
	unsigned int t200_ms[7];
 | 
			
		||||
	uint32_t t200_fn[7];
 | 
			
		||||
	unsigned int t3105_ms;
 | 
			
		||||
	unsigned int t3115_ms;	/* VGCS UPLINK GRANT repeat timer */
 | 
			
		||||
	struct {
 | 
			
		||||
		uint8_t overload_period;
 | 
			
		||||
		struct {
 | 
			
		||||
@@ -274,6 +275,7 @@ struct gsm_bts {
 | 
			
		||||
		} rach;
 | 
			
		||||
	} load;
 | 
			
		||||
	uint8_t ny1;
 | 
			
		||||
	uint8_t ny2;	/* maximum number of repetitions for the VGCS UPLINK GRANT */
 | 
			
		||||
	uint8_t max_ta;
 | 
			
		||||
 | 
			
		||||
	/* AGCH queuing */
 | 
			
		||||
@@ -303,6 +305,15 @@ struct gsm_bts {
 | 
			
		||||
		bool pni;		/* Primary Notification Identifier */
 | 
			
		||||
	} etws;
 | 
			
		||||
 | 
			
		||||
	/* Advanced Speech Call Items (VBS/VGCS) + NCH related bits */
 | 
			
		||||
	struct {
 | 
			
		||||
		int pos_nch;		/* position of the NCH or < 0, if not available */
 | 
			
		||||
		uint8_t nln, nln_status; /* current notification list number and status */
 | 
			
		||||
		struct llist_head notifications;
 | 
			
		||||
		int notification_entries; /* current number of entries in the list */
 | 
			
		||||
		int notification_count; /* counter to count all entries */
 | 
			
		||||
	} asci;
 | 
			
		||||
 | 
			
		||||
	struct paging_state *paging_state;
 | 
			
		||||
	struct llist_head bsc_oml_hosts;
 | 
			
		||||
	unsigned int rtp_jitter_buf_ms;
 | 
			
		||||
@@ -314,8 +325,13 @@ struct gsm_bts {
 | 
			
		||||
	int rtp_ip_dscp;
 | 
			
		||||
	int rtp_priority;
 | 
			
		||||
 | 
			
		||||
	bool rtp_nogaps_mode;		/* emit RTP stream without any gaps */
 | 
			
		||||
	bool use_ul_ecu;		/* "rtp internal-uplink-ecu" option */
 | 
			
		||||
	bool emit_hr_rfc5993;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		uint8_t ciphers;	/* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
 | 
			
		||||
		uint8_t max_ta;		/* maximum timing advance */
 | 
			
		||||
	} support;
 | 
			
		||||
	struct {
 | 
			
		||||
		uint8_t tc4_ctr;
 | 
			
		||||
@@ -360,14 +376,18 @@ struct gsm_bts {
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		char *sock_path;
 | 
			
		||||
		unsigned int sock_wqueue_len_max;
 | 
			
		||||
	} pcu;
 | 
			
		||||
 | 
			
		||||
	/* GSMTAP Um logging (disabled by default) */
 | 
			
		||||
	struct {
 | 
			
		||||
		struct gsmtap_inst *inst;
 | 
			
		||||
		char *remote_host;
 | 
			
		||||
		char *local_host;
 | 
			
		||||
		uint32_t sapi_mask;
 | 
			
		||||
		uint8_t sapi_acch;
 | 
			
		||||
		bool rlp;
 | 
			
		||||
		bool rlp_skip_null;
 | 
			
		||||
	} gsmtap;
 | 
			
		||||
 | 
			
		||||
	struct osmux_state osmux;
 | 
			
		||||
@@ -388,12 +408,13 @@ extern void *tall_bts_ctx;
 | 
			
		||||
#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
 | 
			
		||||
#define GSM_BTS_SI(bts, i)     (void *)((bts)->si_buf[i][0])
 | 
			
		||||
 | 
			
		||||
static inline struct gsm_bts *gsm_bts_sm_get_bts(struct gsm_bts_sm *site_mgr) {
 | 
			
		||||
	return (struct gsm_bts *)container_of(site_mgr, struct gsm_bts, site_mgr);
 | 
			
		||||
static inline struct gsm_bts *gsm_gprs_cell_get_bts(struct gsm_gprs_cell *cell)
 | 
			
		||||
{
 | 
			
		||||
	return (struct gsm_bts *)container_of(cell, struct gsm_bts, gprs.cell);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num);
 | 
			
		||||
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num);
 | 
			
		||||
struct gsm_bts *gsm_bts_alloc(struct gsm_bts_sm *bts_sm, uint8_t bts_num);
 | 
			
		||||
struct gsm_bts *gsm_bts_num(const struct gsm_bts_sm *bts_sm, int num);
 | 
			
		||||
 | 
			
		||||
int bts_init(struct gsm_bts *bts);
 | 
			
		||||
void bts_shutdown(struct gsm_bts *bts, const char *reason);
 | 
			
		||||
@@ -402,10 +423,15 @@ void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc, b
 | 
			
		||||
int bts_link_estab(struct gsm_bts *bts);
 | 
			
		||||
 | 
			
		||||
int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg);
 | 
			
		||||
struct msgb *bts_agch_dequeue(struct gsm_bts *bts);
 | 
			
		||||
int bts_agch_max_queue_length(int T, int bcch_conf);
 | 
			
		||||
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
 | 
			
		||||
		      int is_ag_res);
 | 
			
		||||
 | 
			
		||||
enum ccch_msgt {
 | 
			
		||||
	CCCH_MSGT_AGCH,
 | 
			
		||||
	CCCH_MSGT_PCH,
 | 
			
		||||
	CCCH_MSGT_NCH,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, enum ccch_msgt ccch);
 | 
			
		||||
int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher);
 | 
			
		||||
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time);
 | 
			
		||||
void regenerate_si3_restoctets(struct gsm_bts *bts);
 | 
			
		||||
@@ -421,8 +447,8 @@ struct gsm_time *get_time(struct gsm_bts *bts);
 | 
			
		||||
 | 
			
		||||
int bts_main(int argc, char **argv);
 | 
			
		||||
 | 
			
		||||
int bts_supports_cm(const struct gsm_bts *bts,
 | 
			
		||||
		    const struct rsl_ie_chan_mode *cm);
 | 
			
		||||
bool bts_supports_cm(const struct gsm_bts *bts,
 | 
			
		||||
		     const struct rsl_ie_chan_mode *cm);
 | 
			
		||||
 | 
			
		||||
int32_t bts_get_avg_fn_advance(const struct gsm_bts *bts);
 | 
			
		||||
 | 
			
		||||
@@ -431,4 +457,11 @@ struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
 | 
			
		||||
 | 
			
		||||
int bts_set_c0_pwr_red(struct gsm_bts *bts, const uint8_t red);
 | 
			
		||||
 | 
			
		||||
/* Context information to be put in the control buffer (db) of the AGCH msg
 | 
			
		||||
 * buffer */
 | 
			
		||||
struct bts_agch_msg_cb {
 | 
			
		||||
	uint32_t msg_id;
 | 
			
		||||
	bool confirm;
 | 
			
		||||
} __attribute__ ((packed));
 | 
			
		||||
 | 
			
		||||
#endif /* _BTS_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
 | 
			
		||||
#include <osmocom/gsm/tlv.h>
 | 
			
		||||
#include <osmocom/gsm/gsm_utils.h>
 | 
			
		||||
#include <osmocom/gsm/protocol/gsm_12_21.h>
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/gsm_data.h>
 | 
			
		||||
 | 
			
		||||
@@ -20,8 +21,8 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type,
 | 
			
		||||
			struct tlv_parsed *old_attr, struct tlv_parsed *new_attr,
 | 
			
		||||
			void *obj);
 | 
			
		||||
 | 
			
		||||
int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
 | 
			
		||||
			struct tlv_parsed *new_attr, int obj_kind, void *obj);
 | 
			
		||||
int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg,
 | 
			
		||||
			 struct gsm_abis_mo *mo, void *obj);
 | 
			
		||||
 | 
			
		||||
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
 | 
			
		||||
		      void *obj);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* BTS shutdown FSM */
 | 
			
		||||
 | 
			
		||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 | 
			
		||||
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								include/osmo-bts/bts_sm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								include/osmo-bts/bts_sm.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <osmocom/core/linuxlist.h>
 | 
			
		||||
#include <osmocom/core/socket.h>
 | 
			
		||||
#include <osmocom/gsm/gsm23003.h>
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/oml.h>
 | 
			
		||||
 | 
			
		||||
struct pcu_sock_state;
 | 
			
		||||
 | 
			
		||||
/* GPRS NSVC; ip.access specific NM Object */
 | 
			
		||||
struct gsm_gprs_nse;
 | 
			
		||||
struct gsm_gprs_nsvc {
 | 
			
		||||
	struct gsm_abis_mo mo;
 | 
			
		||||
	struct gsm_gprs_nse *nse;
 | 
			
		||||
	/* data read via VTY config file, to configure the BTS
 | 
			
		||||
	 * via OML from BSC */
 | 
			
		||||
	int id;
 | 
			
		||||
	uint16_t nsvci;
 | 
			
		||||
	struct osmo_sockaddr local;	/* on the BTS */
 | 
			
		||||
	struct osmo_sockaddr remote;	/* on the SGSN */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* GPRS NSE; ip.access specific NM Object */
 | 
			
		||||
struct gsm_gprs_nse {
 | 
			
		||||
	struct gsm_abis_mo mo;
 | 
			
		||||
	uint16_t nsei;
 | 
			
		||||
	uint8_t timer[7];
 | 
			
		||||
	struct gsm_gprs_nsvc nsvc[2];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct gsm_bts *gsm_gprs_nse_get_bts(const struct gsm_gprs_nse *nse);
 | 
			
		||||
 | 
			
		||||
/* BTS Site Manager */
 | 
			
		||||
struct gsm_bts_sm {
 | 
			
		||||
	struct gsm_abis_mo mo;
 | 
			
		||||
	struct llist_head bts_list;
 | 
			
		||||
	unsigned int num_bts;
 | 
			
		||||
	struct osmo_plmn_id plmn;
 | 
			
		||||
	struct {
 | 
			
		||||
		struct pcu_sock_state *pcu_state;
 | 
			
		||||
		struct gsm_gprs_nse nse;
 | 
			
		||||
	} gprs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern struct gsm_bts_sm *g_bts_sm;
 | 
			
		||||
 | 
			
		||||
struct gsm_bts_sm *gsm_bts_sm_alloc(void *talloc_ctx);
 | 
			
		||||
@@ -1,9 +1,16 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <osmocom/core/sockaddr_str.h>
 | 
			
		||||
#include <osmo-bts/gsm_data.h>
 | 
			
		||||
 | 
			
		||||
struct gsm_bts_bb_trx {
 | 
			
		||||
	struct gsm_abis_mo mo;
 | 
			
		||||
	/* how do we talk RSL with this TRX? */
 | 
			
		||||
	struct {
 | 
			
		||||
		struct osmo_sockaddr_str rem_addrstr;
 | 
			
		||||
		uint8_t tei;
 | 
			
		||||
		struct e1inp_sign_link *link;
 | 
			
		||||
	} rsl;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* One TRX in a BTS */
 | 
			
		||||
@@ -16,9 +23,6 @@ struct gsm_bts_trx {
 | 
			
		||||
	uint8_t nr;
 | 
			
		||||
	/* human readable name / description */
 | 
			
		||||
	char *description;
 | 
			
		||||
	/* how do we talk RSL with this TRX? */
 | 
			
		||||
	uint8_t rsl_tei;
 | 
			
		||||
	struct e1inp_sign_link *rsl_link;
 | 
			
		||||
 | 
			
		||||
	/* NM Radio Carrier and Baseband Transciever */
 | 
			
		||||
	struct gsm_abis_mo mo;
 | 
			
		||||
@@ -27,8 +31,8 @@ struct gsm_bts_trx {
 | 
			
		||||
	uint16_t arfcn;
 | 
			
		||||
	int nominal_power;		/* in dBm */
 | 
			
		||||
	unsigned int max_power_red;	/* in actual dB */
 | 
			
		||||
        uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
 | 
			
		||||
        uint8_t c0_idle_power_red;      /* in actual dB OC-2G only */
 | 
			
		||||
	uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
 | 
			
		||||
	uint8_t c0_idle_power_red;      /* in actual dB OC-2G only */
 | 
			
		||||
 | 
			
		||||
	uint8_t ta_ctrl_interval; /* 1 step is 2 SACCH periods */
 | 
			
		||||
 | 
			
		||||
@@ -40,6 +44,12 @@ struct gsm_bts_trx {
 | 
			
		||||
	/* The associated PHY instance */
 | 
			
		||||
	struct phy_instance *pinst;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		uint32_t freq_bands;	/* see NM_IPAC_F_FREQ_BAND_* flags */
 | 
			
		||||
		uint32_t chan_types;	/* see NM_IPAC_F_CHANT_* flags */
 | 
			
		||||
		uint32_t chan_modes;	/* see NM_IPAC_F_CHANM_* flags */
 | 
			
		||||
	} support;
 | 
			
		||||
 | 
			
		||||
	struct gsm_bts_trx_ts ts[TRX_NR_TS];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -58,6 +68,7 @@ int trx_link_estab(struct gsm_bts_trx *trx);
 | 
			
		||||
void trx_operability_update(struct gsm_bts_trx *trx);
 | 
			
		||||
 | 
			
		||||
uint8_t num_agch(const struct gsm_bts_trx *trx, const char * arg);
 | 
			
		||||
int pos_nch(const struct gsm_bts_trx *trx, const char *arg);
 | 
			
		||||
bool trx_ms_pwr_ctrl_is_osmo(const struct gsm_bts_trx *trx);
 | 
			
		||||
 | 
			
		||||
#define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								include/osmo-bts/csd_rlp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								include/osmo-bts/csd_rlp.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Declarations for functions in csd_rlp.c: alignment of downlink RLP frames
 | 
			
		||||
 * and RLP GSMTAP mechanism for CSD NT modes.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <osmocom/core/bits.h>
 | 
			
		||||
#include <osmocom/gsm/l1sap.h>
 | 
			
		||||
#include <osmo-bts/lchan.h>
 | 
			
		||||
 | 
			
		||||
extern const uint8_t csd_tchf48_nt_e2_map[26];
 | 
			
		||||
 | 
			
		||||
/* Per TS 48.020 section 15.1, the cadence of E2+E3 bits in a properly
 | 
			
		||||
 * aligned sequence of pseudo-V.110 frames forming a single RLP frame
 | 
			
		||||
 * is 00-01-10-11.  The following constant captures this bit sequence
 | 
			
		||||
 * in hex, for comparison against align_bits output from
 | 
			
		||||
 * csd_v110_rtp_decode() or against rlpdl_align_bits accumulator
 | 
			
		||||
 * in CSD NT lchan state.
 | 
			
		||||
 */
 | 
			
		||||
#define	NTCSD_ALIGNED_EBITS	0x1B
 | 
			
		||||
 | 
			
		||||
void ntcsd_dl_reset(struct gsm_lchan *lchan);
 | 
			
		||||
void ntcsd_dl_input_48(struct gsm_lchan *lchan, const ubit_t *data_bits,
 | 
			
		||||
			uint8_t align_bits);
 | 
			
		||||
void ntcsd_dl_input_96(struct gsm_lchan *lchan, const ubit_t *data_bits,
 | 
			
		||||
			uint8_t align_bits);
 | 
			
		||||
bool ntcsd_dl_output(struct gsm_lchan *lchan, ubit_t *rlp_frame_out);
 | 
			
		||||
 | 
			
		||||
void gsmtap_csd_rlp_process(struct gsm_lchan *lchan, bool is_uplink,
 | 
			
		||||
			    const struct ph_tch_param *tch_ind,
 | 
			
		||||
			    const ubit_t *data, unsigned int data_len);
 | 
			
		||||
void gsmtap_csd_rlp_dl(struct gsm_lchan *lchan, uint32_t fn,
 | 
			
		||||
			const ubit_t *data, unsigned int data_len);
 | 
			
		||||
							
								
								
									
										24
									
								
								include/osmo-bts/csd_v110.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/osmo-bts/csd_v110.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
/* RFC4040 "clearmode" RTP payload length */
 | 
			
		||||
#define RFC4040_RTP_PLEN 160
 | 
			
		||||
 | 
			
		||||
struct gsm_lchan;
 | 
			
		||||
 | 
			
		||||
struct csd_v110_lchan_desc {
 | 
			
		||||
	uint16_t num_frames;		/* number of V.110 frames in a radio block */
 | 
			
		||||
	uint16_t num_frame_bits;	/* number of bits in each V.110 frame */
 | 
			
		||||
	uint16_t num_other_bits;	/* number of other bits (e.g. M-bits for TCH/F14.4) */
 | 
			
		||||
	uint8_t ra2_ir;			/* intermediate rate (8 or 16 kbit/s) for RA2 step */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const struct csd_v110_lchan_desc csd_v110_lchan_desc[256];
 | 
			
		||||
 | 
			
		||||
#define CSD_V110_NUM_BITS(desc) \
 | 
			
		||||
	((desc)->num_frames * (desc)->num_frame_bits + (desc)->num_other_bits)
 | 
			
		||||
 | 
			
		||||
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
 | 
			
		||||
			const uint8_t *data, size_t data_len,
 | 
			
		||||
			uint8_t nt48_half_num);
 | 
			
		||||
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
 | 
			
		||||
			uint8_t *align_bits, const uint8_t *rtp, size_t rtp_len);
 | 
			
		||||
@@ -41,12 +41,6 @@
 | 
			
		||||
#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41
 | 
			
		||||
#define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91
 | 
			
		||||
 | 
			
		||||
struct gsm_network {
 | 
			
		||||
	struct llist_head bts_list;
 | 
			
		||||
	unsigned int num_bts;
 | 
			
		||||
	struct osmo_plmn_id plmn;
 | 
			
		||||
	struct pcu_sock_state *pcu_state;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1:
 | 
			
		||||
   4-bit index is used (2#1111 = 10#15) */
 | 
			
		||||
@@ -58,12 +52,59 @@ struct gsm_network {
 | 
			
		||||
/* lchans 0..3 are SDCCH in combined channel configuration,
 | 
			
		||||
   use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
 | 
			
		||||
#define CCCH_LCHAN 4
 | 
			
		||||
#define CBCH_LCHAN 2
 | 
			
		||||
 | 
			
		||||
#define TRX_NR_TS	8
 | 
			
		||||
#define TS_MAX_LCHAN	8
 | 
			
		||||
 | 
			
		||||
#define MAX_VERSION_LENGTH 64
 | 
			
		||||
 | 
			
		||||
/* NM_IPAC_F_CHANT_* mask for NM_IPAC_EIE_CHAN_TYPES (common) */
 | 
			
		||||
#define NM_IPAC_MASK_CHANT_COMMON \
 | 
			
		||||
	(NM_IPAC_F_CHANT_TCHF		| \
 | 
			
		||||
	 NM_IPAC_F_CHANT_TCHH		| \
 | 
			
		||||
	 NM_IPAC_F_CHANT_SDCCH8		| \
 | 
			
		||||
	 NM_IPAC_F_CHANT_BCCH		| \
 | 
			
		||||
	 NM_IPAC_F_CHANT_BCCH_SDCCH4)
 | 
			
		||||
/* NM_IPAC_F_CHANM_SPEECH_* mask for NM_IPAC_EIE_CHAN_MODES */
 | 
			
		||||
#define NM_IPAC_MASK_CHANM_SPEECH \
 | 
			
		||||
	(NM_IPAC_F_CHANM_SPEECH_FS	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_SPEECH_EFS	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_SPEECH_AFS	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_SPEECH_HS	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_SPEECH_AHS)
 | 
			
		||||
/* NM_IPAC_F_CHANM_CSD_NT_* mask for NM_IPAC_EIE_CHAN_MODES */
 | 
			
		||||
#define NM_IPAC_MASK_CHANM_CSD_NT \
 | 
			
		||||
	(NM_IPAC_F_CHANM_CSD_NT_4k8	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_CSD_NT_9k6	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_CSD_NT_14k4)
 | 
			
		||||
/* NM_IPAC_F_CHANM_CSD_T_* mask for NM_IPAC_EIE_CHAN_MODES */
 | 
			
		||||
#define NM_IPAC_MASK_CHANM_CSD_T \
 | 
			
		||||
	(NM_IPAC_F_CHANM_CSD_T_1200_75	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_CSD_T_600	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_CSD_T_1k2	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_CSD_T_2k4	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_CSD_T_4k8	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_CSD_T_9k6	| \
 | 
			
		||||
	 NM_IPAC_F_CHANM_CSD_T_14k4)
 | 
			
		||||
/* NM_IPAC_F_GPRS_CODING_CS[1-4] mask for NM_IPAC_EIE_GPRS_CODING */
 | 
			
		||||
#define NM_IPAC_MASK_GPRS_CODING_CS \
 | 
			
		||||
	(NM_IPAC_F_GPRS_CODING_CS1	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_CS2	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_CS3	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_CS4)
 | 
			
		||||
/* NM_IPAC_F_GPRS_CODING_MCS[1-9] mask for NM_IPAC_EIE_GPRS_CODING */
 | 
			
		||||
#define NM_IPAC_MASK_GPRS_CODING_MCS \
 | 
			
		||||
	(NM_IPAC_F_GPRS_CODING_MCS1	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_MCS2	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_MCS3	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_MCS4	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_MCS5	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_MCS6	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_MCS7	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_MCS8	| \
 | 
			
		||||
	 NM_IPAC_F_GPRS_CODING_MCS9)
 | 
			
		||||
 | 
			
		||||
enum gsm_bts_trx_ts_flags {
 | 
			
		||||
	TS_F_PDCH_ACTIVE =		0x1000,
 | 
			
		||||
	TS_F_PDCH_ACT_PENDING =		0x2000,
 | 
			
		||||
@@ -90,7 +131,10 @@ struct gsm_bts_trx_ts {
 | 
			
		||||
 | 
			
		||||
	/* Training Sequence Code (range 0..7) */
 | 
			
		||||
	uint8_t tsc_oml; /* configured via OML */
 | 
			
		||||
	uint8_t tsc; /* currently in use */
 | 
			
		||||
	bool tsc_oml_configured;
 | 
			
		||||
	uint8_t tsc_rsl; /* configured via RSL (Osmo extension) */
 | 
			
		||||
	bool tsc_rsl_configured;
 | 
			
		||||
	uint8_t tsc; /* TSC currently in use. Preference: RSL, OML, BTS-BSIC-OML */
 | 
			
		||||
	/* Training Sequence Set (range 0..3) */
 | 
			
		||||
	uint8_t tsc_set;
 | 
			
		||||
 | 
			
		||||
@@ -193,6 +237,8 @@ int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts,
 | 
			
		||||
 | 
			
		||||
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);
 | 
			
		||||
 | 
			
		||||
void gsm_ts_apply_configured_tsc(struct gsm_bts_trx_ts *ts);
 | 
			
		||||
 | 
			
		||||
void gsm_ts_release(struct gsm_bts_trx_ts *ts);
 | 
			
		||||
 | 
			
		||||
#endif /* _GSM_DATA_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -102,6 +102,7 @@ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr);
 | 
			
		||||
int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr);
 | 
			
		||||
int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr);
 | 
			
		||||
int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr);
 | 
			
		||||
int l1sap_uplink_access(struct gsm_lchan *lchan, bool active);
 | 
			
		||||
 | 
			
		||||
enum l1sap_common_sapi {
 | 
			
		||||
	L1SAP_COMMON_SAPI_UNKNOWN,
 | 
			
		||||
@@ -141,9 +142,11 @@ int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg,
 | 
			
		||||
 | 
			
		||||
#define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h)
 | 
			
		||||
 | 
			
		||||
void radio_link_timeout_reset(struct gsm_lchan *lchan);
 | 
			
		||||
 | 
			
		||||
int bts_check_for_first_ciphrd(struct gsm_lchan *lchan,
 | 
			
		||||
				uint8_t *data, int len);
 | 
			
		||||
 | 
			
		||||
int is_ccch_for_agch(struct gsm_bts_trx *trx, uint32_t fn);
 | 
			
		||||
enum ccch_msgt get_ccch_msgt(struct gsm_bts_trx *trx, uint32_t fn);
 | 
			
		||||
 | 
			
		||||
#endif /* L1SAP_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,12 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocom/core/bits.h>
 | 
			
		||||
#include <osmocom/core/timer.h>
 | 
			
		||||
#include <osmocom/core/linuxlist.h>
 | 
			
		||||
#include <osmocom/core/logging.h>
 | 
			
		||||
#include <osmocom/gsm/gsm_utils.h>
 | 
			
		||||
#include <osmocom/codec/codec.h>
 | 
			
		||||
#include <osmocom/codec/ecu.h>
 | 
			
		||||
#include <osmocom/gsm/lapdm.h>
 | 
			
		||||
#include <osmocom/gsm/sysinfo.h>
 | 
			
		||||
@@ -74,17 +76,25 @@ struct amr_multirate_conf {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum lchan_csd_mode {
 | 
			
		||||
	LCHAN_CSD_M_NT,
 | 
			
		||||
	LCHAN_CSD_M_NT = 0,
 | 
			
		||||
	LCHAN_CSD_M_T_1200_75,
 | 
			
		||||
	LCHAN_CSD_M_T_600,
 | 
			
		||||
	LCHAN_CSD_M_T_1200,
 | 
			
		||||
	LCHAN_CSD_M_T_2400,
 | 
			
		||||
	LCHAN_CSD_M_T_4800,
 | 
			
		||||
	LCHAN_CSD_M_T_9600,
 | 
			
		||||
	LCHAN_CSD_M_T_14400,
 | 
			
		||||
	LCHAN_CSD_M_T_29000,
 | 
			
		||||
	LCHAN_CSD_M_T_32000,
 | 
			
		||||
	_LCHAN_CSD_M_NUM,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const struct value_string lchan_csd_mode_descs[];
 | 
			
		||||
static inline const char *lchan_csd_mode_desc(enum lchan_csd_mode mode)
 | 
			
		||||
{
 | 
			
		||||
	return get_value_string(lchan_csd_mode_descs, mode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* State of the SAPIs in the lchan */
 | 
			
		||||
enum lchan_sapi_state {
 | 
			
		||||
	LCHAN_SAPI_S_NONE,
 | 
			
		||||
@@ -140,6 +150,8 @@ struct gsm_lchan {
 | 
			
		||||
	uint8_t nr;
 | 
			
		||||
	/* The logical channel type */
 | 
			
		||||
	enum gsm_chan_t type;
 | 
			
		||||
	/* RSL channel rate and type */
 | 
			
		||||
	enum rsl_cmod_crt rsl_chan_rt;
 | 
			
		||||
	/* RSL channel mode */
 | 
			
		||||
	enum rsl_cmod_spd rsl_cmode;
 | 
			
		||||
	/* If TCH, traffic channel mode */
 | 
			
		||||
@@ -163,6 +175,7 @@ struct gsm_lchan {
 | 
			
		||||
		uint16_t conn_id;
 | 
			
		||||
		uint8_t rtp_payload;
 | 
			
		||||
		uint8_t rtp_payload2;
 | 
			
		||||
		uint8_t rtp_extensions;
 | 
			
		||||
		uint8_t speech_mode;
 | 
			
		||||
		struct {
 | 
			
		||||
			bool use;
 | 
			
		||||
@@ -203,6 +216,8 @@ struct gsm_lchan {
 | 
			
		||||
	uint8_t sapis_dl[23];
 | 
			
		||||
	uint8_t sapis_ul[23];
 | 
			
		||||
	struct lapdm_channel lapdm_ch;
 | 
			
		||||
	/* It is required to have L3 info with DL establishment. */
 | 
			
		||||
	bool l3_info_estab;
 | 
			
		||||
	struct llist_head dl_tch_queue;
 | 
			
		||||
	unsigned int dl_tch_queue_len;
 | 
			
		||||
	struct {
 | 
			
		||||
@@ -265,9 +280,34 @@ struct gsm_lchan {
 | 
			
		||||
			/* last UL SPEECH resume flag */
 | 
			
		||||
			bool is_speech_resume;
 | 
			
		||||
		} dtx;
 | 
			
		||||
		struct {
 | 
			
		||||
			bool last_rtp_input_was_sid;
 | 
			
		||||
			uint8_t last_sid[GSM_FR_BYTES];
 | 
			
		||||
			uint8_t last_sid_len;
 | 
			
		||||
			uint8_t last_sid_age;
 | 
			
		||||
			/* A SID was transmitted on the DL in the period
 | 
			
		||||
			 * beginning with the last transmitted speech frame
 | 
			
		||||
			 * or the last mandatory-Tx position, whichever was
 | 
			
		||||
			 * more recent. */
 | 
			
		||||
			bool dl_sid_transmitted;
 | 
			
		||||
			/* The current frame in the DL is taken up by FACCH */
 | 
			
		||||
			bool dl_facch_stealing;
 | 
			
		||||
			/* UL SID filter to catch DTXu half-blocks,
 | 
			
		||||
			 * see tch_ul_fr_hr_efr() function. */
 | 
			
		||||
			bool ul_sid_filter;
 | 
			
		||||
		} dtx_fr_hr_efr;
 | 
			
		||||
		uint8_t last_cmr;
 | 
			
		||||
		uint32_t last_fn;
 | 
			
		||||
 | 
			
		||||
		struct {
 | 
			
		||||
			/* RLP GSMTAP mechanism */
 | 
			
		||||
			uint8_t rlp_buf_ul[576/8]; /* maximum size of RLP frame */
 | 
			
		||||
			uint8_t rlp_buf_dl[576/8]; /* maximum size of RLP frame */
 | 
			
		||||
			/* alignment of RLP frames in DL for NT modes */
 | 
			
		||||
			ubit_t rlpdl_data_bits[60 * 7];
 | 
			
		||||
			uint16_t rlpdl_align_bits;
 | 
			
		||||
			uint8_t rlpdl_fill_level;
 | 
			
		||||
			ubit_t tchf48_nt_2ndhalf[120];
 | 
			
		||||
		} csd;
 | 
			
		||||
	} tch;
 | 
			
		||||
 | 
			
		||||
	/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
 | 
			
		||||
@@ -287,6 +327,19 @@ struct gsm_lchan {
 | 
			
		||||
		/* counts up to Ny1 */
 | 
			
		||||
		unsigned int phys_info_count;
 | 
			
		||||
	} ho;
 | 
			
		||||
	struct {
 | 
			
		||||
		bool listener_detected;
 | 
			
		||||
		uint8_t talker_active;
 | 
			
		||||
		uint8_t ref;
 | 
			
		||||
		uint32_t fn;
 | 
			
		||||
		/* T3115: VGCS UPLINK GRANT retransmission */
 | 
			
		||||
		struct osmo_timer_list t3115;
 | 
			
		||||
		/* counts up to Ny2 */
 | 
			
		||||
		unsigned int vgcs_ul_grant_count;
 | 
			
		||||
		/* uplink free message */
 | 
			
		||||
		bool uplink_free;
 | 
			
		||||
		uint8_t uplink_free_msg[GSM_MACBLOCK_LEN];
 | 
			
		||||
	} asci;
 | 
			
		||||
	/* S counter for link loss */
 | 
			
		||||
	int s;
 | 
			
		||||
	/* Kind of the release/activation. E.g. RSL or PCU */
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ enum {
 | 
			
		||||
	DABIS,
 | 
			
		||||
	DRTP,
 | 
			
		||||
	DOSMUX,
 | 
			
		||||
	DASCI,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const struct log_info bts_log_info;
 | 
			
		||||
@@ -37,4 +38,12 @@ extern const struct log_info bts_log_info;
 | 
			
		||||
#define DEBUGPFN(ss, fn, fmt, args...) \
 | 
			
		||||
	LOGP(ss, LOGL_DEBUG, "%s " fmt, gsm_fn_as_gsmtime_str(fn), ## args)
 | 
			
		||||
 | 
			
		||||
/* LOGP with lchan + frame number prefix */
 | 
			
		||||
#define LOGPLCFN(lchan, fn, ss, lvl, fmt, args...) \
 | 
			
		||||
	LOGP(ss, lvl, "%s %s " fmt, gsm_lchan_name(lchan), gsm_fn_as_gsmtime_str(fn), ## args)
 | 
			
		||||
 | 
			
		||||
/* LOGP with lchan + gsm_time prefix */
 | 
			
		||||
#define LOGPLCGT(lchan, gt, ss, lvl, fmt, args...) \
 | 
			
		||||
	LOGP(ss, lvl, "%s %s " fmt, gsm_lchan_name(lchan), osmo_dump_gsmtime(gt), ## args)
 | 
			
		||||
 | 
			
		||||
#endif /* _LOGGING_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -13,14 +13,49 @@
 | 
			
		||||
 | 
			
		||||
struct msgb;
 | 
			
		||||
 | 
			
		||||
/* Access 1st part of msgb control buffer */
 | 
			
		||||
/****************************************************************
 | 
			
		||||
* Accessor macros for control buffer words in RTP input path (DL)
 | 
			
		||||
*****************************************************************/
 | 
			
		||||
 | 
			
		||||
/* Storing RTP header fields in the path from RTP and Osmux
 | 
			
		||||
 * Rx callback functions to TCH-RTS.ind handling.
 | 
			
		||||
 * FIXME: do we really need this RTP header info downstream
 | 
			
		||||
 * of the jitter buffer mechanism in the RTP endpoint library?
 | 
			
		||||
 */
 | 
			
		||||
#define rtpmsg_marker_bit(x) ((x)->cb[0])
 | 
			
		||||
#define rtpmsg_seq(x)        ((x)->cb[1])
 | 
			
		||||
#define rtpmsg_ts(x)         ((x)->cb[2])
 | 
			
		||||
 | 
			
		||||
/* Access 2nd part of msgb control buffer */
 | 
			
		||||
#define rtpmsg_seq(x) ((x)->cb[1])
 | 
			
		||||
/* l1sap_rtp_rx_cb() does some preening or preparsing on some
 | 
			
		||||
 * RTP payloads, and in two cases (HR with RFC 5993 input and
 | 
			
		||||
 * CSD NT modes) this preparsing step produces some metadata
 | 
			
		||||
 * that need to be passed to TCH-RTS.ind handling.
 | 
			
		||||
 */
 | 
			
		||||
#define rtpmsg_is_rfc5993_sid(x) ((x)->cb[3])
 | 
			
		||||
#define rtpmsg_csd_align_bits(x) ((x)->cb[4])
 | 
			
		||||
 | 
			
		||||
/* Access 3rd part of msgb control buffer */
 | 
			
		||||
#define rtpmsg_ts(x) ((x)->cb[2])
 | 
			
		||||
/********************************************************
 | 
			
		||||
* Accessor macros for control buffer words in TCH UL path
 | 
			
		||||
*********************************************************/
 | 
			
		||||
 | 
			
		||||
/* We provide an ability for BTS models to indicate BFI along with payload
 | 
			
		||||
 * bits just like in GSM 08.60 TRAU-UL frames, and the same BFI flag can
 | 
			
		||||
 * then be set by model-independent functions for higher-level BFI
 | 
			
		||||
 * conditions.  This cb word shall act as a Boolean flag.
 | 
			
		||||
 */
 | 
			
		||||
#define tch_ul_msg_bfi(x) ((x)->cb[0])
 | 
			
		||||
 | 
			
		||||
/* For HRv1 codec, we have to pass SID classification from the function
 | 
			
		||||
 * that makes the initial determination to TS 101 318, RFC 5993 and
 | 
			
		||||
 * TW-TS-002 output functions.  Per classic GSM specs, common across
 | 
			
		||||
 * FR/HR/EFR, SID classification code is an integer equal to 0, 1 or 2;
 | 
			
		||||
 * in Osmocom it is enum osmo_gsm631_sid_class.
 | 
			
		||||
 *
 | 
			
		||||
 * NOTE: while the actual SID ternary classification exists in exactly
 | 
			
		||||
 * the same form across all 3 of FR/HR/EFR, we store it in a cb word
 | 
			
		||||
 * only for HR codec where we need it for RTP output functions.
 | 
			
		||||
 */
 | 
			
		||||
#define tch_ul_msg_hr_sid(x) ((x)->cb[1])
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Classification of OML message. ETSI for plain GSM 12.21
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
/* Header for all NM FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21:
 | 
			
		||||
  GSM 12.21 Objects' Operational state and availability status behaviour during initialization */
 | 
			
		||||
 | 
			
		||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 | 
			
		||||
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -30,18 +30,18 @@
 | 
			
		||||
/* Common */
 | 
			
		||||
enum nm_fsm_events {
 | 
			
		||||
	NM_EV_SW_ACT,
 | 
			
		||||
	NM_EV_SETATTR_ACK, /* data: struct nm_fsm_ev_setattr_data */
 | 
			
		||||
	NM_EV_SETATTR_NACK, /* data: struct nm_fsm_ev_setattr_data */
 | 
			
		||||
	NM_EV_RX_SETATTR, /* data: struct nm_fsm_ev_setattr_data */
 | 
			
		||||
	NM_EV_RX_OPSTART,
 | 
			
		||||
	NM_EV_OPSTART_ACK,
 | 
			
		||||
	NM_EV_OPSTART_NACK,
 | 
			
		||||
	NM_EV_SHUTDOWN_START,
 | 
			
		||||
	NM_EV_SHUTDOWN_FINISH,
 | 
			
		||||
	NM_EV_OML_UP,
 | 
			
		||||
	NM_EV_RSL_UP, /* RadioCarrier and BaseBand Transceiver only */
 | 
			
		||||
	NM_EV_RSL_DOWN,  /* RadioCarrier and BaseBand Transceiver only */
 | 
			
		||||
	NM_EV_PHYLINK_UP, /* RadioCarrier and BaseBand Transceiver only */
 | 
			
		||||
	NM_EV_PHYLINK_DOWN,  /* RadioCarrier and BaseBand Transceiver only */
 | 
			
		||||
	NM_EV_DISABLE,  /* RadioCarrier and BaseBand Transceiver only */
 | 
			
		||||
	NM_EV_BBTRANSC_INSTALLED, /* Radio Channel only */
 | 
			
		||||
	NM_EV_BBTRANSC_ENABLED, /* Radio Channel only */
 | 
			
		||||
	NM_EV_BBTRANSC_DISABLED, /* Radio Channel only */
 | 
			
		||||
	NM_EV_RCARRIER_ENABLED, /* Radio Channel only */
 | 
			
		||||
@@ -50,8 +50,7 @@ enum nm_fsm_events {
 | 
			
		||||
extern const struct value_string nm_fsm_event_names[];
 | 
			
		||||
 | 
			
		||||
struct nm_fsm_ev_setattr_data {
 | 
			
		||||
	struct msgb *msg; /* msgb ownership is transferred to FSM */
 | 
			
		||||
	int cause;
 | 
			
		||||
	const struct msgb *msg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -95,3 +94,30 @@ enum nm_chan_op_fsm_states {
 | 
			
		||||
        NM_CHAN_ST_OP_ENABLED,
 | 
			
		||||
};
 | 
			
		||||
extern struct osmo_fsm nm_chan_fsm;
 | 
			
		||||
 | 
			
		||||
/* GPRS NSE */
 | 
			
		||||
enum nm_gprs_nse_op_fsm_states {
 | 
			
		||||
	NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED,
 | 
			
		||||
	NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY,
 | 
			
		||||
	NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE,
 | 
			
		||||
	NM_GPRS_NSE_ST_OP_ENABLED,
 | 
			
		||||
};
 | 
			
		||||
extern struct osmo_fsm nm_gprs_nse_fsm;
 | 
			
		||||
 | 
			
		||||
/* GPRS NSVC */
 | 
			
		||||
enum nm_gprs_nsvc_op_fsm_states {
 | 
			
		||||
	NM_GPRS_NSVC_ST_OP_DISABLED_NOTINSTALLED,
 | 
			
		||||
	NM_GPRS_NSVC_ST_OP_DISABLED_DEPENDENCY,
 | 
			
		||||
	NM_GPRS_NSVC_ST_OP_DISABLED_OFFLINE,
 | 
			
		||||
	NM_GPRS_NSVC_ST_OP_ENABLED,
 | 
			
		||||
};
 | 
			
		||||
extern struct osmo_fsm nm_gprs_nsvc_fsm;
 | 
			
		||||
 | 
			
		||||
/* GPRS CELL */
 | 
			
		||||
enum nm_gprs_cell_op_fsm_states {
 | 
			
		||||
	NM_GPRS_CELL_ST_OP_DISABLED_NOTINSTALLED,
 | 
			
		||||
	NM_GPRS_CELL_ST_OP_DISABLED_DEPENDENCY,
 | 
			
		||||
	NM_GPRS_CELL_ST_OP_DISABLED_OFFLINE,
 | 
			
		||||
	NM_GPRS_CELL_ST_OP_ENABLED,
 | 
			
		||||
};
 | 
			
		||||
extern struct osmo_fsm nm_gprs_cell_fsm;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								include/osmo-bts/notification.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								include/osmo-bts/notification.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
/* Maintain and generate ASCI notifications */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: AGPL-3.0+
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Harald Welte
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
/* one [concurrent] ASCI (VBS/VGCS) notification */
 | 
			
		||||
struct asci_notification {
 | 
			
		||||
	struct llist_head list;	/* linked to bts->asci.notifications */
 | 
			
		||||
 | 
			
		||||
	/* Group call reference (TS 24.008 10.5.1.9 "Descriptive group or broadcast call reference") */
 | 
			
		||||
	uint8_t group_call_ref[5];
 | 
			
		||||
 | 
			
		||||
	/* Group Channel Description (TS 44.018 10.5.2.14b) */
 | 
			
		||||
	struct {
 | 
			
		||||
		bool present;
 | 
			
		||||
		uint8_t value[255];
 | 
			
		||||
		uint8_t len;
 | 
			
		||||
	} chan_desc;
 | 
			
		||||
 | 
			
		||||
	/* NCH DRX Information (TS 48.058 9.3.47) */
 | 
			
		||||
	struct {
 | 
			
		||||
		bool present;
 | 
			
		||||
		struct rsl_ie_nch_drx_info value;
 | 
			
		||||
	} nch_drx_info;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int bts_asci_notification_add(struct gsm_bts *bts, const uint8_t *group_call_ref, const uint8_t *chan_desc,
 | 
			
		||||
			      uint8_t chan_desc_len, const struct rsl_ie_nch_drx_info *nch_drx_info);
 | 
			
		||||
 | 
			
		||||
int bts_asci_notification_del(struct gsm_bts *bts, const uint8_t *group_call_ref);
 | 
			
		||||
 | 
			
		||||
int bts_asci_notification_reset(struct gsm_bts *bts);
 | 
			
		||||
 | 
			
		||||
const struct asci_notification *bts_asci_notification_get_next(struct gsm_bts *bts);
 | 
			
		||||
 | 
			
		||||
void append_group_call_information(struct bitvec *bv, const uint8_t *gcr, const uint8_t *ch_desc, uint8_t ch_desc_len);
 | 
			
		||||
 | 
			
		||||
int bts_asci_notify_nch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf);
 | 
			
		||||
int bts_asci_notify_facch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf, const uint8_t *group_call_ref,
 | 
			
		||||
				  const uint8_t *chan_desc, uint8_t chan_desc_len);
 | 
			
		||||
@@ -63,11 +63,12 @@ int oml_tx_state_changed(const struct gsm_abis_mo *mo);
 | 
			
		||||
int oml_mo_tx_sw_act_rep(const struct gsm_abis_mo *mo);
 | 
			
		||||
 | 
			
		||||
int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause);
 | 
			
		||||
int oml_fom_ack_nack_copy_msg(const struct msgb *old_msg, uint8_t cause);
 | 
			
		||||
 | 
			
		||||
int oml_mo_fom_ack_nack(const struct gsm_abis_mo *mo, uint8_t orig_msg_type,
 | 
			
		||||
			uint8_t cause);
 | 
			
		||||
 | 
			
		||||
extern const unsigned int oml_default_t200_ms[7];
 | 
			
		||||
extern const uint32_t oml_default_t200_fn[7];
 | 
			
		||||
 | 
			
		||||
/* Transmit failure event report */
 | 
			
		||||
int oml_tx_failure_event_rep(const struct gsm_abis_mo *mo, enum abis_nm_severity severity,
 | 
			
		||||
@@ -77,11 +78,11 @@ void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
 | 
			
		||||
		 uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3);
 | 
			
		||||
 | 
			
		||||
struct gsm_abis_mo *gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
 | 
			
		||||
				    const struct abis_om_obj_inst *obj_inst);
 | 
			
		||||
				    const struct abis_om_obj_inst *obj_inst,
 | 
			
		||||
				    enum abis_nm_nack_cause *c);
 | 
			
		||||
 | 
			
		||||
struct gsm_nm_state *gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
 | 
			
		||||
					  const struct abis_om_obj_inst *obj_inst);
 | 
			
		||||
void *gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
 | 
			
		||||
		       const struct abis_om_obj_inst *obj_inst);
 | 
			
		||||
		       const struct abis_om_obj_inst *obj_inst,
 | 
			
		||||
		       enum abis_nm_nack_cause *c);
 | 
			
		||||
 | 
			
		||||
#endif // _OML_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,55 @@
 | 
			
		||||
 | 
			
		||||
struct paging_state;
 | 
			
		||||
struct gsm_bts;
 | 
			
		||||
struct asci_notification;
 | 
			
		||||
 | 
			
		||||
/* abstract representation of P1 rest octets; we only implement those parts we need for now */
 | 
			
		||||
struct p1_rest_octets {
 | 
			
		||||
	struct {
 | 
			
		||||
		bool present;
 | 
			
		||||
		uint8_t nln;
 | 
			
		||||
		uint8_t nln_status;
 | 
			
		||||
	} nln_pch;
 | 
			
		||||
	bool packet_page_ind[2];
 | 
			
		||||
	bool r8_present;
 | 
			
		||||
	struct {
 | 
			
		||||
		bool prio_ul_access;
 | 
			
		||||
		bool etws_present;
 | 
			
		||||
		struct {
 | 
			
		||||
			bool is_first;
 | 
			
		||||
			uint8_t page_nr;
 | 
			
		||||
			const uint8_t *page;
 | 
			
		||||
			size_t page_bytes;
 | 
			
		||||
		} etws;
 | 
			
		||||
	} r8;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* abstract representation of P2 rest octets; we only implement those parts we need for now */
 | 
			
		||||
struct p2_rest_octets {
 | 
			
		||||
	struct {
 | 
			
		||||
		bool present;
 | 
			
		||||
		uint8_t cn3;
 | 
			
		||||
	} cneed;
 | 
			
		||||
	struct {
 | 
			
		||||
		bool present;
 | 
			
		||||
		uint8_t nln;
 | 
			
		||||
		uint8_t nln_status;
 | 
			
		||||
	} nln_pch;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* abstract representation of P3 rest octets; we only implement those parts we need for now */
 | 
			
		||||
struct p3_rest_octets {
 | 
			
		||||
	struct {
 | 
			
		||||
		bool present;
 | 
			
		||||
		uint8_t cn3;
 | 
			
		||||
		uint8_t cn4;
 | 
			
		||||
	} cneed;
 | 
			
		||||
	struct {
 | 
			
		||||
		bool present;
 | 
			
		||||
		uint8_t nln;
 | 
			
		||||
		uint8_t nln_status;
 | 
			
		||||
	} nln_pch;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* initialize paging code */
 | 
			
		||||
struct paging_state *paging_init(struct gsm_bts *bts,
 | 
			
		||||
@@ -35,9 +84,15 @@ int paging_si_update(struct paging_state *ps, struct gsm48_control_channel_descr
 | 
			
		||||
int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
 | 
			
		||||
			const uint8_t *identity_lv, uint8_t chan_needed);
 | 
			
		||||
 | 
			
		||||
/* Add an IMM.ASS message to the paging queue */
 | 
			
		||||
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
 | 
			
		||||
                       uint8_t len, bool from_pcu);
 | 
			
		||||
/* Add a ready formatted MAC block message to the paging queue, this can be an IMMEDIATE ASSIGNMENT, or a
 | 
			
		||||
 * PAGING COMMAND (from the PCU) */
 | 
			
		||||
int paging_add_macblock(struct paging_state *ps, uint32_t msg_id, const char *imsi, bool confirm, const uint8_t *macblock);
 | 
			
		||||
 | 
			
		||||
/* Paging rest octests */
 | 
			
		||||
void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro,
 | 
			
		||||
			   const struct asci_notification *notif);
 | 
			
		||||
void append_p2_rest_octets(struct bitvec *bv, const struct p2_rest_octets *p2ro);
 | 
			
		||||
void append_p3_rest_octets(struct bitvec *bv, const struct p3_rest_octets *p3ro);
 | 
			
		||||
 | 
			
		||||
/* generate paging message for given gsm time */
 | 
			
		||||
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,8 @@
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/pcuif_proto.h>
 | 
			
		||||
 | 
			
		||||
struct gsm_bts_sm;
 | 
			
		||||
 | 
			
		||||
extern int pcu_direct;
 | 
			
		||||
 | 
			
		||||
#define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u))
 | 
			
		||||
@@ -21,11 +23,11 @@ int pcu_tx_rach_ind(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
 | 
			
		||||
int pcu_tx_time_ind(uint32_t fn);
 | 
			
		||||
int pcu_tx_interf_ind(const struct gsm_bts_trx *trx, uint32_t fn);
 | 
			
		||||
int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed);
 | 
			
		||||
int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len);
 | 
			
		||||
int pcu_tx_data_cnf(uint32_t msg_id, uint8_t sapi);
 | 
			
		||||
int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id, uint8_t cause);
 | 
			
		||||
int pcu_sock_send(struct gsm_network *net, struct msgb *msg);
 | 
			
		||||
int pcu_sock_send(struct msgb *msg);
 | 
			
		||||
 | 
			
		||||
int pcu_sock_init(const char *path);
 | 
			
		||||
int pcu_sock_init(const char *path, int qlength_max);
 | 
			
		||||
void pcu_sock_exit(void);
 | 
			
		||||
 | 
			
		||||
bool pcu_connected(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -3,20 +3,20 @@
 | 
			
		||||
 | 
			
		||||
#include <osmocom/gsm/l1sap.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
 | 
			
		||||
 | 
			
		||||
#define PCU_SOCK_DEFAULT	"/tmp/pcu_bts"
 | 
			
		||||
 | 
			
		||||
#define PCU_IF_VERSION		0x0a
 | 
			
		||||
#define PCU_IF_VERSION		0x0c
 | 
			
		||||
#define TXT_MAX_LEN	128
 | 
			
		||||
 | 
			
		||||
/* msg_type */
 | 
			
		||||
#define PCU_IF_MSG_DATA_REQ	0x00	/* send data to given channel */
 | 
			
		||||
#define PCU_IF_MSG_DATA_CNF	0x01	/* confirm (e.g. transmission on PCH) */
 | 
			
		||||
#define PCU_IF_MSG_DATA_IND	0x02	/* receive data from given channel */
 | 
			
		||||
#define PCU_IF_MSG_SUSP_REQ	0x03	/* BTS forwards GPRS SUSP REQ to PCU */
 | 
			
		||||
#define PCU_IF_MSG_APP_INFO_REQ	0x04	/* BTS asks PCU to transmit APP INFO via PACCH */
 | 
			
		||||
#define PCU_IF_MSG_RTS_REQ	0x10	/* ready to send request */
 | 
			
		||||
#define PCU_IF_MSG_DATA_CNF_DT	0x11	/* confirm (with direct tlli) */
 | 
			
		||||
#define PCU_IF_MSG_DATA_CNF_2	0x11	/* confirm (using message id) */
 | 
			
		||||
#define PCU_IF_MSG_RACH_IND	0x22	/* receive RACH */
 | 
			
		||||
#define PCU_IF_MSG_INFO_IND	0x32	/* retrieve BTS info */
 | 
			
		||||
#define PCU_IF_MSG_ACT_REQ	0x40	/* activate/deactivate PDCH */
 | 
			
		||||
@@ -28,17 +28,16 @@
 | 
			
		||||
 | 
			
		||||
/* sapi */
 | 
			
		||||
#define PCU_IF_SAPI_RACH	0x01	/* channel request on CCCH */
 | 
			
		||||
#define PCU_IF_SAPI_AGCH	0x02	/* assignment on AGCH */
 | 
			
		||||
#define PCU_IF_SAPI_PCH		0x03	/* paging/assignment on PCH */
 | 
			
		||||
#define PCU_IF_SAPI_BCCH	0x04	/* SI on BCCH */
 | 
			
		||||
#define PCU_IF_SAPI_PDTCH	0x05	/* packet data/control/ccch block */
 | 
			
		||||
#define PCU_IF_SAPI_PRACH	0x06	/* packet random access channel */
 | 
			
		||||
#define PCU_IF_SAPI_PTCCH	0x07	/* packet TA control channel */
 | 
			
		||||
#define PCU_IF_SAPI_AGCH_DT	0x08	/* assignment on AGCH but with additional TLLI */
 | 
			
		||||
#define PCU_IF_SAPI_PCH_2	0x08	/* assignment on PCH (confirmed using message id) */
 | 
			
		||||
#define PCU_IF_SAPI_AGCH_2	0x09	/* assignment on AGCH (confirmed using message id) */
 | 
			
		||||
 | 
			
		||||
/* flags */
 | 
			
		||||
#define PCU_IF_FLAG_ACTIVE	(1 << 0)/* BTS is active */
 | 
			
		||||
#define PCU_IF_FLAG_SYSMO	(1 << 1)/* access PDCH of sysmoBTS directly */
 | 
			
		||||
#define PCU_IF_FLAG_DIRECT_PHY	(1 << 1)/* access PHY directly via dedicated hardware support */
 | 
			
		||||
#define PCU_IF_FLAG_CS1		(1 << 16)
 | 
			
		||||
#define PCU_IF_FLAG_CS2		(1 << 17)
 | 
			
		||||
#define PCU_IF_FLAG_CS3		(1 << 18)
 | 
			
		||||
@@ -58,6 +57,17 @@
 | 
			
		||||
#define PCU_IF_ADDR_TYPE_IPV4	0x04	/* IPv4 address */
 | 
			
		||||
#define PCU_IF_ADDR_TYPE_IPV6	0x29	/* IPv6 address */
 | 
			
		||||
 | 
			
		||||
/* BTS model */
 | 
			
		||||
enum gsm_pcuif_bts_model {
 | 
			
		||||
	PCU_IF_BTS_MODEL_UNSPEC,
 | 
			
		||||
	PCU_IF_BTS_MODEL_LC15,
 | 
			
		||||
	PCU_IF_BTS_MODEL_OC2G,
 | 
			
		||||
	PCU_IF_BTS_MODEL_OCTPHY,
 | 
			
		||||
	PCU_IF_BTS_MODEL_SYSMO,
 | 
			
		||||
	PCU_IF_BTS_MODEL_TRX,
 | 
			
		||||
	PCU_IF_BTS_MODEL_RBS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PCU_IF_NUM_NSVC 2
 | 
			
		||||
#define PCU_IF_NUM_TRX 8
 | 
			
		||||
 | 
			
		||||
@@ -86,19 +96,10 @@ struct gsm_pcu_if_data {
 | 
			
		||||
	int16_t		lqual_cb;	/* !< \brief Link quality in centiBel */
 | 
			
		||||
} __attribute__ ((packed));
 | 
			
		||||
 | 
			
		||||
/* data confirmation with direct tlli (instead of raw mac block with tlli) */
 | 
			
		||||
struct gsm_pcu_if_data_cnf_dt {
 | 
			
		||||
/* data confirmation with message id (instead of raw mac block) */
 | 
			
		||||
struct gsm_pcu_if_data_cnf {
 | 
			
		||||
	uint8_t		sapi;
 | 
			
		||||
	uint32_t	tlli;
 | 
			
		||||
	uint32_t	fn;
 | 
			
		||||
	uint16_t	arfcn;
 | 
			
		||||
	uint8_t		trx_nr;
 | 
			
		||||
	uint8_t		ts_nr;
 | 
			
		||||
	uint8_t		block_nr;
 | 
			
		||||
	int8_t		rssi;
 | 
			
		||||
	uint16_t	ber10k;		/* !< \brief BER in units of 0.01% */
 | 
			
		||||
	int16_t		ta_offs_qbits;	/* !< \brief Burst TA Offset in quarter bits */
 | 
			
		||||
	int16_t		lqual_cb;	/* !< \brief Link quality in centiBel */
 | 
			
		||||
	uint32_t	msg_id;
 | 
			
		||||
} __attribute__ ((packed));
 | 
			
		||||
 | 
			
		||||
struct gsm_pcu_if_rts_req {
 | 
			
		||||
@@ -180,6 +181,7 @@ struct gsm_pcu_if_info_ind {
 | 
			
		||||
		struct in_addr v4;
 | 
			
		||||
		struct in6_addr v6;
 | 
			
		||||
	} remote_ip[PCU_IF_NUM_NSVC];
 | 
			
		||||
	uint8_t		bts_model; /* enum gsm_pcuif_bts_model */
 | 
			
		||||
} __attribute__ ((packed));
 | 
			
		||||
 | 
			
		||||
struct gsm_pcu_if_act_req {
 | 
			
		||||
@@ -229,6 +231,32 @@ struct gsm_pcu_if_container {
 | 
			
		||||
	uint8_t		data[0];
 | 
			
		||||
} __attribute__ ((packed));
 | 
			
		||||
 | 
			
		||||
/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via PCH. The struct is sent as a data request
 | 
			
		||||
 * (data_req) under SAPI PCU_IF_SAPI_PCH_2. */
 | 
			
		||||
struct gsm_pcu_if_pch {
 | 
			
		||||
	/* message id as reference for confirmation */
 | 
			
		||||
	uint32_t msg_id;
 | 
			
		||||
	/* IMSI (to derive paging group) */
 | 
			
		||||
	char imsi[OSMO_IMSI_BUF_SIZE];
 | 
			
		||||
	/* GSM mac-block (with immediate assignment message) */
 | 
			
		||||
	uint8_t data[GSM_MACBLOCK_LEN];
 | 
			
		||||
	/* Set to true in case the receiving end must send a confirmation
 | 
			
		||||
	 * when the MAC block (data) has been sent. */
 | 
			
		||||
	bool confirm;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via AGCH. The struct is sent as a data request
 | 
			
		||||
 * (data_req) under SAPI PCU_IF_SAPI_AGCH_2. */
 | 
			
		||||
struct gsm_pcu_if_agch {
 | 
			
		||||
	/* message id as reference for confirmation */
 | 
			
		||||
	uint32_t msg_id;
 | 
			
		||||
	/* GSM mac-block (with immediate assignment message) */
 | 
			
		||||
	uint8_t data[GSM_MACBLOCK_LEN];
 | 
			
		||||
	/* Set to true in case the receiving end must send a confirmation
 | 
			
		||||
	 * when the MAC block (data) has been sent. */
 | 
			
		||||
	bool confirm;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
struct gsm_pcu_if {
 | 
			
		||||
	/* context based information */
 | 
			
		||||
	uint8_t		msg_type;	/* message type */
 | 
			
		||||
@@ -237,8 +265,7 @@ struct gsm_pcu_if {
 | 
			
		||||
 | 
			
		||||
	union {
 | 
			
		||||
		struct gsm_pcu_if_data		data_req;
 | 
			
		||||
		struct gsm_pcu_if_data		data_cnf;
 | 
			
		||||
		struct gsm_pcu_if_data_cnf_dt	data_cnf_dt;
 | 
			
		||||
		struct gsm_pcu_if_data_cnf	data_cnf2;
 | 
			
		||||
		struct gsm_pcu_if_data		data_ind;
 | 
			
		||||
		struct gsm_pcu_if_susp_req	susp_req;
 | 
			
		||||
		struct gsm_pcu_if_rts_req	rts_req;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,9 @@
 | 
			
		||||
#define LCHAN_FN_DUMMY 0xFFFFFFFF
 | 
			
		||||
#define LCHAN_FN_WAIT 0xFFFFFFFE
 | 
			
		||||
 | 
			
		||||
bool rsl_chan_rt_is_asci(enum rsl_cmod_crt chan_rt);
 | 
			
		||||
bool rsl_chan_rt_is_vgcs(enum rsl_cmod_crt chan_rt);
 | 
			
		||||
 | 
			
		||||
int down_rsl(struct gsm_bts_trx *trx, struct msgb *msg);
 | 
			
		||||
int rsl_tx_rf_res(struct gsm_bts_trx *trx);
 | 
			
		||||
int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime,
 | 
			
		||||
@@ -14,6 +17,8 @@ int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause);
 | 
			
		||||
int rsl_tx_conn_fail(const struct gsm_lchan *lchan, uint8_t cause);
 | 
			
		||||
int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan);
 | 
			
		||||
int rsl_tx_hando_det(struct gsm_lchan *lchan, uint8_t *ho_delay);
 | 
			
		||||
int rsl_tx_listener_det(struct gsm_lchan *lchan, uint8_t *acc_delay);
 | 
			
		||||
int rsl_tx_talker_det(struct gsm_lchan *lchan, uint8_t *acc_delay);
 | 
			
		||||
 | 
			
		||||
/* call-back for LAPDm code, called when it wants to send msgs UP */
 | 
			
		||||
int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								include/osmo-bts/rtp_input_preen.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								include/osmo-bts/rtp_input_preen.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
/*
 | 
			
		||||
 * RTP input validation function: makes the accept-or-drop decision,
 | 
			
		||||
 * and for some codecs signals additional required actions such as
 | 
			
		||||
 * dropping one header octet.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <osmo-bts/lchan.h>
 | 
			
		||||
 | 
			
		||||
enum pl_input_decision {
 | 
			
		||||
	PL_DECISION_DROP,
 | 
			
		||||
	PL_DECISION_ACCEPT,
 | 
			
		||||
	PL_DECISION_STRIP_HDR_OCTET,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum pl_input_decision
 | 
			
		||||
rtp_payload_input_preen(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
 | 
			
		||||
			unsigned rtp_pl_len, bool *rfc5993_sid_flag);
 | 
			
		||||
@@ -5,13 +5,6 @@
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/gsm_data.h>
 | 
			
		||||
 | 
			
		||||
/* Whether a logical channel must be activated automatically */
 | 
			
		||||
#define TRX_CHAN_FLAG_AUTO_ACTIVE	(1 << 0)
 | 
			
		||||
 | 
			
		||||
/* FIXME: we should actually activate 'auto-active' channels */
 | 
			
		||||
#define TRX_CHAN_IS_ACTIVE(state, chan) \
 | 
			
		||||
	(trx_chan_desc[chan].flags & TRX_CHAN_FLAG_AUTO_ACTIVE || (state)->active)
 | 
			
		||||
 | 
			
		||||
#define TRX_GMSK_NB_TSC(br) \
 | 
			
		||||
	_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
 | 
			
		||||
 | 
			
		||||
@@ -97,10 +90,10 @@ struct l1sched_chan_state {
 | 
			
		||||
	bool			active;		/* Channel is active */
 | 
			
		||||
	ubit_t			*dl_bursts;	/* burst buffer for TX */
 | 
			
		||||
	enum trx_mod_type	dl_mod_type;	/* Downlink modulation type */
 | 
			
		||||
	uint8_t			dl_mask;	/* mask of transmitted bursts */
 | 
			
		||||
	sbit_t			*ul_bursts;	/* burst buffer for RX */
 | 
			
		||||
	sbit_t			*ul_bursts_prev;/* previous burst buffer for RX (repeated SACCH) */
 | 
			
		||||
	uint32_t		ul_first_fn;	/* fn of first burst */
 | 
			
		||||
	uint8_t			ul_mask;	/* mask of received bursts */
 | 
			
		||||
	uint32_t		ul_mask;	/* mask of received bursts */
 | 
			
		||||
 | 
			
		||||
	/* loss detection */
 | 
			
		||||
	uint32_t		last_tdma_fn;	/* last processed TDMA frame number */
 | 
			
		||||
@@ -138,7 +131,7 @@ struct l1sched_chan_state {
 | 
			
		||||
	/* Uplink measurements */
 | 
			
		||||
	struct {
 | 
			
		||||
		/* Active channel measurements (simple ring buffer) */
 | 
			
		||||
		struct l1sched_meas_set buf[8]; /* up to 8 entries */
 | 
			
		||||
		struct l1sched_meas_set buf[24]; /* up to 24 (BUFMAX) entries */
 | 
			
		||||
		unsigned int current; /* current position */
 | 
			
		||||
 | 
			
		||||
		/* Interference measurements */
 | 
			
		||||
@@ -192,6 +185,12 @@ int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pch
 | 
			
		||||
/*! \brief set all matching logical channels active/inactive */
 | 
			
		||||
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active);
 | 
			
		||||
 | 
			
		||||
/*! \brief set uplink access on given logical channels active/inactive */
 | 
			
		||||
int trx_sched_set_ul_access(struct gsm_lchan *lchan, uint8_t chan_nr, bool active);
 | 
			
		||||
 | 
			
		||||
/*! \brief set all logical channels of BCCH/CCCH active/inactive */
 | 
			
		||||
int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool active);
 | 
			
		||||
 | 
			
		||||
/*! \brief set mode of all matching logical channels to given mode(s) */
 | 
			
		||||
int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,
 | 
			
		||||
	uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
 | 
			
		||||
@@ -304,6 +303,10 @@ int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi);
 | 
			
		||||
 | 
			
		||||
/* Averaging mode for trx_sched_meas_avg() */
 | 
			
		||||
enum sched_meas_avg_mode {
 | 
			
		||||
	/* first 22 of last 24 bursts (for TCH/F14.4, TCH/F9.6, TCH/F4.8) */
 | 
			
		||||
	SCHED_MEAS_AVG_M_S24N22,
 | 
			
		||||
	/* last 22 bursts (for TCH/H4.8, TCH/H2.4) */
 | 
			
		||||
	SCHED_MEAS_AVG_M_S22N22,
 | 
			
		||||
	/* last 4 bursts (default for xCCH, PTCCH and PDTCH) */
 | 
			
		||||
	SCHED_MEAS_AVG_M_S4N4,
 | 
			
		||||
	/* last 8 bursts (default for TCH/F and FACCH/F) */
 | 
			
		||||
 
 | 
			
		||||
@@ -42,16 +42,18 @@ extern const ubit_t _sched_train_seq_gmsk_sb[64];
 | 
			
		||||
struct msgb *_sched_dequeue_prim(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);
 | 
			
		||||
 | 
			
		||||
int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn,
 | 
			
		||||
			       enum trx_chan_type chan, uint8_t *l2,
 | 
			
		||||
			       uint8_t l2_len, float rssi,
 | 
			
		||||
			       enum trx_chan_type chan,
 | 
			
		||||
			       const uint8_t *data, size_t data_len,
 | 
			
		||||
			       uint16_t ber10k, float rssi,
 | 
			
		||||
			       int16_t ta_offs_256bits, int16_t link_qual_cb,
 | 
			
		||||
			       uint16_t ber10k,
 | 
			
		||||
			       enum osmo_ph_pres_info_type presence_info);
 | 
			
		||||
 | 
			
		||||
int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn,
 | 
			
		||||
			   enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len,
 | 
			
		||||
			   int16_t ta_offs_256bits, uint16_t ber10k, float rssi,
 | 
			
		||||
			   int16_t link_qual_cb, uint8_t is_sub);
 | 
			
		||||
			   enum trx_chan_type chan,
 | 
			
		||||
			   const uint8_t *data, size_t data_len,
 | 
			
		||||
			   uint16_t ber10k, float rssi,
 | 
			
		||||
			   int16_t ta_offs_256bits, int16_t link_qual_cb,
 | 
			
		||||
			   uint8_t is_sub);
 | 
			
		||||
 | 
			
		||||
int tx_fcch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
 | 
			
		||||
int tx_sch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
 | 
			
		||||
 
 | 
			
		||||
@@ -21,12 +21,9 @@ extern struct cmd_element cfg_bts_no_auto_band_cmd;
 | 
			
		||||
struct phy_instance *vty_get_phy_instance(struct vty *vty, int phy_nr, int inst_nr);
 | 
			
		||||
 | 
			
		||||
int bts_vty_go_parent(struct vty *vty);
 | 
			
		||||
int bts_vty_is_config_node(struct vty *vty, int node);
 | 
			
		||||
 | 
			
		||||
int bts_vty_init(void *ctx);
 | 
			
		||||
 | 
			
		||||
struct gsm_network *gsmnet_from_vty(struct vty *v);
 | 
			
		||||
 | 
			
		||||
extern struct vty_app_info bts_vty_info;
 | 
			
		||||
extern struct gsm_bts *g_bts;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,12 +33,15 @@ libbts_a_SOURCES = \
 | 
			
		||||
	oml.c \
 | 
			
		||||
	osmux.c \
 | 
			
		||||
	bts.c \
 | 
			
		||||
	bts_sm.c \
 | 
			
		||||
	bts_trx.c \
 | 
			
		||||
	rsl.c \
 | 
			
		||||
	rtp_input_preen.c \
 | 
			
		||||
	vty.c \
 | 
			
		||||
	paging.c \
 | 
			
		||||
	measurement.c \
 | 
			
		||||
	amr.c \
 | 
			
		||||
	asci.c \
 | 
			
		||||
	lchan.c \
 | 
			
		||||
	load_indication.c \
 | 
			
		||||
	pcu_sock.c \
 | 
			
		||||
@@ -48,6 +51,8 @@ libbts_a_SOURCES = \
 | 
			
		||||
	bts_ctrl_commands.c \
 | 
			
		||||
	bts_ctrl_lookup.c \
 | 
			
		||||
	bts_shutdown_fsm.c \
 | 
			
		||||
	csd_rlp.c \
 | 
			
		||||
	csd_v110.c \
 | 
			
		||||
	l1sap.c \
 | 
			
		||||
	cbch.c \
 | 
			
		||||
	power_control.c \
 | 
			
		||||
@@ -61,7 +66,11 @@ libbts_a_SOURCES = \
 | 
			
		||||
	nm_bts_fsm.c \
 | 
			
		||||
	nm_bb_transc_fsm.c \
 | 
			
		||||
	nm_channel_fsm.c \
 | 
			
		||||
	nm_gprs_cell_fsm.c \
 | 
			
		||||
	nm_gprs_nse_fsm.c \
 | 
			
		||||
	nm_gprs_nsvc_fsm.c \
 | 
			
		||||
	nm_radio_carrier_fsm.c \
 | 
			
		||||
	notification.c \
 | 
			
		||||
	probes.d \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -39,10 +39,10 @@
 | 
			
		||||
#include <osmocom/core/signal.h>
 | 
			
		||||
#include <osmocom/core/macaddr.h>
 | 
			
		||||
#include <osmocom/core/fsm.h>
 | 
			
		||||
#include <osmocom/gsm/protocol/ipaccess.h>
 | 
			
		||||
#include <osmocom/gsm/ipa.h>
 | 
			
		||||
#include <osmocom/abis/abis.h>
 | 
			
		||||
#include <osmocom/abis/e1_input.h>
 | 
			
		||||
#include <osmocom/abis/ipaccess.h>
 | 
			
		||||
#include <osmocom/gsm/ipa.h>
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/abis.h>
 | 
			
		||||
#include <osmo-bts/logging.h>
 | 
			
		||||
@@ -87,10 +87,17 @@ struct abis_link_fsm_priv {
 | 
			
		||||
 | 
			
		||||
static void reset_oml_link(struct gsm_bts *bts)
 | 
			
		||||
{
 | 
			
		||||
	struct e1inp_sign_link *link;
 | 
			
		||||
 | 
			
		||||
	if (bts->oml_link) {
 | 
			
		||||
		struct timespec now;
 | 
			
		||||
 | 
			
		||||
		e1inp_sign_link_destroy(bts->oml_link);
 | 
			
		||||
		/* Mark bts->oml_link ptr null before calling sign_link_destroy,
 | 
			
		||||
		 * to avoid a callback triggering this same code path. */
 | 
			
		||||
		link = bts->oml_link;
 | 
			
		||||
		bts->oml_link = NULL;
 | 
			
		||||
 | 
			
		||||
		e1inp_sign_link_destroy(link);
 | 
			
		||||
 | 
			
		||||
		/* Log a special notice if the OML connection was dropped relatively quickly. */
 | 
			
		||||
		if (bts->oml_conn_established_timestamp.tv_sec != 0 && clock_gettime(CLOCK_MONOTONIC, &now) == 0 &&
 | 
			
		||||
@@ -100,14 +107,16 @@ static void reset_oml_link(struct gsm_bts *bts)
 | 
			
		||||
			     "A common error is a mismatch between unit_id configuration parameters of BTS and BSC.\n",
 | 
			
		||||
			     (uint64_t) (now.tv_sec - bts->oml_conn_established_timestamp.tv_sec));
 | 
			
		||||
		}
 | 
			
		||||
		bts->oml_link = NULL;
 | 
			
		||||
	}
 | 
			
		||||
	memset(&bts->oml_conn_established_timestamp, 0, sizeof(bts->oml_conn_established_timestamp));
 | 
			
		||||
 | 
			
		||||
	/* Same for IPAC_PROTO_OSMO on the same ipa connection: */
 | 
			
		||||
	if (bts->osmo_link) {
 | 
			
		||||
		e1inp_sign_link_destroy(bts->osmo_link);
 | 
			
		||||
		/* Mark bts->osmo_link ptr null before calling sign_link_destroy,
 | 
			
		||||
		 * to avoid a callback triggering this same code path. */
 | 
			
		||||
		link = bts->osmo_link;
 | 
			
		||||
		bts->osmo_link = NULL;
 | 
			
		||||
		e1inp_sign_link_destroy(link);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -225,9 +234,12 @@ static void abis_link_connected(struct osmo_fsm_inst *fi, uint32_t event, void *
 | 
			
		||||
 | 
			
		||||
	/* Then iterate over the RSL signalling links */
 | 
			
		||||
	llist_for_each_entry(trx, &bts->trx_list, list) {
 | 
			
		||||
		if (trx->rsl_link) {
 | 
			
		||||
			e1inp_sign_link_destroy(trx->rsl_link);
 | 
			
		||||
			trx->rsl_link = NULL;
 | 
			
		||||
		if (trx->bb_transc.rsl.link) {
 | 
			
		||||
			/* Mark link ptr null before calling sign_link_destroy,
 | 
			
		||||
			 * to avoid a callback triggering this same code path. */
 | 
			
		||||
			struct e1inp_sign_link *link = trx->bb_transc.rsl.link;
 | 
			
		||||
			trx->bb_transc.rsl.link = NULL;
 | 
			
		||||
			e1inp_sign_link_destroy(link);
 | 
			
		||||
			if (trx == trx->bts->c0)
 | 
			
		||||
				load_timer_stop(trx->bts);
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -364,7 +376,7 @@ int abis_bts_rsl_sendmsg(struct msgb *msg)
 | 
			
		||||
 | 
			
		||||
	/* osmo-bts uses msg->trx internally, but libosmo-abis uses
 | 
			
		||||
	 * the signalling link at msg->dst */
 | 
			
		||||
	msg->dst = msg->trx->rsl_link;
 | 
			
		||||
	msg->dst = msg->trx->bb_transc.rsl.link;
 | 
			
		||||
	return abis_sendmsg(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -404,10 +416,10 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		e1inp_ts_config_sign(sign_ts, line);
 | 
			
		||||
		trx->rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
 | 
			
		||||
						       trx, trx->rsl_tei, 0);
 | 
			
		||||
		trx->bb_transc.rsl.link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
 | 
			
		||||
								 trx, trx->bb_transc.rsl.tei, 0);
 | 
			
		||||
		trx_link_estab(trx);
 | 
			
		||||
		return trx->rsl_link;
 | 
			
		||||
		return trx->bb_transc.rsl.link;
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -476,8 +488,11 @@ static int inp_s_cbfn(unsigned int subsys, unsigned int signal,
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	struct input_signal_data *isd = signal_data;
 | 
			
		||||
	DEBUGP(DABIS, "Input Signal %s received for link_type=%s\n",
 | 
			
		||||
	       get_value_string(e1inp_signal_names, signal), e1inp_signtype_name(isd->link_type));
 | 
			
		||||
	DEBUGP(DABIS, "Input Signal %s received for ts-%u-%u link_type=%s\n",
 | 
			
		||||
	       get_value_string(e1inp_signal_names, signal),
 | 
			
		||||
	       isd->line ? isd->line->num : -1,
 | 
			
		||||
	       isd->ts_nr,
 | 
			
		||||
	       e1inp_signtype_name(isd->link_type));
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* OSMO extenion link associated to same line as oml_link: */
 | 
			
		||||
 | 
			
		||||
/* (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 | 
			
		||||
/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -30,8 +30,7 @@
 | 
			
		||||
#include <osmo-bts/logging.h>
 | 
			
		||||
#include <osmo-bts/pcu_if.h>
 | 
			
		||||
#include <osmo-bts/pcuif_proto.h>
 | 
			
		||||
 | 
			
		||||
extern struct gsm_network bts_gsmnet;
 | 
			
		||||
#include <osmo-bts/bts_sm.h>
 | 
			
		||||
 | 
			
		||||
#define OM_HEADROOM_SIZE	128
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +105,7 @@ static int rx_down_osmo_pcu(struct gsm_bts *bts, struct msgb *msg)
 | 
			
		||||
	/* Trim Abis lower layers: */
 | 
			
		||||
	msgb_pull_to_l2(msg);
 | 
			
		||||
	/* we simply forward it to PCUIF: */
 | 
			
		||||
	return pcu_sock_send(&bts_gsmnet, msg);
 | 
			
		||||
	return pcu_sock_send(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* incoming IPA/OSMO extension Abis message from BSC */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										211
									
								
								src/common/asci.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								src/common/asci.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,211 @@
 | 
			
		||||
/* ASCI (VGCS/VBS) related common code */
 | 
			
		||||
 | 
			
		||||
/* (C) 2023 by Harald Welte <laforge@osmocom.org>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
 | 
			
		||||
#include <osmocom/gsm/rsl.h>
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/bts.h>
 | 
			
		||||
#include <osmo-bts/bts_model.h>
 | 
			
		||||
#include <osmo-bts/rsl.h>
 | 
			
		||||
#include <osmo-bts/logging.h>
 | 
			
		||||
#include <osmo-bts/l1sap.h>
 | 
			
		||||
#include <osmo-bts/asci.h>
 | 
			
		||||
 | 
			
		||||
static int tx_vgcs_ul_grant(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm0408_vgcs_ul_grant ul_grant;
 | 
			
		||||
	struct gsm_time gt;
 | 
			
		||||
	struct msgb *msg;
 | 
			
		||||
 | 
			
		||||
	gsm_fn2gsmtime(>, lchan->asci.fn);
 | 
			
		||||
 | 
			
		||||
	/* build the RR VGCS UPLINK GRANT message as per TS 44.018 Section 9.1.49 */
 | 
			
		||||
	ul_grant = (struct gsm0408_vgcs_ul_grant) {
 | 
			
		||||
		.hdr = {
 | 
			
		||||
			.proto_discr = GSM48_PDISC_RR,
 | 
			
		||||
			.msg_type = GSM48_MT_RR_VGCS_UPL_GRANT,
 | 
			
		||||
		},
 | 
			
		||||
		.req_ref = {
 | 
			
		||||
			.ra = lchan->asci.ref,
 | 
			
		||||
			.t1 = gt.t1,
 | 
			
		||||
			.t2 = gt.t2,
 | 
			
		||||
			.t3_low = gt.t3 & 7,
 | 
			
		||||
			.t3_high = gt.t3 >> 3,
 | 
			
		||||
		},
 | 
			
		||||
		.ta = lchan->ta_ctrl.current,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/* Wrap it in a RSL UNITDATA REQUEST */
 | 
			
		||||
	msg = rsl_rll_simple(RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan), 0x00, 0);
 | 
			
		||||
	msg->l3h = msg->tail; /* emulate rsl_rx_rll() behaviour */
 | 
			
		||||
	msgb_tl16v_put(msg, RSL_IE_L3_INFO, sizeof(ul_grant), (uint8_t *) &ul_grant);
 | 
			
		||||
 | 
			
		||||
	/* send it towards MS, just like a RSL message from the BSC */
 | 
			
		||||
	return lapdm_rslms_recvmsg(msg, &lchan->lapdm_ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* timer call-back for T3115 (VGCS UPLINK GRANT re-transmit) */
 | 
			
		||||
static void vgcs_t3115_cb(void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_lchan *lchan = data;
 | 
			
		||||
	struct gsm_bts *bts = lchan->ts->trx->bts;
 | 
			
		||||
 | 
			
		||||
	LOGPLCHAN(lchan, DASCI, LOGL_INFO, "T3115 timeout (%d resends left)\n",
 | 
			
		||||
		  bts->ny2 - lchan->asci.vgcs_ul_grant_count);
 | 
			
		||||
 | 
			
		||||
	if (lchan->state != LCHAN_S_ACTIVE) {
 | 
			
		||||
		LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "is not active. It is in state %s. Ignoring\n",
 | 
			
		||||
			  gsm_lchans_name(lchan->state));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lchan->asci.vgcs_ul_grant_count >= bts->ny2) {
 | 
			
		||||
		lchan->asci.vgcs_ul_grant_count = 0;
 | 
			
		||||
		LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "NY2 reached, sending CONNection FAILure to BSC.\n");
 | 
			
		||||
		rsl_tx_conn_fail(lchan, RSL_ERR_TALKER_ACC_FAIL);
 | 
			
		||||
		lchan->asci.talker_active = VGCS_TALKER_NONE;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tx_vgcs_ul_grant(lchan);
 | 
			
		||||
	lchan->asci.vgcs_ul_grant_count++;
 | 
			
		||||
	osmo_timer_schedule(&lchan->asci.t3115, 0, bts->t3115_ms * 1000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Received random access on dedicated channel. */
 | 
			
		||||
void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn)
 | 
			
		||||
{
 | 
			
		||||
	LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "VGCS RACH on dedicated channel type %s received with "
 | 
			
		||||
		  "TA=%u, ref=%u\n", gsm_lchant_name(lchan->type), acc_delay, ra);
 | 
			
		||||
 | 
			
		||||
	if (ra == 0x25) { /* See TS 44.018 Table 9.1.45.1 */
 | 
			
		||||
		/* Listener Detection (TS 48.058 Section 4.14) */
 | 
			
		||||
		if (!lchan->asci.listener_detected) {
 | 
			
		||||
			rsl_tx_listener_det(lchan, &acc_delay);
 | 
			
		||||
			lchan->asci.listener_detected = true;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Talker Detection (TS 48.058 Section 4.13) */
 | 
			
		||||
		struct gsm_bts *bts = lchan->ts->trx->bts;
 | 
			
		||||
 | 
			
		||||
		/* Talker detection on group channels only */
 | 
			
		||||
		if (!rsl_chan_rt_is_vgcs(lchan->rsl_chan_rt))
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		if (lchan->asci.talker_active != VGCS_TALKER_NONE) {
 | 
			
		||||
			LOGPLCHAN(lchan, DASCI, LOGL_DEBUG, "Ignoring RACH, there is an active talker already.\n");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Set timing advance, power level and activate SACCH */
 | 
			
		||||
		lchan->ta_ctrl.current = acc_delay;
 | 
			
		||||
		lchan->ms_power_ctrl.current = lchan->ms_power_ctrl.max;
 | 
			
		||||
		lchan->want_dl_sacch_active = true;
 | 
			
		||||
 | 
			
		||||
		/* Stop RACH detection, wait for valid frame */
 | 
			
		||||
		lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
 | 
			
		||||
		if (l1sap_uplink_access(lchan, false) != 0) {
 | 
			
		||||
			LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access after TALKER DET.\n");
 | 
			
		||||
			rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
 | 
			
		||||
			lchan->asci.talker_active = VGCS_TALKER_NONE;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		lchan->asci.ref = ra;
 | 
			
		||||
		lchan->asci.fn = fn;
 | 
			
		||||
 | 
			
		||||
		/* Send TALKER DETECT via RSL to BSC */
 | 
			
		||||
		rsl_tx_talker_det(lchan, &acc_delay);
 | 
			
		||||
 | 
			
		||||
		/* Send VGCS UPLINK GRANT */
 | 
			
		||||
		lchan->asci.vgcs_ul_grant_count = 1;
 | 
			
		||||
		tx_vgcs_ul_grant(lchan);
 | 
			
		||||
 | 
			
		||||
		/* Start T3115 */
 | 
			
		||||
		LOGPLCHAN(lchan, DASCI, LOGL_DEBUG, "Starting T3115 with %u ms\n", bts->t3115_ms);
 | 
			
		||||
		lchan->asci.t3115.cb = vgcs_t3115_cb;
 | 
			
		||||
		lchan->asci.t3115.data = lchan;
 | 
			
		||||
		osmo_timer_schedule(&lchan->asci.t3115, 0, bts->t3115_ms * 1000);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Received channel activation. */
 | 
			
		||||
void vgcs_lchan_activate(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated.\n");
 | 
			
		||||
	if (l1sap_uplink_access(lchan, true) != 0) {
 | 
			
		||||
		LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to activate uplink access after channel activation.\n");
 | 
			
		||||
		rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Received channel reactivation. (for assignment) */
 | 
			
		||||
void vgcs_lchan_react(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated for assignment.\n");
 | 
			
		||||
	lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
 | 
			
		||||
	if (l1sap_uplink_access(lchan, false) != 0) {
 | 
			
		||||
		LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access for assignment.\n");
 | 
			
		||||
		rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
 | 
			
		||||
	}
 | 
			
		||||
	radio_link_timeout_reset(lchan);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Received first valid data frame on dedicated channel. */
 | 
			
		||||
void vgcs_talker_frame(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	LOGPLCHAN(lchan, DASCI, LOGL_INFO, "First valid frame detected, talker now active.\n");
 | 
			
		||||
	osmo_timer_del(&lchan->asci.t3115);
 | 
			
		||||
	lchan->asci.talker_active = VGCS_TALKER_ACTIVE;
 | 
			
		||||
	radio_link_timeout_reset(lchan);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Release VGCS Talker state. */
 | 
			
		||||
void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access)
 | 
			
		||||
{
 | 
			
		||||
	if (lchan->asci.talker_active == VGCS_TALKER_NONE)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Uplink released, no talker.\n");
 | 
			
		||||
 | 
			
		||||
	/* Stop T3115 */
 | 
			
		||||
	osmo_timer_del(&lchan->asci.t3115);
 | 
			
		||||
 | 
			
		||||
	/* Talker released. */
 | 
			
		||||
	lchan->asci.talker_active = VGCS_TALKER_NONE;
 | 
			
		||||
	if (ul_access) {
 | 
			
		||||
		if (l1sap_uplink_access(lchan, true) != 0) {
 | 
			
		||||
			LOGPLCHAN(lchan, DASCI, LOGL_ERROR,
 | 
			
		||||
				  "Failed to activate uplink access after uplink became free.\n");
 | 
			
		||||
			rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Release VGCS Listener state. */
 | 
			
		||||
void vgcs_listener_reset(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	lchan->asci.listener_detected = false;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										295
									
								
								src/common/bts.c
									
									
									
									
									
								
							
							
						
						
									
										295
									
								
								src/common/bts.c
									
									
									
									
									
								
							@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -44,8 +44,10 @@
 | 
			
		||||
#include <osmo-bts/abis.h>
 | 
			
		||||
#include <osmo-bts/bts.h>
 | 
			
		||||
#include <osmo-bts/bts_model.h>
 | 
			
		||||
#include <osmo-bts/bts_sm.h>
 | 
			
		||||
#include <osmo-bts/dtx_dl_amr_fsm.h>
 | 
			
		||||
#include <osmo-bts/pcuif_proto.h>
 | 
			
		||||
#include <osmo-bts/pcu_if.h>
 | 
			
		||||
#include <osmo-bts/rsl.h>
 | 
			
		||||
#include <osmo-bts/oml.h>
 | 
			
		||||
#include <osmo-bts/signal.h>
 | 
			
		||||
@@ -55,17 +57,14 @@
 | 
			
		||||
#include <osmo-bts/nm_common_fsm.h>
 | 
			
		||||
#include <osmo-bts/power_control.h>
 | 
			
		||||
#include <osmo-bts/osmux.h>
 | 
			
		||||
#include <osmo-bts/notification.h>
 | 
			
		||||
 | 
			
		||||
#define MAX_TA_DEF	 63 /* default max Timing Advance value */
 | 
			
		||||
#define MIN_QUAL_RACH	 50 /* minimum link quality (in centiBels) for Access Bursts */
 | 
			
		||||
#define MIN_QUAL_NORM	 -5 /* minimum link quality (in centiBels) for Normal Bursts */
 | 
			
		||||
 | 
			
		||||
static void bts_update_agch_max_queue_length(struct gsm_bts *bts);
 | 
			
		||||
 | 
			
		||||
struct gsm_network bts_gsmnet = {
 | 
			
		||||
	.bts_list = { &bts_gsmnet.bts_list, &bts_gsmnet.bts_list },
 | 
			
		||||
	.num_bts = 0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void *tall_bts_ctx;
 | 
			
		||||
 | 
			
		||||
/* Table 3.1 TS 04.08: Values of parameter S */
 | 
			
		||||
@@ -98,12 +97,22 @@ static const struct rate_ctr_desc bts_ctr_desc[] = {
 | 
			
		||||
	[BTS_CTR_RACH_RCVD] =		{"rach:rcvd", "Received RACH requests (Um)"},
 | 
			
		||||
	[BTS_CTR_RACH_DROP] =		{"rach:drop", "Dropped RACH requests (Um)"},
 | 
			
		||||
	[BTS_CTR_RACH_HO] =		{"rach:handover", "Received RACH requests (Handover)"},
 | 
			
		||||
	[BTS_CTR_RACH_VGCS] =		{"rach:vgcs", "Received RACH requests (VGCS)"},
 | 
			
		||||
	[BTS_CTR_RACH_CS] =		{"rach:cs", "Received RACH requests (CS/Abis)"},
 | 
			
		||||
	[BTS_CTR_RACH_PS] =		{"rach:ps", "Received RACH requests (PS/PCU)"},
 | 
			
		||||
 | 
			
		||||
	[BTS_CTR_AGCH_RCVD] =		{"agch:rcvd", "Received AGCH requests (Abis)"},
 | 
			
		||||
	[BTS_CTR_AGCH_SENT] =		{"agch:sent", "Sent AGCH requests (Abis)"},
 | 
			
		||||
	[BTS_CTR_AGCH_DELETED] =	{"agch:delete", "Sent AGCH DELETE IND (Abis)"},
 | 
			
		||||
 | 
			
		||||
	[BTS_CTR_RTP_RX_TOTAL] =	{"rtp:rx:total", "Total number of received RTP packets"},
 | 
			
		||||
	[BTS_CTR_RTP_RX_MARKER] =	{"rtp:rx:marker", "Number of received RTP packets with marker bit set"},
 | 
			
		||||
	[BTS_CTR_RTP_RX_DROP_PREEN] =	{"rtp:rx:drop:preen", "Total number of received RTP packets dropped during preening"},
 | 
			
		||||
	[BTS_CTR_RTP_RX_DROP_LOOPBACK] = {"rtp:rx:drop:loopback", "Total number of received RTP packets dropped during loopback"},
 | 
			
		||||
	[BTS_CTR_RTP_RX_DROP_OVERFLOW] = {"rtp:rx:drop:overflow", "Total number of received RTP packets dropped during DL queue overflow"},
 | 
			
		||||
	[BTS_CTR_RTP_RX_DROP_V110_DEC] = {"rtp:rx:drop:v110_dec", "Total number of received RTP packets dropped during V.110 decode"},
 | 
			
		||||
	[BTS_CTR_RTP_TX_TOTAL] =	{"rtp:tx:total", "Total number of transmitted RTP packets"},
 | 
			
		||||
	[BTS_CTR_RTP_TX_MARKER] =	{"rtp:tx:marker", "Number of transmitted RTP packets with marker bit set"},
 | 
			
		||||
};
 | 
			
		||||
static const struct rate_ctr_group_desc bts_ctrg_desc = {
 | 
			
		||||
	"bts",
 | 
			
		||||
@@ -149,7 +158,6 @@ struct osmo_tdef abis_T_defs[] = {
 | 
			
		||||
	{}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
 | 
			
		||||
static const uint8_t bts_cell_timer_default[] =
 | 
			
		||||
				{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
 | 
			
		||||
static const struct gprs_rlc_cfg rlc_cfg_default = {
 | 
			
		||||
@@ -207,15 +215,16 @@ const char *btsatttr2str(enum bts_attribute v)
 | 
			
		||||
const struct value_string bts_impl_flag_desc[] = {
 | 
			
		||||
	{ BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP,	"DSP/HW based MS Power Control Loop" },
 | 
			
		||||
	{ BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB,	"Measurement and Payload data combined" },
 | 
			
		||||
	{ BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER, "OML RadioChannel MO depends on RadioCarrier MO" },
 | 
			
		||||
	{ BTS_INTERNAL_FLAG_INTERF_MEAS,	"Uplink interference measurements" },
 | 
			
		||||
	{ 0, NULL }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Ensure that all BTS_INTERNAL_FLAG_* entries are present in bts_impl_flag_desc[] */
 | 
			
		||||
osmo_static_assert(ARRAY_SIZE(bts_impl_flag_desc) == _BTS_INTERNAL_FLAG_NUM + 1, _bts_impl_flag_desc);
 | 
			
		||||
 | 
			
		||||
static int gsm_bts_talloc_destructor(struct gsm_bts *bts)
 | 
			
		||||
{
 | 
			
		||||
	if (bts->site_mgr.mo.fi) {
 | 
			
		||||
		osmo_fsm_inst_free(bts->site_mgr.mo.fi);
 | 
			
		||||
		bts->site_mgr.mo.fi = NULL;
 | 
			
		||||
	}
 | 
			
		||||
	if (bts->mo.fi) {
 | 
			
		||||
		osmo_fsm_inst_free(bts->mo.fi);
 | 
			
		||||
		bts->mo.fi = NULL;
 | 
			
		||||
@@ -226,19 +235,26 @@ static int gsm_bts_talloc_destructor(struct gsm_bts *bts)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bts_osmux_release(bts);
 | 
			
		||||
 | 
			
		||||
	llist_del(&bts->list);
 | 
			
		||||
	g_bts_sm->num_bts--;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
 | 
			
		||||
struct gsm_bts *gsm_bts_alloc(struct gsm_bts_sm *bts_sm, uint8_t bts_num)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
 | 
			
		||||
	int i;
 | 
			
		||||
	struct gsm_bts *bts = talloc_zero(bts_sm, struct gsm_bts);
 | 
			
		||||
 | 
			
		||||
	if (!bts)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	talloc_set_destructor(bts, gsm_bts_talloc_destructor);
 | 
			
		||||
 | 
			
		||||
	/* add to list of BTSs */
 | 
			
		||||
	llist_add_tail(&bts->list, &bts_sm->bts_list);
 | 
			
		||||
	g_bts_sm->num_bts++;
 | 
			
		||||
 | 
			
		||||
	bts->site_mgr = bts_sm;
 | 
			
		||||
	bts->nr = bts_num;
 | 
			
		||||
	bts->num_trx = 0;
 | 
			
		||||
	INIT_LLIST_HEAD(&bts->trx_list);
 | 
			
		||||
@@ -251,32 +267,19 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
 | 
			
		||||
					       LOGL_INFO, NULL);
 | 
			
		||||
	osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr);
 | 
			
		||||
 | 
			
		||||
	bts->site_mgr.mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts, &bts->site_mgr,
 | 
			
		||||
						  LOGL_INFO, "bts_sm");
 | 
			
		||||
	gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
 | 
			
		||||
		    0xff, 0xff, 0xff);
 | 
			
		||||
 | 
			
		||||
	/* NM BTS */
 | 
			
		||||
	bts->mo.fi = osmo_fsm_inst_alloc(&nm_bts_fsm, bts, bts,
 | 
			
		||||
					 LOGL_INFO, NULL);
 | 
			
		||||
	osmo_fsm_inst_update_id_f(bts->mo.fi, "bts%d", bts->nr);
 | 
			
		||||
	gsm_mo_init(&bts->mo, bts, NM_OC_BTS, bts->nr, 0xff, 0xff);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
 | 
			
		||||
		bts->gprs.nsvc[i].bts = bts;
 | 
			
		||||
		bts->gprs.nsvc[i].id = i;
 | 
			
		||||
		gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
 | 
			
		||||
				bts->nr, i, 0xff);
 | 
			
		||||
	}
 | 
			
		||||
	memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
 | 
			
		||||
		sizeof(bts->gprs.nse.timer));
 | 
			
		||||
	gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
 | 
			
		||||
			bts->nr, 0xff, 0xff);
 | 
			
		||||
	memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
 | 
			
		||||
		sizeof(bts->gprs.cell.timer));
 | 
			
		||||
	gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
 | 
			
		||||
			bts->nr, 0xff, 0xff);
 | 
			
		||||
	memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
 | 
			
		||||
		sizeof(bts->gprs.cell.rlc_cfg));
 | 
			
		||||
	/* NM GPRS CELL */
 | 
			
		||||
	bts->gprs.cell.mo.fi = osmo_fsm_inst_alloc(&nm_gprs_cell_fsm, bts, &bts->gprs.cell,
 | 
			
		||||
						  LOGL_INFO, NULL);
 | 
			
		||||
	osmo_fsm_inst_update_id_f(bts->gprs.cell.mo.fi, "gprs_cell%d-0", bts->nr);
 | 
			
		||||
	gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL, bts->nr, 0, 0xff);
 | 
			
		||||
	memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default, sizeof(bts->gprs.cell.rlc_cfg));
 | 
			
		||||
	memcpy(&bts->gprs.cell.timer, bts_cell_timer_default, sizeof(bts->gprs.cell.timer));
 | 
			
		||||
 | 
			
		||||
	/* create our primary TRX. It will be initialized during bts_init() */
 | 
			
		||||
	bts->c0 = gsm_bts_trx_alloc(bts);
 | 
			
		||||
@@ -292,14 +295,14 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
 | 
			
		||||
	return bts;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num)
 | 
			
		||||
struct gsm_bts *gsm_bts_num(const struct gsm_bts_sm *bts_sm, int num)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts *bts;
 | 
			
		||||
 | 
			
		||||
	if (num >= net->num_bts)
 | 
			
		||||
	if (num >= bts_sm->num_bts)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	llist_for_each_entry(bts, &net->bts_list, list) {
 | 
			
		||||
	llist_for_each_entry(bts, &bts_sm->bts_list, list) {
 | 
			
		||||
		if (bts->nr == num)
 | 
			
		||||
			return bts;
 | 
			
		||||
	}
 | 
			
		||||
@@ -315,19 +318,14 @@ int bts_init(struct gsm_bts *bts)
 | 
			
		||||
	static int initialized = 0;
 | 
			
		||||
	void *tall_rtp_ctx;
 | 
			
		||||
 | 
			
		||||
	/* add to list of BTSs */
 | 
			
		||||
	llist_add_tail(&bts->list, &bts_gsmnet.bts_list);
 | 
			
		||||
 | 
			
		||||
	bts->band = GSM_BAND_1800;
 | 
			
		||||
 | 
			
		||||
	INIT_LLIST_HEAD(&bts->agch_queue.queue);
 | 
			
		||||
	bts->agch_queue.length = 0;
 | 
			
		||||
 | 
			
		||||
	bts->ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);
 | 
			
		||||
	if (!bts->ctrs) {
 | 
			
		||||
		llist_del(&bts->list);
 | 
			
		||||
	if (!bts->ctrs)
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* enable management with default levels,
 | 
			
		||||
	 * raise threshold to GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE to
 | 
			
		||||
@@ -345,37 +343,37 @@ int bts_init(struct gsm_bts *bts)
 | 
			
		||||
	bts->rtp_port_range_next = bts->rtp_port_range_start;
 | 
			
		||||
	bts->rtp_ip_dscp = -1;
 | 
			
		||||
	bts->rtp_priority = -1;
 | 
			
		||||
	bts->emit_hr_rfc5993 = true;
 | 
			
		||||
 | 
			
		||||
	/* Default (fall-back) MS/BS Power control parameters */
 | 
			
		||||
	power_ctrl_params_def_reset(&bts->bs_dpc_params, true);
 | 
			
		||||
	power_ctrl_params_def_reset(&bts->ms_dpc_params, false);
 | 
			
		||||
 | 
			
		||||
	/* configurable via OML */
 | 
			
		||||
	bts->bsic = 0xff; /* invalid value, guarded by bsc_configured=false */
 | 
			
		||||
	bts->bsic_configured = false;
 | 
			
		||||
	bts->load.ccch.load_ind_period = 112;
 | 
			
		||||
	bts->rtp_jitter_buf_ms = 100;
 | 
			
		||||
	bts->max_ta = 63;
 | 
			
		||||
	bts->max_ta = MAX_TA_DEF;
 | 
			
		||||
	bts->ny1 = 4;
 | 
			
		||||
	bts->ny2 = 4;
 | 
			
		||||
	bts->t3105_ms = 300;
 | 
			
		||||
	bts->t3115_ms = 300;
 | 
			
		||||
	bts->min_qual_rach = MIN_QUAL_RACH;
 | 
			
		||||
	bts->min_qual_norm = MIN_QUAL_NORM;
 | 
			
		||||
	bts->max_ber10k_rach = 1707; /* 7 of 41 bits is Eb/N0 of 0 dB = 0.1707 */
 | 
			
		||||
	bts->pcu.sock_path = talloc_strdup(bts, PCU_SOCK_DEFAULT);
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(bts->t200_ms); i++)
 | 
			
		||||
		bts->t200_ms[i] = oml_default_t200_ms[i];
 | 
			
		||||
	bts->pcu.sock_wqueue_len_max = BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT;
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(bts->t200_fn); i++)
 | 
			
		||||
		bts->t200_fn[i] = oml_default_t200_fn[i];
 | 
			
		||||
 | 
			
		||||
	/* default RADIO_LINK_TIMEOUT */
 | 
			
		||||
	bts->radio_link_timeout.oml = 32;
 | 
			
		||||
	bts->radio_link_timeout.current = bts->radio_link_timeout.oml;
 | 
			
		||||
 | 
			
		||||
	/* Start with the site manager */
 | 
			
		||||
	oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
 | 
			
		||||
	/* Start with the BTS */
 | 
			
		||||
	oml_mo_state_init(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
 | 
			
		||||
 | 
			
		||||
	/* set BTS attr to dependency */
 | 
			
		||||
	oml_mo_state_init(&bts->gprs.nse.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
 | 
			
		||||
	oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
 | 
			
		||||
	oml_mo_state_init(&bts->gprs.nsvc[0].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
 | 
			
		||||
	oml_mo_state_init(&bts->gprs.nsvc[1].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
 | 
			
		||||
	oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
 | 
			
		||||
 | 
			
		||||
	/* allocate a talloc pool for ORTP to ensure it doesn't have to go back
 | 
			
		||||
	 * to the libc malloc all the time */
 | 
			
		||||
@@ -384,10 +382,8 @@ int bts_init(struct gsm_bts *bts)
 | 
			
		||||
 | 
			
		||||
	/* Osmux */
 | 
			
		||||
	rc = bts_osmux_init(bts);
 | 
			
		||||
	if (rc < 0) {
 | 
			
		||||
		llist_del(&bts->list);
 | 
			
		||||
	if (rc < 0)
 | 
			
		||||
		return rc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* features implemented in 'common', available for all models,
 | 
			
		||||
	 * order alphabetically */
 | 
			
		||||
@@ -397,16 +393,18 @@ int bts_init(struct gsm_bts *bts)
 | 
			
		||||
	osmo_bts_set_feature(bts->features, BTS_FEAT_ETWS_PN);
 | 
			
		||||
	osmo_bts_set_feature(bts->features, BTS_FEAT_IPV6_NSVC);
 | 
			
		||||
	osmo_bts_set_feature(bts->features, BTS_FEAT_PAGING_COORDINATION);
 | 
			
		||||
	osmo_bts_set_feature(bts->features, BTS_FEAT_TWTS001);
 | 
			
		||||
	osmo_bts_set_feature(bts->features, BTS_FEAT_TWTS002);
 | 
			
		||||
 | 
			
		||||
	/* Maximum TA supported by the PHY (can be overridden by PHY specific code) */
 | 
			
		||||
	bts->support.max_ta = MAX_TA_DEF;
 | 
			
		||||
 | 
			
		||||
	rc = bts_model_init(bts);
 | 
			
		||||
	if (rc < 0) {
 | 
			
		||||
		llist_del(&bts->list);
 | 
			
		||||
	if (rc < 0)
 | 
			
		||||
		return rc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* TRX0 was allocated early during gsm_bts_alloc, not later through VTY */
 | 
			
		||||
	bts_model_trx_init(bts->c0);
 | 
			
		||||
	bts_gsmnet.num_bts++;
 | 
			
		||||
 | 
			
		||||
	if (!initialized) {
 | 
			
		||||
		osmo_signal_register_handler(SS_GLOBAL, bts_signal_cbfn, NULL);
 | 
			
		||||
@@ -423,6 +421,9 @@ int bts_init(struct gsm_bts *bts)
 | 
			
		||||
	bts->smscb_queue_tgt_len = 2;
 | 
			
		||||
	bts->smscb_queue_hyst = 2;
 | 
			
		||||
 | 
			
		||||
	bts->asci.pos_nch = -ENOTSUP;
 | 
			
		||||
	INIT_LLIST_HEAD(&bts->asci.notifications);
 | 
			
		||||
 | 
			
		||||
	INIT_LLIST_HEAD(&bts->bsc_oml_hosts);
 | 
			
		||||
 | 
			
		||||
	/* register DTX DL FSM */
 | 
			
		||||
@@ -440,33 +441,13 @@ int bts_init(struct gsm_bts *bts)
 | 
			
		||||
/* main link is established, send status report */
 | 
			
		||||
int bts_link_estab(struct gsm_bts *bts)
 | 
			
		||||
{
 | 
			
		||||
	int i, j;
 | 
			
		||||
	LOGP(DOML, LOGL_INFO, "Main link established, sending NM Status\n");
 | 
			
		||||
 | 
			
		||||
	LOGP(DOML, LOGL_INFO, "Main link established, sending NM Status.\n");
 | 
			
		||||
 | 
			
		||||
	/* BTS SITE MGR becomes Offline (tx SW ACT Report), BTS is DEPENDENCY */
 | 
			
		||||
	osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SW_ACT, NULL);
 | 
			
		||||
	osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_SW_ACT, NULL);
 | 
			
		||||
 | 
			
		||||
	/* those should all be in DEPENDENCY */
 | 
			
		||||
	oml_tx_state_changed(&bts->gprs.nse.mo);
 | 
			
		||||
	oml_tx_state_changed(&bts->gprs.cell.mo);
 | 
			
		||||
	oml_tx_state_changed(&bts->gprs.nsvc[0].mo);
 | 
			
		||||
	oml_tx_state_changed(&bts->gprs.nsvc[1].mo);
 | 
			
		||||
 | 
			
		||||
	/* All other objects start off-line until the BTS Model code says otherwise */
 | 
			
		||||
	for (i = 0; i < bts->num_trx; i++) {
 | 
			
		||||
		struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, i);
 | 
			
		||||
 | 
			
		||||
		oml_tx_state_changed(&trx->mo);
 | 
			
		||||
		oml_tx_state_changed(&trx->bb_transc.mo);
 | 
			
		||||
 | 
			
		||||
		for (j = 0; j < ARRAY_SIZE(trx->ts); j++) {
 | 
			
		||||
			struct gsm_bts_trx_ts *ts = &trx->ts[j];
 | 
			
		||||
 | 
			
		||||
			oml_tx_state_changed(&ts->mo);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	/* Signal OML UP to BTS SITE MGR. It will automatically SW_ACT repoort
 | 
			
		||||
	 * and become Disabled-Offline, then dispatch same event to its children
 | 
			
		||||
	 * objects.
 | 
			
		||||
	 */
 | 
			
		||||
	osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OML_UP, NULL);
 | 
			
		||||
 | 
			
		||||
	return bts_model_oml_estab(bts);
 | 
			
		||||
}
 | 
			
		||||
@@ -693,7 +674,7 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct msgb *bts_agch_dequeue(struct gsm_bts *bts)
 | 
			
		||||
static struct msgb *bts_agch_dequeue(struct gsm_bts *bts)
 | 
			
		||||
{
 | 
			
		||||
	struct msgb *msg = msgb_dequeue(&bts->agch_queue.queue);
 | 
			
		||||
	if (!msg)
 | 
			
		||||
@@ -759,12 +740,12 @@ static void compact_agch_queue(struct gsm_bts *bts)
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
 | 
			
		||||
		      int is_ag_res)
 | 
			
		||||
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, enum ccch_msgt ccch)
 | 
			
		||||
{
 | 
			
		||||
	struct msgb *msg = NULL;
 | 
			
		||||
	int rc = 0;
 | 
			
		||||
	int is_empty = 1;
 | 
			
		||||
	const struct bts_agch_msg_cb *msg_cb;
 | 
			
		||||
 | 
			
		||||
	/* Do queue house keeping.
 | 
			
		||||
	 * This needs to be done every time a CCCH message is requested, since
 | 
			
		||||
@@ -773,26 +754,39 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt
 | 
			
		||||
	 */
 | 
			
		||||
	compact_agch_queue(bts);
 | 
			
		||||
 | 
			
		||||
	/* Check for paging messages first if this is PCH */
 | 
			
		||||
	if (!is_ag_res)
 | 
			
		||||
	switch (ccch) {
 | 
			
		||||
	case CCCH_MSGT_NCH:
 | 
			
		||||
		/* Send NCH message, it has priority over AGCH and does not overlap with PCH. */
 | 
			
		||||
		rc = bts_asci_notify_nch_gen_msg(bts, out_buf);
 | 
			
		||||
		return rc;
 | 
			
		||||
	case CCCH_MSGT_PCH:
 | 
			
		||||
		/* Check whether the block may be overwritten by AGCH. */
 | 
			
		||||
		rc = paging_gen_msg(bts->paging_state, out_buf, gt, &is_empty);
 | 
			
		||||
 | 
			
		||||
	/* Check whether the block may be overwritten */
 | 
			
		||||
	if (!is_empty)
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	msg = bts_agch_dequeue(bts);
 | 
			
		||||
	if (!msg)
 | 
			
		||||
		return rc;
 | 
			
		||||
		if (!is_empty)
 | 
			
		||||
			return rc;
 | 
			
		||||
		/* fall-through */
 | 
			
		||||
	case CCCH_MSGT_AGCH:
 | 
			
		||||
		/* If fallen here and the AGCH queue is empty, return empty PCH message. */
 | 
			
		||||
		msg = bts_agch_dequeue(bts);
 | 
			
		||||
		if (!msg)
 | 
			
		||||
			return rc;
 | 
			
		||||
		/* Continue to return AGCH message. */
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rate_ctr_inc2(bts->ctrs, BTS_CTR_AGCH_SENT);
 | 
			
		||||
 | 
			
		||||
	/* Confirm sending of the AGCH message towards the PCU */
 | 
			
		||||
	msg_cb = (struct bts_agch_msg_cb *) msg->cb;
 | 
			
		||||
	if (msg_cb->confirm)
 | 
			
		||||
		pcu_tx_data_cnf(msg_cb->msg_id, PCU_IF_SAPI_AGCH_2);
 | 
			
		||||
 | 
			
		||||
	/* Copy AGCH message */
 | 
			
		||||
	memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg));
 | 
			
		||||
	rc = msgb_l3len(msg);
 | 
			
		||||
	msgb_free(msg);
 | 
			
		||||
 | 
			
		||||
	if (is_ag_res)
 | 
			
		||||
	if (ccch == CCCH_MSGT_AGCH)
 | 
			
		||||
		bts->agch_queue.agch_msgs++;
 | 
			
		||||
	else
 | 
			
		||||
		bts->agch_queue.pch_msgs++;
 | 
			
		||||
@@ -820,30 +814,35 @@ struct gsm_time *get_time(struct gsm_bts *bts)
 | 
			
		||||
	return &bts->gsm_time;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bts_supports_cm(const struct gsm_bts *bts,
 | 
			
		||||
		    const struct rsl_ie_chan_mode *cm)
 | 
			
		||||
bool bts_supports_cm_speech(const struct gsm_bts *bts,
 | 
			
		||||
			    const struct rsl_ie_chan_mode *cm)
 | 
			
		||||
{
 | 
			
		||||
	enum osmo_bts_features feature = _NUM_BTS_FEAT;
 | 
			
		||||
 | 
			
		||||
	switch (cm->spd_ind) {
 | 
			
		||||
	case RSL_CMOD_SPD_SIGN:
 | 
			
		||||
		/* We assume that signalling support is mandatory,
 | 
			
		||||
		 * there is no BTS_FEAT_* definition to check that. */
 | 
			
		||||
		return 1;
 | 
			
		||||
	case RSL_CMOD_SPD_SPEECH:
 | 
			
		||||
	/* Stage 1: check support for the requested channel type */
 | 
			
		||||
	switch (cm->chan_rt) {
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_GROUP_Bm:
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_GROUP_Lm:
 | 
			
		||||
		if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VGCS))
 | 
			
		||||
			return false;
 | 
			
		||||
		break;
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_BCAST_Bm:
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_BCAST_Lm:
 | 
			
		||||
		if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VBS))
 | 
			
		||||
			return false;
 | 
			
		||||
		break;
 | 
			
		||||
	case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm:
 | 
			
		||||
	case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm:
 | 
			
		||||
		if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
 | 
			
		||||
			return false;
 | 
			
		||||
		break;
 | 
			
		||||
	case RSL_CMOD_SPD_DATA:
 | 
			
		||||
	default:
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Before the requested pchan/cm combination can be checked, we need to
 | 
			
		||||
	 * convert it to a feature identifier we can check */
 | 
			
		||||
	/* Stage 2: check support for the requested codec */
 | 
			
		||||
	switch (cm->chan_rt) {
 | 
			
		||||
	case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm:
 | 
			
		||||
		if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
 | 
			
		||||
			return 0;
 | 
			
		||||
		/* fall-through */
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_GROUP_Bm:
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_BCAST_Bm:
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_Bm:
 | 
			
		||||
		switch (cm->chan_rate) {
 | 
			
		||||
		case RSL_CMOD_SP_GSM1:
 | 
			
		||||
@@ -857,14 +856,13 @@ int bts_supports_cm(const struct gsm_bts *bts,
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			/* Invalid speech codec type => Not supported! */
 | 
			
		||||
			return 0;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm:
 | 
			
		||||
		if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
 | 
			
		||||
			return 0;
 | 
			
		||||
		/* fall-through */
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_GROUP_Lm:
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_BCAST_Lm:
 | 
			
		||||
	case RSL_CMOD_CRT_TCH_Lm:
 | 
			
		||||
		switch (cm->chan_rate) {
 | 
			
		||||
		case RSL_CMOD_SP_GSM1:
 | 
			
		||||
@@ -875,7 +873,7 @@ int bts_supports_cm(const struct gsm_bts *bts,
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			/* Invalid speech codec type => Not supported! */
 | 
			
		||||
			return 0;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
@@ -883,14 +881,59 @@ int bts_supports_cm(const struct gsm_bts *bts,
 | 
			
		||||
		LOGP(DRSL, LOGL_ERROR,
 | 
			
		||||
		     "Unhandled RSL channel type=0x%02x/rate=0x%02x\n",
 | 
			
		||||
		     cm->chan_rt, cm->chan_rate);
 | 
			
		||||
		return 0;
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check if the feature is supported by this BTS */
 | 
			
		||||
	if (osmo_bts_has_feature(bts->features, feature))
 | 
			
		||||
		return 1;
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool bts_supports_cm_data(const struct gsm_bts *bts,
 | 
			
		||||
				 const struct rsl_ie_chan_mode *cm)
 | 
			
		||||
{
 | 
			
		||||
	switch (bts->variant) {
 | 
			
		||||
	case BTS_OSMO_TRX:
 | 
			
		||||
		switch (cm->chan_rate) {
 | 
			
		||||
		case RSL_CMOD_CSD_NT_14k5:
 | 
			
		||||
		case RSL_CMOD_CSD_T_14k4:
 | 
			
		||||
		case RSL_CMOD_CSD_NT_12k0:
 | 
			
		||||
		case RSL_CMOD_CSD_T_9k6:
 | 
			
		||||
			if (cm->chan_rt != RSL_CMOD_CRT_TCH_Bm)
 | 
			
		||||
				return false; /* invalid */
 | 
			
		||||
			/* fall-through */
 | 
			
		||||
		case RSL_CMOD_CSD_NT_6k0:
 | 
			
		||||
		case RSL_CMOD_CSD_T_4k8:
 | 
			
		||||
		case RSL_CMOD_CSD_T_2k4:
 | 
			
		||||
		case RSL_CMOD_CSD_T_1k2:
 | 
			
		||||
		case RSL_CMOD_CSD_T_600:
 | 
			
		||||
		case RSL_CMOD_CSD_T_1200_75:
 | 
			
		||||
			return true;
 | 
			
		||||
		default:
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool bts_supports_cm(const struct gsm_bts *bts,
 | 
			
		||||
		     const struct rsl_ie_chan_mode *cm)
 | 
			
		||||
{
 | 
			
		||||
	switch (cm->spd_ind) {
 | 
			
		||||
	case RSL_CMOD_SPD_SIGN:
 | 
			
		||||
		/* We assume that signalling support is mandatory,
 | 
			
		||||
		 * there is no BTS_FEAT_* definition to check that. */
 | 
			
		||||
		return true;
 | 
			
		||||
	case RSL_CMOD_SPD_SPEECH:
 | 
			
		||||
		return bts_supports_cm_speech(bts, cm);
 | 
			
		||||
	case RSL_CMOD_SPD_DATA:
 | 
			
		||||
		return bts_supports_cm_data(bts, cm);
 | 
			
		||||
	default:
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* return the gsm_lchan for the CBCH (if it exists at all) */
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -84,12 +84,45 @@ static int set_oml_alert(struct ctrl_cmd *cmd, void *data)
 | 
			
		||||
	return CTRL_CMD_REPLY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int verify_max_ber10k_rach(struct ctrl_cmd *cmd, const char *value, void *_data)
 | 
			
		||||
{
 | 
			
		||||
	int max_ber10k_rach = atoi(cmd->value);
 | 
			
		||||
 | 
			
		||||
	if (max_ber10k_rach < 0 || max_ber10k_rach > 10000) {
 | 
			
		||||
		cmd->reply = "Value is out of range";
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int get_max_ber10k_rach(struct ctrl_cmd *cmd, void *data)
 | 
			
		||||
{
 | 
			
		||||
	cmd->reply = talloc_asprintf(cmd, "%u", g_bts->max_ber10k_rach);
 | 
			
		||||
	if (!cmd->reply) {
 | 
			
		||||
		cmd->reply = "OOM";
 | 
			
		||||
		return CTRL_CMD_ERROR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CTRL_CMD_REPLY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int set_max_ber10k_rach(struct ctrl_cmd *cmd, void *data)
 | 
			
		||||
{
 | 
			
		||||
	g_bts->max_ber10k_rach = atoi(cmd->value);
 | 
			
		||||
	cmd->reply = "OK";
 | 
			
		||||
	return CTRL_CMD_REPLY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CTRL_CMD_DEFINE(max_ber10k_rach, "max-ber10k-rach");
 | 
			
		||||
 | 
			
		||||
int bts_ctrl_cmds_install(struct gsm_bts *bts)
 | 
			
		||||
{
 | 
			
		||||
	int rc = 0;
 | 
			
		||||
 | 
			
		||||
	rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_therm_att);
 | 
			
		||||
	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_oml_alert);
 | 
			
		||||
	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_max_ber10k_rach);
 | 
			
		||||
	g_bts = bts;
 | 
			
		||||
 | 
			
		||||
	return rc;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* BTS shutdown FSM */
 | 
			
		||||
 | 
			
		||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 | 
			
		||||
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -29,6 +29,7 @@
 | 
			
		||||
#include <osmo-bts/gsm_data.h>
 | 
			
		||||
#include <osmo-bts/bts_model.h>
 | 
			
		||||
#include <osmo-bts/bts.h>
 | 
			
		||||
#include <osmo-bts/bts_sm.h>
 | 
			
		||||
#include <osmo-bts/nm_common_fsm.h>
 | 
			
		||||
 | 
			
		||||
#define X(s) (1 << (s))
 | 
			
		||||
@@ -60,7 +61,7 @@ static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 | 
			
		||||
	switch(event) {
 | 
			
		||||
	case BTS_SHUTDOWN_EV_START:
 | 
			
		||||
		/* Firt announce to NM objects that we are starting a shutdown procedure: */
 | 
			
		||||
		osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SHUTDOWN_START, NULL);
 | 
			
		||||
		osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_START, NULL);
 | 
			
		||||
 | 
			
		||||
		count = count_trx_operational(bts);
 | 
			
		||||
		if (count) {
 | 
			
		||||
@@ -164,7 +165,7 @@ static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
 | 
			
		||||
 | 
			
		||||
	osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SHUTDOWN_FINISH, NULL);
 | 
			
		||||
	osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_FINISH, NULL);
 | 
			
		||||
 | 
			
		||||
	if (bts->shutdown_fi_exit_proc) {
 | 
			
		||||
		LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfully, exiting process\n");
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										95
									
								
								src/common/bts_sm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/common/bts_sm.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
/* BTS support code common to all supported BTS models */
 | 
			
		||||
 | 
			
		||||
/* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <osmocom/core/talloc.h>
 | 
			
		||||
#include <osmocom/core/linuxlist.h>
 | 
			
		||||
#include <osmocom/core/fsm.h>
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/bts_sm.h>
 | 
			
		||||
#include <osmo-bts/bts.h>
 | 
			
		||||
#include <osmo-bts/nm_common_fsm.h>
 | 
			
		||||
 | 
			
		||||
struct gsm_bts_sm *g_bts_sm;
 | 
			
		||||
 | 
			
		||||
static const uint8_t nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
 | 
			
		||||
 | 
			
		||||
struct gsm_bts *gsm_gprs_nse_get_bts(const struct gsm_gprs_nse *nse)
 | 
			
		||||
{
 | 
			
		||||
	return gsm_bts_num(g_bts_sm, nse->mo.obj_inst.bts_nr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int gsm_bts_sm_talloc_destructor(struct gsm_bts_sm *bts_sm)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts *bts;
 | 
			
		||||
 | 
			
		||||
	while ((bts = llist_first_entry_or_null(&bts_sm->bts_list, struct gsm_bts, list)))
 | 
			
		||||
		talloc_free(bts);
 | 
			
		||||
 | 
			
		||||
	if (bts_sm->mo.fi) {
 | 
			
		||||
		osmo_fsm_inst_free(bts_sm->mo.fi);
 | 
			
		||||
		bts_sm->mo.fi = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct gsm_bts_sm *gsm_bts_sm_alloc(void *talloc_ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts_sm *bts_sm = talloc_zero(talloc_ctx, struct gsm_bts_sm);
 | 
			
		||||
	struct gsm_gprs_nse *nse = &bts_sm->gprs.nse;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
	if (!bts_sm)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	talloc_set_destructor(bts_sm, gsm_bts_sm_talloc_destructor);
 | 
			
		||||
 | 
			
		||||
	INIT_LLIST_HEAD(&bts_sm->bts_list);
 | 
			
		||||
 | 
			
		||||
	/* NM SITE_MGR */
 | 
			
		||||
	bts_sm->mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts_sm, bts_sm,
 | 
			
		||||
					    LOGL_INFO, "bts_sm");
 | 
			
		||||
	gsm_mo_init(&bts_sm->mo, NULL, NM_OC_SITE_MANAGER,
 | 
			
		||||
		    0xff, 0xff, 0xff);
 | 
			
		||||
	oml_mo_state_init(&bts_sm->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
 | 
			
		||||
 | 
			
		||||
	/* NM GPRS NSE */
 | 
			
		||||
	nse->mo.fi = osmo_fsm_inst_alloc(&nm_gprs_nse_fsm, bts_sm, nse,
 | 
			
		||||
					 LOGL_INFO, "gprs_nse0");
 | 
			
		||||
	gsm_mo_init(&nse->mo, NULL, NM_OC_GPRS_NSE, 0, 0xff, 0xff);
 | 
			
		||||
	oml_mo_state_init(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
 | 
			
		||||
	memcpy(&nse->timer, nse_timer_default, sizeof(nse->timer));
 | 
			
		||||
 | 
			
		||||
	/* NM GPRS NSVCs */
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(nse->nsvc); i++) {
 | 
			
		||||
		struct gsm_gprs_nsvc *nsvc = &nse->nsvc[i];
 | 
			
		||||
		nsvc->nse = nse;
 | 
			
		||||
		nsvc->id = i;
 | 
			
		||||
		nsvc->mo.fi = osmo_fsm_inst_alloc(&nm_gprs_nsvc_fsm, bts_sm, nsvc,
 | 
			
		||||
						  LOGL_INFO, NULL);
 | 
			
		||||
		osmo_fsm_inst_update_id_f(nsvc->mo.fi, "gprs_nsvc%d-%d",
 | 
			
		||||
					  nse->mo.obj_inst.bts_nr, i);
 | 
			
		||||
		gsm_mo_init(&nsvc->mo, NULL, NM_OC_GPRS_NSVC, nse->mo.obj_inst.bts_nr, i, 0xff);
 | 
			
		||||
		oml_mo_state_init(&nsvc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return bts_sm;
 | 
			
		||||
}
 | 
			
		||||
@@ -74,12 +74,17 @@ static void gsm_bts_trx_init_ts(struct gsm_bts_trx *trx)
 | 
			
		||||
		ts->trx = trx;
 | 
			
		||||
		ts->nr = tn;
 | 
			
		||||
 | 
			
		||||
		ts->tsc_oml_configured = false;
 | 
			
		||||
		ts->tsc_rsl_configured = false;
 | 
			
		||||
		ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff;
 | 
			
		||||
 | 
			
		||||
		ts->mo.fi = osmo_fsm_inst_alloc(&nm_chan_fsm, trx, ts,
 | 
			
		||||
						LOGL_INFO, NULL);
 | 
			
		||||
		osmo_fsm_inst_update_id_f(ts->mo.fi, "%s-ts%u",
 | 
			
		||||
					  trx->bb_transc.mo.fi->id, ts->nr);
 | 
			
		||||
		gsm_mo_init(&ts->mo, trx->bts, NM_OC_CHANNEL,
 | 
			
		||||
			    trx->bts->nr, trx->nr, ts->nr);
 | 
			
		||||
		oml_mo_state_init(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
 | 
			
		||||
 | 
			
		||||
		gsm_bts_trx_ts_init_lchan(ts);
 | 
			
		||||
	}
 | 
			
		||||
@@ -99,6 +104,10 @@ void gsm_bts_trx_init_shadow_ts(struct gsm_bts_trx *trx)
 | 
			
		||||
		ts->trx = trx;
 | 
			
		||||
		ts->nr = tn;
 | 
			
		||||
 | 
			
		||||
		ts->tsc_oml_configured = false;
 | 
			
		||||
		ts->tsc_rsl_configured = false;
 | 
			
		||||
		ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff;
 | 
			
		||||
 | 
			
		||||
		/* Link both primary and shadow */
 | 
			
		||||
		trx->ts[tn].vamos.peer = ts;
 | 
			
		||||
		ts->vamos.peer = &trx->ts[tn];
 | 
			
		||||
@@ -148,14 +157,14 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
 | 
			
		||||
	trx->mo.fi = osmo_fsm_inst_alloc(&nm_rcarrier_fsm, trx, trx,
 | 
			
		||||
						  LOGL_INFO, NULL);
 | 
			
		||||
	osmo_fsm_inst_update_id_f(trx->mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
 | 
			
		||||
	gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER,
 | 
			
		||||
		    bts->nr, trx->nr, 0xff);
 | 
			
		||||
	gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER, bts->nr, trx->nr, 0xff);
 | 
			
		||||
	oml_mo_state_init(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
 | 
			
		||||
 | 
			
		||||
	trx->bb_transc.mo.fi = osmo_fsm_inst_alloc(&nm_bb_transc_fsm, trx, &trx->bb_transc,
 | 
			
		||||
						  LOGL_INFO, NULL);
 | 
			
		||||
	osmo_fsm_inst_update_id_f(trx->bb_transc.mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
 | 
			
		||||
	gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC,
 | 
			
		||||
		    bts->nr, trx->nr, 0xff);
 | 
			
		||||
	gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC, bts->nr, trx->nr, 0xff);
 | 
			
		||||
	oml_mo_state_init(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
 | 
			
		||||
 | 
			
		||||
	gsm_bts_trx_init_ts(trx);
 | 
			
		||||
 | 
			
		||||
@@ -227,10 +236,13 @@ int trx_link_estab(struct gsm_bts_trx *trx)
 | 
			
		||||
	osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_RSL_UP, NULL);
 | 
			
		||||
	osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_RSL_UP, NULL);
 | 
			
		||||
 | 
			
		||||
	if ((rc = rsl_tx_rf_res(trx)) < 0)
 | 
			
		||||
		oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
 | 
			
		||||
					 "Failed to establish RSL link (%d)", rc);
 | 
			
		||||
 | 
			
		||||
	if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED ||
 | 
			
		||||
	    trx->bb_transc.mo.nm_state.operational == NM_OPSTATE_ENABLED) {
 | 
			
		||||
		rc = rsl_tx_rf_res(trx);
 | 
			
		||||
		if (rc < 0)
 | 
			
		||||
			oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
 | 
			
		||||
						 "Failed to establish RSL link (%d)", rc);
 | 
			
		||||
	}
 | 
			
		||||
	if (trx == trx->bts->c0)
 | 
			
		||||
		load_timer_start(trx->bts);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -139,12 +139,8 @@ static int get_smscb_block(struct bts_smscb_state *bts_ss, uint8_t *out, uint8_t
 | 
			
		||||
		block_type->seq_nr = block_nr;
 | 
			
		||||
 | 
			
		||||
	/* determine if this is the last block */
 | 
			
		||||
	if (block_nr + 1 == msg->num_segs)
 | 
			
		||||
		block_type->lb = 1;
 | 
			
		||||
	else
 | 
			
		||||
		block_type->lb = 0;
 | 
			
		||||
 | 
			
		||||
	if (block_nr == 4) {
 | 
			
		||||
	block_type->lb = (block_nr + 1 == msg->num_segs);
 | 
			
		||||
	if (block_type->lb) {
 | 
			
		||||
		if (msg != bts_ss->default_msg) {
 | 
			
		||||
			DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n",
 | 
			
		||||
				 chan_name, msg);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										228
									
								
								src/common/csd_rlp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								src/common/csd_rlp.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,228 @@
 | 
			
		||||
/* This module has been split from l1sap.c; original header comments preserved:
 | 
			
		||||
 *
 | 
			
		||||
 * (C) 2011 by Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
 * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocom/core/bits.h>
 | 
			
		||||
#include <osmocom/core/msgb.h>
 | 
			
		||||
#include <osmocom/gsm/l1sap.h>
 | 
			
		||||
#include <osmocom/gsm/gsm_utils.h>
 | 
			
		||||
#include <osmocom/gsm/rsl.h>
 | 
			
		||||
#include <osmocom/gsm/rlp.h>
 | 
			
		||||
#include <osmocom/gsm/rtp_extensions.h>
 | 
			
		||||
#include <osmocom/core/gsmtap.h>
 | 
			
		||||
#include <osmocom/core/gsmtap_util.h>
 | 
			
		||||
#include <osmocom/core/utils.h>
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/logging.h>
 | 
			
		||||
#include <osmo-bts/gsm_data.h>
 | 
			
		||||
#include <osmo-bts/lchan.h>
 | 
			
		||||
#include <osmo-bts/bts.h>
 | 
			
		||||
#include <osmo-bts/csd_rlp.h>
 | 
			
		||||
 | 
			
		||||
/* In the case of TCH/F4.8 NT, each 240-bit RLP frame is split between
 | 
			
		||||
 * two channel-coding blocks of 120 bits each.  We need to know which
 | 
			
		||||
 * frame numbers correspond to which half: in the UL-to-RTP path we have
 | 
			
		||||
 * to set bit E2 based on the TDMA frame number at which we received the
 | 
			
		||||
 * block in question, and in the DL direction we have to transmit the
 | 
			
		||||
 * right half at the right time.
 | 
			
		||||
 *
 | 
			
		||||
 * See GSM 05.03 section 3.4.1 and the mapping tables of GSM 05.02;
 | 
			
		||||
 * having "e2_map" in the array name shall serve as a mnemonic as to
 | 
			
		||||
 * the sense of this array: 0 means 1st half and 1 means 2nd half,
 | 
			
		||||
 * exactly as the value of bit E2 per TS 48.020 section 15.1.
 | 
			
		||||
 */
 | 
			
		||||
const uint8_t csd_tchf48_nt_e2_map[26] = {
 | 
			
		||||
	[4]  = 1,	/* B1 position */
 | 
			
		||||
	[13] = 1,	/* B3 position */
 | 
			
		||||
	[21] = 1,	/* B5 position */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* This function resets (clears) the state of the DL alignment buffer.
 | 
			
		||||
 * It needs to be called when we encounter a gap (packet loss, invalid
 | 
			
		||||
 * packets, etc) in our RTP input stream. */
 | 
			
		||||
void ntcsd_dl_reset(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	lchan->tch.csd.rlpdl_fill_level = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function is to be called with the decoded content of a single
 | 
			
		||||
 * incoming RTP packet (data and alignment bits) for TCH/[FH]4.8 NT. */
 | 
			
		||||
void ntcsd_dl_input_48(struct gsm_lchan *lchan, const ubit_t *data_bits,
 | 
			
		||||
			uint8_t align_bits)
 | 
			
		||||
{
 | 
			
		||||
	memmove(lchan->tch.csd.rlpdl_data_bits,
 | 
			
		||||
		lchan->tch.csd.rlpdl_data_bits + 60 * 2, 60 * 5);
 | 
			
		||||
	memcpy(lchan->tch.csd.rlpdl_data_bits + 60 * 5, data_bits, 60 * 2);
 | 
			
		||||
	lchan->tch.csd.rlpdl_align_bits <<= 4;
 | 
			
		||||
	lchan->tch.csd.rlpdl_align_bits |= (align_bits & 0xF);
 | 
			
		||||
	lchan->tch.csd.rlpdl_fill_level += 2;
 | 
			
		||||
	if (lchan->tch.csd.rlpdl_fill_level > 7)
 | 
			
		||||
		lchan->tch.csd.rlpdl_fill_level = 7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function is to be called with the decoded content of a single
 | 
			
		||||
 * incoming RTP packet (data and alignment bits) for TCH/F9.6 NT. */
 | 
			
		||||
void ntcsd_dl_input_96(struct gsm_lchan *lchan, const ubit_t *data_bits,
 | 
			
		||||
			uint8_t align_bits)
 | 
			
		||||
{
 | 
			
		||||
	memmove(lchan->tch.csd.rlpdl_data_bits,
 | 
			
		||||
		lchan->tch.csd.rlpdl_data_bits + 60 * 4, 60 * 3);
 | 
			
		||||
	memcpy(lchan->tch.csd.rlpdl_data_bits + 60 * 3, data_bits, 60 * 4);
 | 
			
		||||
	lchan->tch.csd.rlpdl_align_bits <<= 8;
 | 
			
		||||
	lchan->tch.csd.rlpdl_align_bits |= (align_bits & 0xFF);
 | 
			
		||||
	lchan->tch.csd.rlpdl_fill_level += 4;
 | 
			
		||||
	if (lchan->tch.csd.rlpdl_fill_level > 7)
 | 
			
		||||
		lchan->tch.csd.rlpdl_fill_level = 7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function is to be called to obtain a complete RLP frame for
 | 
			
		||||
 * downlink transmission.  It will provide either a properly aligned
 | 
			
		||||
 * frame (return value true) or a filler (return value false). */
 | 
			
		||||
bool ntcsd_dl_output(struct gsm_lchan *lchan, ubit_t *rlp_frame_out)
 | 
			
		||||
{
 | 
			
		||||
	if (lchan->tch.csd.rlpdl_fill_level < 4)
 | 
			
		||||
		goto no_frame_out;
 | 
			
		||||
	if (((lchan->tch.csd.rlpdl_align_bits >> 0) & 0xFF) == NTCSD_ALIGNED_EBITS) {
 | 
			
		||||
		memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits + 60 * 3,
 | 
			
		||||
			60 * 4);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	if (lchan->tch.csd.rlpdl_fill_level < 5)
 | 
			
		||||
		goto no_frame_out;
 | 
			
		||||
	if (((lchan->tch.csd.rlpdl_align_bits >> 2) & 0xFF) == NTCSD_ALIGNED_EBITS) {
 | 
			
		||||
		memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits + 60 * 2,
 | 
			
		||||
			60 * 4);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	if (lchan->tch.csd.rlpdl_fill_level < 6)
 | 
			
		||||
		goto no_frame_out;
 | 
			
		||||
	if (((lchan->tch.csd.rlpdl_align_bits >> 4) & 0xFF) == NTCSD_ALIGNED_EBITS) {
 | 
			
		||||
		memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits + 60 * 1,
 | 
			
		||||
			60 * 4);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	if (lchan->tch.csd.rlpdl_fill_level < 7)
 | 
			
		||||
		goto no_frame_out;
 | 
			
		||||
	if (((lchan->tch.csd.rlpdl_align_bits >> 6) & 0xFF) == NTCSD_ALIGNED_EBITS) {
 | 
			
		||||
		memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits, 60 * 4);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
no_frame_out:
 | 
			
		||||
	/* TS 44.021 section 12.1 says that a missing/unavailable 240-bit
 | 
			
		||||
	 * RLP frame is to be filled with 0 bits, unlike ones-fill
 | 
			
		||||
	 * used everywhere else in the world of V.110 and CSD. */
 | 
			
		||||
	memset(rlp_frame_out, 0, 60 * 4);
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* process one MAC block of unpacked bits of a non-transparent CSD channel */
 | 
			
		||||
void gsmtap_csd_rlp_process(struct gsm_lchan *lchan, bool is_uplink,
 | 
			
		||||
			    const struct ph_tch_param *tch_ind,
 | 
			
		||||
			    const ubit_t *data, unsigned int data_len)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts_trx *trx = lchan->ts->trx;
 | 
			
		||||
	struct gsmtap_inst *inst = trx->bts->gsmtap.inst;
 | 
			
		||||
	pbit_t *rlp_buf;
 | 
			
		||||
	uint16_t arfcn;
 | 
			
		||||
	int byte_len;
 | 
			
		||||
 | 
			
		||||
	if (!inst || !trx->bts->gsmtap.rlp)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (lchan->csd_mode != LCHAN_CSD_M_NT)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (is_uplink)
 | 
			
		||||
		rlp_buf = lchan->tch.csd.rlp_buf_ul;
 | 
			
		||||
	else
 | 
			
		||||
		rlp_buf = lchan->tch.csd.rlp_buf_dl;
 | 
			
		||||
 | 
			
		||||
	/* TCH/F 9.6: 4x60bit block => 240bit RLP frame
 | 
			
		||||
	 * TCH/F 4.8: 2x 2x60bit blocks starting at B0/B2/B4 => 240bit RLP frame
 | 
			
		||||
	 * TCH/H 4.8: 4x60bit block => 240bit RLP frame
 | 
			
		||||
	 * TCH/F 2.4: 2x36bit blocks => transparent only
 | 
			
		||||
	 * TCH/H 2.4: 4x36bit blocks => transparent only
 | 
			
		||||
	 * TCH/F 14.4: 2x 290 bit block (starting with M1=0) => 576-bit RLP frame
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	if (lchan->type == GSM_LCHAN_TCH_F &&
 | 
			
		||||
	    lchan->tch_mode == GSM48_CMODE_DATA_6k0 && is_uplink) {
 | 
			
		||||
		/* In this mode we have 120-bit MAC blocks; two of them need
 | 
			
		||||
		 * to be concatenated to render a 240-bit RLP frame. The first
 | 
			
		||||
		 * block is present in B0/B2/B4, and we have to use FN to
 | 
			
		||||
		 * detect this position.
 | 
			
		||||
		 * This code path is only for UL: in the case of DL,
 | 
			
		||||
		 * alignment logic elsewhere in the code will present us
 | 
			
		||||
		 * with a fully assembled RLP frame. */
 | 
			
		||||
		OSMO_ASSERT(data_len == 120);
 | 
			
		||||
		if (csd_tchf48_nt_e2_map[tch_ind->fn % 26] == 0) {
 | 
			
		||||
			osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		osmo_ubit2pbit_ext(rlp_buf, 120, data, 0, data_len, 1);
 | 
			
		||||
		byte_len = 240/8;
 | 
			
		||||
	} else if (lchan->type == GSM_LCHAN_TCH_F && lchan->tch_mode == GSM48_CMODE_DATA_14k5) {
 | 
			
		||||
		/* in this mode we have 290bit MAC blocks containing M1, M2 and 288 data bits;
 | 
			
		||||
		 * two of them need to be concatenated to render a
 | 
			
		||||
		 * 576-bit RLP frame. The start of a RLP frame is
 | 
			
		||||
		 * denoted by a block with M1-bit set to 0. */
 | 
			
		||||
		OSMO_ASSERT(data_len == 290);
 | 
			
		||||
		ubit_t m1 = data[0];
 | 
			
		||||
		if (m1 == 0) {
 | 
			
		||||
			osmo_ubit2pbit_ext(rlp_buf, 0, data, 2, data_len, 1);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		osmo_ubit2pbit_ext(rlp_buf, 288, data, 2, data_len, 1);
 | 
			
		||||
		byte_len = 576/8;
 | 
			
		||||
	} else {
 | 
			
		||||
		byte_len = osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (trx->bts->gsmtap.rlp_skip_null) {
 | 
			
		||||
		struct osmo_rlp_frame_decoded rlpf;
 | 
			
		||||
		int rc = osmo_rlp_decode(&rlpf, 0, rlp_buf, byte_len);
 | 
			
		||||
		if (rc == 0 && rlpf.ftype == OSMO_RLP_FT_U && rlpf.u_ftype == OSMO_RLP_U_FT_NULL)
 | 
			
		||||
			return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	arfcn = trx->arfcn;
 | 
			
		||||
	if (is_uplink)
 | 
			
		||||
		arfcn |= GSMTAP_ARFCN_F_UPLINK;
 | 
			
		||||
 | 
			
		||||
	gsmtap_send_ex(inst, GSMTAP_TYPE_GSM_RLP, arfcn, lchan->ts->nr,
 | 
			
		||||
		       lchan->type == GSM_LCHAN_TCH_H ? GSMTAP_CHANNEL_VOICE_H : GSMTAP_CHANNEL_VOICE_F,
 | 
			
		||||
		       lchan->nr, tch_ind->fn, tch_ind->rssi, 0, rlp_buf, byte_len);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* wrapper for downlink path */
 | 
			
		||||
void gsmtap_csd_rlp_dl(struct gsm_lchan *lchan, uint32_t fn,
 | 
			
		||||
			const ubit_t *data, unsigned int data_len)
 | 
			
		||||
{
 | 
			
		||||
	/* 'fake' tch_ind containing all-zero so gsmtap code can be shared
 | 
			
		||||
	 * between UL and DL */
 | 
			
		||||
	const struct ph_tch_param fake_tch_ind = { .fn = fn };
 | 
			
		||||
	gsmtap_csd_rlp_process(lchan, false, &fake_tch_ind, data, data_len);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										242
									
								
								src/common/csd_v110.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								src/common/csd_v110.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,242 @@
 | 
			
		||||
/*
 | 
			
		||||
 * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * Author: Vadim Yanitskiy <vyanitskiy@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocom/core/bits.h>
 | 
			
		||||
#include <osmocom/core/utils.h>
 | 
			
		||||
#include <osmocom/gsm/gsm44021.h>
 | 
			
		||||
#include <osmocom/gsm/gsm_utils.h>
 | 
			
		||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
 | 
			
		||||
#include <osmocom/isdn/v110.h>
 | 
			
		||||
#include <osmocom/trau/csd_ra2.h>
 | 
			
		||||
#include <osmocom/trau/csd_raa_prime.h>
 | 
			
		||||
 | 
			
		||||
#include <osmo-bts/csd_v110.h>
 | 
			
		||||
#include <osmo-bts/lchan.h>
 | 
			
		||||
 | 
			
		||||
/* key is enum gsm48_chan_mode, so assuming a value in range 0..255 */
 | 
			
		||||
const struct csd_v110_lchan_desc csd_v110_lchan_desc[256] = {
 | 
			
		||||
	[GSM48_CMODE_DATA_14k5] = {
 | 
			
		||||
		/* TCH/F14.4: 8 * 36 + 2 bits every 20 ms (14.5 kbit/s) */
 | 
			
		||||
		.num_frames = 8,
 | 
			
		||||
		.num_frame_bits = 36,	/* D-bits */
 | 
			
		||||
		.num_other_bits = 2,	/* M-bits */
 | 
			
		||||
		.ra2_ir = 16,
 | 
			
		||||
	},
 | 
			
		||||
	[GSM48_CMODE_DATA_12k0] = {
 | 
			
		||||
		/* TCH/F9.6: 4 * 60 bits every 20 ms (12.0 kbit/s) */
 | 
			
		||||
		.num_frames = 4,
 | 
			
		||||
		.num_frame_bits = 60,
 | 
			
		||||
		.ra2_ir = 16,
 | 
			
		||||
	},
 | 
			
		||||
	[GSM48_CMODE_DATA_6k0] = {
 | 
			
		||||
		/* TCH/[FH]4.8: 2 * 60 bits every 20 ms (6.0 kbit/s) */
 | 
			
		||||
		.num_frames = 2,
 | 
			
		||||
		.num_frame_bits = 60,
 | 
			
		||||
		.ra2_ir = 8,
 | 
			
		||||
	},
 | 
			
		||||
	[GSM48_CMODE_DATA_3k6] = {
 | 
			
		||||
		/* TCH/[FH]2.4: 2 * 36 bits every 20 ms (3.6 kbit/s) */
 | 
			
		||||
		.num_frames = 2,
 | 
			
		||||
		.num_frame_bits = 36,
 | 
			
		||||
		.ra2_ir = 8,
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* 3GPP TS 44.021, Figure 4: Coding of data rates (E1/E2/E3 bits) */
 | 
			
		||||
static const uint8_t e1e2e3_map[_LCHAN_CSD_M_NUM][3] = {
 | 
			
		||||
	[LCHAN_CSD_M_T_600]	= { 1, 0, 0 },
 | 
			
		||||
	[LCHAN_CSD_M_T_1200]	= { 0, 1, 0 },
 | 
			
		||||
	[LCHAN_CSD_M_T_2400]	= { 1, 1, 0 },
 | 
			
		||||
	[LCHAN_CSD_M_T_4800]	= { 0, 1, 1 },
 | 
			
		||||
	[LCHAN_CSD_M_T_9600]	= { 0, 1, 1 },
 | 
			
		||||
#if 0
 | 
			
		||||
	[LCHAN_CSD_M_T_19200]	= { 0, 1, 1 },
 | 
			
		||||
	[LCHAN_CSD_M_T_38400]	= { 0, 1, 1 },
 | 
			
		||||
	[LCHAN_CSD_M_T_14400]	= { 1, 0, 1 },
 | 
			
		||||
	[LCHAN_CSD_M_T_28800]	= { 1, 0, 1 },
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
 | 
			
		||||
			const uint8_t *data, size_t data_len,
 | 
			
		||||
			uint8_t nt48_half_num)
 | 
			
		||||
{
 | 
			
		||||
	const struct csd_v110_lchan_desc *desc;
 | 
			
		||||
	ubit_t ra_bits[80 * 4];
 | 
			
		||||
 | 
			
		||||
	OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
 | 
			
		||||
	desc = &csd_v110_lchan_desc[lchan->tch_mode];
 | 
			
		||||
	if (OSMO_UNLIKELY(desc->num_frames == 0))
 | 
			
		||||
		return -ENOTSUP;
 | 
			
		||||
 | 
			
		||||
	/* TCH/F14.4 is special: RAA' function is employed */
 | 
			
		||||
	if (lchan->tch_mode == GSM48_CMODE_DATA_14k5) {
 | 
			
		||||
		/* 3GPP TS 44.021, section 10.3 "TCH/F14.4 channel coding"
 | 
			
		||||
		 * 3GPP TS 48.020, chapter 11 "THE RAA' FUNCTION" */
 | 
			
		||||
		const ubit_t *m_bits = &data[0]; /* M-bits */
 | 
			
		||||
		const ubit_t *d_bits = &data[2]; /* D-bits */
 | 
			
		||||
		ubit_t c4, c5;
 | 
			
		||||
 | 
			
		||||
		/* 3GPP TS 48.020, Table 3
 | 
			
		||||
		 * | C4 | Date Rate |
 | 
			
		||||
		 * | =1 | 14,4 kbit/s |
 | 
			
		||||
		 * | =0 | 14.4 kbit/s idle (IWF to BSS only) | */
 | 
			
		||||
		c4 = 1;
 | 
			
		||||
		/* 3GPP TS 48.020, Table 4
 | 
			
		||||
		 * | C5 | BSS to IWF FT | IWF to BSS UFE |
 | 
			
		||||
		 * | =1 | idle | framing error |
 | 
			
		||||
		 * | =0 | data | no framing error | */
 | 
			
		||||
		c5 = 0;
 | 
			
		||||
 | 
			
		||||
		/* Unless there is a bug, it's highly unlikely */
 | 
			
		||||
		OSMO_ASSERT(data_len == CSD_V110_NUM_BITS(desc));
 | 
			
		||||
 | 
			
		||||
		osmo_csd144_to_atrau_bits(&ra_bits[0], m_bits, d_bits, c4, c5);
 | 
			
		||||
		goto ra1_ra2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* handle empty/incomplete Uplink frames gracefully */
 | 
			
		||||
	if (OSMO_UNLIKELY(data_len < CSD_V110_NUM_BITS(desc))) {
 | 
			
		||||
		/* encode N idle frames as per 3GPP TS 44.021, section 8.1.6 */
 | 
			
		||||
		memset(&ra_bits[0], 0x01, sizeof(ra_bits));
 | 
			
		||||
		for (unsigned int i = 0; i < desc->num_frames; i++)
 | 
			
		||||
			memset(&ra_bits[i * 80], 0x00, 8); /* alignment pattern */
 | 
			
		||||
		goto ra1_ra2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* RA1'/RA1: convert from radio rate to an intermediate data rate */
 | 
			
		||||
	for (unsigned int i = 0; i < desc->num_frames; i++) {
 | 
			
		||||
		struct osmo_v110_decoded_frame df;
 | 
			
		||||
 | 
			
		||||
		/* convert a V.110 36-/60-bit frame to a V.110 80-bit frame */
 | 
			
		||||
		if (desc->num_frame_bits == 60)
 | 
			
		||||
			osmo_csd_12k_6k_decode_frame(&df, &data[i * 60], 60);
 | 
			
		||||
		else /* desc->num_frame_bits == 36 */
 | 
			
		||||
			osmo_csd_3k6_decode_frame(&df, &data[i * 36], 36);
 | 
			
		||||
 | 
			
		||||
		/* E1 .. E3 must set by out-of-band knowledge */
 | 
			
		||||
		if (lchan->csd_mode == LCHAN_CSD_M_NT) {
 | 
			
		||||
			/* non-transparent: as per 3GPP TS 48.020, Table 7 */
 | 
			
		||||
			/* E1: as per 15.1.2, shall be set to 0 (for BSS-MSC) */
 | 
			
		||||
			df.e_bits[0] = 0;
 | 
			
		||||
			/* E2: 0 for Q1/Q2, 1 for Q3/Q4 */
 | 
			
		||||
			if (desc->num_frames == 4)
 | 
			
		||||
				df.e_bits[1] = (i >> 1) & 0x01;
 | 
			
		||||
			else
 | 
			
		||||
				df.e_bits[1] = nt48_half_num;
 | 
			
		||||
			/* E3: 0 for Q1/Q3, 1 for Q2/Q4 */
 | 
			
		||||
			df.e_bits[2] = (i >> 0) & 0x01;
 | 
			
		||||
		} else {
 | 
			
		||||
			/* transparent: as per 3GPP TS 44.021, Figure 4 */
 | 
			
		||||
			df.e_bits[0] = e1e2e3_map[lchan->csd_mode][0]; /* E1 */
 | 
			
		||||
			df.e_bits[1] = e1e2e3_map[lchan->csd_mode][1]; /* E2 */
 | 
			
		||||
			df.e_bits[2] = e1e2e3_map[lchan->csd_mode][2]; /* E3 */
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		osmo_v110_encode_frame(&ra_bits[i * 80], 80, &df);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
ra1_ra2:
 | 
			
		||||
	/* RA1/RA2: convert from an intermediate rate to 64 kbit/s */
 | 
			
		||||
	if (desc->ra2_ir == 16)
 | 
			
		||||
		osmo_csd_ra2_16k_pack(&rtp[0], &ra_bits[0], RFC4040_RTP_PLEN);
 | 
			
		||||
	else /* desc->ra2_ir == 8 */
 | 
			
		||||
		osmo_csd_ra2_8k_pack(&rtp[0], &ra_bits[0], RFC4040_RTP_PLEN);
 | 
			
		||||
 | 
			
		||||
	return RFC4040_RTP_PLEN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool check_v110_align(const ubit_t *ra_bits)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	ubit_t bit0 = 0, bit1 = 1;
 | 
			
		||||
 | 
			
		||||
	/* The weird code structure is for performance optimization,
 | 
			
		||||
	 * to avoid conditionals inside loops. */
 | 
			
		||||
	for (i = 0; i < 8; i++)
 | 
			
		||||
		bit0 |= ra_bits[i];
 | 
			
		||||
	for (i = 1; i < 10; i++)
 | 
			
		||||
		bit1 &= ra_bits[i * 8];
 | 
			
		||||
	return (bit0 == 0) && (bit1 == 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
 | 
			
		||||
			uint8_t *align_bits, const uint8_t *rtp, size_t rtp_len)
 | 
			
		||||
{
 | 
			
		||||
	const struct csd_v110_lchan_desc *desc;
 | 
			
		||||
	ubit_t ra_bits[80 * 4];
 | 
			
		||||
	uint8_t align_accum = 0;
 | 
			
		||||
 | 
			
		||||
	OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
 | 
			
		||||
	desc = &csd_v110_lchan_desc[lchan->tch_mode];
 | 
			
		||||
	if (OSMO_UNLIKELY(desc->num_frames == 0))
 | 
			
		||||
		return -ENOTSUP;
 | 
			
		||||
 | 
			
		||||
	if (OSMO_UNLIKELY(rtp_len != RFC4040_RTP_PLEN))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	/* RA1/RA2: convert from 64 kbit/s to an intermediate rate */
 | 
			
		||||
	if (desc->ra2_ir == 16)
 | 
			
		||||
		osmo_csd_ra2_16k_unpack(&ra_bits[0], &rtp[0], RFC4040_RTP_PLEN);
 | 
			
		||||
	else /* desc->ra2_ir == 8 */
 | 
			
		||||
		osmo_csd_ra2_8k_unpack(&ra_bits[0], &rtp[0], RFC4040_RTP_PLEN);
 | 
			
		||||
 | 
			
		||||
	/* TCH/F14.4 is special: RAA' function is employed */
 | 
			
		||||
	if (lchan->tch_mode == GSM48_CMODE_DATA_14k5) {
 | 
			
		||||
		/* 3GPP TS 44.021, section 10.3 "TCH/F14.4 channel coding"
 | 
			
		||||
		 * 3GPP TS 48.020, chapter 11 "THE RAA' FUNCTION" */
 | 
			
		||||
		ubit_t *m_bits = &data[0]; /* M-bits */
 | 
			
		||||
		ubit_t *d_bits = &data[2]; /* D-bits */
 | 
			
		||||
		int rc;
 | 
			
		||||
 | 
			
		||||
		rc = osmo_csd144_from_atrau_bits(m_bits, d_bits, NULL, NULL, &ra_bits[0]);
 | 
			
		||||
		return rc == 0 ? CSD_V110_NUM_BITS(desc) : rc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* RA1'/RA1: convert from an intermediate rate to radio rate */
 | 
			
		||||
	for (unsigned int i = 0; i < desc->num_frames; i++) {
 | 
			
		||||
		struct osmo_v110_decoded_frame df;
 | 
			
		||||
 | 
			
		||||
		/* We require our RTP input to consist of aligned V.110
 | 
			
		||||
		 * frames.  If we get misaligned input, let's catch it
 | 
			
		||||
		 * explicitly, rather than send garbage downstream. */
 | 
			
		||||
		if (!check_v110_align(&ra_bits[i * 80]))
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		/* convert a V.110 80-bit frame to a V.110 36-/60-bit frame */
 | 
			
		||||
		osmo_v110_decode_frame(&df, &ra_bits[i * 80], 80);
 | 
			
		||||
		if (desc->num_frame_bits == 60)
 | 
			
		||||
			osmo_csd_12k_6k_encode_frame(&data[i * 60], 60, &df);
 | 
			
		||||
		else /* desc->num_frame_bits == 36 */
 | 
			
		||||
			osmo_csd_3k6_encode_frame(&data[i * 36], 36, &df);
 | 
			
		||||
		/* save bits E2 & E3 that may be needed for RLP alignment */
 | 
			
		||||
		align_accum <<= 2;
 | 
			
		||||
		align_accum |= df.e_bits[1] << 1;
 | 
			
		||||
		align_accum |= df.e_bits[2] << 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (align_bits)
 | 
			
		||||
		*align_bits = align_accum;
 | 
			
		||||
	return CSD_V110_NUM_BITS(desc);
 | 
			
		||||
}
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 
 | 
			
		||||
@@ -306,6 +306,29 @@ bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Apply ts->tsc based on what was configured coming from different sources.
 | 
			
		||||
 * Priorities (preferred first, overrides ones afterward):
 | 
			
		||||
 * 1- RSL OSMO_TSC IE
 | 
			
		||||
 * 2- OML SetChannelAttr TSC IE
 | 
			
		||||
 * 3- OML SetBtsAttr BSIC IE
 | 
			
		||||
 */
 | 
			
		||||
void gsm_ts_apply_configured_tsc(struct gsm_bts_trx_ts *ts)
 | 
			
		||||
{
 | 
			
		||||
	if (ts->tsc_rsl_configured) {
 | 
			
		||||
		ts->tsc = ts->tsc_rsl;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (ts->tsc_oml_configured) {
 | 
			
		||||
		ts->tsc = ts->tsc_oml;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (ts->trx->bts->bsic_configured) {
 | 
			
		||||
		ts->tsc = BTS_TSC(ts->trx->bts);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	ts->tsc = 0xff; /* invalid value */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void gsm_ts_release(struct gsm_bts_trx_ts *ts)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int ln;
 | 
			
		||||
@@ -318,4 +341,8 @@ void gsm_ts_release(struct gsm_bts_trx_ts *ts)
 | 
			
		||||
	/* Make sure pchan_is is reset, since PCU act_req to release it will be
 | 
			
		||||
	 * ignored as the lchan will already be released. */
 | 
			
		||||
	ts->dyn.pchan_is = ts->dyn.pchan_want = GSM_PCHAN_NONE;
 | 
			
		||||
 | 
			
		||||
	ts->tsc_oml_configured = false;
 | 
			
		||||
	ts->tsc_rsl_configured = false;
 | 
			
		||||
	ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1370
									
								
								src/common/l1sap.c
									
									
									
									
									
								
							
							
						
						
									
										1370
									
								
								src/common/l1sap.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -33,6 +33,7 @@
 | 
			
		||||
#include <osmo-bts/handover.h>
 | 
			
		||||
#include <osmo-bts/l1sap.h>
 | 
			
		||||
#include <osmo-bts/bts_model.h>
 | 
			
		||||
#include <osmo-bts/asci.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
static const struct value_string lchan_s_names[] = {
 | 
			
		||||
@@ -55,42 +56,55 @@ const struct value_string lchan_ciph_state_names[] = {
 | 
			
		||||
	{ 0, NULL }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const struct value_string lchan_csd_mode_descs[] = {
 | 
			
		||||
	{ LCHAN_CSD_M_NT,		"non-transparent" },
 | 
			
		||||
	{ LCHAN_CSD_M_T_1200_75,	"transparent @ 1200/75 bps" },
 | 
			
		||||
	{ LCHAN_CSD_M_T_600,		"transparent @ 600 bps" },
 | 
			
		||||
	{ LCHAN_CSD_M_T_1200,		"transparent @ 1200 bps" },
 | 
			
		||||
	{ LCHAN_CSD_M_T_2400,		"transparent @ 2400 bps" },
 | 
			
		||||
	{ LCHAN_CSD_M_T_4800,		"transparent @ 4800 bps" },
 | 
			
		||||
	{ LCHAN_CSD_M_T_9600,		"transparent @ 9600 bps" },
 | 
			
		||||
	{ LCHAN_CSD_M_T_14400,		"transparent @ 14400 bps" },
 | 
			
		||||
	{ LCHAN_CSD_M_T_29000,		"transparent @ 29000 bps" },
 | 
			
		||||
	{ LCHAN_CSD_M_T_32000,		"transparent @ 32000 bps" },
 | 
			
		||||
	{ 0, NULL }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* prepare the per-SAPI T200 arrays for a given lchan */
 | 
			
		||||
static int t200_by_lchan(int *t200_ms_dcch, int *t200_ms_acch, struct gsm_lchan *lchan)
 | 
			
		||||
static int t200_by_lchan(uint32_t *t200_fn_dcch, uint32_t *t200_fn_acch, struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts *bts = lchan->ts->trx->bts;
 | 
			
		||||
 | 
			
		||||
	/* we have to compensate for the "RTS advance" due to the asynchronous interface between
 | 
			
		||||
	 * the BTS (LAPDm) and the PHY/L1 (OsmoTRX or DSP in case of osmo-bts-{sysmo,lc15,oc2g,octphy} */
 | 
			
		||||
	int32_t fn_advance = bts_get_avg_fn_advance(bts);
 | 
			
		||||
	int32_t fn_advance_us = fn_advance * 4615;
 | 
			
		||||
	int fn_advance_ms = fn_advance_us / 1000;
 | 
			
		||||
 | 
			
		||||
	t200_ms_acch[DL_SAPI0] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
 | 
			
		||||
	t200_ms_acch[DL_SAPI3] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
 | 
			
		||||
 | 
			
		||||
	if (lchan->rep_acch_cap.dl_facch_all && lchan_is_tch(lchan)) {
 | 
			
		||||
		t200_ms_acch[DL_SAPI0] *= 2;
 | 
			
		||||
		t200_ms_acch[DL_SAPI3] *= 2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (lchan->type) {
 | 
			
		||||
	case GSM_LCHAN_SDCCH:
 | 
			
		||||
		t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_SDCCH] + fn_advance_ms;
 | 
			
		||||
		t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_SDCCH_SAPI3] + fn_advance_ms;
 | 
			
		||||
		t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_SDCCH];
 | 
			
		||||
		t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_SDCCH_SAPI3];
 | 
			
		||||
		t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_SDCCH];
 | 
			
		||||
		t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_SDCCH];
 | 
			
		||||
		break;
 | 
			
		||||
	case GSM_LCHAN_TCH_F:
 | 
			
		||||
		t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
 | 
			
		||||
		t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
 | 
			
		||||
		t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_F];
 | 
			
		||||
		t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_FACCH_F];
 | 
			
		||||
		t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_TCH_SAPI0];
 | 
			
		||||
		t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_TCH_SAPI3];
 | 
			
		||||
		break;
 | 
			
		||||
	case GSM_LCHAN_TCH_H:
 | 
			
		||||
		t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
 | 
			
		||||
		t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
 | 
			
		||||
		t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_H];
 | 
			
		||||
		t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_FACCH_H];
 | 
			
		||||
		t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_TCH_SAPI0];
 | 
			
		||||
		t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_TCH_SAPI3];
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		/* Channels such as CCCH don't use lapdm DL, and hence no T200 is needed */
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Add time of two extra messages frames. */
 | 
			
		||||
	if (lchan->rep_acch_cap.dl_facch_all && lchan_is_tch(lchan)) {
 | 
			
		||||
		t200_fn_acch[DL_SAPI0] += 104 * 2;
 | 
			
		||||
		t200_fn_acch[DL_SAPI3] += 104 * 2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -151,17 +165,17 @@ void gsm_lchan_name_update(struct gsm_lchan *lchan)
 | 
			
		||||
int lchan_init_lapdm(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	struct lapdm_channel *lc = &lchan->lapdm_ch;
 | 
			
		||||
	int t200_ms_dcch[_NR_DL_SAPI], t200_ms_acch[_NR_DL_SAPI];
 | 
			
		||||
	uint32_t t200_fn_dcch[_NR_DL_SAPI], t200_fn_acch[_NR_DL_SAPI];
 | 
			
		||||
 | 
			
		||||
	if (t200_by_lchan(t200_ms_dcch, t200_ms_acch, lchan) == 0) {
 | 
			
		||||
	if (t200_by_lchan(t200_fn_dcch, t200_fn_acch, lchan) == 0) {
 | 
			
		||||
		LOGPLCHAN(lchan, DLLAPD, LOGL_DEBUG,
 | 
			
		||||
			  "Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in ms)\n",
 | 
			
		||||
			  t200_ms_dcch[DL_SAPI0], t200_ms_dcch[DL_SAPI3],
 | 
			
		||||
			  t200_ms_acch[DL_SAPI0], t200_ms_acch[DL_SAPI3]);
 | 
			
		||||
		lapdm_channel_init3(lc, LAPDM_MODE_BTS, t200_ms_dcch, t200_ms_acch, lchan->type,
 | 
			
		||||
				    gsm_lchan_name(lchan));
 | 
			
		||||
		lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY);
 | 
			
		||||
			  "Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in frames)\n",
 | 
			
		||||
			  t200_fn_dcch[DL_SAPI0], t200_fn_dcch[DL_SAPI3],
 | 
			
		||||
			  t200_fn_acch[DL_SAPI0], t200_fn_acch[DL_SAPI3]);
 | 
			
		||||
		lapdm_channel_init3(lc, LAPDM_MODE_BTS, NULL, NULL, lchan->type, gsm_lchan_name(lchan));
 | 
			
		||||
		lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY | LAPDM_ENT_F_RTS);
 | 
			
		||||
		lapdm_channel_set_l1(lc, NULL, lchan);
 | 
			
		||||
		lapdm_channel_set_t200_fn(lc, t200_fn_dcch, t200_fn_acch);
 | 
			
		||||
	}
 | 
			
		||||
	/* We still need to set Rx callback to receive RACH requests: */
 | 
			
		||||
	lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan);
 | 
			
		||||
@@ -216,8 +230,11 @@ void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind
 | 
			
		||||
	if (lchan->state == LCHAN_S_NONE)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* release handover state */
 | 
			
		||||
	/* release handover, listener and talker states */
 | 
			
		||||
	handover_reset(lchan);
 | 
			
		||||
	vgcs_talker_reset(lchan, false);
 | 
			
		||||
	vgcs_listener_reset(lchan);
 | 
			
		||||
	vgcs_uplink_free_reset(lchan);
 | 
			
		||||
 | 
			
		||||
	lchan->rel_act_kind = rel_kind;
 | 
			
		||||
 | 
			
		||||
@@ -322,7 +339,7 @@ void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* See Table 10.5.25 of GSM04.08 */
 | 
			
		||||
/* See 3GPP TS 44.018 Table 10.5.2.5.1 "Channel Description information element" */
 | 
			
		||||
static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
 | 
			
		||||
			  uint8_t ts_nr, uint8_t lchan_nr)
 | 
			
		||||
{
 | 
			
		||||
@@ -367,13 +384,13 @@ static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
 | 
			
		||||
		cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
 | 
			
		||||
		break;
 | 
			
		||||
	case GSM_PCHAN_NONE:
 | 
			
		||||
		LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",
 | 
			
		||||
		     gsm_pchan_name(pchan));
 | 
			
		||||
		cbits = 0x00;
 | 
			
		||||
		LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s not expected!\n",
 | 
			
		||||
		     ts_nr, lchan_nr, gsm_pchan_name(pchan));
 | 
			
		||||
		cbits = 0x00; /* Reserved */
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",
 | 
			
		||||
		     gsm_pchan_name(pchan), (int)pchan);
 | 
			
		||||
		LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s (0x%02x) not expected!\n",
 | 
			
		||||
		     ts_nr, lchan_nr, gsm_pchan_name(pchan), (int)pchan);
 | 
			
		||||
		OSMO_ASSERT(0);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
@@ -649,9 +666,11 @@ void lchan_rtp_socket_free(struct gsm_lchan *lchan)
 | 
			
		||||
/*! limit number of queue entries to %u; drops any surplus messages */
 | 
			
		||||
void lchan_dl_tch_queue_enqueue(struct gsm_lchan *lchan, struct msgb *msg, unsigned int limit)
 | 
			
		||||
{
 | 
			
		||||
	if (lchan->dl_tch_queue_len > limit)
 | 
			
		||||
		LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "freeing %d queued frames\n",
 | 
			
		||||
			  lchan->dl_tch_queue_len - limit);
 | 
			
		||||
	if (lchan->dl_tch_queue_len > limit) {
 | 
			
		||||
		unsigned int excess = lchan->dl_tch_queue_len - limit;
 | 
			
		||||
		LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "freeing %d queued frames\n", excess);
 | 
			
		||||
		rate_ctr_add2(lchan->ts->trx->bts->ctrs, BTS_CTR_RTP_RX_DROP_OVERFLOW, excess);
 | 
			
		||||
	}
 | 
			
		||||
	while (lchan->dl_tch_queue_len > limit) {
 | 
			
		||||
		struct msgb *tmp = msgb_dequeue_count(&lchan->dl_tch_queue, &lchan->dl_tch_queue_len);
 | 
			
		||||
		msgb_free(tmp);
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -125,6 +125,13 @@ static struct log_info_cat bts_log_info_cat[] = {
 | 
			
		||||
		.loglevel = LOGL_NOTICE,
 | 
			
		||||
		.enabled = 1,
 | 
			
		||||
	},
 | 
			
		||||
	[DASCI] = {
 | 
			
		||||
		.name = "DASCI",
 | 
			
		||||
		.description = "ASCI (Advanced Speech Call Items: VGCS/VBS)",
 | 
			
		||||
		.loglevel = LOGL_NOTICE,
 | 
			
		||||
		.enabled = 1,
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int osmo_bts_filter_fn(const struct log_context *ctx, struct log_target *tgt)
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -49,6 +49,7 @@
 | 
			
		||||
#include <osmo-bts/logging.h>
 | 
			
		||||
#include <osmo-bts/abis.h>
 | 
			
		||||
#include <osmo-bts/bts.h>
 | 
			
		||||
#include <osmo-bts/bts_sm.h>
 | 
			
		||||
#include <osmo-bts/vty.h>
 | 
			
		||||
#include <osmo-bts/l1sap.h>
 | 
			
		||||
#include <osmo-bts/bts_model.h>
 | 
			
		||||
@@ -292,7 +293,13 @@ int bts_main(int argc, char **argv)
 | 
			
		||||
	if (vty_test_mode)
 | 
			
		||||
		fprintf(stderr, "--- VTY test mode: not connecting to BSC, not exiting ---\n");
 | 
			
		||||
 | 
			
		||||
	g_bts = gsm_bts_alloc(tall_bts_ctx, 0);
 | 
			
		||||
	g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx);
 | 
			
		||||
	if (!g_bts_sm) {
 | 
			
		||||
		fprintf(stderr, "Failed to create BTS Site Manager structure\n");
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g_bts = gsm_bts_alloc(g_bts_sm, 0);
 | 
			
		||||
	if (!g_bts) {
 | 
			
		||||
		fprintf(stderr, "Failed to create BTS structure\n");
 | 
			
		||||
		exit(1);
 | 
			
		||||
@@ -354,12 +361,12 @@ int bts_main(int argc, char **argv)
 | 
			
		||||
	/* TODO: move this to gsm_bts_alloc() */
 | 
			
		||||
	if (g_bts->gsmtap.remote_host != NULL) {
 | 
			
		||||
		LOGP(DLGLOBAL, LOGL_NOTICE,
 | 
			
		||||
		     "Setting up GSMTAP Um forwarding to '%s:%u'\n",
 | 
			
		||||
		     g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
 | 
			
		||||
		g_bts->gsmtap.inst = gsmtap_source_init(g_bts->gsmtap.remote_host,
 | 
			
		||||
							GSMTAP_UDP_PORT, 1);
 | 
			
		||||
		     "Setting up GSMTAP Um forwarding '%s'->'%s:%u'\n",
 | 
			
		||||
		     g_bts->gsmtap.local_host, g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
 | 
			
		||||
		g_bts->gsmtap.inst = gsmtap_source_init2(g_bts->gsmtap.local_host, 0,
 | 
			
		||||
							 g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT, 1);
 | 
			
		||||
		if (g_bts->gsmtap.inst == NULL) {
 | 
			
		||||
			fprintf(stderr, "Failed during gsmtap_source_init()\n");
 | 
			
		||||
			fprintf(stderr, "Failed during gsmtap_source_init2()\n");
 | 
			
		||||
			exit(1);
 | 
			
		||||
		}
 | 
			
		||||
		gsmtap_source_add_sink(g_bts->gsmtap.inst);
 | 
			
		||||
@@ -373,7 +380,7 @@ int bts_main(int argc, char **argv)
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pcu_sock_init(g_bts->pcu.sock_path)) {
 | 
			
		||||
	if (pcu_sock_init(g_bts->pcu.sock_path, g_bts->pcu.sock_wqueue_len_max)) {
 | 
			
		||||
		fprintf(stderr, "PCU L1 socket failed\n");
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
/* Active TDMA frame subset for TCH/H in DTX mode (see 3GPP TS 45.008 Section 8.3).
 | 
			
		||||
 * This mapping is used to determine if a L2 block starting at the given TDMA FN
 | 
			
		||||
 * belongs to the SUB set and thus shall always be transmitted in DTX mode. */
 | 
			
		||||
static const uint8_t ts45008_dtx_tchh_fn_map[104] = {
 | 
			
		||||
static const uint8_t ts45008_dtx_tchh_speech_fn_map[104] = {
 | 
			
		||||
	/* TCH/H(0): 0, 2, 4, 6, 52, 54, 56, 58 */
 | 
			
		||||
	[0]  = 1, /* block { 0,  2,  4,  6} */
 | 
			
		||||
	[52] = 1, /* block {52, 54, 56, 58} */
 | 
			
		||||
@@ -28,6 +28,15 @@ static const uint8_t ts45008_dtx_tchh_fn_map[104] = {
 | 
			
		||||
	[66] = 1, /* block {66, 68, 70, 72} */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const uint8_t ts45008_dtx_tchh_data_fn_map[104] = {
 | 
			
		||||
	/* UL TCH/H(0): 52, 54, 56, 58, 60, 62, 65, 67, 69, 71 */
 | 
			
		||||
	[52] = 1, /* block {52, 54, 56, 58, 60, 62} */
 | 
			
		||||
	[60] = 1, /* block {60, 62, 65, 67, 69, 71} */
 | 
			
		||||
	/* UL TCH/H(1): 70, 72, 74, 76, 79, 81, 83, 85, 87, 89 */
 | 
			
		||||
	[70] = 1, /* block {70, 72, 74, 76, 79, 81} */
 | 
			
		||||
	[79] = 1, /* block {79, 81, 83, 85, 87, 89} */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* In cases where we less measurements than we expect we must assume that we
 | 
			
		||||
 * just did not receive the block because it was lost due to bad channel
 | 
			
		||||
 * conditions. We set up a dummy measurement result here that reflects the
 | 
			
		||||
@@ -50,7 +59,7 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
	uint32_t fn104 = fn % 104;
 | 
			
		||||
 | 
			
		||||
	/* See TS 45.008 Sections 8.3 and 8.4 for a detailed descriptions of the rules
 | 
			
		||||
	 * implemented here. We only implement the logic for Voice, not CSD */
 | 
			
		||||
	 * implemented here. We implement the logic for both speech and data (CSD). */
 | 
			
		||||
 | 
			
		||||
	/* AMR is special, SID frames may be scheduled dynamically at any time */
 | 
			
		||||
	if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
 | 
			
		||||
@@ -59,8 +68,11 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
	switch (lchan->type) {
 | 
			
		||||
	case GSM_LCHAN_TCH_F:
 | 
			
		||||
		switch (lchan->tch_mode) {
 | 
			
		||||
		case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V1:
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V1_VAMOS:
 | 
			
		||||
		case GSM48_CMODE_SPEECH_EFR:
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V2_VAMOS:
 | 
			
		||||
			/* Active TDMA frame subset for TCH/F: 52, 53, 54, 55, 56, 57, 58, 59.
 | 
			
		||||
			 * There is only one *complete* block in this subset starting at FN=52.
 | 
			
		||||
			 * Incomplete blocks {... 52, 53, 54, 55} and {56, 57, 58, 59 ...}
 | 
			
		||||
@@ -68,29 +80,38 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
			if (fn104 == 52)
 | 
			
		||||
				return true;
 | 
			
		||||
			break;
 | 
			
		||||
		case GSM48_CMODE_SIGN:
 | 
			
		||||
			/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
 | 
			
		||||
			 * SUB */
 | 
			
		||||
			return true;
 | 
			
		||||
		case GSM48_CMODE_DATA_12k0: /* TCH/F9.6 */
 | 
			
		||||
		case GSM48_CMODE_DATA_6k0: /* TCH/F4.8 */
 | 
			
		||||
			/* FIXME: The RXQUAL_SUB (not RXLEV!) report shall include measurements on
 | 
			
		||||
			 * the TDMA frames given in the table of subclause 8.3 only if L2 fill frames
 | 
			
		||||
			 * have been received as FACCH/F frames at the corresponding frame positions. */
 | 
			
		||||
		default:
 | 
			
		||||
			LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n",
 | 
			
		||||
				gsm_lchan_name(lchan), lchan->tch_mode);
 | 
			
		||||
			if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
 | 
			
		||||
				return fn104 == 52;
 | 
			
		||||
			LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case GSM_LCHAN_TCH_H:
 | 
			
		||||
		switch (lchan->tch_mode) {
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V1:
 | 
			
		||||
			if (ts45008_dtx_tchh_fn_map[fn104])
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V1_VAMOS:
 | 
			
		||||
			if (ts45008_dtx_tchh_speech_fn_map[fn104])
 | 
			
		||||
				return true;
 | 
			
		||||
			break;
 | 
			
		||||
		case GSM48_CMODE_SIGN:
 | 
			
		||||
			/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
 | 
			
		||||
			 * SUB */
 | 
			
		||||
			return true;
 | 
			
		||||
		case GSM48_CMODE_DATA_6k0: /* TCH/H4.8 */
 | 
			
		||||
		case GSM48_CMODE_DATA_3k6: /* TCH/H2.4 */
 | 
			
		||||
			/* FIXME: The RXQUAL_SUB (not RXLEV!) report shall include measurements on
 | 
			
		||||
			 * the TDMA frames given in the table of subclause 8.3 only if L2 fill frames
 | 
			
		||||
			 * have been received as FACCH/H frames at the corresponding frame positions. */
 | 
			
		||||
		default:
 | 
			
		||||
			LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n",
 | 
			
		||||
				gsm_lchan_name(lchan), lchan->tch_mode);
 | 
			
		||||
			if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
 | 
			
		||||
				return ts45008_dtx_tchh_data_fn_map[fn104] == 1;
 | 
			
		||||
			LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
@@ -269,9 +290,8 @@ int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (rc == 1) {
 | 
			
		||||
		DEBUGP(DMEAS,
 | 
			
		||||
		       "%s meas period end fn:%u, fn_mod:%i, status:%d, pchan:%s\n",
 | 
			
		||||
		       gsm_lchan_name(lchan), fn, fn_mod, rc, gsm_pchan_name(pchan));
 | 
			
		||||
		LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG, "meas period end fn_mod:%d, status:%d, pchan:%s\n", fn_mod,
 | 
			
		||||
			 rc, gsm_pchan_name(pchan));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return rc;
 | 
			
		||||
@@ -307,16 +327,15 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan,
 | 
			
		||||
	struct bts_ul_meas *dest;
 | 
			
		||||
 | 
			
		||||
	if (lchan->state != LCHAN_S_ACTIVE) {
 | 
			
		||||
		LOGPFN(DMEAS, LOGL_NOTICE, fn,
 | 
			
		||||
		       "%s measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n",
 | 
			
		||||
		       gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
 | 
			
		||||
		       lchan->meas.num_ul_meas, fn_mod);
 | 
			
		||||
		LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE,
 | 
			
		||||
			 "measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n",
 | 
			
		||||
			 gsm_lchans_name(lchan->state), lchan->meas.num_ul_meas, fn_mod);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lchan->meas.num_ul_meas >= ARRAY_SIZE(lchan->meas.uplink)) {
 | 
			
		||||
		LOGPFN(DMEAS, LOGL_NOTICE, fn,
 | 
			
		||||
		       "%s no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n",
 | 
			
		||||
		       gsm_lchan_name(lchan), lchan->meas.num_ul_meas, fn_mod);
 | 
			
		||||
		LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE,
 | 
			
		||||
			 "no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n", lchan->meas.num_ul_meas,
 | 
			
		||||
			 fn_mod);
 | 
			
		||||
		return -ENOSPC;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -328,10 +347,9 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan,
 | 
			
		||||
	if (!ulm->is_sub)
 | 
			
		||||
		dest->is_sub = ts45008_83_is_sub(lchan, fn);
 | 
			
		||||
 | 
			
		||||
	DEBUGPFN(DMEAS, fn, "%s adding a %s measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
 | 
			
		||||
		 gsm_lchan_name(lchan),
 | 
			
		||||
		 dest->is_sub ? "SUB" : "FULL",
 | 
			
		||||
		 ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi,
 | 
			
		||||
	LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG,
 | 
			
		||||
		 "adding a %s measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
 | 
			
		||||
		 dest->is_sub ? "SUB" : "FULL", ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi,
 | 
			
		||||
		 lchan->meas.num_ul_meas, fn_mod);
 | 
			
		||||
 | 
			
		||||
	lchan->meas.last_fn = fn;
 | 
			
		||||
@@ -406,32 +424,50 @@ static unsigned int lchan_meas_num_expected(const struct gsm_lchan *lchan)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* In DTX a subset of blocks must always be transmitted
 | 
			
		||||
 * See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX) */
 | 
			
		||||
static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
 | 
			
		||||
 * See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX)
 | 
			
		||||
 * Return value N: (N < 0) -- at least N SUB frames expected;
 | 
			
		||||
 *                 (N > 0) -- exactly N SUB frames expected;
 | 
			
		||||
 *                 (N == 0) - unknown channel type/mode? */
 | 
			
		||||
static int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
 | 
			
		||||
 | 
			
		||||
	/* AMR is using a more elaborated model with a dymanic amount of
 | 
			
		||||
	 * DTX blocks so this function is not applicable to determine the
 | 
			
		||||
	 * amount of expected SUB Measurements when AMR is used */
 | 
			
		||||
	OSMO_ASSERT(lchan->tch_mode != GSM48_CMODE_SPEECH_AMR);
 | 
			
		||||
 | 
			
		||||
	switch (pchan) {
 | 
			
		||||
	case GSM_PCHAN_TCH_F:
 | 
			
		||||
		if (lchan->tch_mode == GSM48_CMODE_SIGN) {
 | 
			
		||||
			/* 1 block SACCH, 24 blocks TCH (see note 1) */
 | 
			
		||||
			return 25;
 | 
			
		||||
		} else {
 | 
			
		||||
			/* 1 block SACCH, 1 block TCH */
 | 
			
		||||
			return 2;
 | 
			
		||||
		if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
 | 
			
		||||
			return 1 + 1; /* 1 x SACCH + 1 x FACCH */
 | 
			
		||||
		/* else: signalling or speech */
 | 
			
		||||
		switch (lchan->tch_mode) {
 | 
			
		||||
		case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V1: /* TCH/FS */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V1_VAMOS:
 | 
			
		||||
		case GSM48_CMODE_SPEECH_EFR: /* TCH/EFS */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V2_VAMOS:
 | 
			
		||||
			return 1 + 1; /* 1 x SACCH + 1 x TCH */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_AMR: /* TCH/AFS */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V3_VAMOS:
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V4: /* O-TCH/WFS */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V5: /* TCH/WFS */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V5_VAMOS:
 | 
			
		||||
		default:
 | 
			
		||||
			return -1; /* at least 1 x SACCH + M x TCH (variable) */
 | 
			
		||||
		}
 | 
			
		||||
	case GSM_PCHAN_TCH_H:
 | 
			
		||||
		if (lchan->tch_mode == GSM48_CMODE_SIGN) {
 | 
			
		||||
			/* 1 block SACCH, 12 blocks TCH (see ynote 1) */
 | 
			
		||||
			return 13;
 | 
			
		||||
		} else {
 | 
			
		||||
			/* 1 block SACCH, 2 blocks TCH */
 | 
			
		||||
			return 3;
 | 
			
		||||
		if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
 | 
			
		||||
			return 1 + 2; /* 1 x SACCH + 2 x FACCH */
 | 
			
		||||
		/* else: signalling or speech */
 | 
			
		||||
		switch (lchan->tch_mode) {
 | 
			
		||||
		case GSM48_CMODE_SIGN: /* TCH/H sign: DTX *is not* permitted */
 | 
			
		||||
			return 1 + 12; /* 1 x SACCH + 12 x TCH */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V1:
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V1_VAMOS:
 | 
			
		||||
			return 1 + 2; /* 1 x SACCH + 2 x TCH */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_AMR: /* TCH/AHS */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V3_VAMOS:
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V4: /* O-TCH/WHS */
 | 
			
		||||
		case GSM48_CMODE_SPEECH_V6: /* O-TCH/AHS */
 | 
			
		||||
		default:
 | 
			
		||||
			return -1; /* at least 1 x SACCH + M x TCH (variable) */
 | 
			
		||||
		}
 | 
			
		||||
	case GSM_PCHAN_SDCCH8_SACCH8C:
 | 
			
		||||
	case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
 | 
			
		||||
@@ -444,8 +480,6 @@ static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
 | 
			
		||||
	default:
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Note 1: In signalling mode all blocks count as SUB blocks. */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* if we clip the TOA value to 12 bits, i.e. toa256=3200,
 | 
			
		||||
@@ -551,7 +585,7 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
	unsigned int num_meas_sub = 0;
 | 
			
		||||
	unsigned int num_meas_sub_actual = 0;
 | 
			
		||||
	unsigned int num_meas_sub_subst = 0;
 | 
			
		||||
	unsigned int num_meas_sub_expect;
 | 
			
		||||
	int num_meas_sub_expect;
 | 
			
		||||
	unsigned int num_ul_meas;
 | 
			
		||||
	unsigned int num_ul_meas_actual = 0;
 | 
			
		||||
	unsigned int num_ul_meas_subst = 0;
 | 
			
		||||
@@ -571,16 +605,7 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
	 * intentionally to save energy. It is not necessarly an error
 | 
			
		||||
	 * when we get less measurements as we expect. */
 | 
			
		||||
	num_ul_meas_expect = lchan_meas_num_expected(lchan);
 | 
			
		||||
 | 
			
		||||
	if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR)
 | 
			
		||||
		num_meas_sub_expect = lchan_meas_sub_num_expected(lchan);
 | 
			
		||||
	else {
 | 
			
		||||
		/* When AMR is used, we expect at least one SUB frame, since
 | 
			
		||||
		 * the SACCH will always be SUB frame. There may occur more
 | 
			
		||||
		 * SUB frames but since DTX periods in AMR are dynamic, we
 | 
			
		||||
		 * can not know how many exactly. */
 | 
			
		||||
		num_meas_sub_expect = 1;
 | 
			
		||||
	}
 | 
			
		||||
	num_meas_sub_expect = lchan_meas_sub_num_expected(lchan);
 | 
			
		||||
 | 
			
		||||
	if (lchan->meas.num_ul_meas > num_ul_meas_expect)
 | 
			
		||||
		num_ul_meas_excess = lchan->meas.num_ul_meas - num_ul_meas_expect;
 | 
			
		||||
@@ -626,12 +651,9 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
		} else {
 | 
			
		||||
			m = &measurement_dummy;
 | 
			
		||||
 | 
			
		||||
			/* For AMR the amount of SUB frames is defined by the
 | 
			
		||||
			 * the occurrence of DTX periods, which are dynamically
 | 
			
		||||
			 * negotiated in AMR, so we can not know if and how many
 | 
			
		||||
			 * SUB frames are missing. */
 | 
			
		||||
			if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
 | 
			
		||||
				if (num_meas_sub <= i) {
 | 
			
		||||
			/* only if we know the exact number of SUB measurements */
 | 
			
		||||
			if (num_meas_sub_expect >= 0) {
 | 
			
		||||
				if (num_meas_sub < num_meas_sub_expect) {
 | 
			
		||||
					num_meas_sub_subst++;
 | 
			
		||||
					is_sub = true;
 | 
			
		||||
				}
 | 
			
		||||
@@ -647,16 +669,6 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
 | 
			
		||||
		LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
 | 
			
		||||
			  "Received UL measurements contain %u SUB measurements, expected %u\n",
 | 
			
		||||
			  num_meas_sub_actual, num_meas_sub_expect);
 | 
			
		||||
	} else {
 | 
			
		||||
		LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
 | 
			
		||||
			  "Received UL measurements contain %u SUB measurements, expected at least %u\n",
 | 
			
		||||
			  num_meas_sub_actual, num_meas_sub_expect);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, "Replaced %u measurements with dummy values, "
 | 
			
		||||
		  "from which %u were SUB measurements\n", num_ul_meas_subst, num_meas_sub_subst);
 | 
			
		||||
 | 
			
		||||
@@ -667,17 +679,24 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
	 * above only adds missing measurements during the calculation
 | 
			
		||||
	 * it can not remove excess SUB measurements or add missing SUB
 | 
			
		||||
	 * measurements when there is no more room in the interval. */
 | 
			
		||||
	if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
 | 
			
		||||
		if (num_meas_sub != num_meas_sub_expect) {
 | 
			
		||||
	if (num_meas_sub_expect < 0) {
 | 
			
		||||
		num_meas_sub_expect = -num_meas_sub_expect;
 | 
			
		||||
		LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
 | 
			
		||||
			  "Received UL measurements contain %u SUB measurements, expected at least %d\n",
 | 
			
		||||
			  num_meas_sub_actual, num_meas_sub_expect);
 | 
			
		||||
		if (OSMO_UNLIKELY(num_meas_sub < num_meas_sub_expect)) {
 | 
			
		||||
			LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
 | 
			
		||||
				  "Incorrect number of SUB measurements detected! "
 | 
			
		||||
				  "(%u vs exp %u)\n", num_meas_sub, num_meas_sub_expect);
 | 
			
		||||
				  "(%u vs exp >=%d)\n", num_meas_sub, num_meas_sub_expect);
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if (num_meas_sub < num_meas_sub_expect) {
 | 
			
		||||
		LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
 | 
			
		||||
			  "Received UL measurements contain %u SUB measurements, expected %d\n",
 | 
			
		||||
			  num_meas_sub_actual, num_meas_sub_expect);
 | 
			
		||||
		if (OSMO_UNLIKELY(num_meas_sub != num_meas_sub_expect)) {
 | 
			
		||||
			LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
 | 
			
		||||
				  "Incorrect number of SUB measurements detected! "
 | 
			
		||||
				  "(%u vs exp >=%u)\n", num_meas_sub, num_meas_sub_expect);
 | 
			
		||||
				  "(%u vs exp %d)\n", num_meas_sub, num_meas_sub_expect);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -380,15 +380,19 @@ static inline bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn)
 | 
			
		||||
	static const uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 },
 | 
			
		||||
				h0[] = { 0, 2, 4, 6, 52, 54, 56, 58 },
 | 
			
		||||
				h1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };
 | 
			
		||||
	if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1) {
 | 
			
		||||
	switch (lchan->tch_mode) {
 | 
			
		||||
	case GSM48_CMODE_SPEECH_V1:
 | 
			
		||||
		if (lchan->type == GSM_LCHAN_TCH_F)
 | 
			
		||||
			return fn_chk(f, fn, ARRAY_SIZE(f));
 | 
			
		||||
		else
 | 
			
		||||
			return fn_chk(lchan->nr ? h1 : h0, fn,
 | 
			
		||||
				      lchan->nr ? ARRAY_SIZE(h1) :
 | 
			
		||||
				      ARRAY_SIZE(h0));
 | 
			
		||||
	case GSM48_CMODE_SPEECH_EFR:
 | 
			
		||||
		return fn_chk(f, fn, ARRAY_SIZE(f));
 | 
			
		||||
	default:
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*! \brief Check if DTX DL AMR is enabled for a given lchan (it have proper type,
 | 
			
		||||
@@ -466,10 +470,6 @@ void dtx_int_signal(struct gsm_lchan *lchan)
 | 
			
		||||
 */
 | 
			
		||||
uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn)
 | 
			
		||||
{
 | 
			
		||||
	/* FIXME: add EFR support */
 | 
			
		||||
	if (lchan->tch_mode == GSM48_CMODE_SPEECH_EFR)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
 | 
			
		||||
		if (dtx_sched_optional(lchan, fn))
 | 
			
		||||
			return 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* NM Radio Carrier FSM */
 | 
			
		||||
 | 
			
		||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 | 
			
		||||
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -70,17 +70,17 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint3
 | 
			
		||||
static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
 | 
			
		||||
	struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case NM_EV_SW_ACT:
 | 
			
		||||
		oml_mo_tx_sw_act_rep(&bb_transc->mo);
 | 
			
		||||
		nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE);
 | 
			
		||||
		for (i = 0; i < TRX_NR_TS; i++) {
 | 
			
		||||
			struct gsm_bts_trx_ts *ts = &trx->ts[i];
 | 
			
		||||
			osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_BBTRANSC_INSTALLED, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		ev_dispatch_children(bb_transc, event);
 | 
			
		||||
		return;
 | 
			
		||||
	case NM_EV_OML_UP:
 | 
			
		||||
		/* Report current state: */
 | 
			
		||||
		oml_tx_state_changed(&bb_transc->mo);
 | 
			
		||||
		ev_dispatch_children(bb_transc, event);
 | 
			
		||||
		return;
 | 
			
		||||
	case NM_EV_RSL_UP:
 | 
			
		||||
		return;
 | 
			
		||||
@@ -119,17 +119,48 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
 | 
			
		||||
	struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
 | 
			
		||||
	struct gsm_bts *bts = trx->bts;
 | 
			
		||||
	struct nm_fsm_ev_setattr_data *setattr_data;
 | 
			
		||||
	bool phy_state_connected;
 | 
			
		||||
	bool rsl_link_connected;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case NM_EV_SETATTR_ACK:
 | 
			
		||||
	case NM_EV_SETATTR_NACK:
 | 
			
		||||
	case NM_EV_OML_UP:
 | 
			
		||||
		/* Report current state: */
 | 
			
		||||
		oml_tx_state_changed(&bb_transc->mo);
 | 
			
		||||
		ev_dispatch_children(bb_transc, event);
 | 
			
		||||
		return;
 | 
			
		||||
	case NM_EV_RX_SETATTR:
 | 
			
		||||
		setattr_data = (struct nm_fsm_ev_setattr_data *)data;
 | 
			
		||||
		bb_transc->mo.setattr_success = setattr_data->cause == 0;
 | 
			
		||||
		oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
 | 
			
		||||
		break;
 | 
			
		||||
		rc = bts_model_apply_oml(trx->bts, setattr_data->msg,
 | 
			
		||||
					 &bb_transc->mo, bb_transc);
 | 
			
		||||
		bb_transc->mo.setattr_success = rc == 0;
 | 
			
		||||
		oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
 | 
			
		||||
		return;
 | 
			
		||||
	case NM_EV_RX_OPSTART:
 | 
			
		||||
#if 0
 | 
			
		||||
		/* Disabled because osmo-bsc doesn't send SetAttr on BB_TRANSC object */
 | 
			
		||||
		if (!bb_transc->mo.setattr_success) {
 | 
			
		||||
			oml_mo_opstart_nack(&bb_transc->mo, NM_NACK_CANT_PERFORM);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
		/* Connect RSL link: */
 | 
			
		||||
		if (bts->variant == BTS_OSMO_OMLDUMMY) {
 | 
			
		||||
			LOGPFSML(fi, LOGL_NOTICE, "Not connecting RSL in OML-DUMMY!\n");
 | 
			
		||||
		} else {
 | 
			
		||||
			rc = e1inp_ipa_bts_rsl_connect_n(bts->oml_link->ts->line,
 | 
			
		||||
							 bb_transc->rsl.rem_addrstr.ip,
 | 
			
		||||
							 bb_transc->rsl.rem_addrstr.port, trx->nr);
 | 
			
		||||
			if (rc < 0) {
 | 
			
		||||
				LOGPFSML(fi, LOGL_NOTICE, "Error connecting IPA RSL: %d\n", rc);
 | 
			
		||||
				oml_mo_opstart_nack(&bb_transc->mo, NM_NACK_CANT_PERFORM);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		bts_model_opstart(trx->bts, &bb_transc->mo, bb_transc);
 | 
			
		||||
		return;
 | 
			
		||||
	case NM_EV_OPSTART_ACK:
 | 
			
		||||
		bb_transc->mo.opstart_success = true;
 | 
			
		||||
		oml_mo_opstart_ack(&bb_transc->mo);
 | 
			
		||||
@@ -153,10 +184,10 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (trx->bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */
 | 
			
		||||
	if (bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */
 | 
			
		||||
		struct phy_instance *pinst = trx_phy_instance(trx);
 | 
			
		||||
		phy_state_connected = phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED;
 | 
			
		||||
		rsl_link_connected = !!trx->rsl_link;
 | 
			
		||||
		rsl_link_connected = !!trx->bb_transc.rsl.link;
 | 
			
		||||
	} else {
 | 
			
		||||
		phy_state_connected = true;
 | 
			
		||||
		rsl_link_connected = true;
 | 
			
		||||
@@ -231,6 +262,7 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = {
 | 
			
		||||
	[NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED] = {
 | 
			
		||||
		.in_event_mask =
 | 
			
		||||
			X(NM_EV_SW_ACT) |
 | 
			
		||||
			X(NM_EV_OML_UP) |
 | 
			
		||||
			X(NM_EV_RSL_UP) |
 | 
			
		||||
			X(NM_EV_RSL_DOWN) |
 | 
			
		||||
			X(NM_EV_PHYLINK_UP) |
 | 
			
		||||
@@ -245,8 +277,9 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = {
 | 
			
		||||
	},
 | 
			
		||||
	[NM_BBTRANSC_ST_OP_DISABLED_OFFLINE] = {
 | 
			
		||||
		.in_event_mask =
 | 
			
		||||
			X(NM_EV_SETATTR_ACK) |
 | 
			
		||||
			X(NM_EV_SETATTR_NACK) |
 | 
			
		||||
			X(NM_EV_OML_UP) |
 | 
			
		||||
			X(NM_EV_RX_SETATTR) |
 | 
			
		||||
			X(NM_EV_RX_OPSTART) |
 | 
			
		||||
			X(NM_EV_OPSTART_ACK) |
 | 
			
		||||
			X(NM_EV_OPSTART_NACK) |
 | 
			
		||||
			X(NM_EV_RSL_UP) |
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* NM BTS FSM */
 | 
			
		||||
 | 
			
		||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 | 
			
		||||
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -36,6 +36,7 @@
 | 
			
		||||
#include <osmo-bts/nm_common_fsm.h>
 | 
			
		||||
#include <osmo-bts/phy_link.h>
 | 
			
		||||
#include <osmo-bts/cbch.h>
 | 
			
		||||
#include <osmo-bts/notification.h>
 | 
			
		||||
 | 
			
		||||
#define X(s) (1 << (s))
 | 
			
		||||
 | 
			
		||||
@@ -60,8 +61,13 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint3
 | 
			
		||||
	struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
 | 
			
		||||
	/* Reset state: */
 | 
			
		||||
	bts->si_valid = 0;
 | 
			
		||||
	bts->bsic_configured = false;
 | 
			
		||||
	bts->bsic = 0xff; /* invalid value */
 | 
			
		||||
	TALLOC_FREE(bts->mo.nm_attr);
 | 
			
		||||
	bts_cbch_reset(bts);
 | 
			
		||||
	bts_asci_notification_reset(bts);
 | 
			
		||||
	if (bts->c0_power_red_db > 0)
 | 
			
		||||
		bts_set_c0_pwr_red(bts, 0);
 | 
			
		||||
 | 
			
		||||
	bts->mo.setattr_success = false;
 | 
			
		||||
	bts->mo.opstart_success = false;
 | 
			
		||||
@@ -74,7 +80,8 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
 | 
			
		||||
	struct gsm_bts_trx *trx;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case NM_EV_SW_ACT:
 | 
			
		||||
	case NM_EV_OML_UP:
 | 
			
		||||
		/* automatic SW_ACT upon OML link establishment: */
 | 
			
		||||
		oml_mo_tx_sw_act_rep(&bts->mo);
 | 
			
		||||
 | 
			
		||||
		llist_for_each_entry(trx, &bts->trx_list, list) {
 | 
			
		||||
@@ -91,6 +98,7 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_DISABLED_OFFLINE);
 | 
			
		||||
		ev_dispatch_children(bts, event);
 | 
			
		||||
		return;
 | 
			
		||||
	default:
 | 
			
		||||
		OSMO_ASSERT(0);
 | 
			
		||||
@@ -109,13 +117,21 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
 | 
			
		||||
	struct nm_fsm_ev_setattr_data *setattr_data;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case NM_EV_SETATTR_ACK:
 | 
			
		||||
	case NM_EV_SETATTR_NACK:
 | 
			
		||||
	case NM_EV_RX_SETATTR:
 | 
			
		||||
		setattr_data = (struct nm_fsm_ev_setattr_data *)data;
 | 
			
		||||
		bts->mo.setattr_success = setattr_data->cause == 0;
 | 
			
		||||
		oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
 | 
			
		||||
		rc = bts_model_apply_oml(bts, setattr_data->msg, &bts->mo, bts);
 | 
			
		||||
		bts->mo.setattr_success = rc == 0;
 | 
			
		||||
		oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
 | 
			
		||||
		break;
 | 
			
		||||
	case NM_EV_RX_OPSTART:
 | 
			
		||||
		if (!bts->mo.setattr_success) {
 | 
			
		||||
			oml_mo_opstart_nack(&bts->mo, NM_NACK_CANT_PERFORM);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		bts_model_opstart(bts, &bts->mo, bts);
 | 
			
		||||
		break;
 | 
			
		||||
	case NM_EV_OPSTART_ACK:
 | 
			
		||||
		bts->mo.opstart_success = true;
 | 
			
		||||
@@ -166,7 +182,7 @@ static void nm_bts_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data
 | 
			
		||||
static struct osmo_fsm_state nm_bts_fsm_states[] = {
 | 
			
		||||
	[NM_BTS_ST_OP_DISABLED_NOTINSTALLED] = {
 | 
			
		||||
		.in_event_mask =
 | 
			
		||||
			X(NM_EV_SW_ACT),
 | 
			
		||||
			X(NM_EV_OML_UP),
 | 
			
		||||
		.out_state_mask =
 | 
			
		||||
			X(NM_BTS_ST_OP_DISABLED_NOTINSTALLED) |
 | 
			
		||||
			X(NM_BTS_ST_OP_DISABLED_OFFLINE),
 | 
			
		||||
@@ -176,8 +192,8 @@ static struct osmo_fsm_state nm_bts_fsm_states[] = {
 | 
			
		||||
	},
 | 
			
		||||
	[NM_BTS_ST_OP_DISABLED_OFFLINE] = {
 | 
			
		||||
		.in_event_mask =
 | 
			
		||||
			X(NM_EV_SETATTR_ACK) |
 | 
			
		||||
			X(NM_EV_SETATTR_NACK) |
 | 
			
		||||
			X(NM_EV_RX_SETATTR) |
 | 
			
		||||
			X(NM_EV_RX_OPSTART) |
 | 
			
		||||
			X(NM_EV_OPSTART_ACK) |
 | 
			
		||||
			X(NM_EV_OPSTART_NACK),
 | 
			
		||||
		.out_state_mask =
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* NM BTS Site Manager FSM */
 | 
			
		||||
 | 
			
		||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 | 
			
		||||
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -32,6 +32,7 @@
 | 
			
		||||
#include <osmo-bts/gsm_data.h>
 | 
			
		||||
#include <osmo-bts/bts_model.h>
 | 
			
		||||
#include <osmo-bts/bts.h>
 | 
			
		||||
#include <osmo-bts/bts_sm.h>
 | 
			
		||||
#include <osmo-bts/rsl.h>
 | 
			
		||||
#include <osmo-bts/nm_common_fsm.h>
 | 
			
		||||
#include <osmo-bts/phy_link.h>
 | 
			
		||||
@@ -44,8 +45,11 @@
 | 
			
		||||
 | 
			
		||||
static void ev_dispatch_children(struct gsm_bts_sm *site_mgr, uint32_t event)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts *bts = gsm_bts_sm_get_bts(site_mgr);
 | 
			
		||||
	osmo_fsm_inst_dispatch(bts->mo.fi, event, NULL);
 | 
			
		||||
	struct gsm_bts *bts;
 | 
			
		||||
	osmo_fsm_inst_dispatch(site_mgr->gprs.nse.mo.fi, event, NULL);
 | 
			
		||||
	llist_for_each_entry(bts, &site_mgr->bts_list, list) {
 | 
			
		||||
		osmo_fsm_inst_dispatch(bts->mo.fi, event, NULL);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////
 | 
			
		||||
@@ -65,9 +69,11 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
 | 
			
		||||
	struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case NM_EV_SW_ACT:
 | 
			
		||||
	case NM_EV_OML_UP:
 | 
			
		||||
		/* automatic SW_ACT upon OML link establishment: */
 | 
			
		||||
		oml_mo_tx_sw_act_rep(&site_mgr->mo);
 | 
			
		||||
		nm_bts_sm_fsm_state_chg(fi, NM_BTS_SM_ST_OP_DISABLED_OFFLINE);
 | 
			
		||||
		ev_dispatch_children(site_mgr, event);
 | 
			
		||||
		return;
 | 
			
		||||
	default:
 | 
			
		||||
		OSMO_ASSERT(0);
 | 
			
		||||
@@ -86,13 +92,25 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv;
 | 
			
		||||
	struct nm_fsm_ev_setattr_data *setattr_data;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case NM_EV_SETATTR_ACK:
 | 
			
		||||
	case NM_EV_SETATTR_NACK:
 | 
			
		||||
	case NM_EV_RX_SETATTR:
 | 
			
		||||
		setattr_data = (struct nm_fsm_ev_setattr_data *)data;
 | 
			
		||||
		site_mgr->mo.setattr_success = setattr_data->cause == 0;
 | 
			
		||||
		oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
 | 
			
		||||
		/* No bts_model_apply_oml() needed yet for site_mgr obj yet: */
 | 
			
		||||
		rc = 0;
 | 
			
		||||
		site_mgr->mo.setattr_success = rc == 0;
 | 
			
		||||
		oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
 | 
			
		||||
		break;
 | 
			
		||||
	case NM_EV_RX_OPSTART:
 | 
			
		||||
#if 0
 | 
			
		||||
		/* Disabled because osmo-bsc doesn't send SetAttr on SITE_MGR object */
 | 
			
		||||
		if (!site_mgr->mo.setattr_success) {
 | 
			
		||||
			oml_mo_opstart_nack(&site_mgr->mo, NM_NACK_CANT_PERFORM);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
		bts_model_opstart(NULL, &site_mgr->mo, site_mgr);
 | 
			
		||||
		break;
 | 
			
		||||
	case NM_EV_OPSTART_ACK:
 | 
			
		||||
		site_mgr->mo.opstart_success = true;
 | 
			
		||||
@@ -143,7 +161,7 @@ static void nm_bts_sm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *d
 | 
			
		||||
static struct osmo_fsm_state nm_bts_sm_fsm_states[] = {
 | 
			
		||||
	[NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED] = {
 | 
			
		||||
		.in_event_mask =
 | 
			
		||||
			X(NM_EV_SW_ACT),
 | 
			
		||||
			X(NM_EV_OML_UP),
 | 
			
		||||
		.out_state_mask =
 | 
			
		||||
			X(NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED) |
 | 
			
		||||
			X(NM_BTS_SM_ST_OP_DISABLED_OFFLINE),
 | 
			
		||||
@@ -153,8 +171,8 @@ static struct osmo_fsm_state nm_bts_sm_fsm_states[] = {
 | 
			
		||||
	},
 | 
			
		||||
	[NM_BTS_SM_ST_OP_DISABLED_OFFLINE] = {
 | 
			
		||||
		.in_event_mask =
 | 
			
		||||
			X(NM_EV_SETATTR_ACK) |
 | 
			
		||||
			X(NM_EV_SETATTR_NACK) |
 | 
			
		||||
			X(NM_EV_RX_SETATTR) |
 | 
			
		||||
			X(NM_EV_RX_OPSTART) |
 | 
			
		||||
			X(NM_EV_OPSTART_ACK) |
 | 
			
		||||
			X(NM_EV_OPSTART_NACK),
 | 
			
		||||
		.out_state_mask =
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* NM Radio Carrier FSM */
 | 
			
		||||
 | 
			
		||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 | 
			
		||||
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 | 
			
		||||
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 | 
			
		||||
 *
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
@@ -71,7 +71,11 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
 | 
			
		||||
	struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case NM_EV_BBTRANSC_INSTALLED:
 | 
			
		||||
	case NM_EV_OML_UP:
 | 
			
		||||
		/* Report current state: */
 | 
			
		||||
		oml_tx_state_changed(&ts->mo);
 | 
			
		||||
		return;
 | 
			
		||||
	case NM_EV_SW_ACT:
 | 
			
		||||
		oml_mo_tx_sw_act_rep(&ts->mo);
 | 
			
		||||
		if (ts_can_be_enabled(ts))
 | 
			
		||||
			nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_DISABLED_OFFLINE);
 | 
			
		||||
@@ -94,17 +98,30 @@ static void st_op_disabled_dependency(struct osmo_fsm_inst *fi, uint32_t event,
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv;
 | 
			
		||||
	struct nm_fsm_ev_setattr_data *setattr_data;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case NM_EV_SETATTR_ACK:
 | 
			
		||||
	case NM_EV_SETATTR_NACK:
 | 
			
		||||
	case NM_EV_OML_UP:
 | 
			
		||||
		/* Report current state: */
 | 
			
		||||
		oml_tx_state_changed(&ts->mo);
 | 
			
		||||
		return;
 | 
			
		||||
	case NM_EV_RX_SETATTR:
 | 
			
		||||
		setattr_data = (struct nm_fsm_ev_setattr_data *)data;
 | 
			
		||||
		ts->mo.setattr_success = setattr_data->cause == 0;
 | 
			
		||||
		oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
 | 
			
		||||
		rc = bts_model_apply_oml(ts->trx->bts, setattr_data->msg,
 | 
			
		||||
					 &ts->mo, ts);
 | 
			
		||||
		ts->mo.setattr_success = rc == 0;
 | 
			
		||||
		oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
 | 
			
		||||
		break;
 | 
			
		||||
	case NM_EV_RX_OPSTART:
 | 
			
		||||
		LOGPFSML(fi, LOGL_NOTICE, "BSC trying to activate TS while still in avail=dependency. "
 | 
			
		||||
			 "Allowing it to stay backward-compatible with older osmo-bts versions, but BSC is wrong.\n");
 | 
			
		||||
		if (!ts->mo.setattr_success) {
 | 
			
		||||
			oml_mo_opstart_nack(&ts->mo, NM_NACK_CANT_PERFORM);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		bts_model_opstart(ts->trx->bts, &ts->mo, ts);
 | 
			
		||||
		break;
 | 
			
		||||
	case NM_EV_OPSTART_ACK:
 | 
			
		||||
		 LOGPFSML(fi, LOGL_NOTICE, "BSC trying to activate TS while still in avail=dependency. "
 | 
			
		||||
			  "Allowing it to stay backward-compatible with older osmo-bts versions, but BSC is wrong.\n");
 | 
			
		||||
		ts->mo.opstart_success = true;
 | 
			
		||||
		oml_mo_opstart_ack(&ts->mo);
 | 
			
		||||
		nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_ENABLED);
 | 
			
		||||
@@ -138,13 +155,26 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv;
 | 
			
		||||
	struct nm_fsm_ev_setattr_data *setattr_data;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	switch (event) {
 | 
			
		||||
	case NM_EV_SETATTR_ACK:
 | 
			
		||||
	case NM_EV_SETATTR_NACK:
 | 
			
		||||
	case NM_EV_OML_UP:
 | 
			
		||||
		/* Report current state: */
 | 
			
		||||
		oml_tx_state_changed(&ts->mo);
 | 
			
		||||
		return;
 | 
			
		||||
	case NM_EV_RX_SETATTR:
 | 
			
		||||
		setattr_data = (struct nm_fsm_ev_setattr_data *)data;
 | 
			
		||||
		ts->mo.setattr_success = setattr_data->cause == 0;
 | 
			
		||||
		oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
 | 
			
		||||
		rc = bts_model_apply_oml(ts->trx->bts, setattr_data->msg,
 | 
			
		||||
					 &ts->mo, ts);
 | 
			
		||||
		ts->mo.setattr_success = rc == 0;
 | 
			
		||||
		oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
 | 
			
		||||
		break;
 | 
			
		||||
	case NM_EV_RX_OPSTART:
 | 
			
		||||
		if (!ts->mo.setattr_success) {
 | 
			
		||||
			oml_mo_opstart_nack(&ts->mo, NM_NACK_CANT_PERFORM);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		bts_model_opstart(ts->trx->bts, &ts->mo, ts);
 | 
			
		||||
		break;
 | 
			
		||||
	case NM_EV_OPSTART_ACK:
 | 
			
		||||
		ts->mo.opstart_success = true;
 | 
			
		||||
@@ -209,7 +239,8 @@ static void nm_chan_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *dat
 | 
			
		||||
static struct osmo_fsm_state nm_chan_fsm_states[] = {
 | 
			
		||||
	[NM_CHAN_ST_OP_DISABLED_NOTINSTALLED] = {
 | 
			
		||||
		.in_event_mask =
 | 
			
		||||
			X(NM_EV_BBTRANSC_INSTALLED),
 | 
			
		||||
			X(NM_EV_SW_ACT) |
 | 
			
		||||
			X(NM_EV_OML_UP),
 | 
			
		||||
		.out_state_mask =
 | 
			
		||||
			X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) |
 | 
			
		||||
			X(NM_CHAN_ST_OP_DISABLED_OFFLINE) |
 | 
			
		||||
@@ -220,10 +251,11 @@ static struct osmo_fsm_state nm_chan_fsm_states[] = {
 | 
			
		||||
	},
 | 
			
		||||
	[NM_CHAN_ST_OP_DISABLED_DEPENDENCY] = {
 | 
			
		||||
		.in_event_mask =
 | 
			
		||||
			X(NM_EV_SETATTR_ACK) |
 | 
			
		||||
			X(NM_EV_SETATTR_NACK) |
 | 
			
		||||
			X(NM_EV_OPSTART_ACK) |  /* backward compatibility, buggy BSC */
 | 
			
		||||
			X(NM_EV_OPSTART_NACK) |
 | 
			
		||||
			X(NM_EV_OML_UP) |
 | 
			
		||||
			X(NM_EV_RX_SETATTR) |
 | 
			
		||||
			X(NM_EV_RX_OPSTART) | /* backward compatibility, buggy BSC */
 | 
			
		||||
			X(NM_EV_OPSTART_ACK) | /* backward compatibility, buggy BSC */
 | 
			
		||||
			X(NM_EV_OPSTART_NACK) | /* backward compatibility, buggy BSC */
 | 
			
		||||
			X(NM_EV_BBTRANSC_ENABLED) |
 | 
			
		||||
			X(NM_EV_RCARRIER_ENABLED) |
 | 
			
		||||
			X(NM_EV_BBTRANSC_DISABLED) |
 | 
			
		||||
@@ -238,8 +270,9 @@ static struct osmo_fsm_state nm_chan_fsm_states[] = {
 | 
			
		||||
	},
 | 
			
		||||
	[NM_CHAN_ST_OP_DISABLED_OFFLINE] = {
 | 
			
		||||
		.in_event_mask =
 | 
			
		||||
			X(NM_EV_SETATTR_ACK) |
 | 
			
		||||
			X(NM_EV_SETATTR_NACK) |
 | 
			
		||||
			X(NM_EV_OML_UP) |
 | 
			
		||||
			X(NM_EV_RX_SETATTR) |
 | 
			
		||||
			X(NM_EV_RX_OPSTART) |
 | 
			
		||||
			X(NM_EV_OPSTART_ACK) |
 | 
			
		||||
			X(NM_EV_OPSTART_NACK) |
 | 
			
		||||
			X(NM_EV_BBTRANSC_DISABLED) |
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user